arli 0.8.3 → 0.9.0

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.
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ def shell(*args)
8
8
  end
9
9
 
10
10
  task :permissions do
11
- shell('rm -rf pkg/ tmp/' )
11
+ shell('rm -rf pkg/ tmp/ coverage/' )
12
12
  shell("chmod -v o+r,g+r * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*")
13
13
  shell("find . -type d -exec chmod o+x,g+x {} \\;")
14
14
  end
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_dependency 'arduino-library', '~> 0.5.4'
32
32
  spec.add_dependency 'colored2'
33
+ spec.add_dependency 'awesome_print'
33
34
  spec.add_dependency 'hashie'
34
35
  spec.add_dependency 'dry-types'
35
36
  spec.add_dependency 'dry-struct'
data/exe/arli CHANGED
@@ -8,3 +8,4 @@ end
8
8
  require 'arli/cli/runner'
9
9
  Arli::CLI::Runner.new(ARGV.dup).execute!
10
10
 
11
+
@@ -1,5 +1,5 @@
1
1
  require 'arduino/library'
2
-
2
+ require 'arli/helpers/inherited'
3
3
  require 'arli/version'
4
4
  require 'arli/extensions'
5
5
  require 'arli/errors'
@@ -1,10 +1,14 @@
1
- require_relative '../output'
1
+ require 'arli/helpers/output'
2
+ require 'arli/helpers/inherited'
2
3
 
3
4
  module Arli
4
5
  module Actions
5
6
  # Represents an abstract action related to the library
6
7
  class Action
7
- include Arli::Output
8
+ include Arli::Helpers::Output
9
+
10
+ include Arli::Helpers::Inherited
11
+ attr_assignable :check_command, :check_pattern, :description
8
12
 
9
13
  extend Forwardable
10
14
  def_delegators :@library,
@@ -15,37 +19,7 @@ module Arli
15
19
 
16
20
  class << self
17
21
  def inherited(base)
18
-
19
- base.instance_eval do
20
- class << self
21
- attr_writer :check_command, :check_pattern, :description
22
-
23
- def action_name
24
- name.gsub(/.*::/, '').underscore.to_sym
25
- end
26
-
27
- def set_or_get(var_name, val = nil)
28
- var = "@#{var_name}".to_sym
29
- self.instance_variable_set(var, val) if val
30
- self.instance_variable_get(var)
31
- end
32
-
33
- def check_pattern(val = nil)
34
- set_or_get('check_pattern', val)
35
- end
36
-
37
- def check_command(val = nil)
38
- set_or_get('check_command', val)
39
- end
40
-
41
- def description(val = nil)
42
- set_or_get('description', val)
43
- end
44
- end
45
- end
46
-
47
- # Add to the list of actions
48
- ::Arli::Actions.actions[base.action_name] = base
22
+ ::Arli::Actions.actions[base.short_name] = base
49
23
  end
50
24
  end
51
25
 
@@ -12,12 +12,7 @@ module Arli
12
12
  return if library.url !~ /\.zip$/i
13
13
 
14
14
  download!
15
-
16
- if File.exist?(zip_archive)
17
- FileUtils.rm_rf(top_dir_inside_zip) if top_dir_inside_zip
18
- unzip(zip_archive, '.')
19
- FileUtils.move(top_dir_inside_zip, dir) if Dir.exist?(top_dir_inside_zip)
20
- end
15
+ move_in_place!
21
16
  rescue Exception => e
22
17
  fuck
23
18
  raise(e)
@@ -27,6 +22,14 @@ module Arli
27
22
 
28
23
  private
29
24
 
25
+ def move_in_place!
26
+ if File.exist?(zip_archive)
27
+ FileUtils.rm_rf(top_dir_inside_zip) if top_dir_inside_zip
28
+ unzip(zip_archive, '.')
29
+ FileUtils.move(top_dir_inside_zip, dir) if Dir.exist?(top_dir_inside_zip)
30
+ end
31
+ end
32
+
30
33
  def delete_zip!
31
34
  FileUtils.rm_f(zip_archive) if File.exist?(zip_archive)
32
35
  end
@@ -3,24 +3,41 @@ require 'yaml'
3
3
  require 'forwardable'
4
4
  require 'arduino/library'
5
5
  require 'hashie/mash'
6
+ require 'hashie/extensions/symbolize_keys'
7
+ require 'arli/library'
6
8
 
7
9
  module Arli
8
10
  class ArliFile
9
11
  require 'arduino/library/include'
10
12
 
11
13
  include Enumerable
12
- extend Forwardable
13
14
 
15
+ extend Forwardable
14
16
  def_delegators :@dependencies, *(Array.new.methods - Object.methods)
15
17
 
18
+ include ::Arli::Library
19
+
16
20
  attr_accessor :dependencies,
17
21
  :parsed_data,
18
- :arlifile_path
22
+ :arlifile_path,
23
+ :config
19
24
 
20
25
  def initialize(config: Arli.config, libraries: [])
21
- self.arlifile_path = "#{config.arlifile.path}/#{config.arlifile.name}"
22
- self.dependencies = read_dependencies(libraries)
23
- Arli.config.libraries.temp_dir ||= Dir.mktmpdir
26
+ self.config = config
27
+ self.arlifile_path = "#{config.arlifile.path}/#{config.arlifile.name}"
28
+ self.dependencies = read_dependencies(libraries)
29
+
30
+ self.config.libraries.temp_dir ||= Dir.mktmpdir
31
+
32
+ if parsed_data
33
+ if parsed_data.libraries_path
34
+ self.config.libraries.path = parsed_data.libraries_path
35
+ end
36
+
37
+ if parsed_data.lock_format
38
+ Arli.config.arlifile.lock_format = parsed_data.lock_format
39
+ end
40
+ end
24
41
  end
25
42
 
26
43
  alias libraries dependencies
@@ -43,26 +60,6 @@ module Arli
43
60
  end
44
61
  end
45
62
 
46
-
47
- def library_model(lib)
48
- return lib if lib.is_a?(::Arduino::Library::Model)
49
-
50
- ::Arduino::Library::Model.from(lib).tap do |model|
51
- if model.nil?
52
- lib_output = (lib && lib['name']) ? lib['name'] : lib.inspect
53
- raise Arli::Errors::LibraryNotFound, 'Error: '.bold.red +
54
- "Library #{lib_output.yellow} ".red + "was not found.\n\n".red +
55
- %Q[ HINT: run #{"arli search 'name: /#{lib_output}/'".green}\n] +
56
- %Q[ to find the exact name of the library you are trying\n] +
57
- %Q[ to install. Alternatively, provide a url: field.\n]
58
- end
59
- end
60
- end
61
-
62
- def make_lib(lib)
63
- ::Arli::Library::Proxy.new(library_model(lib))
64
- end
65
-
66
63
  def within_path(p, &_block)
67
64
  FileUtils.mkpath(p) unless Dir.exist?(p)
68
65
  Dir.chdir(p) do
@@ -72,7 +69,7 @@ module Arli
72
69
 
73
70
  def read_dependencies(libraries)
74
71
  if libraries && !libraries.empty?
75
- libraries.map { |lib| make_lib(lib) }
72
+ libraries.map {|lib| make_lib(lib)}
76
73
  else
77
74
  unless arlifile_path && File.exist?(arlifile_path)
78
75
  raise(Arli::Errors::ArliFileNotFound,
@@ -83,8 +80,15 @@ module Arli
83
80
  end
84
81
 
85
82
  def parse_yaml_file
86
- self.parsed_data = Hashie::Mash.new(::YAML.load(::File.read(self.arlifile_path)))
87
- parsed_data.dependencies.map { |lib| make_lib(lib) }
83
+ self.parsed_data = Hashie::Mash.new(
84
+ Hashie::Extensions::SymbolizeKeys.symbolize_keys(
85
+ ::YAML.load(
86
+ ::File.read(
87
+ self.arlifile_path)
88
+ )
89
+ )
90
+ )
91
+ parsed_data.dependencies.map {|lib| make_lib(lib)}
88
92
  end
89
93
  end
90
94
  end
@@ -1,18 +1,17 @@
1
1
  require 'forwardable'
2
2
  require 'optparse'
3
- require 'colored2'
4
3
  require 'tmpdir'
5
4
  require_relative 'parser'
6
5
  require_relative 'command_finder'
7
6
  require_relative 'parser_factory'
8
7
  require_relative '../commands'
9
- require_relative '../output'
8
+ require 'arli/helpers/output'
10
9
 
11
10
 
12
11
  module Arli
13
12
  module CLI
14
13
  class App
15
- include Arli::Output
14
+ include Arli::Helpers::Output
16
15
 
17
16
  attr_accessor :argv, :config, :command
18
17
 
@@ -8,13 +8,13 @@ require_relative 'parser_factory'
8
8
  require_relative '../commands'
9
9
  require_relative '../commands/search'
10
10
  require_relative '../commands/install'
11
- require_relative '../output'
11
+ require 'arli/helpers/output'
12
12
 
13
13
  module Arli
14
14
  module CLI
15
15
  class CommandFinder
16
16
 
17
- include Arli::Output
17
+ include Arli::Helpers::Output
18
18
 
19
19
  attr_accessor :argv, :config, :command_name, :command
20
20
 
@@ -69,15 +69,32 @@ module Arli
69
69
  def option_search
70
70
  on('-d', '--database URL',
71
71
  'a JSON(.gz) file path or a URL of the library database.',
72
- 'Defaults to the Arduino-maintained database.') do |v|
72
+ 'Defaults to the Arduino-maintained database.' + "\n\n") do |v|
73
73
  config.database.path = v
74
74
  end
75
75
 
76
76
  on('-m', '--max NUMBER',
77
- 'if provided, limits the result set to this number',
78
- 'Set to 0 to disable. Default is 100.') do |v|
77
+ 'if provided, limits the result set using the ',
78
+ 'total number of the unique library name matches.',
79
+ 'Default is 0, which means no limit.' + "\n\n") do |v|
79
80
  config.search.results.limit = v.to_i if v
80
81
  end
82
+
83
+ formats = Arli::Library::MultiVersion.format_methods
84
+
85
+ on('-f', '--format FMT',
86
+ "Optional format of the search results.",
87
+ "The default is #{'short'.bold.yellow}. Available ",
88
+ "formats: #{formats.join(', ').bold.yellow}\n\n") do |v|
89
+ if formats.include?(v.downcase.to_sym)
90
+ config.search.results.output_format = v.downcase.to_sym
91
+ else
92
+ raise ::OptionParser::InvalidOption,
93
+ "#{v.yellow} is not a supported search result format"
94
+ end
95
+ end
96
+
97
+ option_search_attributes
81
98
  end
82
99
 
83
100
  def option_if_exists
@@ -115,6 +132,17 @@ module Arli
115
132
  end
116
133
  end
117
134
 
135
+ def option_search_attributes
136
+ on('-A', '--print-attrs', 'prints full list of available library',
137
+ 'attributes that can be used in search strings.', ' ') do
138
+
139
+ ::Arli.config.help = true
140
+ output ''
141
+ header('Arduino Library Attributes:')
142
+ output " • " + Arduino::Library::Types::LIBRARY_PROPERTIES.keys.join("\n • ") + "\n\n"
143
+ end
144
+ end
145
+
118
146
  def header(string)
119
147
  output "#{string.bold.magenta}:"
120
148
  output
@@ -174,6 +202,7 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
174
202
  on('-C', '--no-color',
175
203
  'Disable any color output.') do |*|
176
204
  Colored2.disable! # if $stdout.tty?
205
+ config.no_color = true
177
206
  end
178
207
  on('-D', '--debug',
179
208
  'Print debugging info.') do |v|
@@ -183,10 +212,6 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
183
212
  'Print exception stack traces.') do |v|
184
213
  config.trace = v
185
214
  end
186
- # on('-n', '--dry-run',
187
- # 'Only print actions, but do not do them.') do |v|
188
- # config.trace = v
189
- # end
190
215
  on('-v', '--verbose',
191
216
  'Print more information.') do |v|
192
217
  config.verbose = true
@@ -209,7 +234,7 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
209
234
 
210
235
  def output_command_description(command_name)
211
236
  command_hash = factory.command_parsers[command_name]
212
- indent = ' '
237
+ indent = ' '
213
238
 
214
239
  if command_hash
215
240
  if command_hash.description
@@ -218,7 +243,9 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
218
243
  output indent + command_hash.sentence.bold
219
244
  output ''
220
245
  end
221
- output indent + Array(command_hash[:description]).map(&:dark).join('').gsub(/\n/, "\n#{indent}")
246
+
247
+ text = Array(command_hash[:description]).flatten.join(' ')
248
+ output text.reformat_wrapped(width = 70, indent_with = 8)
222
249
  end
223
250
  end
224
251
 
@@ -28,6 +28,7 @@ module Arli
28
28
  @global ||= make_parser do |parser|
29
29
  parser.banner = usage_line
30
30
  parser.sep
31
+ parser.option_search_attributes
31
32
  parser.option_help(commands: true)
32
33
  end
33
34
  end
@@ -36,32 +37,38 @@ module Arli
36
37
  @command_parsers ||= {
37
38
  search: Hashie::Mash.new(
38
39
  {
39
- sentence: 'Search standard Arduino Library Database with over 4K entries',
40
- description: ["This command provides both the simple name-based search interface,\n",
41
- "and the most sophisticated field-by-field search using a downloaded, \n",
42
- "and locally cached Public Arduino Database JSON file, maintained\n",
43
- "by Arduino and the Community. If you know of another database,\n",
44
- "that's what the --database flag is for."],
40
+ sentence: 'Search standard Arduino Library Database with over 4K entries ',
41
+ description: %Q[This command provides both the simple name-based search interface,
42
+ and the most sophisticated attribute-specific search using a downloaded,
43
+ and locally cached Public Arduino Database JSON file, maintained
44
+ by the Arduino Community. If you know of another database,
45
+ that's what the #{'--database'.blue} flag is for.
46
+ Note that you can print the list of available attributes by
47
+ running arli with #{'--print-attrs'.blue} flag.
48
+ ],
45
49
  examples: [
46
- { desc: 'Search using the regular expression containing the name:',
47
- cmd: 'arli search AudioZero' },
50
+ { desc: 'Finds any library with name matching a given string, case insensitively',
51
+ cmd: 'arli search audiozero' },
48
52
 
49
- { desc: 'Same exact search as above, but using ruby hash syntax:',
50
- cmd: %Q{arli search 'name: /AudioZero/'} },
53
+ { desc: 'If the first character is "/", then the argument is assumed to be regex',
54
+ cmd: %Q{arli search /AudioZero$/ } },
51
55
 
52
- { desc: 'Lets get a particular version of the library',
53
- cmd: %Q{arli search 'name: "AudioZero", version: "1.0,2"'} },
56
+ { desc: 'If the first character is "=", then the rest is assumed to be exact name',
57
+ cmd: %Q{arli search =Time } },
54
58
 
55
- { desc: 'Search using case insensitive name search, and :',
56
- cmd: %Q{arli search 'name: /adafruit/i'} },
59
+ { desc: 'Lets get a particular version of the library using another attribute',
60
+ cmd: %Q{arli search 'name: "AudioZero", version: "1.0.2"'} },
57
61
 
58
- { desc: 'Finally, search for the exact name match:',
59
- cmd: %Q{arli search '^Time$'} },
62
+ { desc: 'Search using case insensitive search for the author',
63
+ cmd: %Q{arli search 'author: /adafruit/i'} },
64
+
65
+ { desc: 'Finally, search for regex match for "WiFi" in a sentence or a paragraph',
66
+ cmd: %Q{arli search 'sentence: /wifi/i, paragraph: /wifi/i'} },
60
67
  ],
61
68
 
62
69
  parser: -> (command_name) {
63
70
  make_parser(command_name) do |parser|
64
- parser.banner = usage_line 'search ' + '[ name | search-expression ]'.magenta
71
+ parser.banner = usage_line 'search ' + '[ -A | search-expression ] '.magenta
65
72
  parser.option_search
66
73
  parser.option_help(command_name: command_name)
67
74
  end
@@ -71,15 +78,13 @@ module Arli
71
78
  bundle: Hashie::Mash.new(
72
79
  {
73
80
  sentence: 'Installs all libraries specified in Arlifile',
74
- description:
75
- [
76
- "This command reads ", "Arlifile".bold.green, " (from the current folder, by default),\n",
77
- "and then it installs all dependent libraries specified there, checking if \n",
78
- "each already exists, and if not — downloading them, and installing them into\n",
79
- "your Arduino Library folder. Both the folder with the Arlifile, as well as the\n",
80
- "destination library path folder can be changed with the command line flags.\n",
81
+ description: %Q[This command reads #{'Arlifile'.bold.green} (from the current folder, by default),
82
+ and then it installs all dependent libraries specified there, checking if
83
+ each already exists, and if not downloading them, and installing them into
84
+ your Arduino Library folder. Both the folder with the Arlifile, as well as the
85
+ destination library path folder can be changed with the command line flags.
81
86
  ],
82
- examples: [
87
+ example: [
83
88
  { desc: 'Install all libs defined in Arlifile:',
84
89
  cmd: 'arli bundle ' },
85
90
 
@@ -98,27 +103,24 @@ module Arli
98
103
  install: Hashie::Mash.new(
99
104
  {
100
105
  sentence: 'Installs a single library either by searching, or url or local ZIP',
101
- description: [
102
- "This command installs a single library into your library path\n",
103
- "using the third argument to the command #{'arli install'.bold.white}\n".dark ,
104
- "which can be a library name, local ZIP file, or a remote URL \n",
105
- "(either ZIP or Git Repo)\n"
106
-
106
+ description: %Q[This command installs a single library into your library path
107
+ (which can be set with #{'--lib-path'.blue} flag).
108
+ Arli interpretes the third argument to #{'arli install'.bold.blue}
109
+ as either an exact library name, or a remote URL
110
+ (either ZIP or Git Repo). You can use #{'search'.bold.green} command
111
+ to first find the right library name, and then pass it to the install command.
107
112
  ],
108
113
  examples: [
109
- { desc: 'Install the latest version of this library',
110
- cmd: 'arli install "Adafruit GFX Library"' },
114
+ { desc: 'Install the latest version of this library locally',
115
+ cmd: 'arli install "Adafruit GFX Library" -l ./libraries' },
111
116
 
112
117
  { desc: 'Install the library from a Github URL',
113
- cmd: 'arli install https://github.com/jfturcot/SimpleTimer' },
114
-
115
- { desc: 'Install a local ZIP file',
116
- cmd: 'arli install ~/Downloads/DHT-Library.zip' },
118
+ cmd: 'arli install https://github.com/jfturcot/SimpleTimer' }
117
119
  ],
118
120
 
119
121
  parser: -> (command_name) {
120
122
  make_parser(command_name) do |parser|
121
- parser.banner = usage_line 'install' + ' [ "library name" | url | local-zip ] '.magenta
123
+ parser.banner = usage_line 'install' + ' [ "Exact Library Name" | url ] '.magenta
122
124
  parser.option_install
123
125
  parser.option_help(command_name: command_name)
124
126
  end