arduino-library 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2d37473a87d3b6d1db40f35624c2c797529da16c
4
+ data.tar.gz: 3c8df8283d9c010ef9602ce81e93d892bb7bfcac
5
+ SHA512:
6
+ metadata.gz: 2c2f9b036d4cd3bd906456ec6fcb1282545eedfc93d4de06ad49938cc2f5d78e6f6b07aad1b769d1e7575ad13a9b370a7e85dad46d1ae8b1561ac0e5c033fa56
7
+ data.tar.gz: 46a370bc44c4e21a15a12d90ddbd6c50e6104843a65b68b7d79d9810576347aee88540dc0824e0856724540b29fffbff6f5bff49f211fb873f6e0b704dadc35c
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ .idea/
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /doc/
7
+ /pkg/
8
+ /coverage/
9
+ /spec/coverage/
10
+ /tmp/
11
+ /data
12
+ /spec/coverage/
13
+ /*.enc
14
+ **/.DS_Store
15
+ .ruby-version
16
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format progress
2
+ --color
3
+ --order random
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ sudo: false
2
+ env:
3
+ global:
4
+ - CI=TRAVIS
5
+ - CC_TEST_REPORTER_ID=0e339f5c9d1bbcceab27065342b2e22535bb469bd083a6f44ddb8a262f71f8a4
6
+ language: ruby
7
+ rvm:
8
+ - 2.4.2
9
+ - 2.3.5
10
+ before_install:
11
+ - gem install bundler -v 1.15.4
12
+ before_script:
13
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
+ - chmod +x ./cc-test-reporter
15
+ - ./cc-test-reporter before-build
16
+ script:
17
+ - bundle exec rspec --format documentation
18
+ after_script:
19
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Konstantin Gredeskoul
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,233 @@
1
+ [![Gem Version](https://badge.fury.io/rb/arduino-library.svg)](https://badge.fury.io/rb/arduino-library)
2
+ [![Build Status](https://travis-ci.org/kigster/arduino-library.svg?branch=master)](https://travis-ci.org/kigster/arduino-library)
3
+ [![Maintainability](https://api.codeclimate.com/v1/badges/0da01eba1b556826a231/maintainability)](https://codeclimate.com/github/kigster/arduino-library/maintainability)
4
+ [![Downloads](http://ruby-gem-downloads-badge.herokuapp.com/arduino-library?type=total)](https://rubygems.org/gems/arduino-library)
5
+
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/0da01eba1b556826a231/test_coverage)](https://codeclimate.com/github/kigster/arduino-library/test_coverage)
7
+ [![Test Coverage](https://codeclimate.com/github/kigster/arduino-library/badges/coverage.svg)](https://codeclimate.com/github/kigster/arduino-library/coverage)
8
+
9
+ # Arduino::Library
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.
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.
14
+
15
+ It also provides validation functionality for the `library.properties` file for your custom libraries you would like to open source.
16
+
17
+
18
+ ## Installation
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ ```ruby
23
+ gem 'arduino-library'
24
+ ```
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install arduino-library
33
+
34
+ ## Usage
35
+
36
+ Current version only contains Ruby-based API and is meant to be consumed by other projects (in particularly, check out [Arli](https://github.com/kigster/arli) — a command-line tool and an Arduino Library Manager and installer). This project is invaluable if you are you using, for example, [arduino-cmake](https://github.com/arduino-cmake/arduino-cmake) project to build and upload your Arduino Code.
37
+
38
+
39
+ ### Using the top-level module
40
+
41
+ If you prefer not to have hard-coded dependencies on the `Arduino::Library::*` sub-classes and sub-modules, you can use the top level module, which proxies several shortcut methods.
42
+
43
+ You can access these methods in two different ways:
44
+
45
+ 1. As class methods on `Arduino::Library`, for example `Arduino::Library.db_default`
46
+ 2. By including the top-level module in your context, and using methods as instance methods in the current context, eg. `#db_default`
47
+
48
+ Below we'll focus on the second usage, but if you prefer to use the first syntax, it's there and available for you.
49
+
50
+ ```ruby
51
+ require 'arduino/library'
52
+ include Arduino::Library
53
+ ```
54
+
55
+ #### Using `db_from`
56
+
57
+ This method returns an instance of the `Arduino::Library::Database` from the provided source:
58
+
59
+ ```ruby
60
+ db_from('library_index.json').size
61
+ # => 16
62
+ db_from('library_index.json.gz').size
63
+ # => 16
64
+ db_from('http://downloads.arduino.cc/libraries/library_index.json.gz').size
65
+ # => 3653
66
+ # This required downloading a 400K gzipped file into a temp file, and reading from there.
67
+ ```
68
+
69
+ #### Using `db_default`
70
+
71
+ This method downloads and returns the official Arduino-maintained index of Arduino libraries.
72
+
73
+ ```ruby
74
+ db_default.size
75
+ # => 3653
76
+ ```
77
+
78
+ #### Using `library_from`
79
+
80
+ This method reads from a source that can be of many formats (see below) and returns an instantiated `Arduino::Library::Model` for this library. You can then get all library attributes via corresponding methods:
81
+
82
+ ```ruby
83
+ library_from('spec/fixtures/audio_zero.json').name
84
+ # => 'AudioZero'
85
+ library_from('~/Documents/Arduino/Libraries/AudioZero/library.properties').name
86
+ #=> 'AudioZero'
87
+ library_from('https://raw.githubusercontent.com/PaulStoffregen/DS1307RTC/master/library.properties').name
88
+ #=> 'DS1307RTC'
89
+ ```
90
+
91
+ #### Using `find`
92
+
93
+ Method `find` 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.
94
+
95
+ The method has the following signature:
96
+
97
+ ```ruby
98
+ find(database = db_default, **opts)
99
+ ```
100
+
101
+ `opts` is a Hash that you can use to pass attributes with matchers. All matching results are returned as an array of models.
102
+
103
+ **Examples**
104
+
105
+ ```ruby
106
+ results = find(
107
+ name: 'AudioZero',
108
+ author: /konstantin/i, # regexp supported
109
+ architectures: [ 'avr' ], # array is matched if it's a subset
110
+ version: proc do |value| # or a proc for max flexibility
111
+ value.start_with?('1.')
112
+ end
113
+ )
114
+
115
+ results.size
116
+ #=> <whatever number of matches returned>
117
+ ```
118
+
119
+ Note that multiple attributes must ALL match for the library to be included in the result set.
120
+
121
+ ### `Arduino::Library::Database`
122
+
123
+ > Downloading the index of all libraries, and finding a library.
124
+
125
+ You can load libraries from a local JSON file, or from a remote URL, eg:
126
+
127
+ ```ruby
128
+ require 'arduino/library'
129
+
130
+ database = Arduino::Library::Database.from(
131
+ 'http://downloads.arduino.cc/libraries/library_index.json.gz')
132
+ ```
133
+
134
+ or, since the above link happens to be the default location of Arduino-maintained librarie index file, you can use the `default` method instead:
135
+
136
+ ```ruby
137
+ database = Arduino::Library::Database.default
138
+ ```
139
+
140
+ or, load the list from a local JSON file, that can be optionally gzipped (just like the URL):
141
+
142
+ ```ruby
143
+ database = Arduino::Library::Database.from('library_index.json.gz')
144
+ ```
145
+
146
+ Once the library is initialized, the following operations are supported:
147
+
148
+ ```ruby
149
+ database.find(name: 'AudioZero', version: '1.0.1') do |audio_zero|
150
+ audio_zero.website #=> http://arduino.cc/en/Reference/Audio
151
+ audio_zero.architectures #=> [ 'samd' ]
152
+ end
153
+ ```
154
+
155
+ You can pass any of the attributes to #find, and the value can be a `String` (in which case only equality matches), or a regular expression, eg:
156
+
157
+ ```ruby
158
+ database.find(author: "Paul Stoffregen").size #=> 21
159
+ database.find(author: /stoffregen/i).size #=> 33
160
+ ```
161
+
162
+ You interate over multiple using either a block:
163
+
164
+ ```ruby
165
+ database.find(name: 'AudioZero') do |match|
166
+ puts match.name # => 'AudioZero'
167
+ puts match.version # => will print all versions of the library available
168
+ end
169
+ ```
170
+
171
+ or, just grab the return value from `#find`, which is always an array.
172
+
173
+ ```ruby
174
+ all_versions = database.find(name: 'AudioZero')
175
+ # => [ Arduino::Library::Model<name: AudioZero, version: '1.0.1',... >, .. ]
176
+ ```
177
+
178
+ ### `Arduino::Library::Model`
179
+
180
+ > Use this class to operate on a single library.
181
+
182
+ #### Reading Library from an External Source using `.from`
183
+
184
+ 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.
185
+
186
+ For example, to read from a JSON file:
187
+
188
+ ```ruby
189
+ json_file = 'spec/fixtures/audio_zero.json'
190
+ model = Arduino::Library::Model.from(json_file)
191
+ model.name #=> 'AudioZero'
192
+ ```
193
+
194
+ Or to read from the `.properties` file:
195
+
196
+ ```ruby
197
+ properties_file = 'spec/fixtures/audio_zero.properties'
198
+ model = Arduino::Library::Model.from(properties_file)
199
+ model.name #=> 'AudioZero'
200
+ ```
201
+
202
+ ### Presenters
203
+
204
+ Presenters are there to convert to and from a particular format.
205
+
206
+ #### `.properties` Presenter
207
+
208
+ ```ruby
209
+ props = Arduino::Library::Presenters::Properties.new(model).present
210
+ File.open('/tmp/audio_zero.properties', 'w') do |f|
211
+ f.write(props)
212
+ end
213
+
214
+ # this creates a file in the format:
215
+
216
+ # name=AudioZero
217
+ # version=1.0.1
218
+ # etc.
219
+ ```
220
+
221
+ ## Development
222
+
223
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
224
+
225
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
226
+
227
+ ## Contributing
228
+
229
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/kigster/arduino-library](https://github.com/kigster/arduino-library).
230
+
231
+ ## License
232
+
233
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'arduino/library/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'arduino-library'
8
+ spec.version = Arduino::Library::VERSION
9
+ spec.authors = ['Konstantin Gredeskoul']
10
+ spec.email = ['kigster@gmail.com']
11
+ spec.summary = Arduino::Library::DESCRIPTION
12
+ spec.description = Arduino::Library::DESCRIPTION
13
+ spec.homepage = 'https://github.com/kigster/arduino-library'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_dependency 'dry-configurable'
25
+ spec.add_dependency 'dry-types'
26
+ spec.add_dependency 'dry-struct'
27
+
28
+ spec.add_development_dependency 'simplecov'
29
+ spec.add_development_dependency 'bundler', '~> 1.15'
30
+ spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'rspec', '~> 3.0'
32
+ spec.add_development_dependency 'rspec-its'
33
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "arduino/library"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,55 @@
1
+ require 'open-uri'
2
+
3
+ module Arduino
4
+ module Library
5
+ DEFAULT_ARDUINO_LIBRARY_INDEX_URL = 'http://downloads.arduino.cc/libraries/library_index.json.gz'
6
+ end
7
+ end
8
+
9
+ require 'arduino/library/version'
10
+ require 'arduino/library/utilities'
11
+ require 'arduino/library/types'
12
+ # noinspection RubyResolve
13
+ require 'arduino/library/model'
14
+ require 'arduino/library/database'
15
+
16
+ module Arduino
17
+ module Library
18
+ # @param [String] file_or_url — either a local file, or URL, can be gzipped
19
+ def db_from(file_or_url)
20
+ Database.new(file_or_url)
21
+ end
22
+
23
+ def db_default
24
+ Database.default
25
+ end
26
+
27
+ #
28
+ # +file_or_url+ can be a JSON file name, a .properties file name, or
29
+ # a URL to either of the above.
30
+ #
31
+ # @param [String] file_or_url
32
+ def library_from(file_or_url)
33
+ Arduino::Library::Model.from(file_or_url)
34
+ end
35
+
36
+ # +opts+ is a Hash that you can use to pass attributes with values, any
37
+ # number of them. All matching results are returned as models.
38
+ #
39
+ # name: 'AudioZero'
40
+ # author: /konstantin/i - regexp supported
41
+ # architectures: [ 'avr' ] - array is matched if it's a subset
42
+ # version: proc do |value| — or a proc for max flexibility
43
+ # value.start_with?('1.') )
44
+ # end
45
+ #
46
+ # @param [Hash] opts — hash of attribute names and values to match
47
+ def find(database = db_default, **opts)
48
+ Arduino::Library::Model.database = database
49
+ Arduino::Library::Model.from(nil, **opts)
50
+ end
51
+ end
52
+ end
53
+
54
+ Arduino::Library.extend(Arduino::Library)
55
+
@@ -0,0 +1,82 @@
1
+ require 'open-uri'
2
+ require 'zlib'
3
+ require 'json'
4
+ require 'forwardable'
5
+ require 'arduino/library'
6
+ require 'arduino/library/model'
7
+
8
+ module Arduino
9
+ module Library
10
+
11
+ # This class represents a single entry into the library-index.json file,
12
+ # in other words — a `library.properties` file.
13
+ class Database
14
+ extend Forwardable
15
+ include Utilities
16
+
17
+ def_delegators :@db_list, *(Array.new.methods - Object.methods)
18
+
19
+ class << self
20
+ alias from new
21
+
22
+ def default
23
+ @default ||= new
24
+ end
25
+ end
26
+
27
+ attr_accessor :local_file,
28
+ :db_list
29
+
30
+ def initialize(file_or_url = Arduino::Library::DEFAULT_ARDUINO_LIBRARY_INDEX_URL)
31
+ self.local_file = read_file_or_url(file_or_url)
32
+ load_json
33
+ end
34
+
35
+ # Usage: find(attr1: value, attr2: /regexp/, ... )
36
+ def find(**opts)
37
+ limit = opts[:limit]
38
+ opts.delete(:limit)
39
+ match_list = []
40
+
41
+ db_list.find do |entry|
42
+ matches = entry_matches?(entry, opts)
43
+ match_list << entry if matches
44
+ break if limit && match_list.size >= limit
45
+ end
46
+
47
+ match_list.each { |entry| yield(entry) } if block_given?
48
+ match_list
49
+ end
50
+
51
+ private
52
+
53
+ def entry_matches?(entry, opts)
54
+ matches = true
55
+ opts.each_pair do |attr, check|
56
+ value = entry.send(attr)
57
+ matches &= case check
58
+ when String
59
+ value == check
60
+ when Regexp
61
+ value =~ check
62
+ when Array
63
+ value = value.split(',') unless value.is_a?(Array)
64
+ value.eql?(check) || value.include?(check) || value.first == '*'
65
+ when Proc
66
+ check.call(value)
67
+ else
68
+ raise InvalidArgument, "Class #{check.class.name} is unsupported for value checks"
69
+ end
70
+ break unless matches
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def load_json
77
+ hash = JSON.load(local_file.read)
78
+ self.db_list = hash['libraries'].map { |lib| Model.from_hash(lib) }
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,104 @@
1
+ require_relative 'types'
2
+ require_relative 'utilities'
3
+ require 'json'
4
+
5
+ module Arduino
6
+ module Library
7
+ # This class represents a single entry into the library-index.json file,
8
+ # in other words — a `library.properties` file.
9
+ class Model < Dry::Struct
10
+
11
+ # noinspection RubyResolve
12
+ constructor_type :symbolized
13
+
14
+ Types::LIBRARY_PROPERTIES.each_pair do |field, type|
15
+ self.attribute field, eval(type)
16
+ end
17
+
18
+ class << self
19
+ include Utilities
20
+
21
+ attr_writer :database
22
+
23
+ def from_hash(hash)
24
+ new(Types.schema[hash])
25
+ end
26
+
27
+ def from_json(json)
28
+ from_hash(JSON.load(json))
29
+ end
30
+
31
+ def from_json_file(file_or_url)
32
+ file = read_file_or_url(file_or_url)
33
+ from_json(file.read)
34
+ end
35
+
36
+ def from_properties_file(file_or_url)
37
+ raise "File #{file_or_url} does not exist?" unless File.exist?(file_or_url)
38
+ Presenters::Properties.from(file_or_url)
39
+ end
40
+
41
+ def database
42
+ @database ||= Database.default
43
+ end
44
+
45
+ def find(**opts)
46
+ database.find(**opts)
47
+ end
48
+
49
+ # @param [Object] source — file name or a URL to JSON or .properties file
50
+ #
51
+ # ## Searching
52
+ #
53
+ # #### Database
54
+ #
55
+ # Searching requires a database, which can either be set via
56
+ #
57
+ # Arduino::Library::Model.database = Database.from(file)
58
+ #
59
+ # otherwise it defaults to the default database, +Database.default+.
60
+ #
61
+ # @param [Hash] opts — search parameters to the current database
62
+ #
63
+ # #### Query
64
+ #
65
+ # +opts+ is a Hash that you can use to pass attributes with values, any
66
+ # number of them. All matching results are returned as models from the
67
+ # current database.
68
+ #
69
+ # name: 'AudioZero'
70
+ # author: /konstantin/i - regexp supported
71
+ # architectures: [ 'avr' ] - array is matched if it's a subset
72
+ # version: proc do |value| — or a proc for max flexibility
73
+ # value.start_with?('1.') )
74
+ # ends
75
+ #
76
+ # @return [Model | Array<Model> ] — array for search, otherwise a model
77
+ def from(source = nil, **opts)
78
+ case source
79
+ when Hash
80
+ from_hash(source)
81
+ when String
82
+ if source =~ /^{/m
83
+ from_json(source)
84
+ elsif File.exist?(source)
85
+ if source =~ /\.json(\.gz)?$/i
86
+ from_json_file(source)
87
+ elsif source =~ /\.properties(\.gz)?$/i
88
+ from_properties_file(source)
89
+ end
90
+ end
91
+ when NilClass
92
+ if opts && opts[:name] && opts[:version]
93
+ find(**opts)
94
+ end
95
+ end
96
+ end
97
+
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ require_relative 'presenters/properties'
@@ -0,0 +1,63 @@
1
+ require 'arduino/library/types'
2
+ require 'arduino/library/model'
3
+
4
+ module Arduino
5
+ module Library
6
+ module Presenters
7
+ class Properties < Struct.new(:model)
8
+ class << self
9
+ include ::Arduino::Library::Utilities
10
+ # Class method, that reads a properties file and returns a properly
11
+ # validated Arduino::Library::Model instance.
12
+ def from(file_or_url)
13
+ file = read_file_or_url(file_or_url)
14
+ props = file.read.split(/\n/)
15
+ hash = {}
16
+ props.each do |line|
17
+ attr, value = line.split('=')
18
+ attr = attr.to_sym
19
+ if Types::ARRAY_ATTRIBUTES.include?(attr)
20
+ hash[attr] = value.split(',')
21
+ else
22
+ hash[attr] = value
23
+ end
24
+ end
25
+ ::Arduino::Library::Model.from_hash(hash)
26
+ end
27
+ end
28
+
29
+ attr_accessor :presented
30
+
31
+ def initialize(*args)
32
+ super(*args)
33
+ self.presented = ''
34
+ end
35
+
36
+ # Primary instance method, returns a string representing a
37
+ # library.properties format file, using the model.
38
+ # The presented value is cached in the #presented public instance
39
+ # variable.
40
+ def present
41
+ Types::LIBRARY_PROPERTIES.keys.each do |attr|
42
+ attribute_presenter(attr)
43
+ end
44
+ presented
45
+ end
46
+
47
+ private
48
+
49
+ def attribute_presenter(attr)
50
+ value = model.send(attr) if model && model.respond_to?(attr)
51
+ return unless value
52
+ if value.is_a?(Array)
53
+ self.presented << "#{attr}=#{model.send(attr).join(',')}\n"
54
+ else
55
+ self.presented << "#{attr}=#{model.send(attr)}\n"
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,109 @@
1
+ require 'dry-types'
2
+ require 'dry-struct'
3
+ require 'uri'
4
+
5
+ module Arduino
6
+ module Library
7
+ module Types
8
+ include Dry::Types.module
9
+
10
+ Name = String.constrained format: /^[A-Za-z_.-][A-Za-z0-9 _.-]*[A-Za-z0-9_.-]$/
11
+ Version = String.constrained format: /[0-9]+\.[0-9]+(\.[0-9]+)?/
12
+
13
+ Url = String.constrained format: URI::regexp(%w(http https))
14
+
15
+ Category = String.enum('Display',
16
+ 'Signal Input/Output',
17
+ 'Communication',
18
+ 'Sensors',
19
+ 'Device Control',
20
+ 'Timing',
21
+ 'Data Storage',
22
+ 'Data Processing',
23
+ 'Other')
24
+
25
+ Architecture = String.enum(
26
+ '*',
27
+ 'AVR',
28
+ 'ESP8266',
29
+ 'FP51',
30
+ 'OpenBCI 32',
31
+ 'RFduino',
32
+ 'SAM',
33
+ 'SAMD',
34
+ 'STM32F1',
35
+ 'Simblee',
36
+ 'Simula',
37
+ 'all',
38
+ 'ameba',
39
+ 'arc32',
40
+ 'arm',
41
+ 'atmelavr',
42
+ 'avr',
43
+ 'esp32',
44
+ 'esp8266',
45
+ 'nRF5',
46
+ 'nRF51822',
47
+ 'nRF52832',
48
+ 'nrf52',
49
+ 'pic32',
50
+ 'rtl8195a',
51
+ 'sam',
52
+ 'samd',
53
+ 'simblee',
54
+ 'stm32',
55
+ 'stm32f4',
56
+ 'teensy',
57
+ 'tiny')
58
+
59
+ LibraryTypes = String.enum(
60
+ 'Arduino',
61
+ 'Contributed',
62
+ 'Partner',
63
+ 'Recommended',
64
+ 'Retired'
65
+ )
66
+
67
+ FileName = String.constrained(
68
+ format: /[a-zA-Z0-9_=.:]+/
69
+ )
70
+
71
+ Checksum = String.constrained(
72
+ format: /SHA-256:[0-9a-fA-F]{64}/
73
+ )
74
+
75
+ StringField = Coercible::String
76
+
77
+ LIBRARY_PROPERTIES = {
78
+ name: 'Types::String',
79
+ version: 'Types::String',
80
+ author: 'Types::String',
81
+ maintainer: 'Types::String',
82
+ sentence: 'Types::String',
83
+ paragraph: 'Types::String',
84
+ website: 'Types::Url',
85
+ category: 'Types::Category',
86
+ architectures: 'Types::Json::Array.member(Types::Architecture)',
87
+ types: 'Types::Json::Array.member(Types::LibraryTypes)',
88
+ url: 'Types::Url',
89
+ archiveFileName: 'Types::FileName',
90
+ size: 'Types::Coercible::Int',
91
+ checksum: 'Types::Checksum',
92
+ dot_a_linkage: 'Types::Bool.optional',
93
+ includes: 'Types::Json::Array.member(Types::FileName).optional',
94
+ }.freeze
95
+
96
+ ARRAY_ATTRIBUTES = LIBRARY_PROPERTIES.keys.select { |k| LIBRARY_PROPERTIES[k] =~ /Array/ }
97
+
98
+ class << self
99
+ attr_accessor :schema
100
+ end
101
+
102
+ # Let's keep the original hash intact; otherwise dry-struct munges it.
103
+ hash = LIBRARY_PROPERTIES.dup
104
+ hash.each { |attribute, type| hash[attribute] = eval(type) }
105
+
106
+ self.schema = Types::Hash.symbolized(hash)
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,19 @@
1
+ require 'open-uri'
2
+
3
+ module Arduino
4
+ module Library
5
+
6
+ module Utilities
7
+ def read_file_or_url(file_or_url)
8
+ raise ArgumentError, 'Empty file_or_url provided' unless file_or_url
9
+ temp_file = open(file_or_url)
10
+ if file_or_url =~ /\.gz$/i
11
+ Zlib::GzipReader.new(temp_file)
12
+ else
13
+ temp_file
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ module Arduino
2
+ module Library
3
+ VERSION = '0.3.0'
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.
6
+ eof
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,179 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arduino-library
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Gredeskoul
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dry-configurable
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dry-types
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: dry-struct
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.15'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.15'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-its
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: " This gem encapsulates many concepts related to how Arduino Libraries
126
+ are indexed, how their metadata is validated, or .properties file generated. It
127
+ supports searching the Arduino library database for any terms. This gem is used
128
+ by Arli — Arduino Installer CLI toolkit.\n"
129
+ email:
130
+ - kigster@gmail.com
131
+ executables: []
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - ".rspec"
137
+ - ".travis.yml"
138
+ - Gemfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - arduino-library.gemspec
143
+ - bin/console
144
+ - bin/setup
145
+ - lib/arduino/library.rb
146
+ - lib/arduino/library/database.rb
147
+ - lib/arduino/library/model.rb
148
+ - lib/arduino/library/presenters/properties.rb
149
+ - lib/arduino/library/types.rb
150
+ - lib/arduino/library/utilities.rb
151
+ - lib/arduino/library/version.rb
152
+ homepage: https://github.com/kigster/arduino-library
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.6.11
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: This gem encapsulates many concepts related to how Arduino Libraries are
176
+ indexed, how their metadata is validated, or .properties file generated. It supports
177
+ searching the Arduino library database for any terms. This gem is used by Arli —
178
+ Arduino Installer CLI toolkit.
179
+ test_files: []