hanamismith 0.0.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 (61) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +2 -0
  3. data/LICENSE.adoc +134 -0
  4. data/README.adoc +206 -0
  5. data/exe/hanamismith +6 -0
  6. data/hanamismith.gemspec +42 -0
  7. data/lib/hanamismith/builders/binstub.rb +31 -0
  8. data/lib/hanamismith/builders/bundler.rb +95 -0
  9. data/lib/hanamismith/builders/caliber.rb +26 -0
  10. data/lib/hanamismith/builders/console.rb +22 -0
  11. data/lib/hanamismith/builders/core.rb +64 -0
  12. data/lib/hanamismith/builders/documentation/readme.rb +31 -0
  13. data/lib/hanamismith/builders/environment.rb +31 -0
  14. data/lib/hanamismith/builders/git/commit.rb +12 -0
  15. data/lib/hanamismith/builders/guard.rb +20 -0
  16. data/lib/hanamismith/builders/puma/configuration.rb +32 -0
  17. data/lib/hanamismith/builders/puma/procfile.rb +31 -0
  18. data/lib/hanamismith/builders/rack.rb +28 -0
  19. data/lib/hanamismith/builders/rake.rb +27 -0
  20. data/lib/hanamismith/builders/rspec/hanami.rb +34 -0
  21. data/lib/hanamismith/builders/rspec/helper.rb +24 -0
  22. data/lib/hanamismith/builders/slices/main.rb +67 -0
  23. data/lib/hanamismith/cli/actions/build.rb +66 -0
  24. data/lib/hanamismith/cli/actions/config.rb +34 -0
  25. data/lib/hanamismith/cli/actions/container.rb +19 -0
  26. data/lib/hanamismith/cli/actions/import.rb +11 -0
  27. data/lib/hanamismith/cli/parser.rb +38 -0
  28. data/lib/hanamismith/cli/parsers/core.rb +69 -0
  29. data/lib/hanamismith/cli/shell.rb +36 -0
  30. data/lib/hanamismith/configuration/content.rb +18 -0
  31. data/lib/hanamismith/configuration/defaults.yml +0 -0
  32. data/lib/hanamismith/configuration/loader.rb +27 -0
  33. data/lib/hanamismith/container.rb +17 -0
  34. data/lib/hanamismith/import.rb +7 -0
  35. data/lib/hanamismith/templates/%project_name%/Guardfile.erb +19 -0
  36. data/lib/hanamismith/templates/%project_name%/Procfile.dev.erb +1 -0
  37. data/lib/hanamismith/templates/%project_name%/Procfile.erb +1 -0
  38. data/lib/hanamismith/templates/%project_name%/app/action.rb.erb +9 -0
  39. data/lib/hanamismith/templates/%project_name%/app/repo.rb.erb +10 -0
  40. data/lib/hanamismith/templates/%project_name%/app/view.rb.erb +10 -0
  41. data/lib/hanamismith/templates/%project_name%/bin/hanami.erb +20 -0
  42. data/lib/hanamismith/templates/%project_name%/config/app.rb.erb +8 -0
  43. data/lib/hanamismith/templates/%project_name%/config/providers/persistence.rb.erb +28 -0
  44. data/lib/hanamismith/templates/%project_name%/config/puma.rb.erb +20 -0
  45. data/lib/hanamismith/templates/%project_name%/config/routes.rb.erb +8 -0
  46. data/lib/hanamismith/templates/%project_name%/config/settings.rb.erb +6 -0
  47. data/lib/hanamismith/templates/%project_name%/config.ru.erb +4 -0
  48. data/lib/hanamismith/templates/%project_name%/envrc.erb +1 -0
  49. data/lib/hanamismith/templates/%project_name%/lib/%project_path%/types.rb.erb +10 -0
  50. data/lib/hanamismith/templates/%project_name%/slices/main/action.rb.erb +7 -0
  51. data/lib/hanamismith/templates/%project_name%/slices/main/actions/home/show.rb.erb +10 -0
  52. data/lib/hanamismith/templates/%project_name%/slices/main/repo.rb.erb +7 -0
  53. data/lib/hanamismith/templates/%project_name%/slices/main/templates/home/show.html.erb.erb +3 -0
  54. data/lib/hanamismith/templates/%project_name%/slices/main/templates/layouts/app.html.erb.erb +32 -0
  55. data/lib/hanamismith/templates/%project_name%/slices/main/view.rb.erb +8 -0
  56. data/lib/hanamismith/templates/%project_name%/slices/main/views/home/show.rb.erb +9 -0
  57. data/lib/hanamismith/templates/%project_name%/spec/hanami_helper.rb.erb +22 -0
  58. data/lib/hanamismith.rb +13 -0
  59. data.tar.gz.sig +0 -0
  60. metadata +283 -0
  61. metadata.gz.sig +2 -0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ # Builds project environment skeleton.
8
+ class Environment
9
+ using Refinements::Structs
10
+
11
+ def self.call(...) = new(...).call
12
+
13
+ def initialize configuration, builder: Rubysmith::Builder
14
+ @configuration = configuration
15
+ @builder = builder
16
+ end
17
+
18
+ def call
19
+ builder.call(configuration.merge(template_path: "%project_name%/envrc.erb"))
20
+ .render
21
+ .rename(".envrc")
22
+
23
+ configuration
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :configuration, :builder
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanamismith
4
+ module Builders
5
+ module Git
6
+ # Builds project skeleton initial Git commit message.
7
+ class Commit < Rubysmith::Builders::Git::Commit
8
+ include Import[:specification]
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ # Builds project skeleton Guard support for a red, green, refactor loop.
8
+ class Guard < Rubysmith::Builders::Guard
9
+ using Refinements::Structs
10
+
11
+ def call
12
+ return configuration unless configuration.build_guard
13
+
14
+ super
15
+ builder.call(configuration.merge(template_path: "%project_name%/Guardfile.erb")).render
16
+ configuration
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ module Puma
8
+ # Builds project skeleton Puma configuration.
9
+ class Configuration
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration, builder: Rubysmith::Builder
15
+ @configuration = configuration
16
+ @builder = builder
17
+ end
18
+
19
+ def call
20
+ builder.call(configuration.merge(template_path: "%project_name%/config/puma.rb.erb"))
21
+ .render
22
+
23
+ configuration
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :configuration, :builder
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ module Puma
8
+ # Builds project skeleton Puma Procfile for production and development environments.
9
+ class Procfile
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration, builder: Rubysmith::Builder
15
+ @configuration = configuration
16
+ @builder = builder
17
+ end
18
+
19
+ def call
20
+ builder.call(configuration.merge(template_path: "%project_name%/Procfile.erb")).render
21
+ builder.call(configuration.merge(template_path: "%project_name%/Procfile.dev.erb")).render
22
+ configuration
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :configuration, :builder
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ # Builds project skeleton Rack support.
8
+ class Rack
9
+ using Refinements::Structs
10
+
11
+ def self.call(...) = new(...).call
12
+
13
+ def initialize configuration, builder: Rubysmith::Builder
14
+ @configuration = configuration
15
+ @builder = builder
16
+ end
17
+
18
+ def call
19
+ builder.call(configuration.merge(template_path: "%project_name%/config.ru.erb")).render
20
+ configuration
21
+ end
22
+
23
+ private
24
+
25
+ attr_reader :configuration, :builder
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ # Builds project skeleton Rake support.
8
+ class Rake < Rubysmith::Builders::Rake
9
+ using Refinements::Structs
10
+
11
+ def call
12
+ return configuration unless configuration.build_rake
13
+
14
+ super
15
+ builder.call(configuration.merge(template_path: "%project_name%/Rakefile.erb"))
16
+ .render
17
+ .insert_after(%r(bundler/setup), %(require "hanami/rake_tasks"))
18
+
19
+ configuration
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :configuration, :builder
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ module RSpec
8
+ # Builds project skeleton RSpec helper.
9
+ class Hanami
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration, builder: Rubysmith::Builder
15
+ @configuration = configuration
16
+ @builder = builder
17
+ end
18
+
19
+ def call
20
+ return configuration unless configuration.build_rspec
21
+
22
+ path = "%project_name%/spec/hanami_helper.rb.erb"
23
+ builder.call(configuration.merge(template_path: path)).render
24
+
25
+ configuration
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :configuration, :builder
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ module RSpec
8
+ # Builds project skeleton RSpec helper.
9
+ class Helper < Rubysmith::Builders::RSpec::Helper
10
+ using Refinements::Structs
11
+
12
+ def call
13
+ return configuration unless configuration.build_rspec
14
+
15
+ super
16
+ path = "%project_name%/spec/spec_helper.rb.erb"
17
+ builder.call(configuration.merge(template_path: path))
18
+ .replace(/require.+#{configuration.project_name}.+\n/, "")
19
+ configuration
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/structs"
4
+
5
+ module Hanamismith
6
+ module Builders
7
+ module Slices
8
+ # Builds project skeleton foundation.
9
+ class Main
10
+ using Refinements::Structs
11
+
12
+ def self.call(...) = new(...).call
13
+
14
+ def initialize configuration, builder: Rubysmith::Builder
15
+ @configuration = configuration
16
+ @builder = builder
17
+ end
18
+
19
+ def call
20
+ private_methods.grep(/\Aadd_/).sort.each { |method| __send__ method }
21
+ configuration
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :configuration, :builder
27
+
28
+ def add_action
29
+ path = "%project_name%/slices/main/action.rb.erb"
30
+ builder.call(configuration.merge(template_path: path)).render
31
+ end
32
+
33
+ def add_repository
34
+ path = "%project_name%/slices/main/repo.rb.erb"
35
+ builder.call(configuration.merge(template_path: path)).render
36
+ end
37
+
38
+ def add_view
39
+ path = "%project_name%/slices/main/view.rb.erb"
40
+ builder.call(configuration.merge(template_path: path)).render
41
+ end
42
+
43
+ def add_layout_template
44
+ path = "%project_name%/slices/main/templates/layouts/app.html.erb.erb"
45
+ builder.call(configuration.merge(template_path: path))
46
+ .render
47
+ .replace("<!-- yield -->", "<%= yield %>")
48
+ end
49
+
50
+ def add_show_template
51
+ path = "%project_name%/slices/main/templates/home/show.html.erb.erb"
52
+ builder.call(configuration.merge(template_path: path)).render
53
+ end
54
+
55
+ def add_show_view
56
+ path = "%project_name%/slices/main/views/home/show.rb.erb"
57
+ builder.call(configuration.merge(template_path: path)).render
58
+ end
59
+
60
+ def add_show_action
61
+ path = "%project_name%/slices/main/actions/home/show.rb.erb"
62
+ builder.call(configuration.merge(template_path: path)).render
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanamismith
4
+ module CLI
5
+ module Actions
6
+ # Handles the build action.
7
+ class Build
8
+ include Hanamismith::Import[:logger]
9
+
10
+ # Order is important.
11
+ BUILDERS = [
12
+ Builders::Core,
13
+ Builders::Slices::Main,
14
+ Rubysmith::Builders::Version,
15
+ Builders::Documentation::Readme,
16
+ Rubysmith::Builders::Documentation::Citation,
17
+ Rubysmith::Builders::Documentation::License,
18
+ Rubysmith::Builders::Documentation::Version,
19
+ Rubysmith::Builders::Git::Setup,
20
+ Rubysmith::Builders::Git::Ignore,
21
+ Builders::Bundler,
22
+ Builders::Rake,
23
+ Builders::Binstub,
24
+ Builders::Console,
25
+ Rubysmith::Builders::CircleCI,
26
+ Rubysmith::Builders::Setup,
27
+ Rubysmith::Builders::GitHub,
28
+ Rubysmith::Builders::GitHubCI,
29
+ Builders::Guard,
30
+ Rubysmith::Builders::Reek,
31
+ Rubysmith::Builders::RSpec::Binstub,
32
+ Rubysmith::Builders::RSpec::Context,
33
+ Builders::RSpec::Helper,
34
+ Builders::RSpec::Hanami,
35
+ Builders::Rack,
36
+ Builders::Puma::Configuration,
37
+ Builders::Puma::Procfile,
38
+ Builders::Caliber,
39
+ Rubysmith::Extensions::Bundler,
40
+ Rubysmith::Extensions::Pragmater,
41
+ Rubysmith::Extensions::Tocer,
42
+ Rubysmith::Extensions::Rubocop,
43
+ Builders::Environment,
44
+ Builders::Git::Commit
45
+ ].freeze
46
+
47
+ def initialize builders: BUILDERS, **dependencies
48
+ super(**dependencies)
49
+ @builders = builders
50
+ end
51
+
52
+ def call configuration
53
+ log_info "Building project skeleton: #{configuration.project_name}..."
54
+ builders.each { |builder| builder.call configuration }
55
+ log_info "Project skeleton complete!"
56
+ end
57
+
58
+ private
59
+
60
+ attr_reader :builders
61
+
62
+ def log_info(message) = logger.info { message }
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanamismith
4
+ module CLI
5
+ module Actions
6
+ # Handles the config action.
7
+ class Config
8
+ include Hanamismith::Import[:kernel, :logger]
9
+
10
+ def initialize client: Configuration::Loader::CLIENT, **dependencies
11
+ super(**dependencies)
12
+
13
+ @client = client
14
+ end
15
+
16
+ def call selection
17
+ case selection
18
+ when :edit then edit
19
+ when :view then view
20
+ else logger.error { "Invalid configuration selection: #{selection}." }
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :client
27
+
28
+ def edit = kernel.system("$EDITOR #{client.current}")
29
+
30
+ def view = kernel.system("cat #{client.current}")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/container"
4
+
5
+ module Hanamismith
6
+ module CLI
7
+ module Actions
8
+ # Provides a single container of application and action specific dependencies.
9
+ module Container
10
+ extend Dry::Container::Mixin
11
+
12
+ merge Hanamismith::Container
13
+
14
+ register(:build) { Build.new }
15
+ register(:config) { Config.new }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "infusible"
4
+
5
+ module Hanamismith
6
+ module CLI
7
+ module Actions
8
+ Import = Infusible.with Container
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "core"
4
+ require "optparse"
5
+
6
+ module Hanamismith
7
+ module CLI
8
+ # Assembles and parses all Command Line Interface (CLI) options.
9
+ class Parser
10
+ include Import[:configuration]
11
+
12
+ CLIENT = OptionParser.new nil, 40, " "
13
+
14
+ # Order is important.
15
+ SECTIONS = [Parsers::Core, Rubysmith::CLI::Parsers::Build].freeze
16
+
17
+ def initialize sections: SECTIONS, client: CLIENT, **dependencies
18
+ super(**dependencies)
19
+
20
+ @sections = sections
21
+ @client = client
22
+ @configuration_duplicate = configuration.dup
23
+ end
24
+
25
+ def call arguments = Core::EMPTY_ARRAY
26
+ sections.each { |section| section.call configuration_duplicate, client: }
27
+ client.parse arguments
28
+ configuration_duplicate.freeze
29
+ end
30
+
31
+ def to_s = client.to_s
32
+
33
+ private
34
+
35
+ attr_reader :sections, :client, :configuration_duplicate
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "core"
4
+ require "refinements/structs"
5
+
6
+ module Hanamismith
7
+ module CLI
8
+ module Parsers
9
+ # Handles parsing of Command Line Interface (CLI) core options.
10
+ class Core
11
+ include Import[:specification]
12
+
13
+ using Refinements::Structs
14
+
15
+ def self.call(...) = new(...).call
16
+
17
+ def initialize configuration = Container[:configuration],
18
+ client: Parser::CLIENT,
19
+ **dependencies
20
+
21
+ super(**dependencies)
22
+ @configuration = configuration
23
+ @client = client
24
+ end
25
+
26
+ def call arguments = ::Core::EMPTY_ARRAY
27
+ client.banner = specification.labeled_summary
28
+ client.separator "\nUSAGE:\n"
29
+ collate
30
+ client.parse arguments
31
+ configuration
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :configuration, :client
37
+
38
+ def collate = private_methods.sort.grep(/add_/).each { |method| __send__ method }
39
+
40
+ def add_build
41
+ client.on "-b", "--build NAME [options]", "Build new project." do |name|
42
+ configuration.merge! action_build: true, project_name: name
43
+ end
44
+ end
45
+
46
+ def add_config
47
+ client.on "-c",
48
+ "--config ACTION",
49
+ %i[edit view],
50
+ "Manage gem configuration: edit or view." do |action|
51
+ configuration.merge! action_config: action
52
+ end
53
+ end
54
+
55
+ def add_version
56
+ client.on "-v", "--version", "Show gem version." do
57
+ configuration.merge! action_version: true
58
+ end
59
+ end
60
+
61
+ def add_help
62
+ client.on "-h", "--help", "Show this message." do
63
+ configuration.merge! action_help: true
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "core"
4
+
5
+ module Hanamismith
6
+ module CLI
7
+ # The main Command Line Interface (CLI) object.
8
+ class Shell
9
+ include Actions::Import[:config, :build, :specification, :logger]
10
+
11
+ def initialize parser: Parser.new, **dependencies
12
+ super(**dependencies)
13
+ @parser = parser
14
+ end
15
+
16
+ def call arguments = Core::EMPTY_ARRAY
17
+ perform parser.call(arguments)
18
+ rescue OptionParser::ParseError => error
19
+ logger.error { error.message }
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :parser
25
+
26
+ def perform configuration
27
+ case configuration
28
+ in action_build: true then build.call configuration
29
+ in action_config: Symbol => action then config.call action
30
+ in action_version: true then logger.info { specification.labeled_version }
31
+ else logger.any { parser.to_s }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanamismith
4
+ module Configuration
5
+ # Defines the content of the configuration for use throughout the gem.
6
+ Content = Struct.new(
7
+ :action_config,
8
+ :action_help,
9
+ :action_version,
10
+ keyword_init: true
11
+ ) do
12
+ def initialize *arguments
13
+ super
14
+ freeze
15
+ end
16
+ end
17
+ end
18
+ end
File without changes
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "runcom"
4
+
5
+ module Hanamismith
6
+ module Configuration
7
+ # Represents the fully assembled Command Line Interface (CLI) configuration.
8
+ class Loader < Rubysmith::Configuration::Loader
9
+ DEFAULTS = Rubysmith::Configuration::Loader::DEFAULTS
10
+ CLIENT = Runcom::Config.new "hanamismith/configuration.yml", defaults: DEFAULTS
11
+
12
+ def self.with_overrides
13
+ new client: DEFAULTS,
14
+ enhancers: {template_root: Rubysmith::Configuration::Enhancers::TemplateRoot}
15
+ end
16
+
17
+ def initialize(client: CLIENT, **) = super
18
+
19
+ def call
20
+ return super unless enhancers.key? :template_root
21
+
22
+ enhancers[:template_root].call(super, overrides: Pathname(__dir__).join("../templates"))
23
+ .freeze
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cogger"
4
+ require "dry/container"
5
+ require "spek"
6
+
7
+ module Hanamismith
8
+ # Provides a global gem container for injection into other objects.
9
+ module Container
10
+ extend Dry::Container::Mixin
11
+
12
+ register(:configuration) { Configuration::Loader.call }
13
+ register(:specification) { Spek::Loader.call "#{__dir__}/../../hanamismith.gemspec" }
14
+ register(:kernel) { Kernel }
15
+ register(:logger) { Cogger::Client.new }
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "infusible"
4
+
5
+ module Hanamismith
6
+ Import = Infusible.with Container
7
+ end