rsgem 0.1.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: deec5cd29ecd1189ee350da6c7d15bdf197c21f0670e5158251cb214b0fb98b4
4
- data.tar.gz: 28758518b1a52a52dca2945a136c23ee851e45c9a63ca599b6090c232e6680b6
3
+ metadata.gz: e392882ca1119b54ef75b184ba5e1bb962b1547008048291f97890fc8af9d524
4
+ data.tar.gz: b9f5f832bccb47c09e11fdc5d9ea800853b12ae52a5e5dfa17053a3f4a5d4eef
5
5
  SHA512:
6
- metadata.gz: e646ac023ad600bb4c0556034ba7249d6ca271ba50aecd8d4a0c6eff029095f06250ecd4e742f8d353b2d370af163893a0aac16659a22f115d9eb80c34238ff9
7
- data.tar.gz: 044134b37c4cfca91e21633218f19f299e481b7008b582e412c31fd24e7f358e65b49f12cbefb3bc8d55ca74e130ac013eab339a1ff218782777927b8e0fe9e9
6
+ metadata.gz: bbb346cba7c916958df3f6b59493d7686420874b948494e9d704e40759198fe0af0ea071a1de2ac85d93066a02cf3a67ce0a37779228d4fa54003f5b2bf83189
7
+ data.tar.gz: 19f0c24d253ede15f68d8377abbb43786f3a32ebfffcbefbaebe0a397e0519b107710c60d04cba3df1f5021ede8da0f7ea2aa0e370fbba3f4d364a04834ab2a2
@@ -1,5 +1,45 @@
1
1
  # master
2
2
 
3
+ # 1.1.0
4
+
5
+ * Update Bundler and Ruby versions
6
+
7
+ *Horacio Bertorello*
8
+
9
+ # 1.0.0
10
+
11
+ * Using Github Actions as the default CI provider
12
+ * Dropping Ruby 2.4 support
13
+ * New CLI output format
14
+ * Add rubocop-rootstrap
15
+
16
+ *Juan Manuel Ramallo*
17
+
18
+ * Add placeholder `email` and `name` when no git user is set, issuing a warning while doing so.
19
+ * Add colors to output during gem creation.
20
+
21
+ *Jake Yesbeck*
22
+
23
+ # 0.4.0
24
+
25
+ * Cache bundler directory for 24hs in Github Actions
26
+
27
+ *Martín Rubí*
28
+
29
+ # 0.3.0
30
+
31
+ * Add task to replace system user name in LICENSE.txt with Rootstrap name
32
+
33
+ *Juan Francisco Ferrari*
34
+
35
+ # 0.2.0
36
+
37
+ * Add default configuration for simplecov in spec_helper.rb
38
+
39
+ * Display an error message if bundler failed to run or is not present in the system
40
+
41
+ *Juan Manuel Ramallo*
42
+
3
43
  # 0.1.3
4
44
 
5
45
  * Fix gem creation task on Linux
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020 Juan Manuel Ramallo
3
+ Copyright (c) 2020 Rootstrap
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,20 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'date'
4
+ require 'fileutils'
3
5
  require 'rsgem/version'
4
6
  require 'rsgem/gem'
5
- require 'rsgem/errors/missing_gem_name_error'
7
+ require 'rsgem/errors/base'
8
+ require 'rsgem/errors/missing_gem_name'
6
9
  require 'rsgem/ci_providers/base'
7
10
  require 'rsgem/ci_providers/github_actions'
8
11
  require 'rsgem/ci_providers/travis'
12
+ require 'rsgem/tasks/output'
13
+ require 'rsgem/tasks/base'
14
+ require 'rsgem/tasks/add_ci_provider'
9
15
  require 'rsgem/tasks/add_code_analysis'
10
16
  require 'rsgem/tasks/add_dependency'
11
17
  require 'rsgem/tasks/clean_gemfile'
12
18
  require 'rsgem/tasks/create_gem'
19
+ require 'rsgem/tasks/ensure_author'
13
20
  require 'rsgem/tasks/ignore_gemfile_lock'
14
21
  require 'rsgem/tasks/clean_gemspec'
15
22
  require 'rsgem/tasks/bundle_dependencies'
16
23
  require 'rsgem/tasks/run_rubocop'
17
24
  require 'rsgem/tasks/set_bundled_files'
25
+ require 'rsgem/tasks/set_license_file'
26
+ require 'rsgem/tasks/simple_cov_post_install'
27
+ require 'rsgem/tasks/set_required_ruby_version'
18
28
  require 'rsgem/dependencies/base'
19
29
  require 'rsgem/dependencies/rake'
20
30
  require 'rsgem/dependencies/reek'
@@ -22,6 +32,7 @@ require 'rsgem/dependencies/rspec'
22
32
  require 'rsgem/dependencies/rubocop'
23
33
  require 'rsgem/dependencies/simplecov'
24
34
  require 'rsgem/constants'
35
+ require 'rsgem/colors'
25
36
  require 'rsgem/context'
26
37
  require 'dry/cli'
27
38
  require 'rsgem/cli/commands/new'
@@ -5,7 +5,7 @@ module RSGem
5
5
  class Base
6
6
  attr_reader :config_file_destination, :config_file_source, :name, :display_name
7
7
 
8
- def initialize(config_file_source: nil, config_file_destination: nil, display_name:, name:)
8
+ def initialize(display_name:, name:, config_file_source: nil, config_file_destination: nil)
9
9
  @config_file_source = config_file_source
10
10
  @config_file_destination = config_file_destination
11
11
  @display_name = display_name
@@ -16,19 +16,17 @@ module RSGem
16
16
  remove_travis(context)
17
17
  destination = "#{context.folder_path}/#{config_file_destination}"
18
18
 
19
- File.delete(destination) if File.exist?(destination)
20
- FileUtils.mkdir_p(File.dirname(destination))
21
- File.open(destination, 'w') do |file|
19
+ ::File.delete(destination) if ::File.exist?(destination)
20
+ ::FileUtils.mkdir_p(::File.dirname(destination))
21
+ ::File.open(destination, 'w') do |file|
22
22
  file.puts config_file_source_content
23
23
  end
24
-
25
- puts "\t#{display_name} CI configuration added"
26
24
  end
27
25
 
28
26
  private
29
27
 
30
28
  def config_file_source_content
31
- File.read(config_file_source)
29
+ ::File.read(config_file_source)
32
30
  end
33
31
 
34
32
  #
@@ -36,9 +34,9 @@ module RSGem
36
34
  #
37
35
  def remove_travis(context)
38
36
  travis_path = "#{context.folder_path}/.travis.yml"
39
- return unless File.exist?(travis_path)
37
+ return unless ::File.exist?(travis_path)
40
38
 
41
- File.delete(travis_path)
39
+ ::File.delete(travis_path)
42
40
  end
43
41
  end
44
42
  end
@@ -17,7 +17,7 @@ module RSGem
17
17
 
18
18
  example [
19
19
  'foo # Creates a new gem called foo',
20
- 'bar --ci=github_actions # Creates a new gem called bar, with GitHub Actions as the '\
20
+ 'bar --ci=travis # Creates a new gem called bar, with Travis as the '\
21
21
  'CI provider',
22
22
  'foo_bar --bundler=--ext # Creates a new gem called foo_bar passing the --ext flag to '\
23
23
  'bundler'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ class Colors
5
+ MAPPING = {
6
+ default: 39,
7
+ red: 31,
8
+ green: 32,
9
+ yellow: 33,
10
+ blue: 34,
11
+ white: 97
12
+ }.freeze
13
+
14
+ class << self
15
+ def colorize(string, color)
16
+ "\e[#{color_code(color)}m#{string}\e[0m"
17
+ end
18
+
19
+ def color_code(color)
20
+ MAPPING[color] || MAPPING[:default]
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,6 +6,6 @@ module RSGem
6
6
  RSGem::CIProviders::GithubActions,
7
7
  RSGem::CIProviders::Travis
8
8
  ].freeze
9
- DEFAULT_CI_PROVIDER = RSGem::CIProviders::Travis
9
+ DEFAULT_CI_PROVIDER = RSGem::CIProviders::GithubActions
10
10
  end
11
11
  end
@@ -7,7 +7,7 @@ module RSGem
7
7
  def initialize(options:)
8
8
  @options = options
9
9
 
10
- raise MissingGemNameError unless options[:gem_name]
10
+ raise Errors::MissingGemName unless options[:gem_name]
11
11
  end
12
12
 
13
13
  def bundler_options
@@ -16,10 +16,12 @@ module RSGem
16
16
 
17
17
  def ci_provider
18
18
  @ci_provider ||= begin
19
- return RSGem::Constants::DEFAULT_CI_PROVIDER unless (name = options[:ci_provider])
20
-
21
- RSGem::Constants::CI_PROVIDERS.detect do |provider|
22
- provider.name == name
19
+ if (name = options[:ci_provider])
20
+ RSGem::Constants::CI_PROVIDERS.detect do |provider|
21
+ provider.name == name
22
+ end
23
+ else
24
+ RSGem::Constants::DEFAULT_CI_PROVIDER
23
25
  end
24
26
  end
25
27
  end
@@ -36,6 +38,10 @@ module RSGem
36
38
  "#{folder_path}/#{gem_name}.gemspec"
37
39
  end
38
40
 
41
+ def license_path
42
+ "#{folder_path}/LICENSE.txt"
43
+ end
44
+
39
45
  def folder_path
40
46
  `pwd`.sub("\n", '/') + gem_name
41
47
  end
@@ -47,5 +53,9 @@ module RSGem
47
53
  def rakefile_path
48
54
  "#{folder_path}/Rakefile"
49
55
  end
56
+
57
+ def spec_helper_path
58
+ "#{folder_path}/spec/spec_helper.rb"
59
+ end
50
60
  end
51
61
  end
@@ -3,14 +3,16 @@
3
3
  module RSGem
4
4
  module Dependencies
5
5
  class Base
6
- attr_reader :config_file_destination, :config_file_source, :mode, :name, :version
6
+ attr_reader :config_file_destination, :config_file_source, :mode, :name, :post_install_task,
7
+ :version
7
8
 
8
- def initialize(config_file_source: nil, config_file_destination: nil, mode: :development,
9
- name:, version: nil)
10
- @config_file_source = config_file_source
11
- @config_file_destination = config_file_destination
12
- @mode = mode # Either `development' or `runtime'
9
+ def initialize(name:, **args)
10
+ @config_file_source = args[:config_file_source]
11
+ @config_file_destination = args[:config_file_destination]
12
+ @mode = args[:mode] || 'development' # Either `development' or `runtime'
13
13
  @name = name
14
+ @post_install_task = args[:post_install_task]
15
+ version = args[:version]
14
16
  @version = version ? "'#{version}'" : nil
15
17
  end
16
18
 
@@ -21,7 +23,7 @@ module RSGem
21
23
  end
22
24
  end
23
25
 
24
- puts "\t#{name.capitalize} installed"
26
+ post_install_task&.new(context: context)&.perform
25
27
  end
26
28
 
27
29
  private
@@ -5,7 +5,7 @@ module RSGem
5
5
  Rubocop = Base.new(
6
6
  config_file_source: "#{File.dirname(__FILE__)}/../support/rubocop.yml",
7
7
  config_file_destination: '.rubocop.yml',
8
- name: 'rubocop'
8
+ name: 'rubocop-rootstrap'
9
9
  )
10
10
  end
11
11
  end
@@ -4,6 +4,7 @@ module RSGem
4
4
  module Dependencies
5
5
  # This is the latest stable version working correctly with codeclimate
6
6
  # 0.18+ does not work currently https://github.com/codeclimate/test-reporter/issues/413
7
- Simplecov = Base.new(name: 'simplecov', version: '~> 0.17.1')
7
+ Simplecov = Base.new(name: 'simplecov', version: '~> 0.17.1',
8
+ post_install_task: RSGem::Tasks::SimpleCovPostInstall)
8
9
  end
9
10
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Errors
5
+ class Base < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Errors
5
+ class MissingGemName < Base
6
+ end
7
+ end
8
+ end
@@ -9,7 +9,9 @@ module RSGem
9
9
  end
10
10
 
11
11
  def create
12
+ puts 'Creating gem...'
12
13
  create_gem
14
+ ensure_author
13
15
  add_code_analysis
14
16
  add_dependencies
15
17
  clean_gemfile
@@ -17,18 +19,21 @@ module RSGem
17
19
  add_ci_provider
18
20
  clean_gemspec
19
21
  set_bundled_files
22
+ set_license_file
23
+ set_required_ruby_version
20
24
  bundle_dependencies
21
25
  run_rubocop
26
+ puts "#{context.gem_name} created"
22
27
  end
23
28
 
24
29
  private
25
30
 
26
31
  def add_ci_provider
27
- context.ci_provider.install(context)
32
+ Tasks::AddCIProvider.new(context: context).call
28
33
  end
29
34
 
30
35
  def add_code_analysis
31
- Tasks::AddCodeAnalysis.new(context: context).add
36
+ Tasks::AddCodeAnalysis.new(context: context).call
32
37
  end
33
38
 
34
39
  def add_dependencies
@@ -39,16 +44,16 @@ module RSGem
39
44
  Dependencies::Rubocop,
40
45
  Dependencies::Simplecov
41
46
  ].each do |dependency|
42
- Tasks::AddDependency.new(context: context, dependency: dependency).add
47
+ Tasks::AddDependency.new(context: context, dependency: dependency).call
43
48
  end
44
49
  end
45
50
 
46
51
  def clean_gemfile
47
- Tasks::CleanGemfile.new(context: context).clean
52
+ Tasks::CleanGemfile.new(context: context).call
48
53
  end
49
54
 
50
55
  def clean_gemspec
51
- Tasks::CleanGemspec.new(context: context).clean
56
+ Tasks::CleanGemspec.new(context: context).call
52
57
  end
53
58
 
54
59
  def context
@@ -56,23 +61,35 @@ module RSGem
56
61
  end
57
62
 
58
63
  def create_gem
59
- Tasks::CreateGem.new(context: context).create
64
+ Tasks::CreateGem.new(context: context).call
65
+ end
66
+
67
+ def ensure_author
68
+ Tasks::EnsureAuthor.new(context: context).call
60
69
  end
61
70
 
62
71
  def ignore_gemfile_lock
63
- Tasks::IgnoreGemfileLock.new(context: context).ignore
72
+ Tasks::IgnoreGemfileLock.new(context: context).call
64
73
  end
65
74
 
66
75
  def run_rubocop
67
- Tasks::RunRubocop.new(context: context).run
76
+ Tasks::RunRubocop.new(context: context).call
68
77
  end
69
78
 
70
79
  def bundle_dependencies
71
- Tasks::BundleDependencies.new(context: context).run
80
+ Tasks::BundleDependencies.new(context: context).call
72
81
  end
73
82
 
74
83
  def set_bundled_files
75
- Tasks::SetBundledFiles.new(context: context).set
84
+ Tasks::SetBundledFiles.new(context: context).call
85
+ end
86
+
87
+ def set_license_file
88
+ Tasks::SetLicenseFile.new(context: context).call
89
+ end
90
+
91
+ def set_required_ruby_version
92
+ Tasks::SetRequiredRubyVersion.new(context: context).call
76
93
  end
77
94
  end
78
95
  end
@@ -1,6 +1,6 @@
1
1
  name: ci
2
2
 
3
- on: push
3
+ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
@@ -15,6 +15,11 @@ jobs:
15
15
  uses: actions/setup-ruby@v1
16
16
  with:
17
17
  ruby-version: ${{ matrix.ruby_version }}
18
+ - name: Calculate variable dynamic values
19
+ id: dynamic_values
20
+ run: |
21
+ echo "::set-output name=installed_ruby_version::$(ruby -e 'print RUBY_VERSION')"
22
+ echo "::set-output name=cacheTimeAnchor::$(ruby -e 'require %Q{date}; cacheExpirationSeconds = 60*60*24; print (Time.now.to_i / cacheExpirationSeconds)')"
18
23
  - name: Download CodeClimate reporter
19
24
  run: |
20
25
  curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
@@ -22,12 +27,25 @@ jobs:
22
27
  ./cc-test-reporter before-build
23
28
  env:
24
29
  CC_TEST_REPORTER_ID: get_a_test_reporter_id_from_code_climate
25
- - name: Build and test
30
+ - name: Install and config bundler
31
+ run: |
32
+ gem install bundler:2.1.4
33
+ - name: Generate 'Gemfile.lock' before caching gems
34
+ run: |
35
+ bundle lock --update
36
+ - uses: actions/cache@v2
37
+ with:
38
+ path: vendor/bundle
39
+ key: ${{ runner.os }}-ruby_v${{ steps.dynamic_values.outputs.installed_ruby_version }}-time_${{steps.dynamic_values.outputs.cacheTimeAnchor}}-gems-${{ hashFiles('**/Gemfile.lock') }}
40
+ - name: Install dependencies
26
41
  run: |
27
- gem install bundler:1.17.3
28
- bundle update
42
+ bundle config set path 'vendor/bundle'
29
43
  bundle install --jobs 4 --retry 3
44
+ - name: Run code analysis
45
+ run: |
30
46
  bundle exec rake code_analysis
47
+ - name: Run tests
48
+ run: |
31
49
  bundle exec rspec
32
50
  - name: Report to CodeClimate
33
51
  run: |
@@ -1,67 +1,8 @@
1
- Style/Documentation:
2
- Enabled: false
3
-
4
- Layout/SpaceBeforeFirstArg:
5
- Exclude:
6
-
7
- Lint/AmbiguousBlockAssociation:
8
- Exclude:
9
- - spec/**/*
10
-
11
- Metrics/AbcSize:
12
- # The ABC size is a calculated magnitude, so this number can be an Integer or
13
- # a Float.
14
- Max: 15
15
-
16
- Metrics/BlockLength:
17
- CountComments: false
18
- Max: 25
19
- Exclude:
20
- - '*.gemspec'
21
- - config/**/*
22
- - spec/**/*
23
- ExcludedMethods:
24
- - class_methods
25
-
26
- Metrics/BlockNesting:
27
- Max: 4
28
-
29
- Metrics/ClassLength:
30
- CountComments: false
31
- Max: 200
32
-
33
- # Avoid complex methods.
34
- Metrics/CyclomaticComplexity:
35
- Max: 7
36
-
37
- Metrics/MethodLength:
38
- CountComments: false
39
- Max: 24
40
-
41
- Metrics/ModuleLength:
42
- CountComments: false
43
- Max: 200
44
-
45
- Layout/LineLength:
46
- Max: 100
47
- # To make it possible to copy or click on URIs in the code, we allow lines
48
- # containing a URI to be longer than Max.
49
- AllowURI: true
50
- URISchemes:
51
- - http
52
- - https
53
-
54
- Metrics/ParameterLists:
55
- Max: 5
56
- CountKeywordArgs: true
57
-
58
- Metrics/PerceivedComplexity:
59
- Max: 12
60
-
61
- Style/FrozenStringLiteralComment:
62
- Enabled: true
1
+ inherit_gem:
2
+ rubocop-rootstrap:
3
+ - config/default_edge.yml
63
4
 
64
- Style/ModuleFunction:
5
+ Gemspec/RequiredRubyVersion:
65
6
  Enabled: false
66
7
 
67
8
  Style/RescueModifier:
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ class AddCIProvider < Base
6
+ OUTPUT = OutputStruct.new(name: :output_name)
7
+
8
+ def perform
9
+ context.ci_provider.install(context)
10
+ end
11
+
12
+ def output_name
13
+ "Add CI configuration for #{context.ci_provider.display_name}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,14 +2,10 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class AddCodeAnalysis
6
- attr_reader :context
5
+ class AddCodeAnalysis < Base
6
+ OUTPUT = OutputStruct.new(name: 'Add code analysis')
7
7
 
8
- def initialize(context:)
9
- @context = context
10
- end
11
-
12
- def add
8
+ def perform
13
9
  File.open(context.rakefile_path, 'w') do |file|
14
10
  file.puts rakefile
15
11
  end
@@ -2,15 +2,10 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class AddDependency
6
- attr_reader :context, :dependency
5
+ class AddDependency < Base
6
+ OUTPUT = OutputStruct.new(name: :output_name)
7
7
 
8
- def initialize(context:, dependency:)
9
- @context = context
10
- @dependency = dependency
11
- end
12
-
13
- def add
8
+ def perform
14
9
  return if already_installed?
15
10
 
16
11
  add_dependency
@@ -34,10 +29,18 @@ module RSGem
34
29
  text.compact.join(', ')
35
30
  end
36
31
 
32
+ def dependency
33
+ args[:dependency]
34
+ end
35
+
37
36
  def gemspec_file
38
37
  @gemspec_file ||= File.read(context.gemspec_path)
39
38
  end
40
39
 
40
+ def output_name
41
+ "Install #{dependency.name.capitalize}"
42
+ end
43
+
41
44
  def write_to_gemspec
42
45
  File.open(context.gemspec_path, 'w') do |file|
43
46
  file.puts gemspec_file
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ #
6
+ # Base class for task objects.
7
+ # Child classes must implement the instance method +perform+.
8
+ #
9
+ class Base
10
+ include Output
11
+
12
+ attr_reader :context, :args
13
+
14
+ def initialize(context:, **args)
15
+ @context = context
16
+ @args = args
17
+ end
18
+
19
+ def call
20
+ with_output do
21
+ perform
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,23 +2,13 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class BundleDependencies
6
- attr_reader :context, :output
5
+ class BundleDependencies < Base
6
+ OUTPUT = OutputStruct.new(name: 'Bundle dependencies')
7
7
 
8
- def initialize(context:)
9
- @context = context
10
- end
11
-
12
- def run
13
- puts "\tRunning bundle install:"
14
- @output = `cd #{context.folder_path} && bundle`
15
- puts "\t\t#{last_line}"
16
- end
17
-
18
- private
8
+ def perform
9
+ return if system("cd #{context.folder_path} && bundle", out: '/dev/null')
19
10
 
20
- def last_line
21
- @output.split("\n").last
11
+ raise RSGem::Errors::Base
22
12
  end
23
13
  end
24
14
  end
@@ -13,18 +13,13 @@ module RSGem
13
13
  #
14
14
  # https://github.com/rootstrap/tech-guides/blob/master/open-source/developing_gems.md#gemfilegemfilelockgemspec
15
15
  #
16
- class CleanGemfile
17
- attr_reader :context
16
+ class CleanGemfile < Base
17
+ OUTPUT = OutputStruct.new(name: 'Clean gemfile')
18
18
 
19
- def initialize(context:)
20
- @context = context
21
- end
22
-
23
- def clean
19
+ def perform
24
20
  gemfile.gsub!(/gem .+\n/, '') # Remove all gem definitions
25
21
  gemfile.sub!(/\n\z/, '') # Remove last new line character
26
22
  write_to_gemfile
27
- puts "\tGemfile cleaned"
28
23
  end
29
24
 
30
25
  private
@@ -2,16 +2,11 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class CleanGemspec
6
- attr_reader :context
7
-
5
+ class CleanGemspec < Base
6
+ OUTPUT = OutputStruct.new(name: 'Clean gemspec')
8
7
  KEYS_TO_EMPTY = %w[summary description homepage].freeze
9
8
 
10
- def initialize(context:)
11
- @context = context
12
- end
13
-
14
- def clean
9
+ def perform
15
10
  comment_metadata!
16
11
  empty_keys!
17
12
  write
@@ -2,16 +2,17 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class CreateGem
6
- attr_reader :context
5
+ class CreateGem < Base
6
+ OUTPUT = OutputStruct.new(
7
+ name: 'Create gem',
8
+ success: :success_message
9
+ )
7
10
 
8
- def initialize(context:)
9
- @context = context
10
- end
11
+ def perform
12
+ return if system(shell_command, out: '/dev/null')
11
13
 
12
- def create
13
- system shell_command
14
- puts message
14
+ raise RSGem::Errors::Base, "Failed to run `bundle gem'. Check bundler is installed in "\
15
+ "your system or install it with `gem install bundler'.`"
15
16
  end
16
17
 
17
18
  private
@@ -20,16 +21,13 @@ module RSGem
20
21
  context.bundler_options
21
22
  end
22
23
 
23
- def message
24
- [
25
- "\tGem created",
26
- ("with options: #{bundler_options}" if bundler_options)
27
- ].compact.join(' ')
24
+ def success_message
25
+ "Gem created with bundler options: #{bundler_options}" if bundler_options
28
26
  end
29
27
 
30
28
  def shell_command
31
29
  [
32
- "bundle gem #{context.gem_name}",
30
+ "bundle gem #{context.gem_name} --test=rspec --coc --mit",
33
31
  bundler_options
34
32
  ].compact.join(' ')
35
33
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ class EnsureAuthor < Base
6
+ OUTPUT = OutputStruct.new(
7
+ name: 'Ensure author',
8
+ warning: :warning_message
9
+ )
10
+ TEMP_USERNAME = 'change_me'
11
+ TEMP_EMAIL = 'change_me@notanemail.com'
12
+
13
+ def perform
14
+ ensure_author
15
+ end
16
+
17
+ private
18
+
19
+ def gemspec
20
+ @gemspec ||= File.read(context.gemspec_path)
21
+ end
22
+
23
+ def write_gemspec
24
+ File.write(context.gemspec_path, gemspec)
25
+ end
26
+
27
+ def ensure_author
28
+ return unless missing_git_user?
29
+
30
+ gemspec.gsub!(/spec.email\s+=\s+.+/,
31
+ "spec.email = ['#{TEMP_EMAIL}']")
32
+
33
+ gemspec.gsub!(/spec.authors\s+=\s+.+/,
34
+ "spec.authors = ['#{TEMP_USERNAME}']")
35
+ write_gemspec
36
+ end
37
+
38
+ def missing_git_user?
39
+ `git config user.email`.strip.empty? || `git config user.name`.strip.empty?
40
+ end
41
+
42
+ def warning_message
43
+ return unless missing_git_user?
44
+
45
+ "No git user set. Setting #{TEMP_EMAIL} and #{TEMP_USERNAME} in gemspec, "\
46
+ 'please change this before publishing your gem.'
47
+ end
48
+ end
49
+ end
50
+ end
@@ -7,17 +7,12 @@ module RSGem
7
7
  #
8
8
  # https://github.com/rootstrap/tech-guides/blob/master/open-source/developing_gems.md#gemfilegemfilelockgemspec
9
9
  #
10
- class IgnoreGemfileLock
11
- attr_reader :context
10
+ class IgnoreGemfileLock < Base
11
+ OUTPUT = OutputStruct.new(name: 'Ignore gemfile.lock')
12
12
 
13
- def initialize(context:)
14
- @context = context
15
- end
16
-
17
- def ignore
13
+ def perform
18
14
  gitignore << "\nGemfile.lock\n"
19
15
  write_to_gitignore
20
- puts "\tGemfile.lock added to .gitignore"
21
16
  end
22
17
 
23
18
  private
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ #
6
+ # Structure to bundle all messages from a task
7
+ #
8
+ OutputStruct = Struct.new(:name, :success, :warning, keyword_init: true)
9
+
10
+ module Output
11
+ def with_output
12
+ yield
13
+ puts "\t#{Colors.colorize('[OK]', :green)} #{name}"
14
+ puts "\t#{success}" if success
15
+ puts "\t#{Colors.colorize('Warning: ', :yellow)} #{warning}" if warning
16
+ rescue RSGem::Errors::Base => e
17
+ puts "\t#{Colors.colorize('[X]', :red)} #{e.message}"
18
+ raise e
19
+ end
20
+
21
+ private
22
+
23
+ def deduce_output(value)
24
+ case value
25
+ when String
26
+ value
27
+ when Symbol
28
+ send(value)
29
+ when Proc
30
+ value.call
31
+ end
32
+ end
33
+
34
+ def name
35
+ deduce_output(self.class::OUTPUT.name || self.class.name)
36
+ end
37
+
38
+ def success
39
+ deduce_output(self.class::OUTPUT.success)
40
+ end
41
+
42
+ def warning
43
+ deduce_output(self.class::OUTPUT.warning)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -2,23 +2,14 @@
2
2
 
3
3
  module RSGem
4
4
  module Tasks
5
- class RunRubocop
6
- attr_reader :context, :output
5
+ class RunRubocop < Base
6
+ OUTPUT = OutputStruct.new(name: 'Run rubocop')
7
7
 
8
- def initialize(context:)
9
- @context = context
10
- end
11
-
12
- def run
13
- puts "\tRubocop:"
14
- @output = `cd #{context.folder_path} && bundle exec rubocop -a`
15
- puts "\t\t#{last_line}"
16
- end
17
-
18
- private
8
+ def perform
9
+ return if system("cd #{context.folder_path} && bundle exec rubocop -A",
10
+ %i[out err] => '/dev/null')
19
11
 
20
- def last_line
21
- @output.split("\n").last
12
+ raise RSGem::Errors::Base, 'Failed to run `bundle exec rubocop -A\''
22
13
  end
23
14
  end
24
15
  end
@@ -11,14 +11,10 @@ module RSGem
11
11
  # - README.md
12
12
  # - lib/**/* (everything inside lib)
13
13
  #
14
- class SetBundledFiles
15
- attr_reader :context
14
+ class SetBundledFiles < Base
15
+ OUTPUT = OutputStruct.new(name: 'Set bundled files')
16
16
 
17
- def initialize(context:)
18
- @context = context
19
- end
20
-
21
- def set
17
+ def perform
22
18
  # Explaining the regular expression:
23
19
  # [spec.files][one or more white spaces][=][one or more white spaces][anything until "do"]
24
20
  # [new line][anything until new line]
@@ -28,8 +24,6 @@ module RSGem
28
24
  "spec.files = Dir['LICENSE.txt', 'README.md', 'lib/**/*']"
29
25
  )
30
26
  write
31
-
32
- puts "\tGemspec files config updated"
33
27
  end
34
28
 
35
29
  private
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ class SetLicenseFile < Base
6
+ OUTPUT = OutputStruct.new(name: 'Set license file')
7
+
8
+ def perform
9
+ license.gsub!(
10
+ /.*Copyright.*/,
11
+ "Copyright (c) #{Date.today.year} Rootstrap"
12
+ )
13
+ write
14
+ end
15
+
16
+ private
17
+
18
+ def license
19
+ @license ||= File.read(context.license_path)
20
+ end
21
+
22
+ def write
23
+ File.open(context.license_path, 'w') do |file|
24
+ file.puts license
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ class SetRequiredRubyVersion < Base
6
+ OUTPUT = OutputStruct.new(name: 'Set required Ruby version')
7
+
8
+ def perform
9
+ set_required_ruby_version
10
+ write
11
+ end
12
+
13
+ private
14
+
15
+ def set_required_ruby_version
16
+ gemspec.gsub!(
17
+ /(spec.required_ruby_version.*)=(.*)\n/,
18
+ "spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')\n"
19
+ )
20
+ end
21
+
22
+ def gemspec
23
+ @gemspec ||= File.read(context.gemspec_path)
24
+ end
25
+
26
+ def write
27
+ File.open(context.gemspec_path, 'w') do |file|
28
+ file.puts gemspec
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSGem
4
+ module Tasks
5
+ class SimpleCovPostInstall < Base
6
+ OUTPUT = OutputStruct.new
7
+ def perform
8
+ spec_helper.sub!("require \"#{gem_name}\"", <<~RUBY)
9
+ require 'simplecov'
10
+
11
+ SimpleCov.start do
12
+ add_filter '/spec/'
13
+ end
14
+
15
+ require '#{gem_name}'
16
+ RUBY
17
+
18
+ write
19
+ end
20
+
21
+ private
22
+
23
+ def gem_name
24
+ context.gem_name
25
+ end
26
+
27
+ def spec_helper
28
+ @spec_helper ||= File.read(context.spec_helper_path)
29
+ end
30
+
31
+ def write
32
+ File.open(context.spec_helper_path, 'w') do |file|
33
+ file.puts spec_helper
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSGem
4
- MAJOR = 0
4
+ MAJOR = 1
5
5
  MINOR = 1
6
- PATCH = 3
6
+ PATCH = 0
7
7
  VERSION = [MAJOR, MINOR, PATCH].join('.')
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsgem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Manuel Ramallo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-24 00:00:00.000000000 Z
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-cli
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.13.0
33
+ version: 0.13.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.13.0
40
+ version: 0.13.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 13.0.1
55
- - !ruby/object:Gem::Dependency
56
- name: reek
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 5.6.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 5.6.0
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rspec
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -81,19 +67,19 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: 3.9.0
83
69
  - !ruby/object:Gem::Dependency
84
- name: rubocop
70
+ name: rubocop-rootstrap
85
71
  requirement: !ruby/object:Gem::Requirement
86
72
  requirements:
87
73
  - - "~>"
88
74
  - !ruby/object:Gem::Version
89
- version: 0.80.0
75
+ version: 1.0.0
90
76
  type: :development
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
- version: 0.80.0
82
+ version: 1.0.0
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: simplecov
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +94,7 @@ dependencies:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
96
  version: 0.17.1
111
- description:
97
+ description:
112
98
  email:
113
99
  - ramallojuanm@gmail.com
114
100
  executables:
@@ -129,6 +115,7 @@ files:
129
115
  - lib/rsgem/cli/commands.rb
130
116
  - lib/rsgem/cli/commands/new.rb
131
117
  - lib/rsgem/cli/commands/version.rb
118
+ - lib/rsgem/colors.rb
132
119
  - lib/rsgem/constants.rb
133
120
  - lib/rsgem/context.rb
134
121
  - lib/rsgem/dependencies/base.rb
@@ -137,22 +124,30 @@ files:
137
124
  - lib/rsgem/dependencies/rspec.rb
138
125
  - lib/rsgem/dependencies/rubocop.rb
139
126
  - lib/rsgem/dependencies/simplecov.rb
140
- - lib/rsgem/errors/missing_gem_name_error.rb
127
+ - lib/rsgem/errors/base.rb
128
+ - lib/rsgem/errors/missing_gem_name.rb
141
129
  - lib/rsgem/gem.rb
142
130
  - lib/rsgem/support/Rakefile
143
131
  - lib/rsgem/support/github_actions.yml
144
132
  - lib/rsgem/support/reek.yml
145
133
  - lib/rsgem/support/rubocop.yml
146
134
  - lib/rsgem/support/travis.yml
135
+ - lib/rsgem/tasks/add_ci_provider.rb
147
136
  - lib/rsgem/tasks/add_code_analysis.rb
148
137
  - lib/rsgem/tasks/add_dependency.rb
138
+ - lib/rsgem/tasks/base.rb
149
139
  - lib/rsgem/tasks/bundle_dependencies.rb
150
140
  - lib/rsgem/tasks/clean_gemfile.rb
151
141
  - lib/rsgem/tasks/clean_gemspec.rb
152
142
  - lib/rsgem/tasks/create_gem.rb
143
+ - lib/rsgem/tasks/ensure_author.rb
153
144
  - lib/rsgem/tasks/ignore_gemfile_lock.rb
145
+ - lib/rsgem/tasks/output.rb
154
146
  - lib/rsgem/tasks/run_rubocop.rb
155
147
  - lib/rsgem/tasks/set_bundled_files.rb
148
+ - lib/rsgem/tasks/set_license_file.rb
149
+ - lib/rsgem/tasks/set_required_ruby_version.rb
150
+ - lib/rsgem/tasks/simple_cov_post_install.rb
156
151
  - lib/rsgem/version.rb
157
152
  homepage: https://github.com/rootstrap/rsgem
158
153
  licenses:
@@ -160,7 +155,7 @@ licenses:
160
155
  metadata:
161
156
  homepage_uri: https://github.com/rootstrap/rsgem
162
157
  source_code_uri: https://github.com/rootstrap/rsgem
163
- post_install_message:
158
+ post_install_message:
164
159
  rdoc_options: []
165
160
  require_paths:
166
161
  - lib
@@ -176,7 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
176
171
  version: '0'
177
172
  requirements: []
178
173
  rubygems_version: 3.1.2
179
- signing_key:
174
+ signing_key:
180
175
  specification_version: 4
181
176
  summary: Generating gems the Rootstrap way
182
177
  test_files: []
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RSGem
4
- class MissingGemNameError < StandardError
5
- end
6
- end