arli 0.8.3 → 0.9.0
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 +5 -4
- data/.travis.yml +16 -8
- data/README.md +235 -124
- data/Rakefile +1 -1
- data/arli.gemspec +1 -0
- data/exe/arli +1 -0
- data/lib/arli.rb +1 -1
- data/lib/arli/actions/action.rb +7 -33
- data/lib/arli/actions/unzip_file.rb +9 -6
- data/lib/arli/arli_file.rb +32 -28
- data/lib/arli/cli/app.rb +2 -3
- data/lib/arli/cli/command_finder.rb +2 -2
- data/lib/arli/cli/parser.rb +36 -9
- data/lib/arli/cli/parser_factory.rb +40 -38
- data/lib/arli/cli/runner.rb +0 -1
- data/lib/arli/commands/base.rb +2 -2
- data/lib/arli/commands/install.rb +49 -31
- data/lib/arli/commands/search.rb +40 -35
- data/lib/arli/configuration.rb +4 -3
- data/lib/arli/extensions.rb +6 -0
- data/lib/arli/helpers/inherited.rb +48 -0
- data/lib/arli/helpers/output.rb +187 -0
- data/lib/arli/library.rb +21 -2
- data/lib/arli/library/installer.rb +2 -2
- data/lib/arli/library/multi_version.rb +153 -0
- data/lib/arli/library/{proxy.rb → single_version.rb} +5 -20
- data/lib/arli/lock/file.rb +1 -2
- data/lib/arli/lock/formats/base.rb +8 -0
- data/lib/arli/lock/formats/cmake.rb +21 -5
- data/lib/arli/lock/formats/json.rb +2 -0
- data/lib/arli/lock/formats/text.rb +2 -0
- data/lib/arli/lock/formats/yaml.rb +3 -1
- data/lib/arli/version.rb +1 -1
- metadata +20 -5
- data/.rake_tasks~ +0 -8
- data/lib/arli/output.rb +0 -186
data/Rakefile
CHANGED
data/arli.gemspec
CHANGED
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.add_dependency 'arduino-library', '~> 0.5.4'
|
32
32
|
spec.add_dependency 'colored2'
|
33
|
+
spec.add_dependency 'awesome_print'
|
33
34
|
spec.add_dependency 'hashie'
|
34
35
|
spec.add_dependency 'dry-types'
|
35
36
|
spec.add_dependency 'dry-struct'
|
data/exe/arli
CHANGED
data/lib/arli.rb
CHANGED
data/lib/arli/actions/action.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
|
1
|
+
require 'arli/helpers/output'
|
2
|
+
require 'arli/helpers/inherited'
|
2
3
|
|
3
4
|
module Arli
|
4
5
|
module Actions
|
5
6
|
# Represents an abstract action related to the library
|
6
7
|
class Action
|
7
|
-
include Arli::Output
|
8
|
+
include Arli::Helpers::Output
|
9
|
+
|
10
|
+
include Arli::Helpers::Inherited
|
11
|
+
attr_assignable :check_command, :check_pattern, :description
|
8
12
|
|
9
13
|
extend Forwardable
|
10
14
|
def_delegators :@library,
|
@@ -15,37 +19,7 @@ module Arli
|
|
15
19
|
|
16
20
|
class << self
|
17
21
|
def inherited(base)
|
18
|
-
|
19
|
-
base.instance_eval do
|
20
|
-
class << self
|
21
|
-
attr_writer :check_command, :check_pattern, :description
|
22
|
-
|
23
|
-
def action_name
|
24
|
-
name.gsub(/.*::/, '').underscore.to_sym
|
25
|
-
end
|
26
|
-
|
27
|
-
def set_or_get(var_name, val = nil)
|
28
|
-
var = "@#{var_name}".to_sym
|
29
|
-
self.instance_variable_set(var, val) if val
|
30
|
-
self.instance_variable_get(var)
|
31
|
-
end
|
32
|
-
|
33
|
-
def check_pattern(val = nil)
|
34
|
-
set_or_get('check_pattern', val)
|
35
|
-
end
|
36
|
-
|
37
|
-
def check_command(val = nil)
|
38
|
-
set_or_get('check_command', val)
|
39
|
-
end
|
40
|
-
|
41
|
-
def description(val = nil)
|
42
|
-
set_or_get('description', val)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Add to the list of actions
|
48
|
-
::Arli::Actions.actions[base.action_name] = base
|
22
|
+
::Arli::Actions.actions[base.short_name] = base
|
49
23
|
end
|
50
24
|
end
|
51
25
|
|
@@ -12,12 +12,7 @@ module Arli
|
|
12
12
|
return if library.url !~ /\.zip$/i
|
13
13
|
|
14
14
|
download!
|
15
|
-
|
16
|
-
if File.exist?(zip_archive)
|
17
|
-
FileUtils.rm_rf(top_dir_inside_zip) if top_dir_inside_zip
|
18
|
-
unzip(zip_archive, '.')
|
19
|
-
FileUtils.move(top_dir_inside_zip, dir) if Dir.exist?(top_dir_inside_zip)
|
20
|
-
end
|
15
|
+
move_in_place!
|
21
16
|
rescue Exception => e
|
22
17
|
fuck
|
23
18
|
raise(e)
|
@@ -27,6 +22,14 @@ module Arli
|
|
27
22
|
|
28
23
|
private
|
29
24
|
|
25
|
+
def move_in_place!
|
26
|
+
if File.exist?(zip_archive)
|
27
|
+
FileUtils.rm_rf(top_dir_inside_zip) if top_dir_inside_zip
|
28
|
+
unzip(zip_archive, '.')
|
29
|
+
FileUtils.move(top_dir_inside_zip, dir) if Dir.exist?(top_dir_inside_zip)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
30
33
|
def delete_zip!
|
31
34
|
FileUtils.rm_f(zip_archive) if File.exist?(zip_archive)
|
32
35
|
end
|
data/lib/arli/arli_file.rb
CHANGED
@@ -3,24 +3,41 @@ require 'yaml'
|
|
3
3
|
require 'forwardable'
|
4
4
|
require 'arduino/library'
|
5
5
|
require 'hashie/mash'
|
6
|
+
require 'hashie/extensions/symbolize_keys'
|
7
|
+
require 'arli/library'
|
6
8
|
|
7
9
|
module Arli
|
8
10
|
class ArliFile
|
9
11
|
require 'arduino/library/include'
|
10
12
|
|
11
13
|
include Enumerable
|
12
|
-
extend Forwardable
|
13
14
|
|
15
|
+
extend Forwardable
|
14
16
|
def_delegators :@dependencies, *(Array.new.methods - Object.methods)
|
15
17
|
|
18
|
+
include ::Arli::Library
|
19
|
+
|
16
20
|
attr_accessor :dependencies,
|
17
21
|
:parsed_data,
|
18
|
-
:arlifile_path
|
22
|
+
:arlifile_path,
|
23
|
+
:config
|
19
24
|
|
20
25
|
def initialize(config: Arli.config, libraries: [])
|
21
|
-
self.
|
22
|
-
self.
|
23
|
-
|
26
|
+
self.config = config
|
27
|
+
self.arlifile_path = "#{config.arlifile.path}/#{config.arlifile.name}"
|
28
|
+
self.dependencies = read_dependencies(libraries)
|
29
|
+
|
30
|
+
self.config.libraries.temp_dir ||= Dir.mktmpdir
|
31
|
+
|
32
|
+
if parsed_data
|
33
|
+
if parsed_data.libraries_path
|
34
|
+
self.config.libraries.path = parsed_data.libraries_path
|
35
|
+
end
|
36
|
+
|
37
|
+
if parsed_data.lock_format
|
38
|
+
Arli.config.arlifile.lock_format = parsed_data.lock_format
|
39
|
+
end
|
40
|
+
end
|
24
41
|
end
|
25
42
|
|
26
43
|
alias libraries dependencies
|
@@ -43,26 +60,6 @@ module Arli
|
|
43
60
|
end
|
44
61
|
end
|
45
62
|
|
46
|
-
|
47
|
-
def library_model(lib)
|
48
|
-
return lib if lib.is_a?(::Arduino::Library::Model)
|
49
|
-
|
50
|
-
::Arduino::Library::Model.from(lib).tap do |model|
|
51
|
-
if model.nil?
|
52
|
-
lib_output = (lib && lib['name']) ? lib['name'] : lib.inspect
|
53
|
-
raise Arli::Errors::LibraryNotFound, 'Error: '.bold.red +
|
54
|
-
"Library #{lib_output.yellow} ".red + "was not found.\n\n".red +
|
55
|
-
%Q[ HINT: run #{"arli search 'name: /#{lib_output}/'".green}\n] +
|
56
|
-
%Q[ to find the exact name of the library you are trying\n] +
|
57
|
-
%Q[ to install. Alternatively, provide a url: field.\n]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def make_lib(lib)
|
63
|
-
::Arli::Library::Proxy.new(library_model(lib))
|
64
|
-
end
|
65
|
-
|
66
63
|
def within_path(p, &_block)
|
67
64
|
FileUtils.mkpath(p) unless Dir.exist?(p)
|
68
65
|
Dir.chdir(p) do
|
@@ -72,7 +69,7 @@ module Arli
|
|
72
69
|
|
73
70
|
def read_dependencies(libraries)
|
74
71
|
if libraries && !libraries.empty?
|
75
|
-
libraries.map {
|
72
|
+
libraries.map {|lib| make_lib(lib)}
|
76
73
|
else
|
77
74
|
unless arlifile_path && File.exist?(arlifile_path)
|
78
75
|
raise(Arli::Errors::ArliFileNotFound,
|
@@ -83,8 +80,15 @@ module Arli
|
|
83
80
|
end
|
84
81
|
|
85
82
|
def parse_yaml_file
|
86
|
-
self.parsed_data = Hashie::Mash.new(
|
87
|
-
|
83
|
+
self.parsed_data = Hashie::Mash.new(
|
84
|
+
Hashie::Extensions::SymbolizeKeys.symbolize_keys(
|
85
|
+
::YAML.load(
|
86
|
+
::File.read(
|
87
|
+
self.arlifile_path)
|
88
|
+
)
|
89
|
+
)
|
90
|
+
)
|
91
|
+
parsed_data.dependencies.map {|lib| make_lib(lib)}
|
88
92
|
end
|
89
93
|
end
|
90
94
|
end
|
data/lib/arli/cli/app.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'optparse'
|
3
|
-
require 'colored2'
|
4
3
|
require 'tmpdir'
|
5
4
|
require_relative 'parser'
|
6
5
|
require_relative 'command_finder'
|
7
6
|
require_relative 'parser_factory'
|
8
7
|
require_relative '../commands'
|
9
|
-
|
8
|
+
require 'arli/helpers/output'
|
10
9
|
|
11
10
|
|
12
11
|
module Arli
|
13
12
|
module CLI
|
14
13
|
class App
|
15
|
-
include Arli::Output
|
14
|
+
include Arli::Helpers::Output
|
16
15
|
|
17
16
|
attr_accessor :argv, :config, :command
|
18
17
|
|
@@ -8,13 +8,13 @@ require_relative 'parser_factory'
|
|
8
8
|
require_relative '../commands'
|
9
9
|
require_relative '../commands/search'
|
10
10
|
require_relative '../commands/install'
|
11
|
-
|
11
|
+
require 'arli/helpers/output'
|
12
12
|
|
13
13
|
module Arli
|
14
14
|
module CLI
|
15
15
|
class CommandFinder
|
16
16
|
|
17
|
-
include Arli::Output
|
17
|
+
include Arli::Helpers::Output
|
18
18
|
|
19
19
|
attr_accessor :argv, :config, :command_name, :command
|
20
20
|
|
data/lib/arli/cli/parser.rb
CHANGED
@@ -69,15 +69,32 @@ module Arli
|
|
69
69
|
def option_search
|
70
70
|
on('-d', '--database URL',
|
71
71
|
'a JSON(.gz) file path or a URL of the library database.',
|
72
|
-
'Defaults to the Arduino-maintained database.') do |v|
|
72
|
+
'Defaults to the Arduino-maintained database.' + "\n\n") do |v|
|
73
73
|
config.database.path = v
|
74
74
|
end
|
75
75
|
|
76
76
|
on('-m', '--max NUMBER',
|
77
|
-
'if provided, limits the result set
|
78
|
-
'
|
77
|
+
'if provided, limits the result set using the ',
|
78
|
+
'total number of the unique library name matches.',
|
79
|
+
'Default is 0, which means no limit.' + "\n\n") do |v|
|
79
80
|
config.search.results.limit = v.to_i if v
|
80
81
|
end
|
82
|
+
|
83
|
+
formats = Arli::Library::MultiVersion.format_methods
|
84
|
+
|
85
|
+
on('-f', '--format FMT',
|
86
|
+
"Optional format of the search results.",
|
87
|
+
"The default is #{'short'.bold.yellow}. Available ",
|
88
|
+
"formats: #{formats.join(', ').bold.yellow}\n\n") do |v|
|
89
|
+
if formats.include?(v.downcase.to_sym)
|
90
|
+
config.search.results.output_format = v.downcase.to_sym
|
91
|
+
else
|
92
|
+
raise ::OptionParser::InvalidOption,
|
93
|
+
"#{v.yellow} is not a supported search result format"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
option_search_attributes
|
81
98
|
end
|
82
99
|
|
83
100
|
def option_if_exists
|
@@ -115,6 +132,17 @@ module Arli
|
|
115
132
|
end
|
116
133
|
end
|
117
134
|
|
135
|
+
def option_search_attributes
|
136
|
+
on('-A', '--print-attrs', 'prints full list of available library',
|
137
|
+
'attributes that can be used in search strings.', ' ') do
|
138
|
+
|
139
|
+
::Arli.config.help = true
|
140
|
+
output ''
|
141
|
+
header('Arduino Library Attributes:')
|
142
|
+
output " • " + Arduino::Library::Types::LIBRARY_PROPERTIES.keys.join("\n • ") + "\n\n"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
118
146
|
def header(string)
|
119
147
|
output "#{string.bold.magenta}:"
|
120
148
|
output
|
@@ -174,6 +202,7 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
|
|
174
202
|
on('-C', '--no-color',
|
175
203
|
'Disable any color output.') do |*|
|
176
204
|
Colored2.disable! # if $stdout.tty?
|
205
|
+
config.no_color = true
|
177
206
|
end
|
178
207
|
on('-D', '--debug',
|
179
208
|
'Print debugging info.') do |v|
|
@@ -183,10 +212,6 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
|
|
183
212
|
'Print exception stack traces.') do |v|
|
184
213
|
config.trace = v
|
185
214
|
end
|
186
|
-
# on('-n', '--dry-run',
|
187
|
-
# 'Only print actions, but do not do them.') do |v|
|
188
|
-
# config.trace = v
|
189
|
-
# end
|
190
215
|
on('-v', '--verbose',
|
191
216
|
'Print more information.') do |v|
|
192
217
|
config.verbose = true
|
@@ -209,7 +234,7 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
|
|
209
234
|
|
210
235
|
def output_command_description(command_name)
|
211
236
|
command_hash = factory.command_parsers[command_name]
|
212
|
-
indent
|
237
|
+
indent = ' '
|
213
238
|
|
214
239
|
if command_hash
|
215
240
|
if command_hash.description
|
@@ -218,7 +243,9 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
|
|
218
243
|
output indent + command_hash.sentence.bold
|
219
244
|
output ''
|
220
245
|
end
|
221
|
-
|
246
|
+
|
247
|
+
text = Array(command_hash[:description]).flatten.join(' ')
|
248
|
+
output text.reformat_wrapped(width = 70, indent_with = 8)
|
222
249
|
end
|
223
250
|
end
|
224
251
|
|
@@ -28,6 +28,7 @@ module Arli
|
|
28
28
|
@global ||= make_parser do |parser|
|
29
29
|
parser.banner = usage_line
|
30
30
|
parser.sep
|
31
|
+
parser.option_search_attributes
|
31
32
|
parser.option_help(commands: true)
|
32
33
|
end
|
33
34
|
end
|
@@ -36,32 +37,38 @@ module Arli
|
|
36
37
|
@command_parsers ||= {
|
37
38
|
search: Hashie::Mash.new(
|
38
39
|
{
|
39
|
-
sentence: 'Search standard Arduino Library Database with over 4K entries',
|
40
|
-
description: [
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
sentence: 'Search standard Arduino Library Database with over 4K entries ',
|
41
|
+
description: %Q[This command provides both the simple name-based search interface,
|
42
|
+
and the most sophisticated attribute-specific search using a downloaded,
|
43
|
+
and locally cached Public Arduino Database JSON file, maintained
|
44
|
+
by the Arduino Community. If you know of another database,
|
45
|
+
that's what the #{'--database'.blue} flag is for.
|
46
|
+
Note that you can print the list of available attributes by
|
47
|
+
running arli with #{'--print-attrs'.blue} flag.
|
48
|
+
],
|
45
49
|
examples: [
|
46
|
-
{ desc: '
|
47
|
-
cmd: 'arli search
|
50
|
+
{ desc: 'Finds any library with name matching a given string, case insensitively',
|
51
|
+
cmd: 'arli search audiozero' },
|
48
52
|
|
49
|
-
{ desc: '
|
50
|
-
cmd: %Q{arli search
|
53
|
+
{ desc: 'If the first character is "/", then the argument is assumed to be regex',
|
54
|
+
cmd: %Q{arli search /AudioZero$/ } },
|
51
55
|
|
52
|
-
{ desc: '
|
53
|
-
cmd: %Q{arli search
|
56
|
+
{ desc: 'If the first character is "=", then the rest is assumed to be exact name',
|
57
|
+
cmd: %Q{arli search =Time } },
|
54
58
|
|
55
|
-
{ desc: '
|
56
|
-
cmd: %Q{arli search 'name:
|
59
|
+
{ desc: 'Lets get a particular version of the library using another attribute',
|
60
|
+
cmd: %Q{arli search 'name: "AudioZero", version: "1.0.2"'} },
|
57
61
|
|
58
|
-
{ desc: '
|
59
|
-
cmd: %Q{arli search '
|
62
|
+
{ desc: 'Search using case insensitive search for the author',
|
63
|
+
cmd: %Q{arli search 'author: /adafruit/i'} },
|
64
|
+
|
65
|
+
{ desc: 'Finally, search for regex match for "WiFi" in a sentence or a paragraph',
|
66
|
+
cmd: %Q{arli search 'sentence: /wifi/i, paragraph: /wifi/i'} },
|
60
67
|
],
|
61
68
|
|
62
69
|
parser: -> (command_name) {
|
63
70
|
make_parser(command_name) do |parser|
|
64
|
-
parser.banner = usage_line 'search ' + '[
|
71
|
+
parser.banner = usage_line 'search ' + '[ -A | search-expression ] '.magenta
|
65
72
|
parser.option_search
|
66
73
|
parser.option_help(command_name: command_name)
|
67
74
|
end
|
@@ -71,15 +78,13 @@ module Arli
|
|
71
78
|
bundle: Hashie::Mash.new(
|
72
79
|
{
|
73
80
|
sentence: 'Installs all libraries specified in Arlifile',
|
74
|
-
description:
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
"your Arduino Library folder. Both the folder with the Arlifile, as well as the\n",
|
80
|
-
"destination library path folder can be changed with the command line flags.\n",
|
81
|
+
description: %Q[This command reads #{'Arlifile'.bold.green} (from the current folder, by default),
|
82
|
+
and then it installs all dependent libraries specified there, checking if
|
83
|
+
each already exists, and if not — downloading them, and installing them into
|
84
|
+
your Arduino Library folder. Both the folder with the Arlifile, as well as the
|
85
|
+
destination library path folder can be changed with the command line flags.
|
81
86
|
],
|
82
|
-
|
87
|
+
example: [
|
83
88
|
{ desc: 'Install all libs defined in Arlifile:',
|
84
89
|
cmd: 'arli bundle ' },
|
85
90
|
|
@@ -98,27 +103,24 @@ module Arli
|
|
98
103
|
install: Hashie::Mash.new(
|
99
104
|
{
|
100
105
|
sentence: 'Installs a single library either by searching, or url or local ZIP',
|
101
|
-
description: [
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
106
|
+
description: %Q[This command installs a single library into your library path
|
107
|
+
(which can be set with #{'--lib-path'.blue} flag).
|
108
|
+
Arli interpretes the third argument to #{'arli install'.bold.blue}
|
109
|
+
as either an exact library name, or a remote URL
|
110
|
+
(either ZIP or Git Repo). You can use #{'search'.bold.green} command
|
111
|
+
to first find the right library name, and then pass it to the install command.
|
107
112
|
],
|
108
113
|
examples: [
|
109
|
-
{ desc: 'Install the latest version of this library',
|
110
|
-
cmd: 'arli install "Adafruit GFX Library"' },
|
114
|
+
{ desc: 'Install the latest version of this library locally',
|
115
|
+
cmd: 'arli install "Adafruit GFX Library" -l ./libraries' },
|
111
116
|
|
112
117
|
{ desc: 'Install the library from a Github URL',
|
113
|
-
cmd: 'arli install https://github.com/jfturcot/SimpleTimer' }
|
114
|
-
|
115
|
-
{ desc: 'Install a local ZIP file',
|
116
|
-
cmd: 'arli install ~/Downloads/DHT-Library.zip' },
|
118
|
+
cmd: 'arli install https://github.com/jfturcot/SimpleTimer' }
|
117
119
|
],
|
118
120
|
|
119
121
|
parser: -> (command_name) {
|
120
122
|
make_parser(command_name) do |parser|
|
121
|
-
parser.banner = usage_line 'install' + ' [ "
|
123
|
+
parser.banner = usage_line 'install' + ' [ "Exact Library Name" | url ] '.magenta
|
122
124
|
parser.option_install
|
123
125
|
parser.option_help(command_name: command_name)
|
124
126
|
end
|