safe_update 0.3.3 → 0.4.1

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: a34ecfbe5b686673a2abc202136461330aaa4f2f
4
- data.tar.gz: ebea4606b6853cf0f3e27747eb3eebea8b7fd574
3
+ metadata.gz: bba79506d40fecac8ada14494ed6c4716cf0dd72
4
+ data.tar.gz: 4634161fd299cf504d1e5e8e9335f5792955af82
5
5
  SHA512:
6
- metadata.gz: fc7aa962362fc264c326369a662f2e5e2a75bae8b6c5b196c4747cf48e9f0c49e7f73cf90eabc8bf3ee29bef75dd6e5d49b65446d4a5e5ff2fa4deb365d01724
7
- data.tar.gz: 172d61cd95fcd536f9494ba89887e8d10f1fd94a00cd90826b04afcd250925a68860ebd62a0d4970e7152f39ebab454ec7a21c4c0d629e45f558ebf248b6f28e
6
+ metadata.gz: 6333d5fa8b75759fdee92de16ff01644dbc016ef4b6a53b3e7d9914f80bdb8edbe91a211271c605fa3ae61b5f1c648ed94a173278327a75b3ec778237b93c6a0
7
+ data.tar.gz: 748b56136a743b01c7f5510cbfe169d596173365f553416cff90d18a61f2b8609ca9344718c1734c76425568c2ee023bb9c079c3a0b27c27fce5ed11361f8e91
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.2
1
+ 2.3.0
data/README.md CHANGED
@@ -88,6 +88,8 @@ I've knocked this up really quickly, and it's pretty MVP-ish. Ideas for future i
88
88
 
89
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.
90
90
 
91
+ To test the presenter that displays progress to the terminal: `ruby ./spec/presenter_test.rb`
92
+
91
93
  To install this gem (as in, your development copy of the code) onto your local machine, run `bundle exec rake install`.
92
94
 
93
95
  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).
@@ -7,7 +7,9 @@ module SafeUpdate
7
7
  class GitRepo
8
8
  def perform_safety_checks
9
9
  check_for_staged_changes
10
- check_for_gemfile_lock_changes
10
+ if gemfile_lock_has_changes?
11
+ raise 'safe_update cannot run while there are uncommitted changes in Gemfile.lock'
12
+ end
11
13
  end
12
14
 
13
15
  def discard_local_changes
@@ -23,6 +25,11 @@ module SafeUpdate
23
25
  `git push`
24
26
  end
25
27
 
28
+ def gemfile_lock_has_changes?
29
+ result = `git diff --name-only`
30
+ return result.include? 'Gemfile.lock'
31
+ end
32
+
26
33
  private
27
34
 
28
35
  def check_for_staged_changes
@@ -31,13 +38,5 @@ module SafeUpdate
31
38
  raise 'safe_update cannot run while git repo has staged changes'
32
39
  end
33
40
  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
41
  end
43
42
  end
@@ -1,21 +1,24 @@
1
1
  module SafeUpdate
2
2
  class OutdatedGem
3
- attr_reader :gem_name, :newest, :installed, :requested
3
+ STATUS_PENDING = 'pending'
4
+ STATUS_UPDATING = 'updating'
5
+ STATUS_TESTING = 'testing'
6
+ STATUS_UPDATED = 'updated'
7
+ STATUS_UNCHANGED = 'unchanged'
8
+ STATUS_TESTS_FAIL = 'tests_fail'
9
+
10
+ attr_reader :gem_name, :newest, :installed, :requested, :current_status
4
11
  def initialize(opts = {})
5
12
  @gem_name = opts[:gem_name]
6
13
  @newest = opts[:newest]
7
14
  @installed = opts[:installed]
8
15
  @requested = opts[:requested]
9
16
  @git_repo = opts[:git_repo] || GitRepo.new
17
+ @current_status = STATUS_PENDING
10
18
  end
11
19
 
12
20
  def attempt_update(test_command = nil)
13
- puts '-------------'
14
- puts "OUTDATED GEM: #{@gem_name}"
15
- puts " Newest: #{@newest}. "
16
- puts "Installed: #{@installed}."
17
- puts "Running `bundle update #{@gem_name}`..."
18
-
21
+ @current_status = STATUS_UPDATING
19
22
  `bundle update #{@gem_name}`
20
23
 
21
24
  # sometimes the gem may be outdated, but it's matching the
@@ -26,17 +29,25 @@ module SafeUpdate
26
29
  end
27
30
 
28
31
  if test_command
29
- puts "Running tests with: #{test_command}"
32
+ @current_status = STATUS_TESTING
30
33
  result = system(test_command)
31
34
  if result != true
32
- puts "tests failed - this gem won't be updated (test result: #{$?.to_i})"
35
+ @current_status = STATUS_TESTS_FAIL
33
36
  @git_repo.discard_local_changes
34
37
  return
35
38
  end
36
39
  end
37
40
 
38
- puts "committing changes (message: '#{commit_message}')..."
39
- @git_repo.commit_gemfile_lock(commit_message)
41
+ if @git_repo.gemfile_lock_has_changes?
42
+ @git_repo.commit_gemfile_lock(commit_message)
43
+ @current_status = STATUS_UPDATED
44
+ else
45
+ @current_status = STATUS_UNCHANGED
46
+ end
47
+ end
48
+
49
+ def being_operated_on_now?
50
+ [STATUS_UPDATING, STATUS_TESTING].include?(@current_status)
40
51
  end
41
52
 
42
53
  private
@@ -0,0 +1,95 @@
1
+ require 'curses'
2
+
3
+ module SafeUpdate
4
+ class Presenter
5
+ # outdated_gems is an array of instances of SafeUpdate::OutdatedGem
6
+
7
+ SPINNER_STATES = ['|', '/', '-', '\\']
8
+
9
+ def initialize
10
+ Curses.noecho
11
+ Curses.init_screen
12
+
13
+ @tick = 1
14
+ @running = true
15
+ end
16
+
17
+ def call(outdated_gems)
18
+ @outdated_gems = outdated_gems
19
+ while @running do
20
+ @tick += 1
21
+ update_screen
22
+ sleep 0.3
23
+ end
24
+ end
25
+
26
+ def stop
27
+ @running = false
28
+ print_final_output
29
+ end
30
+
31
+ private
32
+
33
+ def print_final_output
34
+ Curses.close_screen
35
+ puts title
36
+ puts header
37
+ @outdated_gems.each do |outdated_gem|
38
+ puts present_single_gem(outdated_gem)
39
+ end
40
+ end
41
+
42
+ def update_screen
43
+ Curses.setpos(0, 0)
44
+ Curses.addstr(title)
45
+ Curses.refresh
46
+
47
+ Curses.setpos(1, 0)
48
+ Curses.addstr(header)
49
+ Curses.refresh
50
+
51
+ @outdated_gems.each_with_index do |outdated_gem, i|
52
+ Curses.setpos(i + 2, 0)
53
+ line = present_single_gem(outdated_gem)
54
+ Curses.addstr(line)
55
+ Curses.refresh
56
+ end
57
+ end
58
+
59
+ def title
60
+ '=> Updating your gems... safely ' + current_spinner_state
61
+ end
62
+
63
+ def current_spinner_state
64
+ div, remainder = @tick.divmod(SPINNER_STATES.length)
65
+ SPINNER_STATES[remainder]
66
+ end
67
+
68
+ def header
69
+ return [
70
+ fixed_length_string('GEM', 15),
71
+ fixed_length_string('INSTALLED', 10),
72
+ fixed_length_string('REQUESTED', 10),
73
+ fixed_length_string('NEWEST', 7),
74
+ fixed_length_string('STATUS', 10)
75
+ ].join(' | ')
76
+ end
77
+
78
+ def present_single_gem(outdated_gem)
79
+ status = outdated_gem.current_status
80
+ status += ' ' + current_spinner_state if outdated_gem.being_operated_on_now?
81
+ return [
82
+ fixed_length_string(outdated_gem.gem_name, 15),
83
+ fixed_length_string(outdated_gem.installed, 10),
84
+ fixed_length_string(outdated_gem.requested || ' -', 10),
85
+ fixed_length_string(outdated_gem.newest, 7),
86
+ fixed_length_string(status, 10)
87
+ ].join(' | ')
88
+ end
89
+
90
+ # inspired by http://stackoverflow.com/questions/14714936/fix-ruby-string-to-n-characters
91
+ def fixed_length_string(str, length)
92
+ "%-#{length}.#{length}s" % str
93
+ end
94
+ end
95
+ end
@@ -15,6 +15,11 @@ module SafeUpdate
15
15
  push_interval = push.to_i if run_git_push
16
16
 
17
17
  puts 'Finding outdated gems...'
18
+ outdated_gems = get_outdated_gems
19
+
20
+ presenter = SafeUpdate::Presenter.new
21
+ Thread.new { presenter.call(outdated_gems) }
22
+
18
23
  outdated_gems.to_enum.with_index(1) do |outdated_gem, index|
19
24
  outdated_gem.attempt_update(test_command)
20
25
  @git_repo.push if run_git_push && index % push_interval == 0
@@ -23,19 +28,13 @@ module SafeUpdate
23
28
  # run it once at the very end, so the final commit can be tested in CI
24
29
  @git_repo.push if run_git_push
25
30
 
26
- display_finished_message
31
+ presenter.stop
27
32
  end
28
33
 
29
34
  private
30
35
 
31
- def outdated_gems
32
- BundleOutdatedParser.new.call
33
- end
34
-
35
- def display_finished_message
36
- puts '-------------'
37
- puts '-------------'
38
- puts 'FINISHED'
36
+ def get_outdated_gems
37
+ @outdated_gems ||= BundleOutdatedParser.new.call
39
38
  end
40
39
  end
41
40
  end
@@ -1,3 +1,3 @@
1
1
  module SafeUpdate
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.1'
3
3
  end
data/lib/safe_update.rb CHANGED
@@ -10,6 +10,7 @@ require 'safe_update/updater'
10
10
  require 'safe_update/outdated_gem'
11
11
  require 'safe_update/bundle_outdated_parser'
12
12
  require 'safe_update/git_repo'
13
+ require 'safe_update/presenter'
13
14
 
14
15
  module SafeUpdate
15
16
  end
data/safe_update.gemspec CHANGED
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "bundler", "~> 1.11"
22
22
  spec.add_development_dependency "rake", "~> 10.0"
23
23
  spec.add_development_dependency "rspec", "~> 3.0"
24
+
25
+ spec.add_runtime_dependency 'curses', '~> 1.0.1'
24
26
  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.3.3
4
+ version: 0.4.1
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-10-17 00:00:00.000000000 Z
11
+ date: 2016-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: curses
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.1
55
69
  description:
56
70
  email:
57
71
  - joshua.paling@gmail.com
@@ -75,6 +89,7 @@ files:
75
89
  - lib/safe_update/bundle_outdated_parser.rb
76
90
  - lib/safe_update/git_repo.rb
77
91
  - lib/safe_update/outdated_gem.rb
92
+ - lib/safe_update/presenter.rb
78
93
  - lib/safe_update/updater.rb
79
94
  - lib/safe_update/version.rb
80
95
  - safe_update.gemspec
@@ -98,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
113
  version: '0'
99
114
  requirements: []
100
115
  rubyforge_project:
101
- rubygems_version: 2.4.8
116
+ rubygems_version: 2.5.1
102
117
  signing_key:
103
118
  specification_version: 4
104
119
  summary: Safely and automatically update your gems, one at a time, with one git commit