keep_up 0.4.0 → 0.5.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: 139b7cb090fcb84c95e481c0c53916a89bc0a93e
4
- data.tar.gz: d6f41235120d1dcb492039497d151bb27ad48771
3
+ metadata.gz: 8d697f00632839f4e229ca8ce80dee80b7be5f2f
4
+ data.tar.gz: 592795209fe85c984634f464a5f1a0b90cecebef
5
5
  SHA512:
6
- metadata.gz: fd5cd0d7f42b6687ea47d5cf227483128f761fd6a2bc6b14062f83e3e7829f4f216a5b2ff5b02e09227cb26705953a04be7b654b417597e426b76837e6e93214
7
- data.tar.gz: 38f762f73f2ff74b9dd541704ca40574f17856e81bd9ab954bc278f2c079f26b41063c60589c348cc5f40a783c75f8bdafb1e5f01455e4bad5e5a7fcc3713a3b
6
+ metadata.gz: 13810077f15f56bae0f06ceb5857be28378df8ff8b2aea00091ecef593f2d4733ebe8f413101407b438c8308aff7a8429d8d9732b4d969e2bf7053471d33809e
7
+ data.tar.gz: b47bf2945e6ec10338e6c715c9b2f8bfefc71273f57139c00520b22166b5a743ea51189afbf1461e1ba106cd3e15b0cdaf25f4ed62a13d67971c2fef286b1b82
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 / 2016-12-16
4
+
5
+ * Match existing specificity of versions when updating them
6
+ * Stop eating people's homework by doing some sanity checks at the start
7
+
3
8
  ## 0.4.0 / 2016-12-11
4
9
 
5
10
  * Allow local operation
data/README.md CHANGED
@@ -4,8 +4,6 @@ Automatically update your dependencies.
4
4
 
5
5
  ## Installation
6
6
 
7
- THIS GEM IS HIGHLY EXPERIMENTAL AND WILL EAT YOUR HOMEWORK!
8
-
9
7
  KeepUp is not intended to be part of your application's bundle. You should
10
8
  install it yourself as:
11
9
 
@@ -15,16 +13,16 @@ install it yourself as:
15
13
 
16
14
  KeepUp only works with git at the moment!
17
15
 
18
- First, make sure your checkout directory is clean. KeepUp will currently not
19
- check this for you and may throw away your changes!
20
-
21
- Next, it's probably nice to start a new branch.
16
+ Before running KeepUp, it's probably nice to start a new branch. Also, KeepUp
17
+ will refuse to run if your checkout directory is not clean, or if your
18
+ Gemfile.lock is not up-to-date.
22
19
 
23
20
  Run keep_up in your project directory:
24
21
 
25
22
  $ keep_up
26
23
 
27
- KeepUp will do its thing.
24
+ KeepUp will proceed to update your dependencies one by one, committing each
25
+ change if updating the bundle is succesful.
28
26
 
29
27
  Next, run `bundle install` and run your tests or whatever. Since KeepUp
30
28
  generates a separate commit for each succesful update, you can use `git bisect`
@@ -40,7 +38,6 @@ to find any updates that cause problems and remove or fix them.
40
38
 
41
39
  ## Planned Features
42
40
 
43
- * Check the starting situation (clean checkout, Gemfile.lock up to date)
44
41
  * Allow some check for each change. My feeling at the moment is that for local,
45
42
  supervised use it's best to test everything at once at the end and then go
46
43
  back and fix things. However, for automation it may be helpful to fully check
data/Rakefile CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
  require 'cucumber/rake/task'
4
+ require 'rubocop/rake_task'
4
5
 
5
6
  RSpec::Core::RakeTask.new(:spec)
6
7
  Cucumber::Rake::Task.new(:features)
8
+ RuboCop::RakeTask.new
7
9
 
8
- task default: [:spec, :features]
10
+ task default: [:spec, :features, :rubocop]
data/bin/keep_up CHANGED
@@ -25,5 +25,6 @@ end.parse!
25
25
  begin
26
26
  KeepUp::Application.new(options).run
27
27
  rescue KeepUp::BailOut => e
28
- puts "Failure: #{e.message}"
28
+ warn e.message
29
+ exit 1
29
30
  end
data/keep_up.gemspec CHANGED
@@ -25,9 +25,9 @@ Gem::Specification.new do |spec|
25
25
 
26
26
  spec.add_runtime_dependency 'bundler', '~> 1.13'
27
27
 
28
- spec.add_development_dependency 'rake', '~> 11.0'
28
+ spec.add_development_dependency 'rake', '~> 12.0'
29
29
  spec.add_development_dependency 'rspec', '~> 3.0'
30
30
  spec.add_development_dependency 'aruba', '~> 0.14.2'
31
- spec.add_development_dependency 'rubocop', '~> 0.45.0'
31
+ spec.add_development_dependency 'rubocop', '~> 0.46.0'
32
32
  spec.add_development_dependency 'pry'
33
33
  end
@@ -23,6 +23,7 @@ module KeepUp
23
23
  end
24
24
 
25
25
  def run
26
+ sanity_check
26
27
  update_all_dependencies
27
28
  report_up_to_date
28
29
  end
@@ -31,15 +32,26 @@ module KeepUp
31
32
 
32
33
  attr_reader :skip, :local
33
34
 
35
+ def sanity_check
36
+ version_control.clean? or
37
+ raise BailOut, "Commit or stash your work before running 'keep_up'"
38
+ bundle.check? or
39
+ raise BailOut, "Make sure your Gemfile.lock is up-to-date before running 'keep_up'"
40
+ end
41
+
34
42
  def update_all_dependencies
35
43
  Updater.new(bundle: bundle,
36
44
  repository: Repository.new(index: index),
37
- version_control: VersionControl.new,
45
+ version_control: version_control,
38
46
  filter: filter).run
39
47
  end
40
48
 
49
+ def version_control
50
+ @version_control ||= VersionControl.new
51
+ end
52
+
41
53
  def bundle
42
- Bundle.new(definition_builder: definition_builder)
54
+ @bundle ||= Bundle.new(definition_builder: definition_builder)
43
55
  end
44
56
 
45
57
  def report_up_to_date
@@ -57,7 +69,6 @@ module KeepUp
57
69
  else
58
70
  NullFilter.new
59
71
  end
60
-
61
72
  end
62
73
 
63
74
  def index
@@ -11,13 +11,7 @@ module KeepUp
11
11
  end
12
12
 
13
13
  def direct_dependencies
14
- (gemspec_dependencies + gemfile_dependencies).map do |dep|
15
- spec = locked_spec dep
16
- next unless spec
17
- Dependency.new(name: dep.name,
18
- version: dep.requirements_list.first,
19
- locked_version: spec.version)
20
- end.compact
14
+ gemspec_dependencies + gemfile_dependencies
21
15
  end
22
16
 
23
17
  def apply_updated_dependency(dependency)
@@ -27,18 +21,33 @@ module KeepUp
27
21
  update_lockfile(dependency)
28
22
  end
29
23
 
24
+ def check?
25
+ bundler_definition.to_lock == File.read('Gemfile.lock')
26
+ end
27
+
30
28
  private
31
29
 
32
30
  attr_reader :definition_builder
33
31
 
34
32
  def gemfile_dependencies
35
- bundler_lockfile.dependencies
33
+ build_dependencies bundler_lockfile.dependencies
36
34
  end
37
35
 
38
36
  def gemspec_dependencies
39
- gemspec_source = bundler_lockfile.sources.find { |it| it.is_a? Bundler::Source::Gemspec }
37
+ gemspec_source = bundler_lockfile.sources.
38
+ find { |it| it.is_a? Bundler::Source::Gemspec }
40
39
  return [] unless gemspec_source
41
- gemspec_source.gemspec.dependencies
40
+ build_dependencies gemspec_source.gemspec.dependencies
41
+ end
42
+
43
+ def build_dependencies(deps)
44
+ deps.map { |dep| build_dependency dep }.compact
45
+ end
46
+
47
+ def build_dependency(dep)
48
+ spec = locked_spec dep
49
+ return unless spec
50
+ Dependency.new(dependency: dep, locked_spec: spec)
42
51
  end
43
52
 
44
53
  def locked_spec(dep)
@@ -53,21 +62,27 @@ module KeepUp
53
62
  @bundler_definition ||= definition_builder.build(false)
54
63
  end
55
64
 
56
- def update_gemfile_contents(dependency)
57
- current_dependency = gemfile_dependencies.find { |it| it.name == dependency.name }
58
- return if !current_dependency
59
- return if current_dependency.matches_spec?(dependency)
65
+ def update_gemfile_contents(update)
66
+ current_dependency = gemfile_dependencies.find { |it| it.name == update.name }
67
+ return unless current_dependency
68
+ return if current_dependency.matches_spec?(update)
69
+
70
+ update = current_dependency.generalize_specification(update)
71
+
60
72
  contents = File.read 'Gemfile'
61
- updated_contents = GemfileFilter.apply(contents, dependency)
73
+ updated_contents = GemfileFilter.apply(contents, update)
62
74
  File.write 'Gemfile', updated_contents
63
75
  end
64
76
 
65
- def update_gemspec_contents(dependency)
66
- current_dependency = gemspec_dependencies.find { |it| it.name == dependency.name }
67
- return if !current_dependency
68
- return if current_dependency.matches_spec?(dependency)
77
+ def update_gemspec_contents(update)
78
+ current_dependency = gemspec_dependencies.find { |it| it.name == update.name }
79
+ return unless current_dependency
80
+ return if current_dependency.matches_spec?(update)
81
+
82
+ update = current_dependency.generalize_specification(update)
83
+
69
84
  contents = File.read gemspec_name
70
- updated_contents = GemspecFilter.apply(contents, dependency)
85
+ updated_contents = GemspecFilter.apply(contents, update)
71
86
  File.write gemspec_name, updated_contents
72
87
  end
73
88
 
@@ -83,9 +98,9 @@ module KeepUp
83
98
  end
84
99
  end
85
100
 
86
- def update_lockfile(dependency)
101
+ def update_lockfile(update)
87
102
  Bundler.clear_gemspec_cache
88
- definition_builder.build(gems: [dependency.name]).lock('Gemfile.lock')
103
+ definition_builder.build(gems: [update.name]).lock('Gemfile.lock')
89
104
  true
90
105
  rescue Bundler::VersionConflict
91
106
  puts 'Update failed'
@@ -1,6 +1,7 @@
1
1
  require 'bundler'
2
2
 
3
3
  module KeepUp
4
+ # Creates Bunder::Definition objects.
4
5
  class BundlerDefinitionBuilder
5
6
  def initialize(local: false)
6
7
  @local = local
@@ -1,12 +1,42 @@
1
1
  module KeepUp
2
2
  # Single dependency with its current locked version.
3
3
  class Dependency
4
- def initialize(name:, version:, locked_version:)
5
- @name = name
6
- @version = version
7
- @locked_version = locked_version
4
+ def initialize(dependency:, locked_spec:)
5
+ @dependency = dependency
6
+ @locked_spec = locked_spec
8
7
  end
9
8
 
10
- attr_reader :name, :version, :locked_version
9
+ def name
10
+ @dependency.name
11
+ end
12
+
13
+ def locked_version
14
+ @locked_spec.version
15
+ end
16
+
17
+ def matches_spec?(spec)
18
+ @dependency.matches_spec? spec
19
+ end
20
+
21
+ def generalize_specification(specification)
22
+ return specification if requirement.exact?
23
+ segments = specification.version.segments
24
+ return specification if segments.count <= segment_count
25
+ version = segments.take(segment_count).join('.')
26
+ Gem::Specification.new(specification.name, version)
27
+ end
28
+
29
+ private
30
+
31
+ def requirement
32
+ @dependency.requirement
33
+ end
34
+
35
+ def segment_count
36
+ @segment_count ||= begin
37
+ _, ver = requirement.requirements.first
38
+ ver.segments.count
39
+ end
40
+ end
11
41
  end
12
42
  end
@@ -2,8 +2,9 @@ module KeepUp
2
2
  # Filter to update dependency information in a Gemspec.
3
3
  module GemspecFilter
4
4
  def self.apply(contents, dependency)
5
+ matcher = dependency_matcher(dependency)
5
6
  contents.each_line.map do |line|
6
- if line =~ /^(.*_dependency[ (](?:['"]|%q.)#{dependency.name}.(?:\.freeze)?, \[?['"](?:~>|=)? *)[^'"]*(['"].*)/m
7
+ if line =~ matcher
7
8
  match = Regexp.last_match
8
9
  "#{match[1]}#{dependency.version}#{match[2]}"
9
10
  else
@@ -11,5 +12,13 @@ module KeepUp
11
12
  end
12
13
  end.join
13
14
  end
15
+
16
+ def self.dependency_matcher(dependency)
17
+ /
18
+ ^(.*_dependency
19
+ [\ (](?:['"]|%q.)#{dependency.name}.(?:\.freeze)?,
20
+ \ \[?['"](?:~>|=)?\ *)[^'"]*(['"].*)
21
+ /mx
22
+ end
14
23
  end
15
24
  end
@@ -25,7 +25,7 @@ module KeepUp
25
25
  def possible_updates
26
26
  bundle.direct_dependencies.
27
27
  select { |dep| filter.call dep }.
28
- map { |dep| repository.updated_dependency_for dep }.compact
28
+ map { |dep| repository.updated_dependency_for dep }.compact.uniq
29
29
  end
30
30
  end
31
31
  end
@@ -1,3 +1,3 @@
1
1
  module KeepUp
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
@@ -8,5 +8,9 @@ module KeepUp
8
8
  def revert_changes
9
9
  `git reset --hard`
10
10
  end
11
+
12
+ def clean?
13
+ `git status -s` == ''
14
+ end
11
15
  end
12
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keep_up
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matijs van Zuijlen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-11 00:00:00.000000000 Z
11
+ date: 2016-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '11.0'
33
+ version: '12.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '11.0'
40
+ version: '12.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.45.0
75
+ version: 0.46.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.45.0
82
+ version: 0.46.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: pry
85
85
  requirement: !ruby/object:Gem::Requirement