arli 0.2.1 → 0.2.2
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/README.md +33 -10
- data/lib/arli.rb +19 -2
- data/lib/arli/cli.rb +16 -4
- data/lib/arli/commands/base.rb +106 -0
- data/lib/arli/commands/install.rb +23 -36
- data/lib/arli/commands/update.rb +23 -0
- data/lib/arli/parser.rb +23 -13
- data/lib/arli/version.rb +1 -1
- metadata +3 -2
- data/lib/arli/app.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4bcc7bfa074f09ae70dbf449ebe1112c6029bc2
|
4
|
+
data.tar.gz: 5cd8d400ae0861d24d041d39bb2fa46fcc847685
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aef1c241150fadc67b359d8e337d2a3998d70b6e50181800a44b5c202348bcb11f4f9894826361f63455372bdd303404042da4e14f2765de311138ffa4e7ce5c
|
7
|
+
data.tar.gz: 4206dd840bf013f68ee1bb5b64400d3f9ee9225767b23957ad9c02bb728931f15c4faea3cff19b23df3ef98e8129b38d22044a2793f9f755d7e20bb7ab5aa498
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Arli is a simple and easy to use installer of dependencies that can be
|
|
6
6
|
declared in a JSON file of the following format:
|
7
7
|
|
8
8
|
|
9
|
-
```
|
9
|
+
```js
|
10
10
|
{
|
11
11
|
"dependencies": [
|
12
12
|
{
|
@@ -43,14 +43,13 @@ $ sudo gem install arli
|
|
43
43
|
|
44
44
|
Run `arli --help` for more information:
|
45
45
|
|
46
|
-
```
|
46
|
+
```bash
|
47
47
|
Usage:
|
48
48
|
arli [options] [command [options]]
|
49
49
|
|
50
|
-
-
|
51
|
-
-h, --help prints this help
|
50
|
+
-h, --help prints this help
|
52
51
|
|
53
|
-
|
52
|
+
Available Commands:
|
54
53
|
install : installs libraries defined in the JSON file
|
55
54
|
update : updates libraries defined in the JSON file
|
56
55
|
library : Install, update, or remove a single library
|
@@ -60,9 +59,13 @@ See arli <command> --help for more information on a specific command.
|
|
60
59
|
|
61
60
|
#### Install Command
|
62
61
|
|
63
|
-
|
62
|
+
Use this command to install libraries for the first time.
|
64
63
|
|
65
|
-
|
64
|
+
NOTE: you are allowed to pass `-u` flag to automatically fallback
|
65
|
+
to updating any existing folders. So `arli install -u` will either install
|
66
|
+
or update all dependencies.
|
67
|
+
|
68
|
+
```bash
|
66
69
|
Description:
|
67
70
|
installs libraries defined in the JSON file
|
68
71
|
|
@@ -70,11 +73,31 @@ Usage:
|
|
70
73
|
arli install [options]
|
71
74
|
|
72
75
|
Command Options
|
73
|
-
-
|
74
|
-
|
75
|
-
-
|
76
|
+
-l, --lib-home HOME Local folder where libraries are installed
|
77
|
+
Default: ~/Documents/Arduino/Libraries
|
78
|
+
-j, --json FILE JSON file with dependencies (defaults to arli.json)
|
79
|
+
-u, --update-existing Update a library that already exists
|
80
|
+
-h, --help prints this help
|
81
|
+
|
76
82
|
```
|
77
83
|
|
84
|
+
#### Update Command
|
85
|
+
|
86
|
+
To upate previously checked out libraries, use the `update` command:
|
87
|
+
|
88
|
+
```
|
89
|
+
Description:
|
90
|
+
updates libraries defined in the JSON file
|
91
|
+
|
92
|
+
Usage:
|
93
|
+
arli update [options]
|
94
|
+
|
95
|
+
Command Options
|
96
|
+
-l, --lib-home HOME Local folder where libraries are installed
|
97
|
+
Default: ~/Documents/Arduino/Libraries
|
98
|
+
-j, --json FILE JSON file with dependencies (defaults to arli.json)
|
99
|
+
-h, --help prints this help
|
100
|
+
```
|
78
101
|
|
79
102
|
## Development
|
80
103
|
|
data/lib/arli.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
require 'arli/version'
|
2
2
|
require 'arli/cli'
|
3
|
+
require 'logger'
|
3
4
|
|
4
5
|
module Arli
|
5
|
-
DEFAULT_JSON_FILE_ENV
|
6
|
-
DEFAULT_JSON_FILE
|
6
|
+
DEFAULT_JSON_FILE_ENV = 'ARDUINO_ARLI_LIBRARY_FILE'.freeze
|
7
|
+
DEFAULT_JSON_FILE = ENV[DEFAULT_JSON_FILE_ENV] || 'arli.json'.freeze
|
7
8
|
|
8
9
|
DEFAULT_LIBRARY_PATH_ENV = 'ARDUINO_CUSTOM_LIBRARY_PATH'.freeze
|
9
10
|
DEFAULT_LIBRARY_PATH = ENV[DEFAULT_LIBRARY_PATH_ENV] || (ENV['HOME'] + '/Documents/Arduino/Libraries')
|
11
|
+
|
12
|
+
DEBUG = ENV['DEBUG'] ? true : false
|
13
|
+
|
14
|
+
@logger = Logger.new(STDOUT)
|
15
|
+
@logger.level = Logger::INFO
|
16
|
+
|
17
|
+
class << self
|
18
|
+
attr_accessor :logger
|
19
|
+
|
20
|
+
%i(debug info error warn fatal).each do |level|
|
21
|
+
define_method level do |*args|
|
22
|
+
self.logger.send(level, *args) if self.logger
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
10
26
|
end
|
27
|
+
|
data/lib/arli/cli.rb
CHANGED
@@ -4,6 +4,7 @@ require 'hashie/extensions/symbolize_keys'
|
|
4
4
|
require 'colored2'
|
5
5
|
require 'arli'
|
6
6
|
require 'arli/parser'
|
7
|
+
require 'arli/commands/update'
|
7
8
|
require 'arli/commands/install'
|
8
9
|
|
9
10
|
module Arli
|
@@ -37,27 +38,37 @@ module Arli
|
|
37
38
|
options.merge!(parser.options)
|
38
39
|
end
|
39
40
|
|
40
|
-
|
41
|
+
self.options = Hashie::Extensions::SymbolizeKeys.symbolize_keys!(options.to_h)
|
41
42
|
|
42
43
|
run_command! unless options[:help]
|
43
44
|
|
44
45
|
rescue InvalidCommandError => e
|
45
|
-
|
46
|
+
output e.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.output(*args)
|
50
|
+
puts args.join("\n") unless args.empty?
|
51
|
+
end
|
52
|
+
|
53
|
+
def output(*args)
|
54
|
+
self.class.output(*args)
|
46
55
|
end
|
47
56
|
|
48
57
|
private
|
49
58
|
|
50
59
|
def run_command!
|
51
60
|
if command
|
52
|
-
command_class
|
61
|
+
command_class = ::Arli::Commands.const_get(command.to_s.capitalize)
|
53
62
|
|
54
63
|
options[:arli_json] ||= ::Arli::DEFAULT_JSON_FILE
|
55
64
|
options[:lib_home] ||= ::Arli::DEFAULT_LIBRARY_PATH
|
56
65
|
|
66
|
+
output "run_command #{command.to_s.bold.green}, options: #{options.inspect.bold.blue}" if Arli::DEBUG
|
57
67
|
command_class.new(options).run
|
58
68
|
end
|
59
69
|
rescue NameError => e
|
60
|
-
|
70
|
+
output e.inspect
|
71
|
+
output "Unfortunately command #{command.to_s.red} is not yet implemented.\n\n"
|
61
72
|
end
|
62
73
|
|
63
74
|
def parse_command_options!
|
@@ -106,6 +117,7 @@ module Arli
|
|
106
117
|
parser.banner = usage_line 'install'
|
107
118
|
parser.option_lib_home
|
108
119
|
parser.option_dependency_file
|
120
|
+
parser.option_update_if_exists
|
109
121
|
parser.option_help(command: command)
|
110
122
|
end
|
111
123
|
} },
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open3'
|
4
|
+
require 'arli'
|
5
|
+
require 'arli/version'
|
6
|
+
|
7
|
+
module Arli
|
8
|
+
module Commands
|
9
|
+
class Base
|
10
|
+
attr_accessor :lib_path, :json_file, :update_if_exists, :command
|
11
|
+
|
12
|
+
def initialize(options)
|
13
|
+
self.lib_path = options[:lib_home]
|
14
|
+
self.json_file = options[:arli_json]
|
15
|
+
self.update_if_exists = options[:update_if_exists]
|
16
|
+
self.command = self.class.name.gsub(/.*::/, '').downcase.to_sym
|
17
|
+
setup
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Commands implement #run method that uses helpers below:
|
22
|
+
protected
|
23
|
+
|
24
|
+
def header
|
25
|
+
info "Arli : Version #{::Arli::VERSION.bold.yellow}\n" +
|
26
|
+
"Running command : #{command.to_s.bold.blue}\n" +
|
27
|
+
"Library Path : #{lib_path.bold.green}\n" +
|
28
|
+
"JSON File : #{json_file.bold.magenta}\n" +
|
29
|
+
'———————————————————————————————————————————————————————'
|
30
|
+
end
|
31
|
+
|
32
|
+
def all_dependencies(cmd, *args)
|
33
|
+
for_each_dependency do |dep|
|
34
|
+
begin
|
35
|
+
method_name = "#{cmd}_dependency".to_sym
|
36
|
+
argv = args.map { |key| dep[key] }
|
37
|
+
if self.respond_to?(method_name)
|
38
|
+
info("dependency #{dep.inspect}: calling #{method_name} with args #{argv.inspect}") if Arli::DEBUG
|
39
|
+
self.send(method_name, *argv) do |system_command|
|
40
|
+
execute(system_command)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
raise ArgumentError,
|
44
|
+
"Method #{method_name.to_s.bold.blue} is not implemented on #{self.class.name.bold.red}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue Exception => e
|
49
|
+
error "Error while running command #{cmd}:\n\n#{e.message.bold.red}"
|
50
|
+
if Arli::DEBUG
|
51
|
+
error e.backtrace.join("\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def setup
|
56
|
+
FileUtils.mkdir_p(lib_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param <String> *args — list of arguments or a single string
|
60
|
+
def execute(*args)
|
61
|
+
cmd = args.join(' ')
|
62
|
+
info cmd.bold.green
|
63
|
+
o, e, s = Open3.capture3(cmd)
|
64
|
+
puts o if o
|
65
|
+
puts e.red if e
|
66
|
+
s
|
67
|
+
rescue Exception => e
|
68
|
+
error "Error running [#{cmd.bold.yellow}]\n" +
|
69
|
+
"Current folder is [#{Dir.pwd.bold.yellow}]", e
|
70
|
+
raise e
|
71
|
+
end
|
72
|
+
|
73
|
+
def for_each_dependency(&_block)
|
74
|
+
dependencies['dependencies'].each do |dependency|
|
75
|
+
Dir.chdir(lib_path) do
|
76
|
+
yield(dependency)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def dependencies
|
82
|
+
@deps ||= begin
|
83
|
+
JSON.load(File.read(json_file))
|
84
|
+
rescue Errno::ENOENT => e
|
85
|
+
error("File #{json_file.bold.yellow} could not be found!", e)
|
86
|
+
{ 'dependencies' => [] }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def error(msg, exception = nil)
|
91
|
+
printf 'Runtime Error: '.bold.red + "\n#{msg}\n" if msg
|
92
|
+
if exception
|
93
|
+
puts
|
94
|
+
printf 'Exception: '.red + "\n#{exception.inspect.red}\n\n"
|
95
|
+
end
|
96
|
+
puts
|
97
|
+
end
|
98
|
+
|
99
|
+
def info(msg, header = nil)
|
100
|
+
printf('%-20s', header.bold.blue) if header
|
101
|
+
printf((header ? ' : ' : '') + msg + "\n") if msg
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -2,50 +2,37 @@ require 'json'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require 'open3'
|
4
4
|
require 'arli'
|
5
|
+
require 'arli/commands/update'
|
5
6
|
|
6
7
|
module Arli
|
7
8
|
module Commands
|
8
|
-
|
9
|
-
class Install
|
10
|
-
attr_accessor :lib_path, :json_file
|
11
|
-
|
12
|
-
def initialize(options)
|
13
|
-
|
14
|
-
self.lib_path = options[:lib_home]
|
15
|
-
self.json_file = options[:arli_json]
|
16
|
-
|
17
|
-
setup
|
18
|
-
end
|
9
|
+
class Install < Update
|
19
10
|
|
20
11
|
def run
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Dir.chdir(lib_path) do
|
25
|
-
libs['dependencies'].each do |dependency|
|
26
|
-
name = dependency['name']
|
27
|
-
url = dependency['git']
|
28
|
-
printf 'processing library: ' + name.yellow.bold + "\n"
|
29
|
-
unless Dir.exist?(name)
|
30
|
-
cmd = "git clone -v #{url} #{name} 2>&1"
|
31
|
-
else
|
32
|
-
cmd = "cd #{name} && git pull --rebase 2>&1"
|
33
|
-
end
|
34
|
-
puts 'command: ' + cmd.bold.blue
|
35
|
-
o, e, s = Open3.capture3(cmd)
|
36
|
-
puts o if o
|
37
|
-
puts e.red if e
|
38
|
-
end
|
39
|
-
end
|
12
|
+
header
|
13
|
+
all_dependencies(command, 'name', 'git')
|
40
14
|
end
|
41
15
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
16
|
+
def install_dependency(name, url)
|
17
|
+
cmd = if Dir.exist?(name)
|
18
|
+
if update_if_exists
|
19
|
+
update_dependency(name)
|
20
|
+
else
|
21
|
+
raise <<-EOF
|
22
|
+
Existing folder found for library #{name.red}.
|
23
|
+
Please use -u switch with 'install' command,
|
24
|
+
or invoke the 'update' command directly."
|
25
|
+
EOF
|
26
|
+
.gsub(/^\s+/, '')
|
27
|
+
|
28
|
+
end
|
29
|
+
else
|
30
|
+
"git clone -v #{url} #{name} 2>&1"
|
31
|
+
end
|
32
|
+
yield(cmd) if block_given?
|
33
|
+
cmd
|
48
34
|
end
|
49
35
|
end
|
36
|
+
|
50
37
|
end
|
51
38
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open3'
|
4
|
+
require 'arli'
|
5
|
+
require_relative 'base'
|
6
|
+
|
7
|
+
module Arli
|
8
|
+
module Commands
|
9
|
+
class Update < Base
|
10
|
+
|
11
|
+
def run
|
12
|
+
header
|
13
|
+
all_dependencies(command, 'name')
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_dependency(name)
|
17
|
+
cmd = "cd #{name} && git pull --rebase 2>&1"
|
18
|
+
yield(cmd) if block_given?
|
19
|
+
cmd
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/arli/parser.rb
CHANGED
@@ -4,11 +4,10 @@ module Arli
|
|
4
4
|
attr_accessor :output_lines, :command, :options
|
5
5
|
|
6
6
|
def initialize(command = nil)
|
7
|
-
super
|
7
|
+
super(nil, 22)
|
8
8
|
self.output_lines = Array.new
|
9
9
|
self.command = command
|
10
10
|
self.options = Hashie::Mash.new
|
11
|
-
|
12
11
|
end
|
13
12
|
|
14
13
|
def sep(text = nil)
|
@@ -16,7 +15,24 @@ module Arli
|
|
16
15
|
end
|
17
16
|
|
18
17
|
def option_dependency_file
|
19
|
-
on('-
|
18
|
+
on('-j', '--json FILE',
|
19
|
+
"JSON file with dependencies (defaults to #{DEFAULT_JSON_FILE.bold.magenta})\n\n") do |v|
|
20
|
+
options[:arli_json] = v
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def option_lib_home
|
25
|
+
on('-l', '--lib-home HOME', 'Local folder where libraries are installed',
|
26
|
+
"Default: #{Arli::DEFAULT_LIBRARY_PATH.gsub(%r(#{ENV['HOME']}), '~').blue}\n\n") do |v|
|
27
|
+
options[:lib_home] = v
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def option_update_if_exists
|
32
|
+
on('-u', '--update-existing',
|
33
|
+
'Update a library that already exists') do |v|
|
34
|
+
options[:update_if_exists] = true
|
35
|
+
end
|
20
36
|
end
|
21
37
|
|
22
38
|
def option_help(commands: false, command: nil)
|
@@ -30,12 +46,8 @@ module Arli
|
|
30
46
|
end
|
31
47
|
end
|
32
48
|
|
33
|
-
def option_lib_home
|
34
|
-
on('-L', '--lib-home HOME', 'Specify a local directory where libraries are installed') { |v| options[:lib_home] = v }
|
35
|
-
end
|
36
|
-
|
37
49
|
def option_library
|
38
|
-
on('-
|
50
|
+
on('-n', '--lib-name LIBRARY', 'Library Name') { |v| options[:library_name] = v }
|
39
51
|
on('-f', '--from FROM', 'A git or https URL') { |v| options[:library_from] = v }
|
40
52
|
on('-v', '--version VERSION', 'Library Version, i.e. git tag') { |v| options[:library_version] = v }
|
41
53
|
on('-i', '--install', 'Install a library') { |v| options[:library_action] = :install }
|
@@ -56,12 +68,10 @@ module Arli
|
|
56
68
|
end
|
57
69
|
|
58
70
|
def command_help
|
59
|
-
subtext = "
|
71
|
+
subtext = "Available Commands:\n".bold
|
60
72
|
|
61
73
|
::Arli::CLI.commands.each_pair do |command, config|
|
62
|
-
subtext <<
|
63
|
-
#{sprintf(' %-12s', command.to_s).green} : #{sprintf('%-70s', config[:description]).yellow}
|
64
|
-
EOS
|
74
|
+
subtext << %Q/#{sprintf(' %-12s', command.to_s).green} : #{sprintf('%s', config[:description]).yellow}\n/
|
65
75
|
end
|
66
76
|
subtext << <<-EOS
|
67
77
|
|
@@ -77,7 +87,7 @@ See #{COMMAND.bold.blue + ' <command> '.bold.green + '--help'.bold.yellow} for m
|
|
77
87
|
end
|
78
88
|
|
79
89
|
def print
|
80
|
-
puts output.join("\n")
|
90
|
+
puts output.join("\n") unless output.empty?
|
81
91
|
end
|
82
92
|
end
|
83
93
|
end
|
data/lib/arli/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Gredeskoul
|
@@ -130,9 +130,10 @@ files:
|
|
130
130
|
- bin/setup
|
131
131
|
- exe/arli
|
132
132
|
- lib/arli.rb
|
133
|
-
- lib/arli/app.rb
|
134
133
|
- lib/arli/cli.rb
|
134
|
+
- lib/arli/commands/base.rb
|
135
135
|
- lib/arli/commands/install.rb
|
136
|
+
- lib/arli/commands/update.rb
|
136
137
|
- lib/arli/parser.rb
|
137
138
|
- lib/arli/version.rb
|
138
139
|
homepage: https://github.com/kigster/arli
|
data/lib/arli/app.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'colored2'
|
2
|
-
require 'optparse'
|
3
|
-
require 'hashie/mash'
|
4
|
-
require 'saves/cli/parser'
|
5
|
-
require 'forwardable'
|
6
|
-
module Saves
|
7
|
-
module CLI
|
8
|
-
class App
|
9
|
-
extend Forwardable
|
10
|
-
def_delegators :@parser, :options, :output
|
11
|
-
|
12
|
-
attr_accessor :args, :command, :parser, :options, :output
|
13
|
-
|
14
|
-
def initialize(args)
|
15
|
-
if args.nil? || args.empty?
|
16
|
-
self.args = %w[--help]
|
17
|
-
else
|
18
|
-
self.args = args.dup
|
19
|
-
end
|
20
|
-
|
21
|
-
self.parser = ::Saves::CLI::Parser
|
22
|
-
self.options = parser.options
|
23
|
-
self.output = parser.output
|
24
|
-
end
|
25
|
-
|
26
|
-
def parse!
|
27
|
-
if args.first =~ /^-/
|
28
|
-
parser.global.parse!(args)
|
29
|
-
else
|
30
|
-
cmd = self.args.shift.to_sym
|
31
|
-
begin
|
32
|
-
Parser.parser_for(cmd).parse!(args)
|
33
|
-
self.command = cmd # did not raise exception, so valid command.
|
34
|
-
rescue Saves::CLI::InvalidCommandError => e
|
35
|
-
options[:errors] = [e.message]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def out
|
41
|
-
output.join("\n")
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|