lino 1.8.0.pre.1 → 2.0.0.pre.1
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.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +29 -1
- data/README.md +54 -11
- data/Rakefile +62 -42
- data/bin/console +1 -0
- data/lib/lino.rb +2 -0
- data/lib/lino/command_line.rb +14 -10
- data/lib/lino/command_line_builder.rb +63 -27
- data/lib/lino/options.rb +27 -0
- data/lib/lino/subcommand_builder.rb +8 -6
- data/lib/lino/utilities.rb +23 -7
- data/lib/lino/version.rb +3 -1
- metadata +54 -12
- data/lib/lino/option_flag_mixin.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1ed8a59b3a9171234c636171f9b7304637067db63ff130c04c14a780418f28c
|
4
|
+
data.tar.gz: 927e637996bab9611c2233e92b1ab5b0869a5de36847dce88086880fd1022d71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 357901083b289bbf18a2c3f7425ae01967d950c0329b6c793dd214fe2b265bea8f69d40886cd58d169bac03dcff1eb7337ad6a909788da0370836065fa51b9da
|
7
|
+
data.tar.gz: 53a7a833e0725f4f9597dc05afa7213a67790b5c77d0f76bacbbda403a82464dc4a187fc8265999db6dd4e47e4f05deb257370c97734a0356f81ebcf451bb67b
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at
|
58
|
+
reported by contacting the project team at maintainers@infrablocks.io. All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
lino (
|
4
|
+
lino (2.0.0.pre.1)
|
5
5
|
hamster (~> 3.0)
|
6
6
|
open4 (~> 1.3)
|
7
7
|
|
@@ -16,6 +16,7 @@ GEM
|
|
16
16
|
zeitwerk (~> 2.3)
|
17
17
|
addressable (2.7.0)
|
18
18
|
public_suffix (>= 2.0.2, < 5.0)
|
19
|
+
ast (2.4.2)
|
19
20
|
colored2 (3.1.2)
|
20
21
|
concurrent-ruby (1.1.7)
|
21
22
|
diff-lcs (1.4.4)
|
@@ -37,7 +38,11 @@ GEM
|
|
37
38
|
faraday (>= 0.9)
|
38
39
|
sawyer (~> 0.8.0, >= 0.5.3)
|
39
40
|
open4 (1.3.4)
|
41
|
+
parallel (1.20.1)
|
42
|
+
parser (3.0.0.0)
|
43
|
+
ast (~> 2.4.1)
|
40
44
|
public_suffix (4.0.6)
|
45
|
+
rainbow (3.0.0)
|
41
46
|
rake (13.0.3)
|
42
47
|
rake_circle_ci (0.9.0)
|
43
48
|
colored2 (~> 3.1)
|
@@ -59,6 +64,8 @@ GEM
|
|
59
64
|
colored2 (~> 3.1)
|
60
65
|
rake_factory (~> 0.23)
|
61
66
|
sshkey (~> 2.0)
|
67
|
+
regexp_parser (2.1.1)
|
68
|
+
rexml (3.2.4)
|
62
69
|
rspec (3.10.0)
|
63
70
|
rspec-core (~> 3.10.0)
|
64
71
|
rspec-expectations (~> 3.10.0)
|
@@ -72,6 +79,23 @@ GEM
|
|
72
79
|
diff-lcs (>= 1.2.0, < 2.0)
|
73
80
|
rspec-support (~> 3.10.0)
|
74
81
|
rspec-support (3.10.1)
|
82
|
+
rubocop (1.12.0)
|
83
|
+
parallel (~> 1.10)
|
84
|
+
parser (>= 3.0.0.0)
|
85
|
+
rainbow (>= 2.2.2, < 4.0)
|
86
|
+
regexp_parser (>= 1.8, < 3.0)
|
87
|
+
rexml
|
88
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
89
|
+
ruby-progressbar (~> 1.7)
|
90
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
91
|
+
rubocop-ast (1.4.1)
|
92
|
+
parser (>= 2.7.1.5)
|
93
|
+
rubocop-rake (0.5.1)
|
94
|
+
rubocop
|
95
|
+
rubocop-rspec (2.2.0)
|
96
|
+
rubocop (~> 1.0)
|
97
|
+
rubocop-ast (>= 1.1.0)
|
98
|
+
ruby-progressbar (1.11.0)
|
75
99
|
ruby2_keywords (0.0.2)
|
76
100
|
ruby_gpg2 (0.6.0)
|
77
101
|
lino (>= 1.5)
|
@@ -87,6 +111,7 @@ GEM
|
|
87
111
|
sshkey (2.0.0)
|
88
112
|
tzinfo (2.0.4)
|
89
113
|
concurrent-ruby (~> 1.0)
|
114
|
+
unicode-display_width (2.0.0)
|
90
115
|
zeitwerk (2.4.2)
|
91
116
|
|
92
117
|
PLATFORMS
|
@@ -102,6 +127,9 @@ DEPENDENCIES
|
|
102
127
|
rake_gpg (~> 0.12)
|
103
128
|
rake_ssh (~> 0.4)
|
104
129
|
rspec (~> 3.9)
|
130
|
+
rubocop (~> 1.12)
|
131
|
+
rubocop-rake (~> 0.5)
|
132
|
+
rubocop-rspec (~> 2.2)
|
105
133
|
simplecov (~> 0.16)
|
106
134
|
|
107
135
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -40,7 +40,8 @@ command_line.execute
|
|
40
40
|
|
41
41
|
### `Lino::CommandLineBuilder`
|
42
42
|
|
43
|
-
The `CommandLineBuilder` allows a number of different styles of commands to be
|
43
|
+
The `CommandLineBuilder` allows a number of different styles of commands to be
|
44
|
+
built:
|
44
45
|
|
45
46
|
```ruby
|
46
47
|
# commands with flags
|
@@ -61,7 +62,7 @@ Lino::CommandLineBuilder.for_command('gpg')
|
|
61
62
|
|
62
63
|
# => gpg --recipient tobyclemson@gmail.com --sign ./doc.txt
|
63
64
|
|
64
|
-
# commands with an option repeated multiple times
|
65
|
+
# commands with an option repeated multiple times
|
65
66
|
Lino::CommandLineBuilder.for_command('example.sh')
|
66
67
|
.with_repeated_option('--opt', ['file1.txt', nil, '', 'file2.txt'])
|
67
68
|
.build
|
@@ -78,7 +79,7 @@ Lino::CommandLineBuilder.for_command('diff')
|
|
78
79
|
|
79
80
|
# => diff ./file1.txt ./file2.txt
|
80
81
|
|
81
|
-
# commands with an array of arguments
|
82
|
+
# commands with an array of arguments
|
82
83
|
Lino::CommandLineBuilder.for_command('diff')
|
83
84
|
.with_arguments(['./file1.txt', nil, '', './file2.txt'])
|
84
85
|
.build
|
@@ -119,6 +120,18 @@ Lino::CommandLineBuilder.for_command('gcloud')
|
|
119
120
|
.to_s
|
120
121
|
|
121
122
|
# => gcloud sql instances set-root-password some-database --password super-secure
|
123
|
+
|
124
|
+
# ... or alternatively
|
125
|
+
Lino::CommandLineBuilder.for_command('gcloud')
|
126
|
+
.with_subcommands(
|
127
|
+
%w[sql instances set-root-password some-database]
|
128
|
+
) do |sub|
|
129
|
+
sub.with_option('--password', 'super-secure')
|
130
|
+
end
|
131
|
+
.build
|
132
|
+
.to_s
|
133
|
+
|
134
|
+
# => gcloud sql instances set-root-password some-database --password super-secure
|
122
135
|
|
123
136
|
# commands controlled by environment variables
|
124
137
|
Lino::CommandLineBuilder.for_command('node')
|
@@ -147,7 +160,8 @@ command_line.execute
|
|
147
160
|
# => <contents of / directory>
|
148
161
|
```
|
149
162
|
|
150
|
-
By default, the standard input stream is empty and the process writes to the
|
163
|
+
By default, the standard input stream is empty and the process writes to the
|
164
|
+
standard output and error streams.
|
151
165
|
|
152
166
|
To populate standard input:
|
153
167
|
|
@@ -155,7 +169,8 @@ To populate standard input:
|
|
155
169
|
command_line.execute(stdin: 'something to be passed to standard input')
|
156
170
|
```
|
157
171
|
|
158
|
-
The `stdin` option supports any object that responds to `each`, `read` or
|
172
|
+
The `stdin` option supports any object that responds to `each`, `read` or
|
173
|
+
`to_s`.
|
159
174
|
|
160
175
|
To provide custom streams for standard output or standard error:
|
161
176
|
|
@@ -174,16 +189,44 @@ The `stdout` and `stderr` options support any object that responds to `<<`.
|
|
174
189
|
|
175
190
|
## Development
|
176
191
|
|
177
|
-
|
192
|
+
To install dependencies and run the build, run the pre-commit build:
|
178
193
|
|
179
|
-
|
194
|
+
```shell script
|
195
|
+
./go
|
196
|
+
```
|
180
197
|
|
181
|
-
|
198
|
+
This runs all unit tests and other checks including coverage and code linting /
|
199
|
+
formatting.
|
200
|
+
|
201
|
+
To run only the unit tests, including coverage:
|
182
202
|
|
183
|
-
|
203
|
+
```shell script
|
204
|
+
./go test:unit
|
205
|
+
```
|
184
206
|
|
207
|
+
To attempt to fix any code linting / formatting issues:
|
185
208
|
|
186
|
-
|
209
|
+
```shell script
|
210
|
+
./go library:fix
|
211
|
+
```
|
212
|
+
|
213
|
+
To check for code linting / formatting issues without fixing:
|
214
|
+
|
215
|
+
```shell script
|
216
|
+
./go library:check
|
217
|
+
```
|
187
218
|
|
188
|
-
|
219
|
+
You can also run `bin/console` for an interactive prompt that will allow you to
|
220
|
+
experiment.
|
221
|
+
|
222
|
+
## Contributing
|
223
|
+
|
224
|
+
Bug reports and pull requests are welcome on GitHub at
|
225
|
+
https://github.com/infrablocks/lino. This project is intended to be a safe,
|
226
|
+
welcoming space for collaboration, and contributors are expected to adhere to
|
227
|
+
the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
228
|
+
|
229
|
+
## License
|
189
230
|
|
231
|
+
The gem is available as open source under the terms of the
|
232
|
+
[MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
require 'rake_circle_ci'
|
3
5
|
require 'rake_github'
|
@@ -5,10 +7,12 @@ require 'rake_ssh'
|
|
5
7
|
require 'rake_gpg'
|
6
8
|
require 'securerandom'
|
7
9
|
require 'rspec/core/rake_task'
|
10
|
+
require 'rubocop/rake_task'
|
8
11
|
|
9
|
-
task :
|
10
|
-
|
11
|
-
|
12
|
+
task default: %i[
|
13
|
+
library:fix
|
14
|
+
test:unit
|
15
|
+
]
|
12
16
|
|
13
17
|
namespace :encryption do
|
14
18
|
namespace :passphrase do
|
@@ -23,83 +27,99 @@ end
|
|
23
27
|
namespace :keys do
|
24
28
|
namespace :deploy do
|
25
29
|
RakeSSH.define_key_tasks(
|
26
|
-
|
27
|
-
|
30
|
+
path: 'config/secrets/ci/',
|
31
|
+
comment: 'maintainers@infrablocks.io'
|
32
|
+
)
|
28
33
|
end
|
29
34
|
|
30
35
|
namespace :gpg do
|
31
36
|
RakeGPG.define_generate_key_task(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
+
output_directory: 'config/secrets/ci',
|
38
|
+
name_prefix: 'gpg',
|
39
|
+
owner_name: 'InfraBlocks Maintainers',
|
40
|
+
owner_email: 'maintainers@infrablocks.io',
|
41
|
+
owner_comment: 'lino CI Key'
|
42
|
+
)
|
37
43
|
end
|
38
44
|
end
|
39
45
|
|
46
|
+
RuboCop::RakeTask.new
|
47
|
+
|
48
|
+
namespace :library do
|
49
|
+
desc 'Run all checks of the library'
|
50
|
+
task check: [:rubocop]
|
51
|
+
|
52
|
+
desc 'Attempt to automatically fix issues with the library'
|
53
|
+
task fix: [:'rubocop:auto_correct']
|
54
|
+
end
|
55
|
+
|
56
|
+
namespace :test do
|
57
|
+
RSpec::Core::RakeTask.new(:unit)
|
58
|
+
end
|
59
|
+
|
40
60
|
RakeCircleCI.define_project_tasks(
|
41
|
-
|
42
|
-
|
61
|
+
namespace: :circle_ci,
|
62
|
+
project_slug: 'github/infrablocks/lino'
|
43
63
|
) do |t|
|
44
64
|
circle_ci_config =
|
45
|
-
|
65
|
+
YAML.load_file('config/secrets/circle_ci/config.yaml')
|
46
66
|
|
47
|
-
t.api_token = circle_ci_config[
|
67
|
+
t.api_token = circle_ci_config['circle_ci_api_token']
|
48
68
|
t.environment_variables = {
|
49
|
-
|
50
|
-
|
51
|
-
|
69
|
+
ENCRYPTION_PASSPHRASE:
|
70
|
+
File.read('config/secrets/ci/encryption.passphrase')
|
71
|
+
.chomp
|
52
72
|
}
|
53
73
|
t.checkout_keys = []
|
54
74
|
t.ssh_keys = [
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
75
|
+
{
|
76
|
+
hostname: 'github.com',
|
77
|
+
private_key: File.read('config/secrets/ci/ssh.private')
|
78
|
+
}
|
59
79
|
]
|
60
80
|
end
|
61
81
|
|
62
82
|
RakeGithub.define_repository_tasks(
|
63
|
-
|
64
|
-
|
83
|
+
namespace: :github,
|
84
|
+
repository: 'infrablocks/lino'
|
65
85
|
) do |t|
|
66
86
|
github_config =
|
67
|
-
|
87
|
+
YAML.load_file('config/secrets/github/config.yaml')
|
68
88
|
|
69
|
-
t.access_token = github_config[
|
89
|
+
t.access_token = github_config['github_personal_access_token']
|
70
90
|
t.deploy_keys = [
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
91
|
+
{
|
92
|
+
title: 'CircleCI',
|
93
|
+
public_key: File.read('config/secrets/ci/ssh.public')
|
94
|
+
}
|
75
95
|
]
|
76
96
|
end
|
77
97
|
|
78
98
|
namespace :pipeline do
|
79
|
-
task :
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
99
|
+
task prepare: %i[
|
100
|
+
circle_ci:project:follow
|
101
|
+
circle_ci:env_vars:ensure
|
102
|
+
circle_ci:checkout_keys:ensure
|
103
|
+
circle_ci:ssh_keys:ensure
|
104
|
+
github:deploy_keys:ensure
|
85
105
|
]
|
86
106
|
end
|
87
107
|
|
88
108
|
namespace :version do
|
89
|
-
desc
|
109
|
+
desc 'Bump version for specified type (pre, major, minor, patch)'
|
90
110
|
task :bump, [:type] do |_, args|
|
91
111
|
bump_version_for(args.type)
|
92
112
|
end
|
93
113
|
end
|
94
114
|
|
95
|
-
desc
|
115
|
+
desc 'Release gem'
|
96
116
|
task :release do
|
97
|
-
sh
|
117
|
+
sh 'gem release --tag --push'
|
98
118
|
end
|
99
119
|
|
100
120
|
def bump_version_for(version_type)
|
101
|
-
sh "gem bump --version #{version_type} "
|
102
|
-
|
103
|
-
|
104
|
-
|
121
|
+
sh "gem bump --version #{version_type} " \
|
122
|
+
'&& bundle install ' \
|
123
|
+
'&& export LAST_MESSAGE="$(git log -1 --pretty=%B)" ' \
|
124
|
+
'&& git commit -a --amend -m "${LAST_MESSAGE} [ci skip]"'
|
105
125
|
end
|
data/bin/console
CHANGED
data/lib/lino.rb
CHANGED
data/lib/lino/command_line.rb
CHANGED
@@ -1,24 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'open4'
|
2
4
|
|
3
5
|
module Lino
|
4
6
|
class CommandLine
|
5
|
-
def initialize
|
7
|
+
def initialize(command_line)
|
6
8
|
@command_line = command_line
|
7
9
|
end
|
8
10
|
|
9
11
|
def execute(
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
stdin: '',
|
13
|
+
stdout: $stdout,
|
14
|
+
stderr: $stderr
|
15
|
+
)
|
16
|
+
Open4.spawn(
|
17
|
+
@command_line,
|
18
|
+
stdin: stdin,
|
19
|
+
stdout: stdout,
|
20
|
+
stderr: stderr
|
21
|
+
)
|
18
22
|
end
|
19
23
|
|
20
24
|
def to_s
|
21
25
|
@command_line
|
22
26
|
end
|
23
27
|
end
|
24
|
-
end
|
28
|
+
end
|
@@ -1,24 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'hamster'
|
2
4
|
require_relative 'utilities'
|
3
5
|
require_relative 'command_line'
|
4
6
|
require_relative 'subcommand_builder'
|
5
|
-
require_relative '
|
7
|
+
require_relative 'options'
|
6
8
|
|
7
9
|
module Lino
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
8
11
|
class CommandLineBuilder
|
9
12
|
include Lino::Utilities
|
10
|
-
include Lino::
|
13
|
+
include Lino::Options
|
11
14
|
|
12
|
-
class <<self
|
15
|
+
class << self
|
13
16
|
def for_command(command)
|
14
17
|
CommandLineBuilder.new(command: command)
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
21
|
+
# rubocop:disable Metrics/ParameterLists
|
18
22
|
def initialize(
|
19
23
|
command: nil,
|
20
24
|
subcommands: [],
|
21
|
-
|
25
|
+
options: [],
|
22
26
|
arguments: [],
|
23
27
|
environment_variables: [],
|
24
28
|
option_separator: ' ',
|
@@ -26,12 +30,13 @@ module Lino
|
|
26
30
|
)
|
27
31
|
@command = command
|
28
32
|
@subcommands = Hamster::Vector.new(subcommands)
|
29
|
-
@
|
33
|
+
@options = Hamster::Vector.new(options)
|
30
34
|
@arguments = Hamster::Vector.new(arguments)
|
31
35
|
@environment_variables = Hamster::Vector.new(environment_variables)
|
32
36
|
@option_separator = option_separator
|
33
37
|
@option_quoting = option_quoting
|
34
38
|
end
|
39
|
+
# rubocop:enable Metrics/ParameterLists
|
35
40
|
|
36
41
|
def with_subcommand(subcommand, &block)
|
37
42
|
with(
|
@@ -43,6 +48,15 @@ module Lino
|
|
43
48
|
)
|
44
49
|
end
|
45
50
|
|
51
|
+
def with_subcommands(subcommands, &block)
|
52
|
+
without_block = subcommands[0...-1]
|
53
|
+
with_block = subcommands.last
|
54
|
+
|
55
|
+
without_block
|
56
|
+
.inject(self) { |s, sc| s.with_subcommand(sc) }
|
57
|
+
.with_subcommand(with_block, &block)
|
58
|
+
end
|
59
|
+
|
46
60
|
def with_option_separator(option_separator)
|
47
61
|
with(option_separator: option_separator)
|
48
62
|
end
|
@@ -52,32 +66,33 @@ module Lino
|
|
52
66
|
end
|
53
67
|
|
54
68
|
def with_argument(argument)
|
55
|
-
|
69
|
+
return self if missing?(argument)
|
70
|
+
|
71
|
+
with(arguments: @arguments.add({ components: [argument] }))
|
56
72
|
end
|
57
73
|
|
58
74
|
def with_arguments(arguments)
|
59
|
-
arguments.
|
60
|
-
with({})
|
75
|
+
arguments.inject(self) { |s, argument| s.with_argument(argument) }
|
61
76
|
end
|
62
77
|
|
63
78
|
def with_environment_variable(environment_variable, value)
|
64
|
-
with(
|
79
|
+
with(
|
80
|
+
environment_variables:
|
81
|
+
@environment_variables.add(
|
82
|
+
[
|
83
|
+
environment_variable, value
|
84
|
+
]
|
85
|
+
)
|
86
|
+
)
|
65
87
|
end
|
66
88
|
|
67
89
|
def build
|
68
90
|
components = [
|
69
|
-
|
70
|
-
"#{var[0]}=\"#{var[1].to_s.gsub(/"/, '\\"')}\""
|
71
|
-
end,
|
91
|
+
formatted_environment_variables,
|
72
92
|
@command,
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
),
|
77
|
-
map_and_join(@subcommands) do |sub|
|
78
|
-
sub.build(@option_separator, @option_quoting)
|
79
|
-
end,
|
80
|
-
map_and_join(@arguments, &join_with(' '))
|
93
|
+
formatted_options,
|
94
|
+
formatted_subcommands,
|
95
|
+
formatted_arguments
|
81
96
|
]
|
82
97
|
|
83
98
|
command_string = components.reject(&:empty?).join(' ')
|
@@ -87,6 +102,32 @@ module Lino
|
|
87
102
|
|
88
103
|
private
|
89
104
|
|
105
|
+
def formatted_environment_variables
|
106
|
+
map_and_join(@environment_variables) do |var|
|
107
|
+
"#{var[0]}=\"#{var[1].to_s.gsub(/"/, '\\"')}\""
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def formatted_options
|
112
|
+
map_and_join(
|
113
|
+
@options,
|
114
|
+
&(quote_with(@option_quoting) >> join_with(@option_separator))
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
def formatted_subcommands
|
119
|
+
map_and_join(@subcommands) do |sub|
|
120
|
+
sub.build(@option_separator, @option_quoting)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def formatted_arguments
|
125
|
+
map_and_join(
|
126
|
+
@arguments,
|
127
|
+
&join_with(' ')
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
90
131
|
def with(**replacements)
|
91
132
|
CommandLineBuilder.new(**state.merge(replacements))
|
92
133
|
end
|
@@ -95,18 +136,13 @@ module Lino
|
|
95
136
|
{
|
96
137
|
command: @command,
|
97
138
|
subcommands: @subcommands,
|
98
|
-
|
139
|
+
options: @options,
|
99
140
|
arguments: @arguments,
|
100
141
|
environment_variables: @environment_variables,
|
101
142
|
option_separator: @option_separator,
|
102
143
|
option_quoting: @option_quoting
|
103
144
|
}
|
104
145
|
end
|
105
|
-
|
106
|
-
def add_argument(argument)
|
107
|
-
return @arguments if missing?(argument)
|
108
|
-
|
109
|
-
@arguments = @arguments.add({ components: [argument] })
|
110
|
-
end
|
111
146
|
end
|
147
|
+
# rubocop:enable Metrics/ClassLength
|
112
148
|
end
|
data/lib/lino/options.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Lino
|
4
|
+
module Options
|
5
|
+
def with_option(option, value, separator: nil, quoting: nil)
|
6
|
+
return self if missing?(value)
|
7
|
+
|
8
|
+
with(options: @options.add(
|
9
|
+
{
|
10
|
+
components: [option, value],
|
11
|
+
separator: separator,
|
12
|
+
quoting: quoting
|
13
|
+
}
|
14
|
+
))
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_repeated_option(option, values, separator: nil, quoting: nil)
|
18
|
+
values.inject(self) do |s, value|
|
19
|
+
s.with_option(option, value, separator: separator, quoting: quoting)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_flag(flag)
|
24
|
+
with(options: @options.add({ components: [flag] }))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'hamster'
|
2
4
|
require_relative 'utilities'
|
3
|
-
require_relative '
|
5
|
+
require_relative 'options'
|
4
6
|
|
5
7
|
module Lino
|
6
8
|
class SubcommandBuilder
|
7
9
|
include Lino::Utilities
|
8
|
-
include Lino::
|
10
|
+
include Lino::Options
|
9
11
|
|
10
12
|
class <<self
|
11
13
|
def for_subcommand(subcommand)
|
@@ -13,16 +15,16 @@ module Lino
|
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
def initialize(subcommand: nil,
|
18
|
+
def initialize(subcommand: nil, options: [])
|
17
19
|
@subcommand = subcommand
|
18
|
-
@
|
20
|
+
@options = Hamster::Vector.new(options)
|
19
21
|
end
|
20
22
|
|
21
23
|
def build(option_separator, option_quoting)
|
22
24
|
components = [
|
23
25
|
@subcommand,
|
24
26
|
map_and_join(
|
25
|
-
@
|
27
|
+
@options,
|
26
28
|
&(quote_with(option_quoting) >> join_with(option_separator))
|
27
29
|
)
|
28
30
|
]
|
@@ -38,7 +40,7 @@ module Lino
|
|
38
40
|
def state
|
39
41
|
{
|
40
42
|
subcommand: @subcommand,
|
41
|
-
|
43
|
+
options: @options
|
42
44
|
}
|
43
45
|
end
|
44
46
|
end
|
data/lib/lino/utilities.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'pp'
|
2
4
|
|
3
5
|
module Lino
|
@@ -14,16 +16,30 @@ module Lino
|
|
14
16
|
|
15
17
|
def quote_with(global_character)
|
16
18
|
lambda do |item|
|
19
|
+
item.merge(
|
20
|
+
components: resolve_components(item, global_character)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def missing?(value)
|
26
|
+
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def resolve_components(item, global_character)
|
32
|
+
components = item[:components]
|
33
|
+
switch = components[0]
|
34
|
+
|
35
|
+
if components.count > 1
|
17
36
|
character = item[:quoting] || global_character
|
18
|
-
components = item[:components]
|
19
|
-
switch = components[0]
|
20
37
|
value = components[1]
|
21
38
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
components)
|
39
|
+
[switch, "#{character}#{value}#{character}"]
|
40
|
+
else
|
41
|
+
components
|
26
42
|
end
|
27
43
|
end
|
28
44
|
end
|
29
|
-
end
|
45
|
+
end
|
data/lib/lino/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Toby Clemson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hamster
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: gem-release
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,33 +109,33 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0.5'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: rake_gpg
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - "~>"
|
102
116
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
117
|
+
version: '0.12'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
122
|
- - "~>"
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0.
|
124
|
+
version: '0.12'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: rake_ssh
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
129
|
- - "~>"
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
131
|
+
version: '0.4'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
136
|
- - "~>"
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
138
|
+
version: '0.4'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rspec
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,19 +151,47 @@ dependencies:
|
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '3.9'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
154
|
+
name: rubocop
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
157
|
- - "~>"
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: '
|
159
|
+
version: '1.12'
|
146
160
|
type: :development
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version: '
|
166
|
+
version: '1.12'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop-rake
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.5'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.5'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rubocop-rspec
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '2.2'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '2.2'
|
153
195
|
- !ruby/object:Gem::Dependency
|
154
196
|
name: simplecov
|
155
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,7 +224,7 @@ files:
|
|
182
224
|
- lib/lino.rb
|
183
225
|
- lib/lino/command_line.rb
|
184
226
|
- lib/lino/command_line_builder.rb
|
185
|
-
- lib/lino/
|
227
|
+
- lib/lino/options.rb
|
186
228
|
- lib/lino/subcommand_builder.rb
|
187
229
|
- lib/lino/utilities.rb
|
188
230
|
- lib/lino/version.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Lino
|
2
|
-
module OptionFlagMixin
|
3
|
-
def with_option(switch, value, separator: nil, quoting: nil)
|
4
|
-
with(switches: add_option(switch, value, separator, quoting))
|
5
|
-
end
|
6
|
-
|
7
|
-
def with_repeated_option(switch, values, separator: nil, quoting: nil)
|
8
|
-
values.each do |value|
|
9
|
-
add_option(switch, value, separator, quoting)
|
10
|
-
end
|
11
|
-
with({})
|
12
|
-
end
|
13
|
-
|
14
|
-
def with_flag(flag)
|
15
|
-
with(switches: @switches.add({ components: [flag] }))
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def add_option(switch, value, separator, quoting)
|
21
|
-
return @switches if missing?(value)
|
22
|
-
|
23
|
-
@switches = @switches.add(
|
24
|
-
{
|
25
|
-
components: [switch, value],
|
26
|
-
separator: separator,
|
27
|
-
quoting: quoting
|
28
|
-
}
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def missing?(value)
|
33
|
-
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|