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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 43e1909fb095e1501d093f53991d7272281c9bb5
4
- data.tar.gz: ade74d5c96106dc1e1bea96716332fcdbe7648b8
3
+ metadata.gz: c4bcc7bfa074f09ae70dbf449ebe1112c6029bc2
4
+ data.tar.gz: 5cd8d400ae0861d24d041d39bb2fa46fcc847685
5
5
  SHA512:
6
- metadata.gz: 4c9daf3b81b26a8ce323b03f71d14f70523566a6cf39cf29a1292a64f60f8812c5b819414542e43c0fac8c482a756b219f23fec025b8a1ce46efc2ad36a8fd5e
7
- data.tar.gz: d5f564e8272beead7287ebd6b773456ecb42a02af44a61e3ab2a935a33805517390678dc4ae992fadd2f6ade61f71cd79ddfa0c0ebac4756cdf3c3da06d36513
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
- ```json
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
- -L, --lib-home HOME Specify a local directory where libraries are installed
51
- -h, --help prints this help
50
+ -h, --help prints this help
52
51
 
53
- Available Commands:
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
- `install` is currently the only implemented command, and it should be used as follows:
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
- -L, --lib-home HOME Specify a local directory where libraries are installed
74
- -a, --arli-json FILE JSON file with dependencies (defaults to arli.json)
75
- -h, --help prints this help
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 = 'ARDUINO_ARLI_LIBRARY_FILE'.freeze
6
- DEFAULT_JSON_FILE = ENV[DEFAULT_JSON_FILE_ENV] || 'arli.json'.freeze
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
- @options = Hashie::Extensions::SymbolizeKeys.symbolize_keys!(options.to_h)
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
- puts e.message
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 = ::Arli::Commands.const_get(command.to_s.capitalize)
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
- puts "Unfortunately command #{command.to_s.red} is not yet implemented.\n\n"
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
- libs = JSON.load(File.read(json_file))
22
- puts "Installing into #{lib_path.bold.green}"
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
- private
43
-
44
- def setup
45
- FileUtils.mkdir_p(lib_path)
46
- yield self if block_given?
47
- self
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('-a FILE', '--arli-json FILE', "JSON file with dependencies (defaults to #{DEFAULT_JSON_FILE.bold.magenta})") { |v| options[:arli_json] = v }
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('-l', '--lib LIBRARY', 'Library Name') { |v| options[:library_name] = v }
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 = " Available Commands:\n"
71
+ subtext = "Available Commands:\n".bold
60
72
 
61
73
  ::Arli::CLI.commands.each_pair do |command, config|
62
- subtext << <<-EOS
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
@@ -1,3 +1,3 @@
1
1
  module Arli
2
- VERSION = '0.2.1'.freeze
2
+ VERSION = '0.2.2'.freeze
3
3
  end
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.1
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