I was tired of cutting and pasting code snippets between projects in order to improve an existing project without destroying the current state. So I created a cloner that allows you (and me) to clone an existing project and in the process adjust some keys so that the cloned project will work although it now has a new name.
Here is the main code:
- Code: Select all
IBOutlet myButton As NSButton
IBOutlet myView As NSScrollView
Dim thePlist As NSMutableDictionary
Dim thePlistPath As String
Dim fileArray As Array
Dim theApplicationName As String
Dim theApplicationSignature As String
Dim clonedProject As String
Dim sourceProject As String
Dim sourcePath As String
Dim theException As id
Dim theFileManager As NSFileManager
IBAction cloneIt(sender As id)
NSOpenPanel.CanChooseDirectories = Yes
NSOpenPanel.CanChooseFiles = No
NSOpenPanel.AllowsMultipleSelection = No
NSOpenPanel.Run()
Try
sourceProject = NSOpenPanel.FileName()
' did the user select a directory or did he cancel out?
If (sourceProject = "") Then
Exception("Source not selected","sourceNotSelected")
End If
sourcePath = Concat(FilePath(sourceProject), "/")
' check if sourceProject is a valid OB project directory
thePlistPath = Concat(sourceProject, "/Contents")
' Alert(thePlistPath)
fileArray = File.List(thePlistPath)
' Alert(fileArray)
If (fileArray.Count() <> 2) Then
Exception("No Objective Basic project as source", "noOBSource")
End If
theApplicationName = InputPanel("Please input name of cloned project", "", "")
' has the user canceled out of the input process?
If (theApplicationName = Nil) Then
Exception("Destination not selected","destNotSelected")
End If
clonedProject=Concat(sourcePath, theApplicationName)
fileArray = File.List(clonedProject)
If (fileArray.Count() <> 0) Then
Exception("Destination already exists","destExists")
End If
If (theFileManager.ExistsFile(clonedProject)) Then
Exception("Destination already exists","destExists")
End If
' raises "ReadDictionary failed"
thePlist=plist(Concat(thePlistPath,"/Info.plist"))
thePlist.Replace("CFBundleExecutable", theApplicationName)
thePlist.Replace("CFBundleIdentifier", theApplicationName)
thePlist.Replace("CFBundleName", theApplicationName)
theApplicationSignature=LCase(Left(theApplicationName,4))
thePlist.Replace("CFBundleSignature", theApplicationSignature)
' now we have substituted the necessary keys with the new project's fingerprints
If (File.Copy(sourceProject, clonedProject) <> Yes) Then
Exception("Copy failed", "cloneFailed")
End If
WriteDictionary(thePlist, Concat(clonedProject,"/Contents/Info.plist"))
' File.RemoveFile(Concat(Concat("/Users/HU/Desktop/",theApplicationName),"/hund.app"))
' clear cloned project's directory of artefacts left by old project
' tell user that operations have been sucessful and end execution gracefully
Alert("Project has been cloned successfully!")
Catch theException
Select Info(theException)
Case "ReadDictionary failed"
Alert("Error occured", "Info.plist could not be opened")
Case "sourceNotSelected"
Alert("Not sure?", "Please select the project you want to clone")
Case "noOBSource"
Alert("Error occured", "Tool only works on Objective Basic projects")
Case "destNotSelected"
Alert("Not sure?", "Please name the cloned project")
Case "destExists"
Alert("Error occured", "This project name has already been used\nplease select another one!")
Case "cloneFailed"
Alert("Unspecified error occured", "The project could not be cloned!")
End Select
' Alert(theException)
Finally
End Try
End IBAction
You see I have tried to provide as much safeguarding a could think about - raising exceptions for every step that could fail and present a short explanation to the stunned user.
The user interface looks like this:
Here comes the project archive:
If found the program much cleaner once I started to use Exceptions and stopped to interleave If blocks.
What do you think about this style? What would you improve?
BTW: You can use this tool if you started a project with an internal name (e.g. Huhn) and want to rename it to something more meaningful (e.g. cloneProject) before posting it to the board
Regards
Udo