safe_update 0.2.0 → 0.3.2

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: fe337285cafce984750adbc2cdebe202bb84ff56
4
- data.tar.gz: 706d441b2c670f325203e6064ab940bbe1fe4b51
3
+ metadata.gz: 2691acf87593613225b1c53fc4786d330791082c
4
+ data.tar.gz: ed8afd4d7c0508445a1f2f37d847cfac7a647bba
5
5
  SHA512:
6
- metadata.gz: a45361991a9bb4872aa331e258a0963259a136d5c7bbd7eec9c962974c6a3cf09059dc70d4ab38ae4ffbbae31bab885ceccf09af875ef4792ee61296085a7224
7
- data.tar.gz: eeb43295a21a4ef7c050a69f1e46d6873ce5ac3b79cdaacf38ca94cdd1492c99d0d49df2ba2b2ed9746adaee61110df7f9c9dcbd029bc95cf97fbe14b1a96bce
6
+ metadata.gz: 76fa5e5858e0a02595dc15f7f459ca310187e05cf73d80a9d452e5aa56a64489b30912dae3e1756f122d0bd2a89bf214640ca2d6f173804e92d4f1183dca0a14
7
+ data.tar.gz: 9edfaab5bb002051bc1cc9fa135f930a5585b55de794ec1db7ab35012a58b159a0627eac3ffdf74d38c21a6f1b93b57863b390f0095abe31c2c04ebb71440676
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.2.2
data/README.md CHANGED
@@ -36,12 +36,6 @@ Installed: 3.0.0.
36
36
  Running `bundle update sprockets-rails`...
37
37
  committing changes (message: 'bundle update sprockets-rails')...
38
38
  -------------
39
- OUTDATED GEM: unf_ext
40
- Newest: 0.0.7.2.
41
- Installed: 0.0.7.1.
42
- Running `bundle update unf_ext`...
43
- committing changes (message: 'bundle update unf_ext')...
44
- -------------
45
39
  OUTDATED GEM: uniform_notifier
46
40
  Newest: 1.10.0.
47
41
  Installed: 1.9.0.
@@ -52,6 +46,35 @@ committing changes (message: 'bundle update uniform_notifier')...
52
46
  FINISHED
53
47
  ```
54
48
 
49
+ ### Options
50
+
51
+ Run `safe_update -h` to view all options:
52
+
53
+ ```
54
+ Usage: safe_update [options]
55
+ -v, --version Show version
56
+ -p, --push N git push every N commits (so your CI can test changes as you go)
57
+ -t, --test COMMAND Run tests after each commit. Don't update gems which break tests.
58
+ ```
59
+
60
+ ### Recommended workflow
61
+
62
+ **Step 1**
63
+
64
+ Checkout a new branch and run safe-update, pushing every commit so your CI builds can run:
65
+
66
+ ```
67
+ git checkout -b run-safe_update && git push -u origin run-safe_update && safe_update -p 1
68
+ ```
69
+
70
+ **Step 2**
71
+
72
+ Once everything is good, merge the branch back into master and delete the branch:
73
+
74
+ ```
75
+ git checkout master && git merge run-safe_update && git branch -d run-safe_update && git push origin --delete run-safe_update
76
+ ```
77
+
55
78
  ## Future
56
79
 
57
80
  I've knocked this up really quickly, and it's pretty MVP-ish. Ideas for future include:
@@ -65,7 +88,9 @@ I've knocked this up really quickly, and it's pretty MVP-ish. Ideas for future i
65
88
 
66
89
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
67
90
 
68
- 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).
91
+ To install this gem (as in, your development copy of the code) onto your local machine, run `bundle exec rake install`.
92
+
93
+ 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).
69
94
 
70
95
  ## Contributing
71
96
 
data/exe/safe_update CHANGED
@@ -9,9 +9,14 @@ OptionParser.new do |opts|
9
9
  opts.on('-v', '--version', 'Show version') do |v|
10
10
  options[:version] = v
11
11
  end
12
- opts.on('-p', '--push N', 'git push every N commits') do |p|
12
+
13
+ opts.on('-p', '--push N', 'git push every N commits (so your CI can test changes as you go)') do |p|
13
14
  options[:push] = p
14
15
  end
16
+
17
+ opts.on('-t', '--test COMMAND', "Run tests after each commit. Don't update gems which break tests.") do |test_command|
18
+ options[:test_command] = test_command
19
+ end
15
20
  end.parse!
16
21
 
17
22
  if options[:version]
@@ -0,0 +1,43 @@
1
+ # This class models a git repo that we are running safe_update on,
2
+ # and the operations we need to perform in the context
3
+ # of running safe_update. This class is not unit tested.
4
+ # It's simple code that mostly just makes system calls
5
+ # to git.
6
+ module SafeUpdate
7
+ class GitRepo
8
+ def perform_safety_checks
9
+ check_for_staged_changes
10
+ check_for_gemfile_lock_changes
11
+ end
12
+
13
+ def discard_local_changes
14
+ `git reset HEAD --hard`
15
+ end
16
+
17
+ def commit_gemfile_lock(message)
18
+ `git add Gemfile.lock`
19
+ `git commit -m '#{message}'`
20
+ end
21
+
22
+ def push
23
+ `git push`
24
+ end
25
+
26
+ private
27
+
28
+ def check_for_staged_changes
29
+ result = `git diff --name-only --cached`
30
+ if result.strip.length > 0
31
+ raise 'safe_update cannot run while git repo has staged changes'
32
+ end
33
+ end
34
+
35
+ def check_for_gemfile_lock_changes
36
+ result = `git diff --name-only`
37
+ if result.include? 'Gemfile.lock'
38
+ raise 'safe_update cannot run while there are uncommitted changes in Gemfile.lock'
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -5,23 +5,42 @@ module SafeUpdate
5
5
  # line is a line from bundle outdated --parseable
6
6
  # eg. react-rails (newest 1.6.0, installed 1.5.0, requested ~> 1.0)
7
7
  # or. react-rails (newest 1.6.0, installed 1.5.0)
8
- def initialize(line)
8
+ def initialize(line, git_repo = nil)
9
9
  @line = line
10
+ @git_repo = git_repo || GitRepo.new
10
11
  if name.to_s.empty?
11
12
  fail "Unexpected output from `bundle outdated --parseable`: #{@line}"
12
13
  end
13
14
  end
14
15
 
15
- def update
16
+ def attempt_update(test_command = nil)
16
17
  puts '-------------'
17
18
  puts "OUTDATED GEM: #{name}"
18
19
  puts " Newest: #{newest}. "
19
20
  puts "Installed: #{installed}."
20
21
  puts "Running `bundle update #{name}`..."
22
+
21
23
  `bundle update #{name}`
24
+
25
+ # sometimes the gem may be outdated, but it's matching the
26
+ # version required by the gemfile, so bundle update does nothing
27
+ # in which case, don't waste time on tests etc.
28
+ if false
29
+ return
30
+ end
31
+
32
+ if test_command
33
+ puts "Running tests with: #{test_command}"
34
+ result = system(test_command)
35
+ if result != true
36
+ puts "tests failed - this gem won't be updated (test result: #{$?.to_i})"
37
+ @git_repo.discard_local_changes
38
+ return
39
+ end
40
+ end
41
+
22
42
  puts "committing changes (message: '#{commit_message}')..."
23
- `git add Gemfile.lock`
24
- `git commit -m '#{commit_message}'`
43
+ @git_repo.commit_gemfile_lock(commit_message)
25
44
  end
26
45
 
27
46
  def name
@@ -1,27 +1,41 @@
1
1
  module SafeUpdate
2
2
  class Updater
3
- def run(options = {})
4
- options[:push] = options[:push].to_i if options[:push]
5
- check_for_staged_changes
6
- check_for_gemfile_lock_changes
7
- output_array = bundle_outdated_parseable.split(/\n+/)
8
- output_array.to_enum.with_index(1) do |line, index|
9
- update_gem(line)
10
- `git push` if options[:push] && index % options[:push] == 0
3
+ def initialize(git_repo = nil)
4
+ @git_repo = git_repo || GitRepo.new
5
+ @git_repo.perform_safety_checks
6
+ end
7
+ # push:
8
+ # If push is eg. 3, we will run @git_repo.push every 3 commits.
9
+ # If push is nil, we will never run git push.
10
+ # test_command:
11
+ # Command to run your tests after each gem update.
12
+ # If exit status is non-zero, the gem will not be updated.
13
+ def run(push: nil, test_command: nil)
14
+ run_git_push = (push && push.to_i > 0) ? true : false
15
+ push_interval = push.to_i if run_git_push
16
+
17
+ puts 'Finding outdated gems...'
18
+ outdated_gems.to_enum.with_index(1) do |outdated_gem, index|
19
+ outdated_gem.attempt_update(test_command)
20
+ @git_repo.push if run_git_push && index % push_interval == 0
11
21
  end
12
22
 
13
23
  # run it once at the very end, so the final commit can be tested in CI
14
- `git push` if options[:push]
24
+ @git_repo.push if run_git_push
15
25
 
16
- puts '-------------'
17
- puts '-------------'
18
- puts 'FINISHED'
26
+ display_finished_message
19
27
  end
20
28
 
21
29
  private
22
30
 
23
- def update_gem(line)
24
- OutdatedGem.new(line).update
31
+ def outdated_gems
32
+ return @outdated_gems if @outdated_gems
33
+
34
+ @outdated_gems = []
35
+ bundle_outdated_parseable.split(/\n+/).each do |line|
36
+ @outdated_gems << OutdatedGem.new(line, @git_repo)
37
+ end
38
+ return @outdated_gems
25
39
  end
26
40
 
27
41
  def bundle_outdated_parseable
@@ -37,22 +51,10 @@ module SafeUpdate
37
51
  output.strip
38
52
  end
39
53
 
40
- def check_for_staged_changes
41
- result = `git diff --name-only --cached`
42
- if result.strip.length > 0
43
- puts 'You have staged changes in git.'
44
- puts 'Please commit or stash your changes before running safe_update'
45
- exit 1
46
- end
47
- end
48
-
49
- def check_for_gemfile_lock_changes
50
- result = `git diff --name-only`
51
- if result.include? 'Gemfile.lock'
52
- puts 'You have uncommitted changes in your Gemfile.lock.'
53
- puts 'Please commit or stash your changes before running safe_update'
54
- exit 1
55
- end
54
+ def display_finished_message
55
+ puts '-------------'
56
+ puts '-------------'
57
+ puts 'FINISHED'
56
58
  end
57
59
  end
58
60
  end
@@ -1,3 +1,3 @@
1
1
  module SafeUpdate
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.2'
3
3
  end
data/lib/safe_update.rb CHANGED
@@ -8,6 +8,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
8
8
  require 'safe_update/version'
9
9
  require 'safe_update/updater'
10
10
  require 'safe_update/outdated_gem'
11
+ require 'safe_update/git_repo'
11
12
 
12
13
  module SafeUpdate
13
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safe_update
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Paling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-18 00:00:00.000000000 Z
11
+ date: 2016-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -62,6 +62,7 @@ extra_rdoc_files: []
62
62
  files:
63
63
  - ".gitignore"
64
64
  - ".rspec"
65
+ - ".ruby-version"
65
66
  - ".travis.yml"
66
67
  - Gemfile
67
68
  - LICENSE.txt
@@ -71,6 +72,7 @@ files:
71
72
  - bin/setup
72
73
  - exe/safe_update
73
74
  - lib/safe_update.rb
75
+ - lib/safe_update/git_repo.rb
74
76
  - lib/safe_update/outdated_gem.rb
75
77
  - lib/safe_update/updater.rb
76
78
  - lib/safe_update/version.rb
@@ -95,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
97
  version: '0'
96
98
  requirements: []
97
99
  rubyforge_project:
98
- rubygems_version: 2.5.1
100
+ rubygems_version: 2.4.8
99
101
  signing_key:
100
102
  specification_version: 4
101
103
  summary: Safely and automatically update your gems, one at a time, with one git commit