arli 0.5.1 → 0.6.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/.rake_tasks~ +8 -0
- data/README.md +122 -30
- data/Rakefile +24 -2
- data/arli.gemspec +4 -1
- data/exe/arli +2 -4
- data/lib/arli.rb +19 -21
- data/lib/arli/actions.rb +19 -0
- data/lib/arli/actions/action.rb +32 -0
- data/lib/arli/actions/backup.rb +30 -0
- data/lib/arli/actions/dir_name.rb +66 -0
- data/lib/arli/actions/git_repo.rb +43 -0
- data/lib/arli/actions/zip_file.rb +54 -0
- data/lib/arli/arli_file.rb +22 -37
- data/lib/arli/cli.rb +4 -190
- data/lib/arli/cli/app.rb +73 -0
- data/lib/arli/cli/command_finder.rb +72 -0
- data/lib/arli/{parser.rb → cli/parser.rb} +66 -56
- data/lib/arli/cli/parser_factory.rb +97 -0
- data/lib/arli/cli/runner.rb +40 -0
- data/lib/arli/commands.rb +8 -0
- data/lib/arli/commands/base.rb +23 -30
- data/lib/arli/commands/install.rb +14 -9
- data/lib/arli/commands/search.rb +35 -10
- data/lib/arli/configuration.rb +62 -0
- data/lib/arli/extensions.rb +9 -0
- data/lib/arli/installer.rb +30 -78
- data/lib/arli/library.rb +49 -0
- data/lib/arli/output.rb +94 -0
- data/lib/arli/version.rb +1 -1
- metadata +63 -8
- data/lib/arli/config.rb +0 -16
- data/lib/arli/installers/zip_file.rb +0 -61
- data/lib/arli/logger.rb +0 -13
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
require 'colored2'
|
5
|
+
|
6
|
+
require_relative 'parser'
|
7
|
+
require_relative 'parser_factory'
|
8
|
+
require_relative '../commands'
|
9
|
+
require_relative '../commands/search'
|
10
|
+
require_relative '../commands/install'
|
11
|
+
require_relative '../output'
|
12
|
+
|
13
|
+
module Arli
|
14
|
+
module CLI
|
15
|
+
class CommandFinder
|
16
|
+
|
17
|
+
include Arli::Output
|
18
|
+
|
19
|
+
attr_accessor :argv, :config, :command_name, :command
|
20
|
+
|
21
|
+
def initialize(argv, config: Arli.config)
|
22
|
+
self.config = config
|
23
|
+
self.argv = argv
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse!
|
27
|
+
self.command_name = detect_command
|
28
|
+
parse_command_arguments!(command_name)
|
29
|
+
unless Arli.config.help
|
30
|
+
self.command = instantiate_command
|
31
|
+
if self.command
|
32
|
+
config.runtime.command.instance = command
|
33
|
+
config.runtime.command.name = command_name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_command_arguments!(cmd)
|
40
|
+
parser = factory.command_parser(cmd)
|
41
|
+
if parser
|
42
|
+
factory.parse_argv(parser, argv)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def instantiate_command
|
47
|
+
self.command_name = detect_command unless command_name
|
48
|
+
begin
|
49
|
+
name = command_name.to_s.capitalize.to_sym
|
50
|
+
command_class = ::Arli::Commands.const_get(name)
|
51
|
+
raise_invalid_arli_command!(command_name) unless command_class
|
52
|
+
command_class.new(config: config) if command_class
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def detect_command
|
57
|
+
return nil unless argv.first && argv.first !~ /^-.*$/
|
58
|
+
cmd = argv.shift.to_sym
|
59
|
+
if factory.valid_command?(cmd)
|
60
|
+
cmd
|
61
|
+
else
|
62
|
+
raise_invalid_arli_command!(cmd)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def factory
|
67
|
+
Arli::CLI::ParserFactory
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -1,21 +1,19 @@
|
|
1
|
-
require '
|
2
|
-
require 'arli/config'
|
3
|
-
require 'arli/version'
|
1
|
+
require 'arli/configuration'
|
4
2
|
|
5
3
|
module Arli
|
6
|
-
|
4
|
+
module CLI
|
7
5
|
class Parser < OptionParser
|
8
|
-
attr_accessor :output_lines, :command, :options, :arlifile
|
9
6
|
|
10
|
-
|
7
|
+
attr_accessor :output_lines,
|
8
|
+
:command,
|
9
|
+
:config
|
10
|
+
|
11
|
+
def initialize(config: Arli.config, command: nil)
|
11
12
|
super(nil, 22)
|
12
|
-
|
13
|
-
self.
|
14
|
-
self.
|
15
|
-
self.
|
16
|
-
options[:arli_dir] + '/' + Arli::Config::DEFAULT_FILENAME :
|
17
|
-
Arli::Config::DEFAULT_FILENAME
|
18
|
-
self.options[:arlifile] = arlifile
|
13
|
+
|
14
|
+
self.config = config
|
15
|
+
self.command = command
|
16
|
+
self.output_lines = ::Array.new
|
19
17
|
end
|
20
18
|
|
21
19
|
def sep(text = nil)
|
@@ -23,17 +21,18 @@ module Arli
|
|
23
21
|
end
|
24
22
|
|
25
23
|
def option_dependency_file
|
26
|
-
on('-
|
24
|
+
on('-a', '--arli-path PATH',
|
27
25
|
'Folder where ' + 'Arlifile'.green + ' is located,',
|
28
26
|
"Defaults to the current directory.\n\n") do |v|
|
29
|
-
|
27
|
+
config.arlifile.path = v
|
30
28
|
end
|
31
29
|
end
|
32
30
|
|
33
31
|
def option_lib_home
|
34
|
-
on('-l', '--
|
35
|
-
|
36
|
-
|
32
|
+
on('-l', '--libraries PATH',
|
33
|
+
'Local folder where libraries are installed',
|
34
|
+
"Defaults to #{Arli.default_library_path}\n\n") do |v|
|
35
|
+
config.libraries.path = v
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
@@ -41,12 +40,13 @@ module Arli
|
|
41
40
|
on('-d', '--database FILE/URL',
|
42
41
|
'a JSON file name, or a URL that contains the index',
|
43
42
|
'Defaults to the Arduino-maintained list') do |v|
|
44
|
-
|
43
|
+
config.database.path = v
|
45
44
|
end
|
45
|
+
|
46
46
|
on('-m', '--max NUMBER',
|
47
47
|
'if provided, limits the result set to this number',
|
48
48
|
'Defaults to 100') do |v|
|
49
|
-
|
49
|
+
config.search.results.limit = v.to_i if v
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -56,47 +56,37 @@ module Arli
|
|
56
56
|
'it will be overwritten or updated if possible.',
|
57
57
|
'Alternatively you can either ' + 'abort'.bold.blue + ' or ' + 'backup'.bold.blue
|
58
58
|
) do |v|
|
59
|
-
if v
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
if v == 'abort'
|
60
|
+
config.install.if_exists.abort = true
|
61
|
+
config.install.if_exists.overwrite = false
|
62
|
+
elsif v == 'backup'
|
63
|
+
config.install.if_exists.backup = true
|
64
64
|
end
|
65
65
|
end
|
66
66
|
sep ' '
|
67
67
|
end
|
68
68
|
|
69
69
|
def option_help(commands: false, command_name: nil)
|
70
|
-
|
71
|
-
|
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
|
70
|
+
common_help_options
|
71
|
+
|
87
72
|
on('-h', '--help', 'prints this help') do
|
88
|
-
|
89
|
-
|
90
|
-
|
73
|
+
::Arli.config.help = true
|
74
|
+
|
75
|
+
command_hash = factory.command_parsers[command_name]
|
76
|
+
|
77
|
+
if command_hash && command_hash[:description]
|
78
|
+
output 'Description:'
|
79
|
+
output ' ' + command_hash[:description]
|
80
|
+
output ''
|
81
|
+
end
|
82
|
+
|
91
83
|
output_help
|
92
84
|
output_command_help if commands
|
93
85
|
|
94
|
-
if
|
86
|
+
if command_hash && command_hash[:example]
|
95
87
|
output 'Example:'
|
96
|
-
output '
|
88
|
+
output ' ' + command_hash[:example]
|
97
89
|
end
|
98
|
-
|
99
|
-
options[:help] = true
|
100
90
|
end
|
101
91
|
end
|
102
92
|
|
@@ -113,14 +103,14 @@ module Arli
|
|
113
103
|
end
|
114
104
|
|
115
105
|
def command_help
|
116
|
-
subtext = "Available Commands:\n"
|
117
106
|
|
118
|
-
|
119
|
-
|
107
|
+
subtext = "Available Commands:\n"
|
108
|
+
factory.command_parsers.each_pair do |command, config|
|
109
|
+
subtext << %Q/#{sprintf(' %-12s', command.to_s).green} — #{sprintf('%s', config[:description]).blue}\n/
|
120
110
|
end
|
121
111
|
subtext << <<-EOS
|
122
|
-
|
123
|
-
See #{
|
112
|
+
|
113
|
+
See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yellow} for more information on a specific command.
|
124
114
|
|
125
115
|
EOS
|
126
116
|
subtext
|
@@ -135,8 +125,28 @@ See #{COMMAND.blue + ' <command> '.green + '--help'.yellow} for more information
|
|
135
125
|
puts output.join("\n") unless output.empty?
|
136
126
|
end
|
137
127
|
|
138
|
-
def
|
139
|
-
::
|
128
|
+
def factory
|
129
|
+
Arli::CLI::ParserFactory
|
130
|
+
end
|
131
|
+
|
132
|
+
def common_help_options
|
133
|
+
on('-D', '--debug',
|
134
|
+
'Print debugging info.') do |v|
|
135
|
+
config.debug = true
|
136
|
+
end
|
137
|
+
on('-t', '--trace',
|
138
|
+
'Print exception stack traces.') do |v|
|
139
|
+
config.trace = v
|
140
|
+
end
|
141
|
+
on('-v', '--verbose',
|
142
|
+
'Print more information.') do |v|
|
143
|
+
config.verbose = true
|
144
|
+
end
|
145
|
+
on('-V', '--version',
|
146
|
+
'Print current version and exit') do |v|
|
147
|
+
puts 'Version: ' + Arli::VERSION
|
148
|
+
exit
|
149
|
+
end
|
140
150
|
end
|
141
151
|
end
|
142
152
|
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative 'parser'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
module CLI
|
5
|
+
module ParserFactory
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def default_help
|
10
|
+
gp = global_parser
|
11
|
+
gp.parse!(%w(--help))
|
12
|
+
gp.print
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_argv(parser, argv)
|
16
|
+
if parser
|
17
|
+
parser.parse!(argv)
|
18
|
+
parser.print
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_parser(command = nil, &block)
|
23
|
+
::Arli::CLI::Parser.new(command: command,
|
24
|
+
config: Arli.config, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def global_parser
|
28
|
+
@global ||= make_parser do |parser|
|
29
|
+
parser.banner = usage_line
|
30
|
+
parser.sep
|
31
|
+
parser.option_help(commands: true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def command_parsers
|
36
|
+
@command_parsers ||= {
|
37
|
+
install: {
|
38
|
+
description: 'installs libraries defined in Arlifile',
|
39
|
+
parser: -> (command_name) {
|
40
|
+
make_parser(command_name) do |parser|
|
41
|
+
parser.banner = usage_line 'install'
|
42
|
+
parser.option_lib_home
|
43
|
+
parser.option_dependency_file
|
44
|
+
parser.option_abort_if_exists
|
45
|
+
parser.option_help(command_name: command_name)
|
46
|
+
end
|
47
|
+
} },
|
48
|
+
|
49
|
+
search: {
|
50
|
+
description: 'Flexible Search of the Arduino Library Database',
|
51
|
+
example: 'arli search '.green + %Q['name: /AudioZero/, version: "1.0.1"'].green,
|
52
|
+
parser: -> (command_name) {
|
53
|
+
make_parser(command_name) do |parser|
|
54
|
+
parser.banner = usage_line 'search ' + '[ name-match | expression ]'.magenta
|
55
|
+
parser.option_search
|
56
|
+
parser.option_help(command_name: command_name)
|
57
|
+
end
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def commands
|
64
|
+
command_parsers.keys
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid_command?(command)
|
68
|
+
commands.include?(command)
|
69
|
+
end
|
70
|
+
|
71
|
+
def command_parser(cmd)
|
72
|
+
cmd_hash = command_parsers[cmd]
|
73
|
+
cmd_hash ? cmd_hash[:parser].call(cmd) : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
def global_usage(command)
|
77
|
+
"Usage:\n " + Arli::Configuration::ARLI_COMMAND.blue +
|
78
|
+
' [ options ] '.yellow + '[ ' + (command || 'command').green +
|
79
|
+
' [ options ] '.yellow + ' ]' + "\n"
|
80
|
+
end
|
81
|
+
|
82
|
+
def command_usage(command)
|
83
|
+
"Usage:\n " + Arli::Configuration::ARLI_COMMAND.blue + ' ' +
|
84
|
+
command.green +
|
85
|
+
' [options]'.yellow + "\n\n" +
|
86
|
+
'Command Options'
|
87
|
+
end
|
88
|
+
|
89
|
+
def usage_line(command = nil)
|
90
|
+
command ? command_usage(command) : global_usage(command)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'colored2'
|
2
|
+
require 'arli/cli/app'
|
3
|
+
require 'pp'
|
4
|
+
module Arli
|
5
|
+
module CLI
|
6
|
+
# For the reasons this file is the way it is, please refer to
|
7
|
+
# https://github.com/erikhuda/thor/wiki/Integrating-with-Aruba-In-Process-Runs
|
8
|
+
class Runner
|
9
|
+
def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
|
10
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute!
|
14
|
+
exit_code = begin
|
15
|
+
$stderr = @stderr
|
16
|
+
$stdin = @stdin
|
17
|
+
$stdout = @stdout
|
18
|
+
|
19
|
+
Arli::CLI::App.new(@argv).start
|
20
|
+
0
|
21
|
+
rescue StandardError => e
|
22
|
+
b = e.backtrace
|
23
|
+
@stderr.puts("#{b.shift.bold}:\n")
|
24
|
+
@stderr.puts("#{e.message.bold.red} (#{e.class.name.yellow})")
|
25
|
+
@stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n")).red
|
26
|
+
1
|
27
|
+
rescue SystemExit => e
|
28
|
+
e.status
|
29
|
+
ensure
|
30
|
+
$stderr = STDERR
|
31
|
+
$stdin = STDIN
|
32
|
+
$stdout = STDOUT
|
33
|
+
ap(Arli.config.to_hash, indent: 6, index: false) if Arli.config.debug
|
34
|
+
end
|
35
|
+
@kernel.exit(exit_code)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/arli/commands/base.rb
CHANGED
@@ -4,51 +4,44 @@ require 'open3'
|
|
4
4
|
require 'arli'
|
5
5
|
require 'arli/version'
|
6
6
|
require 'arli/errors'
|
7
|
+
require 'arli/output'
|
7
8
|
|
8
9
|
module Arli
|
9
10
|
module Commands
|
10
11
|
class Base
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def initialize(options)
|
20
|
-
self.lib_path = options[:lib_home]
|
21
|
-
self.abort_if_exists = options[:abort_if_exists]
|
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
|
12
|
+
include Arli::Output
|
13
|
+
|
14
|
+
attr_accessor :config, :name
|
15
|
+
|
16
|
+
def initialize(config: Arli.config)
|
17
|
+
self.config = config
|
18
|
+
FileUtils.mkdir_p(library_path) unless Dir.exist?(library_path)
|
27
19
|
setup
|
28
20
|
end
|
29
21
|
|
30
|
-
def
|
31
|
-
|
22
|
+
def run(*args)
|
23
|
+
raise ArgumentError, 'This method must be implemented in subclasses'
|
32
24
|
end
|
33
25
|
|
34
|
-
def
|
35
|
-
|
26
|
+
def runtime
|
27
|
+
config.runtime
|
36
28
|
end
|
37
29
|
|
38
|
-
def
|
39
|
-
|
40
|
-
if exception
|
41
|
-
puts
|
42
|
-
printf 'Exception: '.red + "\n#{exception.inspect.red}\n\n"
|
43
|
-
end
|
44
|
-
puts
|
30
|
+
def name
|
31
|
+
@name ||= self.class.name.gsub(/.*::/, '').downcase.to_sym
|
45
32
|
end
|
46
33
|
|
47
|
-
def
|
48
|
-
|
49
|
-
printf((header ? ' : ' : '') + msg + "\n") if msg
|
34
|
+
def library_path
|
35
|
+
config.libraries.path
|
50
36
|
end
|
51
37
|
|
38
|
+
def setup
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def params
|
43
|
+
|
44
|
+
end
|
52
45
|
end
|
53
46
|
end
|
54
47
|
end
|