gemshine 0.1.5 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|