howzit 2.0.34 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -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: 28505fefd411902ebd75d786f31e6967822aaff975dbb1f55bb13994e583b792
|
4
|
+
data.tar.gz: 105e760d5595f4b8664969b6258240d17fb16ede995d3698e2d7bb4a36276824
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 338ad20ebae27dc9d504671df84789be608fd73b123b1a7966ae5cd6c160c7543d21596df6c6b4268fb827f732d80f581d8cb15520f02b19cb27014f4903ff51
|
7
|
+
data.tar.gz: 6283e6c567425ea667e399ca338ccdea86023157b9b58709d1f006fd94f8b71286eba18f6c170a25d2cae4bbc571f79b0a667936ec162967115b7cdb8b374684
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
### 2.1.1
|
2
|
+
|
3
|
+
2023-03-07 09:47
|
4
|
+
|
5
|
+
#### FIXED
|
6
|
+
|
7
|
+
- Allow variables names to contain numbers and underscores
|
8
|
+
|
9
|
+
### 2.1.0
|
10
|
+
|
11
|
+
2023-03-07 09:24
|
12
|
+
|
13
|
+
#### NEW
|
14
|
+
|
15
|
+
- Use TOPIC_TITLE (var1, var2) to have access to ${var1} ${var2} in text and scripts, populated with positional variables on the command line
|
16
|
+
- Add a default (fallback) value to any variable placeholder with ${var_name:default value}
|
17
|
+
|
1
18
|
### 2.0.34
|
2
19
|
|
3
20
|
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-Z0-9_]+(?::.*?)?)\}/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.
|
4
|
+
version: 2.1.1
|
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
|