Skip to content

Commit d0bce33

Browse files
committed
refactor(commands): rework list command with better options
1 parent 8d65bcb commit d0bce33

File tree

2 files changed

+45
-108
lines changed

2 files changed

+45
-108
lines changed

src/commands/list.cr

Lines changed: 44 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
{% skip_file %}
2-
31
module Geode::Commands
42
class List < Base
53
private class Entry
@@ -24,133 +22,72 @@ module Geode::Commands
2422
@name = "list"
2523
@summary = "list installed shards"
2624
@description = <<-DESC
27-
Lists the shards that have been installed. Due to the nature of the Shards CLI,
28-
transitive dependencies will also be listed even if they are not directly
29-
required by your project.
25+
Lists the shards that have been installed. By default this will only show direct
26+
dependencies listed in shard.yml, development dependencies can be shown by
27+
specifying the '--development' flag. Transitive dependencies (shards used by your
28+
dependencies) can be listed by specifying the '--transitive' flag. Untracked
29+
dependencies (shards that have been installed but aren't listed in shard.yml) can
30+
be listed by specifying the '--untracked' flag.
3031
DESC
3132

32-
add_option "tree", description: "list recursively in tree format"
33+
add_option 'd', "development"
34+
add_option 't', "transitive"
35+
add_option 'u', "untracked"
3336
end
3437

3538
def run(arguments : Cling::Arguments, options : Cling::Options) : Nil
36-
unless File.exists? "shard.yml"
37-
error ["A shard.yml file was not found", "Run 'geode init' to initialize one"]
38-
exit_program
39-
end
40-
return unless Dir.exists? "lib"
39+
ensure_local_shard_and_lib!
4140

4241
root = Shard.load_local
43-
entries = root.dependency_shards.map { |name, spec| Entry.new(name, spec.version, :direct) }
44-
entries.concat root.development_shards.map { |name, spec| Entry.new(name, spec.version, :development) }
45-
46-
deps = root.load_dependency_shards
47-
dev = root.load_development_shards
48-
entries = deps.map { |dep| Entry.new(dep.name, dep.version, :direct) }
49-
entries.concat dev.map { |dep| Entry.new(dep.name, dep.version, :development) }
50-
51-
untracked = [] of Entry
52-
Dir.each_child("lib") do |child|
53-
next if child.starts_with? '.'
54-
next unless File.exists?(path = Path["lib", child, "shard.yml"])
55-
56-
shard = Shard.from_yaml File.read path
57-
next if deps.find { |d| d.name == shard.name } || dev.find { |d| d.name == shard.name }
58-
59-
untracked << Entry.new(shard.name, shard.version, :untracked)
60-
end
61-
62-
unless untracked.empty?
63-
resolve_untracked root, entries, untracked
64-
entries.concat untracked
65-
end
66-
67-
# pp entries
68-
# return
69-
70-
str = String.build do |io|
71-
if options.has? "tree"
72-
deps.each do |spec|
73-
io << spec.name << ": " << spec.version << '\n'
74-
format(io, spec, 0)
75-
end
76-
77-
dev.each do |spec|
78-
io << spec.name << ": " << spec.version << " (development)".colorize.light_gray << '\n'
79-
format(io, spec, 0)
80-
end
81-
else
82-
untracked = [] of {String, String}
83-
Dir.each_child("lib") do |child|
84-
next if child.starts_with? '.'
85-
next if deps.find { |d| d.name == child } || dev.find { |d| d.name == child }
86-
next unless File.exists?(path = Path["lib", child, "shard.yml"])
42+
entries = [] of Entry
43+
development = options.has? "development"
44+
transitive = options.has? "transitive"
45+
untracked = options.has? "untracked"
8746

88-
shard = Shard.from_yaml File.read path
89-
untracked << {shard.name, shard.version}
90-
end
91-
92-
deps.each do |spec|
93-
io << spec.name << ": " << spec.version << '\n'
94-
end
95-
96-
dev.each do |spec|
97-
io << spec.name << ": " << spec.version << " (development)".colorize.light_gray << '\n'
98-
end
47+
root.dependency_shards.each do |name, shard|
48+
entries << Entry.new(name, shard.version, :direct)
9949

100-
untracked.each do |(name, version)|
101-
io << name << ": " << version << " (untracked)".colorize.yellow << '\n'
50+
if transitive
51+
shard.dependency_shards.each do |_, dep|
52+
entries << Entry.new(dep.name, dep.version, :transitive)
10253
end
10354
end
10455
end
10556

106-
stdout.puts str
107-
end
108-
109-
private def resolve_untracked(shard : Shard, resolved : Array(Entry), untracked : Array(Entry)) : Nil
110-
deps = shard.load_dependency_shards
111-
dev = shard.load_development_shards
112-
113-
untracked.each do |entry|
114-
deps.each do |dep|
115-
if dep.dependencies.has_key? name
116-
entry.kind = :transitive
117-
resolved << entry
118-
elsif dep.development.has_key? name
119-
entry.kind = :transitive
120-
resolved << entry
121-
end
122-
end
57+
root.development_shards.each do |name, shard|
58+
entries << Entry.new(name, shard.version, :development)
12359

124-
dev.each do |dep|
125-
if dep.dependencies.has_key? name
126-
entry.kind = :development
127-
resolved << entry
128-
elsif dep.development.has_key? name
129-
entry.kind = :development
130-
resolved << entry
60+
if transitive
61+
shard.development_shards.each do |_, dep|
62+
entries << Entry.new(dep.name, dep.version, :transitive)
13163
end
13264
end
13365
end
134-
end
13566

136-
private def format(io : IO, shard : Shard, level : Int32) : Nil
137-
io << " " * level
138-
deps = shard.load_dependency_shards
139-
dev = shard.load_development_shards
67+
Dir.each_child("lib") do |child|
68+
next if child.starts_with? '.'
69+
next unless Shard.exists? child
14070

141-
deps.each do |spec|
142-
io << "" << spec.name << ": " << spec.version << '\n'
71+
shard = Shard.load child
72+
entry = Entry.new(shard.name, shard.version, :untracked)
73+
next if entries.includes? entry
14374

144-
if spec.dependencies.size > 0 || spec.development.size > 0
145-
format(io, spec, level + 2)
146-
end
75+
entries << entry
14776
end
14877

149-
dev.each do |spec|
150-
io << "" << spec.name << ": " << spec.version << " (development)".colorize.light_gray << '\n'
151-
152-
if spec.dependencies.size > 0 || spec.development.size > 0
153-
format(io, spec, level + 2)
78+
entries.each do |entry|
79+
if entry.kind.direct? ||
80+
(development && entry.kind.development?) ||
81+
(transitive && entry.kind.transitive?) ||
82+
(untracked && entry.kind.untracked?)
83+
stdout << "" if entry.kind.transitive?
84+
stdout << entry.name << ": " << entry.version
85+
case entry.kind
86+
when .development? then stdout << " (development)".colorize.light_gray
87+
when .transitive? then stdout << " (transitive)".colorize.light_gray
88+
when .untracked? then stdout << " (untracked)".colorize.yellow
89+
end
90+
stdout << '\n'
15491
end
15592
end
15693
end

src/geode.cr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ module Geode
4444
# add_command Commands::Vendor.new
4545
add_command Commands::Remove.new
4646
# add_command Commands::Prune.new
47-
# add_command Commands::List.new
47+
add_command Commands::List.new
4848
add_command Commands::Info.new
4949
add_command Commands::Licenses.new
5050
add_command Commands::Run.new

0 commit comments

Comments
 (0)