app_archetype 1.2.8 → 1.3.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +36 -9
  3. data/README.md +150 -28
  4. data/app_archetype.gemspec +3 -0
  5. data/bin/app_archetype +20 -0
  6. data/bin/archetype +1 -1
  7. data/lib/app_archetype/cli.rb +171 -139
  8. data/lib/app_archetype/commands/delete_template.rb +58 -0
  9. data/lib/app_archetype/commands/find_templates.rb +66 -0
  10. data/lib/app_archetype/commands/list_templates.rb +49 -0
  11. data/lib/app_archetype/commands/new_template.rb +42 -0
  12. data/lib/app_archetype/commands/open_manifest.rb +48 -0
  13. data/lib/app_archetype/commands/print_path.rb +20 -0
  14. data/lib/app_archetype/commands/print_template_variables.rb +67 -0
  15. data/lib/app_archetype/commands/print_version.rb +19 -0
  16. data/lib/app_archetype/commands/render_template.rb +178 -0
  17. data/lib/app_archetype/commands.rb +13 -0
  18. data/lib/app_archetype/generators.rb +1 -1
  19. data/lib/app_archetype/template_manager.rb +9 -0
  20. data/lib/app_archetype/version.rb +1 -1
  21. data/lib/app_archetype.rb +40 -23
  22. data/scripts/create_new_command +32 -0
  23. data/scripts/generators/command/manifest.json +15 -0
  24. data/scripts/generators/command/template/lib/app_archetype/commands/{{command_name.snake_case}}.rb.hbs +17 -0
  25. data/spec/app_archetype/cli/presenters_spec.rb +99 -99
  26. data/spec/app_archetype/cli/prompts_spec.rb +291 -291
  27. data/spec/app_archetype/cli_spec.rb +427 -65
  28. data/spec/app_archetype/commands/delete_template_spec.rb +132 -0
  29. data/spec/app_archetype/commands/find_templates_spec.rb +130 -0
  30. data/spec/app_archetype/commands/list_templates_spec.rb +55 -0
  31. data/spec/app_archetype/commands/new_template_spec.rb +84 -0
  32. data/spec/app_archetype/commands/open_manifest_spec.rb +113 -0
  33. data/spec/app_archetype/commands/print_path_spec.rb +22 -0
  34. data/spec/app_archetype/commands/print_template_variables_spec.rb +158 -0
  35. data/spec/app_archetype/commands/print_version_spec.rb +21 -0
  36. data/spec/app_archetype/commands/render_template_spec.rb +479 -0
  37. data/spec/app_archetype/generators_spec.rb +1 -1
  38. data/spec/app_archetype/template_manager_spec.rb +32 -0
  39. data/spec/app_archetype_spec.rb +65 -0
  40. metadata +79 -4
  41. data/lib/app_archetype/cli/presenters.rb +0 -106
  42. data/lib/app_archetype/cli/prompts.rb +0 -152
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::FindTemplates do
4
+ let(:manager) { double(AppArchetype::TemplateManager) }
5
+ let(:options) { Hashie::Mash.new }
6
+ let(:prompt) { double(TTY::Prompt) }
7
+
8
+ subject { described_class.new(manager, options) }
9
+
10
+ before do
11
+ subject.instance_variable_set(:@prompt, prompt)
12
+ end
13
+
14
+ describe '#run' do
15
+ let(:prompt_response) { nil }
16
+ let(:found_manifests) { [] }
17
+
18
+ let(:manifest_name) { 'some-template' }
19
+ let(:manifest_version) { '1.0.0' }
20
+
21
+ let(:manifest) do
22
+ double(
23
+ AppArchetype::Template::Manifest,
24
+ name: manifest_name,
25
+ version: manifest_version
26
+ )
27
+ end
28
+
29
+ before do
30
+ allow(prompt)
31
+ .to receive(:ask)
32
+ .and_return(prompt_response)
33
+
34
+ allow(manager)
35
+ .to receive(:search_by_name)
36
+ .and_return(found_manifests)
37
+
38
+ allow(subject).to receive(:puts)
39
+ end
40
+
41
+ context 'when name is provided in options' do
42
+ let(:options) do
43
+ Hashie::Mash.new(
44
+ name: manifest_name
45
+ )
46
+ end
47
+
48
+ describe 'and the template is not found' do
49
+ before { subject.run }
50
+
51
+ it 'uses manager to search for template by name' do
52
+ expect(manager)
53
+ .to have_received(:search_by_name)
54
+ .with(manifest_name)
55
+ end
56
+
57
+ it 'prints no manifests found message' do
58
+ expect(subject)
59
+ .to have_received(:puts)
60
+ .with("✖ No manifests with name `#{manifest_name}` found.")
61
+ end
62
+ end
63
+
64
+ describe 'and the template is found' do
65
+ let(:found_manifests) { [manifest] }
66
+
67
+ before { subject.run }
68
+
69
+ it 'uses manager to search for template by name' do
70
+ expect(manager)
71
+ .to have_received(:search_by_name)
72
+ .with(manifest_name)
73
+ end
74
+
75
+ it 'prints manifest list table' do
76
+ expected_table = <<~TABLE
77
+ NAME VERSION
78
+ #{manifest_name} #{manifest_version}
79
+ TABLE
80
+
81
+ expect(subject)
82
+ .to have_received(:puts)
83
+ .with(expected_table.strip)
84
+ end
85
+ end
86
+ end
87
+
88
+ context 'when the name is not provided in options' do
89
+ before do
90
+ allow(prompt).to receive(:ask).and_return(manifest_name)
91
+ subject.run
92
+ end
93
+
94
+ it 'prompts user for a template name' do
95
+ expect(prompt)
96
+ .to have_received(:ask)
97
+ .with('Please enter a template name')
98
+ end
99
+
100
+ it 'uses manager to search for template by name' do
101
+ expect(manager)
102
+ .to have_received(:search_by_name)
103
+ .with(manifest_name)
104
+ end
105
+
106
+ describe 'when there are results' do
107
+ let(:found_manifests) { [manifest] }
108
+
109
+ it 'prints manifest list table' do
110
+ expected_table = <<~TABLE
111
+ NAME VERSION
112
+ #{manifest_name} #{manifest_version}
113
+ TABLE
114
+
115
+ expect(subject)
116
+ .to have_received(:puts)
117
+ .with(expected_table.strip)
118
+ end
119
+ end
120
+
121
+ describe 'when there are no results' do
122
+ it 'prints no manifests found messsage' do
123
+ expect(subject)
124
+ .to have_received(:puts)
125
+ .with("✖ No manifests with name `#{manifest_name}` found.")
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::ListTemplates do
4
+ let(:options) { Hashie::Mash.new }
5
+
6
+ let(:manifest_list_table) do
7
+ <<~TABLE
8
+ NAME VERSION
9
+ some-manifest 1.0.0
10
+ TABLE
11
+ end
12
+
13
+ let(:manager) { double(AppArchetype::TemplateManager) }
14
+ let(:manifests) { [manifest] }
15
+
16
+ let(:manifest) do
17
+ double(
18
+ AppArchetype::Template::Manifest,
19
+ name: 'some-manifest',
20
+ version: '1.0.0'
21
+ )
22
+ end
23
+
24
+ subject { described_class.new(manager, options) }
25
+
26
+ before do
27
+ allow(manager)
28
+ .to receive(:manifests)
29
+ .and_return(manifests)
30
+
31
+ allow(TTY::Table).to receive(:new).and_call_original
32
+ allow(subject).to receive(:puts)
33
+ end
34
+
35
+ describe '#run' do
36
+ before { subject.run }
37
+
38
+ it 'retrieves manifests from manager' do
39
+ expect(manager).to have_received(:manifests)
40
+ end
41
+
42
+ it 'renders table' do
43
+ expect(TTY::Table).to have_received(:new).with(
44
+ header: AppArchetype::Commands::ListTemplates::RESULT_HEADER,
45
+ rows: [['some-manifest', '1.0.0']]
46
+ )
47
+ end
48
+
49
+ it 'prints table to STDOUT' do
50
+ expect(subject)
51
+ .to have_received(:puts)
52
+ .with(manifest_list_table.strip)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::NewTemplate do
4
+ let(:template_dir) { 'path/to/templates' }
5
+ let(:options) { Hashie::Mash.new }
6
+ let(:prompt) { double(TTY::Prompt) }
7
+
8
+ subject { described_class.new(template_dir, options) }
9
+
10
+ before do
11
+ subject.instance_variable_set(:@prompt, prompt)
12
+ end
13
+
14
+ describe '#run' do
15
+ let(:template_name) { 'new-template' }
16
+ let(:out_dir) { File.join(template_dir, template_name) }
17
+
18
+ before do
19
+ allow(FileUtils).to receive(:mkdir_p)
20
+ allow(AppArchetype::Generators)
21
+ .to receive(:render_empty_template)
22
+ allow(subject).to receive(:puts)
23
+ end
24
+
25
+ context 'when template name is provided' do
26
+ let(:options) do
27
+ Hashie::Mash.new(
28
+ name: template_name
29
+ )
30
+ end
31
+
32
+ before { subject.run }
33
+
34
+ it 'makes the folder' do
35
+ expect(FileUtils)
36
+ .to have_received(:mkdir_p)
37
+ .with(out_dir)
38
+ end
39
+
40
+ it 'generates the empty template' do
41
+ expect(AppArchetype::Generators)
42
+ .to have_received(:render_empty_template)
43
+ .with(template_name, out_dir)
44
+ end
45
+
46
+ it 'prints success message' do
47
+ expect(subject)
48
+ .to have_received(:puts)
49
+ .with("✔ Template `#{template_name}` created at #{out_dir}")
50
+ end
51
+ end
52
+
53
+ context 'when template name is not provided' do
54
+ before do
55
+ allow(prompt).to receive(:ask).and_return(template_name)
56
+ subject.run
57
+ end
58
+
59
+ it 'prompts user for a new name' do
60
+ expect(prompt)
61
+ .to have_received(:ask)
62
+ .with('Please enter a name for the new template')
63
+ end
64
+
65
+ it 'makes the folder' do
66
+ expect(FileUtils)
67
+ .to have_received(:mkdir_p)
68
+ .with(out_dir)
69
+ end
70
+
71
+ it 'generates the empty template' do
72
+ expect(AppArchetype::Generators)
73
+ .to have_received(:render_empty_template)
74
+ .with(template_name, out_dir)
75
+ end
76
+
77
+ it 'prints success message' do
78
+ expect(subject)
79
+ .to have_received(:puts)
80
+ .with("✔ Template `#{template_name}` created at #{out_dir}")
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::OpenManifest do
4
+ let(:manager) { AppArchetype::TemplateManager }
5
+ let(:editor) { 'vi' }
6
+ let(:options) { Hashie::Mash.new }
7
+ let(:prompt) { double(TTY::Prompt) }
8
+
9
+ subject { described_class.new(manager, editor, options) }
10
+
11
+ before do
12
+ subject.instance_variable_set(:@prompt, prompt)
13
+ end
14
+
15
+ describe '#run' do
16
+ let(:template_name) { 'template-name' }
17
+ let(:manifest_path) { 'path/to/manifest' }
18
+ let(:editor) { 'vi' }
19
+ let(:manifest) { double(AppArchetype::Template::Manifest) }
20
+
21
+ before do
22
+ allow(prompt)
23
+ .to receive(:select)
24
+ .and_return(template_name)
25
+
26
+ allow(manager)
27
+ .to receive(:find_by_name)
28
+ .and_return(manifest)
29
+
30
+ allow(manager)
31
+ .to receive(:manifest_names)
32
+ .and_return([template_name])
33
+
34
+ allow(manifest)
35
+ .to receive(:path)
36
+ .and_return(manifest_path)
37
+
38
+ allow(Process).to receive(:spawn)
39
+ allow(Process).to receive(:waitpid)
40
+
41
+ allow(subject).to receive(:puts)
42
+
43
+ subject.run
44
+ end
45
+
46
+ context 'when name is provided in options' do
47
+ describe 'when the template is found' do
48
+ it 'finds template by name' do
49
+ expect(manager)
50
+ .to have_received(:find_by_name)
51
+ .with(template_name)
52
+ end
53
+
54
+ it 'runs editor process' do
55
+ expect(Process)
56
+ .to have_received(:spawn)
57
+ .with("#{editor} #{manifest_path}")
58
+ end
59
+
60
+ it 'waits for process' do
61
+ expect(Process)
62
+ .to have_received(:waitpid)
63
+ end
64
+ end
65
+
66
+ describe 'when the template is not found' do
67
+ let(:manifest) { nil }
68
+
69
+ it 'attempts to find template by name' do
70
+ expect(manager)
71
+ .to have_received(:find_by_name)
72
+ .with(template_name)
73
+ end
74
+
75
+ it 'prints manifest not found message' do
76
+ expect(subject)
77
+ .to have_received(:puts)
78
+ .with("✖ No manifests with name `#{template_name}` found.")
79
+ end
80
+
81
+ it 'does not start editor process' do
82
+ expect(Process)
83
+ .not_to have_received(:spawn)
84
+ end
85
+ end
86
+ end
87
+
88
+ context 'when name is not provided in options' do
89
+ it 'prompts user to choose template' do
90
+ expect(prompt)
91
+ .to have_received(:select)
92
+ .with('Please choose manifest', [template_name])
93
+ end
94
+
95
+ it 'finds template by name' do
96
+ expect(manager)
97
+ .to have_received(:find_by_name)
98
+ .with(template_name)
99
+ end
100
+
101
+ it 'starts editor process' do
102
+ expect(Process)
103
+ .to have_received(:spawn)
104
+ .with("#{editor} #{manifest_path}")
105
+ end
106
+
107
+ it 'waits for process' do
108
+ expect(Process)
109
+ .to have_received(:waitpid)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::PrintPath do
4
+ let(:options) { Hashie::Mash.new }
5
+ let(:template_dir) { '/path/to/templates' }
6
+
7
+ subject { described_class.new(template_dir, options) }
8
+
9
+ before do
10
+ allow(subject).to receive(:puts)
11
+ end
12
+
13
+ describe '#run' do
14
+ before { subject.run }
15
+
16
+ it 'prints given template path to STDOUT' do
17
+ expect(subject)
18
+ .to have_received(:puts)
19
+ .with(template_dir)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,158 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::PrintTemplateVariables do
4
+ let(:manager) { double(AppArchetype::TemplateManager) }
5
+ let(:options) { Hashie::Mash.new }
6
+ let(:prompt) { double(TTY::Prompt) }
7
+
8
+ subject { described_class.new(manager, options) }
9
+
10
+ before do
11
+ subject.instance_variable_set(:@prompt, prompt)
12
+ end
13
+
14
+ describe '#run' do
15
+ let(:prompt_response) { nil }
16
+ let(:found_manifest) { nil }
17
+
18
+ let(:manifest_name) { 'some-template' }
19
+ let(:manifest_version) { '1.0.0' }
20
+
21
+ let(:manifest) do
22
+ double(
23
+ AppArchetype::Template::Manifest,
24
+ name: manifest_name,
25
+ version: manifest_version,
26
+ variables: variables
27
+ )
28
+ end
29
+
30
+ let(:variable_name) { 'script_name' }
31
+ let(:variable_description) { 'Name of script' }
32
+ let(:variable_default) { 'bashy-bash' }
33
+
34
+ let(:variables) do
35
+ double(AppArchetype::Template::VariableManager)
36
+ end
37
+
38
+ let(:variable) do
39
+ AppArchetype::Template::Variable.new(
40
+ variable_name,
41
+ {
42
+ name: variable_name,
43
+ description: variable_description,
44
+ default: variable_default
45
+ }
46
+ )
47
+ end
48
+
49
+ before do
50
+ allow(prompt)
51
+ .to receive(:select)
52
+ .and_return(prompt_response)
53
+
54
+ allow(manager)
55
+ .to receive(:manifest_names)
56
+ .and_return([manifest_name])
57
+
58
+ allow(manager)
59
+ .to receive(:find_by_name)
60
+ .and_return(found_manifest)
61
+
62
+ allow(variables)
63
+ .to receive(:all)
64
+ .and_return([variable])
65
+
66
+ allow(subject).to receive(:puts)
67
+ end
68
+
69
+ context 'when name is provided in options' do
70
+ let(:options) do
71
+ Hashie::Mash.new(
72
+ name: manifest_name
73
+ )
74
+ end
75
+
76
+ describe 'and the template is not found' do
77
+ before { subject.run }
78
+
79
+ it 'uses manager to search for template by name' do
80
+ expect(manager)
81
+ .to have_received(:find_by_name)
82
+ .with(manifest_name)
83
+ end
84
+
85
+ it 'prints no manifests found message' do
86
+ expect(subject)
87
+ .to have_received(:puts)
88
+ .with("✖ No manifests with name `#{manifest_name}` found.")
89
+ end
90
+ end
91
+
92
+ describe 'and the template is found' do
93
+ let(:found_manifest) { manifest }
94
+
95
+ before { subject.run }
96
+
97
+ it 'uses manager to search for template by name' do
98
+ expect(manager)
99
+ .to have_received(:find_by_name)
100
+ .with(manifest_name)
101
+ end
102
+
103
+ it 'prints manifest list table' do
104
+ expected_table = <<~TABLE
105
+ NAME DESCRIPTION DEFAULT
106
+ #{variable_name} #{variable_description} #{variable_default}
107
+ TABLE
108
+
109
+ expect(subject)
110
+ .to have_received(:puts)
111
+ .with(expected_table.strip)
112
+ end
113
+ end
114
+ end
115
+
116
+ context 'when the name is not provided in options' do
117
+ before do
118
+ allow(prompt).to receive(:select).and_return(manifest_name)
119
+ subject.run
120
+ end
121
+
122
+ it 'prompts user for a template name' do
123
+ expect(prompt)
124
+ .to have_received(:select)
125
+ .with('Please choose manifest', [manifest_name])
126
+ end
127
+
128
+ it 'uses manager to search for template by name' do
129
+ expect(manager)
130
+ .to have_received(:find_by_name)
131
+ .with(manifest_name)
132
+ end
133
+
134
+ describe 'when there is a result' do
135
+ let(:found_manifest) { manifest }
136
+
137
+ it 'prints manifest list table' do
138
+ expected_table = <<~TABLE
139
+ NAME DESCRIPTION DEFAULT
140
+ #{variable_name} #{variable_description} #{variable_default}
141
+ TABLE
142
+
143
+ expect(subject)
144
+ .to have_received(:puts)
145
+ .with(expected_table.strip)
146
+ end
147
+ end
148
+
149
+ describe 'when there is no result' do
150
+ it 'prints no manifests found messsage' do
151
+ expect(subject)
152
+ .to have_received(:puts)
153
+ .with("✖ No manifests with name `#{manifest_name}` found.")
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe AppArchetype::Commands::PrintVersion do
4
+ let(:options) { Hashie::Mash.new }
5
+
6
+ subject { described_class.new(options) }
7
+
8
+ before do
9
+ allow(subject).to receive(:puts)
10
+ end
11
+
12
+ describe '#run' do
13
+ before { subject.run }
14
+
15
+ it 'prints current version to STDOUT' do
16
+ expect(subject)
17
+ .to have_received(:puts)
18
+ .with(AppArchetype::VERSION)
19
+ end
20
+ end
21
+ end