From 0894c56ed471b4c5d0d30cb312f1d8970a0dd216 Mon Sep 17 00:00:00 2001 From: GoannaGuy Date: Sun, 26 Sep 2010 21:51:40 -0500 Subject: [PATCH] Changed Xmod.applescript to better support --machine-dir, --human-dir and --output-dir comments... directories can be specified as either full or relative paths (relative to model file). Xcode group and file references are no longer deleted/re-added with every save. New files are added automatically. This allows group references to be moved or contain files that are not auto generated. --- Xmod/Xmod.applescript | 219 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 179 insertions(+), 40 deletions(-) diff --git a/Xmod/Xmod.applescript b/Xmod/Xmod.applescript index 471036b0..57d08185 100644 --- a/Xmod/Xmod.applescript +++ b/Xmod/Xmod.applescript @@ -16,7 +16,9 @@ on updateProjectXmod(_project) set theComments to the comments of modelItr if theComments contains "xmod" then - set modelInfo to my getModelInfo(full path of modelItr) + set modelInfo to my getModelInfo(full path of modelItr, theComments) + set humanGroupRef to null + set machineGroupRef to null -- Figure out the model's parent group. -- Unversioned models are simple files so their group is the answer. @@ -28,23 +30,45 @@ on updateProjectXmod(_project) set modelGroupRef to item 1 of (every group of _project whose groups contains modelGroupRef) end if - -- Create the .xcdatamodel related source group if necessary. - if not (exists (every item reference of modelGroupRef whose full path is (srcDirPath of modelInfo))) then + -- look for a group in the project that has the full path of the human manageable files + set groupRefs to (every group of _project whose full path is (humanDirPath of modelInfo)) + -- if we don't find one, create it in the same group as the model file + if (count of groupRefs) = 0 then tell modelGroupRef - make new group with properties {full path:(srcDirPath of modelInfo), name:(name of modelInfo)} + -- if we have different human and machine paths, then append '_human' to the model name for the group name + if (humanDirPath of modelInfo) is not equal to (machineDirPath of modelInfo) then + make new group with properties {full path:(humanDirPath of modelInfo), name:(name of modelInfo & "_human")} + else + make new group with properties {full path:(humanDirPath of modelInfo), name:(name of modelInfo)} + end if + set groupRefs to (every group of _project whose full path is (humanDirPath of modelInfo)) end tell end if - set modelSrcGroup to item 1 of (every item reference of modelGroupRef whose full path is (srcDirPath of modelInfo)) - tell modelSrcGroup to delete every item reference -- clear it out for population in case we didn't just create it + set humanGroupRef to item 1 of groupRefs + + -- if we have different human and machine paths, then look for a group for the machine files + if (humanDirPath of modelInfo) is not equal to (machineDirPath of modelInfo) then + set groupRefs to (every group of _project whose full path is (machineDirPath of modelInfo)) + -- if we don't find one, create it in the same group as the model file... named with '_machine' appended to the model name + if (count of groupRefs) = 0 then + tell modelGroupRef + make new group with properties {full path:(machineDirPath of modelInfo), name:(name of modelInfo & "_machine")} + end tell + set groupRefs to (every group of _project whose full path is (machineDirPath of modelInfo)) + end if + set machineGroupRef to item 1 of groupRefs + end if - -- Create the do shell script string and append any custom per model options to it - set theScript to "/usr/bin/mogenerator --model '" & full path of modelItr & "' --output-dir '" & (srcDirPath of modelInfo) & "'" + -- Create the do shell script string and append any custom per model options to it, skipping the ones we've already parsed out + set theScript to "/usr/bin/mogenerator --model '" & full path of modelItr & "' --human-dir '" & (humanDirPath of modelInfo) & "' --machine-dir '" & (machineDirPath of modelInfo) & "'" set theParagraphs to every paragraph of theComments repeat with theParagraph in theParagraphs if (length of the characters of theParagraph) is greater than 2 then set theToken to the first character of theParagraph & the second character of theParagraph if theToken is "--" then - set theScript to theScript & " " & the text of theParagraph + if ((offset of "--human-dir " in theParagraph) = 0) and ((offset of "--machine-dir " in theParagraph) = 0) and ((offset of "--output-dir " in theParagraph) = 0) then + set theScript to theScript & " " & the text of theParagraph + end if end if end if end repeat @@ -52,31 +76,10 @@ on updateProjectXmod(_project) -- Meat. do shell script theScript - -- Build a list of resulting source files. - tell application "System Events" - set modelSrcDirAlias to POSIX file (srcDirPath of modelInfo) as alias - set humanHeaderFileList to (every file of modelSrcDirAlias whose name ends with ".h" and name does not start with "_") - set humanSourceFileList to (every file of modelSrcDirAlias whose (name ends with ".m" or name ends with ".mm") and name does not start with "_") - set machineHeaderFileList to (every file of modelSrcDirAlias whose name ends with ".h" and name starts with "_") - set machineSourceFileList to (every file of modelSrcDirAlias whose (name ends with ".m" or name ends with ".mm") and name starts with "_") - set fileList to humanSourceFileList & humanHeaderFileList & machineSourceFileList & machineHeaderFileList - set pathList to {} - repeat with fileItem in fileList - set pathList to pathList & POSIX path of fileItem - end repeat - end tell - - -- Add the source files to the model's source group and the model's targets. - set targetList to my everyTargetWithBuildFilePath(_project, full path of modelItr) - repeat with pathItr in pathList - tell modelSrcGroup - set modelSrcFileRef to make new file reference with properties {full path:pathItr, name:name of (info for POSIX file pathItr)} - repeat with targetIndex from 1 to (count of targetList) - set targetItr to item targetIndex of targetList - add modelSrcFileRef to targetItr - end repeat - end tell - end repeat + my addFilesFromPathToGroup(_project, modelItr, humanGroupRef) + if machineGroupRef is not null then + my addFilesFromPathToGroup(_project, modelItr, machineGroupRef) + end if end if end repeat end tell @@ -94,10 +97,70 @@ on everyTargetWithBuildFilePath(_project, _buildFilePath) return theResult end everyTargetWithBuildFilePath -on getModelInfo(modelFileUnixPath) +on getModelInfo(modelFileUnixPath, theComments) set modelFilePosixRef to POSIX file modelFileUnixPath set modelFileAlias to modelFilePosixRef as alias + set theOutputDir to "" + set theHumanDir to "" + set theMachineDir to "" + + -- check for any directory path options specified in the commments + set theParagraphs to every paragraph of theComments + repeat with theParagraph in theParagraphs + set paragraphLength to (length of theParagraph) + if (offset of "--human-dir " in theParagraph) = 1 then + set remainderOffset to (length of "--human-dir ") + 1 + if remainderOffset > paragraphLength then + set theHumanDir to "" + else + set theHumanDir to text remainderOffset thru -1 of theParagraph + end if + else if (offset of "--machine-dir " in theParagraph) = 1 then + set remainderOffset to (length of "--machine-dir ") + 1 + if remainderOffset > paragraphLength then + set theMachineDir to "" + else + set theMachineDir to text remainderOffset thru -1 of theParagraph + end if + else if (offset of "--output-dir " in theParagraph) = 1 then + set remainderOffset to (length of "--output-dir ") + 1 + if remainderOffset > paragraphLength then + set theOutputDir to "" + else + set theOutputDir to text remainderOffset thru -1 of theParagraph + end if + end if + end repeat + + -- remove any leading/trailing spaces or tabs from the paths + if (length of theHumanDir) > 0 then + repeat while character 1 of theHumanDir = tab or character 1 of theHumanDir = space + set theHumanDir to text 2 thru -1 of theHumanDir + end repeat + repeat while last character of theHumanDir = tab or last character of theHumanDir = space + set theHumanDir to text 1 thru -2 of theHumanDir + end repeat + end if + + if (length of theMachineDir) > 0 then + repeat while character 1 of theMachineDir = tab or character 1 of theMachineDir = space + set theMachineDir to text 2 thru -1 of theMachineDir + end repeat + repeat while last character of theMachineDir = tab or last character of theMachineDir = space + set theMachineDir to text 1 thru -2 of theMachineDir + end repeat + end if + + if (length of theOutputDir) > 0 then + repeat while character 1 of theOutputDir = tab or character 1 of theOutputDir = space + set theOutputDir to text 2 thru -1 of theOutputDir + end repeat + repeat while last character of theOutputDir = tab or last character of theOutputDir = space + set theOutputDir to text 1 thru -2 of theOutputDir + end repeat + end if + -- get actual the model info and modify value for theOutputDir if necessary tell application "Finder" set modelFileFolder to folder of modelFileAlias @@ -115,15 +178,91 @@ on getModelInfo(modelFileUnixPath) end if set modelName to text 1 thru -(extensionLength + 1) of modelFileName -- pull off the extension - if not (exists folder modelName of modelFileFolder) then - make folder at modelFileFolder with properties {name:modelName} + + -- if we didn't find any directory specifiers in the comments, then make theOutputDir the folder containg the model file + if ((length of theOutputDir) = 0) and ((length of theHumanDir) = 0) and ((length of theMachineDir) = 0) then + set modelSrcFolder to folder modelName of modelFileFolder + set theOutputDir to text 1 thru -2 of (POSIX path of (modelSrcFolder as alias)) + -- otherwise, if theOutputDir isn't a full path itself already, set theOutputDir to a full path relative to the model file + else if theOutputDir does not start with "/" then + set modelFolderPath to text 1 thru -2 of (POSIX path of (modelFileFolder as alias)) + if (length of theOutputDir) = 0 then + set theOutputDir to modelFolderPath + else + copy modelFolderPath & "/" & theOutputDir to theOutputDir + end if end if - set modelSrcFolder to folder modelName of modelFileFolder + end tell - set srcDirPath to text 1 thru -2 of (POSIX path of (modelSrcFolder as alias)) -- kill the trailing slash - return {name:modelName, isBundle:isModelBundle, srcDirPath:srcDirPath} + + + -- if theHumanDir is empty, use theOutputDir value instead, if theHumanDir not empty and it isn't a full path, then treat it as a relative path to theOutputDir + if (length of theHumanDir) = 0 then + set theHumanDir to theOutputDir + else if theHumanDir does not start with "/" then + copy theOutputDir & "/" & theHumanDir to theHumanDir + end if + + -- if theMachineDir is empty, use theOutputDir value instead, if theMachineDir not empty and it isn't a full path, then treat it as a relative path to theOutputDir + if (length of theMachineDir) = 0 then + set theMachineDir to theOutputDir + else if theMachineDir does not start with "/" then + copy theOutputDir & "/" & theMachineDir to theMachineDir + end if + + -- ensure the directories exist + do shell script "mkdir -p '" & theHumanDir & "'" + do shell script "mkdir -p '" & theMachineDir & "'" + + -- the following should resolve any symlinks, '..', or '~' in the paths + tell application "System Events" + set dirAlias to POSIX file theHumanDir as alias + set theHumanDir to (POSIX path of (dirAlias as alias)) + set dirAlias to POSIX file theMachineDir as alias + set theMachineDir to (POSIX path of (dirAlias as alias)) + end tell + + return {name:modelName, isBundle:isModelBundle, machineDirPath:theMachineDir, humanDirPath:theHumanDir} + end getModelInfo on logger(msg) do shell script "logger '" & msg & "'" end logger + +on addFilesFromPathToGroup(_project, modelItr, groupRef) + tell application "Xcode" + -- get the full path of the directory that the groupRef represents + set groupPath to full path of groupRef + + -- Build a list of source files in the group's directory + tell application "System Events" + set modelSrcDirAlias to POSIX file groupPath as alias + set fileList to (every file of modelSrcDirAlias whose (name ends with ".m" or name ends with ".mm" or name ends with ".h")) + set pathList to {} + repeat with fileItem in fileList + set pathList to pathList & POSIX path of fileItem + end repeat + end tell + + -- Add the source files to the group and the model's targets, but only if they don't exist already + set targetList to null + repeat with pathItr in pathList + tell groupRef + set fileRefs to (every file reference of _project whose full path is pathItr) + if (count of fileRefs) = 0 then + set modelSrcFileRef to make new file reference with properties {full path:pathItr, name:name of (info for POSIX file pathItr)} + if targetList is null then + set targetList to my everyTargetWithBuildFilePath(_project, full path of modelItr) + end if + repeat with targetIndex from 1 to (count of targetList) + set targetItr to item targetIndex of targetList + add modelSrcFileRef to targetItr + end repeat + end if + end tell + end repeat + end tell +end addFilesFromPathToGroup + +property ASDScriptUniqueIdentifier : "Xmod.applescript"