safedep 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -0
- data/lib/safedep/abstract_dependency.rb +22 -14
- data/lib/safedep/gemfile/dependency.rb +24 -21
- data/lib/safedep/gemspec/dependency.rb +10 -0
- data/lib/safedep/literal.rb +48 -0
- data/lib/safedep/policy/sem_ver.rb +52 -0
- data/lib/safedep/runner.rb +7 -5
- data/lib/safedep/util.rb +16 -0
- data/lib/safedep/version.rb +2 -2
- data/spec/safedep/gemfile/dependency_spec.rb +62 -12
- data/spec/safedep/gemspec/dependency_spec.rb +97 -18
- data/spec/safedep/literal_spec.rb +49 -0
- data/spec/safedep/policy/sem_ver_spec.rb +35 -0
- data/spec/safedep/runner_spec.rb +46 -1
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 132ffa3638720d8a67ed227359301f04ccd4e825
|
4
|
+
data.tar.gz: 9dfcd1b5e931ee79716bea0d5e967d6d034b8537
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b24aadff525f1c319c3c02470ceb20b731f461c908758abbd42369b39381e36a7bf513b71ea62e78ff52b7eef026f2bdd0a230a2ed28b0a8d5693e760cefe38e
|
7
|
+
data.tar.gz: 3b21b4c4e858c753a1d3e0a37dc96ab35d2c68578b946d8a0b75187a53b1dd95d79e6e57fcc8bccdc9f00cec8bef4983b1ab22ccbfbbb874c9588bc18ae64e22
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
## Development
|
4
4
|
|
5
|
+
## v0.2.0
|
6
|
+
|
7
|
+
* Skip modification of dependencies that have `:git`, `:github` or `:path` option.
|
8
|
+
* Handle depdendencies with prerelease version.
|
9
|
+
|
5
10
|
## v0.1.2
|
6
11
|
|
7
12
|
* Handle error raised when dependency definition is not found in `Gemfile.lock`.
|
data/Gemfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'safedep/literal'
|
2
|
+
|
1
3
|
module Safedep
|
2
4
|
class AbstractDependency
|
3
5
|
attr_reader :node, :rewriter
|
@@ -26,19 +28,24 @@ module Safedep
|
|
26
28
|
fail NotImplementedError
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
|
31
|
-
version_specifier_node.children.first
|
31
|
+
def version_specifiers
|
32
|
+
@version_specifiers ||= version_nodes.map { |node| Literal.value(node) }.flatten
|
32
33
|
end
|
33
34
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
35
|
+
def version_specifiers=(*specifiers)
|
36
|
+
source = specifiers.flatten.map { |specifier| "'#{specifier}'" }.join(', ')
|
37
|
+
|
38
|
+
if version_nodes.empty?
|
39
|
+
rewriter.insert_after(name_node.loc.expression, ", #{source}")
|
37
40
|
else
|
38
|
-
rewriter.
|
41
|
+
rewriter.replace(version_range, source)
|
39
42
|
end
|
40
43
|
end
|
41
44
|
|
45
|
+
def options
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
|
42
49
|
private
|
43
50
|
|
44
51
|
def method_name
|
@@ -49,15 +56,16 @@ module Safedep
|
|
49
56
|
node.children[2]
|
50
57
|
end
|
51
58
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
59
|
+
def trailing_nodes
|
60
|
+
node.children[3..-1]
|
61
|
+
end
|
62
|
+
|
63
|
+
def version_nodes
|
64
|
+
fail NotImplementedError
|
57
65
|
end
|
58
66
|
|
59
|
-
def
|
60
|
-
|
67
|
+
def version_range
|
68
|
+
version_nodes.first.loc.expression.join(version_nodes.last.loc.expression)
|
61
69
|
end
|
62
70
|
|
63
71
|
def content_range_of_str_node(str_node)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'safedep/abstract_dependency'
|
2
|
+
require 'safedep/util'
|
2
3
|
require 'astrolabe/sexp'
|
3
4
|
|
4
5
|
module Safedep
|
5
6
|
class Gemfile
|
6
7
|
class Dependency < AbstractDependency
|
7
|
-
include Astrolabe::Sexp
|
8
|
+
include Util, Astrolabe::Sexp
|
8
9
|
|
9
10
|
METHOD_NAMES = [:gem].freeze
|
10
11
|
|
@@ -16,33 +17,35 @@ module Safedep
|
|
16
17
|
@groups ||= (groups_via_block + groups_via_option).map(&:to_sym)
|
17
18
|
end
|
18
19
|
|
20
|
+
def options
|
21
|
+
@options ||= symbolize_keys(Literal.value(options_node) || {})
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
19
26
|
def groups_via_block
|
20
27
|
return [] unless group_node
|
21
28
|
_receiver_node, _message, *arg_nodes = *group_node
|
22
|
-
|
23
|
-
literal_nodes.map { |literal_node| literal_node.children.first }
|
29
|
+
arg_nodes.map { |node| Literal.value(node) }
|
24
30
|
end
|
25
31
|
|
26
32
|
def groups_via_option
|
27
|
-
|
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
|
33
|
+
Array(options[:group])
|
34
|
+
end
|
44
35
|
|
45
|
-
|
36
|
+
# https://github.com/bundler/bundler/blob/v1.7.11/lib/bundler/dsl.rb#L68-L70
|
37
|
+
def version_nodes
|
38
|
+
@version_nodes ||= trailing_nodes - [options_node]
|
39
|
+
end
|
40
|
+
|
41
|
+
def options_node
|
42
|
+
node = trailing_nodes.last
|
43
|
+
|
44
|
+
if node && node.hash_type?
|
45
|
+
node
|
46
|
+
else
|
47
|
+
nil
|
48
|
+
end
|
46
49
|
end
|
47
50
|
|
48
51
|
def group_node
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'safedep/abstract_dependency'
|
2
|
+
require 'safedep/util'
|
2
3
|
|
3
4
|
module Safedep
|
4
5
|
class Gemspec
|
5
6
|
class Dependency < AbstractDependency
|
7
|
+
include Util
|
8
|
+
|
6
9
|
METHOD_NAMES = [:add_runtime_dependency, :add_development_dependency, :add_dependency].freeze
|
7
10
|
|
8
11
|
def self.method_names
|
@@ -17,6 +20,13 @@ module Safedep
|
|
17
20
|
[]
|
18
21
|
end
|
19
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# https://github.com/rubygems/rubygems/blob/v2.4.5/lib/rubygems/specification.rb#L449-L473
|
27
|
+
def version_nodes
|
28
|
+
trailing_nodes
|
29
|
+
end
|
20
30
|
end
|
21
31
|
end
|
22
32
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Safedep
|
2
|
+
module Literal
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def value(node)
|
6
|
+
concretize(node)
|
7
|
+
end
|
8
|
+
|
9
|
+
def concretize(node) # rubocop:disable CyclomaticComplexity
|
10
|
+
return nil unless node
|
11
|
+
|
12
|
+
case node.type
|
13
|
+
when :true then true
|
14
|
+
when :false then false
|
15
|
+
when :nil then nil
|
16
|
+
when :int, :float, :str, :sym then node.children.first
|
17
|
+
when :regexp then concretize_regexp(node)
|
18
|
+
when :array then concretize_array(node)
|
19
|
+
when :hash then concretize_hash(node)
|
20
|
+
when :irange, :erange then concretize_range(node)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def concretize_regexp(regexp_node)
|
25
|
+
str_node, *_interporated_nodes, regopt_node = *regexp_node
|
26
|
+
string = str_node.children.first
|
27
|
+
options = regopt_node.children.map(&:to_s).reduce(:+)
|
28
|
+
eval("/#{string}/#{options}") # rubocop:disable Eval
|
29
|
+
end
|
30
|
+
|
31
|
+
def concretize_array(array_node)
|
32
|
+
array_node.children.map { |child_node| concretize(child_node) }
|
33
|
+
end
|
34
|
+
|
35
|
+
def concretize_hash(hash_node)
|
36
|
+
hash_node.children.each_with_object({}) do |pair_node, hash|
|
37
|
+
key_node, value_node = *pair_node
|
38
|
+
key = concretize(key_node)
|
39
|
+
hash[key] = concretize(value_node) if key
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def concretize_range(range_node)
|
44
|
+
values = range_node.children.map { |child_node| concretize(child_node) }
|
45
|
+
Range.new(*values, range_node.type == :erange)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Safedep
|
2
|
+
module Policy
|
3
|
+
class SemVer
|
4
|
+
attr_reader :version, :major, :minor, :patch, :suffix
|
5
|
+
|
6
|
+
def self.version_specifiers(version)
|
7
|
+
new(version).version_specifiers
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(version)
|
11
|
+
@version = if version.is_a?(Gem::Version)
|
12
|
+
version
|
13
|
+
else
|
14
|
+
Gem::Version.new(version)
|
15
|
+
end
|
16
|
+
|
17
|
+
decompose_version
|
18
|
+
end
|
19
|
+
|
20
|
+
def version_specifiers
|
21
|
+
specifiers = ['~> ' + [major, minor].join('.')]
|
22
|
+
return specifiers if satisfy_specifiers?(specifiers)
|
23
|
+
|
24
|
+
specifiers = [">= #{version}", "< #{major.to_i + 1}"]
|
25
|
+
return specifiers if satisfy_specifiers?(specifiers)
|
26
|
+
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def decompose_version
|
33
|
+
elements = version.to_s.split('.')
|
34
|
+
|
35
|
+
[:major, :minor, :patch].each do |role|
|
36
|
+
if elements.first && elements.first.match(/^\d+$/)
|
37
|
+
instance_variable_set("@#{role}", elements.shift)
|
38
|
+
else
|
39
|
+
instance_variable_set("@#{role}", '0')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
@suffix = elements.shift if elements.first && !elements.first.match(/^\d+$/)
|
44
|
+
end
|
45
|
+
|
46
|
+
def satisfy_specifiers?(specifiers)
|
47
|
+
requirement = Gem::Requirement.new(*specifiers)
|
48
|
+
requirement.satisfied_by?(version)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/safedep/runner.rb
CHANGED
@@ -2,6 +2,7 @@ require 'safedep/configuration'
|
|
2
2
|
require 'safedep/gemspec'
|
3
3
|
require 'safedep/gemfile'
|
4
4
|
require 'safedep/gemfile_lock'
|
5
|
+
require 'safedep/policy/sem_ver'
|
5
6
|
require 'safedep/error'
|
6
7
|
|
7
8
|
module Safedep
|
@@ -28,7 +29,7 @@ module Safedep
|
|
28
29
|
'Please run `bundle install`.'
|
29
30
|
end
|
30
31
|
|
31
|
-
dep.
|
32
|
+
dep.version_specifiers = version_specifiers(lockfile_dep.version)
|
32
33
|
end
|
33
34
|
|
34
35
|
gemfiles.each(&:rewrite!)
|
@@ -72,12 +73,13 @@ module Safedep
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def should_ignore?(dependency)
|
75
|
-
return true
|
76
|
-
|
76
|
+
return true unless dependency.version_specifiers.empty?
|
77
|
+
return true unless (dependency.groups & configuration.skipped_groups).empty?
|
78
|
+
[:git, :github, :path].any? { |key| dependency.options[key] }
|
77
79
|
end
|
78
80
|
|
79
|
-
def
|
80
|
-
|
81
|
+
def version_specifiers(version)
|
82
|
+
Policy::SemVer.version_specifiers(version)
|
81
83
|
end
|
82
84
|
end
|
83
85
|
end
|
data/lib/safedep/util.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Safedep
|
2
|
+
module Util
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def symbolize_keys(original_hash)
|
6
|
+
hash = original_hash.dup
|
7
|
+
|
8
|
+
original_hash.each do |key, value|
|
9
|
+
hash[key] = symbolize_keys(value) if value.is_a?(Hash)
|
10
|
+
hash[key.to_sym] = hash.delete(key) if key.is_a?(String)
|
11
|
+
end
|
12
|
+
|
13
|
+
hash
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/safedep/version.rb
CHANGED
@@ -16,6 +16,10 @@ module Safedep
|
|
16
16
|
gem 'rspec', '~> 3.1'
|
17
17
|
gem 'rubocop', require: false
|
18
18
|
end
|
19
|
+
|
20
|
+
group :development do
|
21
|
+
gem 'guard', '>= 2.1', '< 3.0'
|
22
|
+
end
|
19
23
|
END
|
20
24
|
|
21
25
|
describe '#name' do
|
@@ -47,7 +51,7 @@ module Safedep
|
|
47
51
|
gem 'fuubar'
|
48
52
|
end
|
49
53
|
|
50
|
-
gem 'rspec', group
|
54
|
+
gem 'rspec', 'group' => [:test, :development]
|
51
55
|
END
|
52
56
|
|
53
57
|
context 'when the dependency is specified in top level' do
|
@@ -81,34 +85,42 @@ module Safedep
|
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
84
|
-
describe '#
|
85
|
-
subject(:
|
88
|
+
describe '#version_specifiers' do
|
89
|
+
subject(:version_specifiers) { dependency.version_specifiers }
|
86
90
|
|
87
|
-
context 'when the dependency has version specifier' do
|
91
|
+
context 'when the dependency has a version specifier' do
|
88
92
|
let(:dependency) { gemfile.find_dependency('rspec') }
|
89
93
|
|
90
94
|
it 'returns the specifier' do
|
91
|
-
expect(
|
95
|
+
expect(version_specifiers).to eq(['~> 3.1'])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when the dependency has multiple specifiers' do
|
100
|
+
let(:dependency) { gemfile.find_dependency('guard') }
|
101
|
+
|
102
|
+
it 'returns the specifiers' do
|
103
|
+
expect(version_specifiers).to eq(['>= 2.1', '< 3.0'])
|
92
104
|
end
|
93
105
|
end
|
94
106
|
|
95
107
|
context 'when the dependency has no version specifier' do
|
96
108
|
context 'and has no options' do
|
97
109
|
let(:dependency) { gemfile.find_dependency('rake') }
|
98
|
-
it { should
|
110
|
+
it { should be_empty }
|
99
111
|
end
|
100
112
|
|
101
113
|
context 'but has options' do
|
102
114
|
let(:dependency) { gemfile.find_dependency('rubocop') }
|
103
|
-
it { should
|
115
|
+
it { should be_empty }
|
104
116
|
end
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
108
|
-
describe '#
|
120
|
+
describe '#version_specifiers=' do
|
109
121
|
let(:rewritten_source) { File.read(gemfile.path) }
|
110
122
|
|
111
|
-
context 'when the dependency has version specifier' do
|
123
|
+
context 'when the dependency has a version specifier' do
|
112
124
|
let(:dependency) { gemfile.find_dependency('rspec') }
|
113
125
|
|
114
126
|
let(:expected_source) { <<-END.strip_indent }
|
@@ -121,10 +133,14 @@ module Safedep
|
|
121
133
|
gem 'rspec', '> 4.0'
|
122
134
|
gem 'rubocop', require: false
|
123
135
|
end
|
136
|
+
|
137
|
+
group :development do
|
138
|
+
gem 'guard', '>= 2.1', '< 3.0'
|
139
|
+
end
|
124
140
|
END
|
125
141
|
|
126
142
|
it 'replaces the existing specifier with the passed specifier' do
|
127
|
-
dependency.
|
143
|
+
dependency.version_specifiers = '> 4.0'
|
128
144
|
gemfile.rewrite!
|
129
145
|
expect(rewritten_source).to eq(expected_source)
|
130
146
|
end
|
@@ -144,10 +160,14 @@ module Safedep
|
|
144
160
|
gem 'rspec', '~> 3.1'
|
145
161
|
gem 'rubocop', require: false
|
146
162
|
end
|
163
|
+
|
164
|
+
group :development do
|
165
|
+
gem 'guard', '>= 2.1', '< 3.0'
|
166
|
+
end
|
147
167
|
END
|
148
168
|
|
149
169
|
it 'adds the passed specifier' do
|
150
|
-
dependency.
|
170
|
+
dependency.version_specifiers = '~> 10.1'
|
151
171
|
gemfile.rewrite!
|
152
172
|
expect(rewritten_source).to eq(expected_source)
|
153
173
|
end
|
@@ -166,15 +186,45 @@ module Safedep
|
|
166
186
|
gem 'rspec', '~> 3.1'
|
167
187
|
gem 'rubocop', '~> 0.28', require: false
|
168
188
|
end
|
189
|
+
|
190
|
+
group :development do
|
191
|
+
gem 'guard', '>= 2.1', '< 3.0'
|
192
|
+
end
|
169
193
|
END
|
170
194
|
|
171
195
|
it 'adds the passed specifier' do
|
172
|
-
dependency.
|
196
|
+
dependency.version_specifiers = '~> 0.28'
|
173
197
|
gemfile.rewrite!
|
174
198
|
expect(rewritten_source).to eq(expected_source)
|
175
199
|
end
|
176
200
|
end
|
177
201
|
end
|
202
|
+
|
203
|
+
context 'when multiple specifiers are passed' do
|
204
|
+
let(:dependency) { gemfile.find_dependency('rspec') }
|
205
|
+
|
206
|
+
let(:expected_source) { <<-END.strip_indent }
|
207
|
+
source 'https://rubygems.org'
|
208
|
+
|
209
|
+
gemspec
|
210
|
+
|
211
|
+
group :development, :test do
|
212
|
+
gem 'rake'
|
213
|
+
gem 'rspec', '>= 4.0', '< 5.0'
|
214
|
+
gem 'rubocop', require: false
|
215
|
+
end
|
216
|
+
|
217
|
+
group :development do
|
218
|
+
gem 'guard', '>= 2.1', '< 3.0'
|
219
|
+
end
|
220
|
+
END
|
221
|
+
|
222
|
+
it 'replaces the existing specifier with the passed specifiers' do
|
223
|
+
dependency.version_specifiers = ['>= 4.0', '< 5.0']
|
224
|
+
gemfile.rewrite!
|
225
|
+
expect(rewritten_source).to eq(expected_source)
|
226
|
+
end
|
227
|
+
end
|
178
228
|
end
|
179
229
|
end
|
180
230
|
end
|
@@ -10,7 +10,8 @@ module Safedep
|
|
10
10
|
Gem::Specification.new do |spec|
|
11
11
|
spec.name = 'safedep'
|
12
12
|
spec.add_dependency 'parser'
|
13
|
-
spec.add_runtime_dependency '
|
13
|
+
spec.add_runtime_dependency 'bundler', '>= 1.3.1', '< 2.0'
|
14
|
+
spec.add_runtime_dependency 'astrolabe', ['>= 1.3', '< 2.0']
|
14
15
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
15
16
|
end
|
16
17
|
END
|
@@ -42,59 +43,137 @@ module Safedep
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
describe '#
|
46
|
-
subject(:version_specifier) { dependency.
|
46
|
+
describe '#version_specifiers' do
|
47
|
+
subject(:version_specifier) { dependency.version_specifiers }
|
47
48
|
|
48
|
-
context 'when the dependency has version specifier' do
|
49
|
+
context 'when the dependency has no version specifier' do
|
50
|
+
let(:dependency) { gemspec.find_dependency('parser') }
|
51
|
+
it { should be_empty }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when the dependency has a version specifier' do
|
49
55
|
let(:dependency) { gemspec.find_dependency('rspec') }
|
50
56
|
|
51
57
|
it 'returns the specifier' do
|
52
|
-
expect(version_specifier).to eq('~> 3.1')
|
58
|
+
expect(version_specifier).to eq(['~> 3.1'])
|
53
59
|
end
|
54
60
|
end
|
55
61
|
|
56
|
-
context 'when the dependency has
|
57
|
-
let(:dependency) { gemspec.find_dependency('
|
58
|
-
|
62
|
+
context 'when the dependency has multiple version specifiers' do
|
63
|
+
let(:dependency) { gemspec.find_dependency('bundler') }
|
64
|
+
|
65
|
+
it 'returns the specifiers' do
|
66
|
+
expect(version_specifier).to eq(['>= 1.3.1', '< 2.0'])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when the dependency has multiple version specifiers in an array' do
|
71
|
+
let(:dependency) { gemspec.find_dependency('astrolabe') }
|
72
|
+
|
73
|
+
it 'returns the specifiers' do
|
74
|
+
expect(version_specifier).to eq(['>= 1.3', '< 2.0'])
|
75
|
+
end
|
59
76
|
end
|
60
77
|
end
|
61
78
|
|
62
|
-
describe '#
|
79
|
+
describe '#version_specifiers=' do
|
63
80
|
let(:rewritten_source) { File.read(gemspec.path) }
|
64
81
|
|
65
|
-
context 'when the dependency has version specifier' do
|
82
|
+
context 'when the dependency has no version specifier' do
|
83
|
+
let(:dependency) { gemspec.find_dependency('parser') }
|
84
|
+
|
85
|
+
let(:expected_source) { <<-END.strip_indent }
|
86
|
+
Gem::Specification.new do |spec|
|
87
|
+
spec.name = 'safedep'
|
88
|
+
spec.add_dependency 'parser', '~> 2.2'
|
89
|
+
spec.add_runtime_dependency 'bundler', '>= 1.3.1', '< 2.0'
|
90
|
+
spec.add_runtime_dependency 'astrolabe', ['>= 1.3', '< 2.0']
|
91
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
92
|
+
end
|
93
|
+
END
|
94
|
+
|
95
|
+
it 'adds the passed specifier' do
|
96
|
+
dependency.version_specifiers = '~> 2.2'
|
97
|
+
gemspec.rewrite!
|
98
|
+
expect(rewritten_source).to eq(expected_source)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when the dependency has a version specifier' do
|
66
103
|
let(:dependency) { gemspec.find_dependency('rspec') }
|
67
104
|
|
68
105
|
let(:expected_source) { <<-END.strip_indent }
|
69
106
|
Gem::Specification.new do |spec|
|
70
107
|
spec.name = 'safedep'
|
71
108
|
spec.add_dependency 'parser'
|
72
|
-
spec.add_runtime_dependency '
|
109
|
+
spec.add_runtime_dependency 'bundler', '>= 1.3.1', '< 2.0'
|
110
|
+
spec.add_runtime_dependency 'astrolabe', ['>= 1.3', '< 2.0']
|
73
111
|
spec.add_development_dependency 'rspec', '> 4.0'
|
74
112
|
end
|
75
113
|
END
|
76
114
|
|
77
115
|
it 'replaces the existing specifier with the passed specifier' do
|
78
|
-
dependency.
|
116
|
+
dependency.version_specifiers = '> 4.0'
|
79
117
|
gemspec.rewrite!
|
80
118
|
expect(rewritten_source).to eq(expected_source)
|
81
119
|
end
|
82
120
|
end
|
83
121
|
|
84
|
-
context 'when the dependency has
|
85
|
-
let(:dependency) { gemspec.find_dependency('
|
122
|
+
context 'when the dependency has multiple version specifiers' do
|
123
|
+
let(:dependency) { gemspec.find_dependency('bundler') }
|
86
124
|
|
87
125
|
let(:expected_source) { <<-END.strip_indent }
|
88
126
|
Gem::Specification.new do |spec|
|
89
127
|
spec.name = 'safedep'
|
90
|
-
spec.add_dependency 'parser'
|
91
|
-
spec.add_runtime_dependency '
|
128
|
+
spec.add_dependency 'parser'
|
129
|
+
spec.add_runtime_dependency 'bundler', '~> 2.0'
|
130
|
+
spec.add_runtime_dependency 'astrolabe', ['>= 1.3', '< 2.0']
|
92
131
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
93
132
|
end
|
94
133
|
END
|
95
134
|
|
96
|
-
it '
|
97
|
-
dependency.
|
135
|
+
it 'replaces the existing specifiers with the passed specifier' do
|
136
|
+
dependency.version_specifiers = '~> 2.0'
|
137
|
+
gemspec.rewrite!
|
138
|
+
expect(rewritten_source).to eq(expected_source)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when the dependency has multiple version specifiers in an array' do
|
143
|
+
let(:dependency) { gemspec.find_dependency('astrolabe') }
|
144
|
+
|
145
|
+
let(:expected_source) { <<-END.strip_indent }
|
146
|
+
Gem::Specification.new do |spec|
|
147
|
+
spec.name = 'safedep'
|
148
|
+
spec.add_dependency 'parser'
|
149
|
+
spec.add_runtime_dependency 'bundler', '>= 1.3.1', '< 2.0'
|
150
|
+
spec.add_runtime_dependency 'astrolabe', '~> 2.0'
|
151
|
+
spec.add_development_dependency 'rspec', '~> 3.1'
|
152
|
+
end
|
153
|
+
END
|
154
|
+
|
155
|
+
it 'replaces the existing specifiers with the passed specifier' do
|
156
|
+
dependency.version_specifiers = '~> 2.0'
|
157
|
+
gemspec.rewrite!
|
158
|
+
expect(rewritten_source).to eq(expected_source)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when multiple specifiers are passed' do
|
163
|
+
let(:dependency) { gemspec.find_dependency('rspec') }
|
164
|
+
|
165
|
+
let(:expected_source) { <<-END.strip_indent }
|
166
|
+
Gem::Specification.new do |spec|
|
167
|
+
spec.name = 'safedep'
|
168
|
+
spec.add_dependency 'parser'
|
169
|
+
spec.add_runtime_dependency 'bundler', '>= 1.3.1', '< 2.0'
|
170
|
+
spec.add_runtime_dependency 'astrolabe', ['>= 1.3', '< 2.0']
|
171
|
+
spec.add_development_dependency 'rspec', '>= 3.1', '< 4.0'
|
172
|
+
end
|
173
|
+
END
|
174
|
+
|
175
|
+
it 'replaces the existing specifier with the passed specifier' do
|
176
|
+
dependency.version_specifiers = ['>= 3.1', '< 4.0']
|
98
177
|
gemspec.rewrite!
|
99
178
|
expect(rewritten_source).to eq(expected_source)
|
100
179
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'safedep/literal'
|
2
|
+
require 'astrolabe/builder'
|
3
|
+
require 'parser/current'
|
4
|
+
|
5
|
+
module Safedep
|
6
|
+
describe Literal do
|
7
|
+
let(:node) do
|
8
|
+
builder = Astrolabe::Builder.new
|
9
|
+
parser = Parser::CurrentRuby.new(builder)
|
10
|
+
parser.parse(source_buffer)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:source_buffer) do
|
14
|
+
Parser::Source::Buffer.new('(string)').tap do |buffer|
|
15
|
+
buffer.source = source
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '.value' do
|
20
|
+
subject { Literal.value(node) }
|
21
|
+
|
22
|
+
[
|
23
|
+
true,
|
24
|
+
false,
|
25
|
+
nil,
|
26
|
+
123,
|
27
|
+
3.14,
|
28
|
+
'foo',
|
29
|
+
:foo,
|
30
|
+
/foo/im,
|
31
|
+
['foo', 123],
|
32
|
+
{ 'foo' => 123, bar: false },
|
33
|
+
1..3,
|
34
|
+
1...3,
|
35
|
+
{ 'foo' => [:bar, { baz: 3.14 }] }
|
36
|
+
].each do |value|
|
37
|
+
context "with #{value.inspect} node" do
|
38
|
+
let(:source) { value.inspect }
|
39
|
+
it { should eq(value) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when nil is passed' do
|
44
|
+
let(:node) { nil }
|
45
|
+
it { should be_nil }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'safedep/policy/sem_ver'
|
2
|
+
|
3
|
+
module Safedep
|
4
|
+
module Policy
|
5
|
+
describe SemVer do
|
6
|
+
describe '.version_specifiers' do
|
7
|
+
subject { SemVer.version_specifiers(version) }
|
8
|
+
|
9
|
+
[
|
10
|
+
['0.0.1', ['~> 0.0']],
|
11
|
+
['1.2.34', ['~> 1.2']],
|
12
|
+
['1.2', ['~> 1.2']],
|
13
|
+
['1', ['~> 1.0']],
|
14
|
+
['1.2.1.beta1', ['~> 1.2']],
|
15
|
+
['1.2.0.beta1', ['>= 1.2.0.beta1', '< 2']],
|
16
|
+
['1.2.beta1', ['>= 1.2.beta1', '< 2']],
|
17
|
+
['1.beta1', ['>= 1.beta1', '< 2']]
|
18
|
+
].each do |version_string, specifiers|
|
19
|
+
context "with #{version_string}" do
|
20
|
+
let(:version) { Gem::Version.new(version_string) }
|
21
|
+
let(:requirement) { Gem::Requirement.new(*specifiers) }
|
22
|
+
|
23
|
+
it { should eq(specifiers) }
|
24
|
+
|
25
|
+
if specifiers
|
26
|
+
it 'returns version specifiers satisfied by the passed version' do
|
27
|
+
expect(requirement).to be_satisfied_by(version)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/safedep/runner_spec.rb
CHANGED
@@ -83,11 +83,56 @@ module Safedep
|
|
83
83
|
|
84
84
|
it 'does not modify dependencies that belong to any of the groups' do
|
85
85
|
development_dependencies.each do |dep|
|
86
|
-
expect(dep).not_to receive(:
|
86
|
+
expect(dep).not_to receive(:version_specifiers=)
|
87
87
|
end
|
88
88
|
|
89
89
|
runner.run
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
context 'when a dependency has :git option', :gemfile, :lockfile do
|
94
|
+
let(:gemfile_source) { <<-END.strip_indent }
|
95
|
+
source 'https://rubygems.org'
|
96
|
+
|
97
|
+
group :development, :test do
|
98
|
+
gem 'rubocop', git: 'https://github.com/bbatsov/rubocop.git'
|
99
|
+
end
|
100
|
+
END
|
101
|
+
|
102
|
+
it 'does not add version specifiers to the dependency' do
|
103
|
+
runner.run
|
104
|
+
expect(rewritten_gemfile_source).to eq(gemfile_source)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when a dependency has :github option', :gemfile, :lockfile do
|
109
|
+
let(:gemfile_source) { <<-END.strip_indent }
|
110
|
+
source 'https://rubygems.org'
|
111
|
+
|
112
|
+
group :development, :test do
|
113
|
+
gem 'rubocop', github: 'bbatsov/rubocop.git'
|
114
|
+
end
|
115
|
+
END
|
116
|
+
|
117
|
+
it 'does not add version specifiers to the dependency' do
|
118
|
+
runner.run
|
119
|
+
expect(rewritten_gemfile_source).to eq(gemfile_source)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'when a dependency has :path option', :gemfile, :lockfile do
|
124
|
+
let(:gemfile_source) { <<-END.strip_indent }
|
125
|
+
source 'https://rubygems.org'
|
126
|
+
|
127
|
+
group :development, :test do
|
128
|
+
gem 'rubocop', path: '../rubocop'
|
129
|
+
end
|
130
|
+
END
|
131
|
+
|
132
|
+
it 'does not add version specifiers to the dependency' do
|
133
|
+
runner.run
|
134
|
+
expect(rewritten_gemfile_source).to eq(gemfile_source)
|
135
|
+
end
|
136
|
+
end
|
92
137
|
end
|
93
138
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safedep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuji Nakayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -82,7 +82,10 @@ files:
|
|
82
82
|
- lib/safedep/gemfile_lock.rb
|
83
83
|
- lib/safedep/gemspec.rb
|
84
84
|
- lib/safedep/gemspec/dependency.rb
|
85
|
+
- lib/safedep/literal.rb
|
86
|
+
- lib/safedep/policy/sem_ver.rb
|
85
87
|
- lib/safedep/runner.rb
|
88
|
+
- lib/safedep/util.rb
|
86
89
|
- lib/safedep/version.rb
|
87
90
|
- safedep.gemspec
|
88
91
|
- spec/.rubocop.yml
|
@@ -92,6 +95,8 @@ files:
|
|
92
95
|
- spec/safedep/gemfile_spec.rb
|
93
96
|
- spec/safedep/gemspec/dependency_spec.rb
|
94
97
|
- spec/safedep/gemspec_spec.rb
|
98
|
+
- spec/safedep/literal_spec.rb
|
99
|
+
- spec/safedep/policy/sem_ver_spec.rb
|
95
100
|
- spec/safedep/runner_spec.rb
|
96
101
|
- spec/spec_helper.rb
|
97
102
|
- spec/support/file_helper.rb
|
@@ -128,6 +133,8 @@ test_files:
|
|
128
133
|
- spec/safedep/gemfile_spec.rb
|
129
134
|
- spec/safedep/gemspec/dependency_spec.rb
|
130
135
|
- spec/safedep/gemspec_spec.rb
|
136
|
+
- spec/safedep/literal_spec.rb
|
137
|
+
- spec/safedep/policy/sem_ver_spec.rb
|
131
138
|
- spec/safedep/runner_spec.rb
|
132
139
|
- spec/spec_helper.rb
|
133
140
|
- spec/support/file_helper.rb
|