howzit 1.2.10 → 1.2.13
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/.gitignore +1 -0
- data/CHANGELOG.md +21 -4
- data/Gemfile +2 -0
- data/Guardfile +3 -1
- data/README.md +1 -0
- data/Rakefile +20 -2
- data/bin/howzit +4 -2
- data/howzit.gemspec +1 -1
- data/lib/howzit/buildnotes.rb +124 -100
- data/lib/howzit/colors.rb +323 -0
- data/lib/howzit/prompt.rb +3 -0
- data/lib/howzit/stringutils.rb +1 -1
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +1 -0
- data/spec/ruby_gem_spec.rb +30 -1
- data/spec/spec_helper.rb +8 -8
- metadata +3 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36a27d1566deff8857d39035c0e40f696a29d78b7ae24274a73ceacc54541321
|
4
|
+
data.tar.gz: 7b13d6644bf397e10f629689b159102a33dd5aa2c3610f368819de3dc8736007
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9da1ea212df950e75a34006a44b0ade09c02fd4fe7c02ea0fddfffcf2936e6ca5db0d7f0c9e6cc44aac3d65eb4544aa9d4c03c156487f9311f39f08ee12199d4
|
7
|
+
data.tar.gz: 99f9be58ff9184a2f96e7db6fed83e3fc19f0945e31c9d58daa32db022b175a8c99a329a9c023528af52100f46583ac892091eb04ed5d9e9e791087fe8f8c82d
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
### 1.2.13
|
2
|
+
|
3
|
+
2022-08-01 20:50
|
4
|
+
|
5
|
+
### 1.2.12
|
6
|
+
|
7
|
+
2022-08-01 16:23
|
8
|
+
|
9
|
+
#### IMPROVED
|
10
|
+
|
11
|
+
- Replace ANSI escape codes with color template system
|
12
|
+
- When @including an external file, if the file doesn't contain any level 2+ headers, import it as plain text.
|
13
|
+
|
14
|
+
### 1.2.11
|
15
|
+
|
16
|
+
2022-08-01 08:23
|
17
|
+
|
18
|
+
#### IMPROVED
|
19
|
+
|
20
|
+
- Code cleanup and refactoring
|
21
|
+
|
1
22
|
### 1.2.10
|
2
23
|
|
3
24
|
2022-08-01 07:45
|
@@ -6,10 +27,6 @@
|
|
6
27
|
|
7
28
|
- Headline formatting when iTerm markers are inserted
|
8
29
|
|
9
|
-
### 1.2.9
|
10
|
-
|
11
|
-
2022-08-01 07:09
|
12
|
-
|
13
30
|
### 1.2.8
|
14
31
|
|
15
32
|
2022-08-01 07:01
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Howzit
|
2
2
|
|
3
3
|
[](https://rubygems.org/gems/howzit)
|
4
|
+
[](https://travis-ci.org/makenew/ruby-gem)
|
4
5
|
[](./LICENSE.txt)
|
5
6
|
|
6
7
|
A command-line reference tool for tracking project build systems
|
data/Rakefile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bump/tasks'
|
2
4
|
require 'bundler/gem_tasks'
|
3
5
|
require 'rspec/core/rake_task'
|
4
6
|
require 'rubocop/rake_task'
|
5
7
|
require 'yard'
|
6
8
|
|
7
|
-
task default: [
|
9
|
+
task default: %i[test yard]
|
8
10
|
|
9
11
|
desc 'Run test suite'
|
10
|
-
task test: [
|
12
|
+
task test: %i[rubocop spec]
|
11
13
|
|
12
14
|
RSpec::Core::RakeTask.new
|
13
15
|
|
@@ -16,3 +18,19 @@ RuboCop::RakeTask.new do |t|
|
|
16
18
|
end
|
17
19
|
|
18
20
|
YARD::Rake::YardocTask.new
|
21
|
+
|
22
|
+
desc 'Development version check'
|
23
|
+
task :ver do
|
24
|
+
gver = `git ver`
|
25
|
+
cver = IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
26
|
+
res = `grep VERSION lib/howzit/version.rb`
|
27
|
+
version = res.match(/VERSION *= *['"](\d+\.\d+\.\d+(\w+)?)/)[1]
|
28
|
+
puts "git tag: #{gver}"
|
29
|
+
puts "version.rb: #{version}"
|
30
|
+
puts "changelog: #{cver}"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Changelog version check'
|
34
|
+
task :cver do
|
35
|
+
puts IO.read(File.join(File.dirname(__FILE__), 'CHANGELOG.md')).match(/^#+ (\d+\.\d+\.\d+(\w+)?)/)[1]
|
36
|
+
end
|
data/bin/howzit
CHANGED
data/howzit.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_development_dependency 'rubocop', '~> 0.28'
|
32
32
|
spec.add_development_dependency 'rspec', '~> 3.1'
|
33
33
|
spec.add_development_dependency 'simplecov', '~> 0.9'
|
34
|
-
spec.add_development_dependency 'codecov', '~> 0.1'
|
34
|
+
# spec.add_development_dependency 'codecov', '~> 0.1'
|
35
35
|
spec.add_development_dependency 'fuubar', '~> 2.0'
|
36
36
|
|
37
37
|
spec.add_development_dependency 'yard', '~> 0.9.5'
|
data/lib/howzit/buildnotes.rb
CHANGED
@@ -2,8 +2,9 @@ module Howzit
|
|
2
2
|
# Primary Class for this module
|
3
3
|
class BuildNotes
|
4
4
|
include Prompt
|
5
|
+
include Color
|
5
6
|
|
6
|
-
attr_accessor :arguments, :metadata
|
7
|
+
attr_accessor :cli_args, :options, :arguments, :metadata
|
7
8
|
|
8
9
|
def topics
|
9
10
|
@topics ||= read_help
|
@@ -40,8 +41,8 @@ module Howzit
|
|
40
41
|
# favoring environment settings
|
41
42
|
def which_pager
|
42
43
|
if @options[:pager] =~ /auto/i
|
43
|
-
pagers = [ENV['
|
44
|
-
'bat', 'less', 'more', '
|
44
|
+
pagers = [ENV['PAGER'], ENV['GIT_PAGER'],
|
45
|
+
'bat', 'less', 'more', 'pager']
|
45
46
|
pagers.delete_if(&:nil?).select!(&:available?)
|
46
47
|
return nil if pagers.empty?
|
47
48
|
|
@@ -145,12 +146,12 @@ module Howzit
|
|
145
146
|
choices.each do |choice|
|
146
147
|
case choice
|
147
148
|
when /[A-Z]/
|
148
|
-
out.push("
|
149
|
+
out.push(Color.template("{bg}#{choice}{xg}"))
|
149
150
|
else
|
150
|
-
out.push(choice)
|
151
|
+
out.push(Color.template("{w}#{choice}"))
|
151
152
|
end
|
152
153
|
end
|
153
|
-
"
|
154
|
+
Color.template("{g}[#{out.join('/')}{g}]{x}")
|
154
155
|
end
|
155
156
|
|
156
157
|
# Create a buildnotes skeleton
|
@@ -159,30 +160,40 @@ module Howzit
|
|
159
160
|
warn "\nCanceled"
|
160
161
|
exit!
|
161
162
|
end
|
163
|
+
default = !$stdout.isatty || @options[:default]
|
162
164
|
# First make sure there isn't already a buildnotes file
|
163
165
|
if note_file
|
164
|
-
fname = "
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
166
|
+
fname = Color.template("{by}#{note_file}{bw}")
|
167
|
+
unless default
|
168
|
+
res = yn("#{fname} exists and appears to be a build note, continue anyway?", false)
|
169
|
+
unless res
|
170
|
+
puts 'Canceled'
|
171
|
+
Process.exit 0
|
172
|
+
end
|
169
173
|
end
|
170
174
|
end
|
171
175
|
|
172
176
|
title = File.basename(Dir.pwd)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
+
if default
|
178
|
+
input = title
|
179
|
+
else
|
180
|
+
printf Color.template("{bw}Project name {xg}[#{title}]{bw}: {x}")
|
181
|
+
input = $stdin.gets.chomp
|
182
|
+
title = input unless input.empty?
|
183
|
+
end
|
177
184
|
summary = ''
|
178
|
-
|
179
|
-
|
180
|
-
|
185
|
+
unless default
|
186
|
+
printf Color.template('{bw}Project summary: {x}')
|
187
|
+
input = $stdin.gets.chomp
|
188
|
+
summary = input unless input.empty?
|
189
|
+
end
|
181
190
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
191
|
+
fname = 'buildnotes.md'
|
192
|
+
unless default
|
193
|
+
printf Color.template("{bw}Build notes filename (must begin with 'howzit' or 'build')\n{xg}[#{fname}]{bw}: {x}")
|
194
|
+
input = $stdin.gets.chomp
|
195
|
+
fname = input unless input.empty?
|
196
|
+
end
|
186
197
|
|
187
198
|
note = <<~EOBUILDNOTES
|
188
199
|
# #{title}
|
@@ -209,8 +220,8 @@ module Howzit
|
|
209
220
|
|
210
221
|
EOBUILDNOTES
|
211
222
|
|
212
|
-
if File.exist?(
|
213
|
-
file = "
|
223
|
+
if File.exist?(fname) && !default
|
224
|
+
file = Color.template("{by}#{fname}")
|
214
225
|
res = yn("Are you absolutely sure you want to overwrite #{file}", false)
|
215
226
|
|
216
227
|
unless res
|
@@ -219,9 +230,9 @@ module Howzit
|
|
219
230
|
end
|
220
231
|
end
|
221
232
|
|
222
|
-
File.open(
|
233
|
+
File.open(fname, 'w') do |f|
|
223
234
|
f.puts note
|
224
|
-
puts "Build notes for #{title} written to #{
|
235
|
+
puts Color.template("{by}Build notes for #{title} written to #{fname}")
|
225
236
|
end
|
226
237
|
end
|
227
238
|
|
@@ -229,8 +240,8 @@ module Howzit
|
|
229
240
|
def format_header(title, opts = {})
|
230
241
|
options = {
|
231
242
|
hr: "\u{254C}",
|
232
|
-
color: '
|
233
|
-
border: '
|
243
|
+
color: '{bg}',
|
244
|
+
border: '{x}',
|
234
245
|
mark: false
|
235
246
|
}
|
236
247
|
|
@@ -239,29 +250,29 @@ module Howzit
|
|
239
250
|
cols = TTY::Screen.columns
|
240
251
|
|
241
252
|
cols = @options[:wrap] if (@options[:wrap]).positive? && cols > @options[:wrap]
|
242
|
-
title = "
|
253
|
+
title = Color.template("#{options[:border]}#{options[:hr] * 2}( #{options[:color]}#{title}#{options[:border]} )")
|
243
254
|
|
244
255
|
tail = if should_mark_iterm?
|
245
256
|
"#{options[:hr] * (cols - title.uncolor.length - 15)}#{options[:mark] ? iterm_marker : ''}"
|
246
257
|
else
|
247
258
|
options[:hr] * (cols - title.uncolor.length)
|
248
259
|
end
|
249
|
-
"#{title}#{tail}
|
260
|
+
Color.template("#{title}#{tail}{x}")
|
250
261
|
end
|
251
262
|
|
252
263
|
def os_open(command)
|
253
264
|
os = RbConfig::CONFIG['target_os']
|
254
|
-
out = "
|
265
|
+
out = Color.template("{bg}Opening {bw}#{command}")
|
255
266
|
case os
|
256
267
|
when /darwin.*/i
|
257
|
-
warn "#{out} (macOS)
|
268
|
+
warn Color.template("#{out} (macOS){x}") if @options[:log_level] < 2
|
258
269
|
`open #{Shellwords.escape(command)}`
|
259
270
|
when /mingw|mswin/i
|
260
|
-
warn "#{out} (Windows)
|
271
|
+
warn Color.template("#{out} (Windows){x}") if @options[:log_level] < 2
|
261
272
|
`start #{Shellwords.escape(command)}`
|
262
273
|
else
|
263
274
|
if 'xdg-open'.available?
|
264
|
-
warn "#{out} (Linux)
|
275
|
+
warn Color.template("#{out} (Linux){x}") if @options[:log_level] < 2
|
265
276
|
`xdg-open #{Shellwords.escape(command)}`
|
266
277
|
else
|
267
278
|
warn out if @options[:log_level] < 2
|
@@ -300,7 +311,7 @@ module Howzit
|
|
300
311
|
directives.each do |c|
|
301
312
|
if c[0].nil?
|
302
313
|
title = c[3] ? c[3].strip : ''
|
303
|
-
warn "
|
314
|
+
warn Color.template("{bg}Running block {bw}#{title}{x}") if @options[:log_level] < 2
|
304
315
|
block = c[4].strip
|
305
316
|
script = Tempfile.new('howzit_script')
|
306
317
|
begin
|
@@ -322,18 +333,18 @@ module Howzit
|
|
322
333
|
warn "No topic match for @include(#{search})"
|
323
334
|
else
|
324
335
|
if @included.include?(matches[0])
|
325
|
-
warn "
|
336
|
+
warn Color.template("{by}Tasks from {bw}#{matches[0]} already included, skipping{x}") if @options[:log_level] < 2
|
326
337
|
else
|
327
|
-
warn "
|
338
|
+
warn Color.template("{by}Including tasks from {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
328
339
|
process_topic(matches[0], true)
|
329
|
-
warn "
|
340
|
+
warn Color.template("{by}End include {bw}#{matches[0]}{x}") if @options[:log_level] < 2
|
330
341
|
end
|
331
342
|
end
|
332
343
|
when /run/i
|
333
|
-
warn "
|
344
|
+
warn Color.template("{bg}Running {bw}#{obj}{x}") if @options[:log_level] < 2
|
334
345
|
system(obj)
|
335
346
|
when /copy/i
|
336
|
-
warn "
|
347
|
+
warn Color.template("{bg}Copied {bw}#{obj}{bg} to clipboard{x}") if @options[:log_level] < 2
|
337
348
|
`echo #{Shellwords.escape(obj)}'\\c'|pbcopy`
|
338
349
|
when /open|url/i
|
339
350
|
os_open(obj)
|
@@ -341,7 +352,7 @@ module Howzit
|
|
341
352
|
end
|
342
353
|
end
|
343
354
|
else
|
344
|
-
warn "
|
355
|
+
warn Color.template("{r}--run: No {br}@directive{xr} found in {bw}#{key}{x}")
|
345
356
|
end
|
346
357
|
output.push("Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}") if @options[:log_level] < 2
|
347
358
|
|
@@ -371,12 +382,12 @@ module Howzit
|
|
371
382
|
unless matches.empty?
|
372
383
|
if opt[:single]
|
373
384
|
title = "From #{matches[0]}:"
|
374
|
-
color = '
|
375
|
-
rule = '
|
385
|
+
color = '{yK}'
|
386
|
+
rule = '{kK}'
|
376
387
|
else
|
377
388
|
title = "Include #{matches[0]}"
|
378
|
-
color = '
|
379
|
-
rule = '
|
389
|
+
color = '{yK}'
|
390
|
+
rule = '{x}'
|
380
391
|
end
|
381
392
|
output.push(format_header("#{'> ' * @nest_level}#{title}", { color: color, hr: '.', border: rule })) unless @included.include?(matches[0])
|
382
393
|
|
@@ -405,15 +416,15 @@ module Howzit
|
|
405
416
|
when /open|url/
|
406
417
|
"\u{279A}"
|
407
418
|
end
|
408
|
-
output.push("
|
419
|
+
output.push(Color.template("{bmK}#{icon} {bwK}#{obj}{x}"))
|
409
420
|
when /(`{3,})run *(.*?)$/i
|
410
421
|
m = Regexp.last_match
|
411
422
|
desc = m[2].length.positive? ? "Block: #{m[2]}" : 'Code Block'
|
412
|
-
output.push("\
|
423
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}\n```"))
|
413
424
|
when /@@@run *(.*?)$/i
|
414
425
|
m = Regexp.last_match
|
415
426
|
desc = m[1].length.positive? ? "Block: #{m[1]}" : 'Code Block'
|
416
|
-
output.push("\
|
427
|
+
output.push(Color.template("{bmK}\u{25B6} {bwK}#{desc}{x}"))
|
417
428
|
else
|
418
429
|
l.wrap!(@options[:wrap]) if (@options[:wrap]).positive?
|
419
430
|
output.push(l)
|
@@ -444,9 +455,9 @@ module Howzit
|
|
444
455
|
# Output a list of topic titles
|
445
456
|
def list_topics
|
446
457
|
output = []
|
447
|
-
output.push("\
|
458
|
+
output.push(Color.template("{bg}Topics:{x}\n"))
|
448
459
|
topics.each_key do |title|
|
449
|
-
output.push("-
|
460
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
450
461
|
end
|
451
462
|
output.join("\n")
|
452
463
|
end
|
@@ -456,14 +467,14 @@ module Howzit
|
|
456
467
|
topics.keys.join("\n")
|
457
468
|
end
|
458
469
|
|
459
|
-
def get_note_title(
|
470
|
+
def get_note_title(truncate = 0)
|
460
471
|
title = nil
|
461
|
-
help = IO.read(
|
472
|
+
help = IO.read(note_file).strip
|
462
473
|
title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
|
463
474
|
title = if title
|
464
475
|
title[1].nil? ? title[2] : title[1]
|
465
476
|
else
|
466
|
-
|
477
|
+
note_file.sub(/(\.\w+)?$/, '')
|
467
478
|
end
|
468
479
|
|
469
480
|
title && truncate.positive? ? title.trunc(truncate) : title
|
@@ -486,7 +497,7 @@ module Howzit
|
|
486
497
|
|
487
498
|
def list_runnable
|
488
499
|
output = []
|
489
|
-
output.push(%(
|
500
|
+
output.push(Color.template(%({bg}"Runnable" Topics:{x}\n)))
|
490
501
|
topics.each do |title, sect|
|
491
502
|
s_out = []
|
492
503
|
lines = sect.split(/\n/)
|
@@ -507,7 +518,7 @@ module Howzit
|
|
507
518
|
end
|
508
519
|
end
|
509
520
|
unless s_out.empty?
|
510
|
-
output.push("-
|
521
|
+
output.push(Color.template("- {bw}#{title}{x}"))
|
511
522
|
output.push(s_out.join("\n"))
|
512
523
|
end
|
513
524
|
end
|
@@ -531,8 +542,8 @@ module Howzit
|
|
531
542
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
532
543
|
required.each do |req|
|
533
544
|
unless @metadata.keys.include?(req.downcase)
|
534
|
-
warn %(
|
535
|
-
warn %(
|
545
|
+
warn Color.template(%({xr}ERROR: Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}))
|
546
|
+
warn Color.template(%({xr}Please define {by}#{req.downcase}{xr} in build notes{x}))
|
536
547
|
Process.exit 1
|
537
548
|
end
|
538
549
|
end
|
@@ -581,6 +592,24 @@ module Howzit
|
|
581
592
|
template_topics
|
582
593
|
end
|
583
594
|
|
595
|
+
def include_file(m)
|
596
|
+
file = File.expand_path(m[1])
|
597
|
+
|
598
|
+
return m[0] unless File.exist?(file)
|
599
|
+
|
600
|
+
content = IO.read(file)
|
601
|
+
home = ENV['HOME']
|
602
|
+
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
603
|
+
prefix = "#{short_path}/#{File.basename(file)}:"
|
604
|
+
parts = content.split(/^##+/)
|
605
|
+
parts.shift
|
606
|
+
if parts.empty?
|
607
|
+
content
|
608
|
+
else
|
609
|
+
"## #{parts.join('## ')}".gsub(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
584
613
|
# Read in the build notes file and output a hash of "Title" => contents
|
585
614
|
def read_help_file(path = nil)
|
586
615
|
filename = path.nil? ? note_file : path
|
@@ -588,21 +617,7 @@ module Howzit
|
|
588
617
|
help = IO.read(filename)
|
589
618
|
|
590
619
|
help.gsub!(/@include\((.*?)\)/) do
|
591
|
-
|
592
|
-
file = File.expand_path(m[1])
|
593
|
-
if File.exist?(file)
|
594
|
-
content = IO.read(file)
|
595
|
-
home = ENV['HOME']
|
596
|
-
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
597
|
-
prefix = "#{short_path}:"
|
598
|
-
parts = content.split(/^##+/)
|
599
|
-
parts.shift
|
600
|
-
content = '## ' + parts.join('## ')
|
601
|
-
content.gsub!(/^(##+ *)(?=\S)/, "\\1#{prefix}")
|
602
|
-
content
|
603
|
-
else
|
604
|
-
m[0]
|
605
|
-
end
|
620
|
+
include_file(Regexp.last_match)
|
606
621
|
end
|
607
622
|
|
608
623
|
template_topics = get_template_topics(help)
|
@@ -673,7 +688,8 @@ module Howzit
|
|
673
688
|
matches
|
674
689
|
end
|
675
690
|
|
676
|
-
def initialize(args)
|
691
|
+
def initialize(args = [])
|
692
|
+
Color.coloring = $stdout.isatty
|
677
693
|
flags = {
|
678
694
|
run: false,
|
679
695
|
list_topics: false,
|
@@ -683,7 +699,8 @@ module Howzit
|
|
683
699
|
title_only: false,
|
684
700
|
choose: false,
|
685
701
|
quiet: false,
|
686
|
-
verbose: false
|
702
|
+
verbose: false,
|
703
|
+
default: false
|
687
704
|
}
|
688
705
|
|
689
706
|
defaults = {
|
@@ -716,7 +733,8 @@ module Howzit
|
|
716
733
|
OptionParser.new do |opts|
|
717
734
|
opts.banner = "Usage: #{__FILE__} [OPTIONS] [TOPIC]"
|
718
735
|
opts.separator ''
|
719
|
-
opts.separator 'Show build notes for the current project (buildnotes.md).
|
736
|
+
opts.separator 'Show build notes for the current project (buildnotes.md).
|
737
|
+
Include a topic name to see just that topic, or no argument to display all.'
|
720
738
|
opts.separator ''
|
721
739
|
opts.separator 'Options:'
|
722
740
|
|
@@ -725,7 +743,8 @@ module Howzit
|
|
725
743
|
Process.exit 0
|
726
744
|
end
|
727
745
|
|
728
|
-
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
746
|
+
opts.on('-e', '--edit', "Edit buildnotes file in current working directory
|
747
|
+
using $EDITOR") do
|
729
748
|
edit_note
|
730
749
|
Process.exit 0
|
731
750
|
end
|
@@ -743,7 +762,8 @@ module Howzit
|
|
743
762
|
@options[:list_topics] = true
|
744
763
|
end
|
745
764
|
|
746
|
-
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
765
|
+
opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
|
766
|
+
'Topics matching type', "(#{MATCHING_OPTIONS.join(', ')})") do |c|
|
747
767
|
@options[:matching] = c
|
748
768
|
end
|
749
769
|
|
@@ -776,8 +796,8 @@ module Howzit
|
|
776
796
|
@options[:log_level] = 0
|
777
797
|
end
|
778
798
|
|
779
|
-
opts.on('-u', '--upstream', 'Traverse up parent directories for additional build notes') do
|
780
|
-
@options[:include_upstream] =
|
799
|
+
opts.on('-u', '--[no-]upstream', 'Traverse up parent directories for additional build notes') do |p|
|
800
|
+
@options[:include_upstream] = p
|
781
801
|
end
|
782
802
|
|
783
803
|
opts.on('--show-code', 'Display the content of fenced run blocks') do
|
@@ -788,7 +808,7 @@ module Howzit
|
|
788
808
|
@options[:wrap] = w.to_i
|
789
809
|
end
|
790
810
|
|
791
|
-
opts.on('--edit-config', "Edit configuration file using
|
811
|
+
opts.on('--edit-config', "Edit configuration file using default $EDITOR") do
|
792
812
|
edit_config(defaults)
|
793
813
|
Process.exit 0
|
794
814
|
end
|
@@ -802,21 +822,21 @@ module Howzit
|
|
802
822
|
Dir.chdir(template_folder)
|
803
823
|
Dir.glob('*.md').each do |file|
|
804
824
|
template = File.basename(file, '.md')
|
805
|
-
puts "
|
806
|
-
puts "
|
825
|
+
puts Color.template("{Mk}template:{Yk}#{template}{x}")
|
826
|
+
puts Color.template("{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}")
|
807
827
|
metadata = file.extract_metadata
|
808
828
|
topics = read_help_file(file)
|
809
|
-
topics.
|
810
|
-
puts "
|
829
|
+
topics.each_key do |topic|
|
830
|
+
puts Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.sub(/^.*?:/, '')}{x}")
|
811
831
|
end
|
812
832
|
if metadata.size > 0
|
813
833
|
meta = []
|
814
|
-
meta << metadata['required'].split(/\s*,\s*/).map {|m| "
|
834
|
+
meta << metadata['required'].split(/\s*,\s*/).map {|m| "*{bw}#{m}{xw}" } if metadata.key?('required')
|
815
835
|
meta << metadata['optional'].split(/\s*,\s*/).map {|m| "#{m}" } if metadata.key?('optional')
|
816
|
-
puts "
|
817
|
-
puts "
|
836
|
+
puts Color.template("{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}")
|
837
|
+
puts Color.template(" {bk}│ {xw}#{meta.join(", ")}{x}")
|
818
838
|
end
|
819
|
-
puts "
|
839
|
+
puts Color.template(" {bk}└───────────────────────────────────────────┘{x}")
|
820
840
|
end
|
821
841
|
Process.exit 0
|
822
842
|
end
|
@@ -843,9 +863,13 @@ module Howzit
|
|
843
863
|
puts "Howzit v#{VERSION}"
|
844
864
|
Process.exit 0
|
845
865
|
end
|
866
|
+
|
867
|
+
opts.on('--default', 'Answer all prompts with default response') do
|
868
|
+
@options[:default] = true
|
869
|
+
end
|
846
870
|
end.parse!(args)
|
847
871
|
|
848
|
-
|
872
|
+
@cli_args = args
|
849
873
|
end
|
850
874
|
|
851
875
|
def edit_note
|
@@ -862,7 +886,7 @@ module Howzit
|
|
862
886
|
end
|
863
887
|
|
864
888
|
##
|
865
|
-
##
|
889
|
+
## Traverse up directory tree looking for build notes
|
866
890
|
##
|
867
891
|
## @return topics dictionary
|
868
892
|
##
|
@@ -1031,7 +1055,7 @@ module Howzit
|
|
1031
1055
|
File.join(config_dir, 'templates')
|
1032
1056
|
end
|
1033
1057
|
|
1034
|
-
def create_config
|
1058
|
+
def create_config(defaults)
|
1035
1059
|
dir, file = [config_dir, config_file]
|
1036
1060
|
unless File.directory?(dir)
|
1037
1061
|
warn "Creating config directory at #{dir}"
|
@@ -1046,7 +1070,7 @@ module Howzit
|
|
1046
1070
|
end
|
1047
1071
|
|
1048
1072
|
def load_config(defaults)
|
1049
|
-
file = create_config
|
1073
|
+
file = create_config(defaults)
|
1050
1074
|
config = YAML.load(IO.read(file))
|
1051
1075
|
newconfig = config ? defaults.merge(config) : defaults
|
1052
1076
|
write_config(newconfig)
|
@@ -1064,7 +1088,7 @@ module Howzit
|
|
1064
1088
|
`#{ENV['EDITOR']} "#{config_file}"`
|
1065
1089
|
end
|
1066
1090
|
|
1067
|
-
def process
|
1091
|
+
def process
|
1068
1092
|
output = []
|
1069
1093
|
|
1070
1094
|
unless note_file
|
@@ -1080,13 +1104,13 @@ module Howzit
|
|
1080
1104
|
end
|
1081
1105
|
|
1082
1106
|
if @options[:title_only]
|
1083
|
-
out = get_note_title(
|
1107
|
+
out = get_note_title(20)
|
1084
1108
|
$stdout.print(out.strip)
|
1085
1109
|
Process.exit(0)
|
1086
1110
|
elsif @options[:output_title]
|
1087
|
-
title = get_note_title
|
1111
|
+
title = get_note_title
|
1088
1112
|
if title && !title.empty?
|
1089
|
-
header = format_header(title, { hr: "\u{2550}", color: '
|
1113
|
+
header = format_header(title, { hr: "\u{2550}", color: '{bwK}' })
|
1090
1114
|
output.push("#{header}\n")
|
1091
1115
|
end
|
1092
1116
|
end
|
@@ -1118,14 +1142,14 @@ module Howzit
|
|
1118
1142
|
elsif @options[:choose]
|
1119
1143
|
topic_match = choose(topics.keys)
|
1120
1144
|
# If there are arguments use those to search for a matching topic
|
1121
|
-
elsif
|
1145
|
+
elsif !@cli_args.empty?
|
1122
1146
|
|
1123
|
-
search =
|
1147
|
+
search = @cli_args.join(' ').strip.downcase
|
1124
1148
|
matches = match_topic(search)
|
1125
1149
|
|
1126
1150
|
if matches.empty?
|
1127
|
-
output.push(%(
|
1128
|
-
|
1151
|
+
output.push(Color.template(%({bR}ERROR:{xr} No topic match found for {bw}#{search}{x}\n)))
|
1152
|
+
unless @options[:show_all_on_error]
|
1129
1153
|
show(output.join("\n"), { color: true, highlight: false, paginate: false, wrap: 0 })
|
1130
1154
|
Process.exit 1
|
1131
1155
|
end
|
@@ -0,0 +1,323 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Cribbed from <https://github.com/flori/term-ansicolor>
|
4
|
+
module Howzit
|
5
|
+
# Terminal output color functions.
|
6
|
+
module Color
|
7
|
+
ESCAPE_REGEX = /(?<=\[)(?:(?:(?:[349]|10)[0-9]|[0-9])?;?)+(?=m)/.freeze
|
8
|
+
# All available color names. Available as methods and string extensions.
|
9
|
+
#
|
10
|
+
# @example Use a color as a method. Color reset will be added to end of string.
|
11
|
+
# Color.yellow('This text is yellow') => "\e[33mThis text is yellow\e[0m"
|
12
|
+
#
|
13
|
+
# @example Use a color as a string extension. Color reset added automatically.
|
14
|
+
# 'This text is green'.green => "\e[1;32mThis text is green\e[0m"
|
15
|
+
#
|
16
|
+
# @example Send a text string as a color
|
17
|
+
# Color.send('red') => "\e[31m"
|
18
|
+
ATTRIBUTES = [
|
19
|
+
[:clear, 0], # String#clear is already used to empty string in Ruby 1.9
|
20
|
+
[:reset, 0], # synonym for :clear
|
21
|
+
[:bold, 1],
|
22
|
+
[:dark, 2],
|
23
|
+
[:italic, 3], # not widely implemented
|
24
|
+
[:underline, 4],
|
25
|
+
[:underscore, 4], # synonym for :underline
|
26
|
+
[:blink, 5],
|
27
|
+
[:rapid_blink, 6], # not widely implemented
|
28
|
+
[:negative, 7], # no reverse because of String#reverse
|
29
|
+
[:concealed, 8],
|
30
|
+
[:strikethrough, 9], # not widely implemented
|
31
|
+
[:strike, 9], # not widely implemented
|
32
|
+
[:black, 30],
|
33
|
+
[:red, 31],
|
34
|
+
[:green, 32],
|
35
|
+
[:yellow, 33],
|
36
|
+
[:blue, 34],
|
37
|
+
[:magenta, 35],
|
38
|
+
[:purple, 35],
|
39
|
+
[:cyan, 36],
|
40
|
+
[:white, 37],
|
41
|
+
[:bgblack, 40],
|
42
|
+
[:bgred, 41],
|
43
|
+
[:bggreen, 42],
|
44
|
+
[:bgyellow, 43],
|
45
|
+
[:bgblue, 44],
|
46
|
+
[:bgmagenta, 45],
|
47
|
+
[:bgpurple, 45],
|
48
|
+
[:bgcyan, 46],
|
49
|
+
[:bgwhite, 47],
|
50
|
+
[:boldblack, 90],
|
51
|
+
[:boldred, 91],
|
52
|
+
[:boldgreen, 92],
|
53
|
+
[:boldyellow, 93],
|
54
|
+
[:boldblue, 94],
|
55
|
+
[:boldmagenta, 95],
|
56
|
+
[:boldpurple, 95],
|
57
|
+
[:boldcyan, 96],
|
58
|
+
[:boldwhite, 97],
|
59
|
+
[:boldbgblack, 100],
|
60
|
+
[:boldbgred, 101],
|
61
|
+
[:boldbggreen, 102],
|
62
|
+
[:boldbgyellow, 103],
|
63
|
+
[:boldbgblue, 104],
|
64
|
+
[:boldbgmagenta, 105],
|
65
|
+
[:boldbgpurple, 105],
|
66
|
+
[:boldbgcyan, 106],
|
67
|
+
[:boldbgwhite, 107],
|
68
|
+
[:softpurple, '0;35;40'],
|
69
|
+
[:hotpants, '7;34;40'],
|
70
|
+
[:knightrider, '7;30;40'],
|
71
|
+
[:flamingo, '7;31;47'],
|
72
|
+
[:yeller, '1;37;43'],
|
73
|
+
[:whiteboard, '1;30;47'],
|
74
|
+
[:chalkboard, '1;37;40'],
|
75
|
+
[:led, '0;32;40'],
|
76
|
+
[:redacted, '0;30;40'],
|
77
|
+
[:alert, '1;31;43'],
|
78
|
+
[:error, '1;37;41'],
|
79
|
+
[:default, '0;39']
|
80
|
+
].map(&:freeze).freeze
|
81
|
+
|
82
|
+
ATTRIBUTE_NAMES = ATTRIBUTES.transpose.first
|
83
|
+
|
84
|
+
# Returns true if Howzit::Color supports the +feature+.
|
85
|
+
#
|
86
|
+
# The feature :clear, that is mixing the clear color attribute into String,
|
87
|
+
# is only supported on ruby implementations, that do *not* already
|
88
|
+
# implement the String#clear method. It's better to use the reset color
|
89
|
+
# attribute instead.
|
90
|
+
def support?(feature)
|
91
|
+
case feature
|
92
|
+
when :clear
|
93
|
+
!String.instance_methods(false).map(&:to_sym).include?(:clear)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Template coloring
|
98
|
+
class ::String
|
99
|
+
##
|
100
|
+
## Extract the longest valid %color name from a string.
|
101
|
+
##
|
102
|
+
## Allows %colors to bleed into other text and still
|
103
|
+
## be recognized, e.g. %greensomething still finds
|
104
|
+
## %green.
|
105
|
+
##
|
106
|
+
## @return [String] a valid color name
|
107
|
+
##
|
108
|
+
def validate_color
|
109
|
+
valid_color = nil
|
110
|
+
compiled = ''
|
111
|
+
normalize_color.split('').each do |char|
|
112
|
+
compiled += char
|
113
|
+
valid_color = compiled if Color.attributes.include?(compiled.to_sym) || compiled =~ /^([fb]g?)?#([a-f0-9]{6})$/i
|
114
|
+
end
|
115
|
+
|
116
|
+
valid_color
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
## Normalize a color name, removing underscores,
|
121
|
+
## replacing "bright" with "bold", and converting
|
122
|
+
## bgbold to boldbg
|
123
|
+
##
|
124
|
+
## @return [String] Normalized color name
|
125
|
+
##
|
126
|
+
def normalize_color
|
127
|
+
gsub(/_/, '').sub(/bright/i, 'bold').sub(/bgbold/, 'boldbg')
|
128
|
+
end
|
129
|
+
|
130
|
+
# Get the calculated ANSI color at the end of the
|
131
|
+
# string
|
132
|
+
#
|
133
|
+
# @return ANSI escape sequence to match color
|
134
|
+
#
|
135
|
+
def last_color_code
|
136
|
+
m = scan(ESCAPE_REGEX)
|
137
|
+
|
138
|
+
em = ['0']
|
139
|
+
fg = nil
|
140
|
+
bg = nil
|
141
|
+
rgbf = nil
|
142
|
+
rgbb = nil
|
143
|
+
|
144
|
+
m.each do |c|
|
145
|
+
case c
|
146
|
+
when '0'
|
147
|
+
em = ['0']
|
148
|
+
fg, bg, rgbf, rgbb = nil
|
149
|
+
when /^[34]8/
|
150
|
+
case c
|
151
|
+
when /^3/
|
152
|
+
fg = nil
|
153
|
+
rgbf = c
|
154
|
+
when /^4/
|
155
|
+
bg = nil
|
156
|
+
rgbb = c
|
157
|
+
end
|
158
|
+
else
|
159
|
+
c.split(/;/).each do |i|
|
160
|
+
x = i.to_i
|
161
|
+
if x <= 9
|
162
|
+
em << x
|
163
|
+
elsif x >= 30 && x <= 39
|
164
|
+
rgbf = nil
|
165
|
+
fg = x
|
166
|
+
elsif x >= 40 && x <= 49
|
167
|
+
rgbb = nil
|
168
|
+
bg = x
|
169
|
+
elsif x >= 90 && x <= 97
|
170
|
+
rgbf = nil
|
171
|
+
fg = x
|
172
|
+
elsif x >= 100 && x <= 107
|
173
|
+
rgbb = nil
|
174
|
+
bg = x
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
escape = "\e[#{em.join(';')}m"
|
181
|
+
escape += "\e[#{rgbb}m" if rgbb
|
182
|
+
escape += "\e[#{rgbf}m" if rgbf
|
183
|
+
escape + "\e[#{[fg, bg].delete_if(&:nil?).join(';')}m"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
class << self
|
188
|
+
# Returns true if the coloring function of this module
|
189
|
+
# is switched on, false otherwise.
|
190
|
+
def coloring?
|
191
|
+
@coloring
|
192
|
+
end
|
193
|
+
|
194
|
+
attr_writer :coloring
|
195
|
+
|
196
|
+
##
|
197
|
+
## Enables colored output
|
198
|
+
##
|
199
|
+
## @example Turn color on or off based on TTY
|
200
|
+
## Howzit::Color.coloring = STDOUT.isatty
|
201
|
+
def coloring
|
202
|
+
@coloring ||= true
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
## Convert a template string to a colored string.
|
207
|
+
## Colors are specified with single letters inside
|
208
|
+
## curly braces. Uppercase changes background color.
|
209
|
+
##
|
210
|
+
## w: white, k: black, g: green, l: blue, y: yellow, c: cyan,
|
211
|
+
## m: magenta, r: red, b: bold, u: underline, i: italic,
|
212
|
+
## x: reset (remove background, color, emphasis)
|
213
|
+
##
|
214
|
+
## @example Convert a templated string
|
215
|
+
## Color.template('{Rwb}Warning:{x} {w}you look a little {g}ill{x}')
|
216
|
+
##
|
217
|
+
## @param input [String, Array] The template
|
218
|
+
## string. If this is an array, the
|
219
|
+
## elements will be joined with a
|
220
|
+
## space.
|
221
|
+
##
|
222
|
+
## @return [String] Colorized string
|
223
|
+
##
|
224
|
+
def template(input)
|
225
|
+
input = input.join(' ') if input.is_a? Array
|
226
|
+
input.gsub!(/%/, '%%')
|
227
|
+
fmt = input.gsub(/\{(\w+)\}/) do
|
228
|
+
Regexp.last_match(1).split('').map { |c| "%<#{c}>s" }.join('')
|
229
|
+
end
|
230
|
+
|
231
|
+
colors = { w: white, k: black, g: green, l: blue,
|
232
|
+
y: yellow, c: cyan, m: magenta, r: red,
|
233
|
+
W: bgwhite, K: bgblack, G: bggreen, L: bgblue,
|
234
|
+
Y: bgyellow, C: bgcyan, M: bgmagenta, R: bgred,
|
235
|
+
b: bold, u: underline, i: italic, x: reset }
|
236
|
+
|
237
|
+
format(fmt, colors)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
ATTRIBUTES.each do |c, v|
|
242
|
+
new_method = <<-EOSCRIPT
|
243
|
+
def #{c}(string = nil)
|
244
|
+
result = ''
|
245
|
+
result << "\e[#{v}m" if Howzit::Color.coloring?
|
246
|
+
if block_given?
|
247
|
+
result << yield
|
248
|
+
elsif string.respond_to?(:to_str)
|
249
|
+
result << string.to_str
|
250
|
+
elsif respond_to?(:to_str)
|
251
|
+
result << to_str
|
252
|
+
else
|
253
|
+
return result #only switch on
|
254
|
+
end
|
255
|
+
result << "\e[0m" if Howzit::Color.coloring?
|
256
|
+
result
|
257
|
+
end
|
258
|
+
EOSCRIPT
|
259
|
+
|
260
|
+
module_eval(new_method)
|
261
|
+
|
262
|
+
next unless c =~ /bold/
|
263
|
+
|
264
|
+
# Accept brightwhite in addition to boldwhite
|
265
|
+
new_method = <<-EOSCRIPT
|
266
|
+
def #{c.to_s.sub(/bold/, 'bright')}(string = nil)
|
267
|
+
result = ''
|
268
|
+
result << "\e[#{v}m" if Howzit::Color.coloring?
|
269
|
+
if block_given?
|
270
|
+
result << yield
|
271
|
+
elsif string.respond_to?(:to_str)
|
272
|
+
result << string.to_str
|
273
|
+
elsif respond_to?(:to_str)
|
274
|
+
result << to_str
|
275
|
+
else
|
276
|
+
return result #only switch on
|
277
|
+
end
|
278
|
+
result << "\e[0m" if Howzit::Color.coloring?
|
279
|
+
result
|
280
|
+
end
|
281
|
+
EOSCRIPT
|
282
|
+
|
283
|
+
module_eval(new_method)
|
284
|
+
end
|
285
|
+
|
286
|
+
def rgb(hex)
|
287
|
+
is_bg = hex.match(/^bg?#/) ? true : false
|
288
|
+
hex_string = hex.sub(/^([fb]g?)?#/, '')
|
289
|
+
|
290
|
+
parts = hex_string.match(/(?<r>..)(?<g>..)(?<b>..)/)
|
291
|
+
t = []
|
292
|
+
%w[r g b].each do |e|
|
293
|
+
t << parts[e].hex
|
294
|
+
end
|
295
|
+
color =
|
296
|
+
"\e[#{is_bg ? '48' : '38'};2;#{t.join(';')}m"
|
297
|
+
end
|
298
|
+
|
299
|
+
# Regular expression that is used to scan for ANSI-sequences while
|
300
|
+
# uncoloring strings.
|
301
|
+
COLORED_REGEXP = /\e\[(?:(?:[349]|10)[0-7]|[0-9])?m/.freeze
|
302
|
+
|
303
|
+
# Returns an uncolored version of the string, that is all
|
304
|
+
# ANSI-sequences are stripped from the string.
|
305
|
+
def uncolor(string = nil) # :yields:
|
306
|
+
if block_given?
|
307
|
+
yield.to_str.gsub(COLORED_REGEXP, '')
|
308
|
+
elsif string.respond_to?(:to_str)
|
309
|
+
string.to_str.gsub(COLORED_REGEXP, '')
|
310
|
+
elsif respond_to?(:to_str)
|
311
|
+
to_str.gsub(COLORED_REGEXP, '')
|
312
|
+
else
|
313
|
+
''
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Returns an array of all Howzit::Color attributes as symbols.
|
318
|
+
def attributes
|
319
|
+
ATTRIBUTE_NAMES
|
320
|
+
end
|
321
|
+
extend self
|
322
|
+
end
|
323
|
+
end
|
data/lib/howzit/prompt.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Howzit
|
4
|
+
# Command line prompt utils
|
4
5
|
module Prompt
|
5
6
|
def yn(prompt, default = true)
|
7
|
+
return default if !$stdout.isatty
|
8
|
+
|
6
9
|
system 'stty cbreak'
|
7
10
|
yn = color_single_options(default ? %w[Y n] : %w[y N])
|
8
11
|
$stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m"
|
data/lib/howzit/stringutils.rb
CHANGED
@@ -5,7 +5,7 @@ module Howzit
|
|
5
5
|
module StringUtils
|
6
6
|
# Just strip out color codes when requested
|
7
7
|
def uncolor
|
8
|
-
gsub(/\e\[[\d;]+m/, '').gsub(/\e]1337;SetMark/,'')
|
8
|
+
gsub(/\e\[[\d;]+m/, '').gsub(/\e\]1337;SetMark/,'')
|
9
9
|
end
|
10
10
|
|
11
11
|
# Adapted from https://github.com/pazdera/word_wrap/,
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
data/spec/ruby_gem_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Howzit::BuildNotes do
|
4
|
-
subject(:ruby_gem) { Howzit::BuildNotes.new }
|
4
|
+
subject(:ruby_gem) { Howzit::BuildNotes.new([]) }
|
5
5
|
|
6
6
|
describe ".new" do
|
7
7
|
it "makes a new instance" do
|
@@ -9,3 +9,32 @@ describe Howzit::BuildNotes do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
describe Howzit::BuildNotes do
|
14
|
+
Dir.chdir('spec')
|
15
|
+
how = Howzit::BuildNotes.new(['--no-upstream', '--default'])
|
16
|
+
how.create_note
|
17
|
+
subject { how }
|
18
|
+
|
19
|
+
describe ".note_file" do
|
20
|
+
it "locates a build note file" do
|
21
|
+
expect(subject.note_file).not_to be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".grep_topics" do
|
26
|
+
it "found editable" do
|
27
|
+
expect(subject.grep_topics('editable')).to include('File Structure')
|
28
|
+
expect(subject.grep_topics('editable')).not_to include('Build')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ".list_topic_titles" do
|
33
|
+
it "found 4 topics" do
|
34
|
+
expect(subject.topics.keys.count).to eq 4
|
35
|
+
end
|
36
|
+
it "outputs a newline-separated string" do
|
37
|
+
expect(subject.list_topic_titles.scan(/\n/).count).to eq 3
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require 'simplecov'
|
1
|
+
# require 'simplecov'
|
2
2
|
|
3
|
-
SimpleCov.start
|
3
|
+
# SimpleCov.start
|
4
4
|
|
5
|
-
if ENV['CI'] == 'true'
|
6
|
-
|
7
|
-
|
8
|
-
else
|
9
|
-
|
10
|
-
end
|
5
|
+
# if ENV['CI'] == 'true'
|
6
|
+
# require 'codecov'
|
7
|
+
# SimpleCov.formatter = SimpleCov::Formatter::Codecov
|
8
|
+
# else
|
9
|
+
# SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
10
|
+
# end
|
11
11
|
|
12
12
|
require 'howzit'
|
13
13
|
|
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: 1.2.
|
4
|
+
version: 1.2.13
|
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-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -150,20 +150,6 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0.9'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: codecov
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0.1'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - "~>"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '0.1'
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
name: fuubar
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -283,6 +269,7 @@ files:
|
|
283
269
|
- lib/.rubocop.yml
|
284
270
|
- lib/howzit.rb
|
285
271
|
- lib/howzit/buildnotes.rb
|
272
|
+
- lib/howzit/colors.rb
|
286
273
|
- lib/howzit/prompt.rb
|
287
274
|
- lib/howzit/stringutils.rb
|
288
275
|
- lib/howzit/version.rb
|