pessimize 0.1.0 → 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 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