bundler-why-plugin 0.1.1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c92de18137a085d1c696e351c029f6b22ccc5a42949c65052082bb43aa2fc753
4
- data.tar.gz: ae5ffde7a03f7282c007af427d9d08c64ea80243b17e7d1d53667e07b3347b64
3
+ metadata.gz: 784f40795674686c348fa654e902d7ac6be67ecbb8b6654a75b85e2cc26f9b62
4
+ data.tar.gz: b9a7569b7fac61fe2286ba607d5389666c83600d4f2879c37680122edf15b546
5
5
  SHA512:
6
- metadata.gz: 2287fb636728d1d51a50916c9d16e0756c88e88e0d422b8c9462d3f6c4266675c6fce29a231b9cbd8397f809724967a58657a598478a4a317af9e637713b3a8c
7
- data.tar.gz: 1a011fce3cf92df2469c068c00fd125274dfd18326406b900e5206fbd6424d611921d707f70dc6a62119b9a702d95008ac9f2a05f8f62e16681ca09c601c173c
6
+ metadata.gz: a3861d7d00e459bb6be4d23ed3bb091170b8560f007490c1edd66451262e6857fa5015741f0beb23f4513f26a6128c96d92f7391414a3836bbeb6ea5fba3582b
7
+ data.tar.gz: 80391cd81cb103720e315dc80ae04cd25abab120653e5467b0b1463f350f6037d8cb37309e801f5c96a9fb1c1c925346bdb9a2e917224acb35c6b28b4a05f587
@@ -19,7 +19,7 @@ module Bundler
19
19
  first = given_args.first
20
20
  known = tasks.keys + %w[help]
21
21
  if known.include?(first)
22
- super(given_args, config)
22
+ super
23
23
  else
24
24
  super(["why"] + given_args, config)
25
25
  end
@@ -41,6 +41,9 @@ module Bundler
41
41
  exit 1
42
42
  end
43
43
 
44
+ # ツリー構造を追加
45
+ result[:dependents_tree] = resolver.build_dependents_tree(package_name)
46
+
44
47
  display_result(result, resolver)
45
48
  end
46
49
 
@@ -54,33 +57,20 @@ module Bundler
54
57
  Bundler.ui.info("#{result[:name]} (#{result[:version]})")
55
58
  Bundler.ui.info("")
56
59
 
57
- # 依存関係チェーンを表示
58
- chains = resolver.find_dependency_chain(result[:name])
59
-
60
- if chains.any?
61
- Bundler.ui.info("Used by:")
62
- chains.each do |chain|
63
- chain_str = chain.join(" > ")
64
- Bundler.ui.info(" #{chain_str}")
65
- end
60
+ # ツリー形式で依存関係を表示
61
+ dependents_tree = result[:dependents_tree]
62
+ if dependents_tree.any?
63
+ Bundler.ui.info("Directly required by:")
64
+ display_tree(dependents_tree, " ")
66
65
  else
67
- # 直接の依存元を表示
68
- direct_dependents = result[:direct_dependents]
69
- if direct_dependents.any?
70
- Bundler.ui.info("Directly required by:")
71
- direct_dependents.each do |dependent|
72
- Bundler.ui.info(" #{dependent[:name]} (#{dependent[:version]}) [#{dependent[:requirement]}]")
66
+ Bundler.ui.info("Required by:")
67
+ all_dependents = result[:all_dependents]
68
+ if all_dependents.any?
69
+ all_dependents.each do |dependent|
70
+ Bundler.ui.info(" #{dependent[:name]} (#{dependent[:version]})")
73
71
  end
74
72
  else
75
- Bundler.ui.info("Required by:")
76
- all_dependents = result[:all_dependents]
77
- if all_dependents.any?
78
- all_dependents.each do |dependent|
79
- Bundler.ui.info(" #{dependent[:name]} (#{dependent[:version]})")
80
- end
81
- else
82
- Bundler.ui.warn("Not required by any other packages (may be a direct dependency)")
83
- end
73
+ Bundler.ui.warn("Not required by any other packages (may be a direct dependency)")
84
74
  end
85
75
  end
86
76
 
@@ -89,6 +79,20 @@ module Bundler
89
79
  Bundler.ui.info("Location: #{result[:path]}")
90
80
  end
91
81
  end
82
+
83
+ def display_tree(items, prefix = "")
84
+ items.each_with_index do |item, index|
85
+ is_last = index == items.length - 1
86
+ current_prefix = is_last ? "└── " : "├── "
87
+ next_prefix = is_last ? " " : "│ "
88
+
89
+ Bundler.ui.info("#{prefix}#{current_prefix}#{item[:name]} (#{item[:version]}) [#{item[:requirement]}]")
90
+
91
+ if item[:children] && item[:children].any?
92
+ display_tree(item[:children], prefix + next_prefix)
93
+ end
94
+ end
95
+ end
92
96
  end
93
97
  end
94
98
  end
@@ -32,7 +32,7 @@ module Bundler
32
32
  # 直接的な依存元(親)を取得
33
33
  def find_direct_dependents(spec)
34
34
  dependents = []
35
-
35
+
36
36
  @specs.each do |other_spec|
37
37
  other_spec.dependencies.each do |dep|
38
38
  if dep.name == spec.name
@@ -44,7 +44,7 @@ module Bundler
44
44
  end
45
45
  end
46
46
  end
47
-
47
+
48
48
  dependents
49
49
  end
50
50
 
@@ -78,26 +78,99 @@ module Bundler
78
78
  end
79
79
  end
80
80
 
81
- # 依存関係チェーンを取得
81
+ # 依存関係チェーンを取得(Gemfileに書かれたgemまで遡る)
82
82
  def find_dependency_chain(target_name)
83
83
  spec = find_spec(target_name)
84
- return nil unless spec
84
+ return [] unless spec
85
85
 
86
86
  chains = []
87
-
88
- # Gemfileの直接の依存関係を確認
89
- @definition.dependencies.each do |dep|
90
- if is_dependency_of?(target_name, dep.name)
91
- chain = trace_chain(dep.name, target_name, [dep.name])
92
- chains << chain if chain
87
+ gemfile_dependencies = @definition.dependencies.map(&:name)
88
+
89
+ # 直接の依存元を探す
90
+ direct_dependents = find_direct_dependents(spec)
91
+
92
+ direct_dependents.each do |dependent|
93
+ # 依存元がGemfileに記載されているかチェック
94
+ if gemfile_dependencies.include?(dependent[:name])
95
+ chains << [dependent[:name], target_name]
96
+ else
97
+ # 依存元をさらに遡る
98
+ parent_chains = find_dependency_chain_recursive(dependent[:name], [target_name], gemfile_dependencies)
99
+ chains.concat(parent_chains)
93
100
  end
94
101
  end
95
102
 
96
- chains
103
+ chains.uniq
104
+ end
105
+
106
+ # Gemfileのdependenciesを取得
107
+ def gemfile_dependencies
108
+ @definition.dependencies.map(&:name)
109
+ end
110
+
111
+ # 依存関係ツリーを構築(各ノードの子を取得)
112
+ def build_dependents_tree(spec_name, visited = Set.new, depth = 0)
113
+ return [] if visited.include?(spec_name) || depth > 10
114
+
115
+ visited.add(spec_name)
116
+ spec = find_spec(spec_name)
117
+ return [] unless spec
118
+
119
+ direct_dependents = []
120
+ @specs.each do |other_spec|
121
+ other_spec.dependencies.each do |dep|
122
+ if dep.name == spec_name
123
+ direct_dependents << {
124
+ name: other_spec.name,
125
+ version: other_spec.version.to_s,
126
+ requirement: dep.requirement.to_s,
127
+ children: build_dependents_tree(other_spec.name, visited.dup, depth + 1)
128
+ }
129
+ end
130
+ end
131
+ end
132
+
133
+ direct_dependents
97
134
  end
98
135
 
99
136
  private
100
137
 
138
+ # 依存関係チェーンを再帰的に遡る
139
+ def find_dependency_chain_recursive(current_name, path, gemfile_deps)
140
+ chains = []
141
+
142
+ # 循環参照を防ぐため、すでにpathに含まれている場合は処理しない
143
+ return chains if path.include?(current_name)
144
+
145
+ current_spec = find_spec(current_name)
146
+ return chains unless current_spec
147
+
148
+ # 現在のgemの依存元を取得
149
+ direct_dependents = find_direct_dependents(current_spec)
150
+
151
+ if direct_dependents.empty?
152
+ # 依存元がない場合でも、Gemfileに記載されていれば追加
153
+ if gemfile_deps.include?(current_name)
154
+ chains << ([current_name] + path)
155
+ end
156
+ else
157
+ direct_dependents.each do |dependent|
158
+ new_path = [current_name] + path
159
+
160
+ if gemfile_deps.include?(dependent[:name])
161
+ # Gemfileに記載されているgemに到達したらチェーンを確定
162
+ chains << ([dependent[:name]] + new_path)
163
+ else
164
+ # さらに親を遡る
165
+ parent_chains = find_dependency_chain_recursive(dependent[:name], new_path, gemfile_deps)
166
+ chains.concat(parent_chains)
167
+ end
168
+ end
169
+ end
170
+
171
+ chains
172
+ end
173
+
101
174
  # targetが sourceの依存関係にあるかチェック
102
175
  def is_dependency_of?(target, source)
103
176
  source_spec = find_spec(source)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Bundler
4
4
  module Why
5
- VERSION = "0.1.1"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler-why-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi SHIBATA