Skip to content

Commit fe00b6c

Browse files
committed
allow array option to be a string with commas
1 parent b293adb commit fe00b6c

File tree

8 files changed

+40
-14
lines changed

8 files changed

+40
-14
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@ Options are structured input for the `Stencil` templates. They serve as document
153153
- `string` a simple string
154154
- `boolean` a boolean
155155
- `choice` a string from a list of choices. Requires `choices` to be defined
156-
- `array` an array of other options. Requires `options` to be defined.
156+
- `array` an array of other options. If child `options` are defined, if will be an array of options, otherwise it will split a string by command, removing any whitespace between
157+
- **options**: An array of child options. Used if the `array` type contains objects
157158
158159
#### Files
159160

Sources/GenesisKit/Option.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public struct Option: Equatable, Decodable {
1111
public var set: String
1212
public var choices: [String]
1313
public var childType: OptionType?
14-
public var options: [Option]
14+
public var options: [Option]?
1515

1616
public enum OptionType: String, Decodable {
1717
case string
@@ -20,7 +20,7 @@ public struct Option: Equatable, Decodable {
2020
case array
2121
}
2222

23-
public init(name: String, description: String? = nil, value: String? = nil, type: OptionType = .string, set: String? = nil, question: String? = nil, required: Bool = false, choices: [String] = [], branch: [String: TemplateSection] = [:], options: [Option] = []) {
23+
public init(name: String, description: String? = nil, value: String? = nil, type: OptionType = .string, set: String? = nil, question: String? = nil, required: Bool = false, choices: [String] = [], branch: [String: TemplateSection] = [:], options: [Option]? = nil) {
2424
self.name = name
2525
self.value = value
2626
self.description = description
@@ -61,6 +61,6 @@ public struct Option: Equatable, Decodable {
6161
required = try container.decodeIfPresent(Bool.self, forKey: .required) ?? false
6262
question = try container.decodeIfPresent(String.self, forKey: .question)
6363
branch = try container.decodeIfPresent([String: TemplateSection].self, forKey: .branch) ?? [:]
64-
options = try container.decodeIfPresent([Option].self, forKey: .options) ?? []
64+
options = try container.decodeIfPresent([Option].self, forKey: .options)
6565
}
6666
}

Sources/GenesisKit/TemplateGenerator.swift

+26-10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ public class TemplateGenerator {
3232
}
3333

3434
fileprivate func getOptionValue(_ option: Option, context: inout Context) throws {
35+
defer {
36+
switch option.type {
37+
case .array:
38+
// split string into array
39+
if let value = context[option.name] as? String, option.options == nil {
40+
context[option.name] = value.split(separator: ",").map { $0.trimmingCharacters(in: .whitespaces) }
41+
}
42+
default:
43+
break
44+
}
45+
}
46+
3547
if context[option.name] != nil {
3648
// found existing option
3749
return
@@ -58,19 +70,23 @@ public class TemplateGenerator {
5870
case .string: context[option.name] = Input.readLine(prompt: question)
5971
case .boolean: context[option.name] = Input.readBool(prompt: question)
6072
case .array:
61-
var array: [Context] = []
62-
func addItem() throws {
63-
if Input.readBool(prompt: question) {
64-
var childContext = Context()
65-
for childOption in option.options {
66-
try getOptionValue(childOption, context: &childContext)
73+
if let options = option.options {
74+
var array: [Context] = []
75+
func addItem() throws {
76+
if Input.readBool(prompt: question) {
77+
var childContext = Context()
78+
for childOption in options {
79+
try getOptionValue(childOption, context: &childContext)
80+
}
81+
array.append(childContext)
82+
context[option.name] = array
83+
try addItem()
6784
}
68-
array.append(childContext)
69-
context[option.name] = array
70-
try addItem()
7185
}
86+
try addItem()
87+
} else {
88+
context[option.name] = Input.readLine(prompt: question)
7289
}
73-
try addItem()
7490
}
7591

7692
answers.append(Answer(question: question, answer: context[option.name] as Any))

Tests/Fixtures/Project.stencil

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11

22
Name: {{project}}
33
Some content
4+
{% for name in names %}
5+
- {{ name }}
6+
{% endfor %}
+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11

22
Name: MyProject
33
Some content
4+
- Sarah
5+
- Stephen

Tests/Fixtures/template.yml

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ options:
2929
required: true
3030
type: string
3131
value: Parent/Child
32+
- name: names
33+
type: array
3234
files:
3335
- template: Project.stencil
3436
path: "{{ project }}.swift"

Tests/GenesisKitTests/TemplateTests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class TemplateTests: XCTestCase {
2424
Option(name: "generate", value: "true", type: .boolean, question: "Should this be generated?"),
2525
]),
2626
Option(name: "path", description: "The name of the path to App directory", value: "Parent/Child", type: .string, question: "What is the name of the path for App directory?", required: true),
27+
Option(name: "names", type: .array),
2728
]
2829
let expectedTemplate = GenesisTemplate(
2930
path: templateFixture,

Tests/GenesisKitTests/WritingTests.swift

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class WritingTests: XCTestCase {
1919
]
2020
],
2121
"path": "App/Child",
22+
"names": "Sarah, Stephen"
2223
]
2324
let result = try generator.generate(context: context, interactive: false)
2425
try result.writeFiles(path: fixturePath + "generated")

0 commit comments

Comments
 (0)