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 +4 -4
- data/README.md +1 -1
- data/lib/gemshine/command.rb +53 -69
- data/lib/gemshine/ui.rb +106 -0
- data/lib/gemshine/version.rb +1 -1
- data/test/integration/cli_test.rb +2 -24
- data/test/test_helper.rb +2 -3
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 969c683a75e09a33d1425599ecc21f1348706753
|
4
|
+
data.tar.gz: 77b36e3464d036160e61ed1401dfccb0216020b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
+-------------------------+-----------------+----------------+-----------------+
|
data/lib/gemshine/command.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
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
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
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
|
-
|
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
|
30
|
-
|
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
|
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
|
-
|
48
|
-
|
60
|
+
@projects = gemfile_paths.size
|
61
|
+
log_path_stats
|
49
62
|
|
50
|
-
|
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
|
57
|
-
plucked_gems
|
66
|
+
def valid_gem_list
|
67
|
+
plucked_gems.map! { |line| parse_gem_from(line) }
|
58
68
|
end
|
59
69
|
|
60
|
-
def plucked_gems
|
61
|
-
|
70
|
+
def plucked_gems
|
71
|
+
data = @bundle_outdated_output.split("\n")
|
62
72
|
|
63
|
-
|
64
|
-
|
65
|
-
gemfile_contents = IO.read(gemfile_path)
|
73
|
+
parse_out_gem_lines data
|
74
|
+
filter_top_level_gems data
|
66
75
|
|
67
|
-
|
76
|
+
data.map! { |line| line[2..-1] }
|
77
|
+
end
|
68
78
|
|
69
|
-
|
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
|
-
|
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
|
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
|
105
|
+
def parse_gem_from(line)
|
90
106
|
parts = line.split
|
91
107
|
|
92
|
-
name = parts
|
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
|
-
[
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
data/lib/gemshine/ui.rb
ADDED
@@ -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
|
data/lib/gemshine/version.rb
CHANGED
@@ -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
|
9
|
+
gemshine "path #{GEMSHINE_PATH}"
|
12
10
|
end
|
13
11
|
|
14
|
-
|
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
|
data/test/test_helper.rb
CHANGED
@@ -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
|
-
|
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} #{
|
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.
|
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-
|
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
|