arli 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|