-
-
Notifications
You must be signed in to change notification settings - Fork 154
/
Copy pathcommand.cr
110 lines (91 loc) · 3.04 KB
/
command.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
module Mint
class Cli < Admiral::Command
module Command
include Errorable
def execute(
message : String,
*,
check_dependencies : Bool = false,
env : String? = nil,
& : -> T
) : T? forall T
# On Ctrl+C and abort and exit.
Process.on_terminate do
terminal.puts
terminal.divider
terminal.puts "Aborted! Exiting..."
exit(1)
end
# Print header and divider.
terminal.header "Mint - #{message}"
terminal.divider
# Save terminal position in order to render divider in
# case of an error.
position =
terminal.position
# Have a variable for the result of the command.
result = nil
begin
check_dependencies! if check_dependencies
# Measure elapsed time of a command.
elapsed = Time.measure { result = yield }
rescue error : Error
# In case of an error print it.
error error.to_terminal, position
rescue exception : Exception
# In case of an exception print it.
error exception.inspect_with_backtrace, position
end
# Format the elapsed time into a human readable format.
formatted =
TimeFormat.auto(elapsed).colorize.mode(:bold)
# Print all done mssage.
terminal.divider
terminal.puts "All done in #{formatted}!"
result
end
# Handles an error.
def error(message, position)
# Check if the command printed anything (last position of the IO is not
# the current one).
printed =
terminal.position != position
# If printed we need to print a divider.
if printed
terminal.puts
terminal.divider
end
# If we have a message we need to print it and a divider.
if message
terminal.puts
terminal.print message
terminal.divider
end
terminal.puts "There was an error, exiting...".colorize.mode(:bold)
# Exit with one to trigger failures in CI environments.
exit(1)
end
def check_dependencies!
MintJson.current.dependencies.each do |dependency|
next if Dir.exists?(".mint/packages/#{dependency.name}")
terminal.puts "#{COG} Ensuring dependencies..."
terminal.puts " ↳ Not all dependencies in your mint.json file are installed."
terminal.puts " Would you like to install them now? (Y/n)"
# Accept 'Y', 'y' or empty string (Enter) as affirmative response
# Empty string is treated as 'Y' since Y is the default option
answer = gets.to_s.strip.downcase
terminal.puts AnsiEscapes::Erase.lines(2)
if answer.empty? || answer == "y"
Installer.new
break
else
error "#{WARNING} Missing dependencies...", terminal.position
end
end
end
def terminal
Render::Terminal::STDOUT
end
end
end
end