@@ -30,108 +30,200 @@ import SPMUtility
3030public struct CLIArguments {
3131
3232 public enum UserCommand {
33- case delete
34- case view
35- case newEntry( entry: String )
33+ case viewState
34+ case outputPrefixes
35+ case deletePrefixes
36+ case modeNormal
37+ case modeBranchParse( validator: String )
38+ case newPrefixes( value: String )
39+ }
40+
41+ private enum ParsedCommand {
42+ case viewState
43+ case outputPrefixes
44+ case deletePrefixes
45+ case modeNormal
46+ case modeBranchParse
47+ case userEntry( value: String )
3648 }
3749
3850 private let parser : ArgumentParser
3951 private let rawArgs : [ String ]
4052
41- private let delete : OptionArgument < Bool >
42- private let view : OptionArgument < Bool >
43- private let newEntry : PositionalArgument < [ String ] >
53+ private let outputPrefixes : OptionArgument < Bool >
54+ private let deletePrefixes : OptionArgument < Bool >
55+ private let modeNormal : OptionArgument < Bool >
56+ private let modeBranchParse : OptionArgument < Bool >
57+ private let userEntry : PositionalArgument < [ String ] >
4458
4559 public init ( arguments: [ String ] = CommandLine . arguments) {
4660 // The first argument specifies the path of the executable file
4761 self . rawArgs = Array ( arguments. dropFirst ( ) )
4862 let argBuilder = ArgumentBuilder ( )
4963 self . parser = argBuilder. buildParser ( )
50- self . delete = argBuilder. buildDeleteArgument ( parser: parser)
51- self . view = argBuilder. buildViewArgument ( parser: parser)
52- self . newEntry = argBuilder. buildNewEntryArgument ( parser: parser)
64+
65+ self . outputPrefixes = argBuilder. buildOutputArgument ( parser: parser)
66+ self . deletePrefixes = argBuilder. buildDeleteArgument ( parser: parser)
67+ self . modeNormal = argBuilder. buildNormalArgument ( parser: parser)
68+ self . modeBranchParse = argBuilder. buildBranchParseArgument ( parser: parser)
69+ self . userEntry = argBuilder. buildUserEntryArgument ( parser: parser)
5370 }
5471
72+ private func singleCommandParse( _ allCommands: [ ParsedCommand ] ) throws -> UserCommand {
73+ precondition ( allCommands. count == 1 , " Intended for single Parsed Command only! " )
74+ guard let foundCommand = allCommands. first else {
75+ throw CPError . userCommandNotRecognized
76+ }
77+
78+ switch foundCommand {
79+ case . outputPrefixes:
80+ return . outputPrefixes
81+ case . deletePrefixes:
82+ return . deletePrefixes
83+ case . modeNormal:
84+ return . modeNormal
85+ case . userEntry( value: let prefixes) :
86+ return . newPrefixes( value: prefixes)
87+ default :
88+ throw CPError . userCommandNotRecognized
89+ }
90+ }
91+
92+ private func doubleCommandParse( _ allCommands: [ ParsedCommand ] ) throws -> UserCommand {
93+ precondition ( allCommands. count == 2 , " Intended for two Parsed Commands only! " )
94+ let firstCommand = allCommands [ 0 ]
95+ let secondCommand = allCommands [ 1 ]
96+
97+ switch ( firstCommand, secondCommand) {
98+ case ( . modeBranchParse, . userEntry( value: let validator) ) :
99+ return . modeBranchParse( validator: validator)
100+ case ( . userEntry( value: let validator) , . modeBranchParse) :
101+ return . modeBranchParse( validator: validator)
102+ default :
103+ throw CPError . userCommandNotRecognized
104+ }
105+ }
106+
55107 func getCommand( ) throws -> UserCommand {
56108 guard let parsedArgs = try ? parser. parse ( rawArgs) else {
57109 throw CPError . userCommandNotRecognized
58110 }
59111
60- var allCommands = [ UserCommand ] ( )
112+ var allCommands = [ ParsedCommand ] ( )
61113
62- parsedArgs. get ( delete) . map { _ in allCommands. append ( . delete) }
63- parsedArgs. get ( view) . map { _ in allCommands. append ( . view) }
64- try parsedArgs. get ( newEntry) . map { userEntry in
65-
66- guard userEntry. count < 2 else {
67- throw CPError . newEntryShouldNotHaveSpaces
68- }
69-
70- guard let theEntry = userEntry. first else {
71- throw CPError . emptyEntry
72- }
73-
74- guard !theEntry. isEmpty else {
75- throw CPError . emptyEntry
76- }
77-
78- allCommands. append ( . newEntry( entry: theEntry) )
79-
80- }
114+ parsedArgs. get ( outputPrefixes) . map { _ in allCommands. append ( . outputPrefixes) }
115+ parsedArgs. get ( deletePrefixes) . map { _ in allCommands. append ( . deletePrefixes) }
116+ parsedArgs. get ( modeNormal) . map { _ in allCommands. append ( . modeNormal) }
117+ parsedArgs. get ( modeBranchParse) . map { _ in allCommands. append ( . modeBranchParse) }
81118
82- guard allCommands. count < 2 else {
83- throw CPError . multipleArguments
119+ try parsedArgs. get ( userEntry) . map { userEntry in
120+ let noMoreThanOneEntry = userEntry. count < 2
121+ guard noMoreThanOneEntry else { throw CPError . newEntryShouldNotHaveSpaces }
122+ guard let theEntry = userEntry. first else { throw CPError . emptyEntry }
123+ allCommands. append ( . userEntry( value: theEntry) )
84124 }
85125
86- guard let command = allCommands. first else {
87- throw CPError . userCommandNotRecognized
126+ switch allCommands. count {
127+ case 0 :
128+ return . viewState
129+ case 1 :
130+ return try singleCommandParse ( allCommands)
131+ case 2 :
132+ return try doubleCommandParse ( allCommands)
133+ default :
134+ throw CPError . multipleArguments
88135 }
89136
90- return command
91137 }
92138
93139}
94140
95141private struct ArgumentBuilder {
96142
97143 let usage : String = """
98- <Commit Prefix Description>
144+ [<PrefixValue1>,<PrefixValue2>,<PrefixValue3>...] [-o | --output] [-d | --delete]
145+ [-n | -normal] [ -b | --branchParse <ValidatorValue> ]
99146 """
100147
101148 let overview : String = """
102- The CommitPrefix stores a desired prefix for your commit messages.
103- It stores it within the .git folder of the current repository. A
104- commit-msg hook is also generated and stored within the .git
105- folder which is used to prefix the commit message.
149+
150+ The CommitPrefix stores a desired set of prefixes for your commit messages. It
151+ stores it within the .git folder of the current repository. A commit-msg hook is
152+ also generated and stored within the .git folder which is used to prefix the
153+ commit message.
154+
155+ Modes:
156+ CommitPrefix has two modes, normal and branch parse.
157+
158+ - NORMAL
159+ example: commitPrefix <PrefixValue1>,<PrefixValue2>,<PrefixValue3>...
160+
161+ You can add normal prefixes by entering comma seperated values. These values will
162+ be parsed as prefixes and prepended to future commit messages.
163+
164+ - BRANCH_PARSE
165+ example commitPrefix -b <ValidatorValue>
166+
167+ Branch parse mode checks the current branch for an issue number validated by the
168+ value passed in as an argument. For example if you passed in a validator value of
169+ " eng " and your current branch was named ENG-342-SomeFeatureBranchLinkedToENG-101,
170+ commitPrefix will pickup [ENG-342] and [ENG-101] as branch prefixes to be
171+ prepended to you next commit along with any other normal prefixes you might have.
172+
173+ You can change back to NORMAL mode by entering:
174+ example: commitPrefix -n
175+
176+ To view the current state of prefixes and mode, enter:
177+ example: commitPrefix
106178 """
107179
108180 func buildParser( ) -> ArgumentParser {
109181 ArgumentParser ( usage: usage, overview: overview)
110182 }
111-
183+
184+ func buildOutputArgument( parser: ArgumentParser ) -> OptionArgument < Bool > {
185+ return parser. add (
186+ option: " --output " ,
187+ shortName: " -o " ,
188+ kind: Bool . self,
189+ usage: " Outputs the full, formated prefix to standard output " ,
190+ completion: nil
191+ )
192+ }
193+
112194 func buildDeleteArgument( parser: ArgumentParser ) -> OptionArgument < Bool > {
113195 return parser. add (
114196 option: " --delete " ,
115197 shortName: " -d " ,
116198 kind: Bool . self,
117- usage: " Deletes the stored prefix " ,
199+ usage: " Deletes the stored prefixes " ,
118200 completion: nil
119201 )
120202 }
121203
122- func buildViewArgument( parser: ArgumentParser ) -> OptionArgument < Bool > {
204+ func buildNormalArgument( parser: ArgumentParser ) -> OptionArgument < Bool > {
205+ return parser. add (
206+ option: " --normal " ,
207+ shortName: " -n " ,
208+ kind: Bool . self,
209+ usage: " Sets the mode to NORMAL " ,
210+ completion: nil
211+ )
212+ }
213+
214+ func buildBranchParseArgument( parser: ArgumentParser ) -> OptionArgument < Bool > {
123215 return parser. add (
124- option: " --view " ,
125- shortName: " -v " ,
216+ option: " --branchParse " ,
217+ shortName: " -b " ,
126218 kind: Bool . self,
127- usage: " Display the currently stored prefix " ,
219+ usage: " Sets the mode to BRANCH_PARSE. Requires a validator argument " ,
128220 completion: nil
129221 )
130222 }
131223
132- func buildNewEntryArgument ( parser: ArgumentParser ) -> PositionalArgument < [ String ] > {
224+ func buildUserEntryArgument ( parser: ArgumentParser ) -> PositionalArgument < [ String ] > {
133225 return parser. add (
134- positional: " NewEntry " ,
226+ positional: " UserEntry " ,
135227 kind: [ String ] . self,
136228 optional: true ,
137229 usage: nil ,
0 commit comments