safedep 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|