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
@@ -2,24 +2,29 @@ require 'json'
|
|
2
2
|
require 'arli'
|
3
3
|
require 'net/http'
|
4
4
|
require_relative 'base'
|
5
|
-
require_relative '../
|
5
|
+
require_relative '../installer'
|
6
6
|
|
7
7
|
module Arli
|
8
8
|
module Commands
|
9
9
|
class Install < Base
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
attr_accessor :arlifile
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
super(*args)
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
arlifile.
|
19
|
-
|
20
|
-
|
17
|
+
def setup
|
18
|
+
self.arlifile = Arli::ArliFile.new(config: config)
|
19
|
+
end
|
20
|
+
|
21
|
+
def params
|
22
|
+
arlifile.file
|
21
23
|
end
|
22
24
|
|
25
|
+
def run
|
26
|
+
arlifile.each_dependency { |lib| lib.install }
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
data/lib/arli/commands/search.rb
CHANGED
@@ -6,6 +6,7 @@ require 'arli/commands/base'
|
|
6
6
|
require 'arli/errors'
|
7
7
|
require 'arduino/library'
|
8
8
|
require 'awesome_print'
|
9
|
+
|
9
10
|
module Arli
|
10
11
|
module Commands
|
11
12
|
class Search < Base
|
@@ -13,41 +14,65 @@ module Arli
|
|
13
14
|
|
14
15
|
attr_accessor :search_string,
|
15
16
|
:search_opts,
|
17
|
+
:results,
|
16
18
|
:limit,
|
17
19
|
:database
|
18
20
|
|
19
|
-
def initialize(
|
20
|
-
super(
|
21
|
-
|
21
|
+
def initialize(*args)
|
22
|
+
super(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup
|
26
|
+
search = runtime.argv.first
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
self.search_string = if search =~ /:/
|
29
|
+
search
|
30
|
+
elsif search
|
31
|
+
"name: /#{search}/"
|
32
|
+
end
|
25
33
|
|
26
|
-
|
27
|
-
|
34
|
+
self.limit = config.search.results.limit
|
35
|
+
|
36
|
+
unless search_string
|
37
|
+
raise Arli::Errors::InvalidSyntaxError,
|
38
|
+
'Please provide search string after the "search" command'
|
39
|
+
end
|
28
40
|
|
29
41
|
begin
|
30
42
|
self.search_opts = eval("{ #{search_string} }")
|
31
43
|
rescue => e
|
32
44
|
raise Arli::Errors::InvalidSyntaxError, "Search string '#{search_string}' is invalid.\n" +
|
33
|
-
|
45
|
+
e.message.red
|
34
46
|
end
|
35
47
|
|
36
48
|
unless search_opts.is_a?(::Hash) && search_opts.size > 0
|
37
49
|
raise Arli::Errors::InvalidSyntaxError, "Search string '#{search_string}' did not eval to Hash.\n"
|
38
50
|
end
|
39
51
|
|
40
|
-
self.database =
|
52
|
+
self.database = db_default
|
41
53
|
|
42
54
|
search_opts.merge!(limit: limit) if limit && limit > 0
|
55
|
+
search_opts.delete(:limit) if limit == 0
|
43
56
|
end
|
44
57
|
|
45
58
|
def run
|
46
|
-
|
59
|
+
self.results = search(database, **search_opts)
|
60
|
+
results.map do |lib|
|
61
|
+
puts pretty_library(lib)
|
62
|
+
end
|
63
|
+
puts "\nTotal matches: #{results.size.to_s.bold.magenta}"
|
47
64
|
rescue Exception => e
|
48
65
|
error e
|
49
66
|
puts e.backtrace.join("\n") if ENV['DEBUG']
|
50
67
|
end
|
68
|
+
|
69
|
+
def pretty_library(lib, **options)
|
70
|
+
"#{lib.name.bold.blue} (#{lib.version.yellow}), by #{lib.author.magenta}"
|
71
|
+
end
|
72
|
+
|
73
|
+
def params
|
74
|
+
search_opts
|
75
|
+
end
|
51
76
|
end
|
52
77
|
end
|
53
78
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'dry-configurable'
|
2
|
+
require 'arduino/library'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Arli
|
6
|
+
class Configuration
|
7
|
+
|
8
|
+
DEFAULT_FILENAME = 'Arlifile'.freeze
|
9
|
+
ACTIONS_WHEN_EXISTS = %i(backup overwrite abort)
|
10
|
+
ARLI_COMMAND = 'arli'.freeze
|
11
|
+
|
12
|
+
extend Dry::Configurable
|
13
|
+
|
14
|
+
# These are populated during the parsing of the params
|
15
|
+
setting :runtime do
|
16
|
+
setting :argv
|
17
|
+
setting :command do
|
18
|
+
setting :name
|
19
|
+
setting :instance
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
setting :libraries do
|
24
|
+
setting :path, ::Arduino::Library::DefaultDatabase.library_path
|
25
|
+
end
|
26
|
+
|
27
|
+
setting :database do
|
28
|
+
setting :path, ::Arduino::Library::DefaultDatabase.library_index_path
|
29
|
+
setting :url, ::Arduino::Library::DefaultDatabase.library_index_url
|
30
|
+
end
|
31
|
+
|
32
|
+
setting :arlifile do
|
33
|
+
setting :path, ::Dir.pwd
|
34
|
+
setting :name, ::Arli::Configuration::DEFAULT_FILENAME
|
35
|
+
end
|
36
|
+
|
37
|
+
setting :search do
|
38
|
+
setting :default_field, :name
|
39
|
+
setting :results do
|
40
|
+
setting :limit, 100
|
41
|
+
setting :format, :inspect
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
setting :install do
|
46
|
+
setting :library
|
47
|
+
setting :if_exists do
|
48
|
+
setting :overwrite, true
|
49
|
+
setting :backup, false
|
50
|
+
setting :abort, false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
setting :debug, ENV['ARLI_DEBUG'] || false
|
55
|
+
setting :trace, false
|
56
|
+
setting :verbose, false
|
57
|
+
setting :help, false
|
58
|
+
setting :command_help, false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
data/lib/arli/installer.rb
CHANGED
@@ -1,100 +1,52 @@
|
|
1
|
-
require 'arli'
|
2
1
|
require 'forwardable'
|
2
|
+
require 'arli'
|
3
|
+
require_relative 'actions'
|
4
|
+
|
3
5
|
module Arli
|
4
6
|
class Installer
|
5
|
-
|
6
|
-
attr_accessor :lib, :lib_dir, :lib_path, :command
|
7
|
+
include ::Arli::Output
|
7
8
|
|
8
|
-
|
9
|
+
extend Forwardable
|
10
|
+
def_delegators :@library, :exists?
|
9
11
|
|
10
|
-
|
11
|
-
self.lib = lib
|
12
|
-
self.command = command
|
13
|
-
self.lib_dir = lib.name.gsub(/ /, '_')
|
14
|
-
self.lib_path = lib_path
|
15
|
-
end
|
12
|
+
attr_accessor :library, :config
|
16
13
|
|
17
|
-
def
|
18
|
-
|
14
|
+
def initialize(library, config: Arli.config)
|
15
|
+
self.config = config
|
16
|
+
self.library = library
|
19
17
|
end
|
20
18
|
|
21
19
|
def install
|
22
|
-
|
23
|
-
backup! if command.create_backup
|
24
|
-
abort! if exists? && command.abort_if_exists
|
20
|
+
___ "#{library.name.blue} "
|
25
21
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
if library.nil?
|
30
|
-
s ' ❌ ' + "\n"
|
22
|
+
if library.nil? && library.library.nil?
|
23
|
+
___ ' (no library) '
|
24
|
+
fuck
|
31
25
|
elsif library.url.nil?
|
32
|
-
|
26
|
+
___ ' (no url) '
|
27
|
+
fuck
|
33
28
|
else
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
29
|
+
___ "(#{library.version.green}) " if library.version
|
30
|
+
actions(library).each do |action|
|
31
|
+
run_action(action)
|
45
32
|
end
|
46
33
|
end
|
47
|
-
|
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')}"
|
34
|
+
___ "\n"
|
61
35
|
end
|
62
36
|
|
63
|
-
def
|
64
|
-
|
37
|
+
def run_action(action)
|
38
|
+
klass = Arli::Actions.action(action)
|
39
|
+
klass.new(library, config: config).act if klass
|
65
40
|
end
|
66
41
|
|
67
|
-
def
|
68
|
-
|
42
|
+
def actions(library)
|
43
|
+
actions = []
|
44
|
+
actions << :backup if exists?
|
45
|
+
# First, how do we get the library?
|
46
|
+
actions << ((library.url =~ /\.zip$/i) ? :zip_file : :git_repo)
|
47
|
+
actions << :dir_name
|
48
|
+
actions
|
69
49
|
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
50
|
end
|
99
51
|
end
|
100
52
|
|
data/lib/arli/library.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'installer'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
class Library
|
5
|
+
attr_accessor :lib, :config, :canonical_dir
|
6
|
+
|
7
|
+
def initialize(lib, config: Arli.config)
|
8
|
+
self.lib = lib
|
9
|
+
self.config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def install
|
13
|
+
Arli::Installer.new(self).install
|
14
|
+
end
|
15
|
+
|
16
|
+
def rm_rf!
|
17
|
+
FileUtils.rm_rf(dir)
|
18
|
+
end
|
19
|
+
|
20
|
+
def libraries_home
|
21
|
+
config.libraries.path
|
22
|
+
end
|
23
|
+
|
24
|
+
def dir
|
25
|
+
lib.name.gsub(/ /, '_')
|
26
|
+
end
|
27
|
+
|
28
|
+
def path
|
29
|
+
libraries_home + '/' + dir
|
30
|
+
end
|
31
|
+
|
32
|
+
def canonical_path
|
33
|
+
libraries_home + '/' + canonical_dir
|
34
|
+
end
|
35
|
+
|
36
|
+
def exists?
|
37
|
+
Dir.exist?(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def method_missing(method, *args, &block)
|
41
|
+
if lib && lib.respond_to?(method)
|
42
|
+
lib.send(method, *args, &block)
|
43
|
+
else
|
44
|
+
super(method, *args, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
data/lib/arli/output.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'colored2'
|
2
|
+
|
3
|
+
module Arli
|
4
|
+
module Output
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :enabled
|
8
|
+
def enable!
|
9
|
+
self.enabled = true
|
10
|
+
end
|
11
|
+
def enabled?
|
12
|
+
self.enabled
|
13
|
+
end
|
14
|
+
def disable!
|
15
|
+
self.enabled = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
self.enable!
|
20
|
+
|
21
|
+
def info(msg, header = nil)
|
22
|
+
__pf('%-20s', header.blue) if header
|
23
|
+
__pf((header ? ' : ' : '') + msg + "\n") if msg
|
24
|
+
end
|
25
|
+
|
26
|
+
def debug(msg)
|
27
|
+
__pf('%-20s', header.blue) if header
|
28
|
+
__pf((header ? ' : ' : '') + msg + "\n") if msg
|
29
|
+
end
|
30
|
+
|
31
|
+
def error(msg, exception = nil)
|
32
|
+
__pf "#{msg.to_s.red}\n" if msg
|
33
|
+
__pf "#{exception.inspect.red}\n\n" if exception
|
34
|
+
end
|
35
|
+
|
36
|
+
def report_exception(e, header = nil)
|
37
|
+
__pf header.bold.yellow + ': ' if header
|
38
|
+
error e.message if (e && e.respond_to?(:message))
|
39
|
+
if e && Arli.config.trace
|
40
|
+
__pf e.backtrace.reverse.join("\n")
|
41
|
+
elsif e
|
42
|
+
__pf "\nUse -t (--trace) for detailed exception\n" +
|
43
|
+
"or -D (--debug) to print Arli config\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def raise_invalid_arli_command!(cmd, e = nil)
|
48
|
+
raise Arli::Errors::InvalidCommandError.new(cmd)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Shortcuts disabled in tests
|
52
|
+
def ___(msg = nil, newline = false)
|
53
|
+
return unless Arli::Output.enabled?
|
54
|
+
__pf msg if msg
|
55
|
+
__p '.'.green if msg.nil?
|
56
|
+
__pt if newline
|
57
|
+
end
|
58
|
+
|
59
|
+
def __pt(*args)
|
60
|
+
puts(*args) if Arli::Output.enabled?
|
61
|
+
end
|
62
|
+
|
63
|
+
def __p(*args)
|
64
|
+
print(*args) if Arli::Output.enabled?
|
65
|
+
end
|
66
|
+
|
67
|
+
def __pf(*args)
|
68
|
+
printf(*args) if Arli::Output.enabled?
|
69
|
+
end
|
70
|
+
|
71
|
+
def ok
|
72
|
+
___ '.'.bold.green
|
73
|
+
end
|
74
|
+
|
75
|
+
def fuck
|
76
|
+
___ '✖'.bold.red
|
77
|
+
end
|
78
|
+
|
79
|
+
def header(command: nil)
|
80
|
+
out = "\n#{hr}\n"
|
81
|
+
out << "Arli (#{::Arli::VERSION.yellow})"
|
82
|
+
out << " running #{command.name.to_s.magenta.bold}" if command
|
83
|
+
out << " for #{command.params.to_s.blue}\n" if command
|
84
|
+
out << "Library Path: #{Arli.default_library_path.green}\n"
|
85
|
+
out << "#{hr}\n"
|
86
|
+
info out
|
87
|
+
end
|
88
|
+
|
89
|
+
def hr
|
90
|
+
'——————————————————————————————————————————————————————————'.red
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|