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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +6 -1
- data/Guardfile +16 -0
- data/bin/safedep +2 -1
- data/lib/safedep/abstract_dependency.rb +13 -1
- data/lib/safedep/cli.rb +14 -2
- data/lib/safedep/cli/option_parser.rb +13 -6
- data/lib/safedep/configuration.rb +11 -0
- data/lib/safedep/error.rb +3 -0
- data/lib/safedep/gemfile/dependency.rb +45 -0
- data/lib/safedep/gemspec/dependency.rb +9 -0
- data/lib/safedep/runner.rb +36 -6
- data/lib/safedep/version.rb +2 -2
- data/spec/.rubocop.yml +18 -0
- data/spec/safedep/cli_spec.rb +48 -0
- data/spec/safedep/gemfile/dependency_spec.rb +57 -9
- data/spec/safedep/gemfile_lock_spec.rb +1 -59
- data/spec/safedep/gemfile_spec.rb +1 -20
- data/spec/safedep/gemspec/dependency_spec.rb +21 -9
- data/spec/safedep/gemspec_spec.rb +4 -20
- data/spec/safedep/runner_spec.rb +79 -0
- data/spec/support/shared_contexts.rb +105 -0
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96720d6f9fd7630c262b4c014d255ffef22a4d5e
|
4
|
+
data.tar.gz: 2f070274f4cf9a60d69ae3096b895a3ec810ef6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
@@ -9,7 +9,7 @@ module Safedep
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.method_names
|
12
|
-
fail
|
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
|
-
|
12
|
-
|
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
|
-
|
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 =
|
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
|
]
|
@@ -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
|
data/lib/safedep/runner.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
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
|
-
|
19
|
+
validate!
|
13
20
|
|
14
21
|
dependencies.each do |dep|
|
15
|
-
next if dep
|
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 ||=
|
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 ||=
|
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)
|
data/lib/safedep/version.rb
CHANGED
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(:
|
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(:
|
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('
|
27
|
-
expect(dependency.name).to eq('
|
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(
|
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
|
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
|