gene_system 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::Commands::PrintVersion do
4
+ let(:options) { double }
5
+
6
+ subject { described_class.new(options) }
7
+
8
+ describe '#run' do
9
+ before do
10
+ allow(subject).to receive(:puts)
11
+ subject.run
12
+ end
13
+
14
+ it 'prints version' do
15
+ expect(subject)
16
+ .to have_received(:puts)
17
+ .with(GeneSystem::VERSION)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,258 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GeneSystem::Commands::RemoveManifest do
4
+ let(:options) { Hashie::Mash.new }
5
+ let(:prompt) { double(TTY::Prompt) }
6
+ let(:version) { '1.0.0' }
7
+ let(:execute_command_result) { 0 }
8
+ let(:manifest_name) { 'some manifest' }
9
+
10
+ subject { described_class.new(options) }
11
+
12
+ before do
13
+ subject.instance_variable_set(:@prompt, prompt)
14
+ end
15
+
16
+ describe '#run' do
17
+ let(:platform) { double(GeneSystem::Platform) }
18
+
19
+ let(:manifest) do
20
+ double(
21
+ GeneSystem::Manifest,
22
+ name: manifest_name,
23
+ name_and_version: "#{manifest_name} v#{version}"
24
+ )
25
+ end
26
+
27
+ let(:skip_command) { 'false' }
28
+ let(:prompts) { [prompt_definition, prompt_definition] }
29
+ let(:prompt_definition) do
30
+ {
31
+ "prompt": 'Please enter your name',
32
+ "var": 'name'
33
+ }
34
+ end
35
+ let(:cmd) { 'echo {{name}}' }
36
+ let(:cmds) do
37
+ [
38
+ cmd
39
+ ]
40
+ end
41
+
42
+ let(:step_definition) do
43
+ {
44
+ "name": 'some step',
45
+ "exe": {
46
+ "remove": {
47
+ "skip": skip_command,
48
+ "prompts": prompts,
49
+ "cmd": cmds
50
+ }
51
+ }
52
+ }
53
+ end
54
+
55
+ let(:step) do
56
+ GeneSystem::Step.new(step_definition)
57
+ end
58
+
59
+ before do
60
+ allow(GeneSystem::Manifest)
61
+ .to receive(:new_from_file)
62
+ .and_return(manifest)
63
+
64
+ allow(GeneSystem::Platform)
65
+ .to receive(:new)
66
+ .and_return(platform)
67
+
68
+ allow(manifest)
69
+ .to receive(:steps)
70
+ .and_return([step, step])
71
+
72
+ allow(manifest)
73
+ .to receive(:version)
74
+ .and_return(version)
75
+
76
+ allow(manifest)
77
+ .to receive(:variables)
78
+ .and_return({})
79
+
80
+ allow(platform)
81
+ .to receive(:execute_commands)
82
+
83
+ allow(platform)
84
+ .to receive(:execute_command)
85
+ .and_return(execute_command_result)
86
+
87
+ allow(prompt).to receive(:ask).and_return(prompt_response)
88
+ allow(subject).to receive(:puts)
89
+ end
90
+
91
+ context 'when manifest path is provided' do
92
+ let(:manifest_path) { 'provided/path/to/manifest.json' }
93
+ let(:execute_command_result) { 1 }
94
+ let(:prompt_response) { 'Jon' }
95
+ let(:options) do
96
+ Hashie::Mash.new(
97
+ manifest: manifest_path
98
+ )
99
+ end
100
+
101
+ before do
102
+ subject.run
103
+ end
104
+
105
+ it 'loads manifest from expected file' do
106
+ expect(GeneSystem::Manifest)
107
+ .to have_received(:new_from_file)
108
+ .with(manifest_path)
109
+ end
110
+
111
+ it 'prints remove message' do
112
+ expect(subject)
113
+ .to have_received(:puts)
114
+ .with("REMOVE #{manifest_name} v#{version}")
115
+ end
116
+
117
+ describe 'skip steps' do
118
+ context 'when there is a skip command defined' do
119
+ it 'checks whether it should skip any steps' do
120
+ expect(platform)
121
+ .to have_received(:execute_command)
122
+ .with(skip_command).twice
123
+ end
124
+ end
125
+
126
+ context 'when there is no skip command defined' do
127
+ let(:step_definition) do
128
+ {
129
+ "name": 'some step',
130
+ "exe": {
131
+ "remove": {
132
+ "skip": nil,
133
+ "cmd": []
134
+ }
135
+ }
136
+ }
137
+ end
138
+
139
+ it 'does not try to run nil command' do
140
+ expect(platform)
141
+ .not_to have_received(:execute_command)
142
+ end
143
+ end
144
+
145
+ context 'when the skip command returns non zero' do
146
+ let(:execute_command_result) { 1 }
147
+ let(:prompts) { [] }
148
+
149
+ it 'does not execute step' do
150
+ expect(platform)
151
+ .not_to have_received(:execute_command)
152
+ .with(cmd)
153
+ end
154
+ end
155
+ end
156
+
157
+ describe 'prompting user for input' do
158
+ context 'when there are no prompts' do
159
+ let(:prompts) { [] }
160
+
161
+ it 'does not ask user for input' do
162
+ expect(prompt)
163
+ .not_to have_received(:ask)
164
+ end
165
+ end
166
+
167
+ context 'when there are prompts' do
168
+ it 'asks user for input' do
169
+ expect(prompt)
170
+ .to have_received(:ask)
171
+ .with('Please enter your name').exactly(4).times
172
+ end
173
+ end
174
+ end
175
+
176
+ it 'executes step commands' do
177
+ expect(platform)
178
+ .to have_received(:execute_commands)
179
+ .with(cmds, 'name' => prompt_response).twice
180
+ end
181
+
182
+ it 'prints success message' do
183
+ expect(subject)
184
+ .to have_received(:puts)
185
+ .with("✔ Manifest #{manifest_name} v#{version} successfully removed")
186
+ end
187
+ end
188
+
189
+ context 'when the manifest name is not provided' do
190
+ let(:prompt_response) { '/path/to/manifest.json' }
191
+
192
+ before do
193
+ allow(prompt)
194
+ .to receive(:ask)
195
+ .and_return(prompt_response)
196
+
197
+ subject.run
198
+ end
199
+
200
+ describe 'prompting user for manifest path' do
201
+ it 'prompts user for manifest path' do
202
+ expect(prompt)
203
+ .to have_received(:ask)
204
+ .with(
205
+ 'Please enter the path to the configuration manifest',
206
+ default: 'manifest.json'
207
+ )
208
+ end
209
+ end
210
+
211
+ describe 'skipping steps' do
212
+ context 'when there is a skip command defined' do
213
+ it 'checks whether it should skip any steps' do
214
+ expect(platform)
215
+ .to have_received(:execute_command)
216
+ .with(skip_command).twice
217
+ end
218
+ end
219
+
220
+ context 'when there is no skip command defined' do
221
+ let(:step_definition) do
222
+ {
223
+ "name": 'some step',
224
+ "exe": {
225
+ "remove": {
226
+ "skip": nil,
227
+ "cmd": []
228
+ }
229
+ }
230
+ }
231
+ end
232
+
233
+ it 'does not try to run nil command' do
234
+ expect(platform)
235
+ .not_to have_received(:execute_command)
236
+ end
237
+ end
238
+
239
+ context 'when the skip command returns non zero' do
240
+ let(:execute_command_result) { 1 }
241
+ let(:prompts) { [] }
242
+
243
+ it 'does not execute step' do
244
+ expect(platform)
245
+ .not_to have_received(:execute_command)
246
+ .with(cmd)
247
+ end
248
+ end
249
+ end
250
+
251
+ it 'prints success message' do
252
+ expect(subject)
253
+ .to have_received(:puts)
254
+ .with("✔ Manifest #{manifest_name} v#{version} successfully removed")
255
+ end
256
+ end
257
+ end
258
+ end
@@ -36,7 +36,7 @@ RSpec.describe GeneSystem::Generators do
36
36
  let(:name) { 'new_dev_setup' }
37
37
  let(:path) { 'path/to/manifests' }
38
38
 
39
- let(:manifest_path) { File.join(path, "#{name}.json") }
39
+ let(:manifest_path) { File.join(path, name) }
40
40
  let(:manifest_file) { double }
41
41
 
42
42
  let(:manifest) { 'manifest' }
@@ -66,6 +66,24 @@ RSpec.describe GeneSystem::Manifest do
66
66
  end
67
67
  end
68
68
 
69
+ context 'when manifest is missing required attributes' do
70
+ let(:content) do
71
+ {
72
+ "steps": []
73
+ }.to_json
74
+ end
75
+
76
+ it 'raises missing required error' do
77
+ expect do
78
+ described_class.new_from_file(file_path)
79
+ end.to raise_error(
80
+ RuntimeError,
81
+ 'manifest is missing required attributes name, '\
82
+ 'version and/or metadata'
83
+ )
84
+ end
85
+ end
86
+
69
87
  context 'when manifest is from a later version of gene_system' do
70
88
  let(:gene_system_meta) do
71
89
  {
@@ -114,6 +132,26 @@ RSpec.describe GeneSystem::Manifest do
114
132
  end
115
133
  end
116
134
 
135
+ describe '#name_and_version' do
136
+ let(:path) { 'path/to/manifest.json' }
137
+
138
+ let(:data) do
139
+ {
140
+ 'name' => 'test_manifest',
141
+ 'version' => '0.1.0',
142
+ 'steps' => []
143
+ }
144
+ end
145
+
146
+ before do
147
+ @manifest = described_class.new(path, data)
148
+ end
149
+
150
+ it 'returns name and version' do
151
+ expect(@manifest.name_and_version).to eq 'test_manifest v0.1.0'
152
+ end
153
+ end
154
+
117
155
  describe '#version' do
118
156
  let(:path) { 'path/to/manifest.json' }
119
157
 
@@ -236,4 +274,34 @@ RSpec.describe GeneSystem::Manifest do
236
274
  end
237
275
  end
238
276
  end
277
+
278
+ describe '#variables' do
279
+ let(:path) { 'path/to/manifest.json' }
280
+ let(:metadata) do
281
+ {
282
+ 'gene_system' => {
283
+ 'version' => '0.3.2'
284
+ }
285
+ }
286
+ end
287
+
288
+ let(:data) do
289
+ {
290
+ 'name' => 'test_manifest',
291
+ 'version' => '0.1.0',
292
+ 'metadata' => metadata,
293
+ 'steps' => []
294
+ }
295
+ end
296
+
297
+ before do
298
+ @manifest = described_class.new(path, data)
299
+ end
300
+
301
+ it 'returns hashie mash with manifest information' do
302
+ expect(@manifest.variables.manifest.name).to eq 'test_manifest'
303
+ expect(@manifest.variables.manifest.version).to eq '0.1.0'
304
+ expect(@manifest.variables.manifest.metadata).to eq metadata
305
+ end
306
+ end
239
307
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gene_system
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Bigger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-14 00:00:00.000000000 Z
11
+ date: 2021-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: thor
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tty-prompt
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: bump
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -278,6 +306,7 @@ description:
278
306
  email:
279
307
  - andrew.bigger@gmail.com
280
308
  executables:
309
+ - gene_system
281
310
  - genesystem
282
311
  extensions: []
283
312
  extra_rdoc_files: []
@@ -293,19 +322,28 @@ files:
293
322
  - LICENSE
294
323
  - README.md
295
324
  - Rakefile
325
+ - bin/gene_system
296
326
  - bin/genesystem
297
327
  - data/manifest.jsonnet
298
328
  - gene_system.gemspec
299
329
  - lib/gene_system.rb
300
330
  - lib/gene_system/cli.rb
301
- - lib/gene_system/cli/commands.rb
331
+ - lib/gene_system/commands.rb
332
+ - lib/gene_system/commands/create_manifest.rb
333
+ - lib/gene_system/commands/install_manifest.rb
334
+ - lib/gene_system/commands/print_version.rb
335
+ - lib/gene_system/commands/remove_manifest.rb
302
336
  - lib/gene_system/generators.rb
303
337
  - lib/gene_system/manifest.rb
304
338
  - lib/gene_system/platform.rb
305
339
  - lib/gene_system/step.rb
306
340
  - lib/gene_system/version.rb
307
- - spec/gene_system/cli/commands_spec.rb
341
+ - manifest.json
308
342
  - spec/gene_system/cli_spec.rb
343
+ - spec/gene_system/commands/create_manifest_spec.rb
344
+ - spec/gene_system/commands/install_manifest_spec.rb
345
+ - spec/gene_system/commands/print_version_spec.rb
346
+ - spec/gene_system/commands/remove_manifest_spec.rb
309
347
  - spec/gene_system/generators_spec.rb
310
348
  - spec/gene_system/manifest_spec.rb
311
349
  - spec/gene_system/platform_spec.rb
@@ -333,10 +371,13 @@ requirements: []
333
371
  rubygems_version: 3.0.3
334
372
  signing_key:
335
373
  specification_version: 4
336
- summary: System configuration tool for applying personal settings to a new machine.
374
+ summary: System configuration tool for applying settings
337
375
  test_files:
338
- - spec/gene_system/cli/commands_spec.rb
339
376
  - spec/gene_system/cli_spec.rb
377
+ - spec/gene_system/commands/create_manifest_spec.rb
378
+ - spec/gene_system/commands/install_manifest_spec.rb
379
+ - spec/gene_system/commands/print_version_spec.rb
380
+ - spec/gene_system/commands/remove_manifest_spec.rb
340
381
  - spec/gene_system/generators_spec.rb
341
382
  - spec/gene_system/manifest_spec.rb
342
383
  - spec/gene_system/platform_spec.rb
@@ -1,109 +0,0 @@
1
- require 'highline'
2
-
3
- module GeneSystem
4
- module CLI
5
- # CLI Actions
6
- module Commands
7
- class <<self
8
- ##
9
- # Creates a new, blank manifest with at the specified
10
- # destination with the given name
11
- #
12
- # It is expected that the first argument provided to the
13
- # command will be the name of the manifest. If this is not
14
- # provided then a RuntimeError will be raised.
15
- #
16
- # @param dest [String]
17
- # @param args [Array]
18
- #
19
- def new(args = [])
20
- manifest_name = args.shift
21
-
22
- raise 'no manifest name provided' unless manifest_name
23
-
24
- GeneSystem::Generators.render_empty_manifest(
25
- manifest_name,
26
- Dir.pwd
27
- )
28
- end
29
-
30
- ##
31
- # Applies install instructions from a manifest to the host system
32
- #
33
- # @param args [Array]
34
- #
35
- def install(args = [])
36
- manifest = load_manifest(args)
37
- platform = GeneSystem::Platform.new
38
-
39
- manifest.steps.each do |step|
40
- next if skip?(step, platform)
41
-
42
- vars = ask(step.install.prompts)
43
- platform.execute_commands(step.install.cmd, vars)
44
- end
45
-
46
- GeneSystem::CLI.print_message("\nmanifest successfully installed")
47
- end
48
-
49
- ##
50
- # Asks for user input when given prompts
51
- #
52
- # @param prompts [Array]
53
- #
54
- # @return Hashie::Mash
55
- #
56
- def ask(prompts = [])
57
- answers = Hashie::Mash.new
58
- return answers if prompts.nil?
59
-
60
- cli = HighLine.new
61
-
62
- prompts.each do |prompt|
63
- resp = cli.ask(prompt.prompt)
64
- answers[prompt.var] = resp
65
- end
66
-
67
- answers
68
- end
69
-
70
- ##
71
- # Applies remove instructions from a manifest to the host system
72
- #
73
- # @param args [Array]
74
- #
75
- def remove(args = [])
76
- manifest = load_manifest(args)
77
- platform = GeneSystem::Platform.new
78
-
79
- manifest.steps.each do |step|
80
- platform.execute_commands(step.remove.cmd)
81
- end
82
-
83
- GeneSystem::CLI.print_message("\nmanifest successfully removed")
84
- end
85
-
86
- private
87
-
88
- def load_manifest(args)
89
- manifest_rel = args.shift
90
- raise 'no manifest path provided' unless manifest_rel
91
-
92
- manifest_path = File.join(Dir.pwd, manifest_rel)
93
-
94
- unless File.exist?(manifest_path)
95
- raise "cannot find manifest at #{manifest_path}"
96
- end
97
-
98
- GeneSystem::Manifest.new_from_file(manifest_path)
99
- end
100
-
101
- def skip?(step, platform)
102
- return false if step.install.skip.nil?
103
-
104
- platform.execute_command(step.install.skip).zero?
105
- end
106
- end
107
- end
108
- end
109
- end