I have a script that creates another script. When it names the new script I want it to add a number to the end if the name it wants to use already exists so the previous file stays. Lets say the script is going to name the new file My Script.app but that file is already there. I need the script to add a number to the end and test again to see if that file exists ( My Script-1.app ) and if so keep repeating until the name it wants to use does not exist then continue. My first thought was to use a repeat until statement something like this.
set appendIncr to "0"
set file_path to (path to desktop as Unicode text) & "Create Process-" & processName & ".app"
set file_path to POSIX path of file_path as string
if exists file_path then
repeat until not exists file_path
set appendIncr to (appendIncr + 1)
set file_path to (path to desktop as Unicode text) & "Create Process-" & processName & appendIncr & ".app"
set file_path to POSIX path of file_path as string
end repeat
end if
do shell script "echo " & quoted form of script_text & "|osacompile -o \"" & file_path & "\""
So I’m thinking it would repeat adding 1 to appendIncr on each repeat until the name is unique. What is the proper syntax to achieve this? This sample is actually a snippet from a handler in a larger script so some variables don’t exist.
I use this universal handler to check the file name
on checkFileName(fDir, fName, separator) -- fDir can be alias or path string
set fDir to fDir as Unicode text
try
set f to (fDir & fName) as alias
set {name:Nm, name extension:Ex} to info for f
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set idx to 0
repeat
set idx to idx + 1
set checkName to (fDir & Nm & separator & (idx as string) & "." & Ex)
try
checkName as alias
on error
return checkName
end try
end repeat
on error
return (fDir & fName)
end try
end checkFileName
It seems this would work great but I’m having trouble working it into my script.
on RunMaker(script_text, bugcheck)
set file_path to (path to desktop as Unicode text) & "Create Process-" & processName & ".app"
set file_path to POSIX path of file_path as string
set fDir to path to desktop as string
set fName to ("Create Process-" & processName & ".app" as string)
set separator to "-"
my checkFileName(fDir, fName, separator)
do shell script "echo " & quoted form of script_text & "|osacompile -o \"" & file_path & "\""
if bugcheck then say "saved"
--Copy Icon to new bundle
set newIconPath to ((path to me) as string)
set newIconPath to (POSIX path of newIconPath) & "Contents/Resources/Appleticon/applet.icns" as string
set iconDestination to (file_path & "/Contents/Resources/" as string)
do shell script "cp " & "\"" & newIconPath & "\"" & " " & "\"" & iconDestination & "\""
end RunMaker
on checkFileName(fDir, fName, separator) -- fDir can be alias or path string
set fDir to fDir as Unicode text
try
set f to (fDir & fName) as alias
set {name:Nm, name extension:Ex} to info for f
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set idx to 0
repeat
set idx to idx + 1
set checkName to (fDir & Nm & separator & (idx as string) & "." & Ex)
try
checkName as alias
on error
return checkName
end try
end repeat
on error
set filepath to (fDir & fName as Unicode text)
set file_path to POSIX path of file_path
--return (fDir & fName)
end try
end checkFileName
Where am I going wrong? Working with handlers is fairly new territory to me.
a handler has a few special rules, one of them is, which is very important,
that local variables are only recognized by the handler, which they are declared in
Only properties and global variables are valid everywhere in the script.
Also your processName variable should be a property or a global!
You can pass parameters through the parentheses and the result is either
the result of the last executed line or the argument of the explicit return command.
Try this:
on RunMaker(script_text, bugcheck)
set fName to "Create Process-" & processName & ".app"
set file_path to POSIX path of checkFileName(path to desktop, fName, "-")
do shell script "echo " & quoted form of script_text & "|osacompile -o " & quoted form of file_path
if bugcheck then say "saved"
--Copy Icon to new bundle
set newIconPath to ((path to me) as Unicode text)
set newIconPath to (POSIX path of newIconPath) & "Contents/Resources/Appleticon/applet.icns"
set iconDestination to file_path & "/Contents/Resources/"
do shell script "cp " & "\"" & newIconPath & "\"" & " " & "\"" & iconDestination & "\""
end RunMaker
on checkFileName(fDir, fName, separator) -- fDir can be alias or path string
set fDir to fDir as Unicode text
try
set f to (fDir & fName) as alias
set {name:Nm, name extension:Ex} to info for f
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set idx to 0
repeat
set idx to idx + 1
set checkName to (fDir & Nm & separator & (idx as string) & "." & Ex)
try
checkName as alias
on error
return checkName
end try
end repeat
on error
return (fDir & fName)
end try
end checkFileName
In my “on run” section of my script I was setting the comments of the resulting file. However if the file is renamed by the checkFileName handler can I get the values of fDir & fName into that part of the script. I declared fDir and fName as property’s at the top of my script and then try to set the comment like
set commentText to ("Quality:" & processQuality & ", Format:" & processFormat & ", Scaling:" & processScale & ", Resolution:" & processRes as string)
set new_file to (fDir & fName as Unicode text)
set new_file to new_file as alias
tell application "Finder"
set comment of file new_file to commentText
end tell
It worked before using the checkFileName handler and the error shows it’s looking for the file name before the handler renamed it. Since the handler explicitly returns fDir and fName and since I declared them as properties I was thinking I could get the new name to set the comments to. Where am I going wrong?
the problem is, if the file already exists, the handler returns checkName, not fName
change the repeat block to this:
...
repeat
set idx to idx + 1
set fName to (Nm & separator & (idx as string) & "." & Ex)
try
(fDir & fName) as alias
on error
return (fDir & fName)
end try
end repeat
...
I commented “–Stefan Look Here” at the start of the section in question. Everything works except the file won’t get comments if the handler renamed it from what the user input in the first dialog processName. Just run the app once hitting return for each dialog then do it a second time to get the handler to rename the file. Get info on both files and you’ll see that one gets the comments and the other did not.
sorry, but I get a couple of errors in your script, which is not your fault,
because my (international) number format settings expect a comma as decimal point instead of a dot.
And then I get an error: No user interaction allowed.
But as far as I can see, the property “fName” should be set properly.
I don’t understand why it doesn’t.
A few notes:
¢ the keyword my in front of a handler call is only necessary if the handler is called within a tell block.
¢ Take care of your coercions, for example
set Pathz to ((path to me) & "Contents:Resources:Scripts:main.scpt" as string)
works, but better is:
set Pathz to (((path to me) as Unicode text) & "Contents:Resources:Scripts:main.scpt")
¢ instead of your yes/no lists I would use yes/no buttons
Edit: I know, what the problem is:
we use the same variable name (fName) as a property and as a parameter variable of a handler.
The handler takes it as a local variable and ignores the property.
Using a different name solves the problem:
on checkFileName(fDir, fN, separator) -- fDir can be alias or path string
set fDir to fDir as Unicode text
try
set f to (fDir & fN) as alias
set {name:Nm, name extension:Ex} to info for f
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set idx to 0
repeat
set idx to idx + 1
set fName to (Nm & separator & (idx as string) & "." & Ex)
try
(fDir & fName) as alias
on error
return (fDir & fName)
end try
end repeat
on error
return (fDir & fN)
end try
end checkFileName