lino 1.9.0 → 2.2.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/Gemfile +2 -0
- data/Gemfile.lock +29 -1
- data/README.md +63 -3
- 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 +102 -36
- data/lib/lino/options.rb +27 -0
- data/lib/lino/subcommand_builder.rb +8 -6
- data/lib/lino/utilities.rb +21 -9
- data/lib/lino/version.rb +3 -1
- metadata +56 -14
- data/lib/lino/switches.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6b8d73d1b83fd4e09bd2cd61bcc0b0717bb14c43976688dbe26d7b84037f725
|
4
|
+
data.tar.gz: b1e0ee813a1300a0935a78eaa224677ec60d36181a573e3f4a0ec0e9fb426c61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e78ac95f2c066ca9de9b1b04aceae7ab7ed0a744df486558414abfb8bf725f3bb3a9f37c53220fbd68b7a5bbb2ec9d0eb98da2e40d08943692ac07a7799f0a07
|
7
|
+
data.tar.gz: 1697191e1593ceef0785913ec5091ba06cad2af156ba97db7196157da9bf017cfc710d434b71012a44b3470c059669a86f06b1e5fdb865593437ab89a4d662dc
|
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.2.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
@@ -79,7 +79,7 @@ Lino::CommandLineBuilder.for_command('diff')
|
|
79
79
|
|
80
80
|
# => diff ./file1.txt ./file2.txt
|
81
81
|
|
82
|
-
#
|
82
|
+
# ... or alternatively
|
83
83
|
Lino::CommandLineBuilder.for_command('diff')
|
84
84
|
.with_arguments(['./file1.txt', nil, '', './file2.txt'])
|
85
85
|
.build
|
@@ -120,6 +120,18 @@ Lino::CommandLineBuilder.for_command('gcloud')
|
|
120
120
|
.to_s
|
121
121
|
|
122
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
|
123
135
|
|
124
136
|
# commands controlled by environment variables
|
125
137
|
Lino::CommandLineBuilder.for_command('node')
|
@@ -130,6 +142,39 @@ Lino::CommandLineBuilder.for_command('node')
|
|
130
142
|
.to_s
|
131
143
|
|
132
144
|
# => PORT=3030 LOG_LEVEL=debug node ./server.js
|
145
|
+
|
146
|
+
# note: by default, options are placed after the command, before all subcommands
|
147
|
+
# and arguments
|
148
|
+
|
149
|
+
# this can be expressed explicitly
|
150
|
+
Lino::CommandLineBuilder.for_command('gcloud')
|
151
|
+
.with_options_after_command
|
152
|
+
.with_option('--password', 'super-secure')
|
153
|
+
.with_subcommands(%w[sql instances set-root-password some-database])
|
154
|
+
.build
|
155
|
+
.to_s
|
156
|
+
|
157
|
+
# => gcloud --password super-secure sql instances set-root-password some-database
|
158
|
+
|
159
|
+
# options can also come after subcommands
|
160
|
+
Lino::CommandLineBuilder.for_command('gcloud')
|
161
|
+
.with_options_after_subcommands
|
162
|
+
.with_option('--password', 'super-secure')
|
163
|
+
.with_subcommands(%w[sql instances set-root-password some-database])
|
164
|
+
.build
|
165
|
+
.to_s
|
166
|
+
|
167
|
+
# => gcloud sql instances set-root-password some-database --password super-secure
|
168
|
+
|
169
|
+
# options can also come after arguments, although usages of this are rare
|
170
|
+
Lino::CommandLineBuilder.for_command('ls')
|
171
|
+
.with_options_after_arguments
|
172
|
+
.with_flag('-l')
|
173
|
+
.with_argument('/some/directory')
|
174
|
+
.build
|
175
|
+
.to_s
|
176
|
+
|
177
|
+
# => ls /some/directory -l
|
133
178
|
```
|
134
179
|
|
135
180
|
### `Lino::CommandLine`
|
@@ -183,10 +228,25 @@ To install dependencies and run the build, run the pre-commit build:
|
|
183
228
|
./go
|
184
229
|
```
|
185
230
|
|
186
|
-
|
231
|
+
This runs all unit tests and other checks including coverage and code linting /
|
232
|
+
formatting.
|
233
|
+
|
234
|
+
To run only the unit tests, including coverage:
|
235
|
+
|
236
|
+
```shell script
|
237
|
+
./go test:unit
|
238
|
+
```
|
239
|
+
|
240
|
+
To attempt to fix any code linting / formatting issues:
|
241
|
+
|
242
|
+
```shell script
|
243
|
+
./go library:fix
|
244
|
+
```
|
245
|
+
|
246
|
+
To check for code linting / formatting issues without fixing:
|
187
247
|
|
188
248
|
```shell script
|
189
|
-
./go
|
249
|
+
./go library:check
|
190
250
|
```
|
191
251
|
|
192
252
|
You can also run `bin/console` for an interactive prompt that will allow you to
|
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,37 +1,53 @@
|
|
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
|
12
|
+
SELECTORS = {
|
13
|
+
after_command:
|
14
|
+
%i[environment_variables command options subcommands arguments],
|
15
|
+
after_subcommands:
|
16
|
+
%i[environment_variables command subcommands options arguments],
|
17
|
+
after_arguments:
|
18
|
+
%i[environment_variables command subcommands arguments options]
|
19
|
+
}.freeze
|
20
|
+
|
9
21
|
include Lino::Utilities
|
10
|
-
include Lino::
|
22
|
+
include Lino::Options
|
11
23
|
|
12
|
-
class <<self
|
24
|
+
class << self
|
13
25
|
def for_command(command)
|
14
26
|
CommandLineBuilder.new(command: command)
|
15
27
|
end
|
16
28
|
end
|
17
29
|
|
30
|
+
# rubocop:disable Metrics/ParameterLists
|
18
31
|
def initialize(
|
19
32
|
command: nil,
|
20
33
|
subcommands: [],
|
21
|
-
|
34
|
+
options: [],
|
22
35
|
arguments: [],
|
23
36
|
environment_variables: [],
|
24
37
|
option_separator: ' ',
|
25
|
-
option_quoting: nil
|
38
|
+
option_quoting: nil,
|
39
|
+
option_placement: :after_command
|
26
40
|
)
|
27
41
|
@command = command
|
28
42
|
@subcommands = Hamster::Vector.new(subcommands)
|
29
|
-
@
|
43
|
+
@options = Hamster::Vector.new(options)
|
30
44
|
@arguments = Hamster::Vector.new(arguments)
|
31
45
|
@environment_variables = Hamster::Vector.new(environment_variables)
|
32
46
|
@option_separator = option_separator
|
33
47
|
@option_quoting = option_quoting
|
48
|
+
@option_placement = option_placement
|
34
49
|
end
|
50
|
+
# rubocop:enable Metrics/ParameterLists
|
35
51
|
|
36
52
|
def with_subcommand(subcommand, &block)
|
37
53
|
with(
|
@@ -43,6 +59,15 @@ module Lino
|
|
43
59
|
)
|
44
60
|
end
|
45
61
|
|
62
|
+
def with_subcommands(subcommands, &block)
|
63
|
+
without_block = subcommands[0...-1]
|
64
|
+
with_block = subcommands.last
|
65
|
+
|
66
|
+
without_block
|
67
|
+
.inject(self) { |s, sc| s.with_subcommand(sc) }
|
68
|
+
.with_subcommand(with_block, &block)
|
69
|
+
end
|
70
|
+
|
46
71
|
def with_option_separator(option_separator)
|
47
72
|
with(option_separator: option_separator)
|
48
73
|
end
|
@@ -51,42 +76,87 @@ module Lino
|
|
51
76
|
with(option_quoting: character)
|
52
77
|
end
|
53
78
|
|
79
|
+
def with_options_after_command
|
80
|
+
with(option_placement: :after_command)
|
81
|
+
end
|
82
|
+
|
83
|
+
def with_options_after_subcommands
|
84
|
+
with(option_placement: :after_subcommands)
|
85
|
+
end
|
86
|
+
|
87
|
+
def with_options_after_arguments
|
88
|
+
with(option_placement: :after_arguments)
|
89
|
+
end
|
90
|
+
|
54
91
|
def with_argument(argument)
|
55
|
-
|
92
|
+
return self if missing?(argument)
|
93
|
+
|
94
|
+
with(arguments: @arguments.add({ components: [argument] }))
|
56
95
|
end
|
57
96
|
|
58
97
|
def with_arguments(arguments)
|
59
|
-
arguments.
|
60
|
-
with({})
|
98
|
+
arguments.inject(self) { |s, argument| s.with_argument(argument) }
|
61
99
|
end
|
62
100
|
|
63
101
|
def with_environment_variable(environment_variable, value)
|
64
|
-
with(
|
102
|
+
with(
|
103
|
+
environment_variables:
|
104
|
+
@environment_variables.add(
|
105
|
+
[
|
106
|
+
environment_variable, value
|
107
|
+
]
|
108
|
+
)
|
109
|
+
)
|
65
110
|
end
|
66
111
|
|
67
112
|
def build
|
68
|
-
components =
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
&(quote_with(@option_quoting) >> join_with(@option_separator))
|
76
|
-
),
|
77
|
-
map_and_join(@subcommands) do |sub|
|
78
|
-
sub.build(@option_separator, @option_quoting)
|
79
|
-
end,
|
80
|
-
map_and_join(@arguments, &join_with(' '))
|
81
|
-
]
|
82
|
-
|
83
|
-
command_string = components.reject(&:empty?).join(' ')
|
84
|
-
|
85
|
-
CommandLine.new(command_string)
|
113
|
+
components = formatted_components
|
114
|
+
command_line = SELECTORS[@option_placement]
|
115
|
+
.inject([]) { |c, key| c << components[key] }
|
116
|
+
.reject(&:empty?)
|
117
|
+
.join(' ')
|
118
|
+
|
119
|
+
CommandLine.new(command_line)
|
86
120
|
end
|
87
121
|
|
88
122
|
private
|
89
123
|
|
124
|
+
def formatted_components
|
125
|
+
{
|
126
|
+
environment_variables: formatted_environment_variables,
|
127
|
+
command: @command,
|
128
|
+
options: formatted_options,
|
129
|
+
subcommands: formatted_subcommands,
|
130
|
+
arguments: formatted_arguments
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
def formatted_environment_variables
|
135
|
+
map_and_join(@environment_variables) do |var|
|
136
|
+
"#{var[0]}=\"#{var[1].to_s.gsub(/"/, '\\"')}\""
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def formatted_options
|
141
|
+
map_and_join(
|
142
|
+
@options,
|
143
|
+
&(quote_with(@option_quoting) >> join_with(@option_separator))
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
def formatted_subcommands
|
148
|
+
map_and_join(@subcommands) do |sub|
|
149
|
+
sub.build(@option_separator, @option_quoting)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def formatted_arguments
|
154
|
+
map_and_join(
|
155
|
+
@arguments,
|
156
|
+
&join_with(' ')
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
90
160
|
def with(**replacements)
|
91
161
|
CommandLineBuilder.new(**state.merge(replacements))
|
92
162
|
end
|
@@ -95,18 +165,14 @@ module Lino
|
|
95
165
|
{
|
96
166
|
command: @command,
|
97
167
|
subcommands: @subcommands,
|
98
|
-
|
168
|
+
options: @options,
|
99
169
|
arguments: @arguments,
|
100
170
|
environment_variables: @environment_variables,
|
101
171
|
option_separator: @option_separator,
|
102
|
-
option_quoting: @option_quoting
|
172
|
+
option_quoting: @option_quoting,
|
173
|
+
option_placement: @option_placement
|
103
174
|
}
|
104
175
|
end
|
105
|
-
|
106
|
-
def add_argument(argument)
|
107
|
-
return @arguments if missing?(argument)
|
108
|
-
|
109
|
-
@arguments = @arguments.add({ components: [argument] })
|
110
|
-
end
|
111
176
|
end
|
177
|
+
# rubocop:enable Metrics/ClassLength
|
112
178
|
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,20 +16,30 @@ module Lino
|
|
14
16
|
|
15
17
|
def quote_with(global_character)
|
16
18
|
lambda do |item|
|
17
|
-
character = item[:quoting] || global_character
|
18
|
-
components = item[:components]
|
19
|
-
switch = components[0]
|
20
|
-
value = components[1]
|
21
|
-
|
22
19
|
item.merge(
|
23
|
-
|
24
|
-
|
25
|
-
components)
|
20
|
+
components: resolve_components(item, global_character)
|
21
|
+
)
|
26
22
|
end
|
27
23
|
end
|
28
24
|
|
29
25
|
def missing?(value)
|
30
26
|
value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
31
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
|
36
|
+
character = item[:quoting] || global_character
|
37
|
+
value = components[1]
|
38
|
+
|
39
|
+
[switch, "#{character}#{value}#{character}"]
|
40
|
+
else
|
41
|
+
components
|
42
|
+
end
|
43
|
+
end
|
32
44
|
end
|
33
|
-
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.2.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: 2021-
|
11
|
+
date: 2021-04-05 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,8 +224,8 @@ files:
|
|
182
224
|
- lib/lino.rb
|
183
225
|
- lib/lino/command_line.rb
|
184
226
|
- lib/lino/command_line_builder.rb
|
227
|
+
- lib/lino/options.rb
|
185
228
|
- lib/lino/subcommand_builder.rb
|
186
|
-
- lib/lino/switches.rb
|
187
229
|
- lib/lino/utilities.rb
|
188
230
|
- lib/lino/version.rb
|
189
231
|
homepage: https://github.com/infrablocks/lino
|
@@ -201,9 +243,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
201
243
|
version: '2.6'
|
202
244
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
203
245
|
requirements:
|
204
|
-
- - "
|
246
|
+
- - ">"
|
205
247
|
- !ruby/object:Gem::Version
|
206
|
-
version:
|
248
|
+
version: 1.3.1
|
207
249
|
requirements: []
|
208
250
|
rubygems_version: 3.0.1
|
209
251
|
signing_key:
|
data/lib/lino/switches.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Lino
|
2
|
-
module Switches
|
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
|
-
end
|
32
|
-
end
|