arduino-library 0.4.1 → 0.5.0

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: 66aeda9e6680093e8c8225ba6b7e4d66b2389c48
4
- data.tar.gz: 695f68cdea0c96ac44a46817b168210a0c0a79c8
3
+ metadata.gz: dfd69741b18cd50e564b668bfec0d7a0e50e1392
4
+ data.tar.gz: bd4b4443a0598213ba330f3ac21082bc29eba77c
5
5
  SHA512:
6
- metadata.gz: a72df69b7cf8ae242bc0ba37dd6abaca3214d52e3e3251bb3015ce08f3bf03883606c065e628b2d09f5d2db0d4d38c2d51423aa29006128bcbcec36c30a29daa
7
- data.tar.gz: bc91451ac384c4f7a6676d61446da720840715a9f707f3e2095a6631604f5413ddf18d4f2a51b4e53e061d5b75a5773adeb658ee675713b77c6e34f3706fdbe5
6
+ metadata.gz: 679f7c39fa04c902061f687be5c9ddfcf56c28b3d754540141cac679390256b9ac312b218b506568613cee9d117453e44676e9a188d4d0c712c4a6972ced374a
7
+ data.tar.gz: 97117d676ce82780c48a6ab277d5e5fa30d65737fbc6df8fb5e1158e51a4149dee6d8d462deab9065ae5e3317b17b3f9ccc81fa1e54702f927a4bb3e5f76edca
data/README.md CHANGED
@@ -8,13 +8,14 @@
8
8
 
9
9
  # Arduino::Library
10
10
 
11
- This gem encapsulates various rules about the [`library.properties`](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#library-metadata) file that contains meta-data about Arduino Libraries.
11
+ > NOTE: This gem is the underpinning for [Arli](https://github.com/kigster/arli) command line Arduino Library manager.
12
12
 
13
- It also provides convenient shortcuts for downloading the Arduino-maintained database of published libraries in JSON format, searching for various libraries, choosing a version, and more.
13
+ This library offers a ruby model representing an Arduino Library, including field validation, reading and writing the [`library.properties`](https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#library-metadata) file, or searching for libraries in the official database.
14
14
 
15
- It also provides validation functionality for the `library.properties` file for your custom libraries you would like to open source.
16
-
15
+ Searching for a library will transparently download and cache the Arduino-maintained JSON database of official libraries locally, so that future searches are fast.
17
16
 
17
+ The library also provides validation functionality for the `library.properties` file for your custom libraries you would like to open source.
18
+
18
19
  ## Installation
19
20
 
20
21
  Add this line to your application's Gemfile:
@@ -69,26 +70,16 @@ Arduino::Library::DefaultDatabase.library_index_url = ''
69
70
  If you change any of the above, please reload the database with:
70
71
 
71
72
  ```ruby
72
- Arduino::Library::DefaultDatabase.instance.setup
73
+ Arduino::Library::DefaultDatabase.reload!
73
74
  ```
74
75
 
75
76
  #### Default Values:
76
77
 
77
- ```ruby
78
- DEFAULT_ARDUINO_LIBRARY_INDEX_URL =
79
- 'http://downloads.arduino.cc/libraries/library_index.json.gz'
80
-
81
- DEFAULT_ARDUINO_LIBRARY_PATH =
82
- ENV['ARDUINO_CUSTOM_LIBRARY_PATH'] || (ENV['HOME'] + '/Documents/Arduino/Libraries')
83
-
84
- DEFAULT_ARDUINO_LIBRARY_INDEX_PATH =
85
- ENV['ARDUINO_LIBRARY_INDEX_PATH'] ||
86
- (ENV['HOME'] + '/Documents/Arduino/Libraries/index.json.gz')
87
- ```
78
+ Please review the [`library.rb`](https://github.com/kigster/arduino-library/blob/master/lib/arduino/library.rb) file to understand how these variables are resolved.
88
79
 
89
80
  ### Finding and Resolving Arduino Libraries
90
81
 
91
- Top level module `Arduino::Library` provides a convenient Facáde into the library functionality. Therefore you can use the library by calling these methods directly, such as `Arduino::Library.library_from(..)` or by including the module in your current context.
82
+ The primary module `Arduino::Library` provides a convenient Facáde into all of the library functionality. Therefore you can use the library by calling these methods directly, such as `Arduino::Library.library_from(..)` or by including the module in your current context.
92
83
 
93
84
  Below we'll include the top level module, and use the shortcut methods to explore available functionality. That said, if you prefer not to include the top level module, you can call the same functions directly on the module itself.
94
85
 
@@ -101,13 +92,14 @@ class Foo
101
92
  end
102
93
  ```
103
94
 
104
- Or, perhaps easier:
95
+ Or, perhaps even easier:
105
96
 
106
97
  ```ruby
107
98
  class Foo
108
- require 'arduino/library/include
99
+ require 'arduino/library/include'
109
100
  end
110
101
  ```
102
+
111
103
  ### Facáde Methods
112
104
 
113
105
  #### Using `db_from`
@@ -146,6 +138,28 @@ library_from('https://raw.githubusercontent.com/PaulStoffregen/DS1307RTC/master/
146
138
  #=> 'DS1307RTC'
147
139
  ```
148
140
 
141
+ In the next section you will read about the search, but the truth is that the `library_from` method actualy will fall back to search if you provide a partial hash. The allowed values in the hash are: `name, checksum, archiveFileName`. Since these keys often uniquely identify a library, the gem attempts to find it for you.
142
+
143
+ ```ruby
144
+ require 'arduino/library/include' #=> true
145
+ library_from(name: 'AudioZero')
146
+ => #<Arduino::Library::Model
147
+ name="AudioZero"
148
+ version="1.1.1"
149
+ author="Arduino"
150
+ maintainer="Arduino <info@arduino.cc>"
151
+ ..........>
152
+
153
+ library_from(checksum: 'SHA-256:4604a3b92b9f4a7dd92534eb09247443fa5078e6bd0e7a2c5f3060eaba2ad974')
154
+ => #<Arduino::Library::Model
155
+ name="AudioZero"
156
+ version="1.1.1"
157
+ author="Arduino"
158
+ maintainer="Arduino <info@arduino.cc>"
159
+ ..........>
160
+ ```
161
+
162
+
149
163
  #### Using `search`
150
164
 
151
165
  Method `search` is, perhaps, some of the most powerful functionality in this gem. It allows constructing very flexible and precise queries, to match any number of library attributes.
@@ -192,7 +206,11 @@ results.size
192
206
 
193
207
  Note that multiple attributes must ALL match for the library to be included in the result set.
194
208
 
195
- ### `Arduino::Library::Database`
209
+ ### Low-level API
210
+
211
+ The Facade is the recommended way to use library. Below we briefly describe the low-level API of the underlying classes.
212
+
213
+ #### `Arduino::Library::Database`
196
214
 
197
215
  > Downloading the index of all libraries, and searching for a library.
198
216
 
@@ -229,7 +247,7 @@ end
229
247
  You can pass any of the attributes to #search, and the value can be a `String` (in which case only equality matches), or a regular expression, eg:
230
248
 
231
249
  ```ruby
232
- database.search(author: "Paul Stoffregen").size #=> 21
250
+ database.search(author: 'Paul Stoffregen').size #=> 21
233
251
  database.search(author: /stoffregen/i).size #=> 33
234
252
  ```
235
253
 
@@ -249,11 +267,11 @@ all_versions = database.search(name: 'AudioZero')
249
267
  # => [ Arduino::Library::Model<name: AudioZero, version: '1.0.1',... >, .. ]
250
268
  ```
251
269
 
252
- ### `Arduino::Library::Model`
270
+ #### `Arduino::Library::Model`
253
271
 
254
272
  > Use this class to operate on a single library.
255
273
 
256
- #### Reading Library from an External Source using `.from`
274
+ ##### Reading Library from an External Source using `.from`
257
275
 
258
276
  You can use an intelligent class method `.from` that attempts to auto-detect the type of file or URL you are passing as an argument, and use an appropriate parser for each type.
259
277
 
@@ -273,11 +291,11 @@ model = Arduino::Library::Model.from(properties_file)
273
291
  model.name #=> 'AudioZero'
274
292
  ```
275
293
 
276
- ### Presenters
294
+ #### Presenters
277
295
 
278
296
  Presenters are there to convert to and from a particular format.
279
297
 
280
- #### `.properties` Presenter
298
+ ##### `.properties` Presenter
281
299
 
282
300
  ```ruby
283
301
  props = Arduino::Library::Presenters::Properties.new(model).present
@@ -21,7 +21,7 @@ require 'arduino/library/types'
21
21
  require 'arduino/library/model'
22
22
  require 'arduino/library/database'
23
23
  require 'arduino/library/default_database'
24
- require 'arduino/library/resolver'
24
+ require 'arduino/library/finder'
25
25
  require 'arduino/library/instance_methods'
26
26
 
27
27
  module Arduino
@@ -12,24 +12,34 @@ module Arduino
12
12
  class << self
13
13
  attr_accessor :library_index_path,
14
14
  :library_path,
15
- :library_index_url
15
+ :library_index_url,
16
+ :url_size_cache
16
17
 
17
18
  def instance
18
19
  @default ||= self.send(:new)
19
20
  end
21
+
22
+ def reload!
23
+ instance.reload!
24
+ end
25
+
26
+ def assign_defaults
27
+ self.url_size_cache ||= {}
28
+ self.library_index_path ||= DEFAULT_ARDUINO_LIBRARY_INDEX_PATH
29
+ self.library_index_url ||= DEFAULT_ARDUINO_LIBRARY_INDEX_URL
30
+ self.library_path ||= DEFAULT_ARDUINO_LIBRARY_PATH
31
+ end
20
32
  end
21
33
 
22
- self.library_index_path ||= DEFAULT_ARDUINO_LIBRARY_INDEX_PATH
23
- self.library_index_url ||= DEFAULT_ARDUINO_LIBRARY_INDEX_URL
24
- self.library_path ||= DEFAULT_ARDUINO_LIBRARY_PATH
34
+ self.assign_defaults
25
35
 
26
36
  attr_accessor :url, :path
27
37
 
28
38
  def initialize
29
- setup
39
+ reload!
30
40
  end
31
41
 
32
- def setup
42
+ def reload!
33
43
  self.url = self.class.library_index_url
34
44
  self.path = self.class.library_index_path
35
45
 
@@ -44,17 +54,26 @@ module Arduino
44
54
 
45
55
  def download_if_needed!
46
56
  if File.exist?(path)
47
- resp = HTTParty.head(url)
48
- remote_size = resp['content-length'].to_i
57
+ remote_size = get_remote_size(url)
49
58
  local_size = File.size(path)
50
- debug("remote: #{remote_size}, local #{local_size}")
59
+ debug("remote size: #{remote_size}, local size: #{local_size}")
51
60
  return if remote_size == local_size
52
61
  backup_previous_library(path)
53
62
  end
54
-
55
63
  download(url, path)
56
64
  end
57
65
 
66
+ def get_remote_size(url)
67
+ with_caching(url) do
68
+ resp = HTTParty.head(url)
69
+ resp['content-length'].to_i
70
+ end
71
+ end
72
+
73
+ def with_caching(url, &_block)
74
+ @cache ||= self.class.url_size_cache
75
+ @cache[url] ||= yield
76
+ end
58
77
  end
59
78
  end
60
79
  end
@@ -1,28 +1,34 @@
1
- require 'arduino/library'
2
- require 'arduino/library/instance_methods'
3
- require 'arduino/library/model'
1
+ require_relative 'instance_methods'
2
+ require_relative 'model'
4
3
 
5
4
  module Arduino
6
5
  module Library
7
- # This method is used internally by the Model class's #from method.
8
- module Resolver
6
+ # The goal of this class is to identify a *single* library
7
+ # complete with all the metadata, in particular URL, so that
8
+ # the library can be installed.
9
+ #
10
+ # We accept partial information about the library, and construct
11
+ # query based this information. If multiple entries returned,
12
+ # but for the same library, the latest version is returned.
13
+ module Finder
9
14
  class << self
10
15
  include ::Arduino::Library::InstanceMethods
11
16
 
12
- # Resolves a given model without a URL by performing a
13
- # search in the Ardiuino Library for the library name and version.
17
+ # Finds a given model with only partial data by
18
+ # searching in the Ardiuino Database.
14
19
  #
15
- # model = Arduino::Library::Resolver.resolve({ name: 'AudioZero'} )
20
+ # model = Arduino::Library::Finder.find({ name: 'AudioZero'} )
16
21
  # # => <Arduino::Library::Model#0x3242gfa2...>
17
22
  #
18
23
  # model.url # => 'https://github.com/.......'
19
24
  #
20
25
  # @param [Model] model with a partial information only, such as the name.
21
- # @return [Model] a resolved model with #url provided, if found, nil otherwise.
22
- def resolve(model)
26
+ # @return [Model] a found model with #url provided, if found, nil otherwise.
27
+ def find(model)
23
28
  raise ArgumentError, 'Model argument is required' unless model
29
+
24
30
  model = Model.from(model) unless model.is_a?(Model)
25
- return model if model && model.url
31
+ return model unless model.partial?
26
32
 
27
33
  query = construct_query(model)
28
34
  return nil if query.empty?
@@ -2,6 +2,9 @@ require 'arduino/library'
2
2
 
3
3
  module Arduino
4
4
  module Library
5
+ # These are the DSL methods that can be imported by requiring
6
+ # 'arduino/library/include'
7
+ #
5
8
  module InstanceMethods
6
9
  # @param [String] file_or_url — either a local file, or URL, can be gzipped
7
10
  def db_from(file_or_url)
@@ -1,7 +1,7 @@
1
1
  require_relative 'types'
2
2
  require_relative 'utilities'
3
3
  require_relative 'instance_methods'
4
- require_relative 'resolver'
4
+ require_relative 'finder'
5
5
  require 'json'
6
6
 
7
7
  module Arduino
@@ -18,6 +18,8 @@ module Arduino
18
18
  self.attribute field, eval(type)
19
19
  end
20
20
 
21
+ SEARCHABLE_FIELDS = %i(name archiveFileName checksum)
22
+
21
23
  # Instance Methods
22
24
 
23
25
  # Convert a version such as '1.44.3' into a number '1044003' for easy
@@ -33,6 +35,11 @@ module Arduino
33
35
  0
34
36
  end
35
37
 
38
+ # @returns true if the library has enough data to be searched in the db
39
+ def partial?
40
+ self.url.nil? && SEARCHABLE_FIELDS.any?{ |field| self.send(field) }
41
+ end
42
+
36
43
  def <=>(another)
37
44
  self.version_to_i <=> another.version_to_i
38
45
  end
@@ -99,7 +106,7 @@ module Arduino
99
106
  # ends
100
107
  #
101
108
  # @return [Model | Array<Model> ] — array for search, otherwise a model
102
- def from(source = nil, **opts)
109
+ def from(source = nil, ** opts)
103
110
  model = case source
104
111
  when Hash
105
112
  from_hash(source)
@@ -114,11 +121,21 @@ module Arduino
114
121
  end
115
122
  end
116
123
  when NilClass
117
- if opts && opts[:name] && opts[:version]
118
- search(**opts)
124
+ if opts
125
+ if SEARCHABLE_FIELDS.any?{ |field| opts[field] }
126
+ results = search(**opts)
127
+ raise "Too many items matched — #{results.size}" if results.size > 1
128
+ results ? results.first : nil
129
+ else
130
+ from_hash(opts)
131
+ end
119
132
  end
120
133
  end
121
- model ? Resolver.resolve(model) : model
134
+ if model&.partial?
135
+ Finder.find(model)
136
+ else
137
+ model
138
+ end
122
139
  end
123
140
  end
124
141
  end
@@ -21,19 +21,7 @@ module Arduino
21
21
  end
22
22
 
23
23
  def backup_previous_library(path)
24
- debug "backup previous library: #{path.bold.green}"
25
- new_name = nil
26
- index = 0
27
-
28
- loop do
29
- index += 1
30
-
31
- new_name = "#{path}.#{index}"
32
- break unless File.exist?(new_name)
33
- debug "file #{new_name.bold.green} exists, next..."
34
- raise 'Too many backup versions created, delete some first' if index > 20
35
- end
36
-
24
+ new_name = path + ".#{short_time}"
37
25
  debug "moving #{path.bold.green}", "to #{new_name.bold.blue}"
38
26
  FileUtils.move(path, new_name)
39
27
  end
@@ -49,6 +37,10 @@ module Arduino
49
37
  def debug(*msgs)
50
38
  puts "\n" + msgs.join("\n") if ENV['DEBUG']
51
39
  end
40
+
41
+ def short_time(time = Time.now)
42
+ time.strftime('%Y%m%d-%H%M%S')
43
+ end
52
44
  end
53
45
  end
54
46
  end
@@ -1,8 +1,8 @@
1
1
  module Arduino
2
2
  module Library
3
- VERSION = '0.4.1'
3
+ VERSION = '0.5.0'
4
4
  DESCRIPTION = <<-eof
5
- This gem encapsulates many concepts related to how Arduino Libraries are indexed, how their metadata is validated, or .properties file generated. It supports searching the Arduino library database for any terms. This gem is used by Arli — Arduino Installer CLI toolkit.
5
+ This library provides a convenient ruby API for representation of an Arduino Library specification, including field and type validation, reading and writing the library.properties file, as well as downloading the official database of Arduino libraries, and offering a highly advanced searching functionality. This gem only offers Ruby API, but for command line usage please checkout the gem called "arli" — Arduino Library Dependency Manager that uses this library behind the scenes.
6
6
  eof
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arduino-library
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-20 00:00:00.000000000 Z
11
+ date: 2017-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-configurable
@@ -164,10 +164,14 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- description: " This gem encapsulates many concepts related to how Arduino Libraries
168
- are indexed, how their metadata is validated, or .properties file generated. It
169
- supports searching the Arduino library database for any terms. This gem is used
170
- by Arli Arduino Installer CLI toolkit.\n"
167
+ description: ' This library provides a convenient ruby API for representation of
168
+ an Arduino Library specification, including field and type validation, reading and
169
+ writing the library.properties file, as well as downloading the official database
170
+ of Arduino libraries, and offering a highly advanced searching functionality. This
171
+ gem only offers Ruby API, but for command line usage please checkout the gem called
172
+ "arli" — Arduino Library Dependency Manager that uses this library behind the scenes.
173
+
174
+ '
171
175
  email:
172
176
  - kigster@gmail.com
173
177
  executables: []
@@ -187,11 +191,11 @@ files:
187
191
  - lib/arduino/library.rb
188
192
  - lib/arduino/library/database.rb
189
193
  - lib/arduino/library/default_database.rb
194
+ - lib/arduino/library/finder.rb
190
195
  - lib/arduino/library/include.rb
191
196
  - lib/arduino/library/instance_methods.rb
192
197
  - lib/arduino/library/model.rb
193
198
  - lib/arduino/library/presenters/properties.rb
194
- - lib/arduino/library/resolver.rb
195
199
  - lib/arduino/library/types.rb
196
200
  - lib/arduino/library/utilities.rb
197
201
  - lib/arduino/library/version.rb
@@ -218,8 +222,10 @@ rubyforge_project:
218
222
  rubygems_version: 2.6.11
219
223
  signing_key:
220
224
  specification_version: 4
221
- summary: This gem encapsulates many concepts related to how Arduino Libraries are
222
- indexed, how their metadata is validated, or .properties file generated. It supports
223
- searching the Arduino library database for any terms. This gem is used by Arli —
224
- Arduino Installer CLI toolkit.
225
+ summary: This library provides a convenient ruby API for representation of an Arduino
226
+ Library specification, including field and type validation, reading and writing
227
+ the library.properties file, as well as downloading the official database of Arduino
228
+ libraries, and offering a highly advanced searching functionality. This gem only
229
+ offers Ruby API, but for command line usage please checkout the gem called "arli"
230
+ — Arduino Library Dependency Manager that uses this library behind the scenes.
225
231
  test_files: []