gem-why 0.0.1 → 0.0.2
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/CHANGELOG.md +8 -0
- data/README.md +3 -0
- data/lib/gem_why/analyzer.rb +23 -15
- data/lib/gem_why/dependent.rb +12 -0
- data/lib/gem_why/formatters/direct_formatter.rb +4 -4
- data/lib/gem_why/json_outputter.rb +2 -6
- data/lib/gem_why/version.rb +1 -1
- data/lib/rubygems/commands/why_command.rb +4 -4
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a438508ad05fcd88de1eb11236f4e716cf40679dee3072d79caab4598ef19d4c
|
|
4
|
+
data.tar.gz: 36e198634d2b8db32b26f1a9adf2683dba758a286998d4ef79308db88072b449
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88e93410498b664730885114cb7e0dfa9de839785665cae19103a917135d8ce622baf4c226563c8a32e3e10b91e1e2e6e0a6972e40b073a87973936cac09f5dd
|
|
7
|
+
data.tar.gz: cfae3e17bb1a250f617cf749ef6f1a80e9563e6b355b09142691c96bf64631f9343e80742e902a8f0b9f9b24a6c758111b311f1b53d0a6eeb32a11ca9a102689
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.2] - 2025-10-11
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Add spec memoization to improve performance of recursive analysis
|
|
13
|
+
- Fix terminology: use 'dependents' instead of 'dependencies' in help text
|
|
14
|
+
- Eliminate redundant spec lookups by passing version from analyze
|
|
15
|
+
|
|
8
16
|
## [0.0.1] - 2025-10-01
|
|
9
17
|
|
|
10
18
|
### Added
|
data/README.md
CHANGED
|
@@ -53,6 +53,8 @@ To see which gems depend on a specific gem:
|
|
|
53
53
|
gem why GEMNAME [options]
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
**Bonus:** If you add this gem to your project, you can use the `bundle exec gem why` command to understand the dependencies of your gems in your project.
|
|
57
|
+
|
|
56
58
|
### Examples
|
|
57
59
|
|
|
58
60
|
#### Default Behavior - Deep Dependencies
|
|
@@ -128,6 +130,7 @@ No gems depend on nonexistent-gem
|
|
|
128
130
|
| (none) | | Show full dependency chains (default) |
|
|
129
131
|
| `--direct` | `-d` | Show only direct dependencies |
|
|
130
132
|
| `--tree` | `-t` | Display as a visual tree |
|
|
133
|
+
| `--json` | | Output in JSON format |
|
|
131
134
|
| `--help` | `-h` | Show help message |
|
|
132
135
|
| `--verbose` | `-V` | Verbose output |
|
|
133
136
|
|
data/lib/gem_why/analyzer.rb
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative "dependent"
|
|
4
|
+
|
|
3
5
|
module GemWhy
|
|
4
6
|
# Analyzes gem dependencies to find dependents and dependency chains
|
|
5
7
|
class Analyzer
|
|
8
|
+
def initialize
|
|
9
|
+
@spec_cache = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
6
12
|
# Finds all gems that directly depend on the target gem
|
|
7
13
|
# @param target_gem_name [String] the gem to find dependents for
|
|
8
|
-
# @return [Array<
|
|
14
|
+
# @return [Array<Dependent>] array of Dependent objects
|
|
9
15
|
def find_direct_dependents(target_gem_name)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Gem::Specification
|
|
17
|
+
.map(&:dependencies).flatten
|
|
18
|
+
.filter { |dep| dep.name.downcase == target_gem_name.downcase }
|
|
19
|
+
.map do |dep|
|
|
20
|
+
Dependent.new(
|
|
21
|
+
name: spec.name,
|
|
22
|
+
version: spec.version.to_s,
|
|
23
|
+
requirement: dep.requirement.to_s
|
|
24
|
+
)
|
|
25
|
+
end.sort_by(&:name)
|
|
20
26
|
end
|
|
21
27
|
|
|
22
28
|
# Finds all dependency chains leading to the target gem
|
|
@@ -65,7 +71,7 @@ module GemWhy
|
|
|
65
71
|
end
|
|
66
72
|
|
|
67
73
|
def process_dependency(dep, target_gem, path, new_node, visited)
|
|
68
|
-
if dep.name.downcase == target_gem
|
|
74
|
+
if dep.name.downcase == target_gem
|
|
69
75
|
[path + [new_node]]
|
|
70
76
|
else
|
|
71
77
|
find_paths_to_target(dep.name, target_gem, path + [new_node], visited)
|
|
@@ -73,9 +79,11 @@ module GemWhy
|
|
|
73
79
|
end
|
|
74
80
|
|
|
75
81
|
def load_gem_spec(gem_name)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
@spec_cache.fetch(gem_name) do
|
|
83
|
+
@spec_cache[gem_name] = Gem::Specification.find_by_name(gem_name)
|
|
84
|
+
rescue Gem::MissingSpecError
|
|
85
|
+
@spec_cache[gem_name] = nil
|
|
86
|
+
end
|
|
79
87
|
end
|
|
80
88
|
|
|
81
89
|
def build_dependency_node(spec, dep)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GemWhy
|
|
4
|
+
# Represents a gem that depends on a target gem
|
|
5
|
+
Dependent = Data.define(:name, :version, :requirement) do
|
|
6
|
+
# Returns the dependent as a hash
|
|
7
|
+
# @return [Hash] hash representation
|
|
8
|
+
def to_h
|
|
9
|
+
{ name:, version:, requirement: }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -8,7 +8,7 @@ module GemWhy
|
|
|
8
8
|
class DirectFormatter < BaseFormatter
|
|
9
9
|
# Formats and displays direct dependencies
|
|
10
10
|
# @param gem_name [String] the target gem name
|
|
11
|
-
# @param dependents [Array<
|
|
11
|
+
# @param dependents [Array<Dependent>] the dependent gems
|
|
12
12
|
# @return [void]
|
|
13
13
|
def format(gem_name, dependents)
|
|
14
14
|
return say "No gems depend on #{colorize(gem_name, :yellow)}" if dependents.empty?
|
|
@@ -21,9 +21,9 @@ module GemWhy
|
|
|
21
21
|
private
|
|
22
22
|
|
|
23
23
|
def print_direct_dependents(dependents, gem_name)
|
|
24
|
-
dependents.each do |
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
dependents.each do |dependent|
|
|
25
|
+
say " #{colorize(dependent.name,
|
|
26
|
+
:blue)} (#{dependent.version}) requires #{gem_name} #{dependent.requirement}"
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -14,17 +14,13 @@ module GemWhy
|
|
|
14
14
|
|
|
15
15
|
# Outputs direct dependencies as JSON
|
|
16
16
|
# @param gem_name [String] the target gem name
|
|
17
|
-
# @param dependents [Array<
|
|
17
|
+
# @param dependents [Array<Dependent>] the dependent gems
|
|
18
18
|
# @return [void]
|
|
19
19
|
def output_direct(gem_name, dependents)
|
|
20
20
|
target = gem_name
|
|
21
21
|
mode = "direct"
|
|
22
22
|
total = dependents.size
|
|
23
|
-
dependents_data = dependents.map
|
|
24
|
-
spec = Gem::Specification.find_by_name(name)
|
|
25
|
-
version = spec.version.to_s
|
|
26
|
-
{ name:, version:, requirement: }
|
|
27
|
-
end
|
|
23
|
+
dependents_data = dependents.map(&:to_h)
|
|
28
24
|
output = { target:, mode:, dependents: dependents_data, total: }
|
|
29
25
|
say JSON.pretty_generate(output)
|
|
30
26
|
end
|
data/lib/gem_why/version.rb
CHANGED
|
@@ -14,8 +14,8 @@ module Gem
|
|
|
14
14
|
# Command to show which gems depend on a specific gem
|
|
15
15
|
#
|
|
16
16
|
# This command helps identify dependency relationships by showing:
|
|
17
|
-
# - Direct
|
|
18
|
-
# - Deep
|
|
17
|
+
# - Direct dependents (--direct): immediate dependents only
|
|
18
|
+
# - Deep dependency chains (default): full dependency chains
|
|
19
19
|
# - Tree visualization (--tree): hierarchical view
|
|
20
20
|
#
|
|
21
21
|
# @example Show all dependency chains
|
|
@@ -73,7 +73,7 @@ module Gem
|
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def setup_direct_option
|
|
76
|
-
add_option("-d", "--direct", "Show only direct
|
|
76
|
+
add_option("-d", "--direct", "Show only direct dependents") do |value, options|
|
|
77
77
|
options[:direct] = value
|
|
78
78
|
end
|
|
79
79
|
end
|
|
@@ -130,7 +130,7 @@ module Gem
|
|
|
130
130
|
end
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
# Shows direct
|
|
133
|
+
# Shows direct dependents only
|
|
134
134
|
# @param gem_name [String] the target gem name
|
|
135
135
|
# @return [void]
|
|
136
136
|
def show_direct_dependencies(gem_name)
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gem-why
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vitaly Slobodin
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
@@ -36,6 +36,7 @@ files:
|
|
|
36
36
|
- README.md
|
|
37
37
|
- Rakefile
|
|
38
38
|
- lib/gem_why/analyzer.rb
|
|
39
|
+
- lib/gem_why/dependent.rb
|
|
39
40
|
- lib/gem_why/formatters/base_formatter.rb
|
|
40
41
|
- lib/gem_why/formatters/deep_formatter.rb
|
|
41
42
|
- lib/gem_why/formatters/direct_formatter.rb
|