rubysmith 0.12.0 → 0.16.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. checksums.yaml.gz.sig +0 -0
  3. data/README.adoc +101 -33
  4. data/lib/rubysmith/builder.rb +7 -13
  5. data/lib/rubysmith/builders/bundler.rb +1 -1
  6. data/lib/rubysmith/builders/circle_ci.rb +26 -0
  7. data/lib/rubysmith/builders/core.rb +3 -1
  8. data/lib/rubysmith/builders/documentation/change.rb +32 -0
  9. data/lib/rubysmith/builders/documentation/conduct.rb +32 -0
  10. data/lib/rubysmith/builders/documentation/contribution.rb +32 -0
  11. data/lib/rubysmith/builders/documentation/license.rb +36 -0
  12. data/lib/rubysmith/builders/documentation/readme.rb +44 -0
  13. data/lib/rubysmith/builders/git_hub.rb +34 -0
  14. data/lib/rubysmith/cli/actions/build.rb +48 -0
  15. data/lib/rubysmith/cli/actions/config.rb +33 -0
  16. data/lib/rubysmith/cli/configuration/content.rb +43 -17
  17. data/lib/rubysmith/cli/configuration/defaults.yml +14 -7
  18. data/lib/rubysmith/cli/configuration/enhancers/current_time.rb +26 -0
  19. data/lib/rubysmith/cli/configuration/enhancers/git_hub_user.rb +33 -0
  20. data/lib/rubysmith/cli/configuration/enhancers/version.rb +26 -0
  21. data/lib/rubysmith/cli/configuration/loader.rb +15 -4
  22. data/lib/rubysmith/cli/parsers/assembler.rb +7 -9
  23. data/lib/rubysmith/cli/parsers/build.rb +168 -42
  24. data/lib/rubysmith/cli/parsers/core.rb +13 -8
  25. data/lib/rubysmith/cli/shell.rb +16 -27
  26. data/lib/rubysmith/container.rb +37 -0
  27. data/lib/rubysmith/identity.rb +1 -1
  28. data/lib/rubysmith/templates/%project_name%/.circleci/config.yml.erb +31 -0
  29. data/lib/rubysmith/templates/%project_name%/.github/ISSUE_TEMPLATE.md.erb +14 -0
  30. data/lib/rubysmith/templates/%project_name%/.github/PULL_REQUEST_TEMPLATE.md.erb +8 -0
  31. data/lib/rubysmith/templates/%project_name%/Gemfile.erb +49 -49
  32. data/lib/rubysmith/templates/%project_name%/README.adoc.erb +4 -0
  33. data/lib/rubysmith/templates/%project_name%/README.md.erb +3 -0
  34. data/lib/rubysmith/templates/%project_name%/lib/%project_path%.rb.erb +4 -5
  35. data/lib/rubysmith/templates/%project_name%/spec/spec_helper.rb.erb +0 -3
  36. data/lib/rubysmith.rb +7 -3
  37. data.tar.gz.sig +0 -0
  38. metadata +79 -10
  39. metadata.gz.sig +0 -0
  40. data/lib/rubysmith/builders/documentation.rb +0 -57
  41. data/lib/rubysmith/cli/processors/build.rb +0 -56
  42. data/lib/rubysmith/cli/processors/config.rb +0 -31
@@ -8,27 +8,30 @@ module Rubysmith
8
8
  module Configuration
9
9
  # Defines the common configuration content for use throughout the gem.
10
10
  Content = Struct.new(
11
- :config,
12
- :template_root,
13
- :template_path,
14
- :build_root,
15
- :project_name,
16
- :author_name,
11
+ :action_build,
12
+ :action_config,
13
+ :action_help,
14
+ :action_version,
17
15
  :author_email,
16
+ :author_name,
18
17
  :author_url,
19
- :now,
20
- :documentation_format,
21
- :documentation_license,
22
- :build_minimum,
23
18
  :build_amazing_print,
24
19
  :build_bundler_leak,
20
+ :build_changes,
21
+ :build_circle_ci,
22
+ :build_conduct,
25
23
  :build_console,
26
- :build_documentation,
24
+ :build_contributions,
25
+ :build_debug,
27
26
  :build_git,
27
+ :build_git_hub,
28
28
  :build_git_lint,
29
29
  :build_guard,
30
- :build_pry,
30
+ :build_license,
31
+ :build_maximum,
32
+ :build_minimum,
31
33
  :build_rake,
34
+ :build_readme,
32
35
  :build_reek,
33
36
  :build_refinements,
34
37
  :build_rspec,
@@ -38,8 +41,15 @@ module Rubysmith
38
41
  :build_zeitwerk,
39
42
  :builders_pragmater_comments,
40
43
  :builders_pragmater_includes,
44
+ :documentation_format,
45
+ :documentation_license,
46
+ :git_hub_user,
47
+ :now,
48
+ :project_name,
49
+ :target_root,
50
+ :template_path,
51
+ :template_root,
41
52
  :version,
42
- :help,
43
53
  keyword_init: true
44
54
  ) do
45
55
  using Refinements::Strings
@@ -48,22 +58,38 @@ module Rubysmith
48
58
  super
49
59
 
50
60
  self[:template_root] ||= Pathname(__dir__).join("../../templates").expand_path
51
- self[:build_root] ||= Pathname.pwd
52
- freeze
61
+ self[:target_root] ||= Pathname.pwd
53
62
  end
54
63
 
55
64
  def with(attributes) = self.class.new(to_h.merge(attributes))
56
65
 
66
+ def maximize = update_build_options(true)
67
+
68
+ def minimize = update_build_options(false)
69
+
57
70
  def project_label = project_name.titleize
58
71
 
59
72
  def project_class = project_name.camelcase
60
73
 
61
- def project_root = build_root.join(project_name)
74
+ def project_root = target_root.join(project_name)
62
75
 
63
76
  def project_path = project_name.snakecase
64
77
 
78
+ def ascii_doc? = documentation_format == "adoc"
79
+
80
+ def markdown? = documentation_format == "md"
81
+
65
82
  def to_pathway
66
- Pathway[start_root: template_root, start_path: template_path, end_root: build_root]
83
+ Pathway[start_root: template_root, start_path: template_path, end_root: target_root]
84
+ end
85
+
86
+ private
87
+
88
+ def update_build_options value
89
+ to_h.except(:build_minimum)
90
+ .select { |key, _value| key.start_with? "build_" }
91
+ .each { |key, _value| self[key] = value }
92
+ .then { self }
67
93
  end
68
94
  end
69
95
  end
@@ -1,23 +1,25 @@
1
- :project:
2
- :name:
3
1
  :author:
4
2
  :name:
5
3
  :email:
6
4
  :url:
7
- :documentation:
8
- :format: "md"
9
- :license: "mit"
10
5
  :build:
11
6
  :amazing_print: true
12
7
  :bundler_leak: true
8
+ :changes: true
9
+ :circle_ci: false
10
+ :conduct: true
13
11
  :console: true
14
- :documentation: true
12
+ :contributions: true
13
+ :debug: true
15
14
  :git: true
15
+ :git_hub: false
16
16
  :git_lint: true
17
17
  :guard: true
18
+ :license: true
19
+ :maximum: false
18
20
  :minimum: false
19
- :pry: true
20
21
  :rake: true
22
+ :readme: true
21
23
  :reek: true
22
24
  :refinements: true
23
25
  :rspec: true
@@ -37,3 +39,8 @@
37
39
  - "**/*Gemfile"
38
40
  - "**/*Guardfile"
39
41
  - "**/*Rakefile"
42
+ :documentation:
43
+ :format: "md"
44
+ :license: "mit"
45
+ :git_hub:
46
+ :user:
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Rubysmith
6
+ module CLI
7
+ module Configuration
8
+ module Enhancers
9
+ # Adds current time to content.
10
+ class CurrentTime
11
+ using Refinements::Structs
12
+
13
+ def initialize now = Time.now
14
+ @now = now
15
+ end
16
+
17
+ def call(content) = content.merge(now: now)
18
+
19
+ private
20
+
21
+ attr_reader :now
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "git_plus"
4
+ require "refinements/strings"
5
+ require "refinements/structs"
6
+
7
+ module Rubysmith
8
+ module CLI
9
+ module Configuration
10
+ module Enhancers
11
+ # Dynamically adds GitHub user if user is defined.
12
+ class GitHubUser
13
+ using Refinements::Strings
14
+ using Refinements::Structs
15
+
16
+ def initialize repository: GitPlus::Repository.new
17
+ @repository = repository
18
+ end
19
+
20
+ def call content
21
+ String(content.git_hub_user).blank? ? content.merge(git_hub_user: user) : content
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :repository
27
+
28
+ def user = repository.config_get("github.user")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Rubysmith
6
+ module CLI
7
+ module Configuration
8
+ module Enhancers
9
+ # Adds this gem's version to content.
10
+ class Version
11
+ using Refinements::Structs
12
+
13
+ def initialize version = Identity::VERSION_LABEL
14
+ @version = version
15
+ end
16
+
17
+ def call(content) = content.merge(version: version)
18
+
19
+ private
20
+
21
+ attr_reader :version
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -17,18 +17,29 @@ module Rubysmith
17
17
  DEFAULTS = YAML.load_file(Pathname(__dir__).join("defaults.yml")).freeze
18
18
  CLIENT = Runcom::Config.new "#{Identity::NAME}/configuration.yml", defaults: DEFAULTS
19
19
 
20
- def self.call = new.call
20
+ ENHANCERS = [
21
+ Enhancers::GitHubUser.new,
22
+ Enhancers::CurrentTime.new,
23
+ Enhancers::Version.new
24
+ ].freeze
21
25
 
22
- def initialize content: Content.new, client: CLIENT
26
+ def self.call(...) = new(...).call
27
+
28
+ def self.with_defaults = new(client: DEFAULTS, enhancers: [])
29
+
30
+ def initialize content: Content.new, client: CLIENT, enhancers: ENHANCERS
23
31
  @content = content
24
32
  @client = client
33
+ @enhancers = enhancers
25
34
  end
26
35
 
27
- def call = content.merge(**client.to_h.flatten_keys)
36
+ def call = enhancers.reduce(preload_content) { |preload, enhancer| enhancer.call preload }
28
37
 
29
38
  private
30
39
 
31
- attr_reader :content, :client
40
+ attr_reader :content, :client, :enhancers
41
+
42
+ def preload_content = content.merge(**client.to_h.flatten_keys)
32
43
  end
33
44
  end
34
45
  end
@@ -7,27 +7,25 @@ module Rubysmith
7
7
  class Assembler
8
8
  SECTIONS = [Core, Build].freeze # Order is important.
9
9
 
10
- def initialize configuration: CLI::Configuration::Loader.call,
11
- sections: SECTIONS,
12
- client: CLIENT
13
- @options = configuration.to_h
10
+ def initialize sections: SECTIONS, client: CLIENT, container: Container
14
11
  @sections = sections
15
12
  @client = client
13
+ @container = container
16
14
  end
17
15
 
18
16
  def call arguments = []
19
- sections.each { |parser| parser.call client: client, options: options }
17
+ sections.each { |parser| parser.call client: client }
20
18
  client.parse! arguments
21
- options
19
+ configuration
22
20
  end
23
21
 
24
- def to_h = options
25
-
26
22
  def to_s = client.to_s
27
23
 
28
24
  private
29
25
 
30
- attr_reader :options, :sections, :client
26
+ attr_reader :sections, :client, :container
27
+
28
+ def configuration = container[__method__]
31
29
  end
32
30
  end
33
31
  end
@@ -7,9 +7,9 @@ module Rubysmith
7
7
  class Build
8
8
  def self.call(...) = new(...).call
9
9
 
10
- def initialize options: {}, client: CLIENT
11
- @options = options
10
+ def initialize client: CLIENT, container: Container
12
11
  @client = client
12
+ @container = container
13
13
  end
14
14
 
15
15
  def call arguments = []
@@ -20,109 +20,235 @@ module Rubysmith
20
20
 
21
21
  private
22
22
 
23
- attr_reader :options, :client
23
+ attr_reader :client, :container
24
24
 
25
- def add_minimum
26
- client.on "--min", "Use minimum/no options." do |value|
27
- options[:build_minimum] = value
25
+ def add_amazing_print
26
+ client.on(
27
+ "--[no-]amazing_print",
28
+ "Add Amazing Print gem. #{default __method__}."
29
+ ) do |value|
30
+ configuration.build_amazing_print = value
28
31
  end
29
32
  end
30
33
 
31
- def add_amazing_print
32
- client.on "--[no-]amazing_print", "Add Amazing Print." do |value|
33
- options[:build_amazing_print] = value
34
+ def add_bundler_leak
35
+ client.on(
36
+ "--[no-]bundler-leak",
37
+ "Add Bundler Leak gem. #{default __method__}."
38
+ ) do |value|
39
+ configuration.build_bundler_leak = value
34
40
  end
35
41
  end
36
42
 
37
- def add_bundler_leak
38
- client.on "--[no-]bundler-leak", "Add Bundler Leak." do |value|
39
- options[:build_bundler_leak] = value
43
+ def add_changes
44
+ client.on(
45
+ "--[no-]changes",
46
+ "Add CHANGES documentation. #{default __method__}."
47
+ ) do |value|
48
+ configuration.build_changes = value
40
49
  end
41
50
  end
42
51
 
43
52
  def add_console
44
- client.on "--[no-]console", "Add console script." do |value|
45
- options[:build_console] = value
53
+ client.on(
54
+ "--[no-]console",
55
+ "Add console script. #{default __method__}."
56
+ ) do |value|
57
+ configuration.build_console = value
58
+ end
59
+ end
60
+
61
+ def add_contributions
62
+ client.on(
63
+ "--[no-]contributions",
64
+ "Add CONTRIBUTING documentation. #{default __method__}."
65
+ ) do |value|
66
+ configuration.build_contributions = value
46
67
  end
47
68
  end
48
69
 
49
- def add_documentation
50
- client.on "--[no-]documentation", "Add documentation." do |value|
51
- options[:build_documentation] = value
70
+ def add_circle_ci
71
+ client.on(
72
+ "--[no-]circle_ci",
73
+ "Add Circle CI configuration and badge. #{default __method__}."
74
+ ) do |value|
75
+ configuration.build_circle_ci = value
76
+ end
77
+ end
78
+
79
+ def add_conduct
80
+ client.on(
81
+ "--[no-]conduct",
82
+ "Add CODE_OF_CONDUCT documentation. #{default __method__}."
83
+ ) do |value|
84
+ configuration.build_conduct = value
85
+ end
86
+ end
87
+
88
+ def add_debug
89
+ client.on(
90
+ "--[no-]debug",
91
+ "Add Debug gem. #{default __method__}."
92
+ ) do |value|
93
+ configuration.build_debug = value
52
94
  end
53
95
  end
54
96
 
55
97
  def add_git
56
- client.on "--[no-]git", "Add Git." do |value|
57
- options[:build_git] = value
98
+ client.on(
99
+ "--[no-]git",
100
+ "Add Git. #{default __method__}."
101
+ ) do |value|
102
+ configuration.build_git = value
103
+ end
104
+ end
105
+
106
+ def add_git_hub
107
+ client.on(
108
+ "--[no-]git_hub",
109
+ "Add GitHub templates. #{default __method__}."
110
+ ) do |value|
111
+ configuration.build_git_hub = value
58
112
  end
59
113
  end
60
114
 
61
115
  def add_git_lint
62
- client.on "--[no-]git-lint", "Add Git Lint." do |value|
63
- options[:build_git_lint] = value
116
+ client.on(
117
+ "--[no-]git-lint",
118
+ "Add Git Lint gem. #{default __method__}."
119
+ ) do |value|
120
+ configuration.build_git_lint = value
64
121
  end
65
122
  end
66
123
 
67
124
  def add_guard
68
- client.on "--[no-]guard", "Add Guard." do |value|
69
- options[:build_guard] = value
125
+ client.on(
126
+ "--[no-]guard",
127
+ "Add Guard gem. #{default __method__}."
128
+ ) do |value|
129
+ configuration.build_guard = value
130
+ end
131
+ end
132
+
133
+ def add_license
134
+ client.on(
135
+ "--[no-]license",
136
+ "Add LICENSE documentation. #{default __method__}."
137
+ ) do |value|
138
+ configuration.build_license = value
70
139
  end
71
140
  end
72
141
 
73
- def add_pry
74
- client.on "--[no-]pry", "Add Pry." do |value|
75
- options[:build_pry] = value
142
+ def add_maximum
143
+ client.on(
144
+ "--max",
145
+ "Use maximum/enabled options. #{default __method__}."
146
+ ) do |value|
147
+ configuration.maximize.build_maximum = value
148
+ end
149
+ end
150
+
151
+ def add_minimum
152
+ client.on(
153
+ "--min",
154
+ "Use minimum/disabled options. #{default __method__}."
155
+ ) do |value|
156
+ configuration.minimize.build_minimum = value
76
157
  end
77
158
  end
78
159
 
79
160
  def add_rake
80
- client.on "--[no-]rake", "Add Rake." do |value|
81
- options[:build_rake] = value
161
+ client.on(
162
+ "--[no-]rake",
163
+ "Add Rake gem. #{default __method__}."
164
+ ) do |value|
165
+ configuration.build_rake = value
166
+ end
167
+ end
168
+
169
+ def add_readme
170
+ client.on(
171
+ "--[no-]readme",
172
+ "Add README documentation. #{default __method__}."
173
+ ) do |value|
174
+ configuration.build_readme = value
82
175
  end
83
176
  end
84
177
 
85
178
  def add_reek
86
- client.on "--[no-]reek", "Add Reek." do |value|
87
- options[:build_reek] = value
179
+ client.on(
180
+ "--[no-]reek",
181
+ "Add Reek gem. #{default __method__}."
182
+ ) do |value|
183
+ configuration.build_reek = value
88
184
  end
89
185
  end
90
186
 
91
187
  def add_refinements
92
- client.on "--[no-]refinements", "Add Refinements." do |value|
93
- options[:build_refinements] = value
188
+ client.on(
189
+ "--[no-]refinements",
190
+ "Add Refinements gem. #{default __method__}."
191
+ ) do |value|
192
+ configuration.build_refinements = value
94
193
  end
95
194
  end
96
195
 
97
196
  def add_rspec
98
- client.on "--[no-]rspec", "Add RSpec." do |value|
99
- options[:build_rspec] = value
197
+ client.on(
198
+ "--[no-]rspec",
199
+ "Add RSpec gem. #{default __method__}."
200
+ ) do |value|
201
+ configuration.build_rspec = value
100
202
  end
101
203
  end
102
204
 
103
205
  def add_rubocop
104
- client.on "--[no-]rubocop", "Add Rubocop." do |value|
105
- options[:build_rubocop] = value
206
+ client.on(
207
+ "--[no-]rubocop",
208
+ "Add Rubocop gems. #{default __method__}."
209
+ ) do |value|
210
+ configuration.build_rubocop = value
106
211
  end
107
212
  end
108
213
 
109
214
  def add_setup
110
- client.on "--[no-]setup", "Add setup script." do |value|
111
- options[:build_setup] = value
215
+ client.on(
216
+ "--[no-]setup",
217
+ "Add setup script. #{default __method__}."
218
+ ) do |value|
219
+ configuration.build_setup = value
112
220
  end
113
221
  end
114
222
 
115
223
  def add_simple_cov
116
- client.on "--[no-]simple_cov", "Add SimpleCov." do |value|
117
- options[:build_simple_cov] = value
224
+ client.on(
225
+ "--[no-]simple_cov",
226
+ "Add SimpleCov gem. #{default __method__}."
227
+ ) do |value|
228
+ configuration.build_simple_cov = value
118
229
  end
119
230
  end
120
231
 
121
232
  def add_zeitwerk
122
- client.on "--[no-]zeitwerk", "Add Zeitwerk." do |value|
123
- options[:build_zeitwerk] = value
233
+ client.on(
234
+ "--[no-]zeitwerk",
235
+ "Add Zeitwerk gem. #{default __method__}."
236
+ ) do |value|
237
+ configuration.build_zeitwerk = value
124
238
  end
125
239
  end
240
+
241
+ def default option
242
+ option.to_s
243
+ .sub("add_", "build_")
244
+ .then { |attribute| configuration.public_send attribute }
245
+ .then { |boolean| boolean ? colorizer.green(boolean) : colorizer.red(boolean) }
246
+ .then { |colored_boolean| "Default: #{colored_boolean}" }
247
+ end
248
+
249
+ def configuration = container[__method__]
250
+
251
+ def colorizer = container[__method__]
126
252
  end
127
253
  end
128
254
  end
@@ -1,17 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rubysmith/identity"
4
+ require "refinements/structs"
4
5
 
5
6
  module Rubysmith
6
7
  module CLI
7
8
  module Parsers
8
9
  # Handles parsing of Command Line Interface (CLI) core options.
9
10
  class Core
11
+ using Refinements::Structs
12
+
10
13
  def self.call(...) = new(...).call
11
14
 
12
- def initialize options: {}, client: CLIENT
13
- @options = options
15
+ def initialize client: CLIENT, container: Container
14
16
  @client = client
17
+ @container = container
15
18
  end
16
19
 
17
20
  def call arguments = []
@@ -23,7 +26,7 @@ module Rubysmith
23
26
 
24
27
  private
25
28
 
26
- attr_reader :options, :client
29
+ attr_reader :client, :container
27
30
 
28
31
  def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
29
32
 
@@ -32,27 +35,29 @@ module Rubysmith
32
35
  "--config ACTION",
33
36
  %i[edit view],
34
37
  "Manage gem configuration: edit or view." do |action|
35
- options[:config] = action
38
+ configuration.action_config = action
36
39
  end
37
40
  end
38
41
 
39
42
  def add_build
40
- client.on "-b", "--build NAME [options]", "Build new project." do |value|
41
- options[:build] = value
43
+ client.on "-b", "--build NAME [options]", "Build new project." do |name|
44
+ configuration.merge! action_build: true, project_name: name
42
45
  end
43
46
  end
44
47
 
45
48
  def add_version
46
49
  client.on "-v", "--version", "Show gem version." do
47
- options[:version] = Identity::VERSION_LABEL
50
+ configuration.action_version = true
48
51
  end
49
52
  end
50
53
 
51
54
  def add_help
52
55
  client.on "-h", "--help", "Show this message." do
53
- options[:help] = true
56
+ configuration.action_help = true
54
57
  end
55
58
  end
59
+
60
+ def configuration = container[__method__]
56
61
  end
57
62
  end
58
63
  end