gemshine 0.1.5 → 0.2.0

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: 11bad1e688de758ef3ecf5d99e89a7604214b8ea
4
- data.tar.gz: acd1bc99e5e35e89e1c81d32b1cf16e430743d8d
3
+ metadata.gz: 969c683a75e09a33d1425599ecc21f1348706753
4
+ data.tar.gz: 77b36e3464d036160e61ed1401dfccb0216020b0
5
5
  SHA512:
6
- metadata.gz: 9040adbfa05e0f4518e2c3491bb9ab7f06be024320f27ff89b5aac19e624b9f66144ad378d918d49fd20f333097add17cd79d65403423892bdc47031e380c0eb
7
- data.tar.gz: b92709d46c0d0509a3b2fde6b5bcb37a7a24ccd79d234b369ae32e83b164317ee82dcb98410a22f4e3b4405dd55b8f8b7580fafea56c8eea1597c2c036ad0538
6
+ metadata.gz: e1f517a6cc739b77c8799e7bb4c0fe6a53027cc2e9d24a2c83cd744041eb2e525f682248f4ac87b8352b0e3cc56ae04723cbb9a330257a2a0c8c3460d805cb01
7
+ data.tar.gz: bb58b90553d6f2e2a3421276861d749cd093a4bd7960b5d839048e23045317e7d32b7a8fc5ca5657be56d8cc6e903ec0763e8fde3bd7857b1d17a3ca54f07abc
data/README.md CHANGED
@@ -36,7 +36,7 @@ A typical rails project might have 40 or even 80 gems and keeping track of when
36
36
 
37
37
  After typing: `$ gemshine path /path/to/some/rails/app`
38
38
 
39
- You would see a table similar to this:
39
+ You would see a table similar to this and it also color codes it based on how out of date the gems are:
40
40
 
41
41
  ```
42
42
  +-------------------------+-----------------+----------------+-----------------+
@@ -1,4 +1,4 @@
1
- require 'terminal-table'
1
+ require 'gemshine/ui'
2
2
  require 'gemshine/version'
3
3
 
4
4
  module Gemshine
@@ -7,9 +7,9 @@ module Gemshine
7
7
  include Thor::Shell
8
8
  include Thor::Actions
9
9
 
10
- MSG_MISSING_GEMFILE = 'A Gemfile could not be found for:'
11
- MSG_GATHER_OUTDATED = 'Gathering outdated top level gems for:'
12
- MSG_UP_TO_DATE = 'Every top level gem is up to date for this project.'
10
+ include UI
11
+
12
+ attr_accessor :project_dir, :project_name, :projects, :gemfile_path, :bundle_outdated_output
13
13
 
14
14
  def initialize(root_path = '', options = {})
15
15
  @root_path = root_path
@@ -21,17 +21,30 @@ module Gemshine
21
21
 
22
22
  def path
23
23
  ruby_project_directories.each do |project_dir|
24
- gemfile_path = File.join(project_dir, 'Gemfile')
25
- project_name = File.basename(project_dir)
24
+ @project_dir = project_dir
25
+ @project_name = File.basename(@project_dir)
26
+ @gemfile_path = File.join(@project_dir, 'Gemfile')
27
+
28
+ log_project
29
+
30
+ unless File.exists?(@gemfile_path)
31
+ log_missing
32
+ next
33
+ end
26
34
 
27
- log_project File.basename(project_dir)
35
+ @bundle_outdated_output = run_bundle_outdated
36
+
37
+ if @bundle_outdated_output.match(/\b#{MSG_BUNDLE_UP_TO_DATE}\b/)
38
+ log_up_to_date
39
+ next
40
+ end
28
41
 
29
- unless File.exists?(gemfile_path)
30
- log_missing project_name
42
+ unless @bundle_outdated_output.match(/\b#{MSG_BUNDLE_OUTDATED}\b/)
43
+ log_bundle_message @bundle_outdated_output
31
44
  next
32
45
  end
33
46
 
34
- gem_table build_gem_list(bundle_outdated(project_dir), project_dir), project_name
47
+ gem_table valid_gem_list
35
48
  end
36
49
  end
37
50
 
@@ -44,37 +57,42 @@ module Gemshine
44
57
  def ruby_project_directories
45
58
  gemfile_paths = Dir.glob(File.join(@root_path, '**', 'Gemfile'))
46
59
 
47
- gemfile_paths.map { |gemfile| File.dirname(gemfile) }
48
- end
60
+ @projects = gemfile_paths.size
61
+ log_path_stats
49
62
 
50
- def bundle_outdated(path)
51
- pwd = Dir.pwd
52
-
53
- run "cd #{path} && bundle outdated && cd #{pwd}", capture: true
63
+ gemfile_paths.map { |gemfile| File.dirname(gemfile) }
54
64
  end
55
65
 
56
- def build_gem_list(data, project_dir)
57
- plucked_gems(data, project_dir).map! { |gem| parse_gem_data(gem) }
66
+ def valid_gem_list
67
+ plucked_gems.map! { |line| parse_gem_from(line) }
58
68
  end
59
69
 
60
- def plucked_gems(bundle_data, project_dir)
61
- lines = bundle_data.split("\n")
70
+ def plucked_gems
71
+ data = @bundle_outdated_output.split("\n")
62
72
 
63
- gemfile_path = File.join(project_dir, 'Gemfile')
64
- gemspec_path = Dir.glob(File.join(project_dir, '*.gemspec')).first
65
- gemfile_contents = IO.read(gemfile_path)
73
+ parse_out_gem_lines data
74
+ filter_top_level_gems data
66
75
 
67
- gemspec_path ? gemspec_contents = IO.read(gemspec_path) : gemspec_contents = ''
76
+ data.map! { |line| line[2..-1] }
77
+ end
68
78
 
69
- lines.keep_if do |line|
79
+ def parse_out_gem_lines(data)
80
+ data.keep_if do |line|
70
81
  line.strip!
71
82
  line.start_with?('*')
72
83
  end
84
+ end
85
+
86
+ def filter_top_level_gems(data)
87
+ gemspec_path = Dir.glob(File.join(@project_dir, '*.gemspec')).first
88
+ gemfile_contents = IO.read(@gemfile_path)
73
89
 
74
- lines.keep_if do |line|
90
+ gemspec_path ? gemspec_contents = IO.read(gemspec_path) : gemspec_contents = ''
91
+
92
+ data.keep_if do |line|
75
93
  parts = line.split
76
94
 
77
- parts[0] == '*' ? is_gem_line = true : is_gem_line = false
95
+ parts.first == '*' ? is_gem_line = true : is_gem_line = false
78
96
 
79
97
  is_gem_line ? name = parts[1][0..-1] : name = ''
80
98
 
@@ -82,14 +100,12 @@ module Gemshine
82
100
 
83
101
  is_gem_line && gemfile_contents.match(expression) || gemspec_contents.match(expression)
84
102
  end
85
-
86
- lines.map! { |line| line[2..-1] }
87
103
  end
88
104
 
89
- def parse_gem_data(line)
105
+ def parse_gem_from(line)
90
106
  parts = line.split
91
107
 
92
- name = parts[0]
108
+ name = parts.first
93
109
  ver_installed = parts[3][0...-1]
94
110
  ver_latest = parts[1][1..-1]
95
111
  ver_specific = parts[4]
@@ -103,44 +119,12 @@ module Gemshine
103
119
  ver_defined = "#{ver_operator} #{ver_locked}"
104
120
  end
105
121
 
106
- [name, ver_defined, ver_installed, ver_latest]
107
- end
108
-
109
- def gem_table(rows, title)
110
- if rows.size == 0
111
- log_up_to_date
112
- return
113
- end
114
-
115
- rows.sort!
116
-
117
- table = Terminal::Table.new title: title, headings: %w(Gem Defined Installed Latest), style: {width: 80} do |t|
118
- t.rows = rows
119
- t.add_separator
120
- t.add_row ["#{rows.size} outdated gems", '', '', '']
121
- end
122
-
123
- puts
124
- puts table
125
- end
126
-
127
- def log_project(project_name)
128
- puts
129
- say_status 'info', "\e[1m#{MSG_GATHER_OUTDATED}\e[0m", :yellow
130
- say_status 'project', project_name, :cyan
131
- puts
132
- end
133
-
134
- def log_up_to_date
135
- puts
136
- say_status 'nice', "#{MSG_UP_TO_DATE}", :magenta
137
- end
138
-
139
- def log_missing(project_name)
140
- puts
141
- say_status 'skip', "\e[1m#{MSG_MISSING_GEMFILE}\e[0m", :red
142
- say_status 'project', project_name, :yellow
143
- puts
122
+ [
123
+ name,
124
+ ver_defined,
125
+ set_color(ver_installed, detect_outdated_color(ver_installed, ver_latest)),
126
+ set_color(ver_latest, :green)
127
+ ]
144
128
  end
145
129
  end
146
130
  end
@@ -0,0 +1,106 @@
1
+ require 'terminal-table'
2
+
3
+ module Gemshine
4
+ module UI
5
+ MSG_PATH_STATS = 'projects were detected, working...'
6
+ MSG_MISSING_GEMFILE = 'A Gemfile could not be found for:'
7
+ MSG_GATHER_OUTDATED = 'Gathering outdated top level gems for:'
8
+ MSG_UP_TO_DATE = 'Every gem is up to date for this project.'
9
+ MSG_BUNDLE_ERROR = 'Bundler reported an issue with this project, here it is:'
10
+ MSG_BUNDLE_OUTDATED = 'Outdated gems included in the bundle'
11
+ MSG_BUNDLE_UP_TO_DATE = 'Your bundle is up to date'
12
+
13
+ def run_bundle_outdated
14
+ pwd = Dir.pwd
15
+
16
+ run "cd #{@project_dir} && bundle outdated && cd #{pwd}", capture: true
17
+ end
18
+
19
+ def gem_table(rows)
20
+ if rows.empty?
21
+ log_up_to_date
22
+ return
23
+ end
24
+
25
+ rows.sort!
26
+
27
+ table = Terminal::Table.new title: set_color(@project_name, :cyan, :bold),
28
+ headings: table_headings,
29
+ style: { width: 70 } do |t|
30
+ t.rows = rows
31
+ t.add_separator
32
+ t.add_row ["#{set_color(rows.size, :bold)} outdated gems", '', '', '']
33
+ end
34
+
35
+ puts
36
+ puts table
37
+ end
38
+
39
+ def detect_outdated_color(installed, latest)
40
+ installed_parts = installed.split('.')
41
+ latest_parts = latest.split('.')
42
+ outdated_position = 2
43
+
44
+ version_comparison = installed_parts.zip(latest_parts).map { |a, b| a < b }
45
+
46
+ version_comparison.each_with_index do |outdated_digit, i|
47
+ if outdated_digit
48
+ outdated_position = i
49
+ break
50
+ end
51
+ end
52
+
53
+ digit_color outdated_position
54
+ end
55
+
56
+ def log_path_stats
57
+ puts
58
+ say_status 'stats', "#{@projects} #{MSG_PATH_STATS}", :yellow
59
+ end
60
+
61
+ def log_project
62
+ log_status 'info', MSG_GATHER_OUTDATED, :blue
63
+ log_project_name :cyan
64
+ end
65
+
66
+ def log_up_to_date
67
+ puts
68
+ say_status 'nice', MSG_UP_TO_DATE, :magenta
69
+ end
70
+
71
+ def log_missing
72
+ log_status 'skip', MSG_MISSING_GEMFILE, :red
73
+ log_project_name :yellow
74
+ end
75
+
76
+ def log_bundle_message(message)
77
+ log_status 'warning', MSG_BUNDLE_ERROR, :red
78
+ say_status 'message', message.strip!, :yellow
79
+ end
80
+
81
+ private
82
+
83
+ def table_headings
84
+ c_name = set_color('Gem', :bold)
85
+ c_defined = set_color('Defined', :bold)
86
+ c_installed = set_color('Installed', :bold)
87
+ c_latest = set_color('Latest', :bold)
88
+
89
+ [c_name, c_defined, c_installed, c_latest]
90
+ end
91
+
92
+ def digit_color(position)
93
+ position == 0 ? :red : :yellow
94
+ end
95
+
96
+ def log_status(type, message, color)
97
+ puts
98
+ say_status type, set_color(message, :bold), color
99
+ end
100
+
101
+ def log_project_name(color)
102
+ say_status 'project', @project_name, color
103
+ puts
104
+ end
105
+ end
106
+ end
@@ -1,3 +1,3 @@
1
1
  module Gemshine
2
- VERSION = '0.1.5'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -5,15 +5,11 @@ class TestCLI < Minitest::Unit::TestCase
5
5
  include Gemshine::Test
6
6
 
7
7
  def test_path
8
- create_dummy_gemfile
9
-
10
8
  out, err = capture_subprocess_io do
11
- gemshine 'path Gemfile'
9
+ gemshine "path #{GEMSHINE_PATH}"
12
10
  end
13
11
 
14
- FileUtils.rm_rf TEST_PATH
15
-
16
- assert_match '', out
12
+ assert_match /Gathering/, out
17
13
  end
18
14
 
19
15
  def test_version
@@ -23,22 +19,4 @@ class TestCLI < Minitest::Unit::TestCase
23
19
 
24
20
  assert_match /Gemshine/, out
25
21
  end
26
-
27
- private
28
-
29
- def create_dummy_gemfile
30
- gems = []
31
- gems << 'gem "rails", "~> 4.0.0"'
32
- gems << ' gem "sidekiq", "~> 2.17.4"'
33
- gems << 'gem "whenever", require: false'
34
- gems << 'gemwhenever",,,,d,,e'
35
- gems << 'gem "sdoc", "~> 0.4.0", require: false'
36
- gems << ' '
37
-
38
- FileUtils.mkpath TEST_PATH
39
-
40
- File.open(TEST_GEMFILE, 'w+') do |f|
41
- gems.each { |element| f.puts(element) }
42
- end
43
- end
44
22
  end
@@ -4,13 +4,12 @@ module Gemshine
4
4
  module Test
5
5
 
6
6
  BINARY_PATH = File.absolute_path(File.join('..', '..', 'bin', 'gemshine'),__FILE__)
7
- TEST_PATH = File.join('', 'tmp')
8
- TEST_GEMFILE = File.join('', 'tmp', 'Gemfile')
7
+ GEMSHINE_PATH = File.absolute_path(File.join('..', '..'),__FILE__)
9
8
 
10
9
  def gemshine(command)
11
10
  cmd, project_path = command.split(' ')
12
11
 
13
- command = "#{cmd} #{File.join(TEST_PATH, project_path)}" if command.include?(' ')
12
+ command = "#{cmd} #{project_path}" if command.include?(' ')
14
13
 
15
14
  system "#{BINARY_PATH} #{command}"
16
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemshine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Janetakis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-26 00:00:00.000000000 Z
11
+ date: 2014-04-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -100,6 +100,7 @@ files:
100
100
  - lib/gemshine.rb
101
101
  - lib/gemshine/cli.rb
102
102
  - lib/gemshine/command.rb
103
+ - lib/gemshine/ui.rb
103
104
  - lib/gemshine/version.rb
104
105
  - test/integration/cli_test.rb
105
106
  - test/test_helper.rb