repo_dependency_graph 0.1.4 → 0.1.5
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/lib/repo_dependency_graph/version.rb +1 -1
- data/lib/repo_dependency_graph.rb +140 -23
- metadata +8 -30
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 578cc8fe75735e91415c393a959f0aad7df3a510
|
4
|
+
data.tar.gz: f2201b99a11c80a5d7d8d7b870c416dc1181c99b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6245f4ab5d69260041e10ec63614c78d5079eae348f19450d444f3a8bf2a7772daa8a40e5dd14791ed538cf2659766333ed4d057943257e75fd36bc928adc4c6
|
7
|
+
data.tar.gz: 9d3d92fe452b30a8d38cf7c23ab17345b60542dd58fafd53329883ff6107d0f1194fb3bea2fc5d64a658b68aebe27937f87e16516706a6c3603be610cd12c4e3
|
@@ -7,7 +7,8 @@ module RepoDependencyGraph
|
|
7
7
|
MAX_HEX = 255
|
8
8
|
|
9
9
|
def run(argv)
|
10
|
-
|
10
|
+
options = parse_options(argv)
|
11
|
+
draw(dependencies(options), options)
|
11
12
|
0
|
12
13
|
end
|
13
14
|
|
@@ -28,6 +29,7 @@ module RepoDependencyGraph
|
|
28
29
|
BANNER
|
29
30
|
opts.on("--token TOKEN", "Use token") { |token| options[:token] = token }
|
30
31
|
opts.on("--user USER", "Use user") { |user| options[:user] = user }
|
32
|
+
opts.on("--draw TYPE", "png, html, table (default: png)") { |draw| options[:draw] = draw }
|
31
33
|
opts.on("--organization ORGANIZATION", "Use organization") { |organization| options[:organization] = organization }
|
32
34
|
opts.on("--private", "Only show private repos") { options[:private] = true }
|
33
35
|
opts.on("--external", "Also include external projects in graph (can get super-messy)") { options[:external] = true }
|
@@ -42,6 +44,12 @@ module RepoDependencyGraph
|
|
42
44
|
opts.on("-h", "--help", "Show this.") { puts opts; exit }
|
43
45
|
opts.on("-v", "--version", "Show Version"){ puts RepoDependencyGraph::VERSION; exit}
|
44
46
|
end.parse!(argv)
|
47
|
+
|
48
|
+
options[:token] ||= begin
|
49
|
+
token = `git config github.token`.strip
|
50
|
+
token if $?.success?
|
51
|
+
end
|
52
|
+
|
45
53
|
options
|
46
54
|
end
|
47
55
|
|
@@ -50,26 +58,119 @@ module RepoDependencyGraph
|
|
50
58
|
result.empty? ? nil : result
|
51
59
|
end
|
52
60
|
|
53
|
-
def draw(dependencies)
|
54
|
-
|
61
|
+
def draw(dependencies, options)
|
62
|
+
case options[:draw]
|
63
|
+
when "html"
|
64
|
+
nodes, edges = convert_to_graphviz(dependencies)
|
65
|
+
html = <<-HTML.gsub(/^ /, "")
|
66
|
+
<!doctype html>
|
67
|
+
<html>
|
68
|
+
<head>
|
69
|
+
<title>Network</title>
|
70
|
+
<style>
|
71
|
+
#mynetwork {
|
72
|
+
width: 2000px;
|
73
|
+
height: 2000px;
|
74
|
+
border: 1px solid lightgray;
|
75
|
+
background: #F3F3F3;
|
76
|
+
}
|
77
|
+
</style>
|
55
78
|
|
56
|
-
|
79
|
+
<script type="text/javascript" src="http://visjs.org/dist/vis.js"></script>
|
80
|
+
<link href="http://visjs.org/dist/vis.css" rel="stylesheet" type="text/css" />
|
57
81
|
|
58
|
-
|
59
|
-
|
82
|
+
<script type="text/javascript">
|
83
|
+
var nodes = null;
|
84
|
+
var edges = null;
|
85
|
+
var network = null;
|
60
86
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
87
|
+
function draw() {
|
88
|
+
nodes = #{nodes.values.to_json};
|
89
|
+
edges = #{edges.to_json};
|
90
|
+
|
91
|
+
var container = document.getElementById('mynetwork');
|
92
|
+
var data = {
|
93
|
+
nodes: nodes,
|
94
|
+
edges: edges
|
95
|
+
};
|
96
|
+
var options = {stabilize: false};
|
97
|
+
|
98
|
+
new vis.Network(container, data, options);
|
99
|
+
}
|
100
|
+
</script>
|
101
|
+
</head>
|
102
|
+
|
103
|
+
<body onload="draw()">
|
104
|
+
<div id="mynetwork"></div>
|
105
|
+
</body>
|
106
|
+
</html>
|
107
|
+
HTML
|
108
|
+
File.write("out.html", html)
|
109
|
+
when "table"
|
110
|
+
tables = dependencies.map do |name, uses|
|
111
|
+
used = dependencies.map do |d, uses|
|
112
|
+
used = uses.detect { |d| d.first == name }
|
113
|
+
[d, used.last] if used
|
114
|
+
end.compact
|
115
|
+
size = [used.size, uses.size, 1].max
|
116
|
+
table = []
|
117
|
+
size.times do |i|
|
118
|
+
table[i] = [
|
119
|
+
(used[i] || []).join(": "),
|
120
|
+
(name if i == 0),
|
121
|
+
(uses[i] || []).join(": ")
|
122
|
+
]
|
123
|
+
end
|
124
|
+
table.unshift ["Used", "", "Uses"]
|
125
|
+
table
|
126
|
+
end
|
127
|
+
tables.map!{ |t| "<table>\n#{t.map{|t| "<tr>#{t.map{|t| "<td>#{t}</td>" }.join("")}</tr>" }.join("\n")}\n</table>" }
|
128
|
+
|
129
|
+
html = <<-HTML.gsub(/^ /, "")
|
130
|
+
<!doctype html>
|
131
|
+
<html>
|
132
|
+
<head>
|
133
|
+
<title>Network</title>
|
134
|
+
<style>
|
135
|
+
table { width: 600px; }
|
136
|
+
</style>
|
137
|
+
</head>
|
138
|
+
<body>
|
139
|
+
#{tables.join("<br>\n<br>\n")}
|
140
|
+
</body>
|
141
|
+
</html>
|
142
|
+
HTML
|
143
|
+
File.write("out.html", html)
|
144
|
+
else
|
145
|
+
nodes, edges = convert_to_graphviz(dependencies)
|
146
|
+
require 'graphviz'
|
147
|
+
g = GraphViz.new(:G, :type => :digraph)
|
148
|
+
|
149
|
+
nodes = Hash[nodes.map do |_, data|
|
150
|
+
node = g.add_node(data[:id], :color => data[:color], :style => "filled")
|
151
|
+
[data[:id], node]
|
152
|
+
end]
|
65
153
|
|
66
|
-
|
67
|
-
|
68
|
-
g.add_edge(nodes[name], nodes[dependency])
|
154
|
+
edges.each do |edge|
|
155
|
+
g.add_edge(nodes[edge[:from]], nodes[edge[:to]], :label => edge[:label])
|
69
156
|
end
|
157
|
+
|
158
|
+
g.output(:png => "out.png")
|
70
159
|
end
|
160
|
+
end
|
71
161
|
|
72
|
-
|
162
|
+
def convert_to_graphviz(dependencies)
|
163
|
+
counts = dependency_counts(dependencies)
|
164
|
+
range = counts.values.min..counts.values.max
|
165
|
+
nodes = Hash[counts.each_with_index.map do |(name, count), i|
|
166
|
+
[name, {:id => name, :color => color(count, range)}]
|
167
|
+
end]
|
168
|
+
edges = dependencies.map do |name, dependencies|
|
169
|
+
dependencies.map do |dependency, version|
|
170
|
+
{:from => nodes[name][:id], :to => nodes[dependency][:id], :label => (version || '')}
|
171
|
+
end
|
172
|
+
end.flatten
|
173
|
+
[nodes, edges]
|
73
174
|
end
|
74
175
|
|
75
176
|
def dependencies(options)
|
@@ -87,9 +188,9 @@ module RepoDependencyGraph
|
|
87
188
|
|
88
189
|
dependencies = all.map do |repo|
|
89
190
|
found = dependent_repos(repo, options) || []
|
90
|
-
found
|
191
|
+
found.select! { |f| possible.include?(f.first) } unless options[:external]
|
91
192
|
next if found.empty?
|
92
|
-
puts "#{repo.name}: #{found.join(", ")}"
|
193
|
+
puts "#{repo.name}: #{found.map { |n,v| "#{n}: #{v}" }.join(", ")}"
|
93
194
|
[repo.name, found]
|
94
195
|
end.compact
|
95
196
|
Hash[dependencies]
|
@@ -98,19 +199,35 @@ module RepoDependencyGraph
|
|
98
199
|
def dependent_repos(repo, options)
|
99
200
|
if options[:chef]
|
100
201
|
if content = repo.content("metadata.rb")
|
101
|
-
content
|
202
|
+
scan_chef_metadata(content)
|
102
203
|
end
|
103
204
|
else
|
104
205
|
if repo.gem? && spec = load_spec(repo.gemspec_content)
|
105
|
-
spec.runtime_dependencies.map
|
206
|
+
spec.runtime_dependencies.map do |d|
|
207
|
+
r = d.requirement.to_s
|
208
|
+
r = nil if r == ">= 0"
|
209
|
+
[d.name, r].compact
|
210
|
+
end
|
106
211
|
elsif content = repo.content("Gemfile.lock")
|
107
|
-
|
212
|
+
scan_gemfile_lock(content)
|
108
213
|
elsif content = repo.content("Gemfile")
|
109
|
-
content
|
214
|
+
scan_gemfile(content)
|
110
215
|
end
|
111
216
|
end
|
112
217
|
end
|
113
218
|
|
219
|
+
def scan_chef_metadata(content)
|
220
|
+
content.scan(/^\s*depends ['"](.*?)['"](?:,\s?['"](.*?)['"])?/).map(&:compact)
|
221
|
+
end
|
222
|
+
|
223
|
+
def scan_gemfile(content)
|
224
|
+
content.scan(/^\s*gem ['"](.*?)['"](?:,\s?['"](.*?)['"]|.*\bref(?::|\s*=>)\s*['"](.*)['"])?/).map(&:compact)
|
225
|
+
end
|
226
|
+
|
227
|
+
def scan_gemfile_lock(content)
|
228
|
+
Bundler::LockfileParser.new(content).specs.map { |d| [d.name, d.version.to_s] }
|
229
|
+
end
|
230
|
+
|
114
231
|
def load_spec(content)
|
115
232
|
eval content.
|
116
233
|
gsub(/^\s*require .*$/, "").
|
@@ -119,7 +236,7 @@ module RepoDependencyGraph
|
|
119
236
|
gsub(/(File|IO)\.read\(['"]VERSION.*?\)/, '"1.2.3"').
|
120
237
|
gsub(/(File|IO)\.read\(.*?\)/, '\' VERSION = "1.2.3"\'')
|
121
238
|
rescue Exception
|
122
|
-
puts "Error when parsing content:\n#{content}\n\n#{$!}"
|
239
|
+
$stderr.puts "Error when parsing content:\n#{content}\n\n#{$!}"
|
123
240
|
nil
|
124
241
|
end
|
125
242
|
|
@@ -135,9 +252,9 @@ module RepoDependencyGraph
|
|
135
252
|
end
|
136
253
|
|
137
254
|
def dependency_counts(dependencies)
|
138
|
-
all = (dependencies.keys + dependencies.values.
|
255
|
+
all = (dependencies.keys + dependencies.values.map { |v| v.map(&:first) }).flatten.uniq
|
139
256
|
Hash[all.map do |k|
|
140
|
-
[k, dependencies.values.count { |
|
257
|
+
[k, dependencies.values.map(&:first).count { |name, _| name == k } ]
|
141
258
|
end]
|
142
259
|
end
|
143
260
|
end
|
metadata
CHANGED
@@ -1,49 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: repo_dependency_graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
11
|
-
-
|
12
|
-
-----BEGIN CERTIFICATE-----
|
13
|
-
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdtaWNo
|
14
|
-
YWVsMRcwFQYKCZImiZPyLGQBGRYHZ3Jvc3NlcjESMBAGCgmSJomT8ixkARkWAml0
|
15
|
-
MB4XDTE0MDIwNDIwMjk0MVoXDTE1MDIwNDIwMjk0MVowPzEQMA4GA1UEAwwHbWlj
|
16
|
-
aGFlbDEXMBUGCgmSJomT8ixkARkWB2dyb3NzZXIxEjAQBgoJkiaJk/IsZAEZFgJp
|
17
|
-
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorXo/hgbUq97+kII9H
|
18
|
-
MsQcLdC/7wQ1ZP2OshVHPkeP0qH8MBHGg6eYisOX2ubNagF9YTCZWnhrdKrwpLOO
|
19
|
-
cPLaZbjUjljJ3cQR3B8Yn1veV5IhG86QseTBjymzJWsLpqJ1UZGpfB9tXcsFtuxO
|
20
|
-
6vHvcIHdzvc/OUkICttLbH+1qb6rsHUceqh+JrH4GrsJ5H4hAfIdyS2XMK7YRKbh
|
21
|
-
h+IBu6dFWJJByzFsYmV1PDXln3UBmgAt65cmCu4qPfThioCGDzbSJrGDGLmw/pFX
|
22
|
-
FPpVCm1zgYSb1v6Qnf3cgXa2f2wYGm17+zAVyIDpwryFru9yF/jJxE38z/DRsd9R
|
23
|
-
/88CAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFLIj
|
24
|
-
Z1x7SnjGGHK+MiVZkFjjS/iMMB0GA1UdEQQWMBSBEm1pY2hhZWxAZ3Jvc3Nlci5p
|
25
|
-
dDAdBgNVHRIEFjAUgRJtaWNoYWVsQGdyb3NzZXIuaXQwDQYJKoZIhvcNAQEFBQAD
|
26
|
-
ggEBAExBcUWfGuamYn+IddOA0Ws8jUKwB14RXoZRDrTiTAlMm3Bkg2OKyxS3uJXa
|
27
|
-
6Z+LwFiZwVYk62yHXqNzEJycQk4SEmY+xDWLj0p7X6qEeU4QZKwR1TwJ5z3PTrZ6
|
28
|
-
irJgM3q7NIBRvmTzRaAghWcQn+Eyr5YLOfMksjVBMUMnzh5/ZDgq53LphgJbGwvz
|
29
|
-
ScJAgfNclLHnjk9q1mT1s0e1FPWbiAL3siBIR5HpH8qtSEiivTf2ntciebOqS93f
|
30
|
-
F5etKHZg0j3eHO31/i2HnswY04lqGImUu6aM5EnijFTB7PPW2KwKKM4+kKDYFdlw
|
31
|
-
/0WV1Ng2/Y6qsHwmqGg2VlYj2h4=
|
32
|
-
-----END CERTIFICATE-----
|
33
|
-
date: 2014-02-04 00:00:00.000000000 Z
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-09-06 00:00:00.000000000 Z
|
34
12
|
dependencies:
|
35
13
|
- !ruby/object:Gem::Dependency
|
36
14
|
name: organization_audit
|
37
15
|
requirement: !ruby/object:Gem::Requirement
|
38
16
|
requirements:
|
39
|
-
- -
|
17
|
+
- - ">="
|
40
18
|
- !ruby/object:Gem::Version
|
41
19
|
version: '0'
|
42
20
|
type: :runtime
|
43
21
|
prerelease: false
|
44
22
|
version_requirements: !ruby/object:Gem::Requirement
|
45
23
|
requirements:
|
46
|
-
- -
|
24
|
+
- - ">="
|
47
25
|
- !ruby/object:Gem::Version
|
48
26
|
version: '0'
|
49
27
|
description:
|
@@ -66,17 +44,17 @@ require_paths:
|
|
66
44
|
- lib
|
67
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
68
46
|
requirements:
|
69
|
-
- -
|
47
|
+
- - ">="
|
70
48
|
- !ruby/object:Gem::Version
|
71
49
|
version: '0'
|
72
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
51
|
requirements:
|
74
|
-
- -
|
52
|
+
- - ">="
|
75
53
|
- !ruby/object:Gem::Version
|
76
54
|
version: '0'
|
77
55
|
requirements: []
|
78
56
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.
|
57
|
+
rubygems_version: 2.2.2
|
80
58
|
signing_key:
|
81
59
|
specification_version: 4
|
82
60
|
summary: Show the dependencies of your private repos
|
checksums.yaml.gz.sig
DELETED
Binary file
|
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
Binary file
|