arli 0.3.2 → 0.5.1
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/.travis.yml +13 -0
- data/README.md +48 -46
- data/arli.gemspec +2 -1
- data/exe/arli +0 -1
- data/lib/arli.rb +28 -27
- data/lib/arli/arli_file.rb +51 -8
- data/lib/arli/cli.rb +87 -67
- data/lib/arli/commands/base.rb +17 -66
- data/lib/arli/commands/install.rb +13 -25
- data/lib/arli/commands/search.rb +9 -8
- data/lib/arli/config.rb +16 -0
- data/lib/arli/errors.rb +19 -0
- data/lib/arli/installer.rb +100 -0
- data/lib/arli/installers/zip_file.rb +61 -0
- data/lib/arli/logger.rb +13 -0
- data/lib/arli/parser.rb +63 -40
- data/lib/arli/version.rb +1 -1
- metadata +26 -9
- data/lib/arli/commands/update.rb +0 -26
- data/lib/arli/configuration.rb +0 -4
data/lib/arli/commands/base.rb
CHANGED
@@ -3,89 +3,40 @@ require 'fileutils'
|
|
3
3
|
require 'open3'
|
4
4
|
require 'arli'
|
5
5
|
require 'arli/version'
|
6
|
+
require 'arli/errors'
|
6
7
|
|
7
8
|
module Arli
|
8
9
|
module Commands
|
9
10
|
class Base
|
10
|
-
attr_accessor :lib_path,
|
11
|
+
attr_accessor :lib_path,
|
12
|
+
:arlifile,
|
13
|
+
:abort_if_exists,
|
14
|
+
:create_backup,
|
15
|
+
:command,
|
16
|
+
:debug,
|
17
|
+
:trace
|
11
18
|
|
12
19
|
def initialize(options)
|
13
20
|
self.lib_path = options[:lib_home]
|
14
21
|
self.abort_if_exists = options[:abort_if_exists]
|
15
|
-
self.
|
22
|
+
self.create_backup = options[:create_backup]
|
23
|
+
self.debug = options[:debug]
|
24
|
+
self.trace = options[:trace]
|
25
|
+
|
26
|
+
self.command = self.class.name.gsub(/.*::/, '').downcase.to_sym
|
16
27
|
setup
|
17
28
|
end
|
18
29
|
|
19
|
-
def
|
20
|
-
|
21
|
-
out << "Arli : Version #{::Arli::VERSION.bold.yellow}\n"
|
22
|
-
out << "Command : #{command.to_s.bold.blue}\n" if command
|
23
|
-
out << "Library Path : #{lib_path.bold.green}\n" if lib_path
|
24
|
-
out << "ArliFile : #{arli_file.file.bold.magenta}\n" if
|
25
|
-
arli_file && arli_file.file
|
26
|
-
out << '——————————————————————————————————————————————————————————'
|
27
|
-
|
28
|
-
info out
|
29
|
-
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
# Commands implement #run method that uses helpers below:
|
34
|
-
protected
|
35
|
-
|
36
|
-
def all_dependencies(cmd, *args)
|
37
|
-
for_each_dependency do |dep|
|
38
|
-
begin
|
39
|
-
method_name = "#{cmd}_dependency".to_sym
|
40
|
-
argv = args.map { |key| dep[key] }
|
41
|
-
if self.respond_to?(method_name)
|
42
|
-
info("dependency #{dep.inspect}: calling #{method_name} with args #{argv.inspect}") if Arli::DEBUG
|
43
|
-
self.send(method_name, *argv) do |system_command|
|
44
|
-
execute(system_command)
|
45
|
-
end
|
46
|
-
else
|
47
|
-
raise ArgumentError,
|
48
|
-
"Method #{method_name.to_s.bold.blue} is not implemented on #{self.class.name.bold.red}"
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
rescue Exception => e
|
53
|
-
error "Error while running command #{cmd}:\n\n#{e.message.bold.red}"
|
54
|
-
if Arli::DEBUG
|
55
|
-
error e.backtrace.join("\n")
|
56
|
-
end
|
30
|
+
def name
|
31
|
+
self.class.name.gsub(/.*::/, '').downcase
|
57
32
|
end
|
58
33
|
|
59
34
|
def setup
|
60
35
|
FileUtils.mkdir_p(lib_path)
|
61
36
|
end
|
62
37
|
|
63
|
-
# @param <String> *args — list of arguments or a single string
|
64
|
-
def execute(*args)
|
65
|
-
cmd = args.join(' ')
|
66
|
-
info cmd.bold.green
|
67
|
-
o, e, s = Open3.capture3(cmd)
|
68
|
-
puts o if o
|
69
|
-
puts e.red if e
|
70
|
-
s
|
71
|
-
rescue Exception => e
|
72
|
-
error "Error running [#{cmd.bold.yellow}]\n" +
|
73
|
-
"Current folder is [#{Dir.pwd.bold.yellow}]", e
|
74
|
-
raise e
|
75
|
-
end
|
76
|
-
|
77
|
-
def for_each_dependency(&_block)
|
78
|
-
raise 'Library Path is nil!' unless lib_path
|
79
|
-
FileUtils.mkpath(lib_path) unless Dir.exist?(lib_path)
|
80
|
-
arli_file.each do |dependency|
|
81
|
-
Dir.chdir(lib_path) do
|
82
|
-
yield(dependency)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
38
|
def error(msg, exception = nil)
|
88
|
-
printf 'Runtime Error: '.
|
39
|
+
printf 'Runtime Error: '.red + "\n#{msg}\n" if msg
|
89
40
|
if exception
|
90
41
|
puts
|
91
42
|
printf 'Exception: '.red + "\n#{exception.inspect.red}\n\n"
|
@@ -94,7 +45,7 @@ module Arli
|
|
94
45
|
end
|
95
46
|
|
96
47
|
def info(msg, header = nil)
|
97
|
-
printf('%-20s', header.
|
48
|
+
printf('%-20s', header.blue) if header
|
98
49
|
printf((header ? ' : ' : '') + msg + "\n") if msg
|
99
50
|
end
|
100
51
|
|
@@ -1,37 +1,25 @@
|
|
1
1
|
require 'json'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'open3'
|
4
2
|
require 'arli'
|
5
|
-
require '
|
3
|
+
require 'net/http'
|
4
|
+
require_relative 'base'
|
5
|
+
require_relative '../installers/zip_file'
|
6
6
|
|
7
7
|
module Arli
|
8
8
|
module Commands
|
9
|
-
class Install <
|
9
|
+
class Install < Base
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def initialize(options)
|
12
|
+
super(options)
|
13
|
+
self.arlifile = Arli::ArliFile.new(lib_path: lib_path,
|
14
|
+
arlifile_path: options[:arli_dir])
|
13
15
|
end
|
14
16
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
Existing folder found for library #{name.red}.
|
20
|
-
Please use -u switch with 'install' command,
|
21
|
-
or invoke the 'update' command directly."
|
22
|
-
EOF
|
23
|
-
.gsub(/^\s+/, '')
|
24
|
-
|
25
|
-
else
|
26
|
-
update_dependency(name)
|
27
|
-
end
|
28
|
-
else
|
29
|
-
"git clone -v #{url} #{name} 2>&1"
|
30
|
-
end
|
31
|
-
yield(cmd) if block_given?
|
32
|
-
cmd
|
17
|
+
def run
|
18
|
+
arlifile.each_dependency do |lib|
|
19
|
+
Arli::Installer.new(lib: lib, command: self).install
|
20
|
+
end
|
33
21
|
end
|
34
|
-
end
|
35
22
|
|
23
|
+
end
|
36
24
|
end
|
37
25
|
end
|
data/lib/arli/commands/search.rb
CHANGED
@@ -3,6 +3,7 @@ require 'fileutils'
|
|
3
3
|
require 'open3'
|
4
4
|
require 'arli'
|
5
5
|
require 'arli/commands/base'
|
6
|
+
require 'arli/errors'
|
6
7
|
require 'arduino/library'
|
7
8
|
require 'awesome_print'
|
8
9
|
module Arli
|
@@ -15,30 +16,30 @@ module Arli
|
|
15
16
|
:limit,
|
16
17
|
:database
|
17
18
|
|
18
|
-
class InvalidOptionError < ArgumentError; end
|
19
|
-
|
20
19
|
def initialize(options)
|
21
20
|
super(options)
|
22
|
-
self.search_string = options[:
|
23
|
-
|
21
|
+
self.search_string = options[:argv].first
|
22
|
+
|
23
|
+
puts "using search string [#{search_string}]" if search_string && Arli.debug?
|
24
|
+
self.limit = options[:limit] || 100
|
24
25
|
|
25
|
-
raise
|
26
|
+
raise Arli::Errors::InvalidSyntaxError, 'Please provide search string after the "search" command' \
|
26
27
|
unless search_string
|
27
28
|
|
28
29
|
begin
|
29
30
|
self.search_opts = eval("{ #{search_string} }")
|
30
31
|
rescue => e
|
31
|
-
raise
|
32
|
+
raise Arli::Errors::InvalidSyntaxError, "Search string '#{search_string}' is invalid.\n" +
|
32
33
|
e.message.red
|
33
34
|
end
|
34
35
|
|
35
36
|
unless search_opts.is_a?(::Hash) && search_opts.size > 0
|
36
|
-
raise
|
37
|
+
raise Arli::Errors::InvalidSyntaxError, "Search string '#{search_string}' did not eval to Hash.\n"
|
37
38
|
end
|
38
39
|
|
39
40
|
self.database = options[:database] ? db_from(option[:database]) : db_default
|
40
41
|
|
41
|
-
search_opts.merge!(limit: limit) if limit
|
42
|
+
search_opts.merge!(limit: limit) if limit && limit > 0
|
42
43
|
end
|
43
44
|
|
44
45
|
def run
|
data/lib/arli/config.rb
ADDED
data/lib/arli/errors.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Arli
|
2
|
+
module Errors
|
3
|
+
class ArliError < StandardError; end
|
4
|
+
|
5
|
+
class InvalidCommandError < ArliError; end
|
6
|
+
|
7
|
+
class InvalidSyntaxError < ArliError; end
|
8
|
+
|
9
|
+
class AbstractMethodCalled < ArliError; end
|
10
|
+
|
11
|
+
class ArliFileNotFound < ArliError; end
|
12
|
+
|
13
|
+
class LibraryAlreadyExists < ArliError; end
|
14
|
+
|
15
|
+
class InstallerError < ArliError; end
|
16
|
+
|
17
|
+
class ZipFileError < InstallerError; end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'arli'
|
2
|
+
require 'forwardable'
|
3
|
+
module Arli
|
4
|
+
class Installer
|
5
|
+
extend Forwardable
|
6
|
+
attr_accessor :lib, :lib_dir, :lib_path, :command
|
7
|
+
|
8
|
+
def_delegators :@command, :info, :error, :debug
|
9
|
+
|
10
|
+
def initialize(lib:, command:, lib_path: Arli.library_path)
|
11
|
+
self.lib = lib
|
12
|
+
self.command = command
|
13
|
+
self.lib_dir = lib.name.gsub(/ /, '_')
|
14
|
+
self.lib_path = lib_path
|
15
|
+
end
|
16
|
+
|
17
|
+
def exists?
|
18
|
+
Dir.exist?(target_lib_path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def install
|
22
|
+
action = self.exists? ? 'replacing' : 'installing'
|
23
|
+
backup! if command.create_backup
|
24
|
+
abort! if exists? && command.abort_if_exists
|
25
|
+
|
26
|
+
s "#{action} #{lib.name.blue}"
|
27
|
+
library = ::Arduino::Library::Resolver.resolve(lib)
|
28
|
+
|
29
|
+
if library.nil?
|
30
|
+
s ' ❌ ' + "\n"
|
31
|
+
elsif library.url.nil?
|
32
|
+
s ' ❌ ' + "\n"
|
33
|
+
else
|
34
|
+
s "(#{library.version.blue})" if library.version
|
35
|
+
s '✔ '.bold.green
|
36
|
+
if library.url =~ /\.zip$/i
|
37
|
+
s 'unpacking zip...'
|
38
|
+
Arli::Installers::ZipFile.new(lib: library).install
|
39
|
+
s '✔ '.bold.green
|
40
|
+
else
|
41
|
+
c = exists? ? git_update_command : git_clone_command
|
42
|
+
s 'running git...'
|
43
|
+
execute(c)
|
44
|
+
s '✔ '.bold.green
|
45
|
+
end
|
46
|
+
end
|
47
|
+
s nil, true
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def git_update_command
|
52
|
+
"cd #{lib_dir} && git pull --rebase 2>&1"
|
53
|
+
end
|
54
|
+
|
55
|
+
def git_clone_command
|
56
|
+
"git clone -v #{lib.url} #{lib_dir} 2>&1"
|
57
|
+
end
|
58
|
+
|
59
|
+
def backup_lib_path
|
60
|
+
target_lib_path + ".#{Time.now.strftime('%Y%m%d%H%M%S')}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def target_lib_path
|
64
|
+
"#{lib_path}/#{lib_dir}"
|
65
|
+
end
|
66
|
+
|
67
|
+
def backup!
|
68
|
+
FileUtils.cp_r(target_lib_path, backup_lib_path) if exists?
|
69
|
+
end
|
70
|
+
|
71
|
+
def abort!
|
72
|
+
raise Arli::Errors::LibraryAlreadyExists,
|
73
|
+
"Library #{target_lib_path} already exists!"
|
74
|
+
end
|
75
|
+
|
76
|
+
def s(msg, newline = false)
|
77
|
+
printf msg + ' ' if msg
|
78
|
+
puts if newline
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
# @param <String> *args — list of arguments or a single string
|
84
|
+
def execute(*args)
|
85
|
+
cmd = args.join(' ')
|
86
|
+
raise 'No command to run was given' unless cmd
|
87
|
+
info("\n" + cmd.green) if self.debug
|
88
|
+
o, e, s = Open3.capture3(cmd)
|
89
|
+
info("\n" + o) if o if self.debug
|
90
|
+
info("\n" + e.red) if e && self.debug
|
91
|
+
s
|
92
|
+
rescue Exception => e
|
93
|
+
error "Error running [#{args.join(' ')}]\n" +
|
94
|
+
"Current folder is [#{Dir.pwd.yellow}]", e
|
95
|
+
raise e
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'archive/zip'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
module Installers
|
5
|
+
class ZipFile
|
6
|
+
attr_accessor :lib, :lib_dir
|
7
|
+
|
8
|
+
def initialize(lib:)
|
9
|
+
self.lib = lib
|
10
|
+
self.lib_dir = lib.name.gsub(/ /, '_')
|
11
|
+
raise 'Invalid URL for this installer: ' + lib.url unless lib.url =~ /\.zip$/i
|
12
|
+
end
|
13
|
+
|
14
|
+
def install
|
15
|
+
download!
|
16
|
+
|
17
|
+
remove_library!
|
18
|
+
remove_library_versions!
|
19
|
+
|
20
|
+
unzip(zip_archive, '.')
|
21
|
+
|
22
|
+
dir = dirs_matching(lib_dir).first
|
23
|
+
|
24
|
+
FileUtils.move(dir, lib_dir) if dir
|
25
|
+
|
26
|
+
FileUtils.rm_f(zip_archive) if File.exist?(zip_archive)
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_library!
|
30
|
+
FileUtils.rm_rf(lib_dir)
|
31
|
+
end
|
32
|
+
|
33
|
+
def remove_library_versions!
|
34
|
+
dirs = dirs_matching(lib_dir)
|
35
|
+
dirs.delete(lib_dir) # we don't want to delete the actual library
|
36
|
+
dirs.each { |d| FileUtils.rm_f(d) }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def dirs_matching(name)
|
42
|
+
Dir.glob("#{name}*").select { |d| File.directory?(d) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def zip_archive
|
46
|
+
@zip_archive ||= File.basename(lib.url)
|
47
|
+
end
|
48
|
+
|
49
|
+
def download!
|
50
|
+
File.write(zip_archive, Net::HTTP.get(URI.parse(lib.url)))
|
51
|
+
end
|
52
|
+
|
53
|
+
# def unzip(file, destination)
|
54
|
+
# Archive::Zip.extract(file, destination, on_error: :skip)
|
55
|
+
# end
|
56
|
+
def unzip(file, destination)
|
57
|
+
`unzip -o #{file} -d #{destination}`
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/arli/logger.rb
ADDED
data/lib/arli/parser.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
require 'arduino/library'
|
2
|
+
require 'arli/config'
|
3
|
+
require 'arli/version'
|
4
|
+
|
2
5
|
module Arli
|
3
6
|
class CLI
|
4
7
|
class Parser < OptionParser
|
5
|
-
attr_accessor :output_lines, :command, :options
|
8
|
+
attr_accessor :output_lines, :command, :options, :arlifile
|
6
9
|
|
7
10
|
def initialize(command = nil)
|
8
11
|
super(nil, 22)
|
9
|
-
self.output_lines
|
10
|
-
self.command
|
11
|
-
self.options
|
12
|
+
self.output_lines = ::Array.new
|
13
|
+
self.command = command
|
14
|
+
self.options = ::Hashie::Mash.new
|
15
|
+
self.arlifile = options[:arli_dir] ?
|
16
|
+
options[:arli_dir] + '/' + Arli::Config::DEFAULT_FILENAME :
|
17
|
+
Arli::Config::DEFAULT_FILENAME
|
18
|
+
self.options[:arlifile] = arlifile
|
12
19
|
end
|
13
20
|
|
14
21
|
def sep(text = nil)
|
@@ -16,66 +23,83 @@ module Arli
|
|
16
23
|
end
|
17
24
|
|
18
25
|
def option_dependency_file
|
19
|
-
on('-
|
20
|
-
'
|
21
|
-
"
|
22
|
-
options[:
|
26
|
+
on('-p', '--arli-path PATH',
|
27
|
+
'Folder where ' + 'Arlifile'.green + ' is located,',
|
28
|
+
"Defaults to the current directory.\n\n") do |v|
|
29
|
+
options[:arli_dir] = v
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
26
33
|
def option_lib_home
|
27
|
-
on('-l', '--
|
28
|
-
"
|
34
|
+
on('-l', '--libs PATH', 'Local folder where libraries are installed',
|
35
|
+
"Defaults to #{default_library_path}\n\n") do |v|
|
29
36
|
options[:lib_home] = v
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
33
|
-
|
34
40
|
def option_search
|
35
|
-
on('-
|
36
|
-
%Q(eg: -s "name: 'AudioZero', version: /^1.0/")) do |v|
|
37
|
-
options[:search] = v
|
38
|
-
end
|
39
|
-
on('-d', '--database SOURCE',
|
41
|
+
on('-d', '--database FILE/URL',
|
40
42
|
'a JSON file name, or a URL that contains the index',
|
41
|
-
'
|
43
|
+
'Defaults to the Arduino-maintained list') do |v|
|
42
44
|
options[:database] = v
|
43
45
|
end
|
44
|
-
on('-m', '--max
|
46
|
+
on('-m', '--max NUMBER',
|
45
47
|
'if provided, limits the result set to this number',
|
46
|
-
'
|
47
|
-
|
48
|
+
'Defaults to 100') do |v|
|
49
|
+
options[:limit] = v.to_i if v
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
53
|
def option_abort_if_exists
|
52
|
-
on('-e', '--
|
53
|
-
'
|
54
|
-
'
|
55
|
-
|
54
|
+
on('-e', '--if-exists ACTION',
|
55
|
+
'If a library folder already exists, by default',
|
56
|
+
'it will be overwritten or updated if possible.',
|
57
|
+
'Alternatively you can either ' + 'abort'.bold.blue + ' or ' + 'backup'.bold.blue
|
58
|
+
) do |v|
|
59
|
+
if v =~ /abort/i
|
60
|
+
options[:abort_if_exists] = true
|
61
|
+
elsif v =~ /backup/
|
62
|
+
options[:create_backup] = true
|
63
|
+
elsif v =~ /replace/
|
64
|
+
end
|
56
65
|
end
|
66
|
+
sep ' '
|
57
67
|
end
|
58
68
|
|
59
|
-
def option_help(commands: false,
|
69
|
+
def option_help(commands: false, command_name: nil)
|
70
|
+
on('-D', '--debug',
|
71
|
+
'Print debugging info.') do |v|
|
72
|
+
options[:debug] = true
|
73
|
+
end
|
74
|
+
on('-t', '--trace',
|
75
|
+
'Print exception stack traces.') do |v|
|
76
|
+
options[:trace] = v
|
77
|
+
end
|
78
|
+
on('-v', '--verbose',
|
79
|
+
'Print more information.') do |v|
|
80
|
+
options[:verbose] = true
|
81
|
+
end
|
82
|
+
on('-V', '--version',
|
83
|
+
'Print current version and exit') do |v|
|
84
|
+
output 'Version: ' + Arli::VERSION
|
85
|
+
options[:help] = true
|
86
|
+
end
|
60
87
|
on('-h', '--help', 'prints this help') do
|
61
|
-
|
62
|
-
output ' ' * 4 +
|
88
|
+
output 'Description:' if command_name
|
89
|
+
output ' ' * 4 + command_name[:description].green if command_name
|
63
90
|
output ''
|
64
91
|
output_help
|
65
92
|
output_command_help if commands
|
93
|
+
|
94
|
+
if command_name && command_name[:example]
|
95
|
+
output 'Example:'
|
96
|
+
output ' ' * 4 + command_name[:example]
|
97
|
+
end
|
98
|
+
|
66
99
|
options[:help] = true
|
67
100
|
end
|
68
101
|
end
|
69
102
|
|
70
|
-
def option_library
|
71
|
-
on('-n', '--lib-name LIBRARY', 'Library Name') { |v| options[:library_name] = v }
|
72
|
-
on('-f', '--from FROM', 'A git or https URL') { |v| options[:library_from] = v }
|
73
|
-
on('-v', '--version VERSION', 'Library Version, i.e. git tag') { |v| options[:library_version] = v }
|
74
|
-
on('-i', '--install', 'Install a library') { |v| options[:library_action] = :install }
|
75
|
-
on('-r', '--remove', 'Remove a library') { |v| options[:library_action] = :remove }
|
76
|
-
on('-u', '--update', 'Update a local library') { |v| options[:library_action] = :update }
|
77
|
-
end
|
78
|
-
|
79
103
|
def option_help_with_subtext
|
80
104
|
option_help
|
81
105
|
end
|
@@ -89,14 +113,14 @@ module Arli
|
|
89
113
|
end
|
90
114
|
|
91
115
|
def command_help
|
92
|
-
subtext = "Available Commands:\n"
|
116
|
+
subtext = "Available Commands:\n"
|
93
117
|
|
94
118
|
::Arli::CLI.commands.each_pair do |command, config|
|
95
119
|
subtext << %Q/#{sprintf(' %-12s', command.to_s).green} : #{sprintf('%s', config[:description]).yellow}\n/
|
96
120
|
end
|
97
121
|
subtext << <<-EOS
|
98
122
|
|
99
|
-
See #{COMMAND.
|
123
|
+
See #{COMMAND.blue + ' <command> '.green + '--help'.yellow} for more information on a specific command.
|
100
124
|
|
101
125
|
EOS
|
102
126
|
subtext
|
@@ -112,9 +136,8 @@ See #{COMMAND.bold.blue + ' <command> '.bold.green + '--help'.bold.yellow} for m
|
|
112
136
|
end
|
113
137
|
|
114
138
|
def default_library_path
|
115
|
-
|
139
|
+
::Arli.config.library_path.gsub(%r(#{ENV['HOME']}), '~').blue
|
116
140
|
end
|
117
|
-
|
118
141
|
end
|
119
142
|
end
|
120
143
|
end
|