howzit 2.0.0 → 2.0.3
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 +7 -1
- data/CHANGELOG.md +29 -0
- data/howzit.gemspec +1 -1
- data/lib/howzit/buildnote.rb +17 -16
- data/lib/howzit/prompt.rb +11 -9
- data/lib/howzit/stringutils.rb +4 -0
- data/lib/howzit/topic.rb +47 -22
- data/lib/howzit/version.rb +2 -1
- data/spec/buildnote_spec.rb +69 -0
- data/spec/buildnotes.md.bak +22 -0
- data/spec/ruby_gem_spec.rb +2 -99
- data/spec/spec_helper.rb +45 -0
- data/spec/task_spec.rb +13 -0
- data/spec/topic_spec.rb +61 -0
- metadata +11 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: febb19742d97801e3dff8026e42e67997ee58e9de5c4e87cd5b9c6fc7ab20fef
|
|
4
|
+
data.tar.gz: 6de0abe65cd3860bf38ac516fbfdf566d2609f88d9c1d74cd51dba57ade056ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7ad5108294d5fca6e1e12e316311c4082ba82694a876d0c0b6ef41eb082041ca300144cdf4782c235245a1c30db031438dcfb4be1d2569af63f4fbbb3e81be7b
|
|
7
|
+
data.tar.gz: 66f51a8da16d89972ea0dbb7ecd209153d3e680d956e8a80d98af9288f014cf1367f89d3a1b42adf4471aace0da8ae2d5d75b6f617c602b5cd272c1361e8c3e9
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,32 @@
|
|
|
1
|
+
### 2.0.3
|
|
2
|
+
|
|
3
|
+
2022-08-04 05:31
|
|
4
|
+
|
|
5
|
+
#### IMPROVED
|
|
6
|
+
|
|
7
|
+
- General code cleanup
|
|
8
|
+
- Attempt at os agnostic @copy command, hopefully works on Windows and Linux systems
|
|
9
|
+
|
|
10
|
+
#### FIXED
|
|
11
|
+
|
|
12
|
+
- Not displaying action if title is missing
|
|
13
|
+
|
|
14
|
+
### 2.0.2
|
|
15
|
+
|
|
16
|
+
2022-08-03 18:26
|
|
17
|
+
|
|
18
|
+
#### IMPROVED
|
|
19
|
+
|
|
20
|
+
- If a title is provided after an @command, display it instead of the contents when viewing
|
|
21
|
+
|
|
22
|
+
### 2.0.1
|
|
23
|
+
|
|
24
|
+
2022-08-03 12:46
|
|
25
|
+
|
|
26
|
+
#### FIXED
|
|
27
|
+
|
|
28
|
+
- Failure to create new notes file when one isn't found
|
|
29
|
+
|
|
1
30
|
### 2.0.0
|
|
2
31
|
|
|
3
32
|
2022-08-03 12:37
|
data/howzit.gemspec
CHANGED
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(features|spec|test)/})
|
|
18
18
|
spec.require_paths = ['lib']
|
|
19
19
|
|
|
20
|
-
spec.required_ruby_version = '>= 2.0
|
|
20
|
+
spec.required_ruby_version = '>= 2.6.0'
|
|
21
21
|
|
|
22
22
|
spec.add_development_dependency 'bundler', '~> 2.2'
|
|
23
23
|
spec.add_development_dependency 'rake', '~> 11.2'
|
data/lib/howzit/buildnote.rb
CHANGED
|
@@ -9,6 +9,7 @@ module Howzit
|
|
|
9
9
|
|
|
10
10
|
def initialize(file: nil, args: [])
|
|
11
11
|
@topics = []
|
|
12
|
+
create_note if note_file.nil?
|
|
12
13
|
@metadata = IO.read(note_file).split(/^#/)[0].strip.get_metadata
|
|
13
14
|
|
|
14
15
|
read_help(file)
|
|
@@ -40,9 +41,9 @@ module Howzit
|
|
|
40
41
|
# Output a list of topic titles
|
|
41
42
|
def list
|
|
42
43
|
output = []
|
|
43
|
-
output.push(
|
|
44
|
+
output.push("{bg}Topics:{x}\n".c)
|
|
44
45
|
@topics.each do |topic|
|
|
45
|
-
output.push(
|
|
46
|
+
output.push("- {bw}#{topic.title}{x}".c)
|
|
46
47
|
end
|
|
47
48
|
output.join("\n")
|
|
48
49
|
end
|
|
@@ -65,7 +66,7 @@ module Howzit
|
|
|
65
66
|
|
|
66
67
|
def list_runnable
|
|
67
68
|
output = []
|
|
68
|
-
output.push(
|
|
69
|
+
output.push(%({bg}"Runnable" Topics:{x}\n).c)
|
|
69
70
|
@topics.each do |topic|
|
|
70
71
|
s_out = []
|
|
71
72
|
|
|
@@ -74,7 +75,7 @@ module Howzit
|
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
unless s_out.empty?
|
|
77
|
-
output.push(
|
|
78
|
+
output.push("- {bw}#{topic.title}{x}".c)
|
|
78
79
|
output.push(s_out.join("\n"))
|
|
79
80
|
end
|
|
80
81
|
end
|
|
@@ -94,9 +95,9 @@ module Howzit
|
|
|
94
95
|
default = !$stdout.isatty || Howzit.options[:default]
|
|
95
96
|
# First make sure there isn't already a buildnotes file
|
|
96
97
|
if note_file
|
|
97
|
-
fname =
|
|
98
|
+
fname = "{by}#{note_file}{bw}".c
|
|
98
99
|
unless default
|
|
99
|
-
res = Prompt.yn("#{fname} exists and appears to be a build note, continue anyway?", false)
|
|
100
|
+
res = Prompt.yn("#{fname} exists and appears to be a build note, continue anyway?", default: false)
|
|
100
101
|
unless res
|
|
101
102
|
puts 'Canceled'
|
|
102
103
|
Process.exit 0
|
|
@@ -108,20 +109,20 @@ module Howzit
|
|
|
108
109
|
if default
|
|
109
110
|
input = title
|
|
110
111
|
else
|
|
111
|
-
printf
|
|
112
|
+
printf "{bw}Project name {xg}[#{title}]{bw}: {x}".c
|
|
112
113
|
input = $stdin.gets.chomp
|
|
113
114
|
title = input unless input.empty?
|
|
114
115
|
end
|
|
115
116
|
summary = ''
|
|
116
117
|
unless default
|
|
117
|
-
printf
|
|
118
|
+
printf '{bw}Project summary: {x}'.c
|
|
118
119
|
input = $stdin.gets.chomp
|
|
119
120
|
summary = input unless input.empty?
|
|
120
121
|
end
|
|
121
122
|
|
|
122
123
|
fname = 'buildnotes.md'
|
|
123
124
|
unless default
|
|
124
|
-
printf
|
|
125
|
+
printf "{bw}Build notes filename (must begin with 'howzit' or 'build')\n{xg}[#{fname}]{bw}: {x}".c
|
|
125
126
|
input = $stdin.gets.chomp
|
|
126
127
|
fname = input unless input.empty?
|
|
127
128
|
end
|
|
@@ -152,8 +153,8 @@ module Howzit
|
|
|
152
153
|
EOBUILDNOTES
|
|
153
154
|
|
|
154
155
|
if File.exist?(fname) && !default
|
|
155
|
-
file =
|
|
156
|
-
res = Prompt.yn("Are you absolutely sure you want to overwrite #{file}", false)
|
|
156
|
+
file = "{by}#{fname}".c
|
|
157
|
+
res = Prompt.yn("Are you absolutely sure you want to overwrite #{file}", default: false)
|
|
157
158
|
|
|
158
159
|
unless res
|
|
159
160
|
puts 'Canceled'
|
|
@@ -163,7 +164,7 @@ module Howzit
|
|
|
163
164
|
|
|
164
165
|
File.open(fname, 'w') do |f|
|
|
165
166
|
f.puts note
|
|
166
|
-
puts
|
|
167
|
+
puts "{by}Build notes for #{title} written to #{fname}".c
|
|
167
168
|
end
|
|
168
169
|
end
|
|
169
170
|
|
|
@@ -258,8 +259,8 @@ module Howzit
|
|
|
258
259
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
|
259
260
|
required.each do |req|
|
|
260
261
|
unless @metadata.keys.include?(req.downcase)
|
|
261
|
-
warn
|
|
262
|
-
warn
|
|
262
|
+
warn %({xr}ERROR: Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}).c
|
|
263
|
+
warn %({xr}Please define {by}#{req.downcase}{xr} in build notes{x}).c
|
|
263
264
|
Process.exit 1
|
|
264
265
|
end
|
|
265
266
|
end
|
|
@@ -409,7 +410,7 @@ module Howzit
|
|
|
409
410
|
raise "Invalid editor (#{editor})" unless Util.valid_command?(editor)
|
|
410
411
|
|
|
411
412
|
if note_file.nil?
|
|
412
|
-
res = Prompt.yn('No build notes file found, create one?', true)
|
|
413
|
+
res = Prompt.yn('No build notes file found, create one?', default: true)
|
|
413
414
|
|
|
414
415
|
create_note if res
|
|
415
416
|
edit_note
|
|
@@ -499,7 +500,7 @@ module Howzit
|
|
|
499
500
|
matches = find_topic(s)
|
|
500
501
|
|
|
501
502
|
if matches.empty?
|
|
502
|
-
output.push(
|
|
503
|
+
output.push(%({bR}ERROR:{xr} No topic match found for {bw}#{s}{x}\n).c)
|
|
503
504
|
else
|
|
504
505
|
case Howzit.options[:multiple_matches]
|
|
505
506
|
when :first
|
data/lib/howzit/prompt.rb
CHANGED
|
@@ -4,16 +4,18 @@ module Howzit
|
|
|
4
4
|
# Command line prompt utils
|
|
5
5
|
module Prompt
|
|
6
6
|
class << self
|
|
7
|
-
def yn(prompt, default
|
|
8
|
-
return default
|
|
7
|
+
def yn(prompt, default: true)
|
|
8
|
+
return default unless $stdout.isatty
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
return default if Howzit.options[:default]
|
|
11
|
+
|
|
12
|
+
system 'stty cbreak'
|
|
13
|
+
yn = color_single_options(default ? %w[Y n] : %w[y N])
|
|
14
|
+
$stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m"
|
|
15
|
+
res = $stdin.sysread 1
|
|
16
|
+
res.chomp!
|
|
17
|
+
puts
|
|
18
|
+
system 'stty cooked'
|
|
17
19
|
res.empty? ? default : res =~ /y/i
|
|
18
20
|
end
|
|
19
21
|
|
data/lib/howzit/stringutils.rb
CHANGED
data/lib/howzit/topic.rb
CHANGED
|
@@ -28,14 +28,14 @@ module Howzit
|
|
|
28
28
|
if @tasks.count.positive?
|
|
29
29
|
unless @prereqs.empty?
|
|
30
30
|
puts @prereqs.join("\n\n")
|
|
31
|
-
res = Prompt.yn('This task has prerequisites, have they been met?', true)
|
|
31
|
+
res = Prompt.yn('This task has prerequisites, have they been met?', default: true)
|
|
32
32
|
Process.exit 1 unless res
|
|
33
33
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
@tasks.each do |task|
|
|
37
37
|
if task.type == :block
|
|
38
|
-
warn
|
|
38
|
+
warn "{bg}Running block {bw}#{title}{x}".c if Howzit.options[:log_level] < 2
|
|
39
39
|
block = task.action
|
|
40
40
|
script = Tempfile.new('howzit_script')
|
|
41
41
|
begin
|
|
@@ -49,22 +49,23 @@ module Howzit
|
|
|
49
49
|
script.unlink
|
|
50
50
|
end
|
|
51
51
|
else
|
|
52
|
+
title = Howzit.options[:show_all_code] ? task.action : task.title
|
|
52
53
|
case task.type
|
|
53
54
|
when :include
|
|
54
55
|
matches = Howzit.buildnote.find_topic(task.action)
|
|
55
56
|
raise "Topic not found: #{task.action}" if matches.empty?
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
$stderr.puts "{by}Running tasks from {bw}#{matches[0].title}{x}".c if Howzit.options[:log_level] < 2
|
|
58
59
|
output.push(matches[0].run(nested: true))
|
|
59
|
-
|
|
60
|
+
$stderr.puts "{by}End include: #{matches[0].tasks.count} tasks".c if Howzit.options[:log_level] < 2
|
|
60
61
|
tasks += matches[0].tasks.count
|
|
61
62
|
when :run
|
|
62
|
-
|
|
63
|
+
$stderr.puts "{bg}Running {bw}#{title}{x}".c if Howzit.options[:log_level] < 2
|
|
63
64
|
system(task.action)
|
|
64
65
|
tasks += 1
|
|
65
66
|
when :copy
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
$stderr.puts "{bg}Copied {bw}#{title}{bg} to clipboard{x}".c if Howzit.options[:log_level] < 2
|
|
68
|
+
os_copy(task.action)
|
|
68
69
|
tasks += 1
|
|
69
70
|
when :open
|
|
70
71
|
os_open(task.action)
|
|
@@ -73,28 +74,52 @@ module Howzit
|
|
|
73
74
|
end
|
|
74
75
|
end
|
|
75
76
|
else
|
|
76
|
-
warn
|
|
77
|
+
warn "{r}--run: No {br}@directive{xr} found in {bw}#{key}{x}".c
|
|
77
78
|
end
|
|
78
|
-
output.push(
|
|
79
|
+
output.push("{bm}Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}{x}".c) if Howzit.options[:log_level] < 2 && !nested
|
|
79
80
|
|
|
80
81
|
puts postreqs.join("\n\n") unless postreqs.empty?
|
|
81
82
|
|
|
82
83
|
output
|
|
83
84
|
end
|
|
84
85
|
|
|
86
|
+
def os_copy(string)
|
|
87
|
+
os = RbConfig::CONFIG['target_os']
|
|
88
|
+
out = "{bg}Copying {bw}#{string}".c
|
|
89
|
+
case os
|
|
90
|
+
when /darwin.*/i
|
|
91
|
+
warn "#{out} (macOS){x}".c if Howzit.options[:log_level] < 2
|
|
92
|
+
`echo #{Shellwords.escape(string)}'\\c'|pbcopy`
|
|
93
|
+
when /mingw|mswin/i
|
|
94
|
+
warn "#{out} (Windows){x}".c if Howzit.options[:log_level] < 2
|
|
95
|
+
`echo #{Shellwords.escape(string)} | clip`
|
|
96
|
+
else
|
|
97
|
+
if 'xsel'.available?
|
|
98
|
+
warn "#{out} (Linux, xsel){x}".c if Howzit.options[:log_level] < 2
|
|
99
|
+
`echo #{Shellwords.escape(string)}'\\c'|xsel -i`
|
|
100
|
+
elsif 'xclip'.available?
|
|
101
|
+
warn "#{out} (Linux, xclip){x}".c if Howzit.options[:log_level] < 2
|
|
102
|
+
`echo #{Shellwords.escape(string)}'\\c'|xclip -i`
|
|
103
|
+
else
|
|
104
|
+
warn out if Howzit.options[:log_level] < 2
|
|
105
|
+
warn 'Unable to determine executable for clipboard.'
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
85
110
|
def os_open(command)
|
|
86
111
|
os = RbConfig::CONFIG['target_os']
|
|
87
|
-
out =
|
|
112
|
+
out = "{bg}Opening {bw}#{command}".c
|
|
88
113
|
case os
|
|
89
114
|
when /darwin.*/i
|
|
90
|
-
warn
|
|
115
|
+
warn "#{out} (macOS){x}".c if Howzit.options[:log_level] < 2
|
|
91
116
|
`open #{Shellwords.escape(command)}`
|
|
92
117
|
when /mingw|mswin/i
|
|
93
|
-
warn
|
|
118
|
+
warn "#{out} (Windows){x}".c if Howzit.options[:log_level] < 2
|
|
94
119
|
`start #{Shellwords.escape(command)}`
|
|
95
120
|
else
|
|
96
121
|
if 'xdg-open'.available?
|
|
97
|
-
warn
|
|
122
|
+
warn "#{out} (Linux){x}".c if Howzit.options[:log_level] < 2
|
|
98
123
|
`xdg-open #{Shellwords.escape(command)}`
|
|
99
124
|
else
|
|
100
125
|
warn out if Howzit.options[:log_level] < 2
|
|
@@ -120,7 +145,6 @@ module Howzit
|
|
|
120
145
|
when /@(before|after|prereq|end)/
|
|
121
146
|
next
|
|
122
147
|
when /@include\((.*?)\)/
|
|
123
|
-
|
|
124
148
|
m = Regexp.last_match
|
|
125
149
|
matches = Howzit.buildnote.find_topic(m[1])
|
|
126
150
|
unless matches.empty?
|
|
@@ -153,10 +177,11 @@ module Howzit
|
|
|
153
177
|
Howzit.inclusions.push(matches[0])
|
|
154
178
|
end
|
|
155
179
|
|
|
156
|
-
when /@(run|copy|open|url|include)\((.*?)\)
|
|
180
|
+
when /@(run|copy|open|url|include)\((.*?)\)(.*?)$/
|
|
157
181
|
m = Regexp.last_match
|
|
158
182
|
cmd = m[1]
|
|
159
183
|
obj = m[2]
|
|
184
|
+
title = m[3].empty? ? obj : m[3]
|
|
160
185
|
icon = case cmd
|
|
161
186
|
when 'run'
|
|
162
187
|
"\u{25B6}"
|
|
@@ -166,21 +191,21 @@ module Howzit
|
|
|
166
191
|
"\u{279A}"
|
|
167
192
|
end
|
|
168
193
|
|
|
169
|
-
output.push(
|
|
194
|
+
output.push("{bmK}#{icon} {bwK}#{title.gsub(/\\n/, '\n')}{x}".c)
|
|
170
195
|
when /(`{3,})run *(.*?)$/i
|
|
171
196
|
m = Regexp.last_match
|
|
172
197
|
desc = m[2].length.positive? ? "Block: #{m[2]}" : 'Code Block'
|
|
173
|
-
output.push(
|
|
198
|
+
output.push("{bmK}\u{25B6} {bwK}#{desc}{x}\n```".c)
|
|
174
199
|
when /@@@run *(.*?)$/i
|
|
175
200
|
m = Regexp.last_match
|
|
176
201
|
desc = m[1].length.positive? ? "Block: #{m[1]}" : 'Code Block'
|
|
177
|
-
output.push(
|
|
202
|
+
output.push("{bmK}\u{25B6} {bwK}#{desc}{x}".c)
|
|
178
203
|
else
|
|
179
|
-
l.wrap!(Howzit.options[:wrap]) if
|
|
204
|
+
l.wrap!(Howzit.options[:wrap]) if Howzit.options[:wrap].positive?
|
|
180
205
|
output.push(l)
|
|
181
206
|
end
|
|
182
207
|
end
|
|
183
|
-
output.push('')
|
|
208
|
+
output.push('')
|
|
184
209
|
end
|
|
185
210
|
|
|
186
211
|
private
|
|
@@ -218,10 +243,10 @@ module Howzit
|
|
|
218
243
|
runnable << Howzit::Task.new(:include, title, obj)
|
|
219
244
|
when /run/i
|
|
220
245
|
title = c[3] || obj
|
|
221
|
-
# warn
|
|
246
|
+
# warn "{bg}Running {bw}#{obj}{x}".c if Howzit.options[:log_level] < 2
|
|
222
247
|
runnable << Howzit::Task.new(:run, title, obj)
|
|
223
248
|
when /copy/i
|
|
224
|
-
# warn
|
|
249
|
+
# warn "{bg}Copied {bw}#{obj}{bg} to clipboard{x}".c if Howzit.options[:log_level] < 2
|
|
225
250
|
runnable << Howzit::Task.new(:copy, title, Shellwords.escape(obj))
|
|
226
251
|
when /open|url/i
|
|
227
252
|
runnable << Howzit::Task.new(:open, title, obj)
|
data/lib/howzit/version.rb
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Howzit::BuildNote do
|
|
6
|
+
subject(:how) { @hz }
|
|
7
|
+
|
|
8
|
+
describe ".note_file" do
|
|
9
|
+
it "locates a build note file" do
|
|
10
|
+
expect(how.note_file).not_to be_empty
|
|
11
|
+
expect(how.note_file).to match /builda.md$/
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe ".grep" do
|
|
16
|
+
it "finds topic containing 'bermuda'" do
|
|
17
|
+
expect(how.grep('bermuda').map { |topic| topic.title }).to include('Topic Tropic')
|
|
18
|
+
end
|
|
19
|
+
it "does not return non-matching topic" do
|
|
20
|
+
expect(how.grep('bermuda').map { |topic| topic.title }).not_to include('Topic Balogna')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe ".find_topic" do
|
|
25
|
+
it "finds the Topic Tropic topic" do
|
|
26
|
+
matches = how.find_topic('tropic')
|
|
27
|
+
expect(matches.count).to eq 1
|
|
28
|
+
expect(matches[0].title).to eq 'Topic Tropic'
|
|
29
|
+
end
|
|
30
|
+
it "fuzzy matches" do
|
|
31
|
+
Howzit.options[:matching] = 'fuzzy'
|
|
32
|
+
matches = how.find_topic('trpc')
|
|
33
|
+
expect(matches.count).to eq 1
|
|
34
|
+
expect(matches[0].title).to eq 'Topic Tropic'
|
|
35
|
+
end
|
|
36
|
+
it "succeeds with partial match" do
|
|
37
|
+
Howzit.options[:matching] = 'partial'
|
|
38
|
+
matches = how.find_topic('trop')
|
|
39
|
+
expect(matches.count).to eq 1
|
|
40
|
+
expect(matches[0].title).to eq 'Topic Tropic'
|
|
41
|
+
end
|
|
42
|
+
it "succeeds with beginswith match" do
|
|
43
|
+
Howzit.options[:matching] = 'beginswith'
|
|
44
|
+
matches = how.find_topic('topic')
|
|
45
|
+
expect(matches.count).to eq 3
|
|
46
|
+
expect(matches[0].title).to eq 'Topic Balogna'
|
|
47
|
+
end
|
|
48
|
+
it "succeeds with exact match" do
|
|
49
|
+
Howzit.options[:matching] = 'exact'
|
|
50
|
+
matches = how.find_topic('topic tropic')
|
|
51
|
+
expect(matches.count).to eq 1
|
|
52
|
+
expect(matches[0].title).to eq 'Topic Tropic'
|
|
53
|
+
end
|
|
54
|
+
it "fails with incomplete exact match" do
|
|
55
|
+
Howzit.options[:matching] = 'exact'
|
|
56
|
+
matches = how.find_topic('topic trop')
|
|
57
|
+
expect(matches.count).to eq 0
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
describe ".topics" do
|
|
62
|
+
it "contains 4 topics" do
|
|
63
|
+
expect(how.list_topics.count).to eq 3
|
|
64
|
+
end
|
|
65
|
+
it "outputs a newline-separated string for completion" do
|
|
66
|
+
expect(how.list_completions.scan(/\n/).count).to eq 2
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
|
data/spec/ruby_gem_spec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe Howzit::BuildNote do
|
|
@@ -9,102 +11,3 @@ describe Howzit::BuildNote do
|
|
|
9
11
|
end
|
|
10
12
|
end
|
|
11
13
|
end
|
|
12
|
-
|
|
13
|
-
describe Howzit::Task do
|
|
14
|
-
subject(:task) { Howzit::Task.new(:run, 'List Directory', 'ls') }
|
|
15
|
-
|
|
16
|
-
describe ".new" do
|
|
17
|
-
it "makes a new task instance" do
|
|
18
|
-
expect(task).to be_a Howzit::Task
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
describe Howzit::Topic do
|
|
24
|
-
title = 'Test Title'
|
|
25
|
-
content = 'Test Content'
|
|
26
|
-
subject(:topic) { Howzit::Topic.new(title, content) }
|
|
27
|
-
|
|
28
|
-
describe ".new" do
|
|
29
|
-
it "makes a new topic instance" do
|
|
30
|
-
expect(topic).to be_a Howzit::Topic
|
|
31
|
-
end
|
|
32
|
-
it "has the correct title" do
|
|
33
|
-
expect(topic.title).to eq title
|
|
34
|
-
end
|
|
35
|
-
it "has the correct content" do
|
|
36
|
-
expect(topic.content).to eq content
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
describe Howzit::BuildNote do
|
|
42
|
-
Dir.chdir('spec')
|
|
43
|
-
Howzit.options[:include_upstream] = false
|
|
44
|
-
Howzit.options[:default] = true
|
|
45
|
-
hz = Howzit.buildnote
|
|
46
|
-
|
|
47
|
-
hz.create_note
|
|
48
|
-
subject(:how) { hz }
|
|
49
|
-
|
|
50
|
-
describe ".note_file" do
|
|
51
|
-
it "locates a build note file" do
|
|
52
|
-
expect(how.note_file).not_to be_empty
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
describe ".grep" do
|
|
57
|
-
it "finds topic containing 'editable'" do
|
|
58
|
-
expect(how.grep('editable').map { |topic| topic.title }).to include('File Structure')
|
|
59
|
-
end
|
|
60
|
-
it "does not return non-matching topic" do
|
|
61
|
-
expect(how.grep('editable').map { |topic| topic.title }).not_to include('Build')
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
describe ".find_topic" do
|
|
66
|
-
it "finds the File Structure topic" do
|
|
67
|
-
matches = how.find_topic('file struct')
|
|
68
|
-
expect(matches.count).to eq 1
|
|
69
|
-
expect(matches[0].title).to eq 'File Structure'
|
|
70
|
-
end
|
|
71
|
-
it "fuzzy matches" do
|
|
72
|
-
Howzit.options[:matching] = 'fuzzy'
|
|
73
|
-
matches = how.find_topic('flestct')
|
|
74
|
-
expect(matches.count).to eq 1
|
|
75
|
-
expect(matches[0].title).to eq 'File Structure'
|
|
76
|
-
end
|
|
77
|
-
it "succeeds with partial match" do
|
|
78
|
-
Howzit.options[:matching] = 'partial'
|
|
79
|
-
matches = how.find_topic('structure')
|
|
80
|
-
expect(matches.count).to eq 1
|
|
81
|
-
expect(matches[0].title).to eq 'File Structure'
|
|
82
|
-
end
|
|
83
|
-
it "succeeds with beginswith match" do
|
|
84
|
-
Howzit.options[:matching] = 'beginswith'
|
|
85
|
-
matches = how.find_topic('file')
|
|
86
|
-
expect(matches.count).to eq 1
|
|
87
|
-
expect(matches[0].title).to eq 'File Structure'
|
|
88
|
-
end
|
|
89
|
-
it "succeeds with exact match" do
|
|
90
|
-
Howzit.options[:matching] = 'exact'
|
|
91
|
-
matches = how.find_topic('file structure')
|
|
92
|
-
expect(matches.count).to eq 1
|
|
93
|
-
expect(matches[0].title).to eq 'File Structure'
|
|
94
|
-
end
|
|
95
|
-
it "fails with incomplete exact match" do
|
|
96
|
-
Howzit.options[:matching] = 'exact'
|
|
97
|
-
matches = how.find_topic('file struct')
|
|
98
|
-
expect(matches.count).to eq 0
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
describe ".topics" do
|
|
103
|
-
it "contains 4 topics" do
|
|
104
|
-
expect(how.list_topics.count).to eq 4
|
|
105
|
-
end
|
|
106
|
-
it "outputs a newline-separated string for completion" do
|
|
107
|
-
expect(how.list_completions.scan(/\n/).count).to eq 3
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -13,7 +13,52 @@ require 'howzit'
|
|
|
13
13
|
|
|
14
14
|
RSpec.configure do |c|
|
|
15
15
|
c.expect_with(:rspec) { |e| e.syntax = :expect }
|
|
16
|
+
|
|
16
17
|
c.before(:each) do
|
|
17
18
|
allow(FileUtils).to receive(:remove_entry_secure).with(anything)
|
|
19
|
+
save_buildnote
|
|
20
|
+
Howzit.options[:include_upstream] = false
|
|
21
|
+
Howzit.options[:default] = true
|
|
22
|
+
@hz = Howzit.buildnote
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
c.after(:each) do
|
|
26
|
+
delete_buildnote
|
|
18
27
|
end
|
|
19
28
|
end
|
|
29
|
+
|
|
30
|
+
def save_buildnote
|
|
31
|
+
note = <<~EONOTE
|
|
32
|
+
# Howzit Test
|
|
33
|
+
|
|
34
|
+
## Topic Balogna
|
|
35
|
+
|
|
36
|
+
@before
|
|
37
|
+
This should be a prerequisite.
|
|
38
|
+
@end
|
|
39
|
+
|
|
40
|
+
@run(ls -1 &> /dev/null) Null Output
|
|
41
|
+
@include(Topic Tropic)
|
|
42
|
+
|
|
43
|
+
@after
|
|
44
|
+
This should be a postrequisite.
|
|
45
|
+
@end
|
|
46
|
+
|
|
47
|
+
## Topic Banana
|
|
48
|
+
|
|
49
|
+
This is just another topic.
|
|
50
|
+
|
|
51
|
+
- It has a list in it
|
|
52
|
+
- That's pretty fun, right?
|
|
53
|
+
|
|
54
|
+
## Topic Tropic
|
|
55
|
+
|
|
56
|
+
Bermuda, Bahama, something something wanna.
|
|
57
|
+
@copy(Balogna) Just some balogna
|
|
58
|
+
EONOTE
|
|
59
|
+
File.open('builda.md', 'w') { |f| f.puts note }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def delete_buildnote
|
|
63
|
+
FileUtils.rm('builda.md')
|
|
64
|
+
end
|
data/spec/task_spec.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Howzit::Task do
|
|
6
|
+
subject(:task) { Howzit::Task.new(:run, 'List Directory', 'ls') }
|
|
7
|
+
|
|
8
|
+
describe ".new" do
|
|
9
|
+
it "makes a new task instance" do
|
|
10
|
+
expect(task).to be_a Howzit::Task
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/spec/topic_spec.rb
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Howzit::Topic do
|
|
6
|
+
title = 'Test Title'
|
|
7
|
+
content = 'Test Content'
|
|
8
|
+
subject(:topic) { Howzit::Topic.new(title, content) }
|
|
9
|
+
|
|
10
|
+
describe ".new" do
|
|
11
|
+
it "makes a new topic instance" do
|
|
12
|
+
expect(topic).to be_a Howzit::Topic
|
|
13
|
+
end
|
|
14
|
+
it "has the correct title" do
|
|
15
|
+
expect(topic.title).to eq title
|
|
16
|
+
end
|
|
17
|
+
it "has the correct content" do
|
|
18
|
+
expect(topic.content).to eq content
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe Howzit::Topic do
|
|
24
|
+
subject(:topic) { @hz.find_topic('Topic Balogna')[0] }
|
|
25
|
+
|
|
26
|
+
describe ".title" do
|
|
27
|
+
it "has the correct title" do
|
|
28
|
+
expect(topic.title).to match /Topic Balogna/
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe ".tasks" do
|
|
33
|
+
it "has 2 tasks" do
|
|
34
|
+
expect(topic.tasks.count).to eq 2
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe ".prereqs" do
|
|
39
|
+
it "has prereq" do
|
|
40
|
+
expect(topic.prereqs.count).to eq 1
|
|
41
|
+
end
|
|
42
|
+
it "has postreq" do
|
|
43
|
+
expect(topic.postreqs.count).to eq 1
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe ".run" do
|
|
48
|
+
Howzit.options[:default] = true
|
|
49
|
+
it "shows prereq and postreq" do
|
|
50
|
+
expect { topic.run }.to output(/prerequisite/).to_stdout
|
|
51
|
+
expect { topic.run }.to output(/postrequisite/).to_stdout
|
|
52
|
+
end
|
|
53
|
+
it "Copies to clipboard" do
|
|
54
|
+
expect {
|
|
55
|
+
ENV['RUBYOPT'] = '-W1'
|
|
56
|
+
Howzit.options[:log_level] = 0
|
|
57
|
+
topic.run
|
|
58
|
+
}.to output(/Copied/).to_stderr
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
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.3
|
|
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-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -280,8 +280,12 @@ files:
|
|
|
280
280
|
- lib/howzit/util.rb
|
|
281
281
|
- lib/howzit/version.rb
|
|
282
282
|
- spec/.rubocop.yml
|
|
283
|
+
- spec/buildnote_spec.rb
|
|
284
|
+
- spec/buildnotes.md.bak
|
|
283
285
|
- spec/ruby_gem_spec.rb
|
|
284
286
|
- spec/spec_helper.rb
|
|
287
|
+
- spec/task_spec.rb
|
|
288
|
+
- spec/topic_spec.rb
|
|
285
289
|
- update_readmes.rb
|
|
286
290
|
homepage: https://github.com/ttscoff/howzit
|
|
287
291
|
licenses:
|
|
@@ -295,7 +299,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
295
299
|
requirements:
|
|
296
300
|
- - ">="
|
|
297
301
|
- !ruby/object:Gem::Version
|
|
298
|
-
version: 2.0
|
|
302
|
+
version: 2.6.0
|
|
299
303
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
300
304
|
requirements:
|
|
301
305
|
- - ">="
|
|
@@ -309,5 +313,9 @@ summary: Provides a way to access Markdown project notes by topic with query cap
|
|
|
309
313
|
and the ability to execute the tasks it describes.
|
|
310
314
|
test_files:
|
|
311
315
|
- spec/.rubocop.yml
|
|
316
|
+
- spec/buildnote_spec.rb
|
|
317
|
+
- spec/buildnotes.md.bak
|
|
312
318
|
- spec/ruby_gem_spec.rb
|
|
313
319
|
- spec/spec_helper.rb
|
|
320
|
+
- spec/task_spec.rb
|
|
321
|
+
- spec/topic_spec.rb
|