howzit 2.0.34 → 2.1.0
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/CHANGELOG.md +9 -0
- data/README.md +1 -0
- data/Rakefile +2 -0
- data/bin/howzit +1 -0
- data/lib/howzit/buildnote.rb +5 -7
- data/lib/howzit/stringutils.rb +19 -6
- data/lib/howzit/task.rb +10 -5
- data/lib/howzit/topic.rb +54 -10
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.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: d61fbc8c08077a6d9e5496fb94c91b051ef02fb258ad162ad6588a73a4ae2e30
|
4
|
+
data.tar.gz: a6512e0efcd43bc57236d7bcbaa7c99baf9825630638b45cb936132fed932b03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 40aa758d7549cb6a2d6b8e6a3c6f9e38aafe377db0c3e2923948dc4981e0b601553c79e73a1e46e097c98f250792bc28b07693a5d3c99b60280cea207322956e
|
7
|
+
data.tar.gz: 07d0d4dbae06e9c9019d7ee74dab8b8b0ffa99d328f416a31566dcdc2741f411507f1be42ba5906a40231c31158eb7de3cc8d156a3e9b5e7e2941a54603a8812
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
### 2.1.0
|
2
|
+
|
3
|
+
2023-03-07 09:24
|
4
|
+
|
5
|
+
#### NEW
|
6
|
+
|
7
|
+
- Use TOPIC_TITLE (var1, var2) to have access to ${var1} ${var2} in text and scripts, populated with positional variables on the command line
|
8
|
+
- Add a default (fallback) value to any variable placeholder with ${var_name:default value}
|
9
|
+
|
1
10
|
### 2.0.34
|
2
11
|
|
3
12
|
2023-01-15 13:32
|
data/README.md
CHANGED
@@ -21,6 +21,7 @@ Howzit is a tool that allows you to keep Markdown-formatted notes about a projec
|
|
21
21
|
- Inside of git repositories, howzit will work from subdirectories, assuming build notes are in top level of repo
|
22
22
|
- Templates for easily including repeat tasks
|
23
23
|
- Grep topics for pattern and choose from matches
|
24
|
+
- Use positional and named variables when executing tasks
|
24
25
|
|
25
26
|
## Getting Started
|
26
27
|
|
data/Rakefile
CHANGED
data/bin/howzit
CHANGED
@@ -9,6 +9,7 @@ Howzit::Color.coloring = $stdout.isatty
|
|
9
9
|
parts = Shellwords.shelljoin(ARGV).split(/ -- /)
|
10
10
|
args = parts[0] ? Shellwords.shellsplit(parts[0]) : []
|
11
11
|
Howzit.arguments = parts[1] ? Shellwords.shellsplit(parts[1]) : []
|
12
|
+
Howzit.named_arguments = {}
|
12
13
|
|
13
14
|
OptionParser.new do |opts|
|
14
15
|
opts.banner = "Usage: #{File.basename(__FILE__)} [OPTIONS] [TOPIC]"
|
data/lib/howzit/buildnote.rb
CHANGED
@@ -69,10 +69,9 @@ module Howzit
|
|
69
69
|
##
|
70
70
|
def find_topic(term = nil)
|
71
71
|
return @topics if term.nil?
|
72
|
-
|
73
72
|
@topics.filter do |topic|
|
74
73
|
rx = term.to_rx
|
75
|
-
topic.title.downcase =~ rx
|
74
|
+
topic.title.downcase.sub(/ *\(.*?\) *$/, '') =~ rx
|
76
75
|
end
|
77
76
|
end
|
78
77
|
|
@@ -109,7 +108,6 @@ module Howzit
|
|
109
108
|
output.join("\n")
|
110
109
|
end
|
111
110
|
|
112
|
-
|
113
111
|
##
|
114
112
|
## Return an array of topic titles
|
115
113
|
##
|
@@ -218,7 +216,7 @@ module Howzit
|
|
218
216
|
end
|
219
217
|
|
220
218
|
if File.exist?(file) && !default && Prompt.yn("{bg}Do you want to open {bw}#{file} {bg}for editing?{x}".c,
|
221
|
-
|
219
|
+
default: false)
|
222
220
|
edit_template_file(file)
|
223
221
|
end
|
224
222
|
|
@@ -364,6 +362,7 @@ module Howzit
|
|
364
362
|
t_leader = Util.read_file(template).split(/^#/)[0].strip
|
365
363
|
if t_leader.length > 0
|
366
364
|
t_meta = t_leader.get_metadata
|
365
|
+
|
367
366
|
if t_meta.key?('required')
|
368
367
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
369
368
|
required.each do |req|
|
@@ -699,14 +698,12 @@ module Howzit
|
|
699
698
|
def process_topic(topic, run, single: false)
|
700
699
|
new_topic = topic.is_a?(String) ? find_topic(topic)[0] : topic.dup
|
701
700
|
|
702
|
-
# Handle variable replacement
|
703
|
-
new_topic.content = new_topic.content.render_arguments
|
704
|
-
|
705
701
|
output = if run
|
706
702
|
new_topic.run
|
707
703
|
else
|
708
704
|
new_topic.print_out({ single: single })
|
709
705
|
end
|
706
|
+
|
710
707
|
output.nil? ? '' : output.join("\n")
|
711
708
|
end
|
712
709
|
|
@@ -755,6 +752,7 @@ module Howzit
|
|
755
752
|
end
|
756
753
|
|
757
754
|
topic_matches = []
|
755
|
+
|
758
756
|
if Howzit.options[:grep]
|
759
757
|
matches = grep(Howzit.options[:grep])
|
760
758
|
case Howzit.options[:multiple_matches]
|
data/lib/howzit/stringutils.rb
CHANGED
@@ -95,7 +95,7 @@ module Howzit
|
|
95
95
|
when 'beginswith'
|
96
96
|
/^#{self}/i
|
97
97
|
when 'fuzzy'
|
98
|
-
/#{split(//).join('
|
98
|
+
/#{split(//).join('.{0,3}?')}/i
|
99
99
|
else
|
100
100
|
/#{self}/i
|
101
101
|
end
|
@@ -241,13 +241,26 @@ module Howzit
|
|
241
241
|
## @return [String] rendered string
|
242
242
|
##
|
243
243
|
def render_arguments
|
244
|
-
|
244
|
+
str = dup
|
245
|
+
str.gsub!(/\$\{(?<name>[A-Z]+(?::.*?)?)\}/i) do |mtch|
|
246
|
+
m = Regexp.last_match
|
247
|
+
arg, default = m['name'].split(/:/).map(&:strip)
|
248
|
+
Howzit.named_arguments.key?(arg) && !Howzit.named_arguments[arg].nil? ? Howzit.named_arguments[arg] : default
|
249
|
+
end
|
245
250
|
|
246
|
-
gsub!(
|
247
|
-
|
248
|
-
|
251
|
+
str.gsub!(/\$\{?(\d+)\}?/) do
|
252
|
+
m = Regexp.last_match
|
253
|
+
arg, default = m[1].split(/:/)
|
254
|
+
idx = arg.to_i - 1
|
255
|
+
if Howzit.arguments.length > idx
|
256
|
+
Howzit.arguments[idx]
|
257
|
+
elsif default
|
258
|
+
default
|
259
|
+
else
|
260
|
+
m[0]
|
261
|
+
end
|
249
262
|
end
|
250
|
-
gsub(/\$[@*]/, Shellwords.join(Howzit.arguments))
|
263
|
+
Howzit.arguments.nil? ? str : str.gsub(/\$[@*]/, Shellwords.join(Howzit.arguments))
|
251
264
|
end
|
252
265
|
|
253
266
|
##
|
data/lib/howzit/task.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module Howzit
|
4
4
|
# Task object
|
5
5
|
class Task
|
6
|
-
attr_reader :type, :title, :action, :parent, :optional, :default
|
6
|
+
attr_reader :type, :title, :action, :arguments, :parent, :optional, :default
|
7
7
|
|
8
8
|
##
|
9
9
|
## Initialize a Task object
|
@@ -21,11 +21,14 @@ module Howzit
|
|
21
21
|
def initialize(attributes, optional: false, default: true)
|
22
22
|
@prefix = "{bw}\u{25B7}\u{25B7} {x}"
|
23
23
|
# arrow = "{bw}\u{279F}{x}"
|
24
|
+
@arguments = attributes[:arguments] || []
|
24
25
|
|
25
26
|
@type = attributes[:type] || :run
|
26
27
|
@title = attributes[:title] || nil
|
27
|
-
@action = attributes[:action].render_arguments || nil
|
28
28
|
@parent = attributes[:parent] || nil
|
29
|
+
|
30
|
+
@action = attributes[:action].render_arguments || nil
|
31
|
+
|
29
32
|
@optional = optional
|
30
33
|
@default = default
|
31
34
|
end
|
@@ -36,7 +39,7 @@ module Howzit
|
|
36
39
|
## @return [String] description
|
37
40
|
##
|
38
41
|
def inspect
|
39
|
-
%(<#Howzit::Task @type=:#{@type} @title="#{@title}" @block?=#{@action.split(/\n/).count > 1}>)
|
42
|
+
%(<#Howzit::Task @type=:#{@type} @title="#{@title}" @arguments=#{@arguments} @block?=#{@action.split(/\n/).count > 1}>)
|
40
43
|
end
|
41
44
|
|
42
45
|
##
|
@@ -75,8 +78,10 @@ module Howzit
|
|
75
78
|
##
|
76
79
|
def run_include
|
77
80
|
output = []
|
78
|
-
|
79
|
-
|
81
|
+
action = @action
|
82
|
+
|
83
|
+
matches = Howzit.buildnote.find_topic(action)
|
84
|
+
raise "Topic not found: #{action}" if matches.empty?
|
80
85
|
|
81
86
|
Howzit.console.info("#{@prefix}{by}Running tasks from {bw}#{matches[0].title}{x}".c)
|
82
87
|
output.concat(matches[0].run(nested: true))
|
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, :results
|
10
|
+
attr_reader :title, :tasks, :prereqs, :postreqs, :results, :named_args
|
11
11
|
|
12
12
|
##
|
13
13
|
## Initialize a topic object
|
@@ -20,10 +20,33 @@ module Howzit
|
|
20
20
|
@content = content
|
21
21
|
@parent = nil
|
22
22
|
@nest_level = 0
|
23
|
+
@named_args = {}
|
24
|
+
arguments
|
25
|
+
|
23
26
|
@tasks = gather_tasks
|
24
27
|
@results = { total: 0, success: 0, errors: 0, message: ''.c }
|
25
28
|
end
|
26
29
|
|
30
|
+
# Get named arguments from title
|
31
|
+
def arguments
|
32
|
+
return unless @title =~ /\(.*?\) *$/
|
33
|
+
|
34
|
+
a = @title.match(/\((?<args>.*?)\) *$/)
|
35
|
+
args = a['args'].split(/ *, */).each(&:strip)
|
36
|
+
|
37
|
+
args.each_with_index do |arg, idx|
|
38
|
+
arg_name, default = arg.split(/:/).map(&:strip)
|
39
|
+
|
40
|
+
@named_args[arg_name] = if Howzit.arguments.count >= idx + 1
|
41
|
+
Howzit.arguments[idx]
|
42
|
+
else
|
43
|
+
default
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
@title = @title.sub(/\(.*?\) *$/, '').strip
|
48
|
+
end
|
49
|
+
|
27
50
|
##
|
28
51
|
## Search title and contents for a pattern
|
29
52
|
##
|
@@ -121,11 +144,19 @@ module Howzit
|
|
121
144
|
case l
|
122
145
|
when /@(before|after|prereq|end)/
|
123
146
|
next
|
124
|
-
when /@include(?<optional>[!?]{1,2})?\((?<action
|
147
|
+
when /@include(?<optional>[!?]{1,2})?\((?<action>[^\)]+)\)/
|
125
148
|
m = Regexp.last_match.named_captures.symbolize_keys
|
126
|
-
|
149
|
+
|
150
|
+
if m[:action] =~ / *\[(.*?)\] *$/
|
151
|
+
Howzit.named_arguments = @named_args
|
152
|
+
Howzit.arguments = Regexp.last_match(1).split(/ *, */).map!(&:render_arguments)
|
153
|
+
end
|
154
|
+
|
155
|
+
matches = Howzit.buildnote.find_topic(m[:action].sub(/ *\[.*?\] *$/, ''))
|
156
|
+
|
127
157
|
unless matches.empty?
|
128
158
|
i_topic = matches[0]
|
159
|
+
|
129
160
|
rule = '{kKd}'
|
130
161
|
color = '{Kyd}'
|
131
162
|
option = if i_topic.tasks.empty?
|
@@ -149,13 +180,14 @@ module Howzit
|
|
149
180
|
output.push("#{'> ' * @nest_level}#{title} included above".format_header(options))
|
150
181
|
elsif opt[:single]
|
151
182
|
@nest_level += 1
|
183
|
+
|
152
184
|
output.concat(i_topic.print_out({ single: true, header: false }))
|
153
185
|
output.push("#{'> ' * @nest_level}...".format_header(options))
|
154
186
|
@nest_level -= 1
|
155
187
|
end
|
156
188
|
Howzit.inclusions.push(i_topic)
|
157
189
|
end
|
158
|
-
when /@(?<cmd>run|copy|open|url
|
190
|
+
when /@(?<cmd>run|copy|open|url)(?<optional>[?!]{1,2})?\((?<action>.*?)\) *(?<title>.*?)$/
|
159
191
|
m = Regexp.last_match.named_captures.symbolize_keys
|
160
192
|
cmd = m[:cmd]
|
161
193
|
obj = m[:action]
|
@@ -205,7 +237,8 @@ module Howzit
|
|
205
237
|
output.push(l)
|
206
238
|
end
|
207
239
|
end
|
208
|
-
|
240
|
+
Howzit.named_arguments = @named_args
|
241
|
+
output.push('').map(&:render_arguments)
|
209
242
|
end
|
210
243
|
|
211
244
|
private
|
@@ -228,6 +261,7 @@ module Howzit
|
|
228
261
|
@content.scan(rx) { matches << Regexp.last_match }
|
229
262
|
matches.each do |m|
|
230
263
|
c = m.named_captures.symbolize_keys
|
264
|
+
Howzit.named_arguments = @named_args
|
231
265
|
|
232
266
|
if c[:cmd].nil?
|
233
267
|
optional = c[:optional2] =~ /[?!]{1,2}/ ? true : false
|
@@ -237,7 +271,7 @@ module Howzit
|
|
237
271
|
runnable << Howzit::Task.new({ type: :block,
|
238
272
|
title: title,
|
239
273
|
action: block,
|
240
|
-
parent:
|
274
|
+
parent: self },
|
241
275
|
optional: optional,
|
242
276
|
default: default)
|
243
277
|
else
|
@@ -258,10 +292,20 @@ module Howzit
|
|
258
292
|
# end
|
259
293
|
# runnable.concat(tasks)
|
260
294
|
# end
|
295
|
+
args = []
|
296
|
+
if title =~ /\[(.*?)\] *$/
|
297
|
+
Howzit.named_arguments = @named_args
|
298
|
+
args = Regexp.last_match(1).split(/ *, */).map(&:render_arguments)
|
299
|
+
Howzit.arguments = args
|
300
|
+
arguments
|
301
|
+
title.sub!(/ *\[.*?\] *$/, '')
|
302
|
+
end
|
303
|
+
|
261
304
|
runnable << Howzit::Task.new({ type: :include,
|
305
|
+
arguments: Howzit.named_arguments,
|
262
306
|
title: title,
|
263
307
|
action: obj,
|
264
|
-
parent:
|
308
|
+
parent: self },
|
265
309
|
optional: optional,
|
266
310
|
default: default)
|
267
311
|
when /run/i
|
@@ -269,7 +313,7 @@ module Howzit
|
|
269
313
|
runnable << Howzit::Task.new({ type: :run,
|
270
314
|
title: title,
|
271
315
|
action: obj,
|
272
|
-
parent:
|
316
|
+
parent: self },
|
273
317
|
optional: optional,
|
274
318
|
default: default)
|
275
319
|
when /copy/i
|
@@ -277,14 +321,14 @@ module Howzit
|
|
277
321
|
runnable << Howzit::Task.new({ type: :copy,
|
278
322
|
title: title,
|
279
323
|
action: Shellwords.escape(obj),
|
280
|
-
parent:
|
324
|
+
parent: self },
|
281
325
|
optional: optional,
|
282
326
|
default: default)
|
283
327
|
when /open|url/i
|
284
328
|
runnable << Howzit::Task.new({ type: :open,
|
285
329
|
title: title,
|
286
330
|
action: obj,
|
287
|
-
parent:
|
331
|
+
parent: self },
|
288
332
|
optional: optional,
|
289
333
|
default: default)
|
290
334
|
end
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
@@ -45,7 +45,7 @@ HEADER_FORMAT_OPTIONS = %w[border block].freeze
|
|
45
45
|
# Main module for howzit
|
46
46
|
module Howzit
|
47
47
|
class << self
|
48
|
-
attr_accessor :arguments, :cli_args
|
48
|
+
attr_accessor :arguments, :named_arguments, :cli_args
|
49
49
|
##
|
50
50
|
## Holds a Configuration object with methods and a @settings hash
|
51
51
|
##
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Terpstra
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|