I have a project that creates a disk image and would like to use a custom icon for the loaded volume. I have a .VolumeIcon.icns
file that looks great, but to make Finder use it, I've had to include an empty file named Icon^M
(Icon\r, Icon<cr>). My custom icon shows up and everything works great.
Except. When I try to check the Icon^M file into my svn repository I get:
svn: Invalid control character '0x0d' in path 'Icon\015'
Subversion ha开发者_Python百科s stricter filename standards than Mac and, reasonably, doesn't allow carriage returns. An old thread on the svn mailing list discussed this problem, and the recommendation was to just create the file with a shell script as part of the build process. I could do that, but my build process is very simple right now and I'm loath to make it more complex.
Is there a more elegant solution?
This problem with icons has bothered me for some time. The basic solution was basically to ignore the file completely, which I refused to do as I am a visual person and enjoy wasting my time creating cool icons for my projects.
Note: I did my best to make sure it works, but I can't guarantee it, so try on a copy of your data. With that said here was my solution to this issue.
Basically I created 3 scripts to address the mac icon\r issue.
- repoMacPrepare.sh
- repoMacRestore.sh
- gitAliasScript.sh
These three scripts are used to add mac Icons in a format that git or svn can accept and store. The first script prepares the repository searching for Icon based files in directories and custom icon formats within files. Then stores them as either .jdIcnd or .jdIcnf (d for directory f for folder) within their respective paths.
The second script allows it to be brought back to life on the mac by searching for .jdIcnd and .jdIcnf files.
The last script shows how to automate the process. I use an alias for git that references the gitAliasScript.sh script in my .bashrc file. Now I switched to git (best thing I did) so the script is shown for git but the basics are the same in svn. I hope this helps mac users using versioning systems who don't won't to lose their icons as part of a checkin process or checkout process. Also note that those not using this script won't have issues since the icons are stored as binary files with a dot prefix making them invisible. Oooh yeah...
file: repoMacPrepare.sh
#! /bin/bash
#
# Author: Joshua Demori
# Email: jdemori@jrdfamily.com
#
# This script is used to prepare a repository
# to still record the Icons used on a mac for files or directories
#
# First
# DeRez Icon^M > .IconCntrlR
# (hit control-v then enter to get the carriage return vi)
#
# Store in Repository
# then to bring back
# Rez -append IconCopy -o Icon
# # may need to set the Folders Icon Info
# SetFile -a C /Path/To/Custom/Folder/With/Icon/
#
# if I need to SetFile the folder I can do this 2 ways
# a main file which has all this data at base of repository (bad)
# as it finds those files it does the folder below it
#
#
#=======================================================#
# Defines
readonly VERSION=1.00
#=======================================================#
# Variables
varVerbose=false
#=======================================================#
# Functions
setupDirIcon () {
DeRez "${file}"/Icon
> "${file}"/.Icon.jdIcnd
if [ $varVerbose == true ]; then
echo Adding Icon File: "$file"/.Icon.jdIcnd
fi
}
setupFileIcon () {
base=`basename "$file"`
path=`dirname "$file"`
DeRez "$file" > "${path}"/."${base}".jdIcnf
if [ $varVerbose == true ]; then
echo Adding Icon File: "$file"/."${base}".jdIcnf
fi
}
# cmd line functions
function funcOptionVersion {
echo "Reposiotry Mac Icon Preperation Script Version: $VERSION"
exit 0
}
function funcOptionHelp {
name=`basename $0`
echo $name Help Screen
echo '-h help'
echo '-v verbose'
echo '-n version'
echo ' '
exit 0
}
function funcOptionVerbose {
varVerbose=true
}
#=======================================================#
# process cmd line arguments
while getopts "vhn" optionName; do
case "$optionName" in
n) funcOptionVersion ;;
h) funcOptionHelp ;;
v) funcOptionVerbose ;;
[?]) printErrorHelpAndExit "$badOptionHelp";;
esac
done
#=======================================================#
#=======================================================#
# Start main portion of script
# ignore . .DS_Store .git folders and files
find . | grep -v ^.$ | grep -v .DS_Store | grep -v .git | grep -v .svn | while read file
do
# does this file have an icon attribute
GetFileInfo -a "$file" | grep C > /dev/null
if [ $? = 0 ]; then
if [ -d "$file" ]; then
setupDirIcon
else
setupFileIcon
fi
fi # end if for icon test
done
# Remove Only the Icon file used by directories
echo Removing Icon File
if [ $varVerbose == true ]; then
find . -name Icon
-print -exec rm {} \;
else
find . -name Icon
-exec rm {} \;
fi
file: repoMacRestore.sh
#! /bin/bash
#
# Author: Joshua Demori
# Email: jdemori@jrdfamily.com
#
# This Script complemnts xxxx by reversing the icons as derez to rez
# then setting the proper file attributes to view the icons
#
# First
# DeRez Icon^M > .IconCntrlR
# (hit control-v then enter to get the carriage return vi)
#
# Store in Repository
# then to bring back
# Rez -append IconCopy -o Icon
# # may need to set the Folders Icon Info
# SetFile -a C /Path/To/Custom/Folder/With/Icon/
#
# if I need to SetFile the folder I can do this 2 ways
# a main file which has all this data at base of repository (bad)
# as it finds those files it does the folder below it
#
#
#=======================================================#
# Defines
readonly VERSION=1.00
#=======================================================#
# Variables
varVerbose=false
#=======================================================#
# Functions
# cmd line functions
function funcOptionVersion {
echo "Repository Mac Icon Restore Script Version: $VERSION"
exit 0
}
function funcOptionHelp {
name=`basename $0`
echo $name Help Screen
echo '-h help'
echo '-v verbose'
echo '-n version'
echo ' '
exit 0
}
function funcOptionVerbose {
varVerbose=true
}
#=======================================================#
# process cmd line arguments
while getopts "vhn" optionName; do
case "$optionName" in
n) funcOptionVersion ;;
h) funcOptionHelp ;;
v) funcOptionVerbose ;;
[?]) printErrorHelpAndExit "$badOptionHelp";;
esac
done
#=======================================================#
#=======================================================#
# Start main portion of script
#=======================================================#
# Go thourgh directories
find . -name *.jdIcnd | while read file
do
# is it a dir - restore dir icon
echo "$file" | grep jdIcnd
if [ $? = 0 ]; then
if [ $varVerbose == true ]; then
echo Fixing Directory Icon: "$file"
fi
path=`dirname "$file"`
Rez "$file" -o "${path}"/Icon
SetFile -a V "${path}"/Icon
SetFile -a C "${path}"
fi
done
# Go thourgh files
# is it a file - restore file icon
find . -name *.jdIcnf | while read file
do
echo "$file" | grep jdIcnf
if [ $? = 0 ]; then
path=`dirname "$file"`
base=`basename "$file"`
origFileName=`echo "$base" | sed 's/\.jdIcnf//'`
origFileName=`echo "${origFileName:1}"`
fileWithPath="${path}"/"${origFileName}"
if [ $varVerbose == true ]; then
echo Restoring File Icon: "$path"
fi
#echo origFileName: "$origFileName"
#echo filesWithPath: "$fileWithPath"
Rez -append "$file" -o "$fileWithPath"
SetFile -a C "$fileWithPath"
fi
done
gitAliasScript.sh
#! /bin/bash
found=false
args=("$@")
for var in "$@"
do
x=`echo $var | grep -ic commit`
if [ $x == 1 ]; then
# prepare icons to be saved
# add them to repository
# at the end git is run
repoMacPrepare.sh
find . -name *.jdIcnd -exec git add {} \;
find . -name *.jdIcnf -exec git add {} \;
found=true
fi
done
#runs git cmd here
cmdPart='git '
cmd=${cmdPart}${@}
$cmd
# finish by bringing back icons
# if commit was called
if [ $found == true ]; then
repoMacRestore.sh
fi
exit 0
I think you're boned. What are you using to build now? I'll tip my hat to anyone that can come up with a better answer than the one you yourself proposed - scripting it in the build.
I'm guessing putting the file in an archive such as tar would allow you to upload it. Let me see if it actually works... looks like I'm right:
$ touch hello^Mhaha
$ svn add hello^Mhaha
svn: Invalid control character '0x0d' in path 'hello\015haha'
$ tar cf hellorhaha.tar hello^Mhaha
$ svn add hellorhaha.tar
A (bin) hellorhaha.tar
Perhaps not what you're looking, but lets you add the file with almost no hustle. I would do it like that anyway. Actually I wouldn't put newlines or carriage returns in my file names, but hey.. to each his own.
This happens to me because there was icon file without extension (in this case .png) after I renamed the icon file to Icon.png it was all okay :)
Make a copy of ~/.subversion/config Then edit ~/.subversion/config by first finding the line which looks like:
global-ignores = *.o *.lo *.la *.al .libs *.so .so.[0-9] *.a *.pyc *.pyo
Then add after that a new line in config:
global-ignores = Icon?
Save the config file. This will ignore all files whose name starts with "Icon" plus one additional character.
Not as good as ignore ignoring exactly what that file is named. But it works with caveat.
精彩评论