gem-compare 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59f10c0b2b0394d2e8a87fbab57322967e748748
4
- data.tar.gz: 71cd97b2bfc5ce47c313ed5f463d4df591b85934
3
+ metadata.gz: 41f631f7e0326a83d40c522f6003ee17c58d3862
4
+ data.tar.gz: 93bbd6f62d8c2a98bd93458f6dbb1c9f74647825
5
5
  SHA512:
6
- metadata.gz: 07b26651170a32be9f87c5f94e8ec954be21ce652bcd4459adab5daaf624f3e403aa5b1c68cf7e17617ade3e55c0ff0db2bae4b517659abf754b91cf34c9eb01
7
- data.tar.gz: d4321b3394deb868ed199c46c41a26a09dc436084d59d97d03ab986d92fc6a95a6e91550164e6d3b003b2ff175efeb809b637c2d99789e7137cb8251c10a0381
6
+ metadata.gz: d384515bab09282848e2900d9737f13222e331d2853cc4fc2bc49411b08118368aec9a4d3fcd023055fba4c3dc127654b35ff09679956485824196b01f35fea5
7
+ data.tar.gz: 3859779673f455b99b0a0230386b25f1b9aab3e02a8db1a533c1fb5fc2f2b97ee16a06707168d041cb7e0dfd89848a98eaeaf14c769944c18c283dc1c8359a48
@@ -1,10 +1,8 @@
1
- Copyright (c) 2013 sanemat
2
-
3
- MIT License
1
+ Copyright (c) Josef Strzibny.
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining
6
4
  a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
5
+ 'Software'), to deal in the Software without restriction, including
8
6
  without limitation the rights to use, copy, modify, merge, publish,
9
7
  distribute, sublicense, and/or sell copies of the Software, and to
10
8
  permit persons to whom the Software is furnished to do so, subject to
@@ -13,10 +11,10 @@ the following conditions:
13
11
  The above copyright notice and this permission notice shall be
14
12
  included in all copies or substantial portions of the Software.
15
13
 
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
15
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -1,29 +1,154 @@
1
- # Gem::Compare
1
+ # gem-compare
2
2
 
3
- Compare gem source code
3
+ ## Description
4
+
5
+ *gem-compare* is a RubyGems plugin that compares different versions of the specified gem. It can help you to track changes in metadata through the time, see how dependencies were evolving and spot important changes in gem's files such as shebang or permissions modifications.
4
6
 
5
7
  ## Installation
6
8
 
7
- Add this line to your application's Gemfile:
9
+ You can install `gem-compare` as a gem from RubyGems.org:
8
10
 
9
- gem 'gem-compare'
11
+ ```
12
+ gem install gem-compare
13
+ ```
10
14
 
11
- And then execute:
15
+ Once it's stable I will package it for Fedora.
12
16
 
13
- $ bundle
17
+ ## Usage
14
18
 
15
- Or install it yourself as:
19
+ By default, `gem-compare` compares specified versions of the given gem and includes only changes in the final report. If it's supposed to compare file lists or Gemfiles it will need to download the gems, otherwise it just downloads the specs. If you want to keep the downloaded `.gem` files, use `-k` (as 'keep') option. If you want to see the full report use `-a` (as 'all') switch:
16
20
 
17
- $ gem install gem-compare
21
+ ```
22
+ $ gem compare rails 3.0.0 4.0.0 -k
23
+ Compared versions: ["3.0.0", "4.0.0"]
24
+ DIFFERENT date:
25
+ 3.0.0: 2010-08-29 00:00:00 UTC
26
+ 4.0.0: 2013-06-25 00:00:00 UTC
27
+ DIFFERENT executables:
28
+ 3.0.0: ["rails"]
29
+ 4.0.0: []
30
+ DIFFERENT has_rdoc:
31
+ 3.0.0: true
32
+ 4.0.0:
33
+ DIFFERENT license:
34
+ 3.0.0:
35
+ 4.0.0: MIT
36
+ DIFFERENT licenses:
37
+ 3.0.0: []
38
+ 4.0.0: ["MIT"]
39
+ DIFFERENT required_ruby_version:
40
+ 3.0.0: >= 1.8.7
41
+ 4.0.0: >= 1.9.3
42
+ DIFFERENT required_rubygems_version:
43
+ 3.0.0: >= 1.3.6
44
+ 4.0.0: >= 1.8.11
45
+ DIFFERENT rubygems_version:
46
+ 3.0.0: 1.3.7
47
+ 4.0.0: 2.0.2
48
+ DIFFERENT version:
49
+ 3.0.0: 3.0.0
50
+ 4.0.0: 4.0.0
51
+ DIFFERENT files:
52
+ 3.0.0->4.0.0:
53
+ * Deleted:
54
+ bin/rails
55
+ * Added:
56
+ README.md
57
+ guides/assets/images/belongs_to.png
58
+ guides/assets/images/book_icon.gif
59
+ (...)
60
+ ```
18
61
 
19
- ## Usage
62
+ You can also specify what you are interested in by using -p (as 'param') option:
63
+
64
+ ```
65
+ $ gem compare activesupport 4.0.0 4.1.0 -p 'runtime_dependency'
66
+ Compared versions: ["4.0.0", "4.1.0"]
67
+ DIFFERENT runtime dependencies:
68
+ 4.0.0->4.1.0:
69
+ * Deleted:
70
+ multi_json ["~> 1.3"] (runtime)
71
+ * Added:
72
+ json [">= 1.7.7", "~> 1.7"] (runtime)
73
+ * Updated:
74
+ i18n from: [">= 0.6.4", "~> 0.6"] to: [">= 0.6.9", "~> 0.6"]
75
+ tzinfo from: ["~> 0.3.37"] to: ["~> 1.1"]
76
+ minitest from: ["~> 4.2"] to: ["~> 5.1"]
77
+ ```
78
+ There are also shortcuts for favourite options. Use `--runtime` for runtime dependencies, `--gemfiles` for comparing Gemfiles or `--files` for comparing file lists:
79
+
80
+ ```
81
+ $ gem compare rails 2.0.1 3.0.0 -k --files
82
+ Compared versions: ["2.0.1", "3.0.0"]
83
+ DIFFERENT files:
84
+ 2.0.1->3.0.0:
85
+ * Deleted:
86
+ bin
87
+ builtin
88
+ CHANGELOG
89
+ configs
90
+ dispatches
91
+ doc
92
+ environments
93
+ fresh_rakefile
94
+ helpers
95
+ html
96
+ lib
97
+ MIT-LICENSE
98
+ (...)
99
+ * Changed:
100
+ bin/rails 7/17
101
+ (!) New permissions: 100644 -> 100755
102
+ (!) File is now executable!
103
+ (!) Shebang probably added: #!/usr/bin/env ruby
104
+ ```
105
+
106
+ If you would like to see all development dependencies for `prawn` since `0.1` version, let *gem-compare* expand the versions for you:
107
+
108
+ ```
109
+ $ gem compare prawn '>=0.1' -k -a -p --development
110
+ Compared versions: ["0.1.0", "0.1.1", "0.1.2", "0.2.0", "0.2.1", "0.2.2", "0.2.3", "0.3.0", "0.4.0", "0.4.1", "0.5.0.1", "0.5.1", "0.6.1", "0.6.2", "0.6.3", "0.7.1", "0.7.2", "0.8.4", "0.11.1", "0.12.0", "0.13.0", "0.13.1", "0.13.2", "0.14.0", "0.15.0", "1.0.0", "1.1.0"]
111
+ DIFFERENT development dependencies:
112
+ 0.12.0->0.13.0:
113
+ * Added:
114
+ pdf-inspector ["~> 1.1.0"] (development)
115
+ coderay ["~> 1.0.7"] (development)
116
+ rdoc [">= 0"] (development)
117
+ 0.13.2->0.14.0:
118
+ * Deleted:
119
+ rdoc [">= 0"] (development)
120
+ * Added:
121
+ yard [">= 0"] (development)
122
+ rspec [">= 0"] (development)
123
+ mocha [">= 0"] (development)
124
+ rake [">= 0"] (development)
125
+ 0.14.0->0.15.0:
126
+ * Added:
127
+ simplecov [">= 0"] (development)
128
+ pdf-reader ["~> 1.2"] (development)
129
+ 1.0.0->1.1.0:
130
+ * Added:
131
+ prawn-manual_builder [">= 0.1.1"] (development)
132
+ rubocop ["= 0.20.1"] (development)
133
+ * Updated:
134
+ rspec from: [">= 0"] to: ["= 2.14.1"]
135
+ ```
136
+
137
+ ### Supported options
138
+
139
+ To see all possible options run:
140
+ ```
141
+ $ gem compare --help
142
+ ```
143
+
144
+ ## Requirements
145
+
146
+ Currently tested against RubyGems 2.x.
147
+
148
+ ## Contributions
20
149
 
21
- $ bundle exec gem compare bundler 2.0.0...2.0.1
150
+ Contributions are welcome! Please send a PR and make sure you follow the coding style.
22
151
 
23
- ## Contributing
152
+ ## Copyright
24
153
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
154
+ Released under the MIT license. Feel free to contribute!
data/Rakefile CHANGED
@@ -1 +1,41 @@
1
- require "bundler/gem_tasks"
1
+ require 'rubygems/package_task'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ gemspec = Gem::Specification.new do |s|
6
+ s.name = 'gem-compare'
7
+ s.version = '0.0.2'
8
+ s.platform = Gem::Platform::RUBY
9
+ s.summary = 'RubyGems plugin for comparing gem versions'
10
+ s.description = <<-EOF
11
+ gem-compare is a RubyGems plugin that helps to compare versions of the given gem.
12
+ It searches for differences in metadata as well as in files.
13
+ EOF
14
+ s.homepage = 'http://github.com/strzibny/gem-compare'
15
+ s.licenses = ['MIT']
16
+ s.author = 'Josef Stribny'
17
+ s.email = 'strzibny@strzibny.name'
18
+ s.files = FileList['README.md', 'LICENSE', 'Rakefile',
19
+ 'lib/**/*.rb', 'lib/**/**/*.rb', 'test/**/test*.rb']
20
+ s.required_ruby_version = '>= 2.0.0'
21
+ s.required_rubygems_version = '>= 2.0.0'
22
+ s.add_runtime_dependency 'diffy'
23
+ s.add_runtime_dependency 'rainbow'
24
+ s.add_runtime_dependency 'gemnasium-parser'
25
+ end
26
+
27
+ Gem::PackageTask.new gemspec do |pkg|
28
+ end
29
+
30
+ Rake::RDocTask.new do |rd|
31
+ rd.main = 'README.md'
32
+ rd.rdoc_files.include('README.md', 'lib/**/*.rb')
33
+ end
34
+
35
+ Rake::TestTask.new('test') do |t|
36
+ t.libs << 'test'
37
+ t.pattern = 'test/**/test*.rb'
38
+ t.verbose = true
39
+ end
40
+
41
+ task :default => [:test]
@@ -1,11 +1,88 @@
1
1
  require 'rubygems/command'
2
+ require 'rubygems/comparator'
2
3
 
3
4
  class Gem::Commands::CompareCommand < Gem::Command
4
5
  def initialize
5
- super 'compare', 'Compare!!!'
6
+ super 'compare', 'Compare gem\'s versions and generate a report of changes',
7
+ :output => Dir.pwd
8
+
9
+ add_option('-a', '--all', 'Show every comparison') do
10
+ options[:log_all] = true
11
+ end
12
+
13
+ add_option('-k', '--keep-all', 'Keep downloaded and extracted gem files') do
14
+ options[:keep_all] = true
15
+ end
16
+
17
+ add_option('-n', '--no-color', 'Do not colorize output') do
18
+ options[:no_color] = true
19
+ end
20
+
21
+ add_option('-pPARAM', '--param=PARAM', 'Compare only a given paramater') do |param, options|
22
+ options[:param] = param
23
+ end
24
+
25
+ add_option('-r', '--runtime', 'Compare only runtime dependencies') do
26
+ options[:param] = 'runtime_dependency'
27
+ end
28
+
29
+ add_option('-d', '--development', 'Compare only development dependencies') do
30
+ options[:param] = 'development_dependency'
31
+ end
32
+
33
+ add_option('-f', '--files', 'Compare only files for runtime') do
34
+ options[:param] = 'files'
35
+ end
36
+
37
+ add_option('-g', '--gemfiles', 'Compare only Gemfiles') do
38
+ options[:param] = 'gemfiles'
39
+ end
40
+
41
+ add_option('-b', '--brief', 'Include only important changes in the report') do
42
+ options[:log_all] = false
43
+ options[:brief] = true
44
+ end
45
+
46
+ end
47
+
48
+ def arguments # :nodoc:
49
+ args = <<-EOF
50
+ GEMNAME gem name
51
+ VERSION [VERSION ...] list of versions to compare
52
+ EOF
53
+ return args.gsub(/^\s+/, '')
54
+ end
55
+
56
+ def description # :nodoc:
57
+ desc = <<-EOF
58
+ gem-compare is a RubyGems plugin that compares versions of the given gem.
59
+ It searches for differences in metadata as well as in files.
60
+ EOF
61
+ return desc.gsub(/^\s+/, '')
62
+ end
63
+
64
+ def usage # :nodoc:
65
+ "#{program_name} GEMNAME VERSION [VERSION ...]"
6
66
  end
7
67
 
8
68
  def execute
9
- say 'compare compare compare'
69
+ gem_name = options[:args].shift
70
+ versions = options[:args]
71
+
72
+ # No gem specified
73
+ unless gem_name
74
+ raise Gem::CommandLineError,
75
+ "Please specify a gem (e.g. gem compare foo VERSION [VERSION ...])"
76
+ end
77
+
78
+ # No versions specified
79
+ if versions.empty?
80
+ raise Gem::CommandLineError,
81
+ "Please specify versions you want to compare (e.g. gem compare foo 0.1.0 0.2.0)"
82
+ end
83
+
84
+ comparator = Gem::Comparator.new(options)
85
+ comparator.compare_versions(gem_name, versions)
86
+ comparator.print_results
10
87
  end
11
88
  end
@@ -0,0 +1,198 @@
1
+ require 'tmpdir'
2
+ require 'rbconfig'
3
+ require 'rainbow'
4
+ require 'rubygems/package'
5
+ require 'rubygems/dependency'
6
+ require 'rubygems/spec_fetcher'
7
+ require 'rubygems/comparator/base'
8
+ require 'rubygems/comparator/report'
9
+ require 'rubygems/comparator/spec_comparator'
10
+ require 'rubygems/comparator/file_list_comparator'
11
+ require 'rubygems/comparator/dependency_comparator'
12
+ require 'rubygems/comparator/gemfile_comparator'
13
+
14
+ ##
15
+ # Gem::Comparator compares different version of the given
16
+ # gem. It can compare spec values as well as file lists or
17
+ # Gemfiles
18
+
19
+ class Gem::Comparator
20
+ include Gem::Comparator::Base
21
+ attr_accessor :options, :report
22
+
23
+ VERSION = '0.0.2'
24
+
25
+ ##
26
+ # Set the working dir and process options
27
+ #
28
+ # Creates temporal directory if the gem files shouldn't be kept
29
+
30
+ def initialize(options)
31
+ unless options[:keep_all]
32
+ options[:output] = Dir.mktmpdir
33
+ end
34
+
35
+ if options[:param] && !param_exists?(options[:param])
36
+ error 'Invalid parameter.'
37
+ end
38
+
39
+ if options[:no_color]
40
+ Rainbow.enabled = false
41
+ end
42
+
43
+ @options = options
44
+
45
+ # Results from the comparison
46
+ @report = Gem::Comparator::Report.new
47
+ end
48
+
49
+ ##
50
+ # Compare versions
51
+ #
52
+ # Compares file lists, requirements, other meta data
53
+
54
+ def compare_versions(gem_name, versions)
55
+ info "gem-compare in #{VERSION}"
56
+ # Expand versions (<=, >=, ~>) and sort them
57
+ versions = expand_versions(gem_name, versions)
58
+
59
+ error 'Only one version specified. Specify at lease two versions.' \
60
+ if versions.size == 1
61
+
62
+ versions.each do |version|
63
+ download_gems? ? download_package(gem_name, version) : download_specification(gem_name, version)
64
+ end
65
+
66
+ @report.set_header "Compared versions: #{versions}"
67
+
68
+ comparators = [SpecComparator,
69
+ FileListComparator,
70
+ DependencyComparator,
71
+ GemfileComparator]
72
+
73
+ comparators.each do |c|
74
+ comparator = c.new
75
+ cmp = (c::COMPARES == :packages) ? gem_packages.values : gem_specs.values
76
+ @report = comparator.compare(cmp, @report, @options)
77
+ end
78
+
79
+ # Clean up
80
+ FileUtils.rm_rf options[:output] unless options[:keep_all]
81
+ end
82
+
83
+ def print_results
84
+ info 'Printing results...'
85
+ @report.print
86
+ end
87
+
88
+ private
89
+
90
+ ##
91
+ # If there is an unexpanded version in +versions+ such
92
+ # as '>= 4.0.0' or '~>1.0.0', find all existing
93
+ # +gem_name+ versions that match the criteria
94
+ #
95
+ # Return list of expanded versions
96
+
97
+ def expand_versions(gem_name, versions)
98
+ info 'Expanding versions...'
99
+ expanded = []
100
+ versions.each do |version|
101
+ if version =~ VERSION_REGEX
102
+ expanded << version
103
+ next
104
+ end
105
+ op, v = (version.scan /(>=|<=|~>|!=|>|<|=)\s*(.*)/).flatten
106
+ # Supported operator and version?
107
+ if OPERATORS.include?(op) && v =~ VERSION_REGEX
108
+ dep = Gem::Dependency.new gem_name, version
109
+ specs_and_sources, errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
110
+ specs_and_sources.each do |s|
111
+ expanded << s[0].version
112
+ end
113
+ else
114
+ warn "Unsupported version specification: #{version}, skipping."
115
+ end
116
+ end
117
+
118
+ versions = expanded.uniq.map do |v|
119
+ Gem::Version.new v
120
+ end.sort.map(&:to_s)
121
+
122
+ error 'No versions found.' if versions.size == 0
123
+
124
+ info "Versions: #{versions}"
125
+ versions
126
+ end
127
+
128
+ def gem_file_name(gem_name, version)
129
+ "#{gem_name}-#{version}.gem"
130
+ end
131
+
132
+ def download_package(gem_name, version)
133
+ gem_file = gem_file_name(gem_name, version)
134
+ return gem_packages["#{gem_file}"] if gem_packages["#{gem_file}"]
135
+
136
+ find_downloaded_gem(gem_file)
137
+ return gem_packages["#{gem_file}"] if gem_packages["#{gem_file}"]
138
+
139
+ spec, source = download_specification(gem_name, version)
140
+
141
+ Dir.chdir @options[:output] do
142
+ source.download spec
143
+ end
144
+
145
+ package = Gem::Package.new File.join(@options[:output], gem_file)
146
+ use_package(package)
147
+ info "#{gem_file} downloaded."
148
+
149
+ package
150
+ end
151
+
152
+ def download_specification(gem_name, version)
153
+ gem_file = gem_file_name(gem_name, version)
154
+ return gem_specs["#{gem_file}"] if gem_specs["#{gem_file}"]
155
+
156
+ find_downloaded_gem(gem_file)
157
+ return gem_specs["#{gem_file}"] if gem_specs["#{gem_file}"]
158
+
159
+ dep = Gem::Dependency.new gem_name, version
160
+ specs_and_sources, _errors = Gem::SpecFetcher.fetcher.spec_for_dependency dep
161
+ spec, source = specs_and_sources.max_by { |s,| s.version }
162
+ error "Gem #{gem_name} in #{version} doesn't exist." if spec.nil?
163
+ gem_specs["#{gem_file}"] = spec
164
+
165
+ [spec, source]
166
+ end
167
+
168
+ def find_downloaded_gem(gem_file)
169
+ if File.exist? File.join(@options[:output], gem_file)
170
+ info "#{gem_file} exists, using already downloaded file."
171
+ package = Gem::Package.new File.join(@options[:output], gem_file)
172
+ use_package(package)
173
+ [package, package.spec]
174
+ else
175
+ [nil, nil]
176
+ end
177
+ end
178
+
179
+ def use_package(package)
180
+ gem_file = gem_file_name(package.spec.name, package.spec.version)
181
+ gem_packages["#{gem_file}"] = package
182
+ gem_specs["#{gem_file}"] = package.spec
183
+ end
184
+
185
+ def download_gems?
186
+ return true if @options[:keep_all]
187
+ @options[:param] ? SPEC_FILES_PARAMS.include?(@options[:param]) : true
188
+ end
189
+
190
+ def gem_packages
191
+ @gem_packages ||= {}
192
+ end
193
+
194
+ def gem_specs
195
+ @gem_specs ||= {}
196
+ end
197
+
198
+ end