Merge pull request #12 from paulcastro/issue_11

Issue 11, Add ability to specify target
diff --git a/WhiskSwiftTools.xcodeproj/project.pbxproj b/WhiskSwiftTools.xcodeproj/project.pbxproj
index d83ba8f..5b170d7 100644
--- a/WhiskSwiftTools.xcodeproj/project.pbxproj
+++ b/WhiskSwiftTools.xcodeproj/project.pbxproj
@@ -259,7 +259,7 @@
 			isa = PBXProject;
 			attributes = {
 				LastSwiftUpdateCheck = 0800;
-				LastUpgradeCheck = 0800;
+				LastUpgradeCheck = 0810;
 				ORGANIZATIONNAME = IBM;
 				TargetAttributes = {
 					D6BC1BF11D4017BE00C2334C = {
@@ -340,8 +340,10 @@
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "-";
@@ -386,8 +388,10 @@
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
 				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
 				CODE_SIGN_IDENTITY = "-";
@@ -406,6 +410,7 @@
 				MACOSX_DEPLOYMENT_TARGET = 10.11;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = macosx;
+				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
 			};
 			name = Release;
 		};
diff --git a/WhiskSwiftTools/ConsoleIO.swift b/WhiskSwiftTools/ConsoleIO.swift
index 589482a..d9e6146 100644
--- a/WhiskSwiftTools/ConsoleIO.swift
+++ b/WhiskSwiftTools/ConsoleIO.swift
@@ -16,13 +16,15 @@
 
 import Foundation
 
-let version = "0.1.0"
+let version = "0.4.0"
 
 enum OptionType: String {
     case Build = "build"
     case Version = "version"
     case Help = "help"
     case Delete = "delete"
+    case Path = "path"
+    case Target = "target"
     case Undefined
     
     init(value: String) {
@@ -39,6 +41,16 @@
             self = .Help
         case "h":
             self = .Help
+        case "path":
+            self = .Path
+        case "p":
+            self = .Path
+        case "target":
+            self = .Target
+        case "t":
+            self = .Target
+
+            
         default:
             self = .Undefined
         }
@@ -53,14 +65,14 @@
         print ("usage:")
         print ("To install a project:")
         print ("=====================")
-        print ("\(executableName) install (for current directory)")
+        print ("\(executableName) install (for current directory) -t <optional target name>")
         print ("or")
-        print ("\(executableName) install <project directory>")
+        print ("\(executableName) install -p <optional project path> -t <optional target name>")
         print ("To uninstall a project:")
         print ("=======================")
-        print ("\(executableName) uninstall (for current directory)")
+        print ("\(executableName) uninstall (for current directory) -t <optional target name>")
         print ("or")
-        print ("\(executableName) uninstall <project directory>")
+        print ("\(executableName) uninstall -p <project directory> -t <optional target name>")
         
         print ("Type \(executableName) -h or --help to show usage information")
     }
diff --git a/WhiskSwiftTools/PBXProject.swift b/WhiskSwiftTools/PBXProject.swift
index 016509f..4d39eb7 100644
--- a/WhiskSwiftTools/PBXProject.swift
+++ b/WhiskSwiftTools/PBXProject.swift
@@ -22,7 +22,7 @@
 class PBXProject {
     
     let fullPath: String!
-    let targetName: String!
+    let targetName: String
     var filesForTarget = [String:[String]]()
     
     init(file: String, targetName: String) {
@@ -47,7 +47,7 @@
                     print("PBXParse: Error, line from parseFile is nil, aborting.")
                     return
                 }
-                var trimmedLine = line.trimmingCharacters(in: CharacterSet.whitespaces)
+                let trimmedLine = line.trimmingCharacters(in: CharacterSet.whitespaces)
                 
                 switch parseState {
                 case .inital:
@@ -56,7 +56,7 @@
                         
                     }
                 case .inTarget:
-                    if trimmedLine.range(of: "PBXNativeTarget \"\(targetName!)\" */;") != nil {
+                    if trimmedLine.range(of: "PBXNativeTarget \"\(targetName)\" */;") != nil {
                         parseState = .inNamedTarget
                     }
                 case .inNamedTarget:
diff --git a/WhiskSwiftTools/ProjectManager.swift b/WhiskSwiftTools/ProjectManager.swift
index 424d176..2b7f728 100644
--- a/WhiskSwiftTools/ProjectManager.swift
+++ b/WhiskSwiftTools/ProjectManager.swift
@@ -22,15 +22,17 @@
     let path: String!
     let projectReader: ProjectReader!
     let namespace: String!
+    var target: String?
     
     
-    public init(path: String, repo: String? = nil, release: String? = nil, xcodeDirectory: String? = nil, credentials: WhiskCredentials, namespace: String) {
+    public init(path: String, repo: String? = nil, release: String? = nil, xcodeDirectory: String? = nil, credentials: WhiskCredentials, namespace: String, target: String?) {
         whisk = WhiskAPI(credentials: credentials)
         self.path = path
         self.namespace = namespace
+        self.target = target
         
         do {
-            projectReader = try ProjectReader(path: path, repo: repo, release: release)
+            projectReader = try ProjectReader(path: path, repo: repo, release: release, target: target)
         } catch {
             projectReader = nil
             print("Error creating project \(error)")
@@ -198,7 +200,8 @@
         
         for (name, rule) in rules {
             print("Creating rule \(name)")
-            try whisk.createRule(name: name as String, namespace: namespace, triggerName: rule.trigger as String, actionName: rule.action as String, group: group)
+            
+            try whisk.createRule(name: name as String, namespace: namespace, triggerName: "/\(namespace!)/\(rule.trigger)", actionName: "/\(namespace!)/\(rule.action)" as String, group: group)
         }
         
         switch group.wait(timeout: DispatchTime.distantFuture) {
diff --git a/WhiskSwiftTools/ProjectReader.swift b/WhiskSwiftTools/ProjectReader.swift
index 1573bdd..8124bc4 100644
--- a/WhiskSwiftTools/ProjectReader.swift
+++ b/WhiskSwiftTools/ProjectReader.swift
@@ -94,10 +94,13 @@
     var manifestDict = [NSString: NSString]()
     var bindingsDict = [NSString: NSString]()
     
+    var target: String?
     
     
-    public init(path: String, repo: String? = nil, release: String? = nil) throws  {
+    
+    public init(path: String, repo: String? = nil, release: String? = nil, target: String?) throws  {
         
+        self.target = target
         
         if let repo = repo {
             
@@ -331,7 +334,7 @@
         } else {
             
             print("Found xcode directory \(isXcode.projectName!)" )
-            let xcodeProject = WhiskTokenizer(from: dirPath, to:projectPath, projectFile: isXcode.projectName!)
+            let xcodeProject = WhiskTokenizer(from: dirPath, to:projectPath, projectFile: isXcode.projectName!, target: target)
             
             do {
                 let xcodeTuple = try xcodeProject.readXCodeProjectDirectory()
diff --git a/WhiskSwiftTools/WhiskInstaller.swift b/WhiskSwiftTools/WhiskInstaller.swift
index de08898..4663d0f 100644
--- a/WhiskSwiftTools/WhiskInstaller.swift
+++ b/WhiskSwiftTools/WhiskInstaller.swift
@@ -20,31 +20,65 @@
     
     let consoleIO = ConsoleIO()
     var projectPath: String!
+    var argumentTarget: String? 
     
     init() {
         projectPath = getCurrentDirectory()
     }
     
     func staticMode() {
-        let argCount = CommandLine.argc
+        let argCount = Int(CommandLine.argc)
         let argument = CommandLine.arguments[1]
+        
+        var i = 1
+        var isBuild = true
 
-        if argCount > 2 {
-            projectPath = NSString(string: CommandLine.arguments[2]).expandingTildeInPath as String
+        
+        while (i < argCount) {
+            let arg = CommandLine.arguments[i]
+            
+            var offset = 0
+            if arg.hasPrefix("--") {
+                offset = 2
+            } else if arg.characters.first == "-" {
+                offset = 1
+            }
+            
+            let skipDashIndex = arg.index(argument.startIndex, offsetBy: offset)
+            let (option, _) = consoleIO.getOption(arg.substring(from: skipDashIndex))
+            
+            switch option {
+            case .Build:
+                isBuild = true
+                i = i + 1
+                print("Got build")
+            case .Delete:
+                isBuild = false
+                i = i + 1
+                print("Got delete")
+            case .Path:
+                projectPath = CommandLine.arguments[i+1]
+                i = i + 2
+                print("Got path \(projectPath)")
+            case .Target:
+                argumentTarget = CommandLine.arguments[i+1]
+                i = i + 2
+                print("Got target \(argumentTarget)")
+            case .Version:
+                ConsoleIO.printVersion()
+                i = i + 1
+            case .Help:
+                ConsoleIO.printUsage()
+                i = i + 1
+            case .Undefined:
+                ConsoleIO.printUsage()
+                i = i + 1
+
+            }
         }
         
-        var offset = 0
-        if argument.hasPrefix("--") {
-            offset = 2
-        } else if argument.characters.first == "-" {
-            offset = 1
-        }
-        
-        let skipDashIndex = argument.index(argument.startIndex, offsetBy: offset)
-        let (option, _) = consoleIO.getOption(argument.substring(from: skipDashIndex))
-        
-        switch option {
-        case .Build:
+        if isBuild == true {
+            
             do {
                 if let pm = try setupProjectManager() {
                     try pm.deployProject()
@@ -54,7 +88,7 @@
             } catch {
                 print("Error installing OpenWhisk project \(error)")
             }
-        case .Delete:
+        } else {
             do {
                 if let pm = try setupProjectManager() {
                     try pm.deleteProject()
@@ -64,13 +98,8 @@
             } catch {
                 print("Error installing OpenWhisk project \(error)")
             }
-        case .Version:
-            ConsoleIO.printVersion()
-        case .Help:
-            ConsoleIO.printUsage()
-        case .Undefined:
-            ConsoleIO.printUsage()
         }
+        
     }
     
     func getCurrentDirectory() -> String {
@@ -97,9 +126,13 @@
                 }
             }
             
+            if namespace == nil {
+                namespace = "_"
+            }
+            
             if let tokens = tokens, let namespace = namespace {
                 let credentials = WhiskCredentials(accessKey: tokens[0], accessToken: tokens[1])
-                return ProjectManager(path: projectPath!, credentials: credentials, namespace: namespace)
+                return ProjectManager(path: projectPath!, credentials: credentials, namespace: namespace, target:argumentTarget)
             }
         } catch {
             print("Error reading ~/.wskprops")
diff --git a/WhiskSwiftTools/WhiskTokenizer.swift b/WhiskSwiftTools/WhiskTokenizer.swift
index 6cb23ad..ecfdf41 100644
--- a/WhiskSwiftTools/WhiskTokenizer.swift
+++ b/WhiskSwiftTools/WhiskTokenizer.swift
@@ -49,27 +49,32 @@
 
 open class WhiskTokenizer {
     
-    let OpenWhiskActionTarget = "OpenWhiskActions"
     
     var atPath: String!
     var toPath: String!
     var projectFileName: NSString!
+    var targetName: String!
     
-    public init(from: String, to: String, projectFile: NSString) {
+    public init(from: String, to: String, projectFile: NSString, target: String? ) {
         atPath = from
         toPath = to
+        if target != nil {
+            targetName = target!
+        } else {
+            targetName = "OpenWhiskActions"
+        }
         self.projectFileName = projectFile
     }
     
-    func readTargetSourceFiles() -> [String] {
-        let pbxProject = PBXProject(file: projectFileName as String, targetName: OpenWhiskActionTarget)
+    func readTargetSourceFiles() -> [String]? {
+        let pbxProject = PBXProject(file: projectFileName as String, targetName: targetName)
         
         var filesForTarget = pbxProject.filesForTarget
         for (target, files) in filesForTarget {
             print("target:\(target), files:\(files)")
         }
         
-        return filesForTarget[OpenWhiskActionTarget]!
+        return filesForTarget[targetName]
     }
     
     open func readXCodeProjectDirectory() throws -> (actions: [Action],triggers: [Trigger], rules: [Rule], sequences: [Sequence]) {
@@ -80,76 +85,81 @@
         var whiskRuleArray = [Rule]()
         var whiskSequenceArray = [Sequence]()
         
-        let fileList = readTargetSourceFiles()
-        
-        if let enumerator: FileManager.DirectoryEnumerator = dir.enumerator(atPath: atPath) {
+        if let fileList = readTargetSourceFiles() {
             
-            while let item = enumerator.nextObject() as? NSString {
+            print("There are \(fileList.count) files for target \(targetName)")
+            
+            if let enumerator: FileManager.DirectoryEnumerator = dir.enumerator(atPath: atPath) {
                 
-                var isDir = ObjCBool(false)
-                let fullPath = atPath+"/\(item)"
-                
-                print("===== inspecting \(item.lastPathComponent)")
-                if dir.fileExists(atPath: fullPath, isDirectory: &isDir) == true {
-                    if isDir.boolValue == true {
-                        
-                    }  else if item.hasSuffix(".swift") {
-                        
-                        if fileList.contains(item.lastPathComponent as String) {
-                            print("****Processing \(item.lastPathComponent)")
-                            do {
-                                let fileStr = try String(contentsOfFile: fullPath)
-                                if let entityTuple = getWhiskEntities(str: fileStr) {
-                                    
-                                    for action in entityTuple.actions {
-                                        do {
-                                            
-                                            let actionDirPath = toPath+"/\(OpenWhiskActionTarget)"
-                                            
-                                            try FileManager.default.createDirectory(atPath: actionDirPath, withIntermediateDirectories: true, attributes: nil)
-                                            
-                                            let actionPath = actionDirPath+"/\(action.actionName).swift"
-                                            
-                                            let fileUrl = URL(fileURLWithPath: actionPath)
-                                            try action.actionCode.write(to: fileUrl, atomically: false, encoding: String.Encoding.utf8)
-                                            
-                                            let whiskAction = Action(name: action.actionName as NSString, path: actionPath as NSString, runtime: Runtime.swift, parameters: nil)
-                                            
-                                            whiskActionArray.append(whiskAction)
-                                            
-                                        } catch {
-                                            print("Error writing actions from Xcode \(error)")
+                while let item = enumerator.nextObject() as? NSString {
+                    
+                    var isDir = ObjCBool(false)
+                    let fullPath = atPath+"/\(item)"
+                    
+                    //print("===== inspecting \(item.lastPathComponent)")
+                    if dir.fileExists(atPath: fullPath, isDirectory: &isDir) == true {
+                        if isDir.boolValue == true {
+                            
+                        }  else if item.hasSuffix(".swift") {
+                            
+                            if fileList.contains(item.lastPathComponent as String) {
+                                print("****Processing \(item.lastPathComponent)")
+                                do {
+                                    let fileStr = try String(contentsOfFile: fullPath)
+                                    if let entityTuple = getWhiskEntities(str: fileStr) {
+                                        
+                                        for action in entityTuple.actions {
+                                            do {
+                                                
+                                                let actionDirPath = toPath+"/\(targetName!)"
+                                                
+                                                try FileManager.default.createDirectory(atPath: actionDirPath, withIntermediateDirectories: true, attributes: nil)
+                                                
+                                                let actionPath = actionDirPath+"/\(action.actionName).swift"
+                                                
+                                                let fileUrl = URL(fileURLWithPath: actionPath)
+                                                try action.actionCode.write(to: fileUrl, atomically: false, encoding: String.Encoding.utf8)
+                                                
+                                                let whiskAction = Action(name: action.actionName as NSString, path: actionPath as NSString, runtime: Runtime.swift, parameters: nil)
+                                                
+                                                whiskActionArray.append(whiskAction)
+                                                
+                                            } catch {
+                                                print("Error writing actions from Xcode \(error)")
+                                            }
                                         }
+                                        
+                                        for trigger in entityTuple.triggers {
+                                            let whiskTrigger = Trigger(name: trigger.triggerName as NSString, feed: nil, parameters: nil)
+                                            whiskTriggerArray.append(whiskTrigger)
+                                        }
+                                        
+                                        for rule in entityTuple.rules {
+                                            let rule = Rule(name: rule.ruleName as NSString, trigger: rule.triggerName as NSString, action: rule.actionName as NSString)
+                                            whiskRuleArray.append(rule)
+                                        }
+                                        
+                                        for sequence in entityTuple.sequences {
+                                            let seq = Sequence(name: sequence.sequenceName as NSString, actions: sequence.actionNames)
+                                            whiskSequenceArray.append(seq)
+                                        }
+                                        
                                     }
                                     
-                                    for trigger in entityTuple.triggers {
-                                        let whiskTrigger = Trigger(name: trigger.triggerName as NSString, feed: nil, parameters: nil)
-                                        whiskTriggerArray.append(whiskTrigger)
-                                    }
-                                    
-                                    for rule in entityTuple.rules {
-                                        let rule = Rule(name: rule.ruleName as NSString, trigger: rule.triggerName as NSString, action: rule.actionName as NSString)
-                                        whiskRuleArray.append(rule)
-                                    }
-                                    
-                                    for sequence in entityTuple.sequences {
-                                        let seq = Sequence(name: sequence.sequenceName as NSString, actions: sequence.actionNames)
-                                        whiskSequenceArray.append(seq)
-                                    }
-                                    
+                                } catch {
+                                    print("Error \(error)")
                                 }
-                                
-                            } catch {
-                                print("Error \(error)")
                             }
                         }
                     }
+                    
                 }
-                
-                
             }
             
+        } else {
+            print("No files for given target \(targetName!)")
         }
+
         
         return (whiskActionArray, whiskTriggerArray, whiskRuleArray, whiskSequenceArray)
     }
@@ -211,7 +221,7 @@
                         let actionName = actionStr[1].replacingOccurrences(of: "(", with: "").replacingOccurrences(of: ")", with: "").trimmingCharacters(in: .whitespaces)
                         
                         
-
+                        
                         print("Got trigger:\(triggerName), action:\(actionName)")
                         
                         let rule = RuleToken(ruleName: ruleName, triggerName: triggerName, actionName: actionName)
diff --git a/WhiskSwiftTools/main.swift b/WhiskSwiftTools/main.swift
index 76790c5..2cc98c2 100644
--- a/WhiskSwiftTools/main.swift
+++ b/WhiskSwiftTools/main.swift
@@ -26,4 +26,3 @@
 
 
 
-