howzit 2.0.26 → 2.0.29
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/bin/howzit +11 -3
- data/lib/howzit/colors.rb +1 -1
- data/lib/howzit/config.rb +3 -1
- data/lib/howzit/prompt.rb +66 -38
- data/lib/howzit/task.rb +27 -21
- data/lib/howzit/topic.rb +28 -5
- data/lib/howzit/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e49b8c3399fb8c6aa96f857ea9dd77e8f91b1292783c0b25167ebf9aa380485
|
4
|
+
data.tar.gz: 9af75120a0e39cc371bf68f78335be3fcc8ea508e18c64fe5b94d1e9affec4a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f13f6c1d353c0ef3f8e041a0e3b2864ad808601c5aa4f3423d2830872e26650d29c33fce7b723489ac0557e314e17de8b3aba333a9692dda4e375bd372f17988
|
7
|
+
data.tar.gz: 9ebc50f699029414cd72d12ac83a591d6bcbe8f18f1cab175ea6bb81e40baf19b823129c7458947d6d9806448e1018209572f73271ca5c2398ba73f3fa9b9967
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
### 2.0.29
|
2
|
+
|
3
|
+
2022-08-30 04:20
|
4
|
+
|
5
|
+
#### NEW
|
6
|
+
|
7
|
+
- --yes flag will answer yes to all prompts when executing
|
8
|
+
- --force flag will continue executing directives after an error
|
9
|
+
|
10
|
+
#### IMPROVED
|
11
|
+
|
12
|
+
- A non-zero exit status on a run directive will stop processing additional directives
|
13
|
+
- A little extra output formatting, more descriptive results logging
|
14
|
+
|
15
|
+
### 2.0.28
|
16
|
+
|
17
|
+
2022-08-29 18:42
|
18
|
+
|
19
|
+
#### IMPROVED
|
20
|
+
|
21
|
+
- If a topic runs multiple directives, stop processing them if one returns a non-zero exit status
|
22
|
+
|
23
|
+
### 2.0.27
|
24
|
+
|
25
|
+
2022-08-23 12:25
|
26
|
+
|
27
|
+
#### IMPROVED
|
28
|
+
|
29
|
+
- Code cleanup
|
30
|
+
|
1
31
|
### 2.0.26
|
2
32
|
|
3
33
|
2022-08-23 11:36
|
data/bin/howzit
CHANGED
@@ -20,14 +20,16 @@ OptionParser.new do |opts|
|
|
20
20
|
|
21
21
|
opts.separator " Behavior:\n\n" #=================================================================== BEHAVIOR
|
22
22
|
|
23
|
-
opts.on('--ask', 'Request confirmation for all tasks when running a topic')
|
24
|
-
Howzit.options[:ask] = true
|
25
|
-
end
|
23
|
+
opts.on('--ask', 'Request confirmation for all tasks when running a topic') { Howzit.options[:ask] = true }
|
26
24
|
|
27
25
|
opts.on('--default', 'Answer all prompts with default response') do
|
26
|
+
raise '--default cannot be used with --yes' if Howzit.options[:yes]
|
27
|
+
|
28
28
|
Howzit.options[:default] = true
|
29
29
|
end
|
30
30
|
|
31
|
+
opts.on('-f', '--force', 'Continue executing after an error') { Howzit.options[:force] = true }
|
32
|
+
|
31
33
|
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
32
34
|
'Topics matching type', "(#{MATCHING_OPTIONS.join(', ')})") do |c|
|
33
35
|
Howzit.options[:matching] = c
|
@@ -42,6 +44,12 @@ OptionParser.new do |opts|
|
|
42
44
|
Howzit.options[:include_upstream] = p
|
43
45
|
end
|
44
46
|
|
47
|
+
opts.on('-y', '--yes', 'Answer yes to all prompts') do
|
48
|
+
raise '--default cannot be used with --yes' if Howzit.options[:default]
|
49
|
+
|
50
|
+
Howzit.options[:yes] = true
|
51
|
+
end
|
52
|
+
|
45
53
|
opts.separator "\n Listing:\n\n" #=================================================================== LISTING
|
46
54
|
|
47
55
|
opts.on('-L', '--list-completions', 'List topics (completion-compatible)') do
|
data/lib/howzit/colors.rb
CHANGED
@@ -227,7 +227,7 @@ module Howzit
|
|
227
227
|
def template(input)
|
228
228
|
input = input.join(' ') if input.is_a? Array
|
229
229
|
fmt = input.gsub(/%/, '%%')
|
230
|
-
fmt = fmt.gsub(
|
230
|
+
fmt = fmt.gsub(/(?<!\\u)\{(\w+)\}/i) do
|
231
231
|
Regexp.last_match(1).split('').map { |c| "%<#{c}>s" }.join('')
|
232
232
|
end
|
233
233
|
|
data/lib/howzit/config.rb
CHANGED
@@ -91,6 +91,7 @@ module Howzit
|
|
91
91
|
choose: false,
|
92
92
|
default: false,
|
93
93
|
for_topic: nil,
|
94
|
+
force: false,
|
94
95
|
grep: nil,
|
95
96
|
list_runnable: false,
|
96
97
|
list_runnable_titles: false,
|
@@ -99,7 +100,8 @@ module Howzit
|
|
99
100
|
quiet: false,
|
100
101
|
run: false,
|
101
102
|
title_only: false,
|
102
|
-
verbose: false
|
103
|
+
verbose: false,
|
104
|
+
yes: false
|
103
105
|
}
|
104
106
|
|
105
107
|
config = load_config
|
data/lib/howzit/prompt.rb
CHANGED
@@ -18,6 +18,8 @@ module Howzit
|
|
18
18
|
def yn(prompt, default: true)
|
19
19
|
return default unless $stdout.isatty
|
20
20
|
|
21
|
+
return true if Howzit.options[:yes]
|
22
|
+
|
21
23
|
return default if Howzit.options[:default]
|
22
24
|
|
23
25
|
tty_state = `stty -g`
|
@@ -87,60 +89,86 @@ module Howzit
|
|
87
89
|
return [] if !$stdout.isatty || matches.count.zero?
|
88
90
|
|
89
91
|
if Util.command_exist?('fzf')
|
90
|
-
height =
|
91
|
-
|
92
|
-
|
93
|
-
TTY::Screen.rows
|
94
|
-
end
|
95
|
-
|
96
|
-
settings = [
|
97
|
-
'-0',
|
98
|
-
'-1',
|
99
|
-
'-m',
|
100
|
-
"--height=#{height}",
|
101
|
-
'--header="Tab: add selection, ctrl-a/d: (de)select all, return: display/run"',
|
102
|
-
'--bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all',
|
103
|
-
'--prompt="Select a topic > "',
|
104
|
-
%(--preview="howzit --no-pager --header-format block --no-color --default --multiple first {}")
|
105
|
-
]
|
92
|
+
height = height == :auto ? matches.count + 3 : TTY::Screen.rows
|
93
|
+
|
94
|
+
settings = fzf_options(height)
|
106
95
|
res = `echo #{Shellwords.escape(matches.join("\n"))} | fzf #{settings.join(' ')}`.strip
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
96
|
+
return fzf_result(res)
|
97
|
+
end
|
98
|
+
|
99
|
+
tty_menu(matches)
|
100
|
+
end
|
101
|
+
|
102
|
+
def fzf_result(res)
|
103
|
+
if res.nil? || res.empty?
|
104
|
+
Howzit.console.info 'Cancelled'
|
105
|
+
Process.exit 0
|
112
106
|
end
|
107
|
+
return res.split(/\n/)
|
108
|
+
end
|
109
|
+
|
110
|
+
def fzf_options(height)
|
111
|
+
[
|
112
|
+
'-0',
|
113
|
+
'-1',
|
114
|
+
'-m',
|
115
|
+
"--height=#{height}",
|
116
|
+
'--header="Tab: add selection, ctrl-a/d: (de)select all, return: display/run"',
|
117
|
+
'--bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all',
|
118
|
+
'--prompt="Select a topic > "',
|
119
|
+
%(--preview="howzit --no-pager --header-format block --no-color --default --multiple first {}")
|
120
|
+
]
|
121
|
+
end
|
113
122
|
|
123
|
+
##
|
124
|
+
## Display a numeric menu on the TTY
|
125
|
+
##
|
126
|
+
## @param matches The matches from which to select
|
127
|
+
##
|
128
|
+
def tty_menu(matches)
|
114
129
|
return matches if matches.count == 1
|
115
130
|
|
116
|
-
|
117
|
-
stty_save = `stty -g`.chomp
|
131
|
+
@stty_save = `stty -g`.chomp
|
118
132
|
|
119
133
|
trap('INT') do
|
120
|
-
system('stty'
|
134
|
+
system('stty')
|
121
135
|
exit
|
122
136
|
end
|
123
137
|
|
124
138
|
options_list(matches)
|
139
|
+
read_selection(matches)
|
140
|
+
end
|
125
141
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
142
|
+
##
|
143
|
+
## Read a single number response from the command line
|
144
|
+
##
|
145
|
+
## @param matches The matches
|
146
|
+
##
|
147
|
+
def read_selection(matches)
|
148
|
+
printf "Type 'q' to cancel, enter for first item"
|
149
|
+
while (line = Readline.readline(': ', true))
|
150
|
+
line = read_num(line)
|
134
151
|
|
135
|
-
|
152
|
+
return [matches[line - 1]] if line.positive? && line <= matches.length
|
136
153
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
154
|
+
puts 'Out of range'
|
155
|
+
read_selection(matches)
|
156
|
+
end
|
157
|
+
ensure
|
158
|
+
system('stty', @stty_save)
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
## Convert a response to an Integer
|
163
|
+
##
|
164
|
+
## @param line The response to convert
|
165
|
+
##
|
166
|
+
def read_num(line)
|
167
|
+
if line =~ /^[a-z]/i
|
168
|
+
system('stty', @stty_save) # Restore
|
142
169
|
exit
|
143
170
|
end
|
171
|
+
line == '' ? 1 : line.to_i
|
144
172
|
end
|
145
173
|
end
|
146
174
|
end
|
data/lib/howzit/task.rb
CHANGED
@@ -19,6 +19,9 @@ module Howzit
|
|
19
19
|
## @option attributes :action [String] task action
|
20
20
|
## @option attributes :parent [String] title of nested (included) topic origin
|
21
21
|
def initialize(attributes, optional: false, default: true)
|
22
|
+
@prefix = "{bw}\u{25B7}\u{25B7} {x}"
|
23
|
+
# arrow = "{bw}\u{279F}{x}"
|
24
|
+
|
22
25
|
@type = attributes[:type] || :run
|
23
26
|
@title = attributes[:title] || nil
|
24
27
|
@action = attributes[:action].render_arguments || nil
|
@@ -49,18 +52,20 @@ module Howzit
|
|
49
52
|
## Execute a block type
|
50
53
|
##
|
51
54
|
def run_block
|
52
|
-
Howzit.console.info "{bg}Running block {bw}#{@title}{x}".c if Howzit.options[:log_level] < 2
|
55
|
+
Howzit.console.info "#{@prefix}{bg}Running block {bw}#{@title}{x}".c if Howzit.options[:log_level] < 2
|
53
56
|
block = @action
|
54
57
|
script = Tempfile.new('howzit_script')
|
55
58
|
begin
|
56
59
|
script.write(block)
|
57
60
|
script.close
|
58
61
|
File.chmod(0o777, script.path)
|
59
|
-
system(%(/bin/sh -c "#{script.path}"))
|
62
|
+
res = system(%(/bin/sh -c "#{script.path}"))
|
60
63
|
ensure
|
61
64
|
script.close
|
62
65
|
script.unlink
|
63
66
|
end
|
67
|
+
|
68
|
+
res
|
64
69
|
end
|
65
70
|
|
66
71
|
##
|
@@ -73,7 +78,7 @@ module Howzit
|
|
73
78
|
matches = Howzit.buildnote.find_topic(@action)
|
74
79
|
raise "Topic not found: #{@action}" if matches.empty?
|
75
80
|
|
76
|
-
Howzit.console.info("{by}Running tasks from {bw}#{matches[0].title}{x}".c)
|
81
|
+
Howzit.console.info("#{@prefix}{by}Running tasks from {bw}#{matches[0].title}{x}".c)
|
77
82
|
output.concat(matches[0].run(nested: true))
|
78
83
|
Howzit.console.info("{by}End include: #{matches[0].tasks.count} tasks{x}".c)
|
79
84
|
[output, matches[0].tasks.count]
|
@@ -84,8 +89,8 @@ module Howzit
|
|
84
89
|
##
|
85
90
|
def run_run
|
86
91
|
title = Howzit.options[:show_all_code] ? @action : @title
|
87
|
-
Howzit.console.info("{bg}Running {bw}#{title}{x}".c)
|
88
|
-
system(@action)
|
92
|
+
Howzit.console.info("#{@prefix}{bg}Running {bw}#{title}{x}".c)
|
93
|
+
return system(@action)
|
89
94
|
end
|
90
95
|
|
91
96
|
##
|
@@ -93,8 +98,9 @@ module Howzit
|
|
93
98
|
##
|
94
99
|
def run_copy
|
95
100
|
title = Howzit.options[:show_all_code] ? @action : @title
|
96
|
-
Howzit.console.info("{bg}Copied {bw}#{title}{bg} to clipboard{x}".c)
|
101
|
+
Howzit.console.info("#{@prefix}{bg}Copied {bw}#{title}{bg} to clipboard{x}".c)
|
97
102
|
Util.os_copy(@action)
|
103
|
+
return true
|
98
104
|
end
|
99
105
|
|
100
106
|
##
|
@@ -103,22 +109,22 @@ module Howzit
|
|
103
109
|
def run
|
104
110
|
output = []
|
105
111
|
tasks = 1
|
106
|
-
if @type == :block
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
112
|
+
res = if @type == :block
|
113
|
+
run_block
|
114
|
+
else
|
115
|
+
case @type
|
116
|
+
when :include
|
117
|
+
output, tasks = run_include
|
118
|
+
when :run
|
119
|
+
run_run
|
120
|
+
when :copy
|
121
|
+
run_copy
|
122
|
+
when :open
|
123
|
+
Util.os_open(@action)
|
124
|
+
end
|
125
|
+
end
|
120
126
|
|
121
|
-
[output, tasks]
|
127
|
+
[output, tasks, res]
|
122
128
|
end
|
123
129
|
|
124
130
|
##
|
data/lib/howzit/topic.rb
CHANGED
@@ -7,7 +7,7 @@ module Howzit
|
|
7
7
|
|
8
8
|
attr_accessor :content
|
9
9
|
|
10
|
-
attr_reader :title, :tasks, :prereqs, :postreqs
|
10
|
+
attr_reader :title, :tasks, :prereqs, :postreqs, :results
|
11
11
|
|
12
12
|
##
|
13
13
|
## Initialize a topic object
|
@@ -21,6 +21,7 @@ module Howzit
|
|
21
21
|
@parent = nil
|
22
22
|
@nest_level = 0
|
23
23
|
@tasks = gather_tasks
|
24
|
+
@results = { total: 0, success: 0, errors: 0, message: ''.c }
|
24
25
|
end
|
25
26
|
|
26
27
|
##
|
@@ -35,7 +36,7 @@ module Howzit
|
|
35
36
|
# Handle run command, execute directives in topic
|
36
37
|
def run(nested: false)
|
37
38
|
output = []
|
38
|
-
|
39
|
+
|
39
40
|
cols = begin
|
40
41
|
TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
|
41
42
|
rescue StandardError
|
@@ -63,14 +64,36 @@ module Howzit
|
|
63
64
|
next unless res
|
64
65
|
|
65
66
|
end
|
66
|
-
run_output, total = task.run
|
67
|
+
run_output, total, success = task.run
|
68
|
+
|
67
69
|
output.concat(run_output)
|
68
|
-
|
70
|
+
@results[:total] += total
|
71
|
+
|
72
|
+
if success
|
73
|
+
@results[:success] += total
|
74
|
+
else
|
75
|
+
Howzit.console.warn %({bw}\u{2297} {br}Error running task {bw}"#{task.title}"{x}).c
|
76
|
+
|
77
|
+
@results[:errors] += total
|
78
|
+
|
79
|
+
break unless Howzit.options[:force]
|
80
|
+
end
|
69
81
|
end
|
82
|
+
|
83
|
+
total = "{bw}#{@results[:total]}{by} #{@results[:total] == 1 ? 'task' : 'tasks'}".c
|
84
|
+
errors = "{bw}#{@results[:errors]}{by} #{@results[:errors] == 1 ? 'error' : 'errors'}".c
|
85
|
+
@results[:message] += if @results[:errors].zero?
|
86
|
+
"{bg}\u{2713} {by}Ran #{total}{x}"
|
87
|
+
elsif Howzit.options[:force]
|
88
|
+
"{br}\u{2715} {by}Completed #{total} with #{errors}{x}".c
|
89
|
+
else
|
90
|
+
"{br}\u{2715} {by}Ran #{total}, terminated due to error{x}".c
|
91
|
+
end
|
70
92
|
else
|
71
93
|
Howzit.console.warn "{r}--run: No {br}@directive{xr} found in {bw}#{@title}{x}".c
|
72
94
|
end
|
73
|
-
|
95
|
+
|
96
|
+
output.push(@results[:message]) if Howzit.options[:log_level] < 2 && !nested
|
74
97
|
|
75
98
|
puts TTY::Box.frame("{bw}#{@postreqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols) unless @postreqs.empty?
|
76
99
|
|
data/lib/howzit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: howzit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.29
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|