rubysmith 0.11.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.adoc +109 -36
  4. data/lib/rubysmith/builder.rb +11 -14
  5. data/lib/rubysmith/builders/bundler.rb +3 -3
  6. data/lib/rubysmith/builders/{ruby_critic.rb → circle_ci.rb} +6 -5
  7. data/lib/rubysmith/builders/console.rb +1 -1
  8. data/lib/rubysmith/builders/core.rb +6 -2
  9. data/lib/rubysmith/builders/documentation/change.rb +32 -0
  10. data/lib/rubysmith/builders/documentation/conduct.rb +32 -0
  11. data/lib/rubysmith/builders/documentation/contribution.rb +32 -0
  12. data/lib/rubysmith/builders/documentation/license.rb +36 -0
  13. data/lib/rubysmith/builders/documentation/readme.rb +44 -0
  14. data/lib/rubysmith/builders/git/commit.rb +1 -1
  15. data/lib/rubysmith/builders/git/setup.rb +1 -1
  16. data/lib/rubysmith/builders/git_hub.rb +34 -0
  17. data/lib/rubysmith/builders/guard.rb +1 -1
  18. data/lib/rubysmith/builders/pragma.rb +1 -1
  19. data/lib/rubysmith/builders/rake.rb +3 -1
  20. data/lib/rubysmith/builders/reek.rb +1 -1
  21. data/lib/rubysmith/builders/rspec/context.rb +1 -1
  22. data/lib/rubysmith/builders/rspec/helper.rb +1 -1
  23. data/lib/rubysmith/builders/rubocop/formatter.rb +1 -1
  24. data/lib/rubysmith/builders/rubocop/setup.rb +1 -1
  25. data/lib/rubysmith/builders/setup.rb +1 -1
  26. data/lib/rubysmith/cli/actions/build.rb +48 -0
  27. data/lib/rubysmith/cli/actions/config.rb +33 -0
  28. data/lib/rubysmith/cli/configuration/content.rb +47 -18
  29. data/lib/rubysmith/cli/configuration/defaults.yml +16 -8
  30. data/lib/rubysmith/cli/configuration/enhancers/current_time.rb +26 -0
  31. data/lib/rubysmith/cli/configuration/enhancers/git_hub_user.rb +33 -0
  32. data/lib/rubysmith/cli/configuration/enhancers/version.rb +26 -0
  33. data/lib/rubysmith/cli/configuration/loader.rb +15 -4
  34. data/lib/rubysmith/cli/parsers/assembler.rb +7 -9
  35. data/lib/rubysmith/cli/parsers/build.rb +176 -45
  36. data/lib/rubysmith/cli/parsers/core.rb +14 -9
  37. data/lib/rubysmith/cli/shell.rb +16 -27
  38. data/lib/rubysmith/container.rb +37 -0
  39. data/lib/rubysmith/identity.rb +2 -2
  40. data/lib/rubysmith/renderers/erb.rb +1 -1
  41. data/lib/rubysmith/renderers/namespace.rb +2 -2
  42. data/lib/rubysmith/templates/%project_name%/.circleci/config.yml.erb +31 -0
  43. data/lib/rubysmith/templates/%project_name%/.github/ISSUE_TEMPLATE.md.erb +14 -0
  44. data/lib/rubysmith/templates/%project_name%/.github/PULL_REQUEST_TEMPLATE.md.erb +11 -0
  45. data/lib/rubysmith/templates/%project_name%/Gemfile.erb +51 -49
  46. data/lib/rubysmith/templates/%project_name%/README.adoc.erb +4 -0
  47. data/lib/rubysmith/templates/%project_name%/README.md.erb +3 -0
  48. data/lib/rubysmith/templates/%project_name%/Rakefile.erb +1 -7
  49. data/lib/rubysmith/templates/%project_name%/bin/console.erb +1 -1
  50. data/lib/rubysmith/templates/%project_name%/lib/%project_path%.rb.erb +12 -0
  51. data/lib/rubysmith/templates/%project_name%/spec/spec_helper.rb.erb +1 -4
  52. data/lib/rubysmith.rb +13 -31
  53. data.tar.gz.sig +0 -0
  54. metadata +94 -13
  55. metadata.gz.sig +0 -0
  56. data/lib/rubysmith/builders/documentation.rb +0 -57
  57. data/lib/rubysmith/cli/processors/build.rb +0 -57
  58. data/lib/rubysmith/cli/processors/config.rb +0 -31
  59. data/lib/rubysmith/templates/%project_name%/.rubycritic.yml.erb +0 -3
  60. data/lib/rubysmith/templates/%project_name%/lib/%project_name%.rb.erb +0 -3
@@ -4,13 +4,12 @@ module Rubysmith
4
4
  module CLI
5
5
  module Parsers
6
6
  # Handles parsing of Command Line Interface (CLI) build options.
7
- # :reek:TooManyMethods
8
7
  class Build
9
- def self.call(options: {}, client: CLIENT) = new(options: options, client: client).call
8
+ def self.call(...) = new(...).call
10
9
 
11
- def initialize options: {}, client: CLIENT
12
- @options = options
10
+ def initialize client: CLIENT, container: Container
13
11
  @client = client
12
+ @container = container
14
13
  end
15
14
 
16
15
  def call arguments = []
@@ -21,103 +20,235 @@ module Rubysmith
21
20
 
22
21
  private
23
22
 
24
- attr_reader :options, :client
23
+ attr_reader :client, :container
25
24
 
26
- def add_minimum
27
- client.on "--min", "Use minimum/no options." do |value|
28
- 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
29
31
  end
30
32
  end
31
33
 
32
- def add_amazing_print
33
- client.on "--[no-]amazing_print", "Add Amazing Print." do |value|
34
- 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
35
40
  end
36
41
  end
37
42
 
38
- def add_bundler_leak
39
- client.on "--[no-]bundler-leak", "Add Bundler Leak." do |value|
40
- 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
41
49
  end
42
50
  end
43
51
 
44
52
  def add_console
45
- client.on "--[no-]console", "Add console script." do |value|
46
- options[:build_console] = value
53
+ client.on(
54
+ "--[no-]console",
55
+ "Add console script. #{default __method__}."
56
+ ) do |value|
57
+ configuration.build_console = value
47
58
  end
48
59
  end
49
60
 
50
- def add_documentation
51
- client.on "--[no-]documentation", "Add documentation." do |value|
52
- options[:build_documentation] = value
61
+ def add_contributions
62
+ client.on(
63
+ "--[no-]contributions",
64
+ "Add CONTRIBUTING documentation. #{default __method__}."
65
+ ) do |value|
66
+ configuration.build_contributions = value
67
+ end
68
+ end
69
+
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
53
94
  end
54
95
  end
55
96
 
56
97
  def add_git
57
- client.on "--[no-]git", "Add Git." do |value|
58
- 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
59
112
  end
60
113
  end
61
114
 
62
115
  def add_git_lint
63
- client.on "--[no-]git-lint", "Add Git Lint." do |value|
64
- 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
65
121
  end
66
122
  end
67
123
 
68
124
  def add_guard
69
- client.on "--[no-]guard", "Add Guard." do |value|
70
- 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
139
+ end
140
+ end
141
+
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
71
157
  end
72
158
  end
73
159
 
74
- def add_pry
75
- client.on "--[no-]pry", "Add Pry." do |value|
76
- options[:build_pry] = value
160
+ def add_rake
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
77
175
  end
78
176
  end
79
177
 
80
178
  def add_reek
81
- client.on "--[no-]reek", "Add Reek." do |value|
82
- options[:build_reek] = value
179
+ client.on(
180
+ "--[no-]reek",
181
+ "Add Reek gem. #{default __method__}."
182
+ ) do |value|
183
+ configuration.build_reek = value
83
184
  end
84
185
  end
85
186
 
86
187
  def add_refinements
87
- client.on "--[no-]refinements", "Add Refinements." do |value|
88
- options[:build_refinements] = value
188
+ client.on(
189
+ "--[no-]refinements",
190
+ "Add Refinements gem. #{default __method__}."
191
+ ) do |value|
192
+ configuration.build_refinements = value
89
193
  end
90
194
  end
91
195
 
92
196
  def add_rspec
93
- client.on "--[no-]rspec", "Add RSpec." do |value|
94
- options[:build_rspec] = value
197
+ client.on(
198
+ "--[no-]rspec",
199
+ "Add RSpec gem. #{default __method__}."
200
+ ) do |value|
201
+ configuration.build_rspec = value
95
202
  end
96
203
  end
97
204
 
98
205
  def add_rubocop
99
- client.on "--[no-]rubocop", "Add Rubocop." do |value|
100
- options[:build_rubocop] = value
206
+ client.on(
207
+ "--[no-]rubocop",
208
+ "Add Rubocop gems. #{default __method__}."
209
+ ) do |value|
210
+ configuration.build_rubocop = value
101
211
  end
102
212
  end
103
213
 
104
- def add_ruby_critic
105
- client.on "--[no-]ruby_critic", "Add RubyCritic." do |value|
106
- options[:build_ruby_critic] = value
214
+ def add_setup
215
+ client.on(
216
+ "--[no-]setup",
217
+ "Add setup script. #{default __method__}."
218
+ ) do |value|
219
+ configuration.build_setup = value
107
220
  end
108
221
  end
109
222
 
110
- def add_setup
111
- client.on "--[no-]setup", "Add setup script." do |value|
112
- options[:build_setup] = value
223
+ def add_simple_cov
224
+ client.on(
225
+ "--[no-]simple_cov",
226
+ "Add SimpleCov gem. #{default __method__}."
227
+ ) do |value|
228
+ configuration.build_simple_cov = value
113
229
  end
114
230
  end
115
231
 
116
- def add_simple_cov
117
- client.on "--[no-]simple_cov", "Add SimpleCov." do |value|
118
- options[:build_simple_cov] = value
232
+ def add_zeitwerk
233
+ client.on(
234
+ "--[no-]zeitwerk",
235
+ "Add Zeitwerk gem. #{default __method__}."
236
+ ) do |value|
237
+ configuration.build_zeitwerk = value
119
238
  end
120
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__]
121
252
  end
122
253
  end
123
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
10
- def self.call(options: {}, client: CLIENT) = new(options: options, client: client).call
11
+ using Refinements::Structs
11
12
 
12
- def initialize options: {}, client: CLIENT
13
- @options = options
13
+ def self.call(...) = new(...).call
14
+
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
@@ -1,56 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "refinements/hashes"
4
-
5
3
  module Rubysmith
6
4
  module CLI
7
5
  # The main Command Line Interface (CLI) object.
8
6
  class Shell
9
- using Refinements::Hashes
10
-
11
- PROCESSORS = {
12
- config: Processors::Config.new,
13
- build_minimum: Processors::Build.with_minimum,
14
- build_maximum: Processors::Build.new
15
- }.freeze
7
+ ACTIONS = {config: Actions::Config.new, build: Actions::Build.new}.freeze
16
8
 
17
- def initialize parser: Parsers::Assembler.new, processors: PROCESSORS
9
+ def initialize parser: Parsers::Assembler.new, actions: ACTIONS, container: Container
18
10
  @parser = parser
19
- @processors = processors
11
+ @actions = actions
12
+ @container = container
20
13
  end
21
14
 
22
15
  def call arguments = []
23
- parse arguments
24
-
25
- case options
26
- in config: Symbol => action then process_config action
27
- in build_minimum: true then process_build :build_minimum, options
28
- in build: then process_build :build_maximum, options
29
- in version: String => version then puts version
16
+ case parse arguments
17
+ in action_config: Symbol => action then config action
18
+ in action_build: true then build
19
+ in action_version: true then logger.info configuration.version
30
20
  else usage
31
21
  end
32
22
  end
33
23
 
34
24
  private
35
25
 
36
- attr_reader :parser, :processors
26
+ attr_reader :parser, :actions, :container
37
27
 
38
28
  def parse arguments = []
39
29
  parser.call arguments
40
30
  rescue StandardError => error
41
- puts error.message
31
+ logger.error error.message
42
32
  end
43
33
 
44
- def process_config(action) = processors.fetch(:config).call(action)
34
+ def config(action) = actions.fetch(__method__).call(action)
45
35
 
46
- def process_build kind, settings
47
- processors.fetch(kind).call settings.transform_keys(build: :project_name)
48
- .merge(now: Time.now)
49
- end
36
+ def build = actions.fetch(__method__).call
37
+
38
+ def usage = logger.unknown(parser.to_s)
50
39
 
51
- def options = parser.to_h
40
+ def configuration = container[__method__]
52
41
 
53
- def usage = puts(parser.to_s)
42
+ def logger = container[__method__]
54
43
  end
55
44
  end
56
45
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-container"
4
+ require "logger"
5
+ require "pastel"
6
+
7
+ module Rubysmith
8
+ # Provides a global gem container for injection into other objects.
9
+ module Container
10
+ extend Dry::Container::Mixin
11
+
12
+ register(:configuration, memoize: true) { CLI::Configuration::Loader.call }
13
+ register(:colorizer) { Pastel.new enabled: $stdout.tty? }
14
+ register(:kernel) { Kernel }
15
+
16
+ register :log_colors do
17
+ {
18
+ "DEBUG" => self[:colorizer].white.detach,
19
+ "INFO" => self[:colorizer].green.detach,
20
+ "WARN" => self[:colorizer].yellow.detach,
21
+ "ERROR" => self[:colorizer].red.detach,
22
+ "FATAL" => self[:colorizer].white.bold.on_red.detach,
23
+ "ANY" => self[:colorizer].white.bold.detach
24
+ }
25
+ end
26
+
27
+ register :logger do
28
+ Logger.new $stdout,
29
+ level: Logger.const_get(ENV.fetch("LOG_LEVEL", "INFO")),
30
+ formatter: (
31
+ lambda do |severity, _at, _name, message|
32
+ self[:log_colors][severity].call "#{message}\n"
33
+ end
34
+ )
35
+ end
36
+ end
37
+ end
@@ -4,8 +4,8 @@ module Rubysmith
4
4
  module Identity
5
5
  NAME = "rubysmith"
6
6
  LABEL = "Rubysmith"
7
- VERSION = "0.11.0"
8
- VERSION_LABEL = "#{LABEL} #{VERSION}"
7
+ VERSION = "0.15.0"
8
+ VERSION_LABEL = "#{LABEL} #{VERSION}".freeze
9
9
  SUMMARY = "A command line interface for smithing Ruby projects."
10
10
  end
11
11
  end
@@ -21,7 +21,7 @@ module Rubysmith
21
21
  attr_accessor :buffer
22
22
  attr_reader :configuration, :scope, :client
23
23
 
24
- def namespace = self.buffer = scope.call(yield)
24
+ def namespace = self.buffer = block_given? ? scope.call(yield) : buffer + scope.call
25
25
  end
26
26
  end
27
27
  end
@@ -14,7 +14,7 @@ module Rubysmith
14
14
  @depth = namespace.scan("::").length
15
15
  end
16
16
 
17
- def call(content) = "#{prefix}#{body content}#{suffix.chomp}"
17
+ def call(content = nil) = "#{prefix}#{body content}#{suffix}"
18
18
 
19
19
  private
20
20
 
@@ -28,7 +28,7 @@ module Rubysmith
28
28
 
29
29
  # :reek:FeatureEnvy
30
30
  def body content
31
- content.lstrip.split("\n").reduce "" do |snippet, line|
31
+ String(content).lstrip.split("\n").reduce "" do |snippet, line|
32
32
  next "#{snippet}\n" if line.blank?
33
33
 
34
34
  "#{snippet}#{line.gsub(/^\s{2}/, "").indent depth + 1}\n"
@@ -0,0 +1,31 @@
1
+ version: 2.1
2
+ jobs:
3
+ build:
4
+ working_directory: ~/project
5
+ docker:
6
+ - image: bkuhlmann/alpine-ruby:latest
7
+ steps:
8
+ - checkout
9
+
10
+ - restore_cache:
11
+ name: Bundler Restore
12
+ keys:
13
+ - gem-cache-{{.Branch}}-{{checksum "Gemfile.lock"}}
14
+ - gem-cache-
15
+
16
+ - run:
17
+ name: Bundler Install
18
+ command: |
19
+ gem update --system
20
+ bundle config set path "vendor/bundle"
21
+ bundle install
22
+
23
+ - save_cache:
24
+ name: Bundler Store
25
+ key: gem-cache-{{.Branch}}-{{checksum "Gemfile.lock"}}
26
+ paths:
27
+ - vendor/bundle
28
+
29
+ - run:
30
+ name: Build
31
+ command: bundle exec rake
@@ -0,0 +1,14 @@
1
+ ## Overview
2
+ <!-- Required. Describe, briefly, the behavior experienced. -->
3
+
4
+ ## Screenshots/Screencasts
5
+ <!-- Optional. Attach screenshot(s) and/or screencast(s) that demo the behavior. -->
6
+
7
+ ## Steps to Recreate
8
+ <!-- Required. List exact steps (numbered list) to reproduce errant behavior. -->
9
+
10
+ ## Desired Behavior
11
+ <!-- Required. Describe the behavior you'd like to see or your idea of a proposed solution. -->
12
+
13
+ ## Environment
14
+ <!-- Required. What is your operating system, software version(s), etc. -->
@@ -0,0 +1,11 @@
1
+ ## Overview
2
+ <!-- Required. Why is this important/necessary and what is the overarching architecture. -->
3
+
4
+ ## Screenshots/Screencasts
5
+ <!-- Optional. Provide supporting image/video. -->
6
+
7
+ ## Details
8
+ <!-- Optional. List the key features/highlights as bullet points. -->
9
+
10
+ ## Notes
11
+ <!-- Optional. List additional notes/references as bullet points. -->