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 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