bundler-audit-ng 0.6.1
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 +7 -0
- data/.document +3 -0
- data/.gitignore +11 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/.travis.yml +13 -0
- data/.yardopts +1 -0
- data/COPYING.txt +674 -0
- data/ChangeLog.md +129 -0
- data/Gemfile +13 -0
- data/README.md +168 -0
- data/Rakefile +57 -0
- data/bin/bundle-audit +10 -0
- data/bin/bundler-audit +3 -0
- data/bundler-audit.gemspec +67 -0
- data/data/ruby-advisory-db.ts +1 -0
- data/gemspec.yml +14 -0
- data/lib/bundler/audit.rb +19 -0
- data/lib/bundler/audit/advisory.rb +177 -0
- data/lib/bundler/audit/cli.rb +155 -0
- data/lib/bundler/audit/database.rb +248 -0
- data/lib/bundler/audit/scanner.rb +213 -0
- data/lib/bundler/audit/task.rb +31 -0
- data/lib/bundler/audit/version.rb +23 -0
- data/spec/advisory_spec.rb +282 -0
- data/spec/audit_spec.rb +8 -0
- data/spec/bundle/insecure_sources/Gemfile +4 -0
- data/spec/bundle/secure/Gemfile +3 -0
- data/spec/bundle/unpatched_gems/Gemfile +3 -0
- data/spec/cli_spec.rb +99 -0
- data/spec/database_spec.rb +138 -0
- data/spec/fixtures/not_a_hash.yml +2 -0
- data/spec/integration_spec.rb +103 -0
- data/spec/scanner_spec.rb +75 -0
- data/spec/spec_helper.rb +62 -0
- metadata +115 -0
data/ChangeLog.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
### 0.6.1 / 2019-01-17
|
2
|
+
|
3
|
+
* Require bundler `>= 1.2.0, < 3` to support [bundler] 2.0.
|
4
|
+
|
5
|
+
### 0.6.0 / 2017-07-18
|
6
|
+
|
7
|
+
* Added `--quiet` option to `check` and `update` commands (@jaredbeck).
|
8
|
+
* Added `bin/bundler-audit` which will be executed when `bundle audit` is ran
|
9
|
+
(@vassilevsky).
|
10
|
+
|
11
|
+
### 0.5.0 / 2016-02-28
|
12
|
+
|
13
|
+
* Added {Bundler::Audit::Task}.
|
14
|
+
* Added {Bundler::Audit::Advisory#date}.
|
15
|
+
* Added {Bundler::Audit::Advisory#cve_id}.
|
16
|
+
* Added {Bundler::Audit::Advisory#osvdb_id}.
|
17
|
+
* Allow insecure gem sources (`http://` and `git://`), if they are hosted on a
|
18
|
+
private network.
|
19
|
+
|
20
|
+
#### CLI
|
21
|
+
|
22
|
+
* Added the `--update` option to `bundle-audit check`.
|
23
|
+
* `bundle-audit update` now returns a non-zero exit status on error.
|
24
|
+
* `bundle-audit update` only updates `~/.local/share/ruby-advisory-db`, if it is a git
|
25
|
+
repository.
|
26
|
+
|
27
|
+
### 0.4.0 / 2015-06-30
|
28
|
+
|
29
|
+
* Require ruby >= 1.9.3 due to i18n gem deprecating < 1.9.3.
|
30
|
+
* Added {Bundler::Audit::Advisory#osvdb}.
|
31
|
+
* Resolve the IP addresses of gem sources and ignore intranet gem sources.
|
32
|
+
(PR #90)
|
33
|
+
* Use ISO8601 date format when querying the git timestamp of ruby-advisory-db.
|
34
|
+
(PR #92)
|
35
|
+
|
36
|
+
#### CLI
|
37
|
+
|
38
|
+
* Print the CVE or OSVDB id.
|
39
|
+
* No longer print "Unpatched versions found!" when an insecure gem source
|
40
|
+
is detected. (PR #84)
|
41
|
+
|
42
|
+
### 0.3.1 / 2014-04-20
|
43
|
+
|
44
|
+
* Added thor ~> 0.18 as a dependency.
|
45
|
+
* No longer rely on the vendored version of thor within bundler.
|
46
|
+
* Store the timestamp of when `data/ruby-advisory-db` was last updated in
|
47
|
+
`data/ruby-advisory-db.ts`.
|
48
|
+
* Use `data/ruby-advisory-db.ts` instead of the creation time of the
|
49
|
+
`dataruby-advisory-db` directory, which is always the install time
|
50
|
+
of the rubygem.
|
51
|
+
|
52
|
+
### 0.3.0 / 2013-10-31
|
53
|
+
|
54
|
+
* Added {Bundler::Audit::Database.update!} which uses `git` to download
|
55
|
+
[ruby-advisory-db] to `~/.local/share/ruby-advisory-db`.
|
56
|
+
* {Bundler::Audit::Database.path} now returns the path to either
|
57
|
+
`~/.local/share/ruby-advisory-db` or the vendored copy, depending on which
|
58
|
+
is more recent.
|
59
|
+
|
60
|
+
#### CLI
|
61
|
+
|
62
|
+
* Added the `bundle-audit update` sub-command.
|
63
|
+
|
64
|
+
### 0.2.0 / 2013-03-05
|
65
|
+
|
66
|
+
* Require RubyGems >= 1.8.0. Prior versions of RubyGems could not correctly
|
67
|
+
parse approximate version requirements (`~> 1.2.3`).
|
68
|
+
* Updated the [ruby-advisory-db].
|
69
|
+
* Added {Bundler::Audit::Advisory#unaffected_versions}.
|
70
|
+
* Added {Bundler::Audit::Advisory#unaffected?}.
|
71
|
+
* Added {Bundler::Audit::Advisory#patched?}.
|
72
|
+
* Renamed `Advisory#cve` to {Bundler::Audit::Advisory#id}.
|
73
|
+
|
74
|
+
### 0.1.2 / 2013-02-17
|
75
|
+
|
76
|
+
* Require [bundler] ~> 1.2.
|
77
|
+
* Vendor a full copy of the [ruby-advisory-db].
|
78
|
+
* Added {Bundler::Audit::Advisory#path} for debugging purposes.
|
79
|
+
* Added {Bundler::Audit::Advisory#to_s} for debugging purposes.
|
80
|
+
|
81
|
+
#### CLI
|
82
|
+
|
83
|
+
* Simply parse the `Gemfile.lock` instead of loading the bundle (@grosser).
|
84
|
+
* Exit with non-zero status on failure (@grosser).
|
85
|
+
|
86
|
+
### 0.1.1 / 2013-02-12
|
87
|
+
|
88
|
+
* Fixed a Ruby 1.8 syntax error.
|
89
|
+
|
90
|
+
### Advisories
|
91
|
+
|
92
|
+
* Imported advisories from the [Ruby Advisory DB][ruby-advisory-db].
|
93
|
+
* [CVE-2011-0739](http://www.osvdb.org/show/osvdb/70667)
|
94
|
+
* [CVE-2012-2139](http://www.osvdb.org/show/osvdb/81631)
|
95
|
+
* [CVE-2012-2140](http://www.osvdb.org/show/osvdb/81632)
|
96
|
+
* [CVE-2012-267](http://osvdb.org/83077)
|
97
|
+
* [CVE-2012-1098](http://osvdb.org/79726)
|
98
|
+
* [CVE-2012-1099](http://www.osvdb.org/show/osvdb/79727)
|
99
|
+
* [CVE-2012-2660](http://www.osvdb.org/show/osvdb/82610)
|
100
|
+
* [CVE-2012-2661](http://www.osvdb.org/show/osvdb/82403)
|
101
|
+
* [CVE-2012-3424](http://www.osvdb.org/show/osvdb/84243)
|
102
|
+
* [CVE-2012-3463](http://osvdb.org/84515)
|
103
|
+
* [CVE-2012-3464](http://www.osvdb.org/show/osvdb/84516)
|
104
|
+
* [CVE-2012-3465](http://www.osvdb.org/show/osvdb/84513)
|
105
|
+
|
106
|
+
### CLI
|
107
|
+
|
108
|
+
* If the advisory has no `patched_versions`, recommend removing or disabling
|
109
|
+
the gem until a patch is made available.
|
110
|
+
|
111
|
+
### 0.1.0 / 2013-02-11
|
112
|
+
|
113
|
+
* Initial release:
|
114
|
+
* Checks for vulnerable versions of gems in `Gemfile.lock`.
|
115
|
+
* Prints advisory information.
|
116
|
+
* Does not require a network connection.
|
117
|
+
|
118
|
+
#### Advisories
|
119
|
+
|
120
|
+
* [CVE-2013-0269](http://direct.osvdb.org/show/osvdb/90074)
|
121
|
+
* [CVE-2013-0263](http://osvdb.org/show/osvdb/89939)
|
122
|
+
* [CVE-2013-0155](http://osvdb.org/show/osvdb/89025)
|
123
|
+
* [CVE-2013-0156](http://osvdb.org/show/osvdb/89026)
|
124
|
+
* [CVE-2013-0276](http://direct.osvdb.org/show/osvdb/90072)
|
125
|
+
* [CVE-2013-0277](http://direct.osvdb.org/show/osvdb/90073)
|
126
|
+
* [CVE-2013-0333](http://osvdb.org/show/osvdb/89594)
|
127
|
+
|
128
|
+
[bundler]: http://gembundler.com/
|
129
|
+
[ruby-advisory-db]: https://github.com/rubysec/ruby-advisory-db#readme
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# bundler-audit
|
2
|
+
[](https://travis-ci.org/rubysec/bundler-audit)
|
3
|
+
[](https://codeclimate.com/github/rubysec/bundler-audit)
|
4
|
+
|
5
|
+
* [Homepage](https://github.com/rubysec/bundler-audit#readme)
|
6
|
+
* [Issues](https://github.com/rubysec/bundler-audit/issues)
|
7
|
+
* [Documentation](http://rubydoc.info/gems/bundler-audit/frames)
|
8
|
+
* [Email](mailto:postmodern.mod3 at gmail.com)
|
9
|
+
|
10
|
+
## Description
|
11
|
+
|
12
|
+
Patch-level verification for [bundler].
|
13
|
+
|
14
|
+
## Features
|
15
|
+
|
16
|
+
* Checks for vulnerable versions of gems in `Gemfile.lock`.
|
17
|
+
* Checks for insecure gem sources (`http://`).
|
18
|
+
* Allows ignoring certain advisories that have been manually worked around.
|
19
|
+
* Prints advisory information.
|
20
|
+
* Does not require a network connection.
|
21
|
+
|
22
|
+
## Synopsis
|
23
|
+
|
24
|
+
Audit a project's `Gemfile.lock`:
|
25
|
+
|
26
|
+
$ bundle-audit
|
27
|
+
Name: actionpack
|
28
|
+
Version: 3.2.10
|
29
|
+
Advisory: OSVDB-91452
|
30
|
+
Criticality: Medium
|
31
|
+
URL: http://www.osvdb.org/show/osvdb/91452
|
32
|
+
Title: XSS vulnerability in sanitize_css in Action Pack
|
33
|
+
Solution: upgrade to ~> 2.3.18, ~> 3.1.12, >= 3.2.13
|
34
|
+
|
35
|
+
Name: actionpack
|
36
|
+
Version: 3.2.10
|
37
|
+
Advisory: OSVDB-91454
|
38
|
+
Criticality: Medium
|
39
|
+
URL: http://osvdb.org/show/osvdb/91454
|
40
|
+
Title: XSS Vulnerability in the `sanitize` helper of Ruby on Rails
|
41
|
+
Solution: upgrade to ~> 2.3.18, ~> 3.1.12, >= 3.2.13
|
42
|
+
|
43
|
+
Name: actionpack
|
44
|
+
Version: 3.2.10
|
45
|
+
Advisory: OSVDB-89026
|
46
|
+
Criticality: High
|
47
|
+
URL: http://osvdb.org/show/osvdb/89026
|
48
|
+
Title: Ruby on Rails params_parser.rb Action Pack Type Casting Parameter Parsing Remote Code Execution
|
49
|
+
Solution: upgrade to ~> 2.3.15, ~> 3.0.19, ~> 3.1.10, >= 3.2.11
|
50
|
+
|
51
|
+
Name: activerecord
|
52
|
+
Version: 3.2.10
|
53
|
+
Advisory: OSVDB-91453
|
54
|
+
Criticality: High
|
55
|
+
URL: http://osvdb.org/show/osvdb/91453
|
56
|
+
Title: Symbol DoS vulnerability in Active Record
|
57
|
+
Solution: upgrade to ~> 2.3.18, ~> 3.1.12, >= 3.2.13
|
58
|
+
|
59
|
+
Name: activerecord
|
60
|
+
Version: 3.2.10
|
61
|
+
Advisory: OSVDB-90072
|
62
|
+
Criticality: Medium
|
63
|
+
URL: http://direct.osvdb.org/show/osvdb/90072
|
64
|
+
Title: Ruby on Rails Active Record attr_protected Method Bypass
|
65
|
+
Solution: upgrade to ~> 2.3.17, ~> 3.1.11, >= 3.2.12
|
66
|
+
|
67
|
+
Name: activerecord
|
68
|
+
Version: 3.2.10
|
69
|
+
Advisory: OSVDB-89025
|
70
|
+
Criticality: High
|
71
|
+
URL: http://osvdb.org/show/osvdb/89025
|
72
|
+
Title: Ruby on Rails Active Record JSON Parameter Parsing Query Bypass
|
73
|
+
Solution: upgrade to ~> 2.3.16, ~> 3.0.19, ~> 3.1.10, >= 3.2.11
|
74
|
+
|
75
|
+
Name: activesupport
|
76
|
+
Version: 3.2.10
|
77
|
+
Advisory: OSVDB-91451
|
78
|
+
Criticality: High
|
79
|
+
URL: http://www.osvdb.org/show/osvdb/91451
|
80
|
+
Title: XML Parsing Vulnerability affecting JRuby users
|
81
|
+
Solution: upgrade to ~> 3.1.12, >= 3.2.13
|
82
|
+
|
83
|
+
Unpatched versions found!
|
84
|
+
|
85
|
+
Update the [ruby-advisory-db] that `bundle audit` uses:
|
86
|
+
|
87
|
+
$ bundle-audit update
|
88
|
+
Updating ruby-advisory-db ...
|
89
|
+
remote: Counting objects: 44, done.
|
90
|
+
remote: Compressing objects: 100% (24/24), done.
|
91
|
+
remote: Total 39 (delta 19), reused 29 (delta 10)
|
92
|
+
Unpacking objects: 100% (39/39), done.
|
93
|
+
From https://github.com/rubysec/ruby-advisory-db
|
94
|
+
* branch master -> FETCH_HEAD
|
95
|
+
Updating 5f8225e..328ca86
|
96
|
+
Fast-forward
|
97
|
+
CONTRIBUTORS.md | 1 +
|
98
|
+
gems/actionmailer/OSVDB-98629.yml | 17 +++++++++++++++++
|
99
|
+
gems/cocaine/OSVDB-98835.yml | 15 +++++++++++++++
|
100
|
+
gems/fog-dragonfly/OSVDB-96798.yml | 13 +++++++++++++
|
101
|
+
gems/sounder/OSVDB-96278.yml | 13 +++++++++++++
|
102
|
+
gems/wicked/OSVDB-98270.yml | 14 ++++++++++++++
|
103
|
+
6 files changed, 73 insertions(+)
|
104
|
+
create mode 100644 gems/actionmailer/OSVDB-98629.yml
|
105
|
+
create mode 100644 gems/cocaine/OSVDB-98835.yml
|
106
|
+
create mode 100644 gems/fog-dragonfly/OSVDB-96798.yml
|
107
|
+
create mode 100644 gems/sounder/OSVDB-96278.yml
|
108
|
+
create mode 100644 gems/wicked/OSVDB-98270.yml
|
109
|
+
ruby-advisory-db: 64 advisories
|
110
|
+
|
111
|
+
Update the [ruby-advisory-db] and check `Gemfile.lock` (useful for CI runs):
|
112
|
+
|
113
|
+
$ bundle-audit check --update
|
114
|
+
|
115
|
+
Ignore specific advisories:
|
116
|
+
|
117
|
+
$ bundle-audit check --ignore OSVDB-108664
|
118
|
+
|
119
|
+
Rake task:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
require 'bundler/audit/task'
|
123
|
+
Bundler::Audit::Task.new
|
124
|
+
|
125
|
+
task default: 'bundle:audit'
|
126
|
+
```
|
127
|
+
|
128
|
+
## Requirements
|
129
|
+
|
130
|
+
* [ruby] >= 1.9.3
|
131
|
+
* [rubygems] >= 1.8
|
132
|
+
* [thor] ~> 0.18
|
133
|
+
* [bundler] ~> 1.2
|
134
|
+
|
135
|
+
## Install
|
136
|
+
|
137
|
+
$ gem install bundler-audit
|
138
|
+
|
139
|
+
## Contributing
|
140
|
+
|
141
|
+
1. Clone the repo
|
142
|
+
1. `git submodule update --init` # To populate data/ruby-advisory-db
|
143
|
+
1. `bundle exec rake`
|
144
|
+
|
145
|
+
## License
|
146
|
+
|
147
|
+
Copyright (c) 2013-2019 Hal Brodigan (postmodern.mod3 at gmail.com)
|
148
|
+
|
149
|
+
bundler-audit is free software: you can redistribute it and/or modify
|
150
|
+
it under the terms of the GNU General Public License as published by
|
151
|
+
the Free Software Foundation, either version 3 of the License, or
|
152
|
+
(at your option) any later version.
|
153
|
+
|
154
|
+
bundler-audit is distributed in the hope that it will be useful,
|
155
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
156
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
157
|
+
GNU General Public License for more details.
|
158
|
+
|
159
|
+
You should have received a copy of the GNU General Public License
|
160
|
+
along with bundler-audit. If not, see <http://www.gnu.org/licenses/>.
|
161
|
+
|
162
|
+
[ruby]: https://ruby-lang.org
|
163
|
+
[rubygems]: https://rubygems.org
|
164
|
+
[thor]: http://whatisthor.com/
|
165
|
+
[bundler]: https://github.com/carlhuda/bundler#readme
|
166
|
+
|
167
|
+
[OSVDB]: http://osvdb.org/
|
168
|
+
[ruby-advisory-db]: https://github.com/rubysec/ruby-advisory-db
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bundler/setup'
|
7
|
+
rescue LoadError => e
|
8
|
+
abort e.message
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'rake'
|
12
|
+
require 'time'
|
13
|
+
|
14
|
+
require 'rubygems/tasks'
|
15
|
+
Gem::Tasks.new
|
16
|
+
|
17
|
+
namespace :db do
|
18
|
+
desc 'Updates data/ruby-advisory-db'
|
19
|
+
task :update do
|
20
|
+
timestamp = nil
|
21
|
+
|
22
|
+
chdir 'data/ruby-advisory-db' do
|
23
|
+
sh 'git', 'pull', 'origin', 'master'
|
24
|
+
|
25
|
+
File.open('../ruby-advisory-db.ts','w') do |file|
|
26
|
+
file.write Time.parse(`git log --pretty="%cd" -1`).utc
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
sh 'git', 'commit', 'data/ruby-advisory-db',
|
31
|
+
'data/ruby-advisory-db.ts',
|
32
|
+
'-m', 'Updated ruby-advisory-db'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rspec/core/rake_task'
|
37
|
+
RSpec::Core::RakeTask.new
|
38
|
+
|
39
|
+
namespace :spec do
|
40
|
+
task :bundle do
|
41
|
+
root = 'spec/bundle'
|
42
|
+
|
43
|
+
%w[secure unpatched_gems insecure_sources].each do |bundle|
|
44
|
+
chdir(File.join(root,bundle)) do
|
45
|
+
sh 'unset BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT && bundle install --path ../../../vendor/bundle'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
task :spec => 'spec:bundle'
|
51
|
+
|
52
|
+
task :test => :spec
|
53
|
+
task :default => :spec
|
54
|
+
|
55
|
+
require 'yard'
|
56
|
+
YARD::Rake::YardocTask.new
|
57
|
+
task :doc => :yard
|
data/bin/bundle-audit
ADDED
data/bin/bundler-audit
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gemspec = YAML.load_file('gemspec.yml')
|
7
|
+
|
8
|
+
gem.name = gemspec.fetch('name')
|
9
|
+
gem.version = gemspec.fetch('version') do
|
10
|
+
lib_dir = File.join(File.dirname(__FILE__),'lib')
|
11
|
+
$LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
|
12
|
+
|
13
|
+
require 'bundler/audit/version'
|
14
|
+
Bundler::Audit::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
gem.summary = gemspec['summary']
|
18
|
+
gem.description = gemspec['description']
|
19
|
+
gem.licenses = Array(gemspec['license'])
|
20
|
+
gem.authors = Array(gemspec['authors'])
|
21
|
+
gem.email = gemspec['email']
|
22
|
+
gem.homepage = gemspec['homepage']
|
23
|
+
|
24
|
+
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
25
|
+
|
26
|
+
gem.files = `git ls-files`.split($/)
|
27
|
+
gem.files = glob[gemspec['files']] if gemspec['files']
|
28
|
+
|
29
|
+
# add paths from data/ruby-advisory-db/
|
30
|
+
gem.files += Dir.chdir('data/ruby-advisory-db') do
|
31
|
+
`git ls-files`.split($/).map do |sub_path|
|
32
|
+
File.join('data','ruby-advisory-db',sub_path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
gem.executables = gemspec.fetch('executables') do
|
37
|
+
glob['bin/*'].map { |path| File.basename(path) }
|
38
|
+
end
|
39
|
+
gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
|
40
|
+
|
41
|
+
gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
|
42
|
+
gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
|
43
|
+
gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
|
44
|
+
|
45
|
+
gem.require_paths = Array(gemspec.fetch('require_paths') {
|
46
|
+
%w[ext lib].select { |dir| File.directory?(dir) }
|
47
|
+
})
|
48
|
+
|
49
|
+
gem.requirements = gemspec['requirements']
|
50
|
+
gem.required_ruby_version = gemspec['required_ruby_version']
|
51
|
+
gem.required_rubygems_version = gemspec['required_rubygems_version']
|
52
|
+
gem.post_install_message = gemspec['post_install_message']
|
53
|
+
|
54
|
+
split = lambda { |string| string.split(/,\s*/) }
|
55
|
+
|
56
|
+
if gemspec['dependencies']
|
57
|
+
gemspec['dependencies'].each do |name,versions|
|
58
|
+
gem.add_dependency(name,split[versions])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if gemspec['development_dependencies']
|
63
|
+
gemspec['development_dependencies'].each do |name,versions|
|
64
|
+
gem.add_development_dependency(name,split[versions])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|