howzit 2.0.6 → 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|