show-gem-junk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c0f1225fea896e47483ceb42cd59b59df1db5dcd59548f4293a7af898ae7b4b4
4
+ data.tar.gz: bbe45d627b5487ab7b0339e253ba2b3a968419681bc146363866d8a36ca92373
5
+ SHA512:
6
+ metadata.gz: 42d1496c62aacfd31f426d04e8b5fb1010c20acb22ca9fbe09e96ff0bd14ba95b3eb1e133f5748df0d99ebc2fa0a347b415f653e78eced2e725bd651e20c92f3
7
+ data.tar.gz: eaf85724deeb6afd15b8557ab9e7a872c67f49108f60aaa37faa0550705310abc970253a2ce5c5c59155ef999bb1d14ea8a4783efae660a42e3d38f554748eee
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
5
+
6
+ require 'show/gem/junk'
7
+ require 'active_support'
8
+ require 'active_support/core_ext/numeric/conversions'
9
+ require 'colorator'
10
+ require 'optparse'
11
+
12
+ HOME_DIR = ENV.fetch('HOME', '~')
13
+ COL_WIDTH = 10
14
+
15
+ def try_fetch_gem_home
16
+ ENV.fetch('GEM_HOME')
17
+ rescue KeyError
18
+ export_line = "export GEM_HOME=#{HOME_DIR}/.gem/ruby/2.6.0".red.bold
19
+ warn <<-MSG
20
+ #{'ERROR:'.red.bold}
21
+ This tool requires the $GEM_HOME environment variable to be set.
22
+ You do not have a value for $GEM_HOME.
23
+
24
+ Before running this tool, please set your $GEM_HOME.
25
+ For example:
26
+
27
+ #{export_line}
28
+
29
+ MSG
30
+ exit 1
31
+ end
32
+
33
+ GEMS_DIR = File.join(try_fetch_gem_home, '/gems/')
34
+
35
+ def main
36
+ # Parse options
37
+ options = {}
38
+ OptionParser.new do |opts|
39
+ opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
40
+
41
+ opts.on('-v', '--[no-]verbose', 'Print verbose list of files') do |v|
42
+ options[:verbose] = v
43
+ end
44
+ end.parse!
45
+
46
+ # Collect gems
47
+ gems = Dir.glob(GEMS_DIR + '*').map do |gem|
48
+ Show::Gem::Junk::RubyGem.new(gem)
49
+ end
50
+ gems = gems.reject { |g| g.junk_files.empty? }.sort.reverse
51
+
52
+ # Print results
53
+ if options[:verbose]
54
+ print_verbose(gems)
55
+ else
56
+ print_table(gems)
57
+ end
58
+
59
+ print_total(gems)
60
+ end
61
+
62
+ def print_table(gems)
63
+ max_gem_name_len = gems.map { |g| g.name.size }.max || 0
64
+
65
+ # Header
66
+ puts
67
+ puts [
68
+ 'Gem Name'.ljust(max_gem_name_len),
69
+ 'Version'.rjust(COL_WIDTH),
70
+ 'Size'.rjust(COL_WIDTH),
71
+ 'Junk'.rjust(COL_WIDTH),
72
+ '% Junk'.rjust(COL_WIDTH)
73
+ ].join(' ').bold
74
+
75
+ # Rows
76
+ gems.each do |gem|
77
+ puts [
78
+ gem.name.ljust(max_gem_name_len),
79
+ gem.version.rjust(COL_WIDTH),
80
+ gem.size.to_s(:human_size).rjust(COL_WIDTH),
81
+ gem.junk_size.to_s(:human_size).rjust(COL_WIDTH),
82
+ gem.percent_junk.round(2).to_s.rjust(COL_WIDTH)
83
+ ].join(' ')
84
+ end
85
+ end
86
+
87
+ def print_verbose(gems)
88
+ gems.each do |gem|
89
+ puts
90
+ puts 'Gem Name: '.bold + gem.name
91
+ puts 'Version: '.bold + gem.version
92
+ puts 'Path: '.bold + gem.path
93
+ puts 'Size: '.bold + gem.size.to_s(:human_size)
94
+ puts 'Junk: '.bold + gem.junk_size.to_s(:human_size)
95
+ puts '% Junk: '.bold + gem.percent_junk.round(2).to_s
96
+ puts
97
+
98
+ max_junk_name_len = gem.junk_files.map { |g| g.pretty_path.size }.max || 0
99
+ puts [
100
+ 'Junk File'.ljust(max_junk_name_len),
101
+ 'Size'.rjust(COL_WIDTH)
102
+ ].join(' ').bold
103
+
104
+ gem.junk_files.sort.reverse.each do |file|
105
+ puts [
106
+ file.pretty_path.ljust(max_junk_name_len),
107
+ file.size.to_s(:human_size).rjust(COL_WIDTH)
108
+ ].join(' ')
109
+ end
110
+ puts
111
+ puts '=' * 80
112
+ end
113
+ end
114
+
115
+ def print_total(gems)
116
+ total_junk = gems.map(&:junk_size).sum
117
+ puts
118
+ puts "Grand total size of junk: #{total_junk.to_s(:human_size)}"
119
+ end
120
+
121
+ main
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'show/gem/junk/version'
4
+
5
+ module Show
6
+ module Gem
7
+ module Junk
8
+ class Error < StandardError; end
9
+ # Your code goes here...
10
+ end
11
+ end
12
+ end
13
+
14
+ require 'show/gem/junk/rubygem'
15
+ require 'show/gem/junk/gemfile'
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ # GemFile is a file that belongs to a rubygem
6
+ class Show::Gem::Junk::GemFile
7
+ attr_accessor :path, :stat
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ @stat = File.stat(path)
12
+ end
13
+
14
+ def size
15
+ stat.size
16
+ end
17
+
18
+ def pretty_path
19
+ path.gsub(GEMS_DIR, '')
20
+ end
21
+
22
+ def <=>(other)
23
+ size <=> other.size
24
+ end
25
+
26
+ def junk?
27
+ return false if File.directory?(path)
28
+
29
+ basename = File.basename(path)
30
+
31
+ # Files
32
+ return true if basename.end_with?('.gemspec')
33
+ return true if basename == '.gitignore'
34
+ return true if basename == '.travis.yml'
35
+ return true if basename == '.appveyor.yml'
36
+
37
+ # Loose path matching
38
+ return true if path.include?('concourse')
39
+
40
+ # Specs
41
+ parts = Pathname.new(pretty_path).each_filename.to_a
42
+ return false if parts.size < 2
43
+ return true if parts[1] == 'test'
44
+ return true if parts[1] == 'spec'
45
+ return true if parts[1] == 'features'
46
+
47
+ false
48
+ end
49
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # RubyGem is an unpacked gem on disk
4
+ class Show::Gem::Junk::RubyGem
5
+ attr_accessor :name, :path, :version, :files
6
+
7
+ def initialize(path)
8
+ @path = File.expand_path(path)
9
+ @name, _, @version = path.gsub(GEMS_DIR, '').rpartition('-')
10
+ @files = Dir.glob("#{GEMS_DIR}#{name}-#{version}/**/*", File::FNM_DOTMATCH).map do |f|
11
+ Show::Gem::Junk::GemFile.new(f)
12
+ end
13
+ end
14
+
15
+ def junk_files
16
+ files.select(&:junk?)
17
+ end
18
+
19
+ def size
20
+ files.map(&:size).sum
21
+ end
22
+
23
+ def junk_size
24
+ junk_files.map(&:size).sum
25
+ end
26
+
27
+ def percent_junk
28
+ return 0.0 if size.zero?
29
+
30
+ (junk_size.to_f / size) * 100
31
+ end
32
+
33
+ def <=>(other)
34
+ percent_junk <=> other.percent_junk
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Show
4
+ module Gem
5
+ module Junk
6
+ VERSION = '1.0.0'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: show-gem-junk
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Tom Richards
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorator
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Analyzes gems and shows a table of junk by percentage.
98
+ email:
99
+ - tom@tomrichards.net
100
+ executables:
101
+ - show-gem-junk
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - exe/show-gem-junk
106
+ - lib/show/gem/junk.rb
107
+ - lib/show/gem/junk/gemfile.rb
108
+ - lib/show/gem/junk/rubygem.rb
109
+ - lib/show/gem/junk/version.rb
110
+ homepage: https://github.com/t-richards/show-gem-junk
111
+ licenses:
112
+ - MIT
113
+ metadata:
114
+ homepage_uri: https://github.com/t-richards/show-gem-junk
115
+ source_code_uri: https://github.com/t-richards/show-gem-junk
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubygems_version: 3.0.4
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: A tool for analyzing junk contained within your GEM_HOME
135
+ test_files: []