safedep 0.1.2 → 0.2.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/.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
|