arli 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +79 -52
- data/arli.gemspec +1 -0
- data/docs/arli-full.png +0 -0
- data/docs/arli-in-action.png +0 -0
- data/lib/arli/actions.rb +0 -1
- data/lib/arli/actions/action.rb +41 -1
- data/lib/arli/actions/dir_name.rb +21 -14
- data/lib/arli/actions/git_repo.rb +2 -6
- data/lib/arli/actions/zip_file.rb +2 -8
- data/lib/arli/arli_file.rb +16 -11
- data/lib/arli/cli/app.rb +3 -1
- data/lib/arli/cli/parser.rb +46 -11
- data/lib/arli/cli/parser_factory.rb +26 -7
- data/lib/arli/commands/install.rb +4 -2
- data/lib/arli/commands/search.rb +1 -1
- data/lib/arli/configuration.rb +2 -2
- data/lib/arli/installer.rb +1 -1
- data/lib/arli/output.rb +15 -6
- data/lib/arli/version.rb +1 -1
- metadata +18 -3
- data/lib/arli/actions/backup.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1457403161e523852f76082f9c5549abcaeb4277
|
4
|
+
data.tar.gz: 9835a1952e3a3baf19ff0e795d71851b9c4d7bab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0478e06f8baf8e6a71591128d917947d3017d118c3ff231edd0c0d63e1167134912c8cc950409c6dcdc0803bd1a8525bd932ab64d60285c1f708eea68cf06e0
|
7
|
+
data.tar.gz: 3a1498015f130059065f2c21fb3fb11eb12316579a082d73d3c6ea2144780497909b6b801ae16256093f9a66f7efb4f82ff9a4107efca54a56411bf0d53d4269
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -5,24 +5,61 @@
|
|
5
5
|
|
6
6
|
# Arli
|
7
7
|
|
8
|
-
Arli is
|
9
|
-
|
8
|
+
Arli is an awesomely simple and very easy to use Arduino Library Installer. It allows your Arduino projects to be portable by including a small text file called `Arlifile` that defines your project's Arduino library dependencies. Using either this file, or command line flags, Arli is able to search for libraries, install them locally to a custom location, and do it all consistently and reliably.
|
9
|
+
|
10
|
+
That way you can share projects with others and they will be able to automatically download and install the dependent libraries instead of having to do that manually. The project is inspired by [Bundler](http://bundler.io/).
|
11
|
+
|
12
|
+
Here is a screenshot of running `arli install` inside a project with the `Arlifile` that defines all of it's library dependencies into a local project folder `./libraries`:
|
13
|
+
|
14
|
+
![](docs/arli-in-action.png)
|
15
|
+
|
16
|
+
|
17
|
+
## Overview
|
18
|
+
|
19
|
+
### How Does It Work?
|
20
|
+
|
21
|
+
In a nutshell, Arli relies on the publicly available database of the vast majority of public Ardiuino libraries. This database is maintained by Arduino themselves, and is a [giant gzipped JSON file](http://downloads.arduino.cc/libraries/library_index.json.gz). Arli automatically downloads and caches the index on a local file system, and then lets you search and install libraries using either a simple name search, or more sophisticated ruby-like syntax that supports searching for ANY attribute as an equal match, or a regular expressions, or even a [Proc](http://ruby-doc.org/core-2.4.2/Proc.html).
|
22
|
+
|
23
|
+
Sometimes, however, an Arduino library you use may not part of the main database. No problem! Just add the `url:` attribute together with the library name. The URL can either be a Github URL, or a URL to a downloadable ZIP file. Arli will figure out the rest.
|
24
|
+
|
25
|
+
### Arlifile
|
26
|
+
|
27
|
+
`Arlifile` is a YAML-formatted file that looks like this below. We list all dependencies using the library names that are provided in the database (you can search for the libraries you need prior to populating this file):
|
28
|
+
|
10
29
|
|
11
30
|
```yaml
|
12
31
|
# vi:syntax=yaml
|
32
|
+
# File: Arlifile
|
13
33
|
version: 1.0.0
|
14
34
|
dependencies:
|
15
35
|
- name: Time
|
16
36
|
- name: "Adafruit GFX Library"
|
37
|
+
version: '1.2.1'
|
17
38
|
- name: SimpleTimer
|
18
39
|
url: https://github.com/jfturcot/SimpleTimer
|
19
40
|
```
|
20
41
|
|
21
|
-
The libraries may be specified with a name and url only
|
42
|
+
The libraries may be specified with a name and url only, in which case no search is performed, and the provided URL is used to install the library. The library `SimpleTimer` above is not in the main database, therefore we provide URL for Arli to use.
|
43
|
+
|
44
|
+
If the URL is not provided, you can specify one of several fields that are searched for a matching library. Remember, in this case Arli must find one and only one library to install, otherwise it will throw an error.
|
45
|
+
|
46
|
+
You can provide the following fields in the Arilfile if you want the library to be installed from the central database:
|
22
47
|
|
23
|
-
|
48
|
+
* `name` should be the exact match. Use double quotes if the name contains spaces.
|
49
|
+
* `version` can be used together with the `name` to specify a particular version. Without this field, and if the `name` is provided, the latest version is used.
|
50
|
+
* `checksum` and `archiveFileName` can be used as they both uniquely identify a library.
|
24
51
|
|
25
|
-
|
52
|
+
In all of the above cases, Arli will search the standard library database provided by the [Arduino official library database](http://downloads.arduino.cc/libraries/library_index.json.gz) JSON file.
|
53
|
+
|
54
|
+
### Single Library Install
|
55
|
+
|
56
|
+
You can also install just a single library by passing `--name` flag (`-n`), for example:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
arli install --name 'Adafruit GFX Library'
|
60
|
+
```
|
61
|
+
|
62
|
+
## Gem Installation
|
26
63
|
|
27
64
|
Install the `arli` ruby gem as follows:
|
28
65
|
|
@@ -37,38 +74,44 @@ $ gem install arli
|
|
37
74
|
Run `arli --help` for more information:
|
38
75
|
|
39
76
|
```bash
|
40
|
-
|
77
|
+
Usage:
|
41
78
|
arli [ options ] [ command [ options ] ]
|
42
79
|
|
43
80
|
-D, --debug Print debugging info.
|
44
81
|
-t, --trace Print exception stack traces.
|
45
82
|
-v, --verbose Print more information.
|
83
|
+
-q, --quiet Print less information.
|
46
84
|
-V, --version Print current version and exit
|
47
85
|
-h, --help prints this help
|
48
86
|
|
49
87
|
Available Commands:
|
50
|
-
install — installs libraries defined in Arlifile
|
88
|
+
install — installs libraries defined in Arlifile or by -n flag
|
51
89
|
search — Flexible Search of the Arduino Library Database
|
52
90
|
|
53
91
|
See arli command --help for more information on a specific command.
|
92
|
+
|
93
|
+
arli (0.6.1) © 2017 Konstantin Gredeskoul, MIT License.
|
54
94
|
```
|
55
95
|
|
56
|
-
|
96
|
+
### Command `install`
|
57
97
|
|
58
|
-
Use this command to install or re-install libraries.
|
98
|
+
Use this command to install or re-install Arduino libraries.
|
59
99
|
|
60
|
-
You can specify libraries in the `Arlifile` by providing
|
100
|
+
You can specify libraries in the `Arlifile` by providing just the `name:` (and posibly `version`) — the name must match exactly a library in the Arduino standard database. Alternatively, your can pass fields `archiveFileName`, `checksum` — which all uniquely identify a library in the database.
|
61
101
|
|
62
|
-
|
102
|
+
If a library you are using is not in the public database just provide its `name` and the `url` fields. The URL can either be a git URL, or a downloadable ZIP file. Arli will use the `url` field if it's available without trying to search for the library elsewhere.
|
63
103
|
|
104
|
+
#### Automatic Folder Name Correction
|
64
105
|
|
65
|
-
|
106
|
+
Arli understands that the folder where the library is installed must be named correctly: in other words, **folder name must match the header file inside of the folder** for the library to be found.
|
66
107
|
|
67
|
-
Arli
|
108
|
+
When Arli downloads libraries in ZIP format, they are unpacked into folder that are named differently. Arli will then search that folder for the source and header files. The name of the directory is then compared to the files found, and in some cases Arli will automatically **rename the library folder to match the main header file.**.
|
68
109
|
|
69
|
-
For example, 'Adafruit GFX Library' is the proper name of
|
110
|
+
> For example, 'Adafruit GFX Library' is the proper name of a corresponding library, and it's ZIP archive will unpack into a folder named `Adafruit_GFX_Library-1.4.3`. Arli will then detect that the header file inside the folder is `Adafruit_GFX.h`. In this case Arli will rename the top-level folder to `Adafruit_GFX`, and make the library valid, and its folder easily found.
|
111
|
+
>
|
112
|
+
> This is an audacious attempt to make sense of the chaos that is the Arduino Library world.
|
70
113
|
|
71
|
-
|
114
|
+
#### An Example
|
72
115
|
|
73
116
|
Here is the `arli install` command inside CMake-based project to build a [Wall Clock using Arduino](https://github.com/kigster/wallclock-arduino). This project has the following `Arlifile`:
|
74
117
|
|
@@ -89,48 +132,26 @@ dependencies:
|
|
89
132
|
|
90
133
|
You can see that most libraries are specified by name, except one (SimpleTimer) is specified together with the URL, which will be used to `git clone` the library.
|
91
134
|
|
92
|
-
So let's specify where our libraries live, and run `arli install` inside that project:
|
135
|
+
So let's specify where our libraries live, and run `arli install` inside that project. Below is a screenshot of running `arli` inside of the Wall Clock Arduino project:
|
93
136
|
|
94
|
-
|
95
|
-
❯ export ARDUINO_CUSTOM_LIBRARY_PATH=~/Documents/Arduino/libraries/
|
96
|
-
❯ cd skethes/wallclock-arduino
|
97
|
-
❯ arli install
|
98
|
-
Adafruit GFX Library (1.2.2) ....... (Adafruit_GFX)
|
99
|
-
DS1307RTC (1.4.0) ......
|
100
|
-
Adafruit LED Backpack Library (1.1.6) ....... (Adafruit_LEDBackpack)
|
101
|
-
Adafruit Unified Sensor (1.0.2) ....... (Adafruit_Sensor)
|
102
|
-
DHT sensor library (1.3.0) ....... (DHT)
|
103
|
-
OneButton (1.2.0) .......
|
104
|
-
SimpleTimer running git clone -v https://github.com/jfturcot/SimpleTimer.git ~/Documents/Arduino/libraries/SimpleTimer 2>&1 .
|
105
|
-
s (1.5.0) ......
|
106
|
-
```
|
137
|
+
![](docs/arli-in-action.png)
|
107
138
|
|
108
|
-
Now, we can inspect the library folder and observe that all of the specified libraries have been installed, and into correct folders:
|
109
|
-
|
110
|
-
```bash
|
111
|
-
❯ ls -1 ~/Documents/Arduino/libraries
|
112
|
-
Adafruit_GFX
|
113
|
-
DS1307RTC
|
114
|
-
Adafruit_LEDBackpack
|
115
|
-
Adafruit_Sensor
|
116
|
-
DHT
|
117
|
-
OneButton
|
118
|
-
SimpleTimer
|
119
|
-
Time
|
120
|
-
```
|
121
139
|
|
122
|
-
Below is the complete help for the install command:
|
140
|
+
Below is the complete help for the install command for reference:
|
123
141
|
|
124
142
|
|
125
143
|
```bash
|
126
144
|
Description:
|
127
|
-
installs libraries defined in Arlifile
|
145
|
+
installs libraries defined in Arlifile or by -n flag
|
128
146
|
|
129
147
|
Usage:
|
130
148
|
arli install [options]
|
131
149
|
|
132
150
|
Command Options
|
133
|
-
-
|
151
|
+
-n, --name NAME If provided a library name is searched and, if found
|
152
|
+
installed. In this mode Arlifile not used.
|
153
|
+
|
154
|
+
-l, --libraries PATH Local folder where custom Arduino libraries are installed
|
134
155
|
Defaults to ~/Dropbox/Workspace/oss/arduino/libraries
|
135
156
|
|
136
157
|
-a, --arli-path PATH Folder where Arlifile is located,
|
@@ -143,25 +164,33 @@ Command Options
|
|
143
164
|
-D, --debug Print debugging info.
|
144
165
|
-t, --trace Print exception stack traces.
|
145
166
|
-v, --verbose Print more information.
|
167
|
+
-q, --quiet Print less information.
|
146
168
|
-V, --version Print current version and exit
|
147
169
|
-h, --help prints this help
|
170
|
+
|
171
|
+
Examples:
|
172
|
+
# Install all libs defined in the ./Arlifile file
|
173
|
+
arli install
|
174
|
+
|
175
|
+
# Install a single library matched by the --name flag
|
176
|
+
arli install -n "Adafruit GFX Library"```
|
148
177
|
```
|
149
178
|
|
150
|
-
|
179
|
+
### Command `search`
|
151
180
|
|
152
181
|
To search Arduino library database, you can use the search command.
|
153
182
|
|
154
183
|
You can search in two ways:
|
155
184
|
|
156
|
-
1. simple
|
185
|
+
1. simple substrin match of the library name
|
157
186
|
2. complex arbitrary attribute match, that supports regular expressions and more.
|
158
187
|
|
159
|
-
`arli search AudioZero` does a simple search by name, and returns
|
188
|
+
`arli search AudioZero` does a simple search by name, and would match any library with 'AudioZero' in the name, such as `AudioZeroUpdated`. This search returns three results sorted by the version number:
|
160
189
|
|
161
190
|
```bash
|
162
191
|
❯ arli search AudioZero
|
163
|
-
AudioZero (1.0.1), by Arduino
|
164
192
|
AudioZero (1.0.0), by Arduino
|
193
|
+
AudioZero (1.0.1), by Arduino
|
165
194
|
AudioZero (1.1.1), by Arduino
|
166
195
|
|
167
196
|
Total matches: 3
|
@@ -169,12 +198,10 @@ Total matches: 3
|
|
169
198
|
|
170
199
|
The search argument can also be a ruby-syntaxed expression, that (if you know ruby) is actually `eval`-ed into the method parameters. Here are a few examples:
|
171
200
|
|
172
|
-
|
173
|
-
|
174
201
|
You can also use regular expressions, and set maximum number of results printed by the `-m MAX` flag.
|
175
202
|
|
176
203
|
```bash
|
177
|
-
❯ arli search 'name: /adafruit/i'
|
204
|
+
❯ arli search 'name: /adafruit/i'
|
178
205
|
Adafruit ADS1X15 (1.0.0), by Adafruit
|
179
206
|
Adafruit ADXL345 (1.0.0), by Adafruit
|
180
207
|
Adafruit AM2315 (1.0.0), by Adafruit
|
data/arli.gemspec
CHANGED
data/docs/arli-full.png
ADDED
Binary file
|
Binary file
|
data/lib/arli/actions.rb
CHANGED
data/lib/arli/actions/action.rb
CHANGED
@@ -11,7 +11,7 @@ module Arli
|
|
11
11
|
|
12
12
|
class << self
|
13
13
|
def inherited(klazz)
|
14
|
-
action_name
|
14
|
+
action_name = klazz.name.gsub(/.*::/, '').underscore.to_sym
|
15
15
|
::Arli::Actions.actions[action_name] = klazz
|
16
16
|
end
|
17
17
|
end
|
@@ -27,6 +27,46 @@ module Arli
|
|
27
27
|
raise 'Abstract method #act called on Action'
|
28
28
|
end
|
29
29
|
|
30
|
+
def overwrite?
|
31
|
+
config.install.if_exists.overwrite
|
32
|
+
end
|
33
|
+
|
34
|
+
def backup?
|
35
|
+
config.install.if_exists.backup
|
36
|
+
end
|
37
|
+
|
38
|
+
def abort?
|
39
|
+
config.install.if_exists.abort
|
40
|
+
end
|
41
|
+
|
42
|
+
def mv(from, to)
|
43
|
+
handle_preexisting_folder(to)
|
44
|
+
FileUtils.mv(from, to)
|
45
|
+
end
|
46
|
+
|
47
|
+
def handle_preexisting_folder(to)
|
48
|
+
if Dir.exist?(to)
|
49
|
+
if abort?
|
50
|
+
raise ::Arli::Errors::LibraryAlreadyExists, "Directory #{to} already exists"
|
51
|
+
elsif backup?
|
52
|
+
backup!(to)
|
53
|
+
elsif overwrite?
|
54
|
+
FileUtils.rm_rf(to)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def backup!(p)
|
60
|
+
if Dir.exist?(p)
|
61
|
+
backup_path = "#{p}.arli-backup-#{Time.now.strftime('%Y%m%d%H%M%S')}"
|
62
|
+
FileUtils.mv(p, backup_path)
|
63
|
+
if config.verbose
|
64
|
+
___ "\nNOTE: path #{p.blue} has been backed up to #{backup_path.bold.green}\n"
|
65
|
+
elsif !config.quiet
|
66
|
+
___ ' backed up and'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
30
70
|
end
|
31
71
|
end
|
32
72
|
end
|
@@ -19,23 +19,30 @@ module Arli
|
|
19
19
|
# but we found header Adafruit_Sensor we should
|
20
20
|
# rename the folder
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
if headers.include?(dir) || sources.include?(dir)
|
23
|
+
print_target_dir(dir)
|
24
|
+
else
|
25
|
+
# if we end up setting this, we'll also move the folder.
|
26
|
+
canonical_dir =
|
27
|
+
if_only_one(headers) ||
|
28
|
+
if_only_one(sources) ||
|
29
|
+
if_header_a_substring(headers)
|
24
30
|
|
25
|
-
|
31
|
+
if canonical_dir
|
32
|
+
library.canonical_dir = canonical_dir
|
33
|
+
mv(dir, library.canonical_dir)
|
34
|
+
print_target_dir(canonical_dir)
|
35
|
+
else
|
36
|
+
library.canonical_dir = dir
|
37
|
+
print_target_dir(dir)
|
38
|
+
end
|
39
|
+
end
|
26
40
|
|
27
|
-
# if we end up setting this, we'll also move the folder.
|
28
|
-
canonical_dir =
|
29
|
-
if_only_one(headers) ||
|
30
|
-
if_only_one(sources) ||
|
31
|
-
if_header_a_substring(headers)
|
32
41
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
FileUtils.mv(dir, library.canonical_dir)
|
38
|
-
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def print_target_dir(d)
|
45
|
+
___ " installed to #{d.green} #{'✔'.green}" unless Arli.config.quiet
|
39
46
|
end
|
40
47
|
|
41
48
|
def if_header_a_substring(files)
|
@@ -5,20 +5,18 @@ module Arli
|
|
5
5
|
|
6
6
|
def act
|
7
7
|
c = library.exists? ? git_update_command : git_clone_command
|
8
|
-
___ 'running ' + c.blue + ' '
|
9
8
|
execute(c)
|
10
|
-
ok
|
11
9
|
rescue Exception => e
|
12
10
|
fuck
|
13
11
|
raise e
|
14
12
|
end
|
15
13
|
|
16
14
|
def git_update_command
|
17
|
-
"cd #{path} && git pull --rebase 2>&1"
|
15
|
+
"cd #{library.path} && git pull --rebase 2>&1"
|
18
16
|
end
|
19
17
|
|
20
18
|
def git_clone_command
|
21
|
-
"git clone -v #{library.url} #{
|
19
|
+
"git clone -v #{library.url} #{library.dir} 2>&1"
|
22
20
|
end
|
23
21
|
|
24
22
|
protected
|
@@ -36,8 +34,6 @@ module Arli
|
|
36
34
|
"Current folder is [#{Dir.pwd.yellow}]", e
|
37
35
|
raise e
|
38
36
|
end
|
39
|
-
|
40
|
-
|
41
37
|
end
|
42
38
|
end
|
43
39
|
end
|
@@ -4,20 +4,14 @@ require_relative 'action'
|
|
4
4
|
module Arli
|
5
5
|
module Actions
|
6
6
|
class ZipFile < Action
|
7
|
-
|
8
7
|
def act
|
9
|
-
|
8
|
+
# TODO: verify that this works if backup option is provided
|
10
9
|
library.rm_rf!
|
11
10
|
download!
|
12
11
|
if File.exist?(zip_archive)
|
13
|
-
ok; ___
|
14
12
|
FileUtils.rm_rf(zip_folder) if zip_folder
|
15
13
|
unzip(zip_archive, '.')
|
16
|
-
if Dir.exist?(zip_folder)
|
17
|
-
ok; ___
|
18
|
-
FileUtils.move(zip_folder, dir)
|
19
|
-
ok
|
20
|
-
end
|
14
|
+
FileUtils.move(zip_folder, dir) if Dir.exist?(zip_folder)
|
21
15
|
end
|
22
16
|
rescue Exception => e
|
23
17
|
fuck
|
data/lib/arli/arli_file.rb
CHANGED
@@ -17,17 +17,20 @@ module Arli
|
|
17
17
|
:file,
|
18
18
|
:library_path
|
19
19
|
|
20
|
-
def initialize(config: Arli.config)
|
20
|
+
def initialize(config: Arli.config, libraries: [])
|
21
21
|
self.library_path = config.libraries.path
|
22
|
-
|
22
|
+
FileUtils.mkpath(library_path) unless Dir.exist?(library_path)
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
if libraries && !libraries.empty?
|
25
|
+
self.dependencies = libraries.map{ |lib| make_lib(lib) }
|
26
|
+
else
|
27
|
+
self.file = "#{config.arlifile.path}/#{config.arlifile.name}"
|
28
|
+
unless file && File.exist?(file)
|
29
|
+
raise(Arli::Errors::ArliFileNotFound,
|
30
|
+
"Arlifile could not be found at\n#{file.bold.yellow}")
|
31
|
+
end
|
32
|
+
self.dependencies = parse_file
|
27
33
|
end
|
28
|
-
|
29
|
-
FileUtils.mkpath(library_path) unless Dir.exist?(library_path)
|
30
|
-
self.dependencies = parse_file
|
31
34
|
end
|
32
35
|
|
33
36
|
def within_library_path
|
@@ -44,9 +47,11 @@ module Arli
|
|
44
47
|
|
45
48
|
def parse_file
|
46
49
|
self.file_hash = ::YAML.load(::File.read(self.file))
|
47
|
-
file_hash['dependencies'].map
|
48
|
-
|
49
|
-
|
50
|
+
file_hash['dependencies'].map { |lib| make_lib(lib) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def make_lib(lib)
|
54
|
+
::Arli::Library.new(::Arduino::Library::Model.from(lib))
|
50
55
|
end
|
51
56
|
end
|
52
57
|
end
|
data/lib/arli/cli/app.rb
CHANGED
@@ -25,10 +25,12 @@ module Arli
|
|
25
25
|
def start
|
26
26
|
if argv.empty?
|
27
27
|
factory.default_help
|
28
|
+
factory.global_parser.print_version_copyright
|
28
29
|
return
|
29
30
|
end
|
30
31
|
|
31
32
|
parse_global_flags
|
33
|
+
|
32
34
|
return if Arli.config.help
|
33
35
|
|
34
36
|
finder = CommandFinder.new(argv, config: config)
|
@@ -58,7 +60,7 @@ module Arli
|
|
58
60
|
|
59
61
|
def execute!
|
60
62
|
if command
|
61
|
-
header(command: command)
|
63
|
+
header(command: command) unless config.quiet
|
62
64
|
command.run
|
63
65
|
else
|
64
66
|
factory.default_help
|
data/lib/arli/cli/parser.rb
CHANGED
@@ -20,6 +20,13 @@ module Arli
|
|
20
20
|
separator text || ''
|
21
21
|
end
|
22
22
|
|
23
|
+
def option_install
|
24
|
+
option_library_name
|
25
|
+
option_lib_home
|
26
|
+
option_dependency_file
|
27
|
+
option_if_exists
|
28
|
+
end
|
29
|
+
|
23
30
|
def option_dependency_file
|
24
31
|
on('-a', '--arli-path PATH',
|
25
32
|
'Folder where ' + 'Arlifile'.green + ' is located,',
|
@@ -28,9 +35,17 @@ module Arli
|
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
38
|
+
def option_library_name
|
39
|
+
on('-n', '--name NAME',
|
40
|
+
'If provided a library name is searched and, if found',
|
41
|
+
'installed. In this mode Arlifile not used.' + "\n\n") do |v|
|
42
|
+
config.install.library_names << { name: v }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
31
46
|
def option_lib_home
|
32
47
|
on('-l', '--libraries PATH',
|
33
|
-
'Local folder where libraries are installed',
|
48
|
+
'Local folder where custom Arduino libraries are installed',
|
34
49
|
"Defaults to #{Arli.default_library_path}\n\n") do |v|
|
35
50
|
config.libraries.path = v
|
36
51
|
end
|
@@ -38,19 +53,19 @@ module Arli
|
|
38
53
|
|
39
54
|
def option_search
|
40
55
|
on('-d', '--database FILE/URL',
|
41
|
-
'a JSON file
|
42
|
-
'Defaults to the Arduino-maintained
|
56
|
+
'a JSON(.gz) file path or a URL of the library database.',
|
57
|
+
'Defaults to the Arduino-maintained database.') do |v|
|
43
58
|
config.database.path = v
|
44
59
|
end
|
45
60
|
|
46
61
|
on('-m', '--max NUMBER',
|
47
62
|
'if provided, limits the result set to this number',
|
48
|
-
'
|
63
|
+
'Set to 0 to disable. Default is 100.') do |v|
|
49
64
|
config.search.results.limit = v.to_i if v
|
50
65
|
end
|
51
66
|
end
|
52
67
|
|
53
|
-
def
|
68
|
+
def option_if_exists
|
54
69
|
on('-e', '--if-exists ACTION',
|
55
70
|
'If a library folder already exists, by default',
|
56
71
|
'it will be overwritten or updated if possible.',
|
@@ -83,13 +98,25 @@ module Arli
|
|
83
98
|
output_help
|
84
99
|
output_command_help if commands
|
85
100
|
|
86
|
-
if command_hash && command_hash[:
|
87
|
-
|
88
|
-
|
101
|
+
if command_hash && command_hash[:examples]
|
102
|
+
output_examples(command_hash[:examples])
|
103
|
+
else
|
104
|
+
print_version_copyright
|
89
105
|
end
|
90
106
|
end
|
91
107
|
end
|
92
108
|
|
109
|
+
def output_examples(examples)
|
110
|
+
output 'Examples:'
|
111
|
+
indent = ' '
|
112
|
+
examples.each do |example|
|
113
|
+
output
|
114
|
+
output indent + '# ' + example[:desc]
|
115
|
+
output indent + example[:cmd].green
|
116
|
+
output ''
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
93
120
|
def option_help_with_subtext
|
94
121
|
option_help
|
95
122
|
end
|
@@ -111,7 +138,6 @@ module Arli
|
|
111
138
|
subtext << <<-EOS
|
112
139
|
|
113
140
|
See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yellow} for more information on a specific command.
|
114
|
-
|
115
141
|
EOS
|
116
142
|
subtext
|
117
143
|
end
|
@@ -142,12 +168,21 @@ See #{Arli::Configuration::ARLI_COMMAND.blue + ' command '.green + '--help'.yell
|
|
142
168
|
'Print more information.') do |v|
|
143
169
|
config.verbose = true
|
144
170
|
end
|
171
|
+
on('-q', '--quiet',
|
172
|
+
'Print less information.') do |v|
|
173
|
+
config.quiet = true
|
174
|
+
end
|
145
175
|
on('-V', '--version',
|
146
176
|
'Print current version and exit') do |v|
|
147
|
-
|
148
|
-
|
177
|
+
print_version_copyright
|
178
|
+
Arli.config.help = true
|
149
179
|
end
|
150
180
|
end
|
181
|
+
|
182
|
+
def print_version_copyright
|
183
|
+
output << Arli::Configuration::ARLI_COMMAND.bold.yellow + ' (' + Arli::VERSION.bold.green + ')' +
|
184
|
+
" © 2017 Konstantin Gredeskoul, MIT License."
|
185
|
+
end
|
151
186
|
end
|
152
187
|
end
|
153
188
|
end
|
@@ -21,7 +21,7 @@ module Arli
|
|
21
21
|
|
22
22
|
def make_parser(command = nil, &block)
|
23
23
|
::Arli::CLI::Parser.new(command: command,
|
24
|
-
config:
|
24
|
+
config: Arli.config, &block)
|
25
25
|
end
|
26
26
|
|
27
27
|
def global_parser
|
@@ -35,23 +35,41 @@ module Arli
|
|
35
35
|
def command_parsers
|
36
36
|
@command_parsers ||= {
|
37
37
|
install: {
|
38
|
-
description: 'installs libraries defined in Arlifile',
|
38
|
+
description: 'installs libraries defined in Arlifile or by -n flag',
|
39
|
+
examples: [
|
40
|
+
{ desc: 'Install all libs defined in the ./Arlifile file',
|
41
|
+
cmd: 'arli install' },
|
42
|
+
{ desc: 'Install a single library matched by the --name flag',
|
43
|
+
cmd: 'arli install -n "Adafruit GFX Library"' }
|
44
|
+
],
|
45
|
+
|
39
46
|
parser: -> (command_name) {
|
40
47
|
make_parser(command_name) do |parser|
|
41
48
|
parser.banner = usage_line 'install'
|
42
|
-
parser.
|
43
|
-
parser.option_dependency_file
|
44
|
-
parser.option_abort_if_exists
|
49
|
+
parser.option_install
|
45
50
|
parser.option_help(command_name: command_name)
|
46
51
|
end
|
47
52
|
} },
|
48
53
|
|
49
54
|
search: {
|
50
55
|
description: 'Flexible Search of the Arduino Library Database',
|
51
|
-
|
56
|
+
examples: [
|
57
|
+
{ desc: 'Search using the regular expression containing the name:',
|
58
|
+
cmd: 'arli search AudioZero' },
|
59
|
+
|
60
|
+
{ desc: 'Same exact search as above, but using advanced ruby hash arguments syntax:',
|
61
|
+
cmd: %Q{arli search 'name: /AudioZero/'} },
|
62
|
+
|
63
|
+
{ desc: 'Search using case insensitive name search:',
|
64
|
+
cmd: %Q{arli search 'name: /adafruit/i'} },
|
65
|
+
|
66
|
+
{ desc: 'Finally, search for the exact name match:',
|
67
|
+
cmd: %Q{arli search '^Time$'} },
|
68
|
+
],
|
69
|
+
|
52
70
|
parser: -> (command_name) {
|
53
71
|
make_parser(command_name) do |parser|
|
54
|
-
parser.banner = usage_line 'search ' + '[ name
|
72
|
+
parser.banner = usage_line 'search ' + '[ name | search-expression ]'.magenta
|
55
73
|
parser.option_search
|
56
74
|
parser.option_help(command_name: command_name)
|
57
75
|
end
|
@@ -60,6 +78,7 @@ module Arli
|
|
60
78
|
}
|
61
79
|
end
|
62
80
|
|
81
|
+
|
63
82
|
def commands
|
64
83
|
command_parsers.keys
|
65
84
|
end
|
@@ -15,11 +15,13 @@ module Arli
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def setup
|
18
|
-
self.arlifile = Arli::ArliFile.new(
|
18
|
+
self.arlifile = Arli::ArliFile.new(
|
19
|
+
config: config,
|
20
|
+
libraries: Arli.config.install.library_names)
|
19
21
|
end
|
20
22
|
|
21
23
|
def params
|
22
|
-
arlifile.
|
24
|
+
"libraries: \n • " + arlifile.dependencies.map(&:name).join("\n • ")
|
23
25
|
end
|
24
26
|
|
25
27
|
def run
|
data/lib/arli/commands/search.rb
CHANGED
data/lib/arli/configuration.rb
CHANGED
@@ -43,7 +43,7 @@ module Arli
|
|
43
43
|
end
|
44
44
|
|
45
45
|
setting :install do
|
46
|
-
setting :
|
46
|
+
setting :library_names, []
|
47
47
|
setting :if_exists do
|
48
48
|
setting :overwrite, true
|
49
49
|
setting :backup, false
|
@@ -55,7 +55,7 @@ module Arli
|
|
55
55
|
setting :trace, false
|
56
56
|
setting :verbose, false
|
57
57
|
setting :help, false
|
58
|
-
setting :
|
58
|
+
setting :quiet, false
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
data/lib/arli/installer.rb
CHANGED
@@ -27,6 +27,7 @@ module Arli
|
|
27
27
|
fuck
|
28
28
|
else
|
29
29
|
___ "(#{library.version.green}) " if library.version
|
30
|
+
___ cursor.column(45) unless config.quiet
|
30
31
|
actions(library).each do |action|
|
31
32
|
run_action(action)
|
32
33
|
end
|
@@ -41,7 +42,6 @@ module Arli
|
|
41
42
|
|
42
43
|
def actions(library)
|
43
44
|
actions = []
|
44
|
-
actions << :backup if exists?
|
45
45
|
# First, how do we get the library?
|
46
46
|
actions << ((library.url =~ /\.zip$/i) ? :zip_file : :git_repo)
|
47
47
|
actions << :dir_name
|
data/lib/arli/output.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'colored2'
|
2
|
+
require 'tty-cursor'
|
2
3
|
|
3
4
|
module Arli
|
4
5
|
module Output
|
5
6
|
|
6
7
|
class << self
|
7
|
-
attr_accessor :enabled
|
8
|
+
attr_accessor :enabled, :cursor
|
8
9
|
def enable!
|
9
10
|
self.enabled = true
|
10
11
|
end
|
@@ -17,6 +18,11 @@ module Arli
|
|
17
18
|
end
|
18
19
|
|
19
20
|
self.enable!
|
21
|
+
self.cursor = TTY::Cursor
|
22
|
+
|
23
|
+
def cursor
|
24
|
+
Arli::Output.cursor
|
25
|
+
end
|
20
26
|
|
21
27
|
def info(msg, header = nil)
|
22
28
|
__pf('%-20s', header.blue) if header
|
@@ -52,7 +58,6 @@ module Arli
|
|
52
58
|
def ___(msg = nil, newline = false)
|
53
59
|
return unless Arli::Output.enabled?
|
54
60
|
__pf msg if msg
|
55
|
-
__p '.'.green if msg.nil?
|
56
61
|
__pt if newline
|
57
62
|
end
|
58
63
|
|
@@ -69,17 +74,21 @@ module Arli
|
|
69
74
|
end
|
70
75
|
|
71
76
|
def ok
|
72
|
-
___ '.'.
|
77
|
+
___ '.'.green
|
78
|
+
end
|
79
|
+
|
80
|
+
def check
|
81
|
+
___ '✔'.green
|
73
82
|
end
|
74
83
|
|
75
84
|
def fuck
|
76
|
-
___ '✖'.
|
85
|
+
___ '✖'.red
|
77
86
|
end
|
78
87
|
|
79
88
|
def header(command: nil)
|
80
89
|
out = "\n#{hr}\n"
|
81
90
|
out << "Arli (#{::Arli::VERSION.yellow})"
|
82
|
-
out << " running #{command.name.to_s.magenta.bold}" if command
|
91
|
+
out << " running command #{command.name.to_s.magenta.bold}" if command
|
83
92
|
out << " for #{command.params.to_s.blue}\n" if command
|
84
93
|
out << "Library Path: #{Arli.default_library_path.green}\n"
|
85
94
|
out << "#{hr}\n"
|
@@ -87,7 +96,7 @@ module Arli
|
|
87
96
|
end
|
88
97
|
|
89
98
|
def hr
|
90
|
-
'
|
99
|
+
('-' * (ENV['COLUMNS'] || 80)).red.dark
|
91
100
|
end
|
92
101
|
|
93
102
|
end
|
data/lib/arli/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
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-
|
11
|
+
date: 2017-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: arduino-library
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: tty-cursor
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: yard
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -241,11 +255,12 @@ files:
|
|
241
255
|
- arli.gemspec
|
242
256
|
- bin/console
|
243
257
|
- bin/setup
|
258
|
+
- docs/arli-full.png
|
259
|
+
- docs/arli-in-action.png
|
244
260
|
- exe/arli
|
245
261
|
- lib/arli.rb
|
246
262
|
- lib/arli/actions.rb
|
247
263
|
- lib/arli/actions/action.rb
|
248
|
-
- lib/arli/actions/backup.rb
|
249
264
|
- lib/arli/actions/dir_name.rb
|
250
265
|
- lib/arli/actions/git_repo.rb
|
251
266
|
- lib/arli/actions/zip_file.rb
|
data/lib/arli/actions/backup.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require_relative 'action'
|
2
|
-
|
3
|
-
module Arli
|
4
|
-
module Actions
|
5
|
-
class Backup < Action
|
6
|
-
|
7
|
-
def act(**options)
|
8
|
-
return false unless exists?
|
9
|
-
|
10
|
-
if backup_action.abort
|
11
|
-
raise Arli::Errors::LibraryAlreadyExists, path
|
12
|
-
elsif backup_action.backup
|
13
|
-
FileUtils.mv(path, backup_library_path)
|
14
|
-
elsif backup_action.overwrite
|
15
|
-
library.rm_rf!
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def backup_action
|
20
|
-
config.install.if_exists
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def backup_library_path
|
26
|
-
path + ".#{Time.now.strftime('%Y%m%d%H%M%S')}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|