safedep 0.0.2 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f81a9a095d287d0acfa6085600c2c91b1fd51886
4
- data.tar.gz: 695497fc629e33cf1815523fbdf9efb63590fd04
3
+ metadata.gz: 96720d6f9fd7630c262b4c014d255ffef22a4d5e
4
+ data.tar.gz: 2f070274f4cf9a60d69ae3096b895a3ec810ef6d
5
5
  SHA512:
6
- metadata.gz: a3800b441e6346922281067c09726085e522dbf472227c18cb8ed7679754fa9535b2f85be8b189fc830964bb89f2565db680deea9f735d1839487f6b31c40daf
7
- data.tar.gz: 6301c82baa0a18e2f30e7e9283fb87fbd3056f6698358094a6d96bc736328c60d0c79720ffae31bb68fe848205deb53aa7fecb2f91199c53e4995e8b3e1a0c30
6
+ metadata.gz: 8132af95ac774d2e2236620ed445b2e8a0e864d00b5ce74a9023ca10da5003d54c8668562e4cb9c71b495e15c604020d2d15066df1437fe6d7f83b4561dadcf6
7
+ data.tar.gz: e4ccdaad7dec69b7067e26059fdb6d76be72b6442d897150a9c97cd77ffcd9559891c52c0e93b2e92411676192684f0f96f7e848e274f29c588867d5327ec2c6
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v0.1.0
6
+
7
+ * Add `--without` option for skipping arbitrary groups.
8
+ * Abort processing if `Gemfile` or `Gemfile.lock` does not exist.
9
+
5
10
  ## v0.0.2
6
11
 
7
12
  * Fix an error when a `Gemfile` includes `bundler` dependency without version specifier.
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in safedep.gemspec
4
3
  gemspec
5
4
 
6
5
  group :development, :test do
@@ -11,6 +10,12 @@ group :development, :test do
11
10
  gem 'simplecov', '~> 0.9'
12
11
  end
13
12
 
13
+ group :development do
14
+ gem 'guard-rspec', '~> 4.5'
15
+ gem 'guard-rubocop', '~> 1.2'
16
+ gem 'fuubar', '~> 2.0'
17
+ end
18
+
14
19
  group :test do
15
20
  gem 'coveralls', '~> 0.7'
16
21
  end
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+
2
+ # This group allows to skip running RuboCop if RSpec failed,
3
+ # like Red > Green (RSpec) > Refactor (RuboCop).
4
+ group :red_green_refactor, halt_on_fail: true do
5
+ guard :rspec, cmd: 'bundle exec rspec --format Fuubar' do
6
+ watch(%r{^spec/.+_spec\.rb$})
7
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
8
+ watch('spec/spec_helper.rb') { 'spec' }
9
+ watch(%r{^spec/support/.+\.rb$}) { 'spec' }
10
+ end
11
+
12
+ guard :rubocop, all_on_start: false, cli: '--format fuubar' do
13
+ watch(%r{.+\.rb$})
14
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
15
+ end
16
+ end
data/bin/safedep CHANGED
@@ -3,4 +3,5 @@
3
3
  $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
4
  require 'safedep/cli'
5
5
 
6
- Safedep::CLI.run
6
+ result = Safedep::CLI.run
7
+ exit(result ? 0 : 1)
@@ -9,7 +9,7 @@ module Safedep
9
9
  end
10
10
 
11
11
  def self.method_names
12
- fail NotImplemenetedError
12
+ fail NotImplementedError
13
13
  end
14
14
 
15
15
  def initialize(node, rewriter)
@@ -22,6 +22,10 @@ module Safedep
22
22
  name_node.children.first
23
23
  end
24
24
 
25
+ def groups
26
+ fail NotImplementedError
27
+ end
28
+
25
29
  def version_specifier
26
30
  return nil unless version_specifier_node
27
31
  version_specifier_node.children.first
@@ -37,6 +41,10 @@ module Safedep
37
41
 
38
42
  private
39
43
 
44
+ def method_name
45
+ node.children[1]
46
+ end
47
+
40
48
  def name_node
41
49
  node.children[2]
42
50
  end
@@ -48,6 +56,10 @@ module Safedep
48
56
  @version_specifier_node = version_node
49
57
  end
50
58
 
59
+ def options_node
60
+ node.children[3..-1].find(&:hash_type?)
61
+ end
62
+
51
63
  def content_range_of_str_node(str_node)
52
64
  map = str_node.loc
53
65
  Parser::Source::Range.new(
data/lib/safedep/cli.rb CHANGED
@@ -8,9 +8,21 @@ module Safedep
8
8
  end
9
9
 
10
10
  def run(args)
11
- OptionParser.new.parse(args)
12
- Runner.run
11
+ option_parser.parse(args)
12
+
13
+ runner = Runner.new(option_parser.configuration)
14
+ runner.run
15
+
13
16
  puts 'Done.'
17
+
18
+ true
19
+ rescue Safedep::Error => error
20
+ warn error.message
21
+ false
22
+ end
23
+
24
+ def option_parser
25
+ @option_parser ||= OptionParser.new
14
26
  end
15
27
  end
16
28
  end
@@ -1,13 +1,13 @@
1
1
  require 'optparse'
2
+ require 'safedep/configuration'
2
3
  require 'safedep/version'
3
4
 
4
5
  module Safedep
5
6
  class OptionParser
6
- def self.parse(args)
7
- new.parse(args)
8
- end
7
+ attr_reader :configuration
9
8
 
10
- def initialize
9
+ def initialize(configuration = Configuration.new)
10
+ @configuration = configuration
11
11
  setup
12
12
  end
13
13
 
@@ -20,6 +20,10 @@ module Safedep
20
20
  private
21
21
 
22
22
  def setup
23
+ define_option('--without GROUP[,GROUP...]') do |arg|
24
+ configuration.skipped_groups = arg.split(',')
25
+ end
26
+
23
27
  define_option('--version') do
24
28
  puts Version.to_s
25
29
  exit
@@ -27,7 +31,7 @@ module Safedep
27
31
  end
28
32
 
29
33
  def define_option(*options, &block)
30
- long_option = options.find { |option| option.start_with?('--') }
34
+ long_option = options.find { |option| option.start_with?('--') }.split(' ').first
31
35
  description_lines = descriptions[long_option]
32
36
  parser.on(*options, *description_lines, &block)
33
37
  end
@@ -35,7 +39,7 @@ module Safedep
35
39
  def parser
36
40
  @parser ||= begin
37
41
  banner = "Usage: #{command_name} [options]\n\n"
38
- summary_width = 32 # Default
42
+ summary_width = 20 # Default
39
43
  indentation = ' ' * 2
40
44
  ::OptionParser.new(banner, summary_width, indentation)
41
45
  end
@@ -47,6 +51,9 @@ module Safedep
47
51
 
48
52
  def descriptions
49
53
  @descriptions ||= {
54
+ '--without' => [
55
+ 'Specify groups to skip modification as comma-separated list.'
56
+ ],
50
57
  '--version' => [
51
58
  "Show #{command_name} version."
52
59
  ]
@@ -0,0 +1,11 @@
1
+ module Safedep
2
+ class Configuration
3
+ def skipped_groups
4
+ @skipped_groups ||= []
5
+ end
6
+
7
+ def skipped_groups=(groups)
8
+ @skipped_groups = groups.map(&:to_sym)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Safedep
2
+ class Error < StandardError; end
3
+ end
@@ -1,13 +1,58 @@
1
1
  require 'safedep/abstract_dependency'
2
+ require 'astrolabe/sexp'
2
3
 
3
4
  module Safedep
4
5
  class Gemfile
5
6
  class Dependency < AbstractDependency
7
+ include Astrolabe::Sexp
8
+
6
9
  METHOD_NAMES = [:gem].freeze
7
10
 
8
11
  def self.method_names
9
12
  METHOD_NAMES
10
13
  end
14
+
15
+ def groups
16
+ @groups ||= (groups_via_block + groups_via_option).map(&:to_sym)
17
+ end
18
+
19
+ def groups_via_block
20
+ return [] unless group_node
21
+ _receiver_node, _message, *arg_nodes = *group_node
22
+ literal_nodes = arg_nodes.select { |arg_node| arg_node.sym_type? || arg_node.str_type? }
23
+ literal_nodes.map { |literal_node| literal_node.children.first }
24
+ end
25
+
26
+ def groups_via_option
27
+ return [] unless options_node
28
+
29
+ options_node.each_child_node do |pair_node|
30
+ key_node, value_node = *pair_node
31
+
32
+ next unless key_node == s(:sym, :group)
33
+
34
+ case value_node.type
35
+ when :sym
36
+ return [value_node.children.first]
37
+ when :array
38
+ literal_nodes = value_node.each_child_node(:sym, :str)
39
+ return literal_nodes.map { |literal_node| literal_node.children.first }
40
+ else
41
+ return []
42
+ end
43
+ end
44
+
45
+ []
46
+ end
47
+
48
+ def group_node
49
+ candidates = node.each_ancestor(:block).map { |block_node| block_node.children.first }
50
+
51
+ candidates.find do |send_node|
52
+ receiver_node, message, = *send_node
53
+ receiver_node.nil? && message == :group
54
+ end
55
+ end
11
56
  end
12
57
  end
13
58
  end
@@ -8,6 +8,15 @@ module Safedep
8
8
  def self.method_names
9
9
  METHOD_NAMES
10
10
  end
11
+
12
+ def groups
13
+ case method_name
14
+ when :add_development_dependency
15
+ [:development]
16
+ else
17
+ []
18
+ end
19
+ end
11
20
  end
12
21
  end
13
22
  end
@@ -1,18 +1,25 @@
1
+ require 'safedep/configuration'
1
2
  require 'safedep/gemspec'
2
3
  require 'safedep/gemfile'
3
4
  require 'safedep/gemfile_lock'
5
+ require 'safedep/error'
4
6
 
5
7
  module Safedep
6
8
  class Runner
7
- def self.run
8
- new.run
9
+ GEMFILE_PATH = 'Gemfile'.freeze
10
+ GEMFILE_LOCK_PATH = 'Gemfile.lock'.freeze
11
+
12
+ attr_reader :configuration
13
+
14
+ def initialize(configuration = Configuration.new)
15
+ @configuration = configuration
9
16
  end
10
17
 
11
18
  def run
12
- dependencies = gemfiles.map(&:dependencies).reduce(:+)
19
+ validate!
13
20
 
14
21
  dependencies.each do |dep|
15
- next if dep.version_specifier
22
+ next if should_ignore?(dep)
16
23
  lockfile_dep = gemfile_lock.find_dependency(dep.name)
17
24
  dep.version_specifier = safe_version_specifier(lockfile_dep.version)
18
25
  end
@@ -20,6 +27,15 @@ module Safedep
20
27
  gemfiles.each(&:rewrite!)
21
28
  end
22
29
 
30
+ def validate!
31
+ gemfile_lock
32
+ gemfile
33
+ end
34
+
35
+ def dependencies
36
+ @dependencies ||= gemfiles.map(&:dependencies).reduce(:+)
37
+ end
38
+
23
39
  def gemfiles
24
40
  @gemfiles ||= [gemspec, gemfile].compact
25
41
  end
@@ -32,11 +48,25 @@ module Safedep
32
48
  end
33
49
 
34
50
  def gemfile
35
- @gemfile ||= Gemfile.new('Gemfile')
51
+ @gemfile ||= begin
52
+ fail Error, "#{GEMFILE_PATH} is not found." unless File.exist?(GEMFILE_PATH)
53
+ Gemfile.new(GEMFILE_PATH)
54
+ end
36
55
  end
37
56
 
38
57
  def gemfile_lock
39
- @gemfile_lock ||= GemfileLock.new('Gemfile.lock')
58
+ @gemfile_lock ||= begin
59
+ unless File.exist?(GEMFILE_LOCK_PATH)
60
+ fail Error, "#{GEMFILE_LOCK_PATH} is not found. Please run `bundle install`."
61
+ end
62
+
63
+ GemfileLock.new(GEMFILE_LOCK_PATH)
64
+ end
65
+ end
66
+
67
+ def should_ignore?(dependency)
68
+ return true if dependency.version_specifier
69
+ !(dependency.groups & configuration.skipped_groups).empty?
40
70
  end
41
71
 
42
72
  def safe_version_specifier(version)
@@ -2,8 +2,8 @@ module Safedep
2
2
  # http://semver.org/
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 0
6
- PATCH = 2
5
+ MINOR = 1
6
+ PATCH = 0
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, PATCH].join('.')
data/spec/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+
2
+ inherit_from: ../.rubocop.yml
3
+
4
+ # Lengthen for long descriptions.
5
+ LineLength:
6
+ Max: 120
7
+
8
+ # raise_error matcher always requires {} form block.
9
+ Blocks:
10
+ Enabled: false
11
+
12
+ # Sometimes block alignment does not suit RSpec syntax.
13
+ BlockAlignment:
14
+ Enabled: false
15
+
16
+ # Suppress offences for namespace classes only with #describe.
17
+ ClassLength:
18
+ Enabled: false
@@ -0,0 +1,48 @@
1
+ require 'safedep/cli'
2
+
3
+ module Safedep
4
+ describe CLI do
5
+ include FileHelper
6
+ include_context 'isolated environment'
7
+
8
+ subject(:cli) { CLI.new }
9
+
10
+ describe '#run' do
11
+ subject(:run) { cli.run(args) }
12
+ let(:args) { [] }
13
+
14
+ context 'when run successfully', :gemfile, :lockfile do
15
+ it 'returns true' do
16
+ allow(cli).to receive(:puts)
17
+ expect(run).to be true
18
+ end
19
+ end
20
+
21
+ context 'when there is no Gemfile.lock' do
22
+ it 'warns of it' do
23
+ expect { run }.to output(/Gemfile.lock/).to_stderr
24
+ end
25
+
26
+ it 'aborts processing' do
27
+ allow(cli).to receive(:warn)
28
+ expect { run }.not_to output.to_stdout
29
+ end
30
+
31
+ it 'returns false' do
32
+ allow(cli).to receive(:warn)
33
+ expect(run).to be false
34
+ end
35
+ end
36
+
37
+ context 'when unknown error is raised' do
38
+ before do
39
+ allow(Runner).to receive(:run).and_raise('foo')
40
+ end
41
+
42
+ it 'does not rescue the error' do
43
+ expect { run }.to raise_error('foo')
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -2,18 +2,11 @@ require 'safedep/gemfile'
2
2
 
3
3
  module Safedep
4
4
  class Gemfile
5
- describe Dependency do
5
+ describe Dependency, :gemfile do
6
6
  include FileHelper
7
7
  include_context 'isolated environment'
8
8
 
9
- let(:gemfile) do
10
- create_file(path, source)
11
- Gemfile.new(path)
12
- end
13
-
14
- let(:path) { 'Gemfile' }
15
-
16
- let(:source) { <<-END.strip_indent }
9
+ let(:gemfile_source) { <<-END.strip_indent }
17
10
  source 'https://rubygems.org'
18
11
 
19
12
  gemspec
@@ -33,6 +26,61 @@ module Safedep
33
26
  end
34
27
  end
35
28
 
29
+ describe '#groups' do
30
+ subject { dependency.groups }
31
+
32
+ let(:gemfile_source) { <<-END.strip_indent }
33
+ source 'https://rubygems.org'
34
+
35
+ gem 'parser'
36
+
37
+ group :development, :test do
38
+ gem 'rake'
39
+ end
40
+
41
+ group :development do
42
+ gem 'guard'
43
+ gem 'rubocop', group: :test
44
+ end
45
+
46
+ group 'development' do
47
+ gem 'fuubar'
48
+ end
49
+
50
+ gem 'rspec', group: [:test, :development]
51
+ END
52
+
53
+ context 'when the dependency is specified in top level' do
54
+ let(:dependency) { gemfile.find_dependency('parser') }
55
+ it { should be_empty }
56
+ end
57
+
58
+ context 'when the dependency is specified in :development block' do
59
+ let(:dependency) { gemfile.find_dependency('guard') }
60
+ it { should eq([:development]) }
61
+ end
62
+
63
+ context 'when the dependency is specified in "development" block' do
64
+ let(:dependency) { gemfile.find_dependency('fuubar') }
65
+ it { should eq([:development]) }
66
+ end
67
+
68
+ context 'when the dependency is specified in :development and :test group' do
69
+ let(:dependency) { gemfile.find_dependency('rake') }
70
+ it { should eq([:development, :test]) }
71
+ end
72
+
73
+ context 'when the dependency is specified with group: [:test, :development] option' do
74
+ let(:dependency) { gemfile.find_dependency('rspec') }
75
+ it { should eq([:test, :development]) }
76
+ end
77
+
78
+ context 'when the dependency is specified with group: :test option in :development group' do
79
+ let(:dependency) { gemfile.find_dependency('rubocop') }
80
+ it { should eq([:development, :test]) }
81
+ end
82
+ end
83
+
36
84
  describe '#version_specifier' do
37
85
  subject(:version_specifier) { dependency.version_specifier }
38
86
 
@@ -1,68 +1,10 @@
1
1
  require 'safedep/gemfile_lock'
2
2
 
3
3
  module Safedep
4
- describe GemfileLock do
4
+ describe GemfileLock, :lockfile do
5
5
  include FileHelper
6
6
  include_context 'isolated environment'
7
7
 
8
- let(:lockfile) do
9
- create_file(path, source)
10
- GemfileLock.new(path)
11
- end
12
-
13
- let(:path) { 'Gemfile.lock' }
14
-
15
- let(:source) { <<-END.strip_indent }
16
- PATH
17
- remote: .
18
- specs:
19
- safedep (0.0.1)
20
- astrolabe
21
- bundler (~> 1.7)
22
- parser
23
-
24
- GEM
25
- remote: https://rubygems.org/
26
- specs:
27
- ast (2.0.0)
28
- astrolabe (1.3.0)
29
- parser (>= 2.2.0.pre.3, < 3.0)
30
- diff-lcs (1.2.5)
31
- parser (2.2.0.2)
32
- ast (>= 1.1, < 3.0)
33
- powerpack (0.0.9)
34
- rainbow (2.0.0)
35
- rake (10.4.2)
36
- rspec (3.1.0)
37
- rspec-core (~> 3.1.0)
38
- rspec-expectations (~> 3.1.0)
39
- rspec-mocks (~> 3.1.0)
40
- rspec-core (3.1.7)
41
- rspec-support (~> 3.1.0)
42
- rspec-expectations (3.1.2)
43
- diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.1.0)
45
- rspec-mocks (3.1.3)
46
- rspec-support (~> 3.1.0)
47
- rspec-support (3.1.2)
48
- rubocop (0.28.0)
49
- astrolabe (~> 1.3)
50
- parser (>= 2.2.0.pre.7, < 3.0)
51
- powerpack (~> 0.0.6)
52
- rainbow (>= 1.99.1, < 3.0)
53
- ruby-progressbar (~> 1.4)
54
- ruby-progressbar (1.7.1)
55
-
56
- PLATFORMS
57
- ruby
58
-
59
- DEPENDENCIES
60
- rake (~> 10.4)
61
- rspec (~> 3.1)
62
- rubocop (~> 0.28)
63
- safedep!
64
- END
65
-
66
8
  describe '#find_dependency' do
67
9
  it 'returns the dependency matching the passed name' do
68
10
  dependency = lockfile.find_dependency('rspec')
@@ -1,29 +1,10 @@
1
1
  require 'safedep/gemfile'
2
2
 
3
3
  module Safedep
4
- describe Gemfile do
4
+ describe Gemfile, :gemfile do
5
5
  include FileHelper
6
6
  include_context 'isolated environment'
7
7
 
8
- subject(:gemfile) do
9
- create_file(path, source)
10
- Gemfile.new(path)
11
- end
12
-
13
- let(:path) { 'Gemfile' }
14
-
15
- let(:source) { <<-END.strip_indent }
16
- source 'https://rubygems.org'
17
-
18
- gemspec
19
-
20
- group :development, :test do
21
- gem 'rake'
22
- gem 'rspec', '~> 3.1'
23
- gem 'rubocop', '~> 0.28'
24
- end
25
- END
26
-
27
8
  describe '#find_dependency' do
28
9
  it 'returns the dependency matching the passed name' do
29
10
  dependency = gemfile.find_dependency('rspec')
@@ -2,18 +2,11 @@ require 'safedep/gemspec'
2
2
 
3
3
  module Safedep
4
4
  class Gemspec
5
- describe Dependency do
5
+ describe Dependency, :gemspec do
6
6
  include FileHelper
7
7
  include_context 'isolated environment'
8
8
 
9
- let(:gemspec) do
10
- create_file(path, source)
11
- Gemspec.new(path)
12
- end
13
-
14
- let(:path) { 'example.gemspec' }
15
-
16
- let(:source) { <<-END.strip_indent }
9
+ let(:gemspec_source) { <<-END.strip_indent }
17
10
  Gem::Specification.new do |spec|
18
11
  spec.name = 'safedep'
19
12
  spec.add_dependency 'parser'
@@ -30,6 +23,25 @@ module Safedep
30
23
  end
31
24
  end
32
25
 
26
+ describe '#groups' do
27
+ subject { dependency.groups }
28
+
29
+ context 'when the dependency is specified via #add_dependency' do
30
+ let(:dependency) { gemspec.find_dependency('parser') }
31
+ it { should be_empty }
32
+ end
33
+
34
+ context 'when the dependency is specified via #add_runtime_dependency' do
35
+ let(:dependency) { gemspec.find_dependency('astrolabe') }
36
+ it { should be_empty }
37
+ end
38
+
39
+ context 'when the dependency is specified via #add_runtime_dependency' do
40
+ let(:dependency) { gemspec.find_dependency('rspec') }
41
+ it { should eq([:development]) }
42
+ end
43
+ end
44
+
33
45
  describe '#version_specifier' do
34
46
  subject(:version_specifier) { dependency.version_specifier }
35
47
 
@@ -1,36 +1,20 @@
1
1
  require 'safedep/gemspec'
2
2
 
3
3
  module Safedep
4
- describe Gemspec do
4
+ describe Gemspec, :gemspec do
5
5
  include FileHelper
6
6
  include_context 'isolated environment'
7
7
 
8
- subject(:gemspec) do
9
- create_file(path, source)
10
- Gemspec.new(path)
11
- end
12
-
13
- let(:path) { 'example.gemspec' }
14
-
15
- let(:source) { <<-END.strip_indent }
16
- Gem::Specification.new do |spec|
17
- spec.name = 'safedep'
18
- spec.add_dependency 'parser'
19
- spec.add_runtime_dependency 'astrolabe', '~> 1.3'
20
- spec.add_development_dependency 'rspec', '~> 3.1'
21
- end
22
- END
23
-
24
8
  describe '#find_dependency' do
25
9
  it 'returns the dependency matching the passed name' do
26
- dependency = gemspec.find_dependency('rspec')
27
- expect(dependency.name).to eq('rspec')
10
+ dependency = gemspec.find_dependency('parser')
11
+ expect(dependency.name).to eq('parser')
28
12
  end
29
13
  end
30
14
 
31
15
  describe '#dependencies' do
32
16
  it 'returns an array of the dependencies' do
33
- expect(gemspec.dependencies.size).to eq(3)
17
+ expect(gemspec.dependencies.size).to eq(2)
34
18
  expect(gemspec.dependencies).to all be_a(Gemspec::Dependency)
35
19
  end
36
20
  end
@@ -0,0 +1,79 @@
1
+ require 'safedep/runner'
2
+
3
+ module Safedep
4
+ describe Runner do
5
+ include FileHelper
6
+ include_context 'isolated environment'
7
+
8
+ subject(:runner) { Runner.new }
9
+
10
+ let(:configuration) { runner.configuration }
11
+
12
+ let(:expected_gemfile_source) { <<-END.strip_indent }
13
+ source 'https://rubygems.org'
14
+
15
+ gemspec
16
+
17
+ group :development, :test do
18
+ gem 'rake', '~> 10.4'
19
+ gem 'rspec', '~> 3.1'
20
+ gem 'rubocop', '~> 0.28', require: false
21
+ end
22
+ END
23
+
24
+ let(:expected_gemspec_source) { <<-END.strip_indent }
25
+ Gem::Specification.new do |spec|
26
+ spec.name = 'safedep'
27
+ spec.add_runtime_dependency 'parser', '~> 2.2'
28
+ spec.add_runtime_dependency 'astrolabe', '~> 1.3'
29
+ end
30
+ END
31
+
32
+ context 'when there is no Gemfile.lock' do
33
+ it 'raises error' do
34
+ expect { runner.run }.to raise_error(/Gemfile.lock/)
35
+ end
36
+ end
37
+
38
+ context 'when there is Gemfile.lock', :lockfile do
39
+ context 'but no Gemfile' do
40
+ it 'raises error' do
41
+ expect { runner.run }.to raise_error(/Gemfile /)
42
+ end
43
+ end
44
+
45
+ context 'and Gemfile', :gemfile do
46
+ it 'rewrites the Gemfile' do
47
+ runner.run
48
+ expect(rewritten_gemfile_source).to eq(expected_gemfile_source)
49
+ end
50
+
51
+ context 'and gemspec', :gemspec do
52
+ it 'rewrites both the Gemfile and the gemspec' do
53
+ runner.run
54
+ expect(rewritten_gemfile_source).to eq(expected_gemfile_source)
55
+ expect(rewritten_gemspec_source).to eq(expected_gemspec_source)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ context 'when Configuration#skipped_groups is specified', :gemspec, :gemfile, :lockfile do
62
+ before do
63
+ configuration.skipped_groups = ['development']
64
+ end
65
+
66
+ let(:development_dependencies) do
67
+ runner.dependencies.select { |dep| dep.groups.include?(:development) }
68
+ end
69
+
70
+ it 'does not modify dependencies that belong to any of the groups' do
71
+ development_dependencies.each do |dep|
72
+ expect(dep).not_to receive(:version_specifier=)
73
+ end
74
+
75
+ runner.run
76
+ end
77
+ end
78
+ end
79
+ end
@@ -9,3 +9,108 @@ shared_context 'isolated environment' do
9
9
  end
10
10
  end
11
11
  end
12
+
13
+ shared_context 'with gemspec', :gemspec do
14
+ let!(:gemspec) do
15
+ require 'safedep/gemspec'
16
+ create_file(gemspec_path, gemspec_source)
17
+ Safedep::Gemspec.new(gemspec_path)
18
+ end
19
+
20
+ let(:gemspec_path) { 'safedep.gemspec' }
21
+
22
+ let(:gemspec_source) { <<-END.strip_indent }
23
+ Gem::Specification.new do |spec|
24
+ spec.name = 'safedep'
25
+ spec.add_runtime_dependency 'parser'
26
+ spec.add_runtime_dependency 'astrolabe'
27
+ end
28
+ END
29
+
30
+ let(:rewritten_gemspec_source) { File.read(gemspec_path) }
31
+ end
32
+
33
+ shared_context 'with Gemfile', :gemfile do
34
+ let!(:gemfile) do
35
+ require 'safedep/gemfile'
36
+ create_file(gemfile_path, gemfile_source)
37
+ Safedep::Gemfile.new(gemfile_path)
38
+ end
39
+
40
+ let(:gemfile_path) { 'Gemfile' }
41
+
42
+ let(:gemfile_source) { <<-END.strip_indent }
43
+ source 'https://rubygems.org'
44
+
45
+ gemspec
46
+
47
+ group :development, :test do
48
+ gem 'rake'
49
+ gem 'rspec'
50
+ gem 'rubocop', require: false
51
+ end
52
+ END
53
+
54
+ let(:rewritten_gemfile_source) { File.read(gemfile_path) }
55
+ end
56
+
57
+ shared_context 'with Gemfile.lock', :lockfile do
58
+ let!(:lockfile) do
59
+ require 'safedep/gemfile_lock'
60
+ create_file(lockfile_path, lockfile_source)
61
+ Safedep::GemfileLock.new(lockfile_path)
62
+ end
63
+
64
+ let(:lockfile_path) { 'Gemfile.lock' }
65
+
66
+ let(:lockfile_source) { <<-END.strip_indent }
67
+ PATH
68
+ remote: .
69
+ specs:
70
+ safedep (0.0.1)
71
+ astrolabe
72
+ bundler (~> 1.7)
73
+ parser
74
+
75
+ GEM
76
+ remote: https://rubygems.org/
77
+ specs:
78
+ ast (2.0.0)
79
+ astrolabe (1.3.0)
80
+ parser (>= 2.2.0.pre.3, < 3.0)
81
+ diff-lcs (1.2.5)
82
+ parser (2.2.0.2)
83
+ ast (>= 1.1, < 3.0)
84
+ powerpack (0.0.9)
85
+ rainbow (2.0.0)
86
+ rake (10.4.2)
87
+ rspec (3.1.0)
88
+ rspec-core (~> 3.1.0)
89
+ rspec-expectations (~> 3.1.0)
90
+ rspec-mocks (~> 3.1.0)
91
+ rspec-core (3.1.7)
92
+ rspec-support (~> 3.1.0)
93
+ rspec-expectations (3.1.2)
94
+ diff-lcs (>= 1.2.0, < 2.0)
95
+ rspec-support (~> 3.1.0)
96
+ rspec-mocks (3.1.3)
97
+ rspec-support (~> 3.1.0)
98
+ rspec-support (3.1.2)
99
+ rubocop (0.28.0)
100
+ astrolabe (~> 1.3)
101
+ parser (>= 2.2.0.pre.7, < 3.0)
102
+ powerpack (~> 0.0.6)
103
+ rainbow (>= 1.99.1, < 3.0)
104
+ ruby-progressbar (~> 1.4)
105
+ ruby-progressbar (1.7.1)
106
+
107
+ PLATFORMS
108
+ ruby
109
+
110
+ DEPENDENCIES
111
+ rake (~> 10.4)
112
+ rspec (~> 3.1)
113
+ rubocop (~> 0.28)
114
+ safedep!
115
+ END
116
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safedep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Nakayama
@@ -66,6 +66,7 @@ files:
66
66
  - ".travis.yml"
67
67
  - CHANGELOG.md
68
68
  - Gemfile
69
+ - Guardfile
69
70
  - LICENSE.txt
70
71
  - README.md
71
72
  - Rakefile
@@ -74,6 +75,8 @@ files:
74
75
  - lib/safedep/abstract_gemfile.rb
75
76
  - lib/safedep/cli.rb
76
77
  - lib/safedep/cli/option_parser.rb
78
+ - lib/safedep/configuration.rb
79
+ - lib/safedep/error.rb
77
80
  - lib/safedep/gemfile.rb
78
81
  - lib/safedep/gemfile/dependency.rb
79
82
  - lib/safedep/gemfile_lock.rb
@@ -82,11 +85,14 @@ files:
82
85
  - lib/safedep/runner.rb
83
86
  - lib/safedep/version.rb
84
87
  - safedep.gemspec
88
+ - spec/.rubocop.yml
89
+ - spec/safedep/cli_spec.rb
85
90
  - spec/safedep/gemfile/dependency_spec.rb
86
91
  - spec/safedep/gemfile_lock_spec.rb
87
92
  - spec/safedep/gemfile_spec.rb
88
93
  - spec/safedep/gemspec/dependency_spec.rb
89
94
  - spec/safedep/gemspec_spec.rb
95
+ - spec/safedep/runner_spec.rb
90
96
  - spec/spec_helper.rb
91
97
  - spec/support/file_helper.rb
92
98
  - spec/support/shared_contexts.rb
@@ -115,11 +121,14 @@ signing_key:
115
121
  specification_version: 4
116
122
  summary: Make your Gemfile safe by adding dependency version specifiers automatically.
117
123
  test_files:
124
+ - spec/.rubocop.yml
125
+ - spec/safedep/cli_spec.rb
118
126
  - spec/safedep/gemfile/dependency_spec.rb
119
127
  - spec/safedep/gemfile_lock_spec.rb
120
128
  - spec/safedep/gemfile_spec.rb
121
129
  - spec/safedep/gemspec/dependency_spec.rb
122
130
  - spec/safedep/gemspec_spec.rb
131
+ - spec/safedep/runner_spec.rb
123
132
  - spec/spec_helper.rb
124
133
  - spec/support/file_helper.rb
125
134
  - spec/support/shared_contexts.rb