drg 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64ab93e66f0e85ab52aad6415ff9742dc974eff3
4
- data.tar.gz: cd44e409518042394da5dd01f18833cb51b37c2b
3
+ metadata.gz: 79972e1a98ed795a5b79bd82df3776f21503cb0a
4
+ data.tar.gz: 6fd465489ef30e2dde409df44d8d7b8d29065e94
5
5
  SHA512:
6
- metadata.gz: 34adbd98f8df9b92863b0b4349895e9241853070c24f99c333f309cbea81a3fd130b49712f73c513073aa521ac59c9f1cca02e4ae60a14bf37cafe215498bf27
7
- data.tar.gz: bd191ee0cba818a2be8e1074bac1e512bed7a42b266542953f66d83e9b5f88aeab9b1d7b5681a9e649fe5574d7ef35cb761c59b8b58ef48f51bb0729339aa526
6
+ metadata.gz: e600c88738d8de1a28b89e4ba88b6cfb9329b3caa1363ed7901dc36eaef19f1682c8f4f05abfdef93a743ac43eb8b7cd3a63237bbde8070d98413aa1fa723a35
7
+ data.tar.gz: 0b50c62122cd9f959f5dc0fd0589feffeea2e9c552c98d927a25d9a8b718a5a54dbd96a6ab0a8499715e5517ad5e00e3102b26616f10787851215875fc082b0b
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # DRG
2
2
 
3
- A Ruby utility to help automate common tasks! Currently includes stuff like enhanced dependency management using Bundler and RSpec scaffolding.
3
+ A Ruby utility to help automate common tasks! Currently includes enhanced dependency management using Bundler. You
4
+ can pin Gem versions to the current or the next available level (major, minor, or patch). Can also automatically
5
+ update your gems to the latest available version.
6
+
7
+ ## Requirements
8
+
9
+ * Bundler 1.10+
4
10
 
5
11
  ## Installation
6
12
 
@@ -15,23 +21,28 @@ gem 'drg'
15
21
  ```bash
16
22
  rake drg:update
17
23
  rake drg:pin
18
- rake drg:pin:minor
19
24
  rake drg:pin:major
25
+ rake drg:pin:minor
26
+ rake drg:pin:patch
27
+ rake drg:pin:latest_patch
28
+ rake drg:pin:latest_minor
20
29
  rake drg:unpin
21
30
  ```
22
31
 
23
32
  ### drg:update
24
33
 
25
- DRG can update your outdated gems, one-by-one, to the latest version. It'll update the gem and then run your tests.
26
- If your tests pass, then the new version will be written to your Gemfile (similar to Gemnasium).
34
+ DRG can update your outdated gems! It does this by checking for outdated gems, and then updating them one at time to the latest
35
+ version. It then run your tests (with `rake`) and if your tests pass, the new version will be written to your Gemfile!
27
36
 
28
37
  ```bash
29
38
  rake drg:update
30
39
  ```
31
40
 
32
- ### pin
41
+ Easy!
42
+
43
+ ### drg:pin
33
44
 
34
- DRG really wants to help you manage your project's gems. But DRG doesn't want to replace Bundler. Instead we want to build on
45
+ DRG really wants to help you manage your project's gems. But DRG doesn't want to replace Bundler. Instead, we want to build on
35
46
  it. Pinning ignores gems that are fetched from somewhere other than rubygems. For example, gems listed with `:git`, `:github`,
36
47
  or `:path` will be ignored. You can "pin" all your versions to the current version listed in the Gemfile.lock:
37
48
 
@@ -39,13 +50,13 @@ or `:path` will be ignored. You can "pin" all your versions to the current versi
39
50
  rake drg:pin
40
51
  ```
41
52
 
42
- Which will change gems list in your Gemfile to their full version. So if you have a gemfile that looks like:
53
+ Will update a Gemfile to their full version:
43
54
 
44
55
  ```ruby
45
56
  gem 'rails'
46
57
  gem 'byebug', require: false
47
58
  gem 'therubyracer', '~> 0.12', platforms: :ruby
48
- gem 'drg'
59
+ gem 'drg' # need this
49
60
  ```
50
61
 
51
62
  it'll get changed to
@@ -54,18 +65,18 @@ it'll get changed to
54
65
  gem 'rails', '4.2.3'
55
66
  gem 'byebug', '5.0.0', require: false
56
67
  gem 'therubyracer', '0.12.2', platforms: :ruby
57
- gem 'drg', '0.4.1'
68
+ gem 'drg', '0.4.1' # need this
58
69
  ```
59
70
 
60
- ### pin:minor
71
+ ### drg:pin:minor
61
72
 
62
- Although, you may want to pin gems with their _minor_ version (which allows updating patches). Run:
73
+ Want to pin gems at their _minor_ version?
63
74
 
64
75
  ```bash
65
76
  rake drg:pin:minor
66
77
  ```
67
78
 
68
- Which will update your Gemfile from
79
+ Will update a Gemfile
69
80
 
70
81
  ```ruby
71
82
  gem 'rails', '4.2.3'
@@ -77,9 +88,29 @@ to
77
88
  gem 'rails', '~> 4.2'
78
89
  ```
79
90
 
91
+ ### drg:pin:patch
92
+
93
+ Want to pin gems at their _patch_ version?
94
+
95
+ ```bash
96
+ rake drg:pin:minor
97
+ ```
98
+
99
+ Will update a Gemfile
100
+
101
+ ```ruby
102
+ gem 'rails', '4.2.3'
103
+ ```
104
+
105
+ to
106
+
107
+ ```ruby
108
+ gem 'rails', '~> 4.2.3'
109
+ ```
110
+
80
111
  This can be combined with `bundle update` to quickly update all gems to the latest patch or minor level.
81
112
 
82
- ### pin:major
113
+ ### drg:pin:major
83
114
 
84
115
  There is also a
85
116
 
data/drg.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
  # spec.add_dependency 'ruby2ruby', '>= 2.2.0', '< 3.0.0'
21
21
  spec.add_dependency 'bundler', '~> 1.10'
22
22
  spec.add_dependency 'duck_puncher', '1.0.0'
23
+ spec.add_dependency 'highline', '~> 1.7'
23
24
 
24
25
  spec.add_development_dependency 'rake', '~> 10.0'
25
26
  spec.add_development_dependency 'rspec', '>= 3.2', '< 4'
@@ -12,8 +12,8 @@ module DRG
12
12
  # @param [GemfileLine] gem
13
13
  # @param [String] version to update the gem line with
14
14
  def update(gem, version)
15
+ saved_lines << lines.clone!
15
16
  lines[gem] = gem.update version
16
- write
17
17
  end
18
18
 
19
19
  def remove_version(gem)
@@ -0,0 +1,11 @@
1
+ module DRG
2
+ module Tasks
3
+ module Log
4
+ module_function
5
+
6
+ def log(msg = nil)
7
+ say %Q( * <%= color('#{msg}', :green) %>)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,9 +1,12 @@
1
1
  module DRG
2
2
  module Tasks
3
3
  class Pinner
4
+ include Log
5
+
4
6
  attr_reader :gemfile, :type
5
7
 
6
- def initialize(type = :patch)
8
+ # @param [Symbol] type of pin to perform. Available options are [:full, :major, :minor, :patch]
9
+ def initialize(type = :full)
7
10
  @type = type
8
11
  @gemfile = Gemfile.new
9
12
  end
@@ -14,6 +17,7 @@ module DRG
14
17
  gem = gemfile.find_by_name spec.name
15
18
  next unless gem
16
19
  gemfile.update gem, public_send(type, spec.version.to_s)
20
+ gemfile.write
17
21
  end
18
22
  log %Q(Done)
19
23
  end
@@ -27,17 +31,12 @@ module DRG
27
31
  log %Q(Done)
28
32
  end
29
33
 
30
- def patch(version)
31
- version
32
- end
34
+ #
35
+ # Types
36
+ #
33
37
 
34
- def minor(version)
35
- v = version[/(\d+\.\d+)/, 1]
36
- if v == '0.0'
37
- version
38
- else
39
- "~> #{v}"
40
- end
38
+ def full(version)
39
+ version
41
40
  end
42
41
 
43
42
  def major(version)
@@ -49,10 +48,17 @@ module DRG
49
48
  end
50
49
  end
51
50
 
52
- private
51
+ def minor(version)
52
+ v = version[/(\d+\.\d+)/, 1]
53
+ if v == '0.0'
54
+ version
55
+ else
56
+ "~> #{v}"
57
+ end
58
+ end
53
59
 
54
- def log(msg = nil)
55
- puts %Q( * #{msg})
60
+ def patch(version)
61
+ "~> #{version}"
56
62
  end
57
63
  end
58
64
  end
@@ -0,0 +1,107 @@
1
+ module DRG
2
+ module Tasks
3
+ class ProgessivePinner
4
+ include Log
5
+
6
+ attr_reader :gemfile, :type, :updated_gems
7
+ attr_writer :versions
8
+
9
+ # @param [Symbol] type of pin to perform. Available options are [:major, :minor, :patch]
10
+ def initialize(type = :patch)
11
+ @type = type
12
+ @gemfile = Gemfile.new
13
+ @versions = {}
14
+ @updated_gems = Set.new
15
+ end
16
+
17
+ def perform(gem_name = nil)
18
+ if gem_name
19
+ update ::Bundler.locked_gems.specs.find { |spec| spec.name == gem_name }
20
+ else
21
+ update_all
22
+ end
23
+ gemfile.write if gemfile.saved_lines.any?
24
+ log %Q(Done.#{' You may want run `bundle update`' if updated_gems.any?})
25
+ end
26
+
27
+ def update_all
28
+ log %Q(No gem specified)
29
+ Updater.new.perform method(:update_handler)
30
+ end
31
+
32
+ def update_handler(gem)
33
+ update ::Bundler.locked_gems.specs.find { |spec| spec.name == gem.name }
34
+ end
35
+
36
+ def update(spec)
37
+ gem = gemfile.find_by_name spec.name
38
+ if gem
39
+ log %Q[Searching for latest #{type} version of "#{spec.name}" (currently #{spec.version.to_s}) ...]
40
+ latest_version = public_send("latest_#{type}_version", spec.name, spec.version)
41
+ if latest_version
42
+ if ask(" * Do you want to update to version #{latest_version} (y/n)?").to_s.downcase == 'y'
43
+ gemfile.update gem, latest_version
44
+ updated_gems << gem.name
45
+ end
46
+ else
47
+ log %Q(No newer #{type} versions found)
48
+ end
49
+ end
50
+ end
51
+
52
+ # @param [String] name of the gem
53
+ # @param [String] current_version of the gem
54
+ def latest_minor_version(name, current_version)
55
+ new_versions(name, current_version).select { |version|
56
+ segments = version.scan(/\d+/)
57
+ major_version = segments[0].to_i
58
+ minor_version = segments[1].to_i
59
+ minor_version > current_version.segments[1] && major_version == current_version.segments[0]
60
+ }.first
61
+ end
62
+
63
+ # @param [String] name of the gem
64
+ # @param [String] current_version of the gem
65
+ def latest_patch_version(name, current_version)
66
+ new_versions(name, current_version).select { |version|
67
+ segments = version.scan(/\d+/)
68
+ patch_version = segments[-1].to_i
69
+ minor_version = segments[1].to_i
70
+ patch_version > current_version.segments[-1] && minor_version == current_version.segments[1]
71
+ }.first
72
+ end
73
+
74
+ # @param [String] name of the gem
75
+ # @param [String] current_version of the gem
76
+ def new_versions(name, current_version)
77
+ versions(name).select { |version| higher?(version.scan(/\d+/), current_version.segments) }
78
+ end
79
+
80
+ # @param [String] name of the gem
81
+ # @return [Array] a list of available versions (e.g. ['1.2.0', '1.1.0'])
82
+ def versions(name)
83
+ @versions[name] ||= `gem query -radn ^#{name}$`.scan(/([\d.]+),/).flatten.uniq
84
+ end
85
+
86
+ def higher?(list, other_list)
87
+ return true if list[0].to_i > other_list[0].to_i
88
+ return true if list[1].to_i > other_list[1].to_i
89
+ return true if list[2].to_i > other_list[2].to_i
90
+ false
91
+ end
92
+
93
+ # @todo delete if not used
94
+ #
95
+ # @param [String] name of the gem
96
+ # @param [String] current_version of the gem
97
+ # def next_patch_version(name, current_version)
98
+ # new_versions(name, current_version).select { |version|
99
+ # puts segments = version.scan(/\d+/)
100
+ # patch_version = segments.last.to_i
101
+ # minor_version = segments[-2].to_i
102
+ # patch_version > current_version.segments[-1] && minor_version <= current_version.segments[-2]
103
+ # }.last
104
+ # end
105
+ end
106
+ end
107
+ end
@@ -1,6 +1,8 @@
1
1
  module DRG
2
2
  module Tasks
3
3
  class Updater
4
+ include Log
5
+
4
6
  attr_reader :gemfile, :failures, :bundler
5
7
 
6
8
  def initialize
@@ -12,10 +14,9 @@ module DRG
12
14
 
13
15
  # Updates the projects outdated gems listed in the Gemfile
14
16
  #
15
- # @todo Incrementally update the gem using +versions+
16
17
  # @todo Cleanup old gems when finished
17
18
  # @note `bundle outdated` returns lines that look like 'slop (newest 4.2.0, installed 3.6.0) in group "default"'
18
- def perform
19
+ def perform(handler = method(:try_update))
19
20
  log 'Searching for outdated gems ....'
20
21
  outdated = `bundle outdated`.scan(/\s\*\s(.+)\s/).flatten
21
22
  gems = outdated.map do |item|
@@ -28,7 +29,7 @@ module DRG
28
29
  gem
29
30
  end.compact
30
31
  if gems.any?
31
- gems.each &method(:try_update)
32
+ gems.each &handler
32
33
  else
33
34
  log 'All gems up to date!'
34
35
  end
@@ -44,6 +45,7 @@ module DRG
44
45
  if system('rake')
45
46
  log(%Q[Tests passed! Updating Gemfile entry for "#{gem.name}" to #{gem.latest_version}])
46
47
  gemfile.update(gem.entry, gem.latest_version)
48
+ gemfile.write
47
49
  else
48
50
  failures << gem.name
49
51
  end
@@ -51,34 +53,14 @@ module DRG
51
53
  fail StandardError, %Q[Failed to update "#{gem.name}"]
52
54
  end
53
55
  rescue Bundler::GemNotFound, Bundler::InstallError, Bundler::VersionConflict => e
56
+ # @todo retry it later
54
57
  log %Q[Failed to find a compatible of "#{gem.name}" (#{gem.latest_version}): #{e.class} #{e.message}]
55
58
  gemfile.rollback
56
59
  failures << gem.name
57
- # @todo retry it later
58
60
  rescue => e
59
61
  puts "#{e.class}: #{e.message} #{e.backtrace}"
60
62
  gemfile.rollback
61
63
  end
62
-
63
- # @note not used
64
- # @param [String] name of the gem
65
- # @param [String] current_version of the gem
66
- def new_versions(name, current_version)
67
- versions(name).select { |version| version > current_version }
68
- end
69
-
70
- # @note not used
71
- # @param [String] name of the gem
72
- # @return [Array] a list of available versions (e.g. ['1.2.0', '1.1.0'])
73
- def versions(name)
74
- @versions[name] ||= `gem query -radn ^#{name}$`.scan(/([\d.]+),/).flatten
75
- end
76
-
77
- private
78
-
79
- def log(msg = nil)
80
- puts %Q( * #{msg})
81
- end
82
64
  end
83
65
  end
84
66
  end
data/lib/drg/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DRG
2
- VERSION = '0.5.1'.freeze
2
+ VERSION = '0.6.0'.freeze
3
3
  end
data/lib/drg.rb CHANGED
@@ -4,21 +4,24 @@ require 'bundler'
4
4
  require 'bundler/cli'
5
5
  require 'drg/version'
6
6
  require 'duck_puncher'
7
+ require 'highline/import'
7
8
 
8
9
  # defines #clone!
9
10
  DuckPuncher.load! :Object
10
11
 
11
12
  module DRG
12
- autoload :FileReader, 'drg/file_reader'
13
- autoload :Scanner, 'drg/scanner'
14
- autoload :Judge, 'drg/judge'
15
- autoload :FileContext, 'drg/file_context'
13
+ # autoload :FileReader, 'drg/file_reader'
14
+ # autoload :Scanner, 'drg/scanner'
15
+ # autoload :Judge, 'drg/judge'
16
+ # autoload :FileContext, 'drg/file_context'
16
17
 
17
18
  module Tasks
18
19
  autoload :Updater, 'drg/tasks/updater'
19
20
  autoload :Pinner, 'drg/tasks/pinner'
21
+ autoload :ProgessivePinner, 'drg/tasks/progressive_pinner'
20
22
  autoload :Gemfile, 'drg/tasks/gemfile'
21
23
  autoload :GemfileLine, 'drg/tasks/gemfile_line'
24
+ autoload :Log, 'drg/tasks/log'
22
25
  end
23
26
  end
24
27
 
data/lib/tasks/drg.rake CHANGED
@@ -21,11 +21,25 @@ namespace :drg do
21
21
  task :major do
22
22
  DRG::Tasks::Pinner.new(:major).perform
23
23
  end
24
+
25
+ desc 'Adds the fuzzy match operator to the patch version of your gems (e.g. rails, "~> 4.2.3")'
26
+ task :patch do
27
+ DRG::Tasks::Pinner.new(:patch).perform
28
+ end
29
+
30
+ desc 'Pins all gems [or the requested gem] to the latest available patch version'
31
+ task :latest_minor, [:gem_name] do |_, options|
32
+ DRG::Tasks::ProgessivePinner.new(:minor).perform(options[:gem_name])
33
+ end
34
+
35
+ desc 'Pins all gems [or the requested gem] to the latest available minor version'
36
+ task :latest_patch, [:gem_name] do |_, options|
37
+ DRG::Tasks::ProgessivePinner.new(:patch).perform(options[:gem_name])
38
+ end
24
39
  end
25
40
 
26
41
  desc 'Updates your gems in the Gemfile to the latest compatible version'
27
42
  task :update do
28
- # sh 'cd /Users/ryanbuckley/apps/dontspreadit && which ruby'
29
43
  DRG::Tasks::Updater.new.perform
30
44
  end
31
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: highline
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -97,7 +111,9 @@ files:
97
111
  - lib/drg/scanner.rb
98
112
  - lib/drg/tasks/gemfile.rb
99
113
  - lib/drg/tasks/gemfile_line.rb
114
+ - lib/drg/tasks/log.rb
100
115
  - lib/drg/tasks/pinner.rb
116
+ - lib/drg/tasks/progressive_pinner.rb
101
117
  - lib/drg/tasks/updater.rb
102
118
  - lib/drg/version.rb
103
119
  - lib/tasks/drg.rake