amber_extension_generator 0.0.5

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 (34) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +185 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.solargraph.yml +20 -0
  6. data/CHANGELOG.md +5 -0
  7. data/Gemfile +20 -0
  8. data/Gemfile.lock +116 -0
  9. data/LICENSE +21 -0
  10. data/README.md +37 -0
  11. data/Rakefile +16 -0
  12. data/amber_extension_generator.gemspec +46 -0
  13. data/exe/amber_extension_generator +6 -0
  14. data/lib/amber_extension_generator/cli/args.rb +47 -0
  15. data/lib/amber_extension_generator/cli/gem_generator.rb +406 -0
  16. data/lib/amber_extension_generator/cli.rb +17 -0
  17. data/lib/amber_extension_generator/gem_name.rb +6 -0
  18. data/lib/amber_extension_generator/templates/assets/stylesheets/components.scss +2 -0
  19. data/lib/amber_extension_generator/templates/assets/stylesheets/main.scss.erb +6 -0
  20. data/lib/amber_extension_generator/templates/bin/dev.erb +10 -0
  21. data/lib/amber_extension_generator/templates/bin/generate.erb +142 -0
  22. data/lib/amber_extension_generator/templates/components/base_component.rb.erb +11 -0
  23. data/lib/amber_extension_generator/templates/components.rb +4 -0
  24. data/lib/amber_extension_generator/templates/rails_dummy/Gemfile.erb +33 -0
  25. data/lib/amber_extension_generator/templates/railtie.rb.erb +13 -0
  26. data/lib/amber_extension_generator/templates/templates/component.rb.tt +11 -0
  27. data/lib/amber_extension_generator/templates/templates/component_test.rb.tt +17 -0
  28. data/lib/amber_extension_generator/templates/templates/style.scss.tt +5 -0
  29. data/lib/amber_extension_generator/templates/templates/view.html.erb.tt +8 -0
  30. data/lib/amber_extension_generator/templates/test/component_test_case.rb +7 -0
  31. data/lib/amber_extension_generator/version.rb +6 -0
  32. data/lib/amber_extension_generator.rb +16 -0
  33. data/lib/dummy_rails_app_template.rb +61 -0
  34. metadata +127 -0
@@ -0,0 +1,406 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ require 'rainbow/refinement'
6
+ require 'cli/ui'
7
+ require 'tty-command'
8
+ require 'erb'
9
+
10
+ using ::Rainbow
11
+
12
+ module ::AmberExtensionGenerator
13
+ module CLI
14
+ # Generates a new extension gem
15
+ class GemGenerator
16
+ class << self
17
+ # @param args [::AmberExtensionGenerator::CLI::Args]
18
+ # @return [void]
19
+ def call(args)
20
+ new(args).call
21
+ end
22
+ end
23
+
24
+ # @param args [::AmberExtensionGenerator::CLI::Args]
25
+ def initialize(args)
26
+ @args = args
27
+ end
28
+
29
+ # @return [void]
30
+ def call
31
+ ::CLI::UI::StdoutRouter.enable
32
+ generate_amber_gem
33
+ puts
34
+ generate_rails_dummy_app
35
+ end
36
+
37
+ private
38
+
39
+ # @return [void]
40
+ def generate_amber_gem
41
+ ::CLI::UI::Frame.open 'Create gem', color: :green do # rubocop:disable Metrics/BlockLength
42
+ ::CLI::UI::Frame.open 'Generate gem with bundler' do
43
+ syscall "bundle gem #{root_path} --linter=rubocop --ci=github --test=minitest", input: "y\n"
44
+ end
45
+
46
+ ::CLI::UI::Frame.open 'Patch gem' do
47
+ template 'components/base_component.rb.erb', gem_entry_folder_path / 'components' / 'base_component.rb'
48
+
49
+ copy 'components.rb', gem_entry_folder_path / 'components.rb'
50
+ template 'railtie.rb.erb', gem_entry_folder_path / 'railtie.rb'
51
+
52
+ substitute gem_entry_file_path, /^end/, <<~RUBY.chomp
53
+ end
54
+
55
+ require 'pathname'
56
+ require_relative '#{gem_entry_folder_path.basename}/railtie' if defined?(::Rails::Railtie)
57
+ require_relative '#{gem_entry_folder_path.basename}/components'
58
+
59
+ # Override this if you want to have a different name for the
60
+ # base component of your gem
61
+ #{root_module_name}::ABSTRACT_COMPONENT = #{root_module_name}::BaseComponent
62
+ #{root_module_name}::ROOT_PATH = ::Pathname.new ::File.expand_path('#{relative_path_to_root}', __dir__)
63
+ RUBY
64
+
65
+ create '.rubocop.yml', ::File.read(ROOT_GEM_PATH / '.rubocop.yml')
66
+
67
+ template 'bin/generate.erb', 'bin/generate'
68
+ template 'bin/dev.erb', 'bin/dev'
69
+ make_executable 'bin/generate'
70
+ make_executable 'bin/dev'
71
+
72
+ make_dir 'assets/stylesheets'
73
+ template 'assets/stylesheets/main.scss.erb', main_stylesheet_path
74
+ copy 'assets/stylesheets/components.scss', stylesheet_dir_path / 'components.scss'
75
+
76
+ make_dir 'templates'
77
+ copy 'templates/component.rb.tt'
78
+ copy 'templates/style.scss.tt'
79
+ copy 'templates/view.html.erb.tt'
80
+ copy 'templates/component_test.rb.tt'
81
+
82
+ substitute "#{gem_name}.gemspec", /^end/, <<~RUBY.chomp
83
+ # ignore the dummy Rails app when building the gem
84
+ spec.files.reject! { _1.match(/^#{rails_dummy_path}/) }
85
+ spec.add_dependency 'amber_component'
86
+ spec.add_development_dependency 'thor'
87
+ spec.add_development_dependency 'sassc'
88
+ end
89
+ RUBY
90
+
91
+ copy 'test/component_test_case.rb'
92
+ substitute 'Rakefile', /test_\*\.rb/, '*_test.rb'
93
+ inner_module_name = gem_name.split('-').last
94
+ move gem_test_folder_path.parent / "test_#{inner_module_name}.rb",
95
+ gem_test_folder_path.parent / "#{inner_module_name}_test.rb"
96
+
97
+ append 'test/test_helper.rb',
98
+ "require_relative 'component_test_case'\n"
99
+ end
100
+ end
101
+ end
102
+
103
+ # @return [void]
104
+ def generate_rails_dummy_app
105
+ ::CLI::UI::Frame.open 'Rails dummy app', color: :magenta do
106
+ unless syscall? 'gem list -i rails'
107
+ ::CLI::UI::Frame.open 'Install Rails' do
108
+ syscall 'gem install rails'
109
+ syscall 'gem install sqlite3'
110
+ end
111
+ end
112
+
113
+ ::CLI::UI::Frame.open 'Generate app' do
114
+ syscall "rails new #{root_path / rails_dummy_path} -m #{rails_template_path}",
115
+ env: { GEM_NAME: gem_name },
116
+ input: "y\n"
117
+ end
118
+
119
+ ::CLI::UI::Frame.open 'Patch app' do
120
+ append rails_dummy_path / 'Gemfile', template_content('rails_dummy/Gemfile.erb')
121
+
122
+ if exist?(rails_dummy_path / 'app' / 'assets' / 'stylesheets' / 'application.css')
123
+ move rails_dummy_path / 'app' / 'assets' / 'stylesheets' / 'application.css',
124
+ rails_dummy_path / 'app' / 'assets' / 'stylesheets' / 'application.scss'
125
+
126
+ append rails_dummy_path / 'app' / 'assets' / 'stylesheets' / 'application.scss', <<~SCSS
127
+ @import "#{gem_name_path}";
128
+ SCSS
129
+ else
130
+ append rails_dummy_path / 'app' / 'assets' / 'stylesheets' / 'application.sass.scss', <<~SCSS
131
+ @import "#{gem_name_path}";
132
+ SCSS
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ # @return [String]
139
+ def relative_path_to_root
140
+ (['..'] * root_module_name.split('::').length).join('/')
141
+ end
142
+
143
+ # Performs a shell command with a PTY,
144
+ # captures its output and logs it to this process's STDOUT.
145
+ #
146
+ # @param command [String]
147
+ # @param env [Hash{Symbol => String}] Environment variables
148
+ # @param input [String, nil] Input to the process
149
+ # @return [String] STDOUT
150
+ def syscall(command, env: {}, input: nil)
151
+ cmd = ::TTY::Command.new(color: true, printer: :quiet)
152
+ cmd.run!(command, pty: true, input: input, env: env)
153
+ end
154
+
155
+ # Performs a quiet shell command (without logging to STDOUT)
156
+ # and returns the process's exit status as a `Boolean`.
157
+ #
158
+ # @param command [String]
159
+ # @param env [Hash{Symbol => String}] Environment variables
160
+ # @param input [String, nil] Input to the process
161
+ # @return [Boolean] whether the command was successful
162
+ def syscall?(command, env: {}, input: nil)
163
+ cmd = ::TTY::Command.new(printer: :null)
164
+ !cmd.run!(command, input: input, env: env).failure?
165
+ end
166
+
167
+ # Make a file in the newly generated gem executable.
168
+ #
169
+ # @param path [String, Pathname]
170
+ # @return [void]
171
+ def make_executable(path)
172
+ ::FileUtils.chmod 'ugo+x', root_path / path
173
+ end
174
+
175
+ # Relative path to the main entry file of the generated gem.
176
+ #
177
+ # @return [Pathname]
178
+ def gem_entry_file_path
179
+ gem_entry_folder_path.sub_ext('.rb')
180
+ end
181
+
182
+ # Relative path to the main folder of the generated gem.
183
+ #
184
+ # @return [Pathname]
185
+ def gem_entry_folder_path
186
+ ::Pathname.new('lib') / gem_name_path
187
+ end
188
+
189
+ # Relative path to the test folder of the generated gem.
190
+ #
191
+ # @return [Pathname]
192
+ def gem_test_folder_path
193
+ ::Pathname.new('test') / gem_name_path
194
+ end
195
+
196
+ # @return [Pathname]
197
+ def gem_name_path
198
+ @gem_name_path ||= ::Pathname.new gem_name.gsub('-', '/')
199
+ end
200
+
201
+ # Name of the generated gem.
202
+ #
203
+ # @return [String]
204
+ def gem_name
205
+ @gem_name ||= root_path.basename.to_s
206
+ end
207
+
208
+ # Relative path to the stylesheet directory of the generated gem.
209
+ #
210
+ # @return [Pathname]
211
+ def stylesheet_dir_path
212
+ ::Pathname.new('assets') / 'stylesheets' / gem_name_path
213
+ end
214
+
215
+ # Relative path to the main stylesheet file of the generated gem.
216
+ #
217
+ # @return [Pathname]
218
+ def main_stylesheet_path
219
+ stylesheet_dir_path.sub_ext '.scss'
220
+ end
221
+
222
+ # @return [Pathname]
223
+ def rails_dummy_path
224
+ ::Pathname.new 'dummy_app'
225
+ end
226
+
227
+ # Path to the root folder of the generated gem.
228
+ #
229
+ # @return [Pathname]
230
+ def root_path
231
+ @args.gem_path
232
+ end
233
+
234
+ # @return [Pathname]
235
+ def rails_template_path
236
+ ROOT_GEM_PATH / 'lib' / 'dummy_rails_app_template.rb'
237
+ end
238
+
239
+ # Check whether the given file/directory exists
240
+ # in the generated gem.
241
+ #
242
+ # @param path [String, Pathname]
243
+ # @return [Boolean]
244
+ def exist?(path)
245
+ (root_path / path).exist?
246
+ end
247
+
248
+ # Create a directory in the generated gem
249
+ # if it doesn't exist already.
250
+ #
251
+ # @param path [String, Pathname]
252
+ # @return [void]
253
+ def make_dir(path)
254
+ dir_path = root_path / path
255
+ ::FileUtils.mkdir_p dir_path unless dir_path.exist?
256
+ end
257
+ alias mkdir make_dir
258
+
259
+ # @param string [String, Symbol]
260
+ # @return [String]
261
+ def action_message(string)
262
+ "#{string.to_s.rjust(12, ' ')} "
263
+ end
264
+
265
+ # Parse a template file from this gem using ERB and
266
+ # and copy it to the newly generated gem.
267
+ #
268
+ # @param template_path [String, Pathname]
269
+ # @param target_path [String, Pathname]
270
+ # @return [void]
271
+ def template(template_path, target_path)
272
+ create target_path, template_content(template_path)
273
+ end
274
+
275
+ # Copy a file from this gem's template folder to
276
+ # the newly generated gem.
277
+ #
278
+ # @param source_path [String, Pathname]
279
+ # @param target_path [String, Pathname]
280
+ # @return [void]
281
+ def copy(source_path, target_path = source_path, recursive: false)
282
+ print action_message(__method__).green
283
+ puts target_path
284
+
285
+ source = TEMPLATES_FOLDER_PATH / source_path
286
+ target = root_path / target_path
287
+ ::FileUtils.mkdir_p(target.dirname) unless target.dirname.directory?
288
+ return ::FileUtils.cp_r source, target if recursive
289
+
290
+ ::FileUtils.cp source, target
291
+ end
292
+
293
+ # Move a file inside the generated gem.
294
+ #
295
+ # @param source_path [String, Pathname]
296
+ # @param target_path [String, Pathname]
297
+ # @return [void]
298
+ def move(source_path, target_path)
299
+ print action_message(__method__).yellow
300
+ puts "#{source_path} -> #{target_path}"
301
+
302
+ source = root_path / source_path
303
+ target = root_path / target_path
304
+ ::FileUtils.move source, target
305
+ end
306
+
307
+ # Read and parse a template with ERB and
308
+ # return the result as a `String`.
309
+ #
310
+ # @param path [String, Pathname]
311
+ # @return [String] Parsed content of the template
312
+ def template_content(path)
313
+ template_path = TEMPLATES_FOLDER_PATH / path
314
+ ::ERB.new(template_path.read).result(binding)
315
+ end
316
+
317
+ # Create a new file with the specified content
318
+ # in the newly generated gem.
319
+ #
320
+ # @param file_path [String, Pathname]
321
+ # @param content [String]
322
+ def create(file_path, content)
323
+ print action_message(__method__).green
324
+ puts file_path
325
+
326
+ path = root_path / file_path
327
+ ::FileUtils.mkdir_p(path.dirname) unless path.dirname.directory?
328
+
329
+ path.write(content)
330
+ end
331
+
332
+ # Substitute a part of a certain file in the generated gem.
333
+ #
334
+ # @param file_path [String, Pathname]
335
+ # @param regexp [Regexp]
336
+ # @param replacement [String]
337
+ # @return [void]
338
+ def substitute(file_path, regexp, replacement)
339
+ print action_message(:gsub).yellow
340
+ puts file_path
341
+
342
+ path = root_path / file_path
343
+ file_content = path.read
344
+ raise "Cannot substitute #{path} because #{regexp.inspect} was not found" unless file_content.match?(regexp)
345
+
346
+ path.write file_content.sub(regexp, replacement)
347
+ end
348
+
349
+ # Prepend some content to a file in the generated gem.
350
+ #
351
+ # @param file_path [String, Pathname]
352
+ # @param content [String]
353
+ # @return [void]
354
+ def prepend(file_path, content)
355
+ print action_message(__method__).yellow
356
+ puts file_path
357
+
358
+ # @type [Pathname]
359
+ path = root_path / file_path
360
+ current_content = ::File.read path
361
+ ::File.open(path, 'w') do |f|
362
+ f.write(content)
363
+ f.write(current_content)
364
+ end
365
+ end
366
+
367
+ # Append some content to a file in the generated gem.
368
+ #
369
+ # @param file_path [String, Pathname]
370
+ # @param content[String]
371
+ # @return [void]
372
+ def append(file_path, content)
373
+ print action_message(__method__).yellow
374
+ puts file_path
375
+
376
+ # @type [Pathname]
377
+ path = root_path / file_path
378
+ ::File.open(path, 'a') { _1.write(content) }
379
+ end
380
+
381
+ # Name of the root module of the generated gem.
382
+ #
383
+ # @return [String]
384
+ def root_module_name
385
+ camelize(gem_name_path)
386
+ end
387
+
388
+ # @param string [String]
389
+ # @param uppercase_first_letter [Boolean]
390
+ # @return [String]
391
+ def camelize(string, uppercase_first_letter: true)
392
+ string = string.to_s
393
+ string = if uppercase_first_letter
394
+ string.sub(/^[a-z\d]*/, &:capitalize)
395
+ else
396
+ string.sub(/^(?:(?=\b|[A-Z_])|\w)/, &:downcase)
397
+ end
398
+
399
+ string.gsub!(%r{(?:_|(/))([a-z\d]*)}) do
400
+ "#{::Regexp.last_match(1)}#{::Regexp.last_match(2).capitalize}"
401
+ end
402
+ string.gsub('/', '::')
403
+ end
404
+ end
405
+ end
406
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module ::AmberExtensionGenerator
6
+ # Contains all code which interacts with the terminal.
7
+ module CLI
8
+ class << self
9
+ def run
10
+ GemGenerator.call Args.parse
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ require_relative 'cli/args'
17
+ require_relative 'cli/gem_generator'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ::AmberExtensionGenerator
4
+ # @return [String]
5
+ GEM_NAME = 'amber_extension_generator'
6
+ end
@@ -0,0 +1,2 @@
1
+ // This file imports all of your components' stylesheets
2
+
@@ -0,0 +1,6 @@
1
+ // This is the main entry point for all your styles.
2
+ // This file will be imported by the users of this gem,
3
+ // so every stylesheet required by this gem should
4
+ // be imported here.
5
+
6
+ @import "<%= gem_name_path.basename %>/components";
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+
3
+ BIN_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
4
+
5
+ echo "╔════════════════════════════════════╗"
6
+ echo "║ Starting the development Rails App ║"
7
+ echo "╚════════════════════════════════════╝"
8
+ echo
9
+
10
+ $BIN_DIR/../<%= rails_dummy_path %>/bin/rails server
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'thor'
5
+ require 'pathname'
6
+ require 'fileutils'
7
+
8
+ require_relative '../<%= gem_entry_folder_path %>'
9
+
10
+ class ::GenerateCommand < ::Thor
11
+ include ::Thor::Actions
12
+
13
+ # @return [Module]
14
+ LIBRARY_MODULE = <%= root_module_name %>
15
+ # @return [String]
16
+ LIBRARY_NAME = '<%= gem_name %>'
17
+ # @return [Pathname]
18
+ ROOT_PATH = ::Pathname.new ::File.expand_path('..', __dir__)
19
+ # @return [Pathname]
20
+ GEM_ENTRY_FOLDER_PATH = ::Pathname.new '<%= gem_entry_folder_path %>'
21
+
22
+ class << self
23
+ # Define the generator's root folder
24
+ #
25
+ # @return [String]
26
+ def source_root
27
+ ::File.expand_path('..', __dir__)
28
+ end
29
+ end
30
+
31
+ desc 'component NAME', 'Generate a new component with the specified NAME'
32
+
33
+ # @param name [String]
34
+ # @return [void]
35
+ def component(name)
36
+ name = snake_case(name)
37
+ name = "#{name}_component" unless name.end_with? '_component'
38
+ @name = name
39
+
40
+ template 'templates/component.rb.tt', component_path
41
+ component_assets_path.mkdir unless component_assets_path.exist?
42
+
43
+ template 'templates/view.html.erb.tt', component_assets_path / 'view.html.erb'
44
+ template 'templates/style.scss.tt', component_assets_path / 'style.scss'
45
+ template 'templates/component_test.rb.tt', component_test_file_path
46
+
47
+ append_file main_components_stylesheet_path, %(\n@import "../../../#{component_assets_path}/style.scss";)
48
+ end
49
+
50
+ private
51
+
52
+ # @return [Pathname]
53
+ def component_test_file_path
54
+ components_test_folder_path / "#{@name}_test.rb"
55
+ end
56
+
57
+ # @return [Pathname]
58
+ def main_components_stylesheet_path
59
+ ROOT_PATH / 'assets' / 'stylesheets' / library_relative_path / 'components.scss'
60
+ end
61
+
62
+ # @return [Pathname]
63
+ def components_test_folder_path
64
+ ROOT_PATH / 'test' / library_relative_path / 'components'
65
+ end
66
+
67
+ # @return [Pathname]
68
+ def library_relative_path
69
+ @library_relative_path ||= ::Pathname.new LIBRARY_NAME.gsub('-', '/')
70
+ end
71
+
72
+ # @return [Pathname]
73
+ def component_assets_path
74
+ @component_assets_path ||= GEM_ENTRY_FOLDER_PATH / 'components' / @name
75
+ end
76
+
77
+ # @return [Pathname]
78
+ def component_path
79
+ @component_path ||= GEM_ENTRY_FOLDER_PATH / 'components' / file_name
80
+ end
81
+
82
+ # @return [String]
83
+ def full_class_name
84
+ "#{LIBRARY_MODULE}::#{class_name}"
85
+ end
86
+
87
+ # @return [String]
88
+ def component_css_class
89
+ "#{LIBRARY_NAME}--#{@name}"
90
+ end
91
+
92
+ # @return [String]
93
+ def class_name
94
+ @class_name ||= camelize(@name)
95
+ end
96
+
97
+ # @return [String]
98
+ def file_name
99
+ @file_name ||= "#{@name}.rb"
100
+ end
101
+
102
+ # @return [Class]
103
+ def abstract_component
104
+ LIBRARY_MODULE::ABSTRACT_COMPONENT
105
+ end
106
+
107
+ # Converts a string to camel/Pascal Case.
108
+ #
109
+ # camelize('some_snake_case') #=> "SomeSnakeCase"
110
+ # camelize('some/snake_case') #=> "Some::SnakeCase"
111
+ #
112
+ # @param string [String]
113
+ # @param uppercase_first_letter [Boolean]
114
+ # @return [String]
115
+ def camelize(string, uppercase_first_letter: true)
116
+ string = if uppercase_first_letter
117
+ string.sub(/^[a-z\d]*/, &:capitalize)
118
+ else
119
+ string.sub(/^(?:(?=\b|[A-Z_])|\w)/, &:downcase)
120
+ end
121
+
122
+ string.gsub!(%r{(?:_|(/))([a-z\d]*)}) do
123
+ "#{::Regexp.last_match(1)}#{::Regexp.last_match(2).capitalize}"
124
+ end
125
+ string.gsub('/', '::')
126
+ end
127
+
128
+ # Converts a string in PascalCase or camelCase to snake_case.
129
+ #
130
+ # snake_case('SomePascalCase') => "some_pascal_case"
131
+ # snake_case('Some::PascalCase') => "some/pascal_case"
132
+ #
133
+ # @param string [String]
134
+ # @return [String]
135
+ def snake_case(string)
136
+ string.gsub(/([^A-Z])([A-Z]+)/, '\1_\2')
137
+ .gsub(%r{::_|/_}, '/')
138
+ .downcase
139
+ end
140
+ end
141
+
142
+ ::GenerateCommand.start
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'amber_component'
4
+
5
+ module <%= root_module_name %>
6
+ # Abstract class which should serve as a superclass
7
+ # for all components.
8
+ #
9
+ # @abstract Subclass to create a new component.
10
+ class BaseComponent < ::AmberComponent::Base; end
11
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'components/base_component'
4
+ ::Dir[::File.expand_path('components/**/*.rb', __dir__)].sort.each { require_relative _1 }
@@ -0,0 +1,33 @@
1
+ # === GEM AUTO-RELOADING ===
2
+
3
+ class ::ExtensionGem
4
+ # @return [String] Name of the gem.
5
+ attr_reader :name
6
+ # @return [Pathname] Path to the gem.
7
+ attr_reader :path
8
+ # @return [Array<Symbol>] Top-level constants defined by the gem.
9
+ attr_reader :constants
10
+ # @return [String]
11
+ attr_reader :require_path
12
+
13
+ # @param name [String]
14
+ # @param path [String, Pathname]
15
+ # @param constants [Array<Symbol>]
16
+ # @param require_path [String, nil]
17
+ def initialize(name:, path:, constants:, require_path: nil)
18
+ @name = name
19
+ @path = ::File.expand_path(path, __dir__)
20
+ @constants = constants
21
+ @require_path = require_path || @name.gsub('-', '/')
22
+ end
23
+ end
24
+
25
+ # @return [ExtensionGem]
26
+ ::AMBER_EXTENSION_GEM = ::ExtensionGem.new(
27
+ name: "<%= gem_name %>",
28
+ path: '..',
29
+ constants: %i[<%= root_module_name %>].freeze
30
+ )
31
+ gem ::AMBER_EXTENSION_GEM.name, path: ::AMBER_EXTENSION_GEM.path
32
+
33
+ # === END GEM AUTO-RELOADING ===
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module <%= root_module_name %>
4
+ # Class which hooks into Rails
5
+ # and configures the application.
6
+ class Railtie < ::Rails::Railtie
7
+ initializer '<%= gem_name %>.assets' do |app|
8
+ (ROOT_PATH / 'assets').each_child do |asset_dir|
9
+ app.config.assets.paths << asset_dir.to_s
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= full_class_name %> < <%= abstract_component %>
4
+ # Props that your component accepts
5
+ prop :description, type: ::String, default: -> { 'Default Description' }
6
+
7
+ after_initialize do
8
+ # some initialization
9
+ @time = ::Time.now
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class <%= full_class_name %>Test < ::ComponentTestCase
6
+ # For a full list of available assertions see
7
+ # https://rubydoc.info/github/jnicklas/capybara/Capybara/Node/Matchers
8
+
9
+ # def test_returns_correct_html
10
+ # render do
11
+ # <%= full_class_name %>.call
12
+ # end
13
+ #
14
+ # assert_text 'Hello from <%= full_class_name %>'
15
+ # assert_selector "div.<%= component_css_class %> p", text: 'Default Description'
16
+ # end
17
+ end