Skip to content

Commit 1a93f43

Browse files
committed
Initial commit.
0 parents  commit 1a93f43

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

PodTree.rb

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/bin/ruby
2+
3+
# Created by Vyacheslav Khorkov on 17.07.2020.
4+
# Copyright © 2020 Vyacheslav Khorkov. All rights reserved.
5+
6+
require 'set'
7+
8+
# Constants
9+
OUTPUT_BULLET = "•"
10+
OUTPUT_BULLET_COLORS = [9, 3, 2, 75, 99]
11+
12+
# Help information
13+
HELP_COMMANDS = ["-h", "--help", "help"]
14+
def putsHelp()
15+
puts "Tiny utility for visualise Pod dependencies tree.".colorize(2)
16+
puts "Skips subspecs and pods without versions.".colorize(2)
17+
puts "Help options: #{HELP_COMMANDS}"
18+
puts " • 1st argument will be used as root Pod".colorize(3)
19+
puts " • 2nd one is path to Podfile (pwd by default)\n".colorize(3)
20+
puts "ruby PodTree.rb A Podfile.lock".colorize(3)
21+
puts "Podfile.lock:".colorize(2) + " Output:".colorize(2)
22+
margin = " "
23+
puts "- A (1.0.0)" + margin + "•".colorize(9) + " A"
24+
puts "- B (1.0.0):" + margin + " •".colorize(3) + " D"
25+
puts " - A (= 1.0.0)" + margin + "•".colorize(2) + " C"
26+
puts " - C (= 1.0.0)" + margin + " •".colorize(75) + " B"
27+
puts " - D (= 1.0.0)" + margin + "•".colorize(2) + " E"
28+
puts "- C (1.0.0):"
29+
puts " - A (= 1.0.0)"
30+
puts " - D (= 1.0.0)"
31+
puts "- D (1.0.0):"
32+
puts " - A (= 1.0.0)"
33+
puts "- E (1.0.0):"
34+
puts " - A (= 1.0.0)"
35+
puts " - D (= 1.0.0)"
36+
end
37+
38+
# Class describing Pod
39+
class Pod
40+
attr_reader :name, :parents, :children
41+
def initialize(name)
42+
@name = name
43+
@parents = Set.new; @children = Set.new
44+
end
45+
end
46+
47+
# Parsing
48+
def parsePodfile(pod_file)
49+
currentPod = nil
50+
pods = Hash.new
51+
File.readlines(pod_file).each do |line|
52+
next if line.start_with?("PODS:")
53+
break if line.start_with?("DEPENDENCIES:")
54+
55+
if line.start_with?(" -") # Parents
56+
parts = line.split(" ")
57+
name = parts[1].split("/")[0]
58+
59+
unless pods.has_key?(name)
60+
pods[name] = Pod.new(name)
61+
end
62+
currentPod = pods[name]
63+
elsif line.start_with?(" -") # Childs
64+
parts = line.split(" ")
65+
next if parts.count == 2 # Skip without version
66+
name = parts[1].split("/")[0]
67+
68+
unless pods.has_key?(name)
69+
pods[name] = Pod.new(name)
70+
end
71+
pods[name].parents.add(currentPod)
72+
currentPod.children.add(pods[name])
73+
end
74+
end
75+
return pods
76+
end
77+
78+
# Create dependecies tree
79+
def buildTree(pods, pod_name)
80+
root = Pod.new(pod_name)
81+
last = { root.name => root }
82+
83+
names = pods[pod_name].parents.map { |pod| pod.name }.to_set
84+
names.delete(pod_name)
85+
while !names.empty? do
86+
step = Set.new
87+
88+
# Calculate step
89+
names.each { |name|
90+
podNames = pods[name].children.map { |pod| pod.name }.to_set
91+
podNames.delete(name) # Remove subspecs intersection
92+
if podNames.intersection(names).empty?
93+
step.add(name)
94+
end
95+
}
96+
if step.empty?
97+
STDERR.puts("Can't build a step.".colorize(9))
98+
exit(false)
99+
end
100+
101+
# Build tree level
102+
new = Hash.new
103+
step.each { |name|
104+
pods[name].children.each { |pod|
105+
if last.has_key?(pod.name)
106+
newPod = Pod.new(name)
107+
last[pod.name].children.add(newPod)
108+
new[name] = newPod
109+
end
110+
}
111+
}
112+
last = new
113+
names.subtract(step)
114+
end
115+
return root
116+
end
117+
118+
# Colorize output
119+
class String
120+
def colorize(color_code)
121+
"\e[38;5;#{color_code}m#{self}\e[0m"
122+
end
123+
end
124+
125+
# Output tree recursively
126+
def putsTree(root, level = 0, bullet, colors)
127+
if level != 0
128+
prefix = " " * (level - 1) + bullet
129+
color = colors[(level - 1) % colors.count]
130+
puts prefix.colorize(color) + " " + root.name
131+
end
132+
root.children.each { |pod|
133+
putsTree(pod, level + 1, bullet, colors)
134+
}
135+
end
136+
137+
# === Main ===
138+
# Check if 1st argument is help
139+
if HELP_COMMANDS.include?ARGV[0]
140+
putsHelp()
141+
exit(false)
142+
end
143+
144+
# Get input arguments
145+
POD_NAME = ARGV[0]
146+
POD_FILE = ARGV[1] || "Podfile.lock"
147+
148+
# Parse Podfile
149+
PODS = parsePodfile(POD_FILE)
150+
unless PODS.has_key?(POD_NAME)
151+
STDERR.puts("Can't find pod name.".colorize(9))
152+
putsHelp()
153+
exit(false)
154+
end
155+
156+
# Build and output tree
157+
TREE = buildTree(PODS, POD_NAME)
158+
putsTree(TREE, 1, OUTPUT_BULLET, OUTPUT_BULLET_COLORS)

Preview.png

65.7 KB
Loading

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<img src="https://github.com/swiftyfinch/PodTree/blob/main/Preview.png" width="430"/>
2+
3+
🌳 Tiny utility for visualising [#CocoaPods](https://github.com/CocoaPods/CocoaPods) dependencies tree.
4+
5+
## Author
6+
7+
Vyacheslav Khorkov\
8+
Twitter: [@SwiftyFinch](https://twitter.com/swiftyfinch)\
9+
Blog: [swiftyfinch.github.io](https://swiftyfinch.github.io/en)\
10+
Feel free to contact me for any questions.

0 commit comments

Comments
 (0)