smarter_bundler 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ 1.8.7-p375
2
+ 1.9.3-p551
3
+ 1.9.2-p330
4
+ 2.2.0
5
+ 2.2.2
6
+ 2.3.0
@@ -0,0 +1,2 @@
1
+ * 1.0.0
2
+ * First producton version (used by health_check tests and my clients projects)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SmarterBundler
2
2
 
3
- Enhances bundler by adjusting Gemfile when correctable errors are found
3
+ Enhances bundler by adjusting Gemfile when correctable errors are found.
4
4
 
5
5
  It is primarily aimed at resolving ruby version conflicts where a gem now requires a later ruby version.
6
6
 
@@ -16,15 +16,20 @@ Do not install it via Gemfile, as it needs to execute even if bundle can't insta
16
16
 
17
17
  Use smarter_bundle instead of the bundle command when installing or upgrading gems.
18
18
 
19
+ If you are using it in an automated deploy, then monitor the time the deploy takes, as
20
+ the more fixes this program does, the longer it takes (since it reruns bundler to check the fixed Gemfile).
21
+ A reasonable limit would be four to ten times the time it normally takes to install.
22
+ Once you hit that limit, then check your install log and incorporate the fixes it has found into your Gemfile
23
+ source to remove the need for it to run bundler multiple times whilst it fixes the Gemfile.
24
+
19
25
  ## Notes
20
26
 
21
- The algorithm is simplistic - when an error of the form
22
- `Gem::RuntimeRequirementNotMetError: <gem_name> requires Ruby version`
23
- is found, as well as
24
- `An error occurred while installing <gem_name> (<gem_version>), and Bundler cannot continue`
25
- Then it adjusts the Gemfile to require a version of that gem lower than the one that produced the error.
27
+ If the error indicates a ruby version conflict, then it will lookup the gem on rubygems to find the earliest version with the same ruby spec
28
+ and update the Gemfile to specify a version prior to that. If the lookup of rubygems fails, then it will simply check the next earlier version.
29
+
30
+ If the error was not from a ruby version conflict, it will attempt to install the gem directly once more.
26
31
 
27
- It will attempt upto 100 times to adjust the Gemfile before giving up.
32
+ It will attempt to fix the Gemfile up to 100 times before giving up as long as each attempt is making progress.
28
33
 
29
34
  Once the Gemfile has been adjusted, commit it into your source repository so that it does not need to be used again.
30
35
 
@@ -34,6 +39,43 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
34
39
 
35
40
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
36
41
 
42
+
43
+ ### Testing in a VM
44
+
45
+ Use a vagrant virtual box for consistant results.
46
+
47
+ Install vagrant 1.9.7 or later and virtual_box or other local virtual machine providor.
48
+
49
+ Create a temp directory for throw away testing, and clone the gem into it
50
+
51
+ mkdir -p ~/tmp
52
+ cd ~/tmp
53
+ git clone https://github.com/ianheggie/smarter_bundler.git ~/tmp/smarter_bundler
54
+
55
+ The Vagrantfile includes provisioning rules to install chruby (ruby version control),
56
+ ruby-build will also be installed and run to build various rubies under /opt/rubies.
57
+
58
+ Use <tt>vagrant ssh</tt> to connect to the virtual box and run tests.
59
+
60
+ Cd to the checked out smarter_bundler directory and then run the test as follows:
61
+
62
+ cd ~/tmp/smarter_bundler
63
+
64
+ vagrant up # this will also run vagrant provision and take some time
65
+ # chruby and various ruby versions will be installed
66
+
67
+ vagrant ssh
68
+
69
+ cd /vagrant # the current directory on your host is mounted here on the virtual machine
70
+
71
+ chruby 2.2.2 # or some other ruby version (run chruby with no arguments to see the current list)
72
+
73
+ bin/test
74
+
75
+ exit # from virtual machine when finished
76
+
77
+ The test script will run the smarter_bundle command on various rails Gemfiles (selected based on the current ruby version).
78
+
37
79
  ## Contributing
38
80
 
39
81
  Bug reports and pull requests are welcome on GitHub at https://github.com/ianheggie/smarter_bundler.
@@ -0,0 +1,89 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+
6
+ # Latest Ubunutu LTS
7
+ config.vm.box = "ubuntu/xenial64"
8
+
9
+ # provision with a shell script.
10
+ config.vm.provision "shell",
11
+ path: "https://raw.githubusercontent.com/ianheggie/provision_vagrant/master/provision?cache_bust=#{Process.pid}",
12
+ args: %w{ /vagrant }
13
+
14
+ # Stop nagging as this box changes daily...
15
+ config.vm.box_check_update = true
16
+
17
+ # Do NOT download the iso file from a webserver (we don't use it)
18
+ config.vbguest.no_remote = true
19
+
20
+ # -------------------------------------------------------------
21
+ # DEFAULT HELP COMMENTS FROM VAGRANT
22
+
23
+ # All Vagrant configuration is done below (from Vagrant.configure onwards).
24
+ # The "2" in Vagrant.configure
25
+ # configures the configuration version (we support older styles for
26
+ # backwards compatibility). Please don't change it unless you know what
27
+ # you're doing.
28
+
29
+ # The most common configuration options are documented and commented below.
30
+ # For a complete reference, please see the online documentation at
31
+ # https://docs.vagrantup.com.
32
+
33
+ # Every Vagrant development environment requires a box. You can search for
34
+ # boxes at https://vagrantcloud.com/search.
35
+
36
+ # Disable automatic box update checking. If you disable this, then
37
+ # boxes will only be checked for updates when the user runs
38
+ # `vagrant box outdated`. This is not recommended.
39
+ # config.vm.box_check_update = false
40
+
41
+ # Create a forwarded port mapping which allows access to a specific port
42
+ # within the machine from a port on the host machine. In the example below,
43
+ # accessing "localhost:8080" will access port 80 on the guest machine.
44
+ # NOTE: This will enable public access to the opened port
45
+ # config.vm.network "forwarded_port", guest: 80, host: 8080
46
+
47
+ # Create a forwarded port mapping which allows access to a specific port
48
+ # within the machine from a port on the host machine and only allow access
49
+ # via 127.0.0.1 to disable public access
50
+ # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
51
+
52
+ # Create a private network, which allows host-only access to the machine
53
+ # using a specific IP.
54
+ # config.vm.network "private_network", ip: "192.168.33.10"
55
+
56
+ # Create a public network, which generally matched to bridged network.
57
+ # Bridged networks make the machine appear as another physical device on
58
+ # your network.
59
+ # config.vm.network "public_network"
60
+
61
+ # Share an additional folder to the guest VM. The first argument is
62
+ # the path on the host to the actual folder. The second argument is
63
+ # the path on the guest to mount the folder. And the optional third
64
+ # argument is a set of non-required options.
65
+ # config.vm.synced_folder "../data", "/vagrant_data"
66
+
67
+ # Provider-specific configuration so you can fine-tune various
68
+ # backing providers for Vagrant. These expose provider-specific options.
69
+ # Example for VirtualBox:
70
+ #
71
+ # config.vm.provider "virtualbox" do |vb|
72
+ # # Display the VirtualBox GUI when booting the machine
73
+ # vb.gui = true
74
+ #
75
+ # # Customize the amount of memory on the VM:
76
+ # vb.memory = "1024"
77
+ # end
78
+ #
79
+ # View the documentation for the provider you are using for more
80
+ # information on available options.
81
+
82
+ # Enable provisioning with a shell script. Additional provisioners such as
83
+ # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
84
+ # documentation for more information about their specific syntax and use.
85
+ # config.vm.provision "shell", inline: <<-SHELL
86
+ # apt-get update
87
+ # apt-get install -y apache2
88
+ # SHELL
89
+ end
data/bin/test CHANGED
@@ -48,6 +48,9 @@ if [ $# -gt 0 ]; then
48
48
  dirs="$*"
49
49
  fi
50
50
  unset BUNDLE_GEMFILE
51
+
52
+ which bundle || ( gem install bundler ; bundle )
53
+
51
54
  for d in $dirs
52
55
  do
53
56
  if [ -s "test/$d/Gemfile.default" ] ; then
@@ -8,7 +8,7 @@ module SmarterBundler
8
8
  class Bundle
9
9
  include SmarterBundler::Shell
10
10
 
11
- KNOWN_ISSUES_192 = {
11
+ KNOWN_ISSUES_187_192 = {
12
12
  'unicorn' => '5.0',
13
13
  'nokogiri' => '1.6.0',
14
14
  'jbuilder' => '2.0.0',
@@ -16,9 +16,20 @@ module SmarterBundler
16
16
  'factory_bot' => '3.0',
17
17
  }
18
18
 
19
+ KNOWN_ISSUES_193_221 = {
20
+ }
21
+
22
+ KNOWN_ISSUES_222_22x = {
23
+ 'listen' => '3.1.2',
24
+ 'acts-as-taggable-on' => '5.0.0',
25
+ 'guard-rails' => '0.7.3',
26
+ 'jasmine' => '3.0.0',
27
+ 'ruby_dep' => '1.4.0',
28
+ }
29
+
19
30
 
20
31
  def run(bundle_args)
21
- puts "Smarter Bundler will recursively install your gems and output the successful bundler output. This may take a while."
32
+ puts 'Smarter Bundler will recursively install your gems and output the successful bundler output. This may take a while.'
22
33
  count = 0
23
34
  gemfile = SmarterBundler::Gemfile.new
24
35
  previous_failure = []
@@ -28,13 +39,13 @@ module SmarterBundler
28
39
  failed_gem_and_version = parse_output(result)
29
40
  if failed_gem_and_version
30
41
  if previous_failure == failed_gem_and_version
31
- puts "Aborting: Stuck trying to install the same gem and version!"
42
+ puts 'Aborting: Stuck trying to install the same gem and version!'
32
43
  exit 1
33
44
  end
34
45
  previous_failure = failed_gem_and_version
35
46
  gem, version = *failed_gem_and_version
36
47
  if !ruby_version_clash(result) && install_failed_gem(gem, version)
37
- puts "Retrying seems to have fixed the problem"
48
+ puts 'Retrying seems to have fixed the problem'
38
49
  elsif gemfile.restrict_gem_version(gem, known_issues(gem))
39
50
  gemfile.save
40
51
  count += 1
@@ -45,7 +56,7 @@ module SmarterBundler
45
56
  gemfile.save
46
57
  count += 1
47
58
  else
48
- puts "Aborting: Unable to fix installation of gems"
59
+ puts 'Aborting: Unable to fix installation of gems'
49
60
  exit 2
50
61
  end
51
62
  else
@@ -69,8 +80,12 @@ module SmarterBundler
69
80
  end
70
81
 
71
82
  def known_issues(gem)
72
- if RUBY_VERSION < '1.9.3'
73
- KNOWN_ISSUES_192[gem]
83
+ if RUBY_VERSION <= '1.9.2'
84
+ KNOWN_ISSUES_187_192[gem]
85
+ elsif RUBY_VERSION <= '2.2.1'
86
+ KNOWN_ISSUES_193_221[gem]
87
+ elsif RUBY_VERSION <= '2.3'
88
+ KNOWN_ISSUES_222_22x[gem]
74
89
  else
75
90
  nil
76
91
  end
@@ -113,9 +128,9 @@ module SmarterBundler
113
128
  end
114
129
  # puts "Trimmed prerelease list: #{list.inspect}"
115
130
  list
116
- # rescue RuntimeError => ex
117
- # puts "Ignoring exception: #{ex} - we will have to work it out the slow way"
118
- # []
131
+ rescue RuntimeError => ex
132
+ puts "Ignoring exception: #{ex} - we will have to work it out the slow way"
133
+ []
119
134
  end
120
135
  list = @rubygems_cache[gem]
121
136
  if list.size == 0
@@ -6,7 +6,7 @@ module SmarterBundler
6
6
 
7
7
  def initialize
8
8
  @filename = ENV['BUNDLE_GEMFILE'] || 'Gemfile'
9
- @contents = [ ]
9
+ @contents = []
10
10
  File.open(@filename, 'r').each do |line|
11
11
  line.chomp
12
12
  @contents << line
@@ -16,7 +16,7 @@ module SmarterBundler
16
16
 
17
17
  def restrict_gem_version gem, version_limit
18
18
  return false unless version_limit.to_s =~ /\d\.\d/
19
- if @contents.select{|line| line =~ /^\s*gem\s+['"]#{gem}['"]/}.empty?
19
+ if @contents.select { |line| line =~ /^\s*gem\s+['"]#{gem}['"]/ }.empty?
20
20
  @contents << "gem '#{gem}', '>=0'"
21
21
  end
22
22
  adjusted = false
@@ -24,17 +24,17 @@ module SmarterBundler
24
24
  if line =~ /^(\s*gem\s+['"]#{gem}['"])(.*)$/
25
25
  gem_and_name = $1
26
26
  rest_of_line = $2
27
- versions = [ ]
27
+ versions = []
28
28
  if rest_of_line =~ /^\s*,\s*['"]([^'"]*)['"](.*)/
29
- versions = [ $1 ]
29
+ versions = [$1]
30
30
  rest_of_line = $2
31
31
  elsif rest_of_line =~ /^\s*,\s*\[([^\]]*)\](.*)/
32
32
  rest_of_line = $2
33
- versions = $1.split(',').map{|s| s.sub(/^[\s'"]*/, '').sub(/[\s'"]*$/, '')}
33
+ versions = $1.split(',').map { |s| s.sub(/^[\s'"]*/, '').sub(/[\s'"]*$/, '') }
34
34
  end
35
35
  #puts "Found #{gem_and_name} in Gemfile with version spec: #{versions.inspect} and other args: #{rest_of_line}"
36
36
  new_versions = versions.dup
37
- new_versions.delete_if{|s| s =~ /</}
37
+ new_versions.delete_if { |s| s =~ /</ }
38
38
  new_versions << "< #{version_limit}"
39
39
  #puts " Replacing with new version spec: #{new_versions.inspect}"
40
40
  if new_versions != versions
@@ -62,7 +62,7 @@ module SmarterBundler
62
62
  end
63
63
  FileUtils.move "#{@filename}.new", @filename, :force => true
64
64
  @changed = false
65
- puts 'Currently restricted:', *(@contents.select{|line| line =~ /Added by SmartBundler/})
65
+ puts 'Currently restricted:', *(@contents.select { |line| line =~ /Added by SmarterBundler/ })
66
66
  end
67
67
  end
68
68
 
@@ -1,8 +1,8 @@
1
1
  module SmarterBundler
2
2
  module Shell
3
3
  def shell(command)
4
- puts '',"+ #{command}"
5
- output = [ ]
4
+ puts '', "+ #{command}"
5
+ output = []
6
6
  IO.popen("#{command} 2>&1") do |io|
7
7
  while line = io.gets
8
8
  puts line.chomp
@@ -13,7 +13,7 @@ module SmarterBundler
13
13
  puts "Command returned status: #{$?.to_i} (#{$?.success? ? 'success' : 'fail'})"
14
14
  Struct.new(:status, :output).new($?, output)
15
15
  end
16
-
16
+
17
17
  def shell?(command)
18
18
  result = shell(command)
19
19
  result.status.success?
@@ -1,3 +1,3 @@
1
1
  module SmarterBundler
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
metadata CHANGED
@@ -1,79 +1,87 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: smarter_bundler
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 3
10
+ version: 0.1.3
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Ian Heggie
9
14
  autorequire:
10
15
  bindir: exe
11
16
  cert_chain: []
12
- date: 2018-03-12 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
+
18
+ date: 2018-03-14 00:00:00 +11:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ version_requirements: &id001 !ruby/object:Gem::Requirement
17
23
  none: false
18
- requirements:
24
+ requirements:
19
25
  - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '1.16'
22
- type: :development
26
+ - !ruby/object:Gem::Version
27
+ hash: 47
28
+ segments:
29
+ - 1
30
+ - 16
31
+ version: "1.16"
23
32
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
33
+ type: :development
34
+ requirement: *id001
35
+ name: bundler
36
+ - !ruby/object:Gem::Dependency
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
25
38
  none: false
26
- requirements:
39
+ requirements:
27
40
  - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '1.16'
30
- - !ruby/object:Gem::Dependency
41
+ - !ruby/object:Gem::Version
42
+ hash: 35
43
+ segments:
44
+ - 10
45
+ - 0
46
+ version: "10.0"
47
+ prerelease: false
48
+ type: :development
49
+ requirement: *id002
31
50
  name: rake
32
- requirement: !ruby/object:Gem::Requirement
51
+ - !ruby/object:Gem::Dependency
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
33
53
  none: false
34
- requirements:
54
+ requirements:
35
55
  - - ~>
36
- - !ruby/object:Gem::Version
37
- version: '10.0'
38
- type: :development
56
+ - !ruby/object:Gem::Version
57
+ hash: 31
58
+ segments:
59
+ - 5
60
+ - 0
61
+ version: "5.0"
39
62
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: '10.0'
46
- - !ruby/object:Gem::Dependency
47
- name: minitest
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: '5.0'
54
63
  type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '5.0'
62
- description: The smarter_bundle retries installing gems, and if that fails it tries
63
- installing an earlier version by adjusting the Gemfile
64
- email:
64
+ requirement: *id003
65
+ name: minitest
66
+ description: The smarter_bundle retries installing gems, and if that fails it tries installing an earlier version by adjusting the Gemfile
67
+ email:
65
68
  - ian@heggie.biz
66
- executables:
69
+ executables:
67
70
  - smarter_bundle
68
71
  extensions: []
72
+
69
73
  extra_rdoc_files: []
70
- files:
74
+
75
+ files:
71
76
  - .gitignore
77
+ - .ruby-versions
72
78
  - .travis.yml
79
+ - CHANGELOG
73
80
  - Gemfile
74
81
  - LICENSE.txt
75
82
  - README.md
76
83
  - Rakefile
84
+ - Vagrantfile
77
85
  - bin/console
78
86
  - bin/setup
79
87
  - bin/test
@@ -84,35 +92,39 @@ files:
84
92
  - lib/smarter_bundler/shell.rb
85
93
  - lib/smarter_bundler/version.rb
86
94
  - smarter_bundler.gemspec
95
+ has_rdoc: true
87
96
  homepage: https://github.com/ianheggie/smarter_bundler
88
- licenses:
97
+ licenses:
89
98
  - MIT
90
99
  post_install_message:
91
100
  rdoc_options: []
92
- require_paths:
101
+
102
+ require_paths:
93
103
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
104
+ required_ruby_version: !ruby/object:Gem::Requirement
95
105
  none: false
96
- requirements:
97
- - - ! '>='
98
- - !ruby/object:Gem::Version
99
- version: '0'
100
- segments:
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
101
111
  - 0
102
- hash: 2247782191630905192
103
- required_rubygems_version: !ruby/object:Gem::Requirement
112
+ version: "0"
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
114
  none: false
105
- requirements:
106
- - - ! '>='
107
- - !ruby/object:Gem::Version
108
- version: '0'
109
- segments:
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ hash: 3
119
+ segments:
110
120
  - 0
111
- hash: 2247782191630905192
121
+ version: "0"
112
122
  requirements: []
123
+
113
124
  rubyforge_project:
114
- rubygems_version: 1.8.23.2
125
+ rubygems_version: 1.6.2
115
126
  signing_key:
116
127
  specification_version: 3
117
128
  summary: Enhances bundler by adjusting Gemfile when correctable errors are found
118
129
  test_files: []
130
+