dsu 0.1.0.alpha.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../ask'
4
- require_relative '../colorable'
5
- require_relative '../say'
6
-
7
- module Dsu
8
- module Interactive
9
- class Cli
10
- include Support::Colorable
11
- include Support::Ask
12
- include Support::Say
13
-
14
- BACK_COMMANDS = %w[b].freeze
15
- EXIT_COMMANDS = %w[x].freeze
16
- HELP_COMMANDS = %w[?].freeze
17
- PROMPT_TOKEN = '>'
18
-
19
- attr_reader :name, :parent, :prompt
20
-
21
- def initialize(name:, parent: nil, **options)
22
- @name = name
23
- @parent = parent
24
- @prompt = options[:prompt]
25
- end
26
-
27
- # Starts our interactive loop.
28
- def start
29
- help
30
- process_commands
31
- end
32
-
33
- def process(command:)
34
- if command.cancelled?
35
- nil
36
- elsif help?(command.command)
37
- help
38
- elsif back_or_exit?(command.command)
39
- parent&.help
40
- else
41
- unrecognized_command command.command
42
- end
43
- end
44
-
45
- # Dispays the full help; header and body.
46
- def help
47
- help_header
48
- help_body
49
- end
50
-
51
- private
52
-
53
- # This is our interaction loop. Commands that are NOT help or
54
- # back or exit commands are yielded to the subclass to execute. Help
55
- # commands simply display help; back (or exit) commands transfer control
56
- # back to the parent cli (if parent? is true) or exits the current
57
- # cli (if parent? is false) respectfully.
58
- def process_commands
59
- loop do
60
- command = wrap_command(ask)
61
- process(command: command)
62
- next if command.cancelled?
63
- break if back_or_exit?(command.command)
64
- end
65
- say 'Done.', ABORTED unless parent?
66
- end
67
-
68
- def wrap_command(command)
69
- Struct.new(:command, :args, :cancelled, keyword_init: true) do
70
- def cancelled?
71
- cancelled
72
- end
73
-
74
- def cancelled!
75
- self[:cancelled] = true
76
- end
77
- end.new(
78
- command: command.split[0],
79
- args: command.split[1..],
80
- cancelled: false
81
- )
82
- end
83
-
84
- # This is the full prompt that needs to be displayed that includes
85
- # all parent prompts, right down to the current prompt.
86
- def full_prompt
87
- prompts = full_prompt_build prompts: []
88
- prompt_token = "#{PROMPT_TOKEN} "
89
- "#{prompts.join prompt_token}#{prompt_token}"
90
- end
91
-
92
- def parent?
93
- !parent.nil?
94
- end
95
-
96
- def back?(command)
97
- back_commands.include? command
98
- end
99
-
100
- def back_commands
101
- @back_commands ||= BACK_COMMANDS
102
- end
103
-
104
- def exit?(command)
105
- exit_commands.include? command
106
- end
107
-
108
- def exit_commands
109
- @exit_commands ||= EXIT_COMMANDS
110
- end
111
-
112
- def back_or_exit?(command)
113
- (back_commands + exit_commands).include? command
114
- end
115
-
116
- def help?(command)
117
- help_commands.include? command
118
- end
119
-
120
- # Returns what are considered to be commands associated with
121
- # displaying help.
122
- def help_commands
123
- @help_commands ||= HELP_COMMANDS
124
- end
125
-
126
- # Displays the help header; override this if you want to customize
127
- # your own help header in your subclass.
128
- def help_header
129
- say "#{name} Help", HIGHLIGHT
130
- say '---', HIGHLIGHT
131
- end
132
-
133
- # Override this in your subclass and call super AFTER you've
134
- # displayed your subclass' help body.
135
- def help_body
136
- say "[#{HELP_COMMANDS.join(' | ')}] Display help", HIGHLIGHT
137
- say "[#{BACK_COMMANDS.join(' | ')}] Go back", HIGHLIGHT if parent?
138
- say "[#{EXIT_COMMANDS.join(' | ')}] Exit", HIGHLIGHT unless parent?
139
- end
140
-
141
- # This simply outputs our prompt and accepts user input.
142
- def ask
143
- super full_prompt
144
- end
145
-
146
- def unrecognized_command(command)
147
- say "Unrecognized command (\"#{command}\"). Try again.", ERROR
148
- end
149
-
150
- # Builds the full prompt to be used which amounts to:
151
- # <parent cli prompt> PROMPT_TOKEN <child cli 1 prompt>
152
- # PROMPT_TOKEN <child 2 cli prompt> ...
153
- def full_prompt_build(prompts:)
154
- parent.send(:full_prompt_build, prompts: prompts) if parent?
155
-
156
- prompts << prompt
157
- prompts.flatten
158
- end
159
- end
160
- end
161
- end