Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

svn returns "Invalid control character '0x0d' in path 'Icon\015'" when trying to add Mac custom icon file

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 has 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?

like image 759
blahdiblah Avatar asked Nov 05 '22 20:11

blahdiblah


2 Answers

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.

  1. repoMacPrepare.sh
  2. repoMacRestore.sh
  3. 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: [email protected]
#
# 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: [email protected]
#
# 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
like image 147
Joshua Demori Avatar answered Nov 09 '22 17:11

Joshua Demori


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.

like image 28
thekbb Avatar answered Nov 09 '22 17:11

thekbb