safe_update 0.2.0 → 0.3.2

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 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