pessimize 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 07827e52ca20091ec3c526e48c17b98cba42b107
4
+ data.tar.gz: b564e247b10d5047a2ac550ea8dfe30173915ede
5
+ SHA512:
6
+ metadata.gz: 16636018050e5d063a624208ba84ff2e9a111e810e5a1cbc405a4aa0a18f5f09a75eb0b72d6fa9813ba3da08615938d15ec54081942d86e5af152a7ec5c35008
7
+ data.tar.gz: bbd02c68466c4dba8109f88c6cdf02ec1d7104d8a42317b84b279daf3d7709e7d51a3d7d6b580a5583fd52c40adacee0aa33fc5d34476f4e0eb89d1b0314fc1b
data/.travis.yml CHANGED
@@ -4,4 +4,4 @@ rvm:
4
4
  - 2.0.0
5
5
  - 1.9.3
6
6
  - 1.9.2
7
- - jruby-1.7.3
7
+ - jruby-1.7.10
@@ -1,3 +1,8 @@
1
+ === Pessimize 0.2.0
2
+
3
+ Features:
4
+ * Use token parsing instead of interpreting the Gemfile, which allows the Gemfile formatting to be retained (issue #5)
5
+
1
6
  === Pessimize 0.1.0
2
7
 
3
8
  Features:
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Pessimize
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/pessimize.png)](http://badge.fury.io/rb/pessimize)
3
4
  [![Build Status](https://travis-ci.org/joonty/pessimize.png?branch=master)](https://travis-ci.org/joonty/pessimize)
4
5
 
5
6
  ### Who is this for?
@@ -64,9 +65,9 @@ Also, by default, the Gemfile and Gemfile.lock are copied as a form of backup. T
64
65
 
65
66
  ## Known issues
66
67
 
67
- Pessimize evaluates the Gemfile as executable ruby code. That means that anything method-like will be retained in the output (e.g. `gem "nokogiri"`, or `source "https://rubygems.org"`), but anything else such as conditional statements will not.
68
+ Pessimize parses the Gemfile as tokens, and does some tricky stuff to replace or insert version numbers. However, this is fairly experimental and there are plans to use a proper ruby parser, which should be more reliable and cut out the edge cases. It *should* currently work for the majority of cases, but there are no guarantees.
68
69
 
69
- There are plans to fix this: [see this issue][3] for tracking the progress.
70
+ [See this issue][3] for tracking the progress.
70
71
 
71
72
  ## Why `bundle update` can be dangerous
72
73
 
@@ -32,7 +32,7 @@ module Pessimize
32
32
  def backup_file!(file)
33
33
  cmd = "cp #{file} #{file}.backup"
34
34
  puts " + #{cmd}"
35
- system cmd
35
+ `#{cmd}`
36
36
  $?.exitstatus == 0
37
37
  end
38
38
  end
data/lib/pessimize/gem.rb CHANGED
@@ -1,25 +1,63 @@
1
1
  module Pessimize
2
2
  class Gem
3
- attr_reader :name, :version, :options
4
- attr_writer :version
3
+ attr_reader :name, :original_tokens
4
+ attr_accessor :version
5
5
 
6
- def initialize(*args)
7
- @name = args.shift
8
- while arg = args.shift
9
- if arg.is_a? Hash
10
- @options = arg
11
- else
12
- @version = arg
13
- end
6
+ def initialize(gem_tokens)
7
+ self.original_tokens = gem_tokens
8
+ parse_name
9
+ parse_version
10
+ end
11
+
12
+ def tokens
13
+ compiled_tokens = original_tokens.dup
14
+ if version_index
15
+ compiled_tokens[version_index][2] = version
16
+ elsif version
17
+ compiled_tokens[after_name_index..0] = version_tokens
14
18
  end
19
+ compiled_tokens
15
20
  end
16
21
 
17
- def to_code
18
- s = ""
19
- s << %Q{gem "#{name}"}
20
- s << %Q{, "#{version}"} if version
21
- s << %Q{, #{options.inspect}} if options
22
- s
22
+ def to_s
23
+ tokens.inject("") { |a, t| a << t[2] }
24
+ end
25
+
26
+ protected
27
+ attr_writer :name, :original_tokens
28
+ attr_accessor :version_index,
29
+ :token_before_version,
30
+ :after_name_index
31
+
32
+ def version_tokens
33
+ [
34
+ [[], :on_comma, ","],
35
+ [[], :on_sp, " "],
36
+ [[], :on_tstring_beg, "\""],
37
+ [[], :on_tstring_content, version],
38
+ [[], :on_tstring_end, "\""]
39
+ ]
40
+ end
41
+
42
+ def parse_name
43
+ name_index = original_tokens.index { |t| t[1] == :on_tstring_content }
44
+ self.name = original_tokens[name_index][2]
45
+ self.after_name_index = name_index + 2
46
+ end
47
+
48
+ def parse_version
49
+ token_before_version = original_tokens.index { |t| t[1] == :on_comma }
50
+ if token_before_version
51
+ remaining_tokens = original_tokens[(token_before_version + 1)..-1]
52
+ while [:on_sp, :on_tstring_beg].include? remaining_tokens.first[1]
53
+ remaining_tokens.shift
54
+ token_before_version += 1
55
+ end
56
+ if remaining_tokens.first[1] == :on_tstring_content
57
+ self.version_index = token_before_version + 1
58
+ self.version = remaining_tokens.first[2]
59
+ end
60
+ end
23
61
  end
24
62
  end
25
63
  end
@@ -0,0 +1,52 @@
1
+ require 'ripper'
2
+ require 'pessimize/gem'
3
+
4
+ module Pessimize
5
+ class Gemfile
6
+ attr_reader :tokens, :gems
7
+
8
+ def initialize(contents)
9
+ self.tokens = Ripper.lex(contents)
10
+ self.gems = []
11
+ self.gem_token_map = []
12
+ parse_tokens!
13
+ end
14
+
15
+ def to_s
16
+ compiled_tokens = tokens.dup
17
+ current_offset = 0
18
+ gem_token_map.zip(gems).each do |(tok_start, tok_end), gem|
19
+ gem_tokens = gem.tokens
20
+ compiled_tokens[(current_offset + tok_start)..(current_offset + tok_end)] = gem_tokens
21
+ current_offset += gem_tokens.length - (tok_end - tok_start + 1)
22
+ end
23
+ compiled_tokens.inject("") { |a, e|
24
+ a + e[2]
25
+ }
26
+ end
27
+
28
+ protected
29
+ attr_writer :gems, :tokens
30
+ attr_accessor :gem_token_map
31
+
32
+ def parse_tokens!
33
+ enum = tokens.each_with_index
34
+
35
+ loop do
36
+ (tok, i) = enum.next
37
+
38
+ if tok[1] == :on_ident && tok[2] == "gem"
39
+ gem_toks = []
40
+ until [:on_nl].include?(enum.peek[0][1])
41
+ (tok, j) = enum.next
42
+ gem_toks << tok
43
+ end
44
+
45
+ self.gems << Pessimize::Gem.new(gem_toks)
46
+ self.gem_token_map << [i + 1, j]
47
+ end
48
+ end
49
+ rescue StopIteration
50
+ end
51
+ end
52
+ end
@@ -6,21 +6,21 @@ module Pessimize
6
6
 
7
7
  def initialize
8
8
  self.versions = {}
9
- self.parse_enabled = false
10
9
  end
11
10
 
12
11
  def call(gemfile_lock_file)
13
- parser = Bundler::LockfileParser.new gemfile_lock_file.read
14
- self.versions = collect_names_and_versions parser.specs
12
+ parser = Bundler::LockfileParser.new(gemfile_lock_file.read)
13
+ self.versions = collect_names_and_versions(parser.specs)
15
14
  self
16
15
  end
17
16
 
18
17
  protected
19
18
  attr_writer :versions
20
- attr_accessor :parse_enabled
21
19
 
22
20
  def collect_names_and_versions(specs)
23
- Hash[specs.collect { |s| [s.name, s.version.to_s] }]
21
+ Hash[specs.
22
+ reject { |s| s.source.is_a?(Bundler::Source::Git) }.
23
+ collect { |s| [s.name, s.version.to_s] }]
24
24
  end
25
25
  end
26
26
  end
@@ -1,5 +1,4 @@
1
- require 'pessimize/dsl'
2
- require 'pessimize/gem_collection'
1
+ require 'pessimize/gemfile'
3
2
  require 'pessimize/gemfile_lock_version_parser'
4
3
  require 'pessimize/version_mapper'
5
4
 
@@ -8,8 +7,6 @@ module Pessimize
8
7
  def initialize(file_manager, options)
9
8
  self.file_manager = file_manager
10
9
  self.options = options
11
- self.collection = GemCollection.new
12
- self.dsl = DSL.new collection
13
10
  self.lock_parser = GemfileLockVersionParser.new
14
11
  end
15
12
 
@@ -17,49 +14,30 @@ module Pessimize
17
14
  collect_gems_and_versions
18
15
  update_gem_versions
19
16
  write_new_gemfile
20
- puts "~> written #{collection.all.length} gems to Gemfile, constrained to #{options[:version_constraint]} version updates\n\n"
17
+ puts "~> written #{gemfile.gems.length} gems to Gemfile, constrained to #{options[:version_constraint]} version updates\n\n"
21
18
  end
22
19
 
23
20
  protected
24
- attr_accessor :collection, :dsl, :lock_parser, :file_manager, :options
21
+ attr_accessor :gemfile, :lock_parser, :file_manager, :options
25
22
 
26
23
  def sep(num = 1)
27
24
  "\n" * num
28
25
  end
29
26
 
30
27
  def collect_gems_and_versions
31
- dsl.parse file_manager.gemfile_contents
28
+ self.gemfile = Gemfile.new(file_manager.gemfile_contents)
32
29
  lock_parser.call File.open(file_manager.gemfile_lock)
33
30
  end
34
31
 
35
32
  def update_gem_versions
36
- VersionMapper.new.call(collection.all, lock_parser.versions, options[:version_constraint])
33
+ VersionMapper.new.call(gemfile.gems, lock_parser.versions, options[:version_constraint])
37
34
  end
38
35
 
39
36
  def write_new_gemfile
40
37
  File.delete(file_manager.gemfile)
41
38
  File.open(file_manager.gemfile, 'w') do |f|
42
- collection.declarations.each do |dec|
43
- f.write(dec.to_code + sep)
44
- end
45
- f.write sep(1)
46
- gem_groups = collection.gems
47
- global_gems = gem_groups[:global]
48
- gem_groups.delete :global
49
- gem_groups.each do |group, gems|
50
- f.write("group :#{group} do#{sep}")
51
- gems.each do |gem|
52
- f.write(" " + gem.to_code + sep)
53
- end
54
- f.write("end" + sep(2))
55
- end
56
- if global_gems
57
- global_gems.each do |gem|
58
- f.write(gem.to_code + sep)
59
- end
60
- end
39
+ f.write gemfile.to_s
61
40
  end
62
41
  end
63
-
64
42
  end
65
43
  end
@@ -1,3 +1,3 @@
1
1
  module Pessimize
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/spec/gem_spec.rb CHANGED
@@ -1,36 +1,74 @@
1
1
  require 'spec_helper'
2
- require 'pessimize/gem.rb'
2
+ require 'pessimize/gem'
3
3
 
4
4
  module Pessimize
5
5
  describe Gem do
6
- context "creating with the name as the only parameter" do
7
- let(:gem) { Gem.new 'ponies' }
8
- subject { gem }
6
+ context "creating a gem with just a name" do
7
+ let(:gem) { Gem.new(Ripper.lex('gem "monkey"')) }
8
+ subject { gem }
9
9
 
10
- its(:name) { should == 'ponies' }
11
- its(:to_code) { should == 'gem "ponies"' }
10
+ its(:name) { should == "monkey" }
11
+ its(:version) { should be_nil }
12
+ its(:to_s) { should == 'gem "monkey"' }
12
13
 
13
- context "setting the version" do
14
- before { gem.version = '~> 3.0.0' }
14
+ context "after setting the version" do
15
+ before do
16
+ gem.version = "~> 2.3.5"
17
+ end
15
18
 
16
- its(:version) { should == '~> 3.0.0' }
17
- its(:to_code) { should == 'gem "ponies", "~> 3.0.0"' }
19
+ its(:to_s) { should == 'gem "monkey", "~> 2.3.5"' }
18
20
  end
19
21
  end
20
22
 
21
- context "creating with a name and version string" do
22
- subject { Gem.new 'trolls', '>= 3.0' }
23
+ context "creating a gem with a name and version" do
24
+ let(:gem) { Gem.new(Ripper.lex('gem "monkey", "~> 3.0"')) }
25
+ subject { gem }
23
26
 
24
- its(:name) { should == 'trolls' }
25
- its(:version) { should == '>= 3.0' }
26
- its(:to_code) { should == 'gem "trolls", ">= 3.0"' }
27
+ its(:name) { should == "monkey" }
28
+ its(:version) { should == "~> 3.0" }
29
+ its(:to_s) { should == 'gem "monkey", "~> 3.0"' }
30
+
31
+ context "after setting the version" do
32
+ before do
33
+ gem.version = "~> 1.0"
34
+ end
35
+
36
+ its(:to_s) { should == 'gem "monkey", "~> 1.0"' }
37
+ end
27
38
  end
28
39
 
29
- context "creating with a name and options hash" do
30
- subject { Gem.new 'slow_loris', :require => false, :path => '/a/b/c' }
31
- its(:name) { should == 'slow_loris' }
32
- its(:options) { should == {:require => false, :path => '/a/b/c'} }
33
- its(:to_code) { should == 'gem "slow_loris", {:require=>false, :path=>"/a/b/c"}' }
40
+ context "creating a gem with a name and git url" do
41
+ let(:gem) { Gem.new(Ripper.lex('gem "something", git: git@somewhere.org:project.git')) }
42
+ subject { gem }
43
+
44
+ its(:name) { should == "something" }
45
+ its(:version) { should be_nil }
46
+
47
+ context "after setting the version" do
48
+ before do
49
+ gem.version = "~> 0.0.1"
50
+ end
51
+
52
+ its(:to_s) { should == 'gem "something", "~> 0.0.1", git: git@somewhere.org:project.git' }
53
+ end
54
+
55
+ end
56
+
57
+ context "creating a gem with a name, version and options" do
58
+ let(:gem) { Gem.new(Ripper.lex('gem "blah", "2.0.0beta", group: :development')) }
59
+ subject { gem }
60
+
61
+ its(:name) { should == "blah" }
62
+ its(:version) { should == "2.0.0beta" }
63
+
64
+ context "after setting the version" do
65
+ before do
66
+ gem.version = "~> 2.1"
67
+ end
68
+
69
+ its(:to_s) { should == 'gem "blah", "~> 2.1", group: :development' }
70
+ end
71
+
34
72
  end
35
73
  end
36
74
  end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+ require 'pessimize/gemfile'
3
+
4
+ module Pessimize
5
+ describe Gemfile do
6
+ context "with a single gem definition" do
7
+ let(:gem_defn) { <<-GEM
8
+ source "https://rubygems.org"
9
+
10
+ gem "monkey"
11
+ GEM
12
+ }
13
+
14
+ subject(:gemfile) { Gemfile.new(gem_defn) }
15
+
16
+ its(:to_s) { should == gem_defn }
17
+
18
+ describe "#gems" do
19
+ subject(:gems) { gemfile.gems }
20
+
21
+ its(:length) { should == 1 }
22
+
23
+ describe "the first gem" do
24
+ subject { gems.first }
25
+
26
+ its(:name) { should == "monkey" }
27
+ end
28
+ end
29
+ end
30
+
31
+ context "with a gem definition and group" do
32
+ let(:gem_defn) { <<-GEM
33
+ source "https://rubygems.org"
34
+
35
+ group :development do
36
+ gem "monkey"
37
+ end
38
+ GEM
39
+ }
40
+
41
+ subject(:gemfile) { Gemfile.new(gem_defn) }
42
+
43
+ its(:to_s) { should == gem_defn }
44
+
45
+ describe "#gems" do
46
+ subject(:gems) { gemfile.gems }
47
+
48
+ its(:length) { should == 1 }
49
+
50
+ describe "the first gem" do
51
+ subject { gems.first }
52
+
53
+ its(:name) { should == "monkey" }
54
+ end
55
+ end
56
+ end
57
+
58
+ context "with multiple gem definitions" do
59
+
60
+ let(:gem_defn) { <<-GEM
61
+ source "https://rubygems.org"
62
+
63
+ gem "monkey", "2.0.0"
64
+
65
+ gem "thor", ">= 1.3.0"
66
+ GEM
67
+ }
68
+
69
+ subject(:gemfile) { Gemfile.new(gem_defn) }
70
+
71
+ its(:to_s) { should == gem_defn }
72
+
73
+ describe "#gems" do
74
+ subject(:gems) { gemfile.gems }
75
+
76
+ its(:length) { should == 2 }
77
+
78
+ describe "the first gem" do
79
+ subject(:gem) { gems[0] }
80
+
81
+ its(:name) { should == "monkey" }
82
+ its(:version) { should == "2.0.0" }
83
+ its(:to_s) { should == ' "monkey", "2.0.0"' }
84
+
85
+ context "setting the version" do
86
+ before do
87
+ gem.version = "~> 2.0.0"
88
+ end
89
+
90
+ its(:to_s) { should == ' "monkey", "~> 2.0.0"' }
91
+ end
92
+ end
93
+
94
+ describe "the second gem" do
95
+ subject { gems[1] }
96
+
97
+ its(:name) { should == "thor" }
98
+ its(:version) { should == ">= 1.3.0" }
99
+ end
100
+ end
101
+
102
+ context "after setting the gem versions" do
103
+ before do
104
+ gemfile.gems.each do |gem|
105
+ gem.version = "~> 1.0.0"
106
+ end
107
+ end
108
+
109
+ let(:expected_defn) { <<-GEM
110
+ source "https://rubygems.org"
111
+
112
+ gem "monkey", "~> 1.0.0"
113
+
114
+ gem "thor", "~> 1.0.0"
115
+ GEM
116
+ }
117
+
118
+ its(:to_s) { should == expected_defn }
119
+ end
120
+ end
121
+ end
122
+ end
@@ -12,13 +12,13 @@ describe "running pessimize" do
12
12
 
13
13
  context "after execution" do
14
14
 
15
- context "the stderr" do
15
+ context "the stderr", exclude_platform: :java do
16
16
  subject { stderr }
17
17
  it { should == "" }
18
18
  end
19
19
 
20
20
  # exclude from jruby
21
- context "the return code", platform: :jruby do
21
+ context "the return code", exclude_platform: :java do
22
22
  subject { $?.exitstatus }
23
23
  it { should == 0 }
24
24
  end
@@ -56,7 +56,7 @@ describe "running pessimize" do
56
56
  end
57
57
 
58
58
  # exclude from jruby
59
- context "the return code", platform: :jruby do
59
+ context "the return code", exclude_platform: :java do
60
60
  subject { $?.exitstatus }
61
61
  it { should == 0 }
62
62
  end
@@ -240,9 +240,8 @@ GEM
240
240
 
241
241
  result = <<-EOD
242
242
  source "https://rubygems.org"
243
-
244
- gem "json", "~> 1.8"
245
- gem "rake", "~> 10.0"
243
+ gem 'json', "~> 1.8"
244
+ gem 'rake', "~> 10.0"
246
245
  EOD
247
246
 
248
247
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -275,17 +274,16 @@ GEM
275
274
 
276
275
  result = <<-EOD
277
276
  source "https://rubygems.org"
277
+ gem 'json', "~> 1.8"
278
+ gem 'rake', "~> 10.0"
278
279
 
279
280
  group :development do
280
- gem "sqlite3", "~> 1.3"
281
+ gem 'sqlite3', '~> 1.3'
281
282
  end
282
283
 
283
284
  group :production do
284
- gem "pg", "~> 0.15"
285
+ gem 'pg', '~> 0.15', '<= 0.15.2'
285
286
  end
286
-
287
- gem "json", "~> 1.8"
288
- gem "rake", "~> 10.0"
289
287
  EOD
290
288
 
291
289
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -313,17 +311,12 @@ GEM
313
311
 
314
312
  result = <<-EOD
315
313
  source "https://rubygems.org"
314
+ gem 'json', "~> 1.8"
315
+ gem 'rake', "~> 10.0"
316
316
 
317
- group :development do
318
- gem "sqlite3", "~> 1.3"
319
- end
320
-
321
- group :test do
322
- gem "sqlite3", "~> 1.3"
317
+ group :development, :test do
318
+ gem 'sqlite3', '~> 1.3'
323
319
  end
324
-
325
- gem "json", "~> 1.8"
326
- gem "rake", "~> 10.0"
327
320
  EOD
328
321
 
329
322
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -351,17 +344,12 @@ GEM
351
344
 
352
345
  result = <<-EOD
353
346
  source "https://rubygems.org"
347
+ gem 'json', "~> 1.8"
348
+ gem 'rake', "~> 10.0"
354
349
 
355
- group :development do
356
- gem "sqlite3", "~> 1.3"
357
- end
358
-
359
- group :test do
360
- gem "sqlite3", "~> 1.3"
350
+ group [:development, :test] do
351
+ gem 'sqlite3', '~> 1.3'
361
352
  end
362
-
363
- gem "json", "~> 1.8"
364
- gem "rake", "~> 10.0"
365
353
  EOD
366
354
 
367
355
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -383,8 +371,7 @@ GEM
383
371
 
384
372
  result = <<-EOD
385
373
  source "https://rubygems.org"
386
- source "https://somewhereelse.com"
387
-
374
+ source 'https://somewhereelse.com'
388
375
  EOD
389
376
 
390
377
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -430,9 +417,9 @@ GEM
430
417
 
431
418
  result = <<-EOD
432
419
  source "https://somewhere-else.org"
420
+ gem 'metric_fu', :git => 'https://github.com/joonty/metric_fu.git', :branch => 'master'
433
421
 
434
- gem "metric_fu", {:git=>"https://github.com/joonty/metric_fu.git", :branch=>"master"}
435
- gem "kaminari", "~> 0.14", {:require=>false}
422
+ gem "kaminari", "~> 0.14", :require => false
436
423
  EOD
437
424
 
438
425
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -478,9 +465,9 @@ GEM
478
465
 
479
466
  result = <<-EOD
480
467
  source "https://somewhere-else.org"
468
+ gem 'metric_fu', :git => 'https://github.com/joonty/metric_fu.git', :branch => 'master'
481
469
 
482
- gem "metric_fu", {:git=>"https://github.com/joonty/metric_fu.git", :branch=>"master"}
483
- gem "kaminari", "~> 0.14", {:require=>false}
470
+ gem "kaminari", "~> 0.14", :require => false
484
471
  EOD
485
472
 
486
473
  it_behaves_like "a working pessimizer", gemfile, lockfile, result
@@ -508,17 +495,12 @@ GEM
508
495
 
509
496
  result = <<-EOD
510
497
  source "https://rubygems.org"
498
+ gem 'json', "~> 1.8.0"
499
+ gem 'rake', "~> 10.0.4"
511
500
 
512
- group :development do
513
- gem "sqlite3", "~> 1.3.7"
514
- end
515
-
516
- group :test do
517
- gem "sqlite3", "~> 1.3.7"
501
+ group :development, :test do
502
+ gem 'sqlite3', '~> 1.3.7'
518
503
  end
519
-
520
- gem "json", "~> 1.8.0"
521
- gem "rake", "~> 10.0.4"
522
504
  EOD
523
505
 
524
506
  it_behaves_like "a working pessimizer", gemfile, lockfile, result, '-c patch'
@@ -546,17 +528,12 @@ GEM
546
528
 
547
529
  result = <<-EOD
548
530
  source "https://rubygems.org"
531
+ gem 'json', "~> 1.8"
532
+ gem 'rake', "~> 10.0"
549
533
 
550
- group :development do
551
- gem "sqlite3", "~> 1.3"
552
- end
553
-
554
- group :test do
555
- gem "sqlite3", "~> 1.3"
534
+ group :development, :test do
535
+ gem 'sqlite3', '~> 1.3'
556
536
  end
557
-
558
- gem "json", "~> 1.8"
559
- gem "rake", "~> 10.0"
560
537
  EOD
561
538
 
562
539
  it_behaves_like "a working pessimizer without backups", gemfile, lockfile, result, '--no-backup'
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  require 'rspec'
2
2
  require 'pessimize'
3
3
  require 'open3'
4
+ require 'ripper'
4
5
 
5
6
  def data_file(name)
6
7
  File.new(File.dirname(__FILE__) + '/data/' + name)
7
8
  end
8
9
 
9
10
  RSpec.configure do |c|
10
- c.filter_run_excluding :platform => lambda { |platform|
11
+ c.filter_run_excluding :exclude_platform => lambda { |platform|
11
12
  RUBY_PLATFORM.to_s == platform.to_s
12
13
  }
13
14
  end
@@ -4,8 +4,14 @@ require 'pessimize/gem'
4
4
 
5
5
  module Pessimize
6
6
  describe VersionMapper do
7
+ def gem(name, version = nil)
8
+ gem_string = %Q{gem "#{name}"}
9
+ gem_string << %Q{, "#{version}"} if version
10
+ Gem.new(Ripper.lex(gem_string))
11
+ end
12
+
7
13
  context "with a gem, version hash and minor constraint" do
8
- let(:gems) { [ Gem.new('example') ] }
14
+ let(:gems) { [ gem('example') ] }
9
15
  let(:versions) { { 'example' => '2.2.3' } }
10
16
  let(:mapper) { VersionMapper.new }
11
17
 
@@ -19,7 +25,7 @@ module Pessimize
19
25
  end
20
26
 
21
27
  context "with multiple gems, version hash and minor constraint" do
22
- let(:gems) { [ Gem.new('example'), Gem.new('fish', '1.3.2') ] }
28
+ let(:gems) { [ gem('example'), gem('fish', '1.3.2') ] }
23
29
  let(:versions) { { 'example' => '1.4.9', 'fish' => '2.3.0' } }
24
30
  let(:mapper) { VersionMapper.new }
25
31
 
@@ -41,7 +47,7 @@ module Pessimize
41
47
  end
42
48
 
43
49
  context "with a gem, version hash and patch constraint" do
44
- let(:gems) { [ Gem.new('example') ] }
50
+ let(:gems) { [ gem('example') ] }
45
51
  let(:versions) { { 'example' => '2.2.3' } }
46
52
  let(:mapper) { VersionMapper.new }
47
53
 
@@ -55,7 +61,7 @@ module Pessimize
55
61
  end
56
62
 
57
63
  context "with multiple gems, version hash and patch constraint" do
58
- let(:gems) { [ Gem.new('example'), Gem.new('fish', '1.3.2') ] }
64
+ let(:gems) { [ gem('example'), gem('fish', '1.3.2') ] }
59
65
  let(:versions) { { 'example' => '1.4.9', 'fish' => '2.3.0' } }
60
66
  let(:mapper) { VersionMapper.new }
61
67
 
metadata CHANGED
@@ -1,89 +1,75 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pessimize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jon Cairns
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-03 00:00:00.000000000 Z
11
+ date: 2015-10-29 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
15
+ version_requirements: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
20
+ requirement: !ruby/object:Gem::Requirement
26
21
  requirements:
27
- - - ! '>='
22
+ - - '>='
28
23
  - !ruby/object:Gem::Version
29
24
  version: '0'
25
+ prerelease: false
26
+ type: :runtime
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: trollop
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
29
+ version_requirements: !ruby/object:Gem::Requirement
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
34
+ requirement: !ruby/object:Gem::Requirement
42
35
  requirements:
43
- - - ! '>='
36
+ - - '>='
44
37
  - !ruby/object:Gem::Version
45
38
  version: '0'
39
+ prerelease: false
40
+ type: :runtime
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
43
+ version_requirements: !ruby/object:Gem::Requirement
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
53
47
  version: 2.13.0
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
48
+ requirement: !ruby/object:Gem::Requirement
58
49
  requirements:
59
50
  - - ~>
60
51
  - !ruby/object:Gem::Version
61
52
  version: 2.13.0
53
+ prerelease: false
54
+ type: :development
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
57
+ version_requirements: !ruby/object:Gem::Requirement
66
58
  requirements:
67
59
  - - ~>
68
60
  - !ruby/object:Gem::Version
69
61
  version: 10.0.3
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
62
+ requirement: !ruby/object:Gem::Requirement
74
63
  requirements:
75
64
  - - ~>
76
65
  - !ruby/object:Gem::Version
77
66
  version: 10.0.3
78
- description: ! 'Add the pessimistic constraint operator to all gems in your Gemfile,
79
- restricting the maximum update version.
80
-
67
+ prerelease: false
68
+ type: :development
69
+ description: |-
70
+ Add the pessimistic constraint operator to all gems in your Gemfile, restricting the maximum update version.
81
71
 
82
- This is for people who work with projects that use bundler, such as rails projects.
83
- The pessimistic constraint operator (~>) allows you to specify the maximum version
84
- that a gem can be updated, and reduces potential breakages when running `bundle
85
- update`. Pessimize automatically retrieves the current versions of your gems, then
86
- adds them to your Gemfile (so you don''t have to do it by hand).'
72
+ This is for people who work with projects that use bundler, such as rails projects. The pessimistic constraint operator (~>) allows you to specify the maximum version that a gem can be updated, and reduces potential breakages when running `bundle update`. Pessimize automatically retrieves the current versions of your gems, then adds them to your Gemfile (so you don't have to do it by hand).
87
73
  email:
88
74
  - jon@joncairns.com
89
75
  executables:
@@ -93,18 +79,16 @@ extra_rdoc_files: []
93
79
  files:
94
80
  - .gitignore
95
81
  - .travis.yml
82
+ - CHANGELOG
96
83
  - Gemfile
97
- - HISTORY
98
84
  - LICENSE.txt
99
85
  - README.md
100
86
  - Rakefile
101
87
  - bin/pessimize
102
88
  - lib/pessimize.rb
103
- - lib/pessimize/declaration.rb
104
- - lib/pessimize/dsl.rb
105
89
  - lib/pessimize/file_manager.rb
106
90
  - lib/pessimize/gem.rb
107
- - lib/pessimize/gem_collection.rb
91
+ - lib/pessimize/gemfile.rb
108
92
  - lib/pessimize/gemfile_lock_version_parser.rb
109
93
  - lib/pessimize/pessimizer.rb
110
94
  - lib/pessimize/shell.rb
@@ -113,54 +97,42 @@ files:
113
97
  - pessimize.gemspec
114
98
  - spec/data/Gemfile.lock.example
115
99
  - spec/data/Gemfile.lock.example2
116
- - spec/declaration_spec.rb
117
- - spec/dsl_spec.rb
118
- - spec/gem_collection_spec.rb
119
100
  - spec/gem_spec.rb
120
101
  - spec/gemfile_lock_version_parser_spec.rb
102
+ - spec/gemfile_spec.rb
121
103
  - spec/integration_spec.rb
122
104
  - spec/spec_helper.rb
123
105
  - spec/version_mapper_spec.rb
124
106
  homepage: https://github.com/joonty/pessimize
125
107
  licenses:
126
108
  - MIT
127
- post_install_message:
109
+ metadata: {}
110
+ post_install_message:
128
111
  rdoc_options: []
129
112
  require_paths:
130
113
  - lib
131
114
  required_ruby_version: !ruby/object:Gem::Requirement
132
- none: false
133
115
  requirements:
134
- - - ! '>='
116
+ - - '>='
135
117
  - !ruby/object:Gem::Version
136
118
  version: '0'
137
- segments:
138
- - 0
139
- hash: 102420707118458476
140
119
  required_rubygems_version: !ruby/object:Gem::Requirement
141
- none: false
142
120
  requirements:
143
- - - ! '>='
121
+ - - '>='
144
122
  - !ruby/object:Gem::Version
145
123
  version: '0'
146
- segments:
147
- - 0
148
- hash: 102420707118458476
149
124
  requirements: []
150
- rubyforge_project:
151
- rubygems_version: 1.8.25
152
- signing_key:
153
- specification_version: 3
154
- summary: Add the pessimistic constraint operator to all gems in your Gemfile, restricting
155
- the maximum update version.
125
+ rubyforge_project:
126
+ rubygems_version: 2.4.6
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Add the pessimistic constraint operator to all gems in your Gemfile, restricting the maximum update version.
156
130
  test_files:
157
131
  - spec/data/Gemfile.lock.example
158
132
  - spec/data/Gemfile.lock.example2
159
- - spec/declaration_spec.rb
160
- - spec/dsl_spec.rb
161
- - spec/gem_collection_spec.rb
162
133
  - spec/gem_spec.rb
163
134
  - spec/gemfile_lock_version_parser_spec.rb
135
+ - spec/gemfile_spec.rb
164
136
  - spec/integration_spec.rb
165
137
  - spec/spec_helper.rb
166
138
  - spec/version_mapper_spec.rb
@@ -1,17 +0,0 @@
1
- module Pessimize
2
- class Declaration
3
- attr_reader :name, :args
4
-
5
- def initialize(name, *args)
6
- @name = name
7
- @args = args
8
- end
9
-
10
- def to_code
11
- s = ""
12
- s << "#{name} "
13
- s << args.map(&:inspect).join(", ")
14
- s
15
- end
16
- end
17
- end
data/lib/pessimize/dsl.rb DELETED
@@ -1,39 +0,0 @@
1
- module Pessimize
2
- class DSL
3
- def initialize(collector)
4
- @collector = collector
5
- @current_groups = nil
6
- end
7
-
8
- def parse(definition)
9
- instance_eval definition, __FILE__, __LINE__
10
- end
11
-
12
- def method_missing(name, *args)
13
- collector.add_declaration(name.to_s, *args)
14
- end
15
-
16
- protected
17
- attr_reader :collector
18
- attr_accessor :current_groups
19
-
20
- def gem(*args)
21
- if current_groups
22
- current_groups.each do |group|
23
- collector.add_grouped_gem(group, *args)
24
- end
25
- else
26
- collector.add_gem(*args)
27
- end
28
- end
29
-
30
- def group(group, *others)
31
- groups = [group].flatten + others
32
- if block_given?
33
- self.current_groups = groups
34
- yield
35
- self.current_groups = nil
36
- end
37
- end
38
- end
39
- end
@@ -1,34 +0,0 @@
1
- require_relative 'gem'
2
- require_relative 'declaration'
3
-
4
- module Pessimize
5
- class GemCollection
6
- attr_reader :gems, :declarations
7
-
8
- def initialize
9
- @gems = Hash.new do |hash, missing|
10
- hash[missing] = []
11
- end
12
- @declarations = []
13
- end
14
-
15
- def add_gem(*args)
16
- add_grouped_gem(:global, *args)
17
- end
18
-
19
- def add_grouped_gem(group, *args)
20
- self.gems[group] << Gem.new(*args)
21
- end
22
-
23
- def add_declaration(name, *args)
24
- self.declarations << Declaration.new(name, *args)
25
- end
26
-
27
- def all
28
- gems.values.flatten
29
- end
30
-
31
- protected
32
- attr_writer :gems, :declarations
33
- end
34
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
- require 'pessimize/declaration'
3
-
4
- module Pessimize
5
- describe Declaration do
6
- context "creating a 'source' declaration" do
7
- subject { Declaration.new 'source', 'https://rubygems.org' }
8
- its(:to_code) { should == 'source "https://rubygems.org"' }
9
- end
10
-
11
- context "creating a 'source' declaration with a symbol value" do
12
- subject { Declaration.new 'source', :rubygems }
13
- its(:to_code) { should == 'source :rubygems' }
14
- end
15
-
16
- context "creating a 'git' declaration" do
17
- subject { Declaration.new 'git', 'git://github.com/wycats/thor.git', :tag => "v0.13.4" }
18
- its(:to_code) { should == 'git "git://github.com/wycats/thor.git", {:tag=>"v0.13.4"}' }
19
- end
20
- end
21
- end
data/spec/dsl_spec.rb DELETED
@@ -1,140 +0,0 @@
1
- require 'spec_helper'
2
- require 'pessimize/dsl'
3
-
4
- module Pessimize
5
- describe DSL do
6
- let(:collector) { double "collector" }
7
- let(:dsl) { DSL.new collector }
8
-
9
- shared_examples "a collector receiving a gem" do |definition, *args|
10
- context "the collector" do
11
- it "should receive the gem message with correct arguments" do
12
- collector.should_receive(:add_gem).with(*args)
13
- dsl.parse definition
14
- end
15
- end
16
- end
17
-
18
- context "with a string containing a gem definition" do
19
- it_behaves_like "a collector receiving a gem", "gem 'monkey'", 'monkey'
20
- end
21
-
22
- context "with a string containing a gem definition with multiple arguments" do
23
- it_behaves_like "a collector receiving a gem",
24
- "gem 'hippo', '~> 2.0.0', :require => false",
25
- 'hippo', '~> 2.0.0', :require => false
26
- end
27
-
28
- context "with a string containing multiple gem definitions" do
29
- let(:definition) { <<-EOD
30
- gem 'ponies', '>= 3.0.0'
31
- gem 'shark', :require => false
32
- EOD
33
- }
34
- context "the collector" do
35
- it "should receive the gem message with correct arguments" do
36
- collector.should_receive(:add_gem).with('ponies', '>= 3.0.0')
37
- collector.should_receive(:add_gem).with('shark', :require => false)
38
- dsl.parse definition
39
- end
40
- end
41
- end
42
-
43
- context "with a string containing a group definition" do
44
- let(:definition) { <<-EOD
45
- group :test do
46
- gem 'ponies', '>= 3.0.0'
47
- end
48
- EOD
49
- }
50
- context "the collector" do
51
- it "should receive the grouped gem message with correct arguments" do
52
- collector.should_receive(:add_grouped_gem).with(:test, 'ponies', '>= 3.0.0')
53
- dsl.parse definition
54
- end
55
- end
56
- end
57
-
58
- context "with a string containing a group definition and multiple gems" do
59
- let(:definition) { <<-EOD
60
- group :development do
61
- gem 'ponies', '>= 3.0.0'
62
- gem 'badgers', '~> 1.3.2', :require => false
63
- end
64
-
65
- gem 'ostriches', '0.0.1'
66
- EOD
67
- }
68
- context "the collector" do
69
- it "should receive the grouped gem message with correct arguments" do
70
- collector.should_receive(:add_grouped_gem).with(:development, 'ponies', '>= 3.0.0')
71
- collector.should_receive(:add_grouped_gem).with(:development, 'badgers', '~> 1.3.2', :require => false)
72
- collector.should_receive(:add_gem).with('ostriches', '0.0.1')
73
- dsl.parse definition
74
- end
75
- end
76
- end
77
-
78
- context "with a string containing a group definition with multiple arguments" do
79
- let(:definition) { <<-EOD
80
- group :development, :test do
81
- gem 'ponies', '>= 3.0.0'
82
- end
83
- EOD
84
- }
85
- context "the collector" do
86
- it "should receive the grouped gem message with correct arguments" do
87
- collector.should_receive(:add_grouped_gem).with(:development, 'ponies', '>= 3.0.0')
88
- collector.should_receive(:add_grouped_gem).with(:test, 'ponies', '>= 3.0.0')
89
- dsl.parse definition
90
- end
91
- end
92
- end
93
-
94
- context "with a string containing a group definition with an array of groups" do
95
- let(:definition) { <<-EOD
96
- group [:development, :test] do
97
- gem 'ponies', '>= 3.0.0'
98
- end
99
- EOD
100
- }
101
- context "the collector" do
102
- it "should receive the grouped gem message with correct arguments" do
103
- collector.should_receive(:add_grouped_gem).with(:development, 'ponies', '>= 3.0.0')
104
- collector.should_receive(:add_grouped_gem).with(:test, 'ponies', '>= 3.0.0')
105
- dsl.parse definition
106
- end
107
- end
108
- end
109
-
110
- context "with a string containing a source declaration and a gem" do
111
- let(:definition) { <<-EOD
112
- source "https://rubygems.org"
113
- gem 'ostriches', '0.0.1'
114
- EOD
115
- }
116
- context "the collector" do
117
- it "should receive the grouped gem message with correct arguments" do
118
- collector.should_receive(:add_declaration).with('source', 'https://rubygems.org')
119
- collector.should_receive(:add_gem).with('ostriches', '0.0.1')
120
- dsl.parse definition
121
- end
122
- end
123
- end
124
-
125
- context "with a string containing a git declaration and something unknown" do
126
- let(:definition) { <<-EOD
127
- git 'git://github.com/wycats/thor.git', :tag => 'v0.13.4'
128
- unknown 'sausages'
129
- EOD
130
- }
131
- context "the collector" do
132
- it "should receive the grouped gem message with correct arguments" do
133
- collector.should_receive(:add_declaration).with('git', 'git://github.com/wycats/thor.git', :tag => 'v0.13.4')
134
- collector.should_receive(:add_declaration).with('unknown', 'sausages')
135
- dsl.parse definition
136
- end
137
- end
138
- end
139
- end
140
- end
@@ -1,91 +0,0 @@
1
- require 'spec_helper'
2
- require 'pessimize/gem_collection'
3
-
4
- module Pessimize
5
- describe GemCollection do
6
- let(:collection) { GemCollection.new }
7
-
8
- describe "#add_gem" do
9
- context "adding a gem with a version" do
10
- before { collection.add_gem('ponies', '>= 0.3.0') }
11
- let(:gem) { collection.all.first }
12
- subject { gem }
13
-
14
- it { should be_a Gem }
15
- its(:name) { should == 'ponies' }
16
- its(:version) { should == '>= 0.3.0' }
17
-
18
- it "should be the same as the first gem in the global group" do
19
- subject.should === collection.gems[:global].first
20
- end
21
-
22
- context "after setting the version" do
23
- before { gem.version = '~> 0.3.1' }
24
-
25
- its(:version) { should == '~> 0.3.1' }
26
- end
27
- end
28
-
29
- context "adding a gem with options" do
30
- before { collection.add_gem('ponies', :git => 'git@github.com:rails/rails.git') }
31
- subject { collection.all.first }
32
-
33
- it { should be_a Gem }
34
- its(:name) { should == 'ponies' }
35
- its(:options) { should == {:git=>'git@github.com:rails/rails.git'} }
36
-
37
- it "should be the same as the first gem in the global group" do
38
- subject.should === collection.gems[:global].first
39
- end
40
- end
41
- end
42
-
43
- describe "#add_grouped_gem" do
44
- context "adding a gem in the development group" do
45
- before { collection.add_grouped_gem(:development, 'ponies', '~> 0.2.3') }
46
- subject { collection.all.first }
47
-
48
- it { should be_a Gem }
49
- its(:name) { should == 'ponies' }
50
- its(:version) { should == '~> 0.2.3' }
51
-
52
- it "should be the same as the first gem in the development group" do
53
- subject.should === collection.gems[:development].first
54
- end
55
- end
56
-
57
- context "adding a gem in the production group" do
58
- before { collection.add_grouped_gem(:production, 'badger', '~> 1.4.1') }
59
- subject { collection.all.first }
60
-
61
- it { should be_a Gem }
62
- its(:name) { should == 'badger' }
63
- its(:version) { should == '~> 1.4.1' }
64
-
65
- it "should be the same as the first gem in the production group" do
66
- subject.should === collection.gems[:production].first
67
- end
68
- end
69
- end
70
-
71
- describe "#add_declaration" do
72
- context "adding a source declaration" do
73
- before { collection.add_declaration('source', 'https://rubygems.org') }
74
- subject { collection.declarations.first }
75
-
76
- it { should be_a Declaration }
77
- its(:name) { should == 'source' }
78
- its(:to_code) { should == 'source "https://rubygems.org"' }
79
- end
80
-
81
- context "adding a git declaration" do
82
- before { collection.add_declaration('git', 'git://github.com/wycats/thor.git', :tag => 'v0.13.4') }
83
- subject { collection.declarations.first }
84
-
85
- it { should be_a Declaration }
86
- its(:name) { should == 'git' }
87
- its(:to_code) { should == 'git "git://github.com/wycats/thor.git", {:tag=>"v0.13.4"}' }
88
- end
89
- end
90
- end
91
- end