howzit 2.0.6 → 2.0.9
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 +35 -0
- data/README.md +4 -333
- data/bin/howzit +101 -76
- data/howzit.gemspec +2 -0
- data/lib/howzit/buildnote.rb +13 -11
- data/lib/howzit/config.rb +62 -7
- data/lib/howzit/console_logger.rb +80 -0
- data/lib/howzit/prompt.rb +7 -6
- data/lib/howzit/stringutils.rb +1 -1
- data/lib/howzit/task.rb +4 -0
- data/lib/howzit/topic.rb +34 -17
- data/lib/howzit/util.rb +13 -8
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +8 -1
- data/spec/cli_spec.rb +27 -0
- data/spec/spec_helper.rb +1 -0
- metadata +33 -2
data/lib/howzit/buildnote.rb
CHANGED
@@ -10,7 +10,7 @@ module Howzit
|
|
10
10
|
def initialize(file: nil, args: [])
|
11
11
|
@topics = []
|
12
12
|
create_note if note_file.nil?
|
13
|
-
@metadata =
|
13
|
+
@metadata = Util.read_file(note_file).split(/^#/)[0].strip.get_metadata
|
14
14
|
|
15
15
|
read_help(file)
|
16
16
|
end
|
@@ -89,7 +89,7 @@ module Howzit
|
|
89
89
|
# Create a buildnotes skeleton
|
90
90
|
def create_note
|
91
91
|
trap('SIGINT') do
|
92
|
-
|
92
|
+
Howzit.console.info "\nCancelled"
|
93
93
|
exit!
|
94
94
|
end
|
95
95
|
default = !$stdout.isatty || Howzit.options[:default]
|
@@ -210,9 +210,11 @@ module Howzit
|
|
210
210
|
buildnotes.reverse
|
211
211
|
end
|
212
212
|
|
213
|
-
def
|
214
|
-
return false if filename.downcase !~
|
213
|
+
def build_note?(filename)
|
214
|
+
return false if filename.downcase !~ /^(howzit[^.]*|build[^.]+)/
|
215
|
+
|
215
216
|
return false if Howzit.config.should_ignore(filename)
|
217
|
+
|
216
218
|
true
|
217
219
|
end
|
218
220
|
|
@@ -222,7 +224,7 @@ module Howzit
|
|
222
224
|
# with "build" and have an extension of txt, md, or markdown.
|
223
225
|
|
224
226
|
Dir.glob('*.{txt,md,markdown}').each do |f|
|
225
|
-
if
|
227
|
+
if build_note?(f)
|
226
228
|
filename = f
|
227
229
|
break
|
228
230
|
end
|
@@ -262,15 +264,15 @@ module Howzit
|
|
262
264
|
end
|
263
265
|
|
264
266
|
def ensure_requirements(template)
|
265
|
-
t_leader =
|
267
|
+
t_leader = Util.read_file(template).split(/^#/)[0].strip
|
266
268
|
if t_leader.length > 0
|
267
269
|
t_meta = t_leader.get_metadata
|
268
270
|
if t_meta.key?('required')
|
269
271
|
required = t_meta['required'].strip.split(/\s*,\s*/)
|
270
272
|
required.each do |req|
|
271
273
|
unless @metadata.keys.include?(req.downcase)
|
272
|
-
|
273
|
-
|
274
|
+
Howzit.console.error %({xr}ERROR: Missing required metadata key from template '{bw}#{File.basename(template, '.md')}{xr}'{x}).c
|
275
|
+
Howzit.console.error %({xr}Please define {by}#{req.downcase}{xr} in build notes{x}).c
|
274
276
|
Process.exit 1
|
275
277
|
end
|
276
278
|
end
|
@@ -330,7 +332,7 @@ module Howzit
|
|
330
332
|
|
331
333
|
return m[0] unless File.exist?(file)
|
332
334
|
|
333
|
-
content =
|
335
|
+
content = Util.read_file(file)
|
334
336
|
home = ENV['HOME']
|
335
337
|
short_path = File.dirname(file.sub(/^#{home}/, '~'))
|
336
338
|
prefix = "#{short_path}/#{File.basename(file)}:"
|
@@ -344,7 +346,7 @@ module Howzit
|
|
344
346
|
end
|
345
347
|
|
346
348
|
def note_title(truncate = 0)
|
347
|
-
help =
|
349
|
+
help = Util.read_file(note_file)
|
348
350
|
title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
|
349
351
|
title = if title
|
350
352
|
title[1].nil? ? title[2] : title[1]
|
@@ -361,7 +363,7 @@ module Howzit
|
|
361
363
|
|
362
364
|
filename = path.nil? ? note_file : path
|
363
365
|
|
364
|
-
help =
|
366
|
+
help = Util.read_file(filename)
|
365
367
|
|
366
368
|
@title = note_title
|
367
369
|
|
data/lib/howzit/config.rb
CHANGED
@@ -3,6 +3,7 @@ module Howzit
|
|
3
3
|
class Config
|
4
4
|
attr_reader :options
|
5
5
|
|
6
|
+
# Configuration defaults
|
6
7
|
DEFAULTS = {
|
7
8
|
color: true,
|
8
9
|
config_editor: ENV['EDITOR'] || nil,
|
@@ -22,18 +23,31 @@ module Howzit
|
|
22
23
|
wrap: 0
|
23
24
|
}.deep_freeze
|
24
25
|
|
26
|
+
##
|
27
|
+
## Initialize a config object
|
28
|
+
##
|
25
29
|
def initialize
|
26
30
|
load_options
|
27
31
|
end
|
28
32
|
|
33
|
+
##
|
34
|
+
## Write a config to a file
|
35
|
+
##
|
36
|
+
## @param config The configuration
|
37
|
+
##
|
29
38
|
def write_config(config)
|
30
39
|
File.open(config_file, 'w') { |f| f.puts config.to_yaml }
|
31
40
|
end
|
32
41
|
|
42
|
+
##
|
43
|
+
## Test if a file should be ignored based on YAML file
|
44
|
+
##
|
45
|
+
## @param filename The filename to test
|
46
|
+
##
|
33
47
|
def should_ignore(filename)
|
34
48
|
return false unless File.exist?(ignore_file)
|
35
49
|
|
36
|
-
@ignore_patterns ||= YAML.safe_load(
|
50
|
+
@ignore_patterns ||= YAML.safe_load(Util.read_file(ignore_file))
|
37
51
|
|
38
52
|
ignore = false
|
39
53
|
|
@@ -47,16 +61,29 @@ module Howzit
|
|
47
61
|
ignore
|
48
62
|
end
|
49
63
|
|
64
|
+
##
|
65
|
+
## Find the template folder
|
66
|
+
##
|
67
|
+
## @return [String] path to template folder
|
68
|
+
##
|
50
69
|
def template_folder
|
51
70
|
File.join(config_dir, 'templates')
|
52
71
|
end
|
53
72
|
|
73
|
+
##
|
74
|
+
## Initiate the editor for the config
|
75
|
+
##
|
54
76
|
def editor
|
55
77
|
edit_config(DEFAULTS)
|
56
78
|
end
|
57
79
|
|
58
80
|
private
|
59
81
|
|
82
|
+
##
|
83
|
+
## Load command line options
|
84
|
+
##
|
85
|
+
## @return [Hash] options with command line flags merged in
|
86
|
+
##
|
60
87
|
def load_options
|
61
88
|
Color.coloring = $stdout.isatty
|
62
89
|
flags = {
|
@@ -77,40 +104,68 @@ module Howzit
|
|
77
104
|
@options = flags.merge(config)
|
78
105
|
end
|
79
106
|
|
107
|
+
##
|
108
|
+
## Get the config directory
|
109
|
+
##
|
110
|
+
## @return [String] path to config directory
|
111
|
+
##
|
80
112
|
def config_dir
|
81
113
|
File.expand_path(CONFIG_DIR)
|
82
114
|
end
|
83
115
|
|
116
|
+
##
|
117
|
+
## Get the config file
|
118
|
+
##
|
119
|
+
## @return [String] path to config file
|
120
|
+
##
|
84
121
|
def config_file
|
85
122
|
File.join(config_dir, CONFIG_FILE)
|
86
123
|
end
|
87
124
|
|
125
|
+
##
|
126
|
+
## Get the ignore config file
|
127
|
+
##
|
128
|
+
## @return [String] path to ignore config file
|
129
|
+
##
|
88
130
|
def ignore_file
|
89
131
|
File.join(config_dir, IGNORE_FILE)
|
90
132
|
end
|
91
133
|
|
92
|
-
|
134
|
+
##
|
135
|
+
## Create a new config file (and directory if needed)
|
136
|
+
##
|
137
|
+
## @param default [Hash] default configuration to write
|
138
|
+
##
|
139
|
+
def create_config(default)
|
93
140
|
unless File.directory?(config_dir)
|
94
|
-
|
141
|
+
Howzit::ConsoleLogger.new(1).info "Creating config directory at #{config_dir}"
|
95
142
|
FileUtils.mkdir_p(config_dir)
|
96
143
|
end
|
97
144
|
|
98
145
|
unless File.exist?(config_file)
|
99
|
-
|
100
|
-
write_config(
|
146
|
+
Howzit::ConsoleLogger.new(1).info "Writing fresh config file to #{config_file}"
|
147
|
+
write_config(default)
|
101
148
|
end
|
102
149
|
config_file
|
103
150
|
end
|
104
151
|
|
152
|
+
##
|
153
|
+
## Load the config file
|
154
|
+
##
|
155
|
+
## @return [Hash] configuration object
|
156
|
+
##
|
105
157
|
def load_config
|
106
158
|
file = create_config(DEFAULTS)
|
107
|
-
config = YAML.load(
|
159
|
+
config = YAML.load(Util.read_file(file))
|
108
160
|
newconfig = config ? DEFAULTS.merge(config) : DEFAULTS
|
109
161
|
write_config(newconfig)
|
110
162
|
newconfig.dup
|
111
163
|
end
|
112
164
|
|
113
|
-
|
165
|
+
##
|
166
|
+
## Open the config in an editor
|
167
|
+
##
|
168
|
+
def edit_config
|
114
169
|
editor = Howzit.options.fetch(:config_editor, ENV['EDITOR'])
|
115
170
|
|
116
171
|
raise 'No config_editor defined' if editor.nil?
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
LOG_LEVELS = {
|
4
|
+
debug: 0,
|
5
|
+
info: 1,
|
6
|
+
warn: 2,
|
7
|
+
error: 3
|
8
|
+
}.deep_freeze
|
9
|
+
|
10
|
+
module Howzit
|
11
|
+
# Console logging
|
12
|
+
class ConsoleLogger
|
13
|
+
attr_accessor :log_level
|
14
|
+
|
15
|
+
##
|
16
|
+
## Init the console logging object
|
17
|
+
##
|
18
|
+
## @param level [Integer] log level
|
19
|
+
##
|
20
|
+
def initialize(level = nil)
|
21
|
+
@log_level = level.to_i || Howzit.options[:log_level]
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
## Get the log level from options
|
26
|
+
##
|
27
|
+
## @return [Integer] log level
|
28
|
+
##
|
29
|
+
def reset_level
|
30
|
+
@log_level = Howzit.options[:log_level]
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
## Write a message to the console based on the urgency
|
35
|
+
## level and user's log level setting
|
36
|
+
##
|
37
|
+
## @param msg [String] The message
|
38
|
+
## @param level [Symbol] The level
|
39
|
+
##
|
40
|
+
def write(msg, level = :info)
|
41
|
+
$stderr.puts msg if LOG_LEVELS[level] >= @log_level
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
## Write a message at debug level
|
46
|
+
##
|
47
|
+
## @param msg The message
|
48
|
+
##
|
49
|
+
def debug(msg)
|
50
|
+
write msg, :debug
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
## Write a message at info level
|
55
|
+
##
|
56
|
+
## @param msg The message
|
57
|
+
##
|
58
|
+
def info(msg)
|
59
|
+
write msg, :info
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
## Write a message at warn level
|
64
|
+
##
|
65
|
+
## @param msg The message
|
66
|
+
##
|
67
|
+
def warn(msg)
|
68
|
+
write msg, :warn
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
## Write a message at error level
|
73
|
+
##
|
74
|
+
## @param msg The message
|
75
|
+
##
|
76
|
+
def error(msg)
|
77
|
+
write msg, :error
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/howzit/prompt.rb
CHANGED
@@ -8,14 +8,15 @@ module Howzit
|
|
8
8
|
return default unless $stdout.isatty
|
9
9
|
|
10
10
|
return default if Howzit.options[:default]
|
11
|
-
|
12
|
-
system 'stty cbreak'
|
11
|
+
tty_state = `stty -g`
|
12
|
+
system 'stty raw -echo cbreak isig'
|
13
13
|
yn = color_single_options(default ? %w[Y n] : %w[y N])
|
14
14
|
$stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m"
|
15
15
|
res = $stdin.sysread 1
|
16
16
|
res.chomp!
|
17
17
|
puts
|
18
18
|
system 'stty cooked'
|
19
|
+
system "stty #{tty_state}"
|
19
20
|
res.empty? ? default : res =~ /y/i
|
20
21
|
end
|
21
22
|
|
@@ -24,12 +25,12 @@ module Howzit
|
|
24
25
|
choices.each do |choice|
|
25
26
|
case choice
|
26
27
|
when /[A-Z]/
|
27
|
-
out.push(Color.template("{
|
28
|
+
out.push(Color.template("{bw}#{choice}{x}"))
|
28
29
|
else
|
29
|
-
out.push(Color.template("{
|
30
|
+
out.push(Color.template("{dw}#{choice}{xg}"))
|
30
31
|
end
|
31
32
|
end
|
32
|
-
Color.template("{
|
33
|
+
Color.template("{xg}[#{out.join('/')}{xg}]{x}")
|
33
34
|
end
|
34
35
|
|
35
36
|
def options_list(matches)
|
@@ -54,7 +55,7 @@ module Howzit
|
|
54
55
|
]
|
55
56
|
res = `echo #{Shellwords.escape(matches.join("\n"))} | fzf #{settings.join(' ')}`.strip
|
56
57
|
if res.nil? || res.empty?
|
57
|
-
|
58
|
+
Howzit.console.info 'Cancelled'
|
58
59
|
Process.exit 0
|
59
60
|
end
|
60
61
|
return res.split(/\n/)
|
data/lib/howzit/stringutils.rb
CHANGED
data/lib/howzit/task.rb
CHANGED
data/lib/howzit/topic.rb
CHANGED
@@ -9,6 +9,12 @@ module Howzit
|
|
9
9
|
|
10
10
|
attr_reader :title, :tasks, :prereqs, :postreqs
|
11
11
|
|
12
|
+
##
|
13
|
+
## Initialize a topic object
|
14
|
+
##
|
15
|
+
## @param title [String] The topic title
|
16
|
+
## @param content [String] The raw topic content
|
17
|
+
##
|
12
18
|
def initialize(title, content)
|
13
19
|
@title = title
|
14
20
|
@content = content
|
@@ -17,18 +23,29 @@ module Howzit
|
|
17
23
|
@tasks = gather_tasks
|
18
24
|
end
|
19
25
|
|
26
|
+
##
|
27
|
+
## Search title and contents for a pattern
|
28
|
+
##
|
29
|
+
## @param term [String] the search pattern
|
30
|
+
##
|
20
31
|
def grep(term)
|
21
32
|
@title =~ /#{term}/i || @content =~ /#{term}/i
|
22
33
|
end
|
23
34
|
|
24
|
-
# Handle run command, execute directives
|
35
|
+
# Handle run command, execute directives in topic
|
25
36
|
def run(nested: false)
|
26
37
|
output = []
|
27
38
|
tasks = 0
|
39
|
+
cols = begin
|
40
|
+
TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
|
41
|
+
rescue StandardError
|
42
|
+
60
|
43
|
+
end
|
44
|
+
|
28
45
|
if @tasks.count.positive?
|
29
46
|
unless @prereqs.empty?
|
30
|
-
puts @prereqs.join("\n\n")
|
31
|
-
res = Prompt.yn('
|
47
|
+
puts TTY::Box.frame("{by}#{@prereqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols)
|
48
|
+
res = Prompt.yn('Have the above prerequisites been met?', default: true)
|
32
49
|
Process.exit 1 unless res
|
33
50
|
|
34
51
|
end
|
@@ -42,7 +59,7 @@ module Howzit
|
|
42
59
|
end
|
43
60
|
|
44
61
|
if task.type == :block
|
45
|
-
|
62
|
+
Howzit.console.info "{bg}Running block {bw}#{title}{x}".c if Howzit.options[:log_level] < 2
|
46
63
|
block = task.action
|
47
64
|
script = Tempfile.new('howzit_script')
|
48
65
|
begin
|
@@ -81,11 +98,11 @@ module Howzit
|
|
81
98
|
end
|
82
99
|
end
|
83
100
|
else
|
84
|
-
warn "{r}--run: No {br}@directive{xr} found in {bw}#{@title}{x}".c
|
101
|
+
Howzit.console.warn "{r}--run: No {br}@directive{xr} found in {bw}#{@title}{x}".c
|
85
102
|
end
|
86
103
|
output.push("{bm}Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}{x}".c) if Howzit.options[:log_level] < 2 && !nested
|
87
104
|
|
88
|
-
puts postreqs.join("\n\n") unless postreqs.empty?
|
105
|
+
puts TTY::Box.frame("{bw}#{@postreqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols) unless @postreqs.empty?
|
89
106
|
|
90
107
|
output
|
91
108
|
end
|
@@ -95,21 +112,21 @@ module Howzit
|
|
95
112
|
out = "{bg}Copying {bw}#{string}".c
|
96
113
|
case os
|
97
114
|
when /darwin.*/i
|
98
|
-
|
115
|
+
$stderr.puts "#{out} (macOS){x}".c if Howzit.options[:log_level].zero?
|
99
116
|
`echo #{Shellwords.escape(string)}'\\c'|pbcopy`
|
100
117
|
when /mingw|mswin/i
|
101
|
-
|
118
|
+
$stderr.puts "#{out} (Windows){x}".c if Howzit.options[:log_level].zero?
|
102
119
|
`echo #{Shellwords.escape(string)} | clip`
|
103
120
|
else
|
104
121
|
if 'xsel'.available?
|
105
|
-
|
122
|
+
$stderr.puts "#{out} (Linux, xsel){x}".c if Howzit.options[:log_level].zero?
|
106
123
|
`echo #{Shellwords.escape(string)}'\\c'|xsel -i`
|
107
124
|
elsif 'xclip'.available?
|
108
|
-
|
125
|
+
$stderr.puts "#{out} (Linux, xclip){x}".c if Howzit.options[:log_level].zero?
|
109
126
|
`echo #{Shellwords.escape(string)}'\\c'|xclip -i`
|
110
127
|
else
|
111
|
-
|
112
|
-
|
128
|
+
$stderr.puts out if Howzit.options[:log_level].zero?
|
129
|
+
$stderr.puts 'Unable to determine executable for clipboard.'
|
113
130
|
end
|
114
131
|
end
|
115
132
|
end
|
@@ -119,18 +136,18 @@ module Howzit
|
|
119
136
|
out = "{bg}Opening {bw}#{command}".c
|
120
137
|
case os
|
121
138
|
when /darwin.*/i
|
122
|
-
|
139
|
+
Howzit.console.debug "#{out} (macOS){x}".c if Howzit.options[:log_level] < 2
|
123
140
|
`open #{Shellwords.escape(command)}`
|
124
141
|
when /mingw|mswin/i
|
125
|
-
|
142
|
+
Howzit.console.debug "#{out} (Windows){x}".c if Howzit.options[:log_level] < 2
|
126
143
|
`start #{Shellwords.escape(command)}`
|
127
144
|
else
|
128
145
|
if 'xdg-open'.available?
|
129
|
-
|
146
|
+
Howzit.console.debug "#{out} (Linux){x}".c if Howzit.options[:log_level] < 2
|
130
147
|
`xdg-open #{Shellwords.escape(command)}`
|
131
148
|
else
|
132
|
-
|
133
|
-
|
149
|
+
Howzit.console.debug out if Howzit.options[:log_level] < 2
|
150
|
+
Howzit.console.debug 'Unable to determine executable for `open`.'
|
134
151
|
end
|
135
152
|
end
|
136
153
|
end
|
data/lib/howzit/util.rb
CHANGED
@@ -1,21 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Howzit
|
4
|
+
# Util class
|
2
5
|
module Util
|
3
6
|
class << self
|
7
|
+
def read_file(path)
|
8
|
+
IO.read(path).force_encoding('utf-8').strip
|
9
|
+
end
|
10
|
+
|
4
11
|
def valid_command?(command)
|
5
12
|
cmd = command.split(' ')[0]
|
6
13
|
command_exist?(cmd)
|
7
14
|
end
|
8
|
-
|
15
|
+
|
9
16
|
def command_exist?(command)
|
10
17
|
exts = ENV.fetch('PATHEXT', '').split(::File::PATH_SEPARATOR)
|
11
18
|
if Pathname.new(command).absolute?
|
12
|
-
::File.exist?(command) ||
|
13
|
-
exts.any? { |ext| ::File.exist?("#{command}#{ext}") }
|
19
|
+
::File.exist?(command) || exts.any? { |ext| ::File.exist?("#{command}#{ext}") }
|
14
20
|
else
|
15
21
|
ENV.fetch('PATH', '').split(::File::PATH_SEPARATOR).any? do |dir|
|
16
22
|
file = ::File.join(dir, command)
|
17
|
-
::File.exist?(file) ||
|
18
|
-
exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
|
23
|
+
::File.exist?(file) || exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -40,7 +45,7 @@ module Howzit
|
|
40
45
|
if hl.available?
|
41
46
|
Howzit.options[:highlighter]
|
42
47
|
else
|
43
|
-
|
48
|
+
Howzit.console.error Color.template("{Rw}Error:{xbw} Specified highlighter (#{Howzit.options[:highlighter]}) not found, switching to auto")
|
44
49
|
Howzit.options[:highlighter] = 'auto'
|
45
50
|
which_highlighter
|
46
51
|
end
|
@@ -78,7 +83,7 @@ module Howzit
|
|
78
83
|
if pg.available?
|
79
84
|
Howzit.options[:pager]
|
80
85
|
else
|
81
|
-
|
86
|
+
Howzit.console.error Color.template("{Rw}Error:{xbw} Specified pager (#{Howzit.options[:pager]}) not found, switching to auto")
|
82
87
|
Howzit.options[:pager] = 'auto'
|
83
88
|
which_pager
|
84
89
|
end
|
@@ -104,7 +109,7 @@ module Howzit
|
|
104
109
|
begin
|
105
110
|
exec(pager)
|
106
111
|
rescue SystemCallError => e
|
107
|
-
|
112
|
+
Howzit.console.error(e)
|
108
113
|
exit 1
|
109
114
|
end
|
110
115
|
end
|
data/lib/howzit/version.rb
CHANGED
data/lib/howzit.rb
CHANGED
@@ -5,8 +5,9 @@ require_relative 'howzit/prompt'
|
|
5
5
|
require_relative 'howzit/colors'
|
6
6
|
require_relative 'howzit/stringutils'
|
7
7
|
|
8
|
-
require_relative 'howzit/util'
|
9
8
|
require_relative 'howzit/hash'
|
9
|
+
require_relative 'howzit/console_logger'
|
10
|
+
require_relative 'howzit/util'
|
10
11
|
require_relative 'howzit/config'
|
11
12
|
require_relative 'howzit/task'
|
12
13
|
require_relative 'howzit/topic'
|
@@ -20,6 +21,7 @@ require 'tempfile'
|
|
20
21
|
require 'yaml'
|
21
22
|
|
22
23
|
require 'tty/screen'
|
24
|
+
require 'tty/box'
|
23
25
|
# require 'tty/prompt'
|
24
26
|
|
25
27
|
CONFIG_DIR = '~/.config/howzit'
|
@@ -29,6 +31,7 @@ MATCHING_OPTIONS = %w[partial exact fuzzy beginswith].freeze
|
|
29
31
|
MULTIPLE_OPTIONS = %w[first best all choose].freeze
|
30
32
|
HEADER_FORMAT_OPTIONS = %w[border block].freeze
|
31
33
|
|
34
|
+
# Main module for howzit
|
32
35
|
module Howzit
|
33
36
|
class << self
|
34
37
|
attr_accessor :arguments, :cli_args
|
@@ -52,5 +55,9 @@ module Howzit
|
|
52
55
|
def buildnote
|
53
56
|
@buildnote ||= BuildNote.new
|
54
57
|
end
|
58
|
+
|
59
|
+
def console
|
60
|
+
@console ||= Howzit::ConsoleLogger.new(options[:log_level])
|
61
|
+
end
|
55
62
|
end
|
56
63
|
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# https://github.com/thoiberg/cli-test
|
6
|
+
describe 'CLI' do
|
7
|
+
include CliTest
|
8
|
+
|
9
|
+
it 'executes successfully' do
|
10
|
+
execute_script('bin/howzit', use_bundler: true)
|
11
|
+
expect(last_execution).to be_successful
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'lists available topics' do
|
15
|
+
execute_script('bin/howzit', use_bundler: true, args: %w[-L])
|
16
|
+
expect(last_execution).to be_successful
|
17
|
+
expect(last_execution.stdout).to match(/Topic Balogna/)
|
18
|
+
expect(last_execution.stdout.split(/\n/).count).to eq 3
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'lists available tasks' do
|
22
|
+
execute_script('bin/howzit', use_bundler: true, args: %w[-T])
|
23
|
+
expect(last_execution).to be_successful
|
24
|
+
expect(last_execution.stdout).to match(/Topic Balogna/)
|
25
|
+
expect(last_execution.stdout.split(/\n/).count).to eq 2
|
26
|
+
end
|
27
|
+
end
|