lino 1.10.0.pre.1 → 2.2.0.pre.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b2d97cd89debbd53f7eae071f39fd98568652e7771957c1e6584ca3756edc76
4
- data.tar.gz: d1e6e64522855b0b0ac7dab0f7d309d4bf79a894bac43690fa965dbc94e4ce02
3
+ metadata.gz: 2d3239ef901d72bbd89e5598f649ee2625db692423799f43ca6f19d5a2c5adc3
4
+ data.tar.gz: 0af4ae160b6537f103ee8c3e44be99dc340e0a6f197fc4c24e0abb4400caeaac
5
5
  SHA512:
6
- metadata.gz: 85f9539da48b728c57ff7725650d5a6fb16c41e401b6313a7bc6dfcfa91747617c21f8732e6b516d4b8f3dd28c21fa96a478b6977b431214d03e335dee3e49b0
7
- data.tar.gz: 73ec86a9cfbabc102ee71d83c954541724eaf7454731568e9c00d7f50691e0726a39332a696a3df49f05feedfae72281ed1d79ead14929f88a60c4207b5ba26d
6
+ metadata.gz: c32a2ca3976575b417d6c2aa2f90c187aca4b1de97cddc668a3da9e2e3f01a8b8e5a67d1c2333aa37f108cac3823682e40a11dbbb7a07e558a2c04ce86bdaec7
7
+ data.tar.gz: 1158933758b878a110f6d956d24484e65a3cd3271c98e39c6f32754f0af2b92beb1d3e2a02950e0b3e604a7db4211960f52c0cb960aa17109b417174db139a10
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lino (1.10.0.pre.1)
4
+ lino (2.2.0.pre.2)
5
5
  hamster (~> 3.0)
6
6
  open4 (~> 1.3)
7
7
 
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
- # commands with an array of arguments
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
- To run only the specs:
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 spec
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
@@ -4,13 +4,22 @@ require 'hamster'
4
4
  require_relative 'utilities'
5
5
  require_relative 'command_line'
6
6
  require_relative 'subcommand_builder'
7
- require_relative 'switches'
7
+ require_relative 'options'
8
8
 
9
9
  module Lino
10
10
  # rubocop:disable Metrics/ClassLength
11
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
+
12
21
  include Lino::Utilities
13
- include Lino::Switches
22
+ include Lino::Options
14
23
 
15
24
  class << self
16
25
  def for_command(command)
@@ -22,19 +31,21 @@ module Lino
22
31
  def initialize(
23
32
  command: nil,
24
33
  subcommands: [],
25
- switches: [],
34
+ options: [],
26
35
  arguments: [],
27
36
  environment_variables: [],
28
37
  option_separator: ' ',
29
- option_quoting: nil
38
+ option_quoting: nil,
39
+ option_placement: :after_command
30
40
  )
31
41
  @command = command
32
42
  @subcommands = Hamster::Vector.new(subcommands)
33
- @switches = Hamster::Vector.new(switches)
43
+ @options = Hamster::Vector.new(options)
34
44
  @arguments = Hamster::Vector.new(arguments)
35
45
  @environment_variables = Hamster::Vector.new(environment_variables)
36
46
  @option_separator = option_separator
37
47
  @option_quoting = option_quoting
48
+ @option_placement = option_placement
38
49
  end
39
50
  # rubocop:enable Metrics/ParameterLists
40
51
 
@@ -48,6 +59,15 @@ module Lino
48
59
  )
49
60
  end
50
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
+
51
71
  def with_option_separator(option_separator)
52
72
  with(option_separator: option_separator)
53
73
  end
@@ -56,13 +76,28 @@ module Lino
56
76
  with(option_quoting: character)
57
77
  end
58
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
+
59
91
  def with_argument(argument)
60
- with(arguments: add_argument(argument))
92
+ return self if missing?(argument)
93
+
94
+ with(arguments: @arguments.add({ components: [argument] }))
61
95
  end
62
96
 
63
97
  def with_arguments(arguments)
64
- arguments.each { |argument| add_argument(argument) }
65
- with({})
98
+ return self if missing?(arguments)
99
+
100
+ arguments.inject(self) { |s, argument| s.with_argument(argument) }
66
101
  end
67
102
 
68
103
  def with_environment_variable(environment_variable, value)
@@ -77,30 +112,36 @@ module Lino
77
112
  end
78
113
 
79
114
  def build
80
- components = [
81
- formatted_environment_variables,
82
- @command,
83
- formatted_switches,
84
- formatted_subcommands,
85
- formatted_arguments
86
- ]
115
+ components = formatted_components
116
+ command_line = SELECTORS[@option_placement]
117
+ .inject([]) { |c, key| c << components[key] }
118
+ .reject(&:empty?)
119
+ .join(' ')
87
120
 
88
- command_string = components.reject(&:empty?).join(' ')
89
-
90
- CommandLine.new(command_string)
121
+ CommandLine.new(command_line)
91
122
  end
92
123
 
93
124
  private
94
125
 
126
+ def formatted_components
127
+ {
128
+ environment_variables: formatted_environment_variables,
129
+ command: @command,
130
+ options: formatted_options,
131
+ subcommands: formatted_subcommands,
132
+ arguments: formatted_arguments
133
+ }
134
+ end
135
+
95
136
  def formatted_environment_variables
96
137
  map_and_join(@environment_variables) do |var|
97
138
  "#{var[0]}=\"#{var[1].to_s.gsub(/"/, '\\"')}\""
98
139
  end
99
140
  end
100
141
 
101
- def formatted_switches
142
+ def formatted_options
102
143
  map_and_join(
103
- @switches,
144
+ @options,
104
145
  &(quote_with(@option_quoting) >> join_with(@option_separator))
105
146
  )
106
147
  end
@@ -112,7 +153,10 @@ module Lino
112
153
  end
113
154
 
114
155
  def formatted_arguments
115
- map_and_join(@arguments, &join_with(' '))
156
+ map_and_join(
157
+ @arguments,
158
+ &join_with(' ')
159
+ )
116
160
  end
117
161
 
118
162
  def with(**replacements)
@@ -123,19 +167,14 @@ module Lino
123
167
  {
124
168
  command: @command,
125
169
  subcommands: @subcommands,
126
- switches: @switches,
170
+ options: @options,
127
171
  arguments: @arguments,
128
172
  environment_variables: @environment_variables,
129
173
  option_separator: @option_separator,
130
- option_quoting: @option_quoting
174
+ option_quoting: @option_quoting,
175
+ option_placement: @option_placement
131
176
  }
132
177
  end
133
-
134
- def add_argument(argument)
135
- return @arguments if missing?(argument)
136
-
137
- @arguments = @arguments.add({ components: [argument] })
138
- end
139
178
  end
140
179
  # rubocop:enable Metrics/ClassLength
141
180
  end
@@ -0,0 +1,35 @@
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
+ return self if missing?(flag)
25
+
26
+ with(options: @options.add({ components: [flag] }))
27
+ end
28
+
29
+ def with_flags(flags)
30
+ return self if missing?(flags)
31
+
32
+ flags.inject(self) { |s, flag| s.with_flag(flag) }
33
+ end
34
+ end
35
+ end
@@ -2,12 +2,12 @@
2
2
 
3
3
  require 'hamster'
4
4
  require_relative 'utilities'
5
- require_relative 'switches'
5
+ require_relative 'options'
6
6
 
7
7
  module Lino
8
8
  class SubcommandBuilder
9
9
  include Lino::Utilities
10
- include Lino::Switches
10
+ include Lino::Options
11
11
 
12
12
  class <<self
13
13
  def for_subcommand(subcommand)
@@ -15,16 +15,16 @@ module Lino
15
15
  end
16
16
  end
17
17
 
18
- def initialize(subcommand: nil, switches: [])
18
+ def initialize(subcommand: nil, options: [])
19
19
  @subcommand = subcommand
20
- @switches = Hamster::Vector.new(switches)
20
+ @options = Hamster::Vector.new(options)
21
21
  end
22
22
 
23
23
  def build(option_separator, option_quoting)
24
24
  components = [
25
25
  @subcommand,
26
26
  map_and_join(
27
- @switches,
27
+ @options,
28
28
  &(quote_with(option_quoting) >> join_with(option_separator))
29
29
  )
30
30
  ]
@@ -40,7 +40,7 @@ module Lino
40
40
  def state
41
41
  {
42
42
  subcommand: @subcommand,
43
- switches: @switches
43
+ options: @options
44
44
  }
45
45
  end
46
46
  end
data/lib/lino/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Lino
4
- VERSION = '1.10.0.pre.1'
4
+ VERSION = '2.2.0.pre.2'
5
5
  end
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: 1.10.0.pre.1
4
+ version: 2.2.0.pre.2
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-04-02 00:00:00.000000000 Z
11
+ date: 2021-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hamster
@@ -224,8 +224,8 @@ files:
224
224
  - lib/lino.rb
225
225
  - lib/lino/command_line.rb
226
226
  - lib/lino/command_line_builder.rb
227
+ - lib/lino/options.rb
227
228
  - lib/lino/subcommand_builder.rb
228
- - lib/lino/switches.rb
229
229
  - lib/lino/utilities.rb
230
230
  - lib/lino/version.rb
231
231
  homepage: https://github.com/infrablocks/lino
data/lib/lino/switches.rb DELETED
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Lino
4
- module Switches
5
- def with_option(switch, value, separator: nil, quoting: nil)
6
- with(switches: add_option(switch, value, separator, quoting))
7
- end
8
-
9
- def with_repeated_option(switch, values, separator: nil, quoting: nil)
10
- values.each do |value|
11
- add_option(switch, value, separator, quoting)
12
- end
13
- with({})
14
- end
15
-
16
- def with_flag(flag)
17
- with(switches: @switches.add({ components: [flag] }))
18
- end
19
-
20
- private
21
-
22
- def add_option(switch, value, separator, quoting)
23
- return @switches if missing?(value)
24
-
25
- @switches = @switches.add(
26
- {
27
- components: [switch, value],
28
- separator: separator,
29
- quoting: quoting
30
- }
31
- )
32
- end
33
- end
34
- end