gem_footprint_analyzer 0.1.7 → 0.1.8

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
2
  SHA256:
3
- metadata.gz: 13ad6f4a90d9f22d88152496807371138eecc8456b195ecf63597771c3e5f43d
4
- data.tar.gz: 6f78c45ebac12fb4602c61d3ff59b71b9c8dc0dff0fb88a7344ce56506e0c4f1
3
+ metadata.gz: 222e0c4ea30e4a328897f79bb5c1bbd137b8fd5f063bbf9fe74bc697fbebbe76
4
+ data.tar.gz: d65e4e2b96459f029579244653a87761f137f21f43a6bdb56b456b2f2946923d
5
5
  SHA512:
6
- metadata.gz: 5aa544dacfe1ac6d74622d07ed884e92ddeb40203f460701a2afe05f691bd0df2d495bac22efb3dba8b32d0b678e925ede6d00fbfaf66fe1fcef472c541f83b0
7
- data.tar.gz: 52ee797d7c5a24d16effc451eb9d64b5bfd577601767e2efd974d9b7fe013cddceca41d9d89aaffcefb7931f8ac75920869a63fb53e89696dc97b4d169e64459
6
+ metadata.gz: d18b017d780781fb892285df686cafd654d852f5ddb8b82b42ff221cc7ffb0651ae9b2d2e3ac1f4a22712e6d3b1296512fa2fcb5bb2f9532fdda8a0bf1da8349
7
+ data.tar.gz: 9eaad5508e6687e037d1ed49aa2e26ab81cc5e42b38804907b91a2661fecfc98f3554e9d7feb0e5341ff9c244a39eceb3348d9ee9418a73139a02c751f2a5340
data/Gemfile CHANGED
@@ -5,3 +5,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
5
5
  # Specify your gem's dependencies in gem_footprint_analyzer.gemspec
6
6
  gemspec
7
7
 
8
+ group :development do
9
+ gem 'rubocop', github: 'rubocop-hq/rubocop', branch: 'master'
10
+ end
11
+
@@ -1,7 +1,21 @@
1
+ GIT
2
+ remote: https://github.com/rubocop-hq/rubocop
3
+ revision: aa2c86fd45463acd2818650898771bd9bed8731b
4
+ branch: master
5
+ specs:
6
+ rubocop (0.60.0)
7
+ jaro_winkler (~> 1.5.1)
8
+ parallel (~> 1.10)
9
+ parser (>= 2.5, != 2.5.1.1)
10
+ powerpack (~> 0.1)
11
+ rainbow (>= 2.2.2, < 4.0)
12
+ ruby-progressbar (~> 1.7)
13
+ unicode-display_width (~> 1.4.0)
14
+
1
15
  PATH
2
16
  remote: .
3
17
  specs:
4
- gem_footprint_analyzer (0.1.7)
18
+ gem_footprint_analyzer (0.1.8)
5
19
 
6
20
  GEM
7
21
  remote: https://rubygems.org/
@@ -28,14 +42,6 @@ GEM
28
42
  diff-lcs (>= 1.2.0, < 2.0)
29
43
  rspec-support (~> 3.8.0)
30
44
  rspec-support (3.8.0)
31
- rubocop (0.60.0)
32
- jaro_winkler (~> 1.5.1)
33
- parallel (~> 1.10)
34
- parser (>= 2.5, != 2.5.1.1)
35
- powerpack (~> 0.1)
36
- rainbow (>= 2.2.2, < 4.0)
37
- ruby-progressbar (~> 1.7)
38
- unicode-display_width (~> 1.4.0)
39
45
  rubocop-rspec (1.30.1)
40
46
  rubocop (>= 0.60.0)
41
47
  ruby-progressbar (1.10.0)
@@ -49,7 +55,7 @@ DEPENDENCIES
49
55
  gem_footprint_analyzer!
50
56
  rake (~> 10.0)
51
57
  rspec (~> 3.0)
52
- rubocop (~> 0.60.0)
58
+ rubocop!
53
59
  rubocop-rspec (~> 1.30)
54
60
 
55
61
  BUNDLED WITH
@@ -26,6 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "bundler", "~> 1.16"
27
27
  spec.add_development_dependency "rake", "~> 10.0"
28
28
  spec.add_development_dependency "rspec", "~> 3.0"
29
- spec.add_development_dependency "rubocop", "~> 0.60.0"
30
29
  spec.add_development_dependency "rubocop-rspec", "~> 1.30"
31
30
  end
@@ -9,6 +9,8 @@ module GemFootprintAnalyzer
9
9
  PARENT_FIFO = '/tmp/parent'.freeze
10
10
  CHILD_FIFO = '/tmp/child'.freeze
11
11
 
12
+ # Prints the process pid, so it can be grabbed by the supervisor process, inits tranport fifos
13
+ # and requires requested libraries.
12
14
  def initialize
13
15
  output Process.pid
14
16
  init_transport
@@ -7,6 +7,7 @@ module GemFootprintAnalyzer
7
7
  LEGACY_RUBY_CMD = [RbConfig.ruby, '--disable=gem'].freeze
8
8
  RUBY_CMD = [RbConfig.ruby, '--disable=did_you_mean', '--disable=gem'].freeze
9
9
 
10
+ # Sets necessary ivars
10
11
  def initialize(library, require_string, fifos, options = {})
11
12
  @library = library
12
13
  @require_string = require_string || library
@@ -15,6 +16,8 @@ module GemFootprintAnalyzer
15
16
  @options = options
16
17
  end
17
18
 
19
+ # Starts a child process in a child-watching-thread
20
+ # Reads it's PID from the new process' STDOUT and sets it as an instance variable
18
21
  def start_child
19
22
  @child_thread ||= Thread.new do # rubocop:disable Naming/MemoizedInstanceVariableName
20
23
  Open3.popen3(child_env_vars, *ruby_command, context_file) do |_, stdout, stderr|
@@ -27,6 +30,8 @@ module GemFootprintAnalyzer
27
30
  end
28
31
  end
29
32
 
33
+ # Blocking method
34
+ # @return [Integer|nil] Process id or nil, if the child-watching-thread is not started
30
35
  def pid
31
36
  return unless child_thread
32
37
 
@@ -4,6 +4,7 @@ module GemFootprintAnalyzer
4
4
  # A command line interface class for the gem.
5
5
  # Provides options parsing and help messages for the user.
6
6
  class CLI
7
+ # Sets default options, to be overwritten by option parser down the road
7
8
  def initialize
8
9
  @options = {}
9
10
  @options[:runs] = 10
@@ -57,6 +57,8 @@ module GemFootprintAnalyzer
57
57
 
58
58
  attr_reader :options
59
59
 
60
+ private
61
+
60
62
  def banner
61
63
  script_name = "bundle exec #{File.basename($PROGRAM_NAME)}"
62
64
 
@@ -2,6 +2,9 @@ module GemFootprintAnalyzer
2
2
  class CLI
3
3
  # A module containing helper methods for CLI
4
4
  module Utils
5
+ # Outputs strings to STDOUT, in case it's no longer possible (ex. when piped to head),
6
+ # it exits the process.
7
+ # @param output [String] message to be outputted to STDOUT
5
8
  def self.safe_puts(output)
6
9
  output ||= "\n"
7
10
 
@@ -2,6 +2,7 @@ module GemFootprintAnalyzer
2
2
  module CoreExt
3
3
  # Provides Array#sum, missing in Ruby 2.2.0
4
4
  module Array
5
+ # Sums over the array
5
6
  def sum(init = 0, &block)
6
7
  if block
7
8
  reduce(init) { |acc, el| acc + yield(el) }
@@ -2,6 +2,7 @@ module GemFootprintAnalyzer
2
2
  module CoreExt
3
3
  # Provides File#mkfifo, missing in Ruby 2.2.0
4
4
  module File
5
+ # @param name [String] Name of the fifo file to be created
5
6
  def mkfifo(name)
6
7
  system("mkfifo #{name}") || fail('Failed to make FIFO special file')
7
8
  end
@@ -2,6 +2,7 @@ module GemFootprintAnalyzer
2
2
  module CoreExt
3
3
  # Provides Hash#dig, missing in Ruby 2.2.0
4
4
  module Hash
5
+ # @param keys [Array<Symbol|String>] list of keys to dig from the hash
5
6
  def dig(*keys)
6
7
  value = self
7
8
  keys.each do |key|
@@ -3,6 +3,7 @@ module GemFootprintAnalyzer
3
3
  # A formatter class outputting bare JSON.
4
4
  # Useful for integrating with other tools.
5
5
  class Json
6
+ # Initializer conforms to formatters interface
6
7
  def initialize(*); end
7
8
 
8
9
  # @return [String] A JSON form of the requires_list array, last entry is the cumulated result.
@@ -9,33 +9,41 @@ module GemFootprintAnalyzer
9
9
  class Entry
10
10
  BUNDLER_RUNTIME = 'bundler/runtime'.freeze
11
11
 
12
+ # @param entry_hash [Hash<Symbol>] Hash with a single require analysis
13
+ # @param options [Hash<Symbol>]
12
14
  def initialize(entry_hash, options = {})
13
15
  @entry_hash = entry_hash
14
16
  @options = options
15
17
  end
16
18
 
19
+ # @return [String] Require name
17
20
  def name
18
21
  @entry_hash[:name]
19
22
  end
20
23
 
24
+ # @return [String] Formatted parent require name
21
25
  def parent
22
26
  @entry_hash[:parent_name]
23
27
  end
24
28
 
29
+ # @return [Integer] Formatted time value
25
30
  def time
26
31
  time = @entry_hash.dig(:time, :mean)
27
32
  time && time.round
28
33
  end
29
34
 
35
+ # @return [Integer] Formatted RSS value
30
36
  def rss
31
37
  rss = @entry_hash.dig(:rss, :mean)
32
38
  rss && rss.round
33
39
  end
34
40
 
41
+ # @return [String] Formatted require name
35
42
  def formatted_name
36
43
  "#{name}#{debug_parent}"
37
44
  end
38
45
 
46
+ # @return [Bool] Is the entry a Gem or original require to be analyzed
39
47
  def top_level?
40
48
  parent.nil? || parent == BUNDLER_RUNTIME
41
49
  end
@@ -7,6 +7,9 @@ module GemFootprintAnalyzer
7
7
  %r{active_support/dependencies\.rb.+(`require'|`load_dependency'|`block in require')\z}.freeze
8
8
 
9
9
  class << self
10
+ # @param caller_entry [String] A single stack frame
11
+ # @param require_name [String|nil] An optional require name to calculate full_path from
12
+ # @return [String] path relative to the gem lib directory
10
13
  def relative_path(caller_entry, require_name = nil)
11
14
  caller_file = caller_entry.split(':')[0]
12
15
  if require_name
@@ -19,14 +22,19 @@ module GemFootprintAnalyzer
19
22
  full_path.sub(%r{\A#{load_path}/}, '')
20
23
  end
21
24
 
25
+ # @return [Array<String>] All configured load paths in the full directory form
22
26
  def load_paths
23
27
  @load_paths ||= $LOAD_PATH.map { |path| File.expand_path(path) }
24
28
  end
25
29
 
30
+ # @param name [String] require name
31
+ # @return [String] name with the .rb extension truncated
26
32
  def without_extension(name)
27
33
  name.sub(/\.rb\z/, '')
28
34
  end
29
35
 
36
+ # @param [Array<String>] List of caller stack frames
37
+ # @return [String|nil] First caller entry that doesn't originate from this gem
30
38
  def first_foreign_caller(caller_list)
31
39
  ffc = caller_list.find do |c|
32
40
  c !~ ACTIVESUPPORT_REQUIRE_DEPENDENCY &&
@@ -35,6 +43,7 @@ module GemFootprintAnalyzer
35
43
  without_extension(relative_path(ffc)) if ffc
36
44
  end
37
45
 
46
+ # Installs require spying on all relevant methods
38
47
  def spy_require(transport)
39
48
  alias_require_methods
40
49
 
@@ -42,6 +51,7 @@ module GemFootprintAnalyzer
42
51
  define_requires(transport)
43
52
  end
44
53
 
54
+ # @return [Array] Tuple with method call duration and return value
45
55
  def timed_exec
46
56
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
47
57
  result = yield
@@ -49,6 +59,7 @@ module GemFootprintAnalyzer
49
59
  [duration, result]
50
60
  end
51
61
 
62
+ # Aliases original methods, so they are accessible from methods that shadow them
52
63
  def alias_require_methods
53
64
  kernels.each do |k|
54
65
  k.send :alias_method, :regular_require, :require
@@ -56,14 +67,19 @@ module GemFootprintAnalyzer
56
67
  end
57
68
  end
58
69
 
70
+ # @return [Array<Class>] CLasses that have require* methods that we'll spy on
59
71
  def kernels
60
72
  @kernels ||= [(class << ::Kernel; self; end), Kernel]
61
73
  end
62
74
 
75
+ # @param transport [Transport] Instance of transport to be used by the require proxy method
63
76
  def define_requires(transport)
64
77
  kernels.each { |k| define_require(k, transport) }
65
78
  end
66
79
 
80
+ # @param klass [Class] Target class to have the spying require defined
81
+ # @param transport [Transport] Instance of transport to be used by the require proxy method
82
+ # Replaces require methods with proxied versions
67
83
  def define_require(klass, transport)
68
84
  klass.send :define_method, :require do |name|
69
85
  transport.ready_and_wait_for_start
@@ -78,6 +94,7 @@ module GemFootprintAnalyzer
78
94
  end
79
95
  end
80
96
 
97
+ # Replaces require_relative methods with proxied versions
81
98
  def define_require_relatives
82
99
  # As of Ruby 2.5.1, both :require and :require_relative use an unexposed native method
83
100
  # rb_safe_require, however it's challenging to plug into it and using original
@@ -85,9 +102,10 @@ module GemFootprintAnalyzer
85
102
  # we're redirecting :require_relative to the regular :require
86
103
  kernels.each do |k|
87
104
  k.send :define_method, :require_relative do |name|
105
+ return require(name) if name.start_with?('/')
106
+
88
107
  last_caller = caller(1..1).first
89
108
  relative_path = GemFootprintAnalyzer::RequireSpy.relative_path(last_caller, name)
90
-
91
109
  require(relative_path)
92
110
  end
93
111
  end
@@ -1,3 +1,3 @@
1
1
  module GemFootprintAnalyzer
2
- VERSION = '0.1.7'.freeze
2
+ VERSION = '0.1.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gem_footprint_analyzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciek Dubiński
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-24 00:00:00.000000000 Z
11
+ date: 2018-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 0.60.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 0.60.0
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rubocop-rspec
71
57
  requirement: !ruby/object:Gem::Requirement