gemsmith 15.5.0 → 16.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/LICENSE.adoc +207 -155
  4. data/README.adoc +177 -189
  5. data/exe/gemsmith +6 -0
  6. data/gemsmith.gemspec +41 -0
  7. data/lib/gemsmith/builders/bundler.rb +34 -0
  8. data/lib/gemsmith/builders/cli.rb +86 -0
  9. data/lib/gemsmith/builders/git/commit.rb +46 -0
  10. data/lib/gemsmith/builders/git/ignore.rb +37 -0
  11. data/lib/gemsmith/builders/rspec/helper.rb +47 -0
  12. data/lib/gemsmith/builders/specification.rb +35 -0
  13. data/lib/gemsmith/cli/actions/build.rb +53 -0
  14. data/lib/gemsmith/cli/actions/config.rb +35 -0
  15. data/lib/gemsmith/cli/actions/edit.rb +38 -0
  16. data/lib/gemsmith/cli/actions/install.rb +36 -0
  17. data/lib/gemsmith/cli/actions/publish.rb +36 -0
  18. data/lib/gemsmith/cli/actions/view.rb +38 -0
  19. data/lib/gemsmith/cli/parser.rb +33 -0
  20. data/lib/gemsmith/cli/parsers/build.rb +54 -0
  21. data/lib/gemsmith/cli/parsers/core.rb +94 -0
  22. data/lib/gemsmith/cli/shell.rb +66 -0
  23. data/lib/gemsmith/configuration/enhancers/template_root.rb +20 -0
  24. data/lib/gemsmith/configuration/loader.rb +50 -0
  25. data/lib/gemsmith/container.rb +21 -0
  26. data/lib/gemsmith/gems/finder.rb +21 -0
  27. data/lib/gemsmith/gems/loader.rb +21 -0
  28. data/lib/gemsmith/gems/picker.rb +43 -0
  29. data/lib/gemsmith/gems/presenter.rb +50 -0
  30. data/lib/gemsmith/templates/%project_name%/%project_name%.gemspec.erb +49 -0
  31. data/lib/gemsmith/templates/%project_name%/exe/%project_name%.erb +5 -0
  32. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/cli/actions/config.rb.erb +35 -0
  33. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/cli/parser.rb.erb +31 -0
  34. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/cli/parsers/core.rb.erb +54 -0
  35. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/cli/shell.rb.erb +38 -0
  36. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/configuration/content.rb.erb +18 -0
  37. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/configuration/defaults.yml.erb +0 -0
  38. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/configuration/loader.rb.erb +33 -0
  39. data/lib/gemsmith/templates/%project_name%/lib/%project_path%/container.rb.erb +35 -0
  40. data/lib/gemsmith/templates/{%gem_name%/lib/%gem_path%/identity.rb.tt → %project_name%/lib/%project_path%/identity.rb.erb} +1 -1
  41. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/cli/actions/config_spec.rb.erb +24 -0
  42. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/cli/parser_spec.rb.erb +25 -0
  43. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/cli/parsers/core_spec.rb.erb +53 -0
  44. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/cli/shell_spec.rb.erb +43 -0
  45. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/configuration/content_spec.rb.erb +15 -0
  46. data/lib/gemsmith/templates/%project_name%/spec/lib/%project_path%/configuration/loader_spec.rb.erb +29 -0
  47. data/lib/gemsmith/templates/%project_name%/spec/support/shared_contexts/application_container.rb.erb +22 -0
  48. data/lib/gemsmith/templates/%project_name%/spec/support/shared_examples/a_parser.rb.erb +7 -0
  49. data/lib/gemsmith/tools/cleaner.rb +29 -0
  50. data/lib/gemsmith/tools/editor.rb +30 -0
  51. data/lib/gemsmith/tools/installer.rb +39 -0
  52. data/lib/gemsmith/tools/packager.rb +33 -0
  53. data/lib/gemsmith/tools/publisher.rb +34 -0
  54. data/lib/gemsmith/tools/pusher.rb +36 -0
  55. data/lib/gemsmith/tools/validator.rb +28 -0
  56. data/lib/gemsmith/tools/versioner.rb +43 -0
  57. data/lib/gemsmith/tools/viewer.rb +28 -0
  58. data/lib/gemsmith.rb +5 -3
  59. data.tar.gz.sig +0 -0
  60. metadata +87 -115
  61. metadata.gz.sig +0 -0
  62. data/bin/gemsmith +0 -9
  63. data/lib/gemsmith/authenticators/basic.rb +0 -28
  64. data/lib/gemsmith/authenticators/ruby_gems.rb +0 -41
  65. data/lib/gemsmith/cli.rb +0 -259
  66. data/lib/gemsmith/credentials.rb +0 -82
  67. data/lib/gemsmith/errors/base.rb +0 -9
  68. data/lib/gemsmith/errors/requirement_conversion.rb +0 -9
  69. data/lib/gemsmith/errors/requirement_operator.rb +0 -9
  70. data/lib/gemsmith/errors/specification.rb +0 -9
  71. data/lib/gemsmith/gem/inspector.rb +0 -30
  72. data/lib/gemsmith/gem/module_formatter.rb +0 -50
  73. data/lib/gemsmith/gem/requirement.rb +0 -55
  74. data/lib/gemsmith/gem/specification.rb +0 -74
  75. data/lib/gemsmith/generators/base.rb +0 -46
  76. data/lib/gemsmith/generators/bundler.rb +0 -19
  77. data/lib/gemsmith/generators/bundler_audit.rb +0 -15
  78. data/lib/gemsmith/generators/circle_ci.rb +0 -14
  79. data/lib/gemsmith/generators/cli.rb +0 -17
  80. data/lib/gemsmith/generators/documentation.rb +0 -36
  81. data/lib/gemsmith/generators/engine.rb +0 -77
  82. data/lib/gemsmith/generators/gem.rb +0 -29
  83. data/lib/gemsmith/generators/git.rb +0 -45
  84. data/lib/gemsmith/generators/git_hub.rb +0 -15
  85. data/lib/gemsmith/generators/git_lint.rb +0 -14
  86. data/lib/gemsmith/generators/guard.rb +0 -14
  87. data/lib/gemsmith/generators/pragma.rb +0 -49
  88. data/lib/gemsmith/generators/rake.rb +0 -76
  89. data/lib/gemsmith/generators/reek.rb +0 -17
  90. data/lib/gemsmith/generators/rspec.rb +0 -39
  91. data/lib/gemsmith/generators/rubocop.rb +0 -18
  92. data/lib/gemsmith/generators/ruby.rb +0 -12
  93. data/lib/gemsmith/helpers/cli.rb +0 -59
  94. data/lib/gemsmith/helpers/template.rb +0 -30
  95. data/lib/gemsmith/identity.rb +0 -12
  96. data/lib/gemsmith/rake/builder.rb +0 -57
  97. data/lib/gemsmith/rake/publisher.rb +0 -100
  98. data/lib/gemsmith/rake/setup.rb +0 -4
  99. data/lib/gemsmith/rake/tasks.rb +0 -83
  100. data/lib/gemsmith/templates/%gem_name%/%gem_name%.gemspec.tt +0 -44
  101. data/lib/gemsmith/templates/%gem_name%/.circleci/config.yml.tt +0 -31
  102. data/lib/gemsmith/templates/%gem_name%/.github/ISSUE_TEMPLATE.md.tt +0 -14
  103. data/lib/gemsmith/templates/%gem_name%/.github/PULL_REQUEST_TEMPLATE.md.tt +0 -11
  104. data/lib/gemsmith/templates/%gem_name%/.gitignore.tt +0 -6
  105. data/lib/gemsmith/templates/%gem_name%/.reek.yml.tt +0 -6
  106. data/lib/gemsmith/templates/%gem_name%/.rubocop.yml.tt +0 -15
  107. data/lib/gemsmith/templates/%gem_name%/.ruby-version.tt +0 -1
  108. data/lib/gemsmith/templates/%gem_name%/CHANGES.md.tt +0 -3
  109. data/lib/gemsmith/templates/%gem_name%/CODE_OF_CONDUCT.md.tt +0 -66
  110. data/lib/gemsmith/templates/%gem_name%/CONTRIBUTING.md.tt +0 -22
  111. data/lib/gemsmith/templates/%gem_name%/Gemfile.tt +0 -47
  112. data/lib/gemsmith/templates/%gem_name%/Guardfile.tt +0 -21
  113. data/lib/gemsmith/templates/%gem_name%/LICENSE.md.tt +0 -20
  114. data/lib/gemsmith/templates/%gem_name%/README.md.tt +0 -93
  115. data/lib/gemsmith/templates/%gem_name%/Rakefile.tt +0 -12
  116. data/lib/gemsmith/templates/%gem_name%/bin/%gem_name%.tt +0 -8
  117. data/lib/gemsmith/templates/%gem_name%/bin/console.tt +0 -10
  118. data/lib/gemsmith/templates/%gem_name%/bin/setup.tt +0 -8
  119. data/lib/gemsmith/templates/%gem_name%/lib/%gem_path%/cli.rb.tt +0 -61
  120. data/lib/gemsmith/templates/%gem_name%/lib/%gem_path%/engine.rb.tt +0 -6
  121. data/lib/gemsmith/templates/%gem_name%/lib/%gem_path%.rb.tt +0 -7
  122. data/lib/gemsmith/templates/%gem_name%/lib/generators/%gem_path%/install/USAGE.tt +0 -8
  123. data/lib/gemsmith/templates/%gem_name%/lib/generators/%gem_path%/install/install_generator.rb.tt +0 -12
  124. data/lib/gemsmith/templates/%gem_name%/lib/generators/%gem_path%/upgrade/USAGE.tt +0 -8
  125. data/lib/gemsmith/templates/%gem_name%/lib/generators/%gem_path%/upgrade/upgrade_generator.rb.tt +0 -10
  126. data/lib/gemsmith/templates/%gem_name%/spec/lib/%gem_path%/cli_spec.rb.tt +0 -81
  127. data/lib/gemsmith/templates/%gem_name%/spec/rails_helper.rb.tt +0 -14
  128. data/lib/gemsmith/templates/%gem_name%/spec/spec_helper.rb.tt +0 -37
  129. data/lib/gemsmith/templates/%gem_name%/spec/support/shared_contexts/temp_dir.rb.tt +0 -9
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe <%= configuration.project_class %>::Configuration::Content do
4
+ subject(:content) { described_class.new }
5
+
6
+ describe "#initialize" do
7
+ it "answers default hash" do
8
+ expect(content).to have_attributes(
9
+ action_config: nil,
10
+ action_help: nil,
11
+ action_version: nil
12
+ )
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe <%= configuration.project_class %>::Configuration::Loader do
4
+ subject(:loader) { described_class.with_defaults }
5
+
6
+ let(:content) { <%= configuration.project_class %>::Configuration::Content.new }
7
+
8
+ describe ".call" do
9
+ it "answers default configuration" do
10
+ expect(described_class.call).to be_a(<%= configuration.project_class %>::Configuration::Content)
11
+ end
12
+ end
13
+
14
+ describe ".with_defaults" do
15
+ it "answers default configuration" do
16
+ expect(described_class.with_defaults.call).to eq(content)
17
+ end
18
+ end
19
+
20
+ describe "#call" do
21
+ it "answers default configuration" do
22
+ expect(loader.call).to eq(content)
23
+ end
24
+
25
+ it "answers frozen configuration" do
26
+ expect(loader.call).to be_frozen
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require "dry/container/stub"
2
+
3
+ RSpec.shared_context "with application container" do
4
+ using Refinements::Structs
5
+
6
+ include_context "with temporary directory"
7
+
8
+ let(:container) { <%= configuration.project_class %>::Container }
9
+ let(:configuration) { <%= configuration.project_class %>::Configuration::Loader.with_defaults.call }
10
+ let(:kernel) { class_spy Kernel }
11
+
12
+ before do
13
+ container.enable_stubs!
14
+ container.stub :configuration, configuration
15
+ container.stub :kernel, kernel
16
+ end
17
+
18
+ after do
19
+ container.unstub :configuration
20
+ container.unstub :kernel
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.shared_examples "a parser" do
2
+ describe ".call" do
3
+ it "answers configuration" do
4
+ expect(described_class.call).to be_a(<%= configuration.project_class %>::Configuration::Content)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "refinements/pathnames"
5
+
6
+ module Gemsmith
7
+ module Tools
8
+ # Cleans gem artifacts.
9
+ class Cleaner
10
+ include Dry::Monads[:result]
11
+
12
+ using Refinements::Pathnames
13
+
14
+ def initialize root_dir: Pathname.pwd
15
+ @root_dir = root_dir
16
+ end
17
+
18
+ def call specification
19
+ root_dir.join("pkg").remove_tree
20
+ root_dir.files("**/*.gem").each(&:delete)
21
+ Success specification
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :root_dir
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+
5
+ module Gemsmith
6
+ module Tools
7
+ # Edits a gem within default editor.
8
+ class Editor
9
+ include Dry::Monads[:result]
10
+
11
+ def initialize container: Container
12
+ @container = container
13
+ end
14
+
15
+ def call specification
16
+ executor.capture3(client, specification.source_path.to_s).then do |_stdout, stderr, status|
17
+ status.success? ? Success(specification) : Failure(stderr)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :container
24
+
25
+ def executor = container[__method__]
26
+
27
+ def client = container[:environment].fetch("EDITOR")
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+
5
+ module Gemsmith
6
+ module Tools
7
+ # Installs a locally built gem.
8
+ class Installer
9
+ include Dry::Monads[:result, :do]
10
+
11
+ # Order matters.
12
+ STEPS = [Tools::Cleaner.new, Tools::Packager.new].freeze
13
+
14
+ def initialize steps: STEPS, container: Container
15
+ @steps = steps
16
+ @container = container
17
+ end
18
+
19
+ def call specification
20
+ steps.each { |step| yield step.call(specification) }
21
+ run specification
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :steps, :container
27
+
28
+ def run specification
29
+ path = specification.package_path
30
+
31
+ executor.capture3("gem", "install", path.to_s).then do |_stdout, _stderr, status|
32
+ status.success? ? Success(specification) : Failure("Unable to install: #{path}.")
33
+ end
34
+ end
35
+
36
+ def executor = container[__method__]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "refinements/pathnames"
5
+ require "rubygems/command_manager"
6
+
7
+ module Gemsmith
8
+ module Tools
9
+ # Builds a gem package for distribution.
10
+ class Packager
11
+ include Dry::Monads[:result]
12
+
13
+ using Refinements::Pathnames
14
+
15
+ def initialize command: Gem::CommandManager.new
16
+ @command = command
17
+ end
18
+
19
+ # :reek:TooManyStatements
20
+ def call specification
21
+ command.run ["build", "#{specification.name}.gemspec"]
22
+ specification.package_path.then { |path| path.make_ancestors.basename.copy path.parent }
23
+ Success specification
24
+ rescue Gem::Exception => error
25
+ Failure error.message
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :command
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+
5
+ module Gemsmith
6
+ module Tools
7
+ # Handles the publication of a gem version.
8
+ class Publisher
9
+ include Dry::Monads[:result, :do]
10
+
11
+ # Order matters.
12
+ STEPS = [
13
+ Tools::Cleaner.new,
14
+ Tools::Validator.new,
15
+ Tools::Packager.new,
16
+ Tools::Versioner.new,
17
+ Tools::Pusher.new
18
+ ].freeze
19
+
20
+ def initialize steps: STEPS
21
+ @steps = steps
22
+ end
23
+
24
+ def call specification
25
+ steps.each { |step| yield step.call(specification) }
26
+ Success specification
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :steps
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "rubygems/command_manager"
5
+
6
+ module Gemsmith
7
+ module Tools
8
+ # Pushes a gem package to remote gem server.
9
+ class Pusher
10
+ include Dry::Monads[:result]
11
+
12
+ def initialize command: Gem::CommandManager.new, container: Container
13
+ @command = command
14
+ @container = container
15
+ end
16
+
17
+ def call specification
18
+ command.run ["push", specification.package_path.to_s, *one_time_password]
19
+ Success specification
20
+ rescue Gem::Exception => error
21
+ Failure error.message
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :command, :container
27
+
28
+ def one_time_password
29
+ executor.capture3("ykman", "oath", "accounts", "code", "--single", "RubyGems")
30
+ .then { |stdout, _stderr, status| status.success? ? ["--otp", stdout.chomp] : [] }
31
+ end
32
+
33
+ def executor = container[__method__]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+
5
+ module Gemsmith
6
+ module Tools
7
+ # Validates whether a gem can be published or not.
8
+ class Validator
9
+ include Dry::Monads[:result]
10
+
11
+ def initialize container: Container
12
+ @container = container
13
+ end
14
+
15
+ def call specification
16
+ executor.capture3("git", "status", "--porcelain").then do |_stdout, _stderr, status|
17
+ status.success? ? Success(specification) : Failure("Project has uncommitted changes.")
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :container
24
+
25
+ def executor = container[__method__]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "milestoner"
5
+
6
+ module Gemsmith
7
+ module Tools
8
+ # Versions (tags) current project (local and remote).
9
+ class Versioner
10
+ include Dry::Monads[:result]
11
+
12
+ def initialize client: Milestoner::Tags::Publisher.new,
13
+ content: Milestoner::Configuration::Content,
14
+ container: Container
15
+ @client = client
16
+ @content = content
17
+ @container = container
18
+ end
19
+
20
+ def call specification
21
+ client.call settings(specification)
22
+ Success specification
23
+ rescue Milestoner::Error => error
24
+ Failure error.message
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :client, :content, :container
30
+
31
+ def settings specification
32
+ content[
33
+ documentation_format: configuration.extensions_milestoner_documentation_format,
34
+ prefixes: configuration.extensions_milestoner_prefixes,
35
+ sign: configuration.extensions_milestoner_sign,
36
+ version: specification.version
37
+ ]
38
+ end
39
+
40
+ def configuration = container[__method__]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+
5
+ module Gemsmith
6
+ module Tools
7
+ # Views a gem within default browser.
8
+ class Viewer
9
+ include Dry::Monads[:result]
10
+
11
+ def initialize container: Container
12
+ @container = container
13
+ end
14
+
15
+ def call specification
16
+ executor.capture3("open", specification.homepage_url).then do |_stdout, stderr, status|
17
+ status.success? ? Success(specification) : Failure(stderr)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :container
24
+
25
+ def executor = container[__method__]
26
+ end
27
+ end
28
+ end
data/lib/gemsmith.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "zeitwerk"
4
+ require "rubysmith"
4
5
 
5
- loader = Zeitwerk::Loader.for_gem
6
- loader.inflector.inflect "cli" => "CLI", "circle_ci" => "CircleCI"
7
- loader.setup
6
+ Zeitwerk::Loader.for_gem.then do |loader|
7
+ loader.inflector.inflect "cli" => "CLI", "circle_ci" => "CircleCI", "rspec" => "RSpec"
8
+ loader.setup
9
+ end
8
10
 
9
11
  # Main namespace.
10
12
  module Gemsmith
data.tar.gz.sig CHANGED
Binary file