howzit 2.0.10 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +8 -0
- data/fish/completions/howzit.fish +34 -2
- data/lib/howzit/buildnote.rb +4 -27
- data/lib/howzit/hash.rb +23 -2
- data/lib/howzit/prompt.rb +37 -2
- data/lib/howzit/stringutils.rb +130 -3
- data/lib/howzit/task.rb +9 -6
- data/lib/howzit/topic.rb +51 -6
- data/lib/howzit/util.rb +25 -0
- data/lib/howzit/version.rb +1 -1
- data/spec/task_spec.rb +6 -1
- metadata +1 -3
- data/spec/buildnotes.md.bak +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 700ee2e9d73bdfcfeea142ed992c442119513428c7f4ceca415df2c3c792c844
|
4
|
+
data.tar.gz: c13005486bfac3f5add20bc1076a89f5b9cfad43288c9d5661d059d35271f1d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd6f68ba71489fcc87a9cc833ba7ab1c28fa0e680d12f92f09cf59e82bb1e289390a75631a69437c9f1f64e3f0dad470f7c783f5200affdad78e96cec14e35bc
|
7
|
+
data.tar.gz: 9eec9ae3a192de290026b129c81d97ec2a76940e14ea3f958b60e899bbb8a2951923cbf0186a9cecf4a0dae471a46cdc144157aa85df8d764026af70911bbdd2
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
1
|
complete -xc howzit -a "(howzit -L)"
|
2
|
-
complete -
|
3
|
-
|
2
|
+
complete -c howzit -l default -d "Answer all prompts with default response"
|
3
|
+
complete -c howzit -x -s m -l matching -a "partial exact fuzzy beginswith" -d "Topics matching type"
|
4
|
+
complete -c howzit -x -l multiple -a "first best all choose" -d "Multiple result handling"
|
5
|
+
complete -c howzit -s u -l no-upstream -d "Don't traverse up parent directories for additional build notes"
|
6
|
+
complete -c howzit -s u -l upstream -d "Traverse up parent directories for additional build notes"
|
7
|
+
complete -c howzit -s L -l list-completions -d "List topics for completion"
|
8
|
+
complete -c howzit -s l -l list -d "List available topics"
|
9
|
+
complete -c howzit -s R -l list-runnable -d "List topics containing @ directives (verbose)"
|
10
|
+
complete -c howzit -s T -l task-list -d "List topics containing @ directives (completion-compatible)"
|
11
|
+
complete -c howzit -l templates -d "List available templates"
|
12
|
+
complete -c howzit -l title-only -d "Output title only"
|
13
|
+
complete -c howzit -s c -l create -d "Create a skeleton build note in the current working directory"
|
14
|
+
complete -c howzit -f -l config-get -d "Display the configuration settings or setting for a specific key"
|
15
|
+
complete -c howzit -f -l config-set -d "Set a config value (must be a valid key)"
|
16
|
+
complete -c howzit -l edit-config -d "Edit configuration file using editor (subl)"
|
17
|
+
complete -c howzit -s e -l edit -d "Edit buildnotes file in current working directory using editor (subl)"
|
18
|
+
complete -c howzit -x -l grep -d "Display sections matching a search pattern"
|
19
|
+
complete -c howzit -s r -l run -a "(howzit -T)" -d "Execute @run, @open, and/or @copy commands for given topic"
|
20
|
+
complete -c howzit -s s -l select -d "Select topic from menu"
|
21
|
+
complete -c howzit -l color -d "Colorize output (default on)"
|
22
|
+
complete -c howzit -l no-color -d "Don't colorize output (default on)"
|
23
|
+
complete -c howzit -x -l header-format -d "Formatting style for topic titles (border, block)"
|
24
|
+
complete -c howzit -l md-highlight -d "Highlight Markdown syntax (default on), requires mdless or mdcat"
|
25
|
+
complete -c howzit -l no-md-highlight -d "Don't highlight Markdown syntax (default on), requires mdless or mdcat"
|
26
|
+
complete -c howzit -l pager -d "Paginate output (default on)"
|
27
|
+
complete -c howzit -l no-pager -d "Don't paginate output (default on)"
|
28
|
+
complete -c howzit -l show-code -d "Display the content of fenced run blocks"
|
29
|
+
complete -c howzit -s t -l title -d "Output title with build notes"
|
30
|
+
complete -c howzit -x -s w -l wrap -d "Wrap to specified width (default 80, 0 to disable)"
|
31
|
+
complete -c howzit -s d -l debug -d "Show debug messages (and all messages)"
|
32
|
+
complete -c howzit -s q -l quiet -d "Silence info message"
|
33
|
+
complete -c howzit -l verbose -d "Show all messages"
|
34
|
+
complete -c howzit -s h -l help -d "Display this screen"
|
35
|
+
complete -c howzit -s v -l version -d "Display version number"
|
data/lib/howzit/buildnote.rb
CHANGED
@@ -120,7 +120,7 @@ module Howzit
|
|
120
120
|
|
121
121
|
##
|
122
122
|
## Return a formatted list of topics containing
|
123
|
-
##
|
123
|
+
## directives suitable for console output
|
124
124
|
##
|
125
125
|
## @return [String] formatted list
|
126
126
|
##
|
@@ -275,38 +275,15 @@ module Howzit
|
|
275
275
|
buildnotes.reverse
|
276
276
|
end
|
277
277
|
|
278
|
-
##
|
279
|
-
## Test if the filename matches the conditions to be a build note
|
280
|
-
##
|
281
|
-
## @param filename [String] The filename to test
|
282
|
-
##
|
283
|
-
## @return [Boolean] true if filename passes test
|
284
|
-
##
|
285
|
-
def build_note?(filename)
|
286
|
-
return false if filename.downcase !~ /^(howzit[^.]*|build[^.]+)/
|
287
|
-
|
288
|
-
return false if Howzit.config.should_ignore(filename)
|
289
|
-
|
290
|
-
true
|
291
|
-
end
|
292
|
-
|
293
278
|
##
|
294
279
|
## Glob current directory for valid build note filenames
|
280
|
+
## (must start with "build" or "howzit" and have
|
281
|
+
## extension of "txt", "md", or "markdown")
|
295
282
|
##
|
296
283
|
## @return [String] file path
|
297
284
|
##
|
298
285
|
def glob_note
|
299
|
-
|
300
|
-
# Check for a build note file in the current folder. Filename must start
|
301
|
-
# with "build" and have an extension of txt, md, or markdown.
|
302
|
-
|
303
|
-
Dir.glob('*.{txt,md,markdown}').each do |f|
|
304
|
-
if build_note?(f)
|
305
|
-
filename = f
|
306
|
-
break
|
307
|
-
end
|
308
|
-
end
|
309
|
-
filename
|
286
|
+
Dir.glob('*.{txt,md,markdown}').select(&:build_note?)[0]
|
310
287
|
end
|
311
288
|
|
312
289
|
##
|
data/lib/howzit/hash.rb
CHANGED
@@ -5,7 +5,7 @@ class ::Hash
|
|
5
5
|
##
|
6
6
|
## Freeze all values in a hash
|
7
7
|
##
|
8
|
-
## @return Hash with all values frozen
|
8
|
+
## @return [Hash] Hash with all values frozen
|
9
9
|
##
|
10
10
|
def deep_freeze
|
11
11
|
chilled = {}
|
@@ -16,10 +16,18 @@ class ::Hash
|
|
16
16
|
chilled.freeze
|
17
17
|
end
|
18
18
|
|
19
|
+
##
|
20
|
+
## Deep freeze a hash in place (destructive)
|
21
|
+
##
|
19
22
|
def deep_freeze!
|
20
23
|
replace deep_thaw.deep_freeze
|
21
24
|
end
|
22
25
|
|
26
|
+
##
|
27
|
+
## Unfreeze nested hash values
|
28
|
+
##
|
29
|
+
## @return [Hash] Hash with all values unfrozen
|
30
|
+
##
|
23
31
|
def deep_thaw
|
24
32
|
chilled = {}
|
25
33
|
each do |k, v|
|
@@ -29,26 +37,39 @@ class ::Hash
|
|
29
37
|
chilled.dup
|
30
38
|
end
|
31
39
|
|
40
|
+
##
|
41
|
+
## Unfreeze nested hash values in place (destructive)
|
42
|
+
##
|
32
43
|
def deep_thaw!
|
33
44
|
replace deep_thaw
|
34
45
|
end
|
35
46
|
|
36
47
|
# Turn all keys into string
|
37
48
|
#
|
38
|
-
#
|
49
|
+
# @return [Hash] hash with all keys as strings
|
50
|
+
#
|
39
51
|
def stringify_keys
|
40
52
|
each_with_object({}) { |(k, v), hsh| hsh[k.to_s] = v.is_a?(Hash) ? v.stringify_keys : v }
|
41
53
|
end
|
42
54
|
|
55
|
+
##
|
56
|
+
## Turn all keys into strings in place (destructive)
|
57
|
+
##
|
43
58
|
def stringify_keys!
|
44
59
|
replace stringify_keys
|
45
60
|
end
|
46
61
|
|
47
62
|
# Turn all keys into symbols
|
63
|
+
#
|
64
|
+
# @return [Hash] hash with all keys as symbols
|
65
|
+
#
|
48
66
|
def symbolize_keys
|
49
67
|
each_with_object({}) { |(k, v), hsh| hsh[k.to_sym] = v.is_a?(Hash) ? v.symbolize_keys : v }
|
50
68
|
end
|
51
69
|
|
70
|
+
##
|
71
|
+
## Turn all keys into symbols in place (destructive)
|
72
|
+
##
|
52
73
|
def symbolize_keys!
|
53
74
|
replace symbolize_keys
|
54
75
|
end
|
data/lib/howzit/prompt.rb
CHANGED
@@ -4,10 +4,22 @@ module Howzit
|
|
4
4
|
# Command line prompt utils
|
5
5
|
module Prompt
|
6
6
|
class << self
|
7
|
-
|
7
|
+
|
8
|
+
##
|
9
|
+
## Display and read a Yes/No prompt
|
10
|
+
##
|
11
|
+
## @param prompt [String] The prompt string
|
12
|
+
## @param default [Boolean] default value if
|
13
|
+
## return is pressed or prompt is
|
14
|
+
## skipped
|
15
|
+
##
|
16
|
+
## @return [Boolean] result
|
17
|
+
##
|
18
|
+
def yn(prompt, default: true)
|
8
19
|
return default unless $stdout.isatty
|
9
20
|
|
10
21
|
return default if Howzit.options[:default]
|
22
|
+
|
11
23
|
tty_state = `stty -g`
|
12
24
|
system 'stty raw -echo cbreak isig'
|
13
25
|
yn = color_single_options(default ? %w[Y n] : %w[y N])
|
@@ -20,6 +32,14 @@ module Howzit
|
|
20
32
|
res.empty? ? default : res =~ /y/i
|
21
33
|
end
|
22
34
|
|
35
|
+
##
|
36
|
+
## Helper function to colorize the Y/N prompt
|
37
|
+
##
|
38
|
+
## @param choices [Array] The choices with
|
39
|
+
## default capitalized
|
40
|
+
##
|
41
|
+
## @return [String] colorized string
|
42
|
+
##
|
23
43
|
def color_single_options(choices = %w[y n])
|
24
44
|
out = []
|
25
45
|
choices.each do |choice|
|
@@ -33,6 +53,12 @@ module Howzit
|
|
33
53
|
Color.template("{xg}[#{out.join('/')}{xg}]{x}")
|
34
54
|
end
|
35
55
|
|
56
|
+
##
|
57
|
+
## Create a numbered list of options. Outputs directly
|
58
|
+
## to console, returns nothing
|
59
|
+
##
|
60
|
+
## @param matches [Array] The list items
|
61
|
+
##
|
36
62
|
def options_list(matches)
|
37
63
|
counter = 1
|
38
64
|
puts
|
@@ -43,6 +69,15 @@ module Howzit
|
|
43
69
|
puts
|
44
70
|
end
|
45
71
|
|
72
|
+
##
|
73
|
+
## Choose from a list of items. If fzf is available,
|
74
|
+
## uses that, otherwise generates its own list of
|
75
|
+
## options and accepts a numeric response
|
76
|
+
##
|
77
|
+
## @param matches [Array] The options list
|
78
|
+
##
|
79
|
+
## @return [Array] the selected results
|
80
|
+
##
|
46
81
|
def choose(matches)
|
47
82
|
if Util.command_exist?('fzf')
|
48
83
|
settings = [
|
@@ -80,7 +115,7 @@ module Howzit
|
|
80
115
|
end
|
81
116
|
line = line == '' ? 1 : line.to_i
|
82
117
|
|
83
|
-
return matches[line - 1] if line.positive? && line <= matches.length
|
118
|
+
return [matches[line - 1]] if line.positive? && line <= matches.length
|
84
119
|
|
85
120
|
puts 'Out of range'
|
86
121
|
options_list(matches)
|
data/lib/howzit/stringutils.rb
CHANGED
@@ -3,7 +3,37 @@
|
|
3
3
|
module Howzit
|
4
4
|
# String Extensions
|
5
5
|
module StringUtils
|
6
|
+
##
|
7
|
+
## Test if the filename matches the conditions to be a build note
|
8
|
+
##
|
9
|
+
## @return [Boolean] true if filename passes test
|
10
|
+
##
|
11
|
+
def build_note?
|
12
|
+
return false if downcase !~ /^(howzit[^.]*|build[^.]+)/
|
13
|
+
|
14
|
+
return false if Howzit.config.should_ignore(self)
|
15
|
+
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
## Replace slash escaped characters in a string with a
|
21
|
+
## zero-width space that will prevent a shell from
|
22
|
+
## interpreting them when output to console
|
23
|
+
##
|
24
|
+
## @return [String] new string
|
25
|
+
##
|
26
|
+
def preserve_escapes
|
27
|
+
gsub(/\\([a-z])/, '\\1')
|
28
|
+
end
|
29
|
+
|
6
30
|
# Convert a string to a valid YAML value
|
31
|
+
#
|
32
|
+
# @param orig_value The original value from which
|
33
|
+
# type will be determined
|
34
|
+
#
|
35
|
+
# @return coerced value
|
36
|
+
#
|
7
37
|
def to_config_value(orig_value = nil)
|
8
38
|
if orig_value
|
9
39
|
case orig_value.class.to_s
|
@@ -28,10 +58,21 @@ module Howzit
|
|
28
58
|
end
|
29
59
|
end
|
30
60
|
|
61
|
+
##
|
62
|
+
## Shortcut for calling Color.template
|
63
|
+
##
|
64
|
+
## @return [String] colorized string
|
65
|
+
##
|
31
66
|
def c
|
32
67
|
Color.template(self)
|
33
68
|
end
|
34
69
|
|
70
|
+
|
71
|
+
##
|
72
|
+
## Convert a string to a regex object based on matching settings
|
73
|
+
##
|
74
|
+
## @return [Regexp] Receive regex representation of the object.
|
75
|
+
##
|
35
76
|
def to_rx
|
36
77
|
case Howzit.options[:matching]
|
37
78
|
when 'exact'
|
@@ -50,9 +91,17 @@ module Howzit
|
|
50
91
|
gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'')
|
51
92
|
end
|
52
93
|
|
94
|
+
# Wrap text at a specified width.
|
95
|
+
#
|
53
96
|
# Adapted from https://github.com/pazdera/word_wrap/,
|
54
|
-
# copyright (c) 2014, 2015 Radek Pazdera
|
55
|
-
#
|
97
|
+
# copyright (c) 2014, 2015 Radek Pazdera Distributed
|
98
|
+
# under the MIT License
|
99
|
+
#
|
100
|
+
# @param width [Integer] The width at which to
|
101
|
+
# wrap lines
|
102
|
+
#
|
103
|
+
# @return [String] wrapped string
|
104
|
+
#
|
56
105
|
def wrap(width)
|
57
106
|
width ||= 80
|
58
107
|
output = []
|
@@ -84,12 +133,19 @@ module Howzit
|
|
84
133
|
output.join("\n")
|
85
134
|
end
|
86
135
|
|
136
|
+
##
|
137
|
+
## Wrap string in place (destructive)
|
138
|
+
##
|
139
|
+
## @param width [Integer] The width at which to wrap
|
140
|
+
##
|
87
141
|
def wrap!(width)
|
88
142
|
replace(wrap(width))
|
89
143
|
end
|
90
144
|
|
91
145
|
# Truncate string to nearest word
|
92
|
-
#
|
146
|
+
#
|
147
|
+
# @param len [Integer] max length of string
|
148
|
+
#
|
93
149
|
def trunc(len)
|
94
150
|
split(/ /).each_with_object([]) do |x, ob|
|
95
151
|
break ob unless ob.join(' ').length + ' '.length + x.length <= len
|
@@ -98,10 +154,21 @@ module Howzit
|
|
98
154
|
end.join(' ').strip
|
99
155
|
end
|
100
156
|
|
157
|
+
##
|
158
|
+
## Truncate string in place (destructive)
|
159
|
+
##
|
160
|
+
## @param len [Integer] The length to truncate at
|
161
|
+
##
|
101
162
|
def trunc!(len)
|
102
163
|
replace trunc(len)
|
103
164
|
end
|
104
165
|
|
166
|
+
##
|
167
|
+
## Splits a line at nearest word break
|
168
|
+
##
|
169
|
+
## @param width [Integer] The width of the first segment
|
170
|
+
## @param indent [String] The indent string
|
171
|
+
##
|
105
172
|
def split_line(width, indent = '')
|
106
173
|
line = dup
|
107
174
|
at = line.index(/\s/)
|
@@ -119,10 +186,23 @@ module Howzit
|
|
119
186
|
end
|
120
187
|
end
|
121
188
|
|
189
|
+
##
|
190
|
+
## Test if an executable is available on the system
|
191
|
+
##
|
192
|
+
## @return [Boolean] executable is available
|
193
|
+
##
|
122
194
|
def available?
|
123
195
|
Util.valid_command?(self)
|
124
196
|
end
|
125
197
|
|
198
|
+
##
|
199
|
+
## Render [%variable] placeholders in a templated string
|
200
|
+
##
|
201
|
+
## @param vars [Hash] Key/value pairs of variable
|
202
|
+
## values
|
203
|
+
##
|
204
|
+
## @return [String] Rendered string
|
205
|
+
##
|
126
206
|
def render_template(vars)
|
127
207
|
vars.each do |k, v|
|
128
208
|
gsub!(/\[%#{k}(:.*?)?\]/, v)
|
@@ -131,10 +211,20 @@ module Howzit
|
|
131
211
|
gsub(/\[%(.*?):(.*?)\]/, '\2')
|
132
212
|
end
|
133
213
|
|
214
|
+
##
|
215
|
+
## Render [%variable] placeholders in place
|
216
|
+
##
|
217
|
+
## @param vars [Hash] Key/value pairs of variable values
|
218
|
+
##
|
134
219
|
def render_template!(vars)
|
135
220
|
replace render_template(vars)
|
136
221
|
end
|
137
222
|
|
223
|
+
##
|
224
|
+
## Render $X placeholders based on positional arguments
|
225
|
+
##
|
226
|
+
## @return [String] rendered string
|
227
|
+
##
|
138
228
|
def render_arguments
|
139
229
|
return self if Howzit.arguments.nil? || Howzit.arguments.empty?
|
140
230
|
|
@@ -145,6 +235,13 @@ module Howzit
|
|
145
235
|
gsub(/\$[@*]/, Shellwords.join(Howzit.arguments))
|
146
236
|
end
|
147
237
|
|
238
|
+
##
|
239
|
+
## Split the content at the first top-level header and
|
240
|
+
## assume everything before it is metadata. Passes to
|
241
|
+
## #get_metadata for processing
|
242
|
+
##
|
243
|
+
## @return [Hash] key/value pairs
|
244
|
+
##
|
148
245
|
def extract_metadata
|
149
246
|
if File.exist?(self)
|
150
247
|
leader = Util.read_file(self).split(/^#/)[0].strip
|
@@ -154,6 +251,11 @@ module Howzit
|
|
154
251
|
end
|
155
252
|
end
|
156
253
|
|
254
|
+
##
|
255
|
+
## Examine text for multimarkdown-style metadata and return key/value pairs
|
256
|
+
##
|
257
|
+
## @return [Hash] The metadata as key/value pairs
|
258
|
+
##
|
157
259
|
def get_metadata
|
158
260
|
data = {}
|
159
261
|
scan(/(?mi)^(\S[\s\S]+?): ([\s\S]*?)(?=\n\S[\s\S]*?:|\Z)/).each do |m|
|
@@ -162,6 +264,13 @@ module Howzit
|
|
162
264
|
normalize_metadata(data)
|
163
265
|
end
|
164
266
|
|
267
|
+
##
|
268
|
+
## Autocorrect some keys
|
269
|
+
##
|
270
|
+
## @param meta [Hash] The metadata
|
271
|
+
##
|
272
|
+
## @return [Hash] corrected metadata
|
273
|
+
##
|
165
274
|
def normalize_metadata(meta)
|
166
275
|
data = {}
|
167
276
|
meta.each do |k, v|
|
@@ -177,15 +286,33 @@ module Howzit
|
|
177
286
|
data
|
178
287
|
end
|
179
288
|
|
289
|
+
##
|
290
|
+
## Test if iTerm markers should be output. Requires that
|
291
|
+
## the $TERM_PROGRAM be iTerm and howzit is not running
|
292
|
+
## directives or paginating output
|
293
|
+
##
|
294
|
+
## @return [Boolean] should mark?
|
295
|
+
##
|
180
296
|
def should_mark_iterm?
|
181
297
|
ENV['TERM_PROGRAM'] =~ /^iTerm/ && !Howzit.options[:run] && !Howzit.options[:paginate]
|
182
298
|
end
|
183
299
|
|
300
|
+
##
|
301
|
+
## Output an iTerm marker
|
302
|
+
##
|
303
|
+
## @return [String] ANSI escape sequence for iTerm
|
304
|
+
## marker
|
305
|
+
##
|
184
306
|
def iterm_marker
|
185
307
|
"\e]1337;SetMark\a" if should_mark_iterm?
|
186
308
|
end
|
187
309
|
|
188
310
|
# Make a fancy title line for the topic
|
311
|
+
#
|
312
|
+
# @param opts [Hash] options
|
313
|
+
#
|
314
|
+
# @return [String] formatted string
|
315
|
+
#
|
189
316
|
def format_header(opts = {})
|
190
317
|
title = dup
|
191
318
|
options = {
|
data/lib/howzit/task.rb
CHANGED
@@ -5,11 +5,14 @@ module Howzit
|
|
5
5
|
class Task
|
6
6
|
attr_reader :type, :title, :action, :parent, :optional, :default
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@
|
8
|
+
##
|
9
|
+
## Initialize a Task object
|
10
|
+
##
|
11
|
+
def initialize(params, optional: false, default: true)
|
12
|
+
@type = params[:type]
|
13
|
+
@title = params[:title]
|
14
|
+
@action = params[:action].render_arguments
|
15
|
+
@parent = params[:parent] || nil
|
13
16
|
@optional = optional
|
14
17
|
@default = default
|
15
18
|
end
|
@@ -23,7 +26,7 @@ module Howzit
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def to_list
|
26
|
-
" * #{@type}: #{@title.
|
29
|
+
" * #{@type}: #{@title.preserve_escapes}"
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
data/lib/howzit/topic.rb
CHANGED
@@ -107,6 +107,11 @@ module Howzit
|
|
107
107
|
output
|
108
108
|
end
|
109
109
|
|
110
|
+
##
|
111
|
+
## Platform-agnostic copy-to-clipboard
|
112
|
+
##
|
113
|
+
## @param string [String] The string to copy
|
114
|
+
##
|
110
115
|
def os_copy(string)
|
111
116
|
os = RbConfig::CONFIG['target_os']
|
112
117
|
out = "{bg}Copying {bw}#{string}".c
|
@@ -131,6 +136,11 @@ module Howzit
|
|
131
136
|
end
|
132
137
|
end
|
133
138
|
|
139
|
+
##
|
140
|
+
## Platform-agnostic open command
|
141
|
+
##
|
142
|
+
## @param command [String] The command
|
143
|
+
##
|
134
144
|
def os_open(command)
|
135
145
|
os = RbConfig::CONFIG['target_os']
|
136
146
|
out = "{bg}Opening {bw}#{command}".c
|
@@ -153,6 +163,11 @@ module Howzit
|
|
153
163
|
end
|
154
164
|
|
155
165
|
# Output a topic with fancy title and bright white text.
|
166
|
+
#
|
167
|
+
# @param options [Hash] The options
|
168
|
+
#
|
169
|
+
# @return [Array] array of formatted lines
|
170
|
+
#
|
156
171
|
def print_out(options = {})
|
157
172
|
defaults = { single: false, header: true }
|
158
173
|
opt = defaults.merge(options)
|
@@ -223,7 +238,7 @@ module Howzit
|
|
223
238
|
"\u{279A}"
|
224
239
|
end
|
225
240
|
|
226
|
-
output.push("{bmK}#{icon} {bwK}#{title.
|
241
|
+
output.push("{bmK}#{icon} {bwK}#{title.preserve_escapes}{x}#{option}".c)
|
227
242
|
when /(?<fence>`{3,})run(?<optional>[!?]{1,2})? *(?<title>.*?)$/i
|
228
243
|
m = Regexp.last_match.named_captures.symbolize_keys
|
229
244
|
optional = m[:optional] =~ /[?!]+/ ? true : false
|
@@ -256,6 +271,11 @@ module Howzit
|
|
256
271
|
|
257
272
|
private
|
258
273
|
|
274
|
+
##
|
275
|
+
## Collect all directives in the topic content
|
276
|
+
##
|
277
|
+
## @return [Array] array of Task objects
|
278
|
+
##
|
259
279
|
def gather_tasks
|
260
280
|
runnable = []
|
261
281
|
@prereqs = @content.scan(/(?<=@before\n).*?(?=\n@end)/im).map(&:strip)
|
@@ -275,7 +295,12 @@ module Howzit
|
|
275
295
|
default = c[:optional2] =~ /!/ ? false : true
|
276
296
|
title = c[:title2].nil? ? '' : c[:title2].strip
|
277
297
|
block = c[:block]&.strip
|
278
|
-
runnable << Howzit::Task.new(:
|
298
|
+
runnable << Howzit::Task.new({ type: :block,
|
299
|
+
title: title,
|
300
|
+
action: block,
|
301
|
+
parent: nil },
|
302
|
+
optional: optional,
|
303
|
+
default: default)
|
279
304
|
else
|
280
305
|
cmd = c[:cmd]
|
281
306
|
optional = c[:optional] =~ /[?!]{1,2}/ ? true : false
|
@@ -294,15 +319,35 @@ module Howzit
|
|
294
319
|
# end
|
295
320
|
# runnable.concat(tasks)
|
296
321
|
# end
|
297
|
-
runnable << Howzit::Task.new(:
|
322
|
+
runnable << Howzit::Task.new({ type: :include,
|
323
|
+
title: title,
|
324
|
+
action: obj,
|
325
|
+
parent: nil },
|
326
|
+
optional: optional,
|
327
|
+
default: default)
|
298
328
|
when /run/i
|
299
329
|
# warn "{bg}Running {bw}#{obj}{x}".c if Howzit.options[:log_level] < 2
|
300
|
-
runnable << Howzit::Task.new(:
|
330
|
+
runnable << Howzit::Task.new({ type: :run,
|
331
|
+
title: title,
|
332
|
+
action: obj,
|
333
|
+
parent: nil },
|
334
|
+
optional: optional,
|
335
|
+
default: default)
|
301
336
|
when /copy/i
|
302
337
|
# warn "{bg}Copied {bw}#{obj}{bg} to clipboard{x}".c if Howzit.options[:log_level] < 2
|
303
|
-
runnable << Howzit::Task.new(:
|
338
|
+
runnable << Howzit::Task.new({ type: :copy,
|
339
|
+
title: title,
|
340
|
+
action: Shellwords.escape(obj),
|
341
|
+
parent: nil },
|
342
|
+
optional: optional,
|
343
|
+
default: default)
|
304
344
|
when /open|url/i
|
305
|
-
runnable << Howzit::Task.new(:
|
345
|
+
runnable << Howzit::Task.new({ type: :open,
|
346
|
+
title: title,
|
347
|
+
action: obj,
|
348
|
+
parent: nil },
|
349
|
+
optional: optional,
|
350
|
+
default: default)
|
306
351
|
end
|
307
352
|
end
|
308
353
|
end
|
data/lib/howzit/util.rb
CHANGED
@@ -4,15 +4,40 @@ module Howzit
|
|
4
4
|
# Util class
|
5
5
|
module Util
|
6
6
|
class << self
|
7
|
+
|
8
|
+
##
|
9
|
+
## Read a file with UTF-8 encoding and
|
10
|
+
## leading/trailing whitespace removed
|
11
|
+
##
|
12
|
+
## @param path [String] The path to read
|
13
|
+
##
|
14
|
+
## @return [String] UTF-8 encoded string
|
15
|
+
##
|
7
16
|
def read_file(path)
|
8
17
|
IO.read(path).force_encoding('utf-8').strip
|
9
18
|
end
|
10
19
|
|
20
|
+
##
|
21
|
+
## Test if an external command exists and is
|
22
|
+
## executable. Removes additional arguments and passes
|
23
|
+
## just the executable to #command_exist?
|
24
|
+
##
|
25
|
+
## @param command [String] The command
|
26
|
+
##
|
27
|
+
## @return [Boolean] command is valid
|
28
|
+
##
|
11
29
|
def valid_command?(command)
|
12
30
|
cmd = command.split(' ')[0]
|
13
31
|
command_exist?(cmd)
|
14
32
|
end
|
15
33
|
|
34
|
+
##
|
35
|
+
## Test if external command exists
|
36
|
+
##
|
37
|
+
## @param command [String] The command
|
38
|
+
##
|
39
|
+
## @return [Boolean] command exists
|
40
|
+
##
|
16
41
|
def command_exist?(command)
|
17
42
|
exts = ENV.fetch('PATHEXT', '').split(::File::PATH_SEPARATOR)
|
18
43
|
if Pathname.new(command).absolute?
|
data/lib/howzit/version.rb
CHANGED
data/spec/task_spec.rb
CHANGED
@@ -3,7 +3,12 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Howzit::Task do
|
6
|
-
subject(:task)
|
6
|
+
subject(:task) do
|
7
|
+
Howzit::Task.new({ type: :run,
|
8
|
+
title: 'List Directory',
|
9
|
+
action: 'ls',
|
10
|
+
parent: nil })
|
11
|
+
end
|
7
12
|
|
8
13
|
describe ".new" do
|
9
14
|
it "makes a new task instance" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
@@ -309,7 +309,6 @@ files:
|
|
309
309
|
- lib/howzit/version.rb
|
310
310
|
- spec/.rubocop.yml
|
311
311
|
- spec/buildnote_spec.rb
|
312
|
-
- spec/buildnotes.md.bak
|
313
312
|
- spec/cli_spec.rb
|
314
313
|
- spec/ruby_gem_spec.rb
|
315
314
|
- spec/spec_helper.rb
|
@@ -343,7 +342,6 @@ summary: Provides a way to access Markdown project notes by topic with query cap
|
|
343
342
|
test_files:
|
344
343
|
- spec/.rubocop.yml
|
345
344
|
- spec/buildnote_spec.rb
|
346
|
-
- spec/buildnotes.md.bak
|
347
345
|
- spec/cli_spec.rb
|
348
346
|
- spec/ruby_gem_spec.rb
|
349
347
|
- spec/spec_helper.rb
|
data/spec/buildnotes.md.bak
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# spec
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
## File Structure
|
6
|
-
|
7
|
-
Where are the main editable files? Is there a dist/build folder that should be ignored?
|
8
|
-
|
9
|
-
## Build
|
10
|
-
|
11
|
-
What build system/parameters does this use?
|
12
|
-
|
13
|
-
@run(./build command)
|
14
|
-
|
15
|
-
## Deploy
|
16
|
-
|
17
|
-
What are the procedures/commands to deploy this project?
|
18
|
-
|
19
|
-
## Other
|
20
|
-
|
21
|
-
Version control notes, additional gulp/rake/make/etc tasks...
|
22
|
-
|