arli 0.7.0 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +0 -2
- data/README.md +149 -48
- data/arli.gemspec +1 -3
- data/docs/arli-in-action.png +0 -0
- data/docs/arlifile.png +0 -0
- data/exe/arli +5 -1
- data/lib/arli.rb +2 -2
- data/lib/arli/actions.rb +6 -1
- data/lib/arli/actions/action.rb +57 -37
- data/lib/arli/actions/dir_name.rb +18 -16
- data/lib/arli/actions/git_repo.rb +8 -8
- data/lib/arli/actions/move_to_library_path.rb +54 -0
- data/lib/arli/actions/{zip_file.rb → unzip_file.rb} +14 -10
- data/lib/arli/arli_file.rb +52 -32
- data/lib/arli/cli/app.rb +11 -4
- data/lib/arli/cli/command_finder.rb +14 -11
- data/lib/arli/cli/parser.rb +70 -29
- data/lib/arli/cli/parser_factory.rb +105 -50
- data/lib/arli/cli/runner.rb +8 -4
- data/lib/arli/commands.rb +1 -0
- data/lib/arli/commands/base.rb +11 -6
- data/lib/arli/commands/bundle.rb +43 -0
- data/lib/arli/commands/install.rb +56 -13
- data/lib/arli/commands/search.rb +82 -27
- data/lib/arli/configuration.rb +37 -18
- data/lib/arli/errors.rb +6 -0
- data/lib/arli/library.rb +4 -46
- data/lib/arli/library/installer.rb +71 -0
- data/lib/arli/library/proxy.rb +79 -0
- data/lib/arli/lock/file.rb +65 -0
- data/lib/arli/lock/formats.rb +4 -0
- data/lib/arli/lock/formats/base.rb +26 -0
- data/lib/arli/lock/formats/cmake.rb +24 -0
- data/lib/arli/lock/formats/json.rb +25 -0
- data/lib/arli/lock/formats/text.rb +13 -0
- data/lib/arli/lock/formats/yaml.rb +14 -0
- data/lib/arli/output.rb +94 -11
- data/lib/arli/version.rb +1 -1
- metadata +17 -35
- data/docs/arli-full.png +0 -0
- data/lib/arli/installer.rb +0 -52
data/lib/arli/configuration.rb
CHANGED
@@ -5,23 +5,28 @@ require 'yaml'
|
|
5
5
|
module Arli
|
6
6
|
class Configuration
|
7
7
|
|
8
|
-
DEFAULT_FILENAME
|
9
|
-
|
10
|
-
|
8
|
+
DEFAULT_FILENAME = 'Arlifile'.freeze
|
9
|
+
DEFAULT_LOCK_FILENAME = (DEFAULT_FILENAME + '.lock').freeze
|
10
|
+
ACTIONS_WHEN_EXISTS = %i(backup overwrite abort)
|
11
|
+
ARLI_COMMAND = 'arli'.freeze
|
12
|
+
DEFAULT_RESULTS_LIMIT = 100
|
11
13
|
|
12
14
|
extend Dry::Configurable
|
13
15
|
|
14
16
|
# These are populated during the parsing of the params
|
15
17
|
setting :runtime do
|
16
18
|
setting :argv
|
19
|
+
setting :pwd
|
17
20
|
setting :command do
|
18
21
|
setting :name
|
19
22
|
setting :instance
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
26
|
+
# Default locations
|
23
27
|
setting :libraries do
|
24
28
|
setting :path, ::Arduino::Library::DefaultDatabase.library_path
|
29
|
+
setting :temp_dir
|
25
30
|
end
|
26
31
|
|
27
32
|
setting :database do
|
@@ -29,33 +34,47 @@ module Arli
|
|
29
34
|
setting :url, ::Arduino::Library::DefaultDatabase.library_index_url
|
30
35
|
end
|
31
36
|
|
32
|
-
setting :
|
33
|
-
setting :
|
34
|
-
setting :
|
37
|
+
setting :if_exists do
|
38
|
+
setting :overwrite, true
|
39
|
+
setting :backup, false
|
40
|
+
setting :abort, false
|
35
41
|
end
|
36
42
|
|
43
|
+
# Global flags
|
44
|
+
setting :debug, ENV['ARLI_DEBUG'] || false
|
45
|
+
setting :trace, false
|
46
|
+
setting :dry_run, false
|
47
|
+
setting :verbose, false
|
48
|
+
setting :help, false
|
49
|
+
setting :quiet, false
|
50
|
+
|
51
|
+
# Commands
|
37
52
|
setting :search do
|
53
|
+
setting :argument
|
38
54
|
setting :default_field, :name
|
39
55
|
setting :results do
|
40
|
-
setting :
|
56
|
+
setting :attrs
|
57
|
+
setting :limit, DEFAULT_RESULTS_LIMIT
|
41
58
|
setting :format, :inspect
|
42
59
|
end
|
43
60
|
end
|
44
61
|
|
45
|
-
|
62
|
+
# Arlifile
|
63
|
+
setting :arlifile do
|
64
|
+
setting :path, ::Dir.pwd
|
65
|
+
setting :name, ::Arli::Configuration::DEFAULT_FILENAME
|
66
|
+
setting :lock_name, ::Arli::Configuration::DEFAULT_LOCK_FILENAME
|
67
|
+
setting :lock_format, :json
|
68
|
+
end
|
69
|
+
|
70
|
+
setting :bundle do
|
46
71
|
setting :library_names, []
|
47
|
-
setting :if_exists do
|
48
|
-
setting :overwrite, true
|
49
|
-
setting :backup, false
|
50
|
-
setting :abort, false
|
51
|
-
end
|
52
72
|
end
|
53
73
|
|
54
|
-
setting :
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
setting :quiet, false
|
74
|
+
setting :install do
|
75
|
+
setting :library
|
76
|
+
end
|
77
|
+
|
59
78
|
end
|
60
79
|
end
|
61
80
|
|
data/lib/arli/errors.rb
CHANGED
@@ -6,6 +6,10 @@ module Arli
|
|
6
6
|
|
7
7
|
class InvalidSyntaxError < ArliError; end
|
8
8
|
|
9
|
+
class InvalidSearchSyntaxError < InvalidSyntaxError; end
|
10
|
+
|
11
|
+
class InvalidInstallSyntaxError < InvalidSyntaxError; end
|
12
|
+
|
9
13
|
class AbstractMethodCalled < ArliError; end
|
10
14
|
|
11
15
|
class ArliFileNotFound < ArliError; end
|
@@ -16,6 +20,8 @@ module Arli
|
|
16
20
|
|
17
21
|
class InstallerError < ArliError; end
|
18
22
|
|
23
|
+
class TooManyMatchesError < ArliError; end
|
24
|
+
|
19
25
|
class ZipFileError < InstallerError; end
|
20
26
|
end
|
21
27
|
end
|
data/lib/arli/library.rb
CHANGED
@@ -1,50 +1,8 @@
|
|
1
|
-
require_relative 'installer'
|
2
|
-
require_relative 'errors'
|
3
|
-
|
4
1
|
module Arli
|
5
|
-
|
6
|
-
attr_accessor :lib, :config, :canonical_dir
|
7
|
-
|
8
|
-
def initialize(lib, config: Arli.config)
|
9
|
-
self.lib = lib
|
10
|
-
self.config = config
|
11
|
-
end
|
12
|
-
|
13
|
-
def install
|
14
|
-
Arli::Installer.new(self).install
|
15
|
-
end
|
16
|
-
|
17
|
-
def rm_rf!
|
18
|
-
FileUtils.rm_rf(dir)
|
19
|
-
end
|
20
|
-
|
21
|
-
def libraries_home
|
22
|
-
config.libraries.path
|
23
|
-
end
|
24
|
-
|
25
|
-
def dir
|
26
|
-
lib.name.gsub(/ /, '_')
|
27
|
-
end
|
28
|
-
|
29
|
-
def path
|
30
|
-
libraries_home + '/' + dir
|
31
|
-
end
|
32
|
-
|
33
|
-
def canonical_path
|
34
|
-
libraries_home + '/' + canonical_dir
|
35
|
-
end
|
36
|
-
|
37
|
-
def exists?
|
38
|
-
Dir.exist?(path)
|
39
|
-
end
|
40
|
-
|
41
|
-
def method_missing(method, *args, &block)
|
42
|
-
if lib && lib.respond_to?(method)
|
43
|
-
lib.send(method, *args, &block)
|
44
|
-
else
|
45
|
-
super(method, *args, &block)
|
46
|
-
end
|
47
|
-
end
|
2
|
+
module Library
|
48
3
|
|
49
4
|
end
|
50
5
|
end
|
6
|
+
|
7
|
+
require_relative 'library/proxy'
|
8
|
+
require_relative 'library/installer'
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'arli'
|
3
|
+
require 'arli/actions'
|
4
|
+
require_relative 'proxy'
|
5
|
+
|
6
|
+
module Arli
|
7
|
+
module Library
|
8
|
+
class Installer
|
9
|
+
include ::Arli::Output
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
def_delegators :@library, :exists?
|
13
|
+
|
14
|
+
attr_accessor :library, :config, :temp_dir
|
15
|
+
|
16
|
+
def initialize(library, config: Arli.config)
|
17
|
+
self.config = config
|
18
|
+
self.library = library
|
19
|
+
self.temp_dir = Arli.config.libraries.temp_dir
|
20
|
+
end
|
21
|
+
|
22
|
+
def install
|
23
|
+
___ "#{library.name.blue} "
|
24
|
+
if library.nil? && library.library.nil?
|
25
|
+
___ ' (no library) '
|
26
|
+
fuck
|
27
|
+
elsif library.url.nil?
|
28
|
+
___ ' (no url) '
|
29
|
+
fuck
|
30
|
+
else
|
31
|
+
___ "(#{library.version.green}) " if library.version
|
32
|
+
indent_cursor
|
33
|
+
actions(library).each do |action|
|
34
|
+
run_action(action)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
___ "\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_action(action_name)
|
41
|
+
klass = Arli::Actions.action(action_name)
|
42
|
+
if klass
|
43
|
+
action = klass.new(library, config: config)
|
44
|
+
if action.supported?
|
45
|
+
print_action_starting(action_name.to_s) do
|
46
|
+
action.run!
|
47
|
+
end
|
48
|
+
puts if verbose?
|
49
|
+
else
|
50
|
+
print_action_failure("unsupported", "missing pre-requisites: #{klass.command_name.bold.yellow} did not succeed")
|
51
|
+
end
|
52
|
+
else
|
53
|
+
print_action_failure("#{action_name.red} not found")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def verbose?
|
58
|
+
config.verbose
|
59
|
+
end
|
60
|
+
|
61
|
+
def actions(library)
|
62
|
+
actions = []
|
63
|
+
# First, how do we get the library?
|
64
|
+
actions << ((library.url =~ /\.zip$/i) ? :unzip_file : :git_repo)
|
65
|
+
actions << :dir_name
|
66
|
+
actions << :move_to_library_path
|
67
|
+
actions.flatten
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require_relative 'installer'
|
2
|
+
require 'arli/errors'
|
3
|
+
|
4
|
+
module Arli
|
5
|
+
module Library
|
6
|
+
# Represents a wrapper around Arduino::Library::Model instance
|
7
|
+
# and decorates with a few additional helpers.
|
8
|
+
class Proxy
|
9
|
+
attr_accessor :lib,
|
10
|
+
:lib_dir,
|
11
|
+
:canonical_dir,
|
12
|
+
:config
|
13
|
+
|
14
|
+
def initialize(lib, config: Arli.config)
|
15
|
+
self.lib = lib
|
16
|
+
self.config = config
|
17
|
+
self.lib_dir = lib.name.gsub(/ /, '_')
|
18
|
+
end
|
19
|
+
|
20
|
+
def install
|
21
|
+
installer.install
|
22
|
+
end
|
23
|
+
|
24
|
+
def installer
|
25
|
+
@installer ||= Installer.new(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def libraries_home
|
29
|
+
config.libraries.path
|
30
|
+
end
|
31
|
+
|
32
|
+
def temp_dir
|
33
|
+
config.libraries.temp_dir
|
34
|
+
end
|
35
|
+
|
36
|
+
def dir
|
37
|
+
canonical_dir || lib_dir
|
38
|
+
end
|
39
|
+
|
40
|
+
def path
|
41
|
+
libraries_home + '/' + dir
|
42
|
+
end
|
43
|
+
|
44
|
+
def temp_path
|
45
|
+
temp_dir + '/' + dir
|
46
|
+
end
|
47
|
+
|
48
|
+
def exists?
|
49
|
+
Dir.exist?(path)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Formats
|
53
|
+
def to_s_short
|
54
|
+
"#{lib.name.bold.blue} (#{lib.version.yellow}), by #{lib.author.magenta}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_s_json
|
58
|
+
puts lib.to_json
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s_long
|
62
|
+
"#{lib.name.bold.blue} (#{lib.version.yellow}), by #{lib.author.magenta}}\n\t#{lib.description}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s_pretty(lib, **options)
|
66
|
+
"#{lib.name.bold.blue} (#{lib.version.yellow}), by #{lib.author.magenta}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def method_missing(method, *args, &block)
|
70
|
+
if lib && lib.respond_to?(method)
|
71
|
+
lib.send(method, *args, &block)
|
72
|
+
else
|
73
|
+
super(method, *args, &block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'arli'
|
2
|
+
require 'yaml'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'arduino/library'
|
5
|
+
require 'hashie/mash'
|
6
|
+
|
7
|
+
require_relative 'formats'
|
8
|
+
|
9
|
+
module Arli
|
10
|
+
module Lock
|
11
|
+
class File
|
12
|
+
attr_accessor :lock_file_path,
|
13
|
+
:config,
|
14
|
+
:formatter,
|
15
|
+
:file,
|
16
|
+
:format
|
17
|
+
|
18
|
+
def initialize(config: Arli.config)
|
19
|
+
self.config = config
|
20
|
+
self.lock_file_path = "#{config.arlifile.path}/#{config.arlifile.lock_name}"
|
21
|
+
self.format = config.arlifile.lock_format
|
22
|
+
self.formatter = set_formatter(format)
|
23
|
+
self.file = ::File.open(lock_file_path, 'w')
|
24
|
+
|
25
|
+
append(formatter.header)
|
26
|
+
end
|
27
|
+
|
28
|
+
def lock(*libraries)
|
29
|
+
libraries.each do |lib|
|
30
|
+
append(formatter.format(lib))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def lock!(*args)
|
35
|
+
lock(*args)
|
36
|
+
ensure
|
37
|
+
close
|
38
|
+
end
|
39
|
+
|
40
|
+
def close
|
41
|
+
append(formatter.footer)
|
42
|
+
ensure
|
43
|
+
file.close
|
44
|
+
FileUtils.cp(lock_file_path, "#{lock_file_path}.#{format}")
|
45
|
+
end
|
46
|
+
|
47
|
+
def append(line = nil)
|
48
|
+
return unless line
|
49
|
+
line.end_with?("\n") ? file.print(line) : file.puts(line)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def set_formatter(format)
|
55
|
+
klass = format.to_s.capitalize.to_sym
|
56
|
+
klazz = ::Arli::Lock::Formats.const_get(klass)
|
57
|
+
klazz.new(self)
|
58
|
+
rescue NameError
|
59
|
+
raise Arli::Errors::ArliError,
|
60
|
+
"invalid format #{format}, Arli::Lock::Formats::#{klass} does not exist"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module Arli
|
3
|
+
module Lock
|
4
|
+
module Formats
|
5
|
+
class Base
|
6
|
+
attr_accessor :lock_file
|
7
|
+
|
8
|
+
def initialize(lock_file)
|
9
|
+
self.lock_file = lock_file
|
10
|
+
end
|
11
|
+
|
12
|
+
# Optional header
|
13
|
+
def header
|
14
|
+
end
|
15
|
+
|
16
|
+
def format(library)
|
17
|
+
raise Arli::Errors::AbstractMethodCalled, "#format on Base"
|
18
|
+
end
|
19
|
+
|
20
|
+
# Optional footer
|
21
|
+
def footer
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
module Lock
|
5
|
+
module Formats
|
6
|
+
class Cmake < Base
|
7
|
+
|
8
|
+
def header
|
9
|
+
"# vi:syntax=cmake\n" +
|
10
|
+
"set(ARLI_LIBRARIES)"
|
11
|
+
end
|
12
|
+
|
13
|
+
def format(library)
|
14
|
+
"# Library #{library.name}, version #{library.version}, url: #{library.url}\n" +
|
15
|
+
"prepend(ARDUINO_ARLI_LIBS ${ARDUINO_ARLI_LIBS} #{library.canonical_dir})"
|
16
|
+
end
|
17
|
+
|
18
|
+
def footer
|
19
|
+
"set(ARLI_LIBRARIES $ARLI_LIBRARIES PARENT_SCOPE)"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
module Lock
|
5
|
+
module Formats
|
6
|
+
class Json < Base
|
7
|
+
attr_accessor :hash
|
8
|
+
|
9
|
+
def header
|
10
|
+
self.hash = {}
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def format(library)
|
15
|
+
hash[library.canonical_dir] = library.to_hash
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def footer
|
20
|
+
JSON.pretty_generate(hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|