bundler-stats 1.3.4 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: eee76f69e73d6036e090b2bee0eba231f835ebc2
4
- data.tar.gz: '09f8d3089540158fd2a06e8bd53ff0fbd2154bfd'
2
+ SHA256:
3
+ metadata.gz: effbf5fc1dcb265737923b548467df2b831f444638f673e37622a2efd564cb54
4
+ data.tar.gz: 23cae592f904d2cdaef97b5597f953b0a927f24368d5f6e1b8763224391d4884
5
5
  SHA512:
6
- metadata.gz: 83527495fddca9076679e2a409854e33c08654307aed35e0ca29daefef1f48726bfb8287430d5fab681f7401c0664ec6a86309560fee8442c0da805105fd132e
7
- data.tar.gz: 6710d3f9948e9c4721fc11767bd736184776db218db45895f019df84c66a8837ba75d6401d86f1bb79e8de523f8de5f167e758f57b5e4f688124cad688bda3aa
6
+ metadata.gz: de70cf8fedea1260329b24fea38e1f564215ae7f6bf67d5d0d87d6aa1b639cad39ced3625069ea6ecb38e315a3fec7de561cde0a331e951d550234f90e6ed0c7
7
+ data.tar.gz: 606dc092473b823593dc2baec837c91956a6554c31f66990afc1f89052dac95f9c0209324b7e643429e04fe922025bcb090264f9730a7b6d900706bf6138ccfd
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Guardfile CHANGED
@@ -15,18 +15,6 @@
15
15
  #
16
16
  # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
17
 
18
- guard :bundler do
19
- require 'guard/bundler'
20
- require 'guard/bundler/verify'
21
- helper = Guard::Bundler::Verify.new
22
-
23
- files = ['Gemfile']
24
- files += Dir['*.gemspec'] if files.any? { |f| helper.uses_gemspec?(f) }
25
-
26
- # Assume files are symlinked from somewhere
27
- files.each { |file| watch(helper.real_path(file)) }
28
- end
29
-
30
18
  guard :rspec, cmd: 'rspec' do
31
19
  watch(%r{^spec/.+_spec\.rb$})
32
20
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
data/README.md CHANGED
@@ -1,15 +1,16 @@
1
1
  Bundler Stats
2
2
  =============
3
3
 
4
- You remember that time [someone yanked their library](http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm)
5
- and the entire Node universe fell apart? Yeah, me too. And all the
4
+ You remember that time [someone yanked their
5
+ library](http://blog.npmjs.org/post/141577284765/kik-left-pad-and-npm) and the
6
+ entire Node universe fell apart? Yeah, me too. And all the
6
7
  [thinkpieces](http://www.haneycodes.net/npm-left-pad-have-we-forgotten-how-to-program/)
7
- that came out just afterward were right: you should be careful about
8
- what dependencies you include in your project.
8
+ that came out just afterward were right: you should be careful about what
9
+ dependencies you include in your project.
9
10
 
10
11
  This project gives you some tools you can use with an existing Gemfile to
11
- determine which gems are including long trees of their own dependencies,
12
- and which you can potentially remove.
12
+ determine which gems are including long trees of their own dependencies, and
13
+ which you can potentially remove.
13
14
 
14
15
  This is an exploratory tool, and I'd be interested to hear what other criteria
15
16
  would be useful in determining what tools to remove.
@@ -33,75 +34,106 @@ Usage
33
34
  bundle-stats version # Prints the bundler-stats version
34
35
  bundle-stats versions TARGET # Shows versions requirements for target in other dependencies
35
36
 
36
- The most obvious thing to do is run the command by itself, which should help identify problem areas:
37
+ The most obvious thing to do is run the command by itself, which should help
38
+ identify problem areas:
37
39
 
38
40
  > bundle-stats
39
41
 
40
- +------------------------------|-----------------|-----------------+
41
- | Name | Total Deps | 1st Level Deps |
42
- +------------------------------|-----------------|-----------------+
43
- ... omitted stuff here ...
44
- | fog | 15 | 6 |
45
- | fancybox2-rails | 15 | 1 |
46
- | quiet_assets | 15 | 1 |
47
- | coffee-rails | 18 | 2 |
48
- | angular-rails-templates | 19 | 3 |
49
- | devise | 19 | 6 |
50
- | rspec-rails | 20 | 7 |
51
- | sass-rails | 21 | 4 |
52
- | foundation-icons-sass-rails | 22 | 2 |
53
- | rails | 29 | 9 |
54
- | angular_rails_csrf | 30 | 1 |
55
- | ngannotate-rails | 31 | 2 |
56
- | activeadmin | 48 | 12 |
57
- +------------------------------|-----------------|-----------------+
58
-
59
- Declared Gems: 35
60
- Total Gems: 113
61
-
62
- Unpinned Versions: 30
63
- Github Refs: 1
64
-
65
- It looks like activeadmin is a huge problem. Use `show` to investigate:
66
-
67
- > bundle-stats show activeadmin
68
- bundle-stats for activeadmin
69
-
70
- depended upon by (0) |
71
- depends on (48) | arbre, bourbon, coffee-rails, formtastic, formtastic_i18n, inherited_resources, jquery-rails, jquery-ui-rails, kaminari, rails, ransack, sass-rails, activesupport, i18n, json, minitest, thread_safe, tzinfo, sass, thor, coffee-script, railties, coffee-script-source, execjs, actionpack, rake, actionview, rack, rack-test, builder, erubis, has_scope, responders, actionmailer, activemodel, activerecord, bundler, sprockets-rails, mail, mime-types, treetop, polyglot, arel, sprockets, hike, multi_json, tilt, polyamorous
72
- unique to this (12) | arbre, bourbon, formtastic, formtastic_i18n, inherited_resources, jquery-rails, jquery-ui-rails, kaminari, ransack, has_scope, bundler, polyamorous
73
-
74
- Removing the dep will only actually remove 12 gems. The rest are shared dependencies with rails. We can also omit trees we aren't going to remove (hi rails) by not following them:
42
+ +----------------------------|------------|----------------+
43
+ | Name | Total Deps | 1st Level Deps |
44
+ +----------------------------|------------|----------------+
45
+ | rails_admin | 60 | 12 |
46
+ | rails | 40 | 12 |
47
+ | compass-rails | 35 | 3 |
48
+ | haml-rails | 29 | 5 |
49
+ | rspec-rails | 27 | 7 |
50
+ | sass-rails | 26 | 5 |
51
+ | devise | 26 | 5 |
52
+ | scenic | 25 | 2 |
53
+ | coffee-rails | 25 | 2 |
54
+ | guard-rubocop | 24 | 2 |
55
+ | versionist | 23 | 3 |
56
+ | factory_bot_rails | 23 | 2 |
57
+ | ... omitted stuff here ... |
58
+ +----------------------------|------------|----------------+
59
+
60
+ Declared Gems 56
61
+ Total Gems 170
62
+ Unpinned Versions 54
63
+ Github Refs 0
64
+
65
+ It looks like rails_admin is a huge problem. Use `show` to investigate:
66
+
67
+ > bundle-stats show rails_admin
68
+ bundle-stats for rails_admin
69
+
70
+ +--------------------------------|----------------------------------------+
71
+ | Depended Upon By (0) | |
72
+ | Depends On (60) | builder, coffee-rails |
73
+ | | font-awesome-rails, haml, jquery-rails |
74
+ | | jquery-ui-rails, kaminari, nested_form |
75
+ | | rack-pjax, rails, remotipart |
76
+ | | sass-rails, coffee-script, railties |
77
+ | | coffee-script-source, execjs |
78
+ | | actionpack, activesupport |
79
+ | | method_source, rake, thor, actionview |
80
+ | | rack, rack-test, rails-dom-testing |
81
+ | | rails-html-sanitizer, erubi |
82
+ | | concurrent-ruby, i18n, minitest |
83
+ | | tzinfo, thread_safe, nokogiri |
84
+ | | mini_portile2, loofah, crass, temple |
85
+ | | tilt, kaminari-actionview |
86
+ | | kaminari-activerecord, kaminari-core |
87
+ | | activerecord, activemodel, arel |
88
+ | | actioncable, actionmailer, activejob |
89
+ | | activestorage, bundler |
90
+ | | sprockets-rails, nio4r |
91
+ | | websocket-driver, websocket-extensions |
92
+ | | mail, globalid, mini_mime, marcel |
93
+ | | mimemagic, sprockets, sass |
94
+ | Unique to This (9) | font-awesome-rails, kaminari |
95
+ | | nested_form, rack-pjax, remotipart |
96
+ | | kaminari-actionview |
97
+ | | kaminari-activerecord, kaminari-core |
98
+ | | bundler |
99
+ +--------------------------------|----------------------------------------+
100
+
101
+ Removing the dep will only actually remove 9 gems. The rest are shared
102
+ dependencies with other gems like rails. We can also omit trees we aren't going
103
+ to remove (hi rails) by not following them:
75
104
 
76
105
  > bundle-stats show sass-rails --nofollow="railties,activesupport,actionpack"
77
106
  bundle-stats for sass-rails
78
107
 
79
- depended upon by (2) | activeadmin, foundation-icons-sass-rails
80
- depends on (10) | railties, sass, sprockets, sprockets-rails, hike, multi_json, rack, tilt, actionpack, activesupport
81
- unique to this (0) |
108
+ +--------------------------------|----------------------------------------+
109
+ | Depended Upon By (2) | compass-rails, rails_admin |
110
+ | Depends On (9) | railties, sass, sprockets |
111
+ | | sprockets-rails, tilt, concurrent-ruby |
112
+ | | rack, actionpack, activesupport |
113
+ | Unique to This (0) | |
114
+ +--------------------------------|----------------------------------------+
82
115
 
83
116
  To consume information with a build job or somesuch, all commands can emit JSON:
84
117
 
85
118
  > bundle-stats show sass-rails --nofollow="railties,activesupport,actionpack" -f json
86
119
  {
87
120
  "name": "sass-rails",
88
- "total_dependencies": 10,
89
- "first_level_dependencies": 4,
121
+ "total_dependencies": 9,
122
+ "first_level_dependencies": 5,
90
123
  "top_level_dependencies": {
91
- "activeadmin": "activeadmin (1.0.0.pre)",
92
- "foundation-icons-sass-rails": "foundation-icons-sass-rails (3.0.0)"
124
+ "compass-rails": "compass-rails (3.1.0)",
125
+ "rails_admin": "rails_admin (1.3.0)"
93
126
  },
94
127
  "transitive_dependencies": [
95
- "railties (< 5.0, >= 4.0.0)",
96
- "sass (~> 3.2.0)",
97
- "sprockets (<= 2.11.0, ~> 2.8)",
98
- "sprockets-rails (~> 2.0)",
99
- "hike (~> 1.2)",
100
- "multi_json (~> 1.0)",
101
- "rack (~> 1.0)",
102
- "tilt (!= 1.3.0, ~> 1.1)",
103
- "actionpack (>= 3.0)",
104
- "activesupport (>= 3.0)"
128
+ "railties (< 6, >= 4.0.0)",
129
+ "sass (~> 3.1)",
130
+ "sprockets (< 4.0, >= 2.8)",
131
+ "sprockets-rails (< 4.0, >= 2.0)",
132
+ "tilt (< 3, >= 1.1)",
133
+ "concurrent-ruby (~> 1.0)",
134
+ "rack (< 3, > 1)",
135
+ "actionpack (>= 4.0)",
136
+ "activesupport (>= 4.0)"
105
137
  ],
106
138
  "potential_removals": [
107
139
 
@@ -119,12 +151,13 @@ Contribution is expected to conform to the [Contributor Covenant](https://github
119
151
  Credits
120
152
  -------
121
153
 
122
- Thanks to the many kind people at [RailsCamp East 2016](http://east.railscamp.com)
123
- for the help, the ideas, and the support.
154
+ Thanks to the many kind people at [RailsCamp East
155
+ 2016](http://east.railscamp.com) for the help, the ideas, and the support.
124
156
 
125
157
  Thanks to Isaac Bowen for being pedantic about speeling.
126
158
 
127
159
  License
128
160
  -------
129
161
 
130
- This software is released under the [MIT License](https://github.com/jmmastey/bundler-stats/blob/master/MIT-LICENSE).
162
+ This software is released under the [MIT
163
+ License](https://github.com/jmmastey/bundler-stats/blob/master/MIT-LICENSE).
@@ -1 +1 @@
1
- bundle-stats
1
+ bin/bundle-stats
@@ -40,5 +40,7 @@ Gem::Specification.new do |gem|
40
40
 
41
41
  gem.add_development_dependency "rspec", "~> 3.4"
42
42
  gem.add_development_dependency "guard", "~> 2.13"
43
+ gem.add_development_dependency "guard-rspec"
43
44
  gem.add_development_dependency "pry", "~> 0.10"
45
+ gem.add_development_dependency "rb-readline"
44
46
  end
@@ -1,4 +1,5 @@
1
- require_relative 'stats/version'
2
- require_relative 'stats/tree'
3
- require_relative 'stats/remover'
4
1
  require_relative 'stats/calculator'
2
+ require_relative 'stats/printer'
3
+ require_relative 'stats/remover'
4
+ require_relative 'stats/tree'
5
+ require_relative 'stats/version'
@@ -59,56 +59,61 @@ module Bundler
59
59
 
60
60
  private
61
61
 
62
- # TODO: just install table_print, 'eh?
63
62
  def draw_stats(gem_stats, summary)
64
63
  max_name_length = gem_stats.map { |gem| gem[:name].length }.max
65
64
 
66
- say "+-#{"-" * max_name_length}-|-----------------|-----------------+"
67
- say "| %-#{max_name_length}s | Total Deps | 1st Level Deps |" % ["Name"]
68
- say "+-#{"-" * max_name_length}-|-----------------|-----------------+"
69
-
70
- gem_stats.each do |stat_line|
71
- say "| %-#{max_name_length}s | %-15s | %-15s |" % [stat_line[:name], stat_line[:total_dependencies], stat_line[:first_level_dependencies]]
72
- end
73
- say "+-#{"-" * max_name_length}-|-----------------|-----------------+"
74
- say ""
75
- say "Declared Gems: #{summary[:declared]}"
76
- say "Total Gems: #{summary[:total]}"
65
+ say Printer.new(
66
+ headers: ["Name", "Total Deps", "1st Level Deps"],
67
+ data: gem_stats.map { |stat_line|
68
+ [stat_line[:name], stat_line[:total_dependencies], stat_line[:first_level_dependencies]]
69
+ }).to_s
70
+
71
+ say Printer.new(
72
+ headers: nil,
73
+ borders: false,
74
+ data: [
75
+ ["Declared Gems", summary[:declared]],
76
+ ["Total Gems", summary[:total]],
77
+ ["", ""],
78
+ ["Unpinned Versions", summary[:unpinned]],
79
+ ["Github Refs", summary[:github]],
80
+ ]).to_s
77
81
  say ""
78
- say "Unpinned Versions: #{summary[:unpinned]}"
79
- say "Github Refs: #{summary[:github]}"
80
82
  end
81
83
 
82
84
  def draw_show(stats, target)
83
85
  say "bundle-stats for #{target}"
84
86
  say ""
85
- say "depended upon by (#{stats[:top_level_dependencies].count}) | #{stats[:top_level_dependencies].values.map(&:name).join(', ')}\n"
86
- say "depends on (#{stats[:transitive_dependencies].count}) | #{stats[:transitive_dependencies].map(&:name).join(', ')}\n"
87
- say "unique to this (#{stats[:potential_removals].count}) | #{stats[:potential_removals].map(&:name).join(', ')}\n"
88
- say ""
87
+
88
+ say Printer.new(
89
+ data: [
90
+ ["Depended Upon By (#{stats[:top_level_dependencies].count})", stats[:top_level_dependencies].values.map(&:name)],
91
+ ["Depends On (#{stats[:transitive_dependencies].count})", stats[:transitive_dependencies].map(&:name)],
92
+ ["Unique to This (#{stats[:potential_removals].count})", stats[:potential_removals].map(&:name)],
93
+ ]).to_s
89
94
  end
90
95
 
91
96
  def draw_versions(stats, target)
92
97
  dependers = stats[:top_level_dependencies] # they do the depending
93
98
  say "bundle-stats for #{target}"
94
- say ""
95
- say "Depended upon by #{stats[:top_level_dependencies].count}\n"
99
+ say Printer.new(
100
+ headers: nil,
101
+ borders: false,
102
+ data: [
103
+ ["Depended Upon By", stats[:top_level_dependencies].count],
104
+ ["Resolved Version", stats[:resolved_version]],
105
+ ]).to_s
96
106
 
97
- if stats[:resolved_version]
98
- say "Resolved version is #{stats[:resolved_version]}"
99
- end
100
107
  if dependers.count > 0
101
- max_name_length = dependers.map { |gem| gem[:name].length }.max
102
-
103
- say "+-#{"-" * max_name_length}-|-------------------+"
104
- say "| %-#{max_name_length}s | Required Version |" % ["Name"]
105
- say "+-#{"-" * max_name_length}-|-------------------+"
106
- dependers.each do |stat_line|
107
- say "| %-#{max_name_length}s | %-17s |" % [stat_line[:name], stat_line[:version]]
108
- end
109
- say "+-#{"-" * max_name_length}-|-------------------+"
110
108
  say ""
109
+ say Printer.new(
110
+ headers: ["Name", "Required Version"],
111
+ data: dependers.map { |stat_line|
112
+ [stat_line[:name], stat_line[:version]]
113
+ }).to_s
111
114
  end
115
+
116
+ say ""
112
117
  end
113
118
 
114
119
  def build_calculator(options)
@@ -0,0 +1,143 @@
1
+ # this is somewhat duplicative of the table_print gem, but tbh I like that we
2
+ # don't have many dependencies yet, so I'd rather keep it this way.
3
+ class Bundler::Stats::Printer
4
+ attr_accessor :headers, :data, :borders
5
+
6
+ MIN_COL_SIZE = 10
7
+
8
+ BORDERS = {
9
+ on: { corner: "+", horizontal: "-", vertical: "|" },
10
+ off: { corner: " ", horizontal: " ", vertical: " " },
11
+ }
12
+
13
+ def initialize(headers: nil, data: [], borders: true)
14
+ @headers = headers
15
+ @data = data
16
+ @borders = borders ? BORDERS[:on] : BORDERS[:off]
17
+ end
18
+
19
+ def to_s
20
+ table_data = ([headers] + data).compact
21
+ col_widths = column_widths(table_data)
22
+
23
+ lines = []
24
+ lines << separator_row(col_widths)
25
+
26
+ if headers
27
+ lines << aligned_row(headers, col_widths)
28
+ lines << separator_row(col_widths)
29
+ end
30
+
31
+ data.each do |row|
32
+ lines += split_rows(row, col_widths)
33
+ end
34
+ lines << separator_row(col_widths)
35
+
36
+ lines.join("\n")
37
+ end
38
+
39
+ def terminal_width
40
+ Integer(Kernel.send(:"`", "tput cols"))
41
+ rescue Errno::ENOENT, TypeError, Errno::ENOENT
42
+ 80
43
+ end
44
+
45
+ def column_widths(table_data)
46
+ num_cols = table_data.first.length
47
+ chrome = 2 + 2 + (num_cols - 1) * 3
48
+
49
+ # doesn't fit at all
50
+ if chrome + (num_cols * MIN_COL_SIZE) > terminal_width
51
+ raise ArgumentError, "Table smooshed. Refusing to print table."
52
+ end
53
+
54
+ data_widths = 0.upto(num_cols - 1).map do |idx|
55
+ max_width(table_data.map { |row| row[idx] })
56
+ end
57
+
58
+ # fits comfortably
59
+ if data_widths.inject(&:+) + chrome < terminal_width
60
+ return data_widths
61
+ end
62
+
63
+ free_space = terminal_width
64
+ free_space -= chrome
65
+ free_space -= MIN_COL_SIZE * num_cols
66
+
67
+ # fit uncomfortably
68
+ widths = [MIN_COL_SIZE] * num_cols
69
+ data_widths.each_with_index do |width, idx|
70
+ next unless width > widths[idx]
71
+
72
+ allocated = [width, free_space].min
73
+
74
+ if allocated > 0
75
+ widths[idx] += allocated
76
+ free_space -= allocated
77
+ end
78
+ end
79
+
80
+ widths
81
+ end
82
+
83
+ private
84
+
85
+ def max_width(data)
86
+ data.map do |value|
87
+ Array(value).join(", ").length
88
+ end.max
89
+ end
90
+
91
+ def separator_row(col_widths)
92
+ sep = "#{borders[:horizontal]}#{borders[:vertical]}#{borders[:horizontal]}"
93
+
94
+ "#{borders[:corner]}#{borders[:horizontal]}" +
95
+ col_widths.map { |width| borders[:horizontal] * width }.join(sep) +
96
+ "#{borders[:horizontal]}#{borders[:corner]}"
97
+ end
98
+
99
+ def split_rows(row, col_widths)
100
+ return [] unless row.find { |v| v && v.length > 0 }
101
+
102
+ rows_with_splits = [row]
103
+ next_row = []
104
+
105
+ joined_data = row.each_with_index.map do |val, idx|
106
+ words = Array(val).map(&:to_s)
107
+ target_width = col_widths[idx]
108
+
109
+ (cell, remainder) = row_and_remainder(words, target_width)
110
+
111
+ next_row[idx] = remainder
112
+ cell
113
+ end
114
+
115
+ ([aligned_row(joined_data, col_widths)] +
116
+ split_rows(next_row, col_widths)).compact
117
+ end
118
+
119
+ def row_and_remainder(words, target_width)
120
+ if(words.join(", ").length < target_width)
121
+ return [words.join(", "), nil]
122
+ end
123
+
124
+ this_row = []
125
+ while words.length > 0 && (this_row.join(", ").length + words[0].length) <= target_width
126
+ this_row << words.shift
127
+ end
128
+
129
+ [this_row.join(", "), words]
130
+ end
131
+
132
+ def aligned_row(row, col_widths)
133
+ aligned_values = row.each_with_index.map do |data, idx|
134
+ if idx == 0
135
+ data.rjust(col_widths[idx])
136
+ else
137
+ data.ljust(col_widths[idx])
138
+ end
139
+ end
140
+
141
+ "#{borders[:vertical]} " + aligned_values.join(" #{borders[:vertical]} ") + " #{borders[:vertical]}"
142
+ end
143
+ end
@@ -1,5 +1,5 @@
1
1
  module Bundler
2
2
  module Stats
3
- VERSION = '1.3.4'
3
+ VERSION = '2.0.1'
4
4
  end
5
5
  end
@@ -0,0 +1,214 @@
1
+ require 'bundler'
2
+ require 'bundler/stats'
3
+
4
+ describe Bundler::Stats::Printer do
5
+ subject { described_class }
6
+
7
+ def set_term_width(width)
8
+ allow(Kernel).to receive(:"`").and_return(width)
9
+ end
10
+
11
+ describe "#terminal_width" do
12
+ context "*nix systems" do
13
+ it "return the kernel width" do
14
+ set_term_width(180)
15
+
16
+ printer = subject.new
17
+ response = printer.terminal_width
18
+
19
+ expect(response).to eq(180)
20
+ end
21
+ end
22
+
23
+ context "non-*nix systems" do
24
+ it "always returns a small number" do
25
+ set_term_width(nil)
26
+
27
+ printer = subject.new
28
+ response = printer.terminal_width
29
+
30
+ expect(response).to eq(80)
31
+ end
32
+ end
33
+ end
34
+
35
+ describe "#column_widths" do
36
+ it "comfortably prints tables of comfortable data" do
37
+ set_term_width(80)
38
+ printer = subject.new
39
+ table_data = [
40
+ [ "name", "data" ],
41
+ [ "*" * 10, "*" * 20 ],
42
+ ]
43
+
44
+ widths = printer.column_widths(table_data)
45
+
46
+ expect(widths).to eq([10, 20])
47
+ end
48
+
49
+ it "smooshes uncomfortably long data" do
50
+ set_term_width(60)
51
+ printer = subject.new
52
+ table_data = [
53
+ [ "name", "data" ],
54
+ [ "*" * 10, "*" * 60 ],
55
+ ]
56
+
57
+ widths = printer.column_widths(table_data)
58
+
59
+ target_widths = [10, 43] # 7 for gutters
60
+ expect(widths).to eq(target_widths)
61
+ end
62
+
63
+ it "always allows some amount of space for data" do
64
+ set_term_width(60)
65
+ printer = subject.new
66
+ table_data = [
67
+ [ "name", "data1", "data2", "data3" ],
68
+ [ "*" * 10, "*" * 60, "*" * 60, "*" * 60 ],
69
+ ]
70
+
71
+ widths = printer.column_widths(table_data)
72
+
73
+ target_widths = [10, 17, 10, 10] # 13 for gutters
74
+ expect(widths).to eq(target_widths)
75
+ end
76
+
77
+ it "bails if it can't handle that data" do
78
+ set_term_width(10)
79
+ printer = subject.new
80
+ table_data = [
81
+ [ "name", "data" ],
82
+ [ "*" * 10, "*" * 20 ],
83
+ ]
84
+
85
+ expect {
86
+ printer.column_widths(table_data)
87
+ }.to raise_error(ArgumentError)
88
+ end
89
+ end
90
+
91
+ describe "#to_s" do
92
+ it "prints a pretty table" do
93
+ set_term_width(80)
94
+ printer = subject.new(headers: ["stars", "stripes"],
95
+ data: [["*****", "*****"]]
96
+ )
97
+
98
+ output = printer.to_s
99
+ table = <<-TABLE
100
+ +-------|---------+
101
+ | stars | stripes |
102
+ +-------|---------+
103
+ | ***** | ***** |
104
+ +-------|---------+
105
+ TABLE
106
+
107
+ expect(output).to eq(table.chomp)
108
+ end
109
+
110
+ it "deals with data alignment" do
111
+ set_term_width(80)
112
+ printer = subject.new(headers: ["name", "value"],
113
+ data: [
114
+ ["one", "*****"],
115
+ ["seventeen", "///////////////"]
116
+ ])
117
+
118
+ output = printer.to_s
119
+ table = <<-TABLE
120
+ +-----------|-----------------+
121
+ | name | value |
122
+ +-----------|-----------------+
123
+ | one | ***** |
124
+ | seventeen | /////////////// |
125
+ +-----------|-----------------+
126
+ TABLE
127
+
128
+ expect(output).to eq(table.chomp)
129
+ end
130
+
131
+ it "wraps data as necessary" do
132
+ set_term_width(35)
133
+ printer = subject.new(headers: ["name", "value"],
134
+ data: [
135
+ ["words", ["one", "two", "three", "four", "five"]],
136
+ ])
137
+
138
+ output = printer.to_s
139
+ table = <<-TABLE
140
+ +------------|--------------------+
141
+ | name | value |
142
+ +------------|--------------------+
143
+ | words | one, two, three |
144
+ | | four, five |
145
+ +------------|--------------------+
146
+ TABLE
147
+
148
+ expect(output).to eq(table.chomp)
149
+ end
150
+
151
+ it "can wrap multiple columns" do
152
+ set_term_width(45)
153
+ printer = subject.new(headers: ["name", "value", "other value"],
154
+ data: [
155
+ [ "words",
156
+ ["one", "two", "three", "four", "five"],
157
+ ["six", "seven", "eight", "nine", "ten"],
158
+ ]
159
+ ])
160
+
161
+ output = printer.to_s
162
+ table = <<-TABLE
163
+ +------------|-----------------|------------+
164
+ | name | value | other value |
165
+ +------------|-----------------|------------+
166
+ | words | one, two, three | six, seven |
167
+ | | four, five | eight, nine |
168
+ | | | ten |
169
+ +------------|-----------------|------------+
170
+ TABLE
171
+
172
+ expect(output).to eq(table.chomp)
173
+ end
174
+
175
+ it "can print without a header" do
176
+ set_term_width(80)
177
+ printer = subject.new(headers: nil,
178
+ data: [
179
+ ["*****", "********"],
180
+ ["++++++++", "+++++"],
181
+ ])
182
+
183
+ output = printer.to_s
184
+ table = <<-TABLE
185
+ +----------|----------+
186
+ | ***** | ******** |
187
+ | ++++++++ | +++++ |
188
+ +----------|----------+
189
+ TABLE
190
+
191
+ expect(output).to eq(table.chomp)
192
+ end
193
+
194
+ it "can print without separators at all!" do
195
+ set_term_width(80)
196
+ printer = subject.new(headers: nil,
197
+ borders: false,
198
+ data: [
199
+ ["*****", "********"],
200
+ ["++++++++", "+++++"],
201
+ ])
202
+
203
+ output = printer.to_s
204
+ table = <<-TABLE
205
+
206
+ ***** ********
207
+ ++++++++ +++++
208
+
209
+ TABLE
210
+
211
+ expect(output).to eq(table.chomp)
212
+ end
213
+ end
214
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-stats
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.4
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Mastey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-18 00:00:00.000000000 Z
11
+ date: 2019-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.13'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: pry
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0.10'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rb-readline
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: Looks through your lockfile and tries to identify problematic use of
84
112
  dependencies
85
113
  email: jmmastey@gmail.com
@@ -93,6 +121,7 @@ extra_rdoc_files:
93
121
  - README.md
94
122
  files:
95
123
  - ".gitignore"
124
+ - ".rspec"
96
125
  - ".travis.yml"
97
126
  - CHANGELOG.md
98
127
  - CODE_OF_CONDUCT.md
@@ -106,10 +135,12 @@ files:
106
135
  - lib/bundler/stats.rb
107
136
  - lib/bundler/stats/calculator.rb
108
137
  - lib/bundler/stats/cli.rb
138
+ - lib/bundler/stats/printer.rb
109
139
  - lib/bundler/stats/remover.rb
110
140
  - lib/bundler/stats/tree.rb
111
141
  - lib/bundler/stats/version.rb
112
142
  - spec/lib/bundler/stats/calculator_spec.rb
143
+ - spec/lib/bundler/stats/printer_spec.rb
113
144
  - spec/lib/bundler/stats/remover_spec.rb
114
145
  - spec/lib/bundler/stats/tree_spec.rb
115
146
  - spec/test_gemfile
@@ -137,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
168
  version: '0'
138
169
  requirements: []
139
170
  rubyforge_project:
140
- rubygems_version: 2.5.2.3
171
+ rubygems_version: 2.7.3
141
172
  signing_key:
142
173
  specification_version: 4
143
174
  summary: Dependency investigation for Bundler