rpremote 0.6.0 → 0.7.0

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: b30b1f27c4bdbb212d69bc30f79342bf2caa6ae5c6787125a9627e53f15a714a
4
- data.tar.gz: a7ab212fa48b5f58aa11357ffdf52c2f5c8dbf47c2b00c6d3b7279c38a1431d3
3
+ metadata.gz: 69cb11c8175c8864e4ae4a11108fb37e1ac08bab49b0b61ade2331f550b7d4b6
4
+ data.tar.gz: 7e32c77e20cda016f4b95ad5e60a5ccabf8a5d8aa1570ce8bcf3fd642b700b9d
5
5
  SHA512:
6
- metadata.gz: 6086af03b4459d2c96102e7f884cd888276735ae77d30132189a4191c66892366a7deb51676613966751d343d79d5b53519242ac5171cee9d60044d81a4f7225
7
- data.tar.gz: dc2851099a3a6a3c019a3cbb8936b4b111f9359d964208163d688d4afb4b4cf27135286949304954f7ea685a215f6373f27e23a3c20c3aa4fb5382e93bec6620
6
+ metadata.gz: f690408489ed84040dd492d4872747ec0a523d17bafc76603c885722c5aaca43a3a5f0d74584ca81f0ec5e7b4758bf0477a17f2877af045c81756894962fd5a8
7
+ data.tar.gz: bd1046210f3d48e00604328f72531455f236bd3e348b2bded6495b2681bf383367413ed2083b1469090d24ce10ab37ce85605454efa867e01c88a351807595aa
data/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ Notable changes to the `rpremote` RubyGem will be documented in this file. Repos
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.7.0 - 2026-10-04
8
+
9
+ - Add Bundler-style `group` blocks and `gem ..., group:` to `Mrbgems`; `mrbgems lock|update --with/--without` now selects the locked firmware contents, with exclusions taking precedence, and build/runtime commands consume `Mrbgems.lock` without selecting groups again.
10
+ - Make `Mrbgems.lock` version 2 a self-contained build input, add path checksum verification, and replace build/runtime `--mrbgems` and `--groups` options with `--lockfile`.
11
+ - Keep active RP2040/RP2350 PWM slices clocked during scheduler sleep on PicoRuby 4.0.4, and restore clock gating after the final slice stops.
12
+
7
13
  ## 0.6.0 - 2026-09-20
8
14
 
9
15
  - Change the default PicoRuby version to `latest`, backed by the current `master` branch, while retaining `--language-version` for selecting a release tag.
data/README.ja.md CHANGED
@@ -59,7 +59,9 @@ rpremote mrbgems lock
59
59
  rpremote build
60
60
  ```
61
61
 
62
- `Mrbgems.lock`はGitHubのコミットとローカルgemの内容ハッシュを固定します。`build`は既存のlockを再利用し、`rpremote mrbgems update`だけが新しいコミットを解決します。
62
+ `Mrbgems.lock`は`build`で使うmrbgemを確定します。ビルドは`Mrbgems`を評価せず、GitHub branchも解決せずにlockを読みます。新しいコミットを解決するのは`rpremote mrbgems update`です。
63
+
64
+ 構成ごとのgemは`group :development do ... end`または`gem ..., group: :development`で整理できます。`rpremote mrbgems lock --with production --without test`はグループ外の共通gemとproduction gemをlockへ記録します。除外指定が優先され、`build`、`deploy`、`run`、`exec`はそのlockだけを使います。
63
65
 
64
66
  ファームウェアへ組み込む一方で、すべての`run`、`exec`、`deploy`に先行ロードしないgemには`auto_require: false`を指定できます。アプリケーション側から必要なgemを明示的に`require`してください。
65
67
 
data/README.md CHANGED
@@ -59,7 +59,9 @@ rpremote mrbgems lock
59
59
  rpremote build
60
60
  ```
61
61
 
62
- `Mrbgems.lock` pins GitHub commits and hashes local gem contents. Existing locks are reused by `build`; `rpremote mrbgems update` deliberately resolves new commits.
62
+ `Mrbgems.lock` pins the exact mrbgems used by `build`. Builds read the lock without evaluating `Mrbgems` or resolving GitHub branches; `rpremote mrbgems update` deliberately resolves new commits.
63
+
64
+ Use `group :development do ... end` blocks or `gem ..., group: :development` to organize variant-specific gems. `rpremote mrbgems lock --with production --without test` writes common and production gems to the lock; exclusions take precedence, and `build`, `deploy`, `run`, and `exec` then use exactly that lock.
63
65
 
64
66
  Set `auto_require: false` for a gem that should remain embedded in firmware without being loaded before every `run`, `exec`, or `deploy`. Require that gem explicitly from the application when needed.
65
67
 
data/RELEASING.md CHANGED
@@ -49,7 +49,7 @@ bundle exec rake release
49
49
  After the tag exists on GitHub, create a GitHub Release and attach the exact gem that passed validation. `--verify-tag` prevents GitHub CLI from silently creating a tag at another commit:
50
50
 
51
51
  ```sh
52
- gh release create v0.5.0 rpremote-0.5.0.gem --verify-tag --generate-notes
52
+ gh release create v0.7.0 rpremote-0.7.0.gem --verify-tag --generate-notes
53
53
  ```
54
54
 
55
- Replace `0.5.0` in both places for later versions. Finally, install from RubyGems.org in a fresh environment and run `rpremote --version`.
55
+ Replace `0.7.0` in both places for later versions. Finally, install from RubyGems.org in a fresh environment and run `rpremote --version`.
@@ -1,6 +1,6 @@
1
1
  # Third-Party Notices
2
2
 
3
- `rpremote` does not bundle R2P2 firmware. The `setup` command downloads a selected PicoRuby/R2P2 4.0.3 or 3.4.2 release from the PicoRuby project and verifies its published SHA-256 digest.
3
+ `rpremote` does not bundle R2P2 firmware. The `setup` command downloads and prepares the selected PicoRuby/R2P2 source archive from the PicoRuby project.
4
4
 
5
5
  `setup` also downloads Raspberry Pi's `nuke_universal.uf2` from the official Pico SDK prebuilts release. It is used only by `rpremote bootsel --reset-flash-memory` to erase external flash memory.
6
6
 
@@ -19,7 +19,7 @@ module Rpremote
19
19
  board: Target::DEFAULT_BOARD,
20
20
  cache_dir: defaults.fetch(:cache, Target::DEFAULT_CACHE_DIR),
21
21
  firmware: defaults[:firmware],
22
- mrbgems: nil
22
+ mrbgems_lock: defaults[:mrbgems_lock]
23
23
  }.merge(defaults.except(:cache))
24
24
  OptionParser.new do |parser|
25
25
  parser.on("--language LANGUAGE") { |value| options[:language] = value }
@@ -27,8 +27,8 @@ module Rpremote
27
27
  parser.on("--board BOARD") { |value| options[:board] = value }
28
28
  parser.on("--firmware FILE") { |value| options[:firmware] = value }
29
29
  parser.on("--cache DIR") { |value| options[:cache_dir] = value }
30
- parser.on("--mrbgems FILE") { |value| options[:mrbgems] = value }
31
- parser.on("--no-mrbgems") { options[:mrbgems] = false }
30
+ parser.on("--lockfile FILE") { |value| options[:mrbgems_lock] = value }
31
+ parser.on("--no-mrbgems") { options[:mrbgems_lock] = false }
32
32
  end.parse!(args)
33
33
  raise ArgumentError, "build does not accept arguments" unless args.empty?
34
34
 
@@ -71,12 +71,12 @@ module Rpremote
71
71
  end
72
72
 
73
73
  def add_mrbgems_environment!(environment, options, source_dir, output)
74
- definition = mrbgems_definition(options[:mrbgems])
75
- return unless definition
74
+ lock_file = mrbgems_lock(options[:mrbgems_lock])
75
+ return unless lock_file
76
76
 
77
- manager = mrbgems_class.new(path: definition, cwd: root)
77
+ manager = mrbgems_class.new(lock_path: lock_file, cwd: root)
78
78
  config_language = mrbgems_config_language(
79
- manager.vm, options.fetch(:language), options.fetch(:language_version)
79
+ manager.locked_vm, options.fetch(:language), options.fetch(:language_version)
80
80
  )
81
81
  config_name = "r2p2-#{config_language}-#{options.fetch(:board)}"
82
82
  base_config = File.join(source_dir, "build_config", "#{config_name}.rb")
@@ -90,7 +90,6 @@ module Rpremote
90
90
  environment["RPREMOTE_CONFIG_NAME"] = config_name
91
91
  environment["RPREMOTE_MRUBY_CONFIG"] = overlay.path
92
92
  environment["RPREMOTE_MRBGEMS_FINGERPRINT"] = overlay.fingerprint
93
- output.puts("using Mrbgems: #{manager.path}")
94
93
  output.puts("using Mrbgems.lock: #{manager.lock_path}")
95
94
  end
96
95
 
@@ -103,12 +102,19 @@ module Rpremote
103
102
  modern ? "picoruby" : "microruby"
104
103
  end
105
104
 
106
- def mrbgems_definition(option)
105
+ def mrbgems_lock(option)
107
106
  return if option == false
108
107
 
109
- candidate = File.expand_path(option || Mrbgems::DEFAULT_PATH, root)
108
+ candidate = File.expand_path(option || Mrbgems::DEFAULT_LOCK_PATH, root)
110
109
  return candidate if File.file?(candidate)
111
- raise Error, "mrbgems definition does not exist: #{candidate}" if option
110
+ raise Error, "mrbgems lock file does not exist: #{candidate}" if option
111
+
112
+ definition = File.join(root, Mrbgems::DEFAULT_PATH)
113
+ if File.file?(definition)
114
+ raise Error,
115
+ "Mrbgems.lock does not exist: #{candidate}; " \
116
+ "run `rpremote mrbgems lock` before building"
117
+ end
112
118
 
113
119
  nil
114
120
  end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rpremote
4
+ class CLI
5
+ module FilesystemCommands
6
+ private
7
+
8
+ def fs(args)
9
+ subcommand = args.shift
10
+ recursive = subcommand == "cp" && (args.delete("--recursive") || args.delete("-r"))
11
+ options = parse_connection_options(args)
12
+ case subcommand
13
+ when "cp"
14
+ copy(args, options, recursive: recursive)
15
+ when "push"
16
+ copy(args, options, recursive: true, command: "push")
17
+ when "cat"
18
+ cat(args, options)
19
+ when "ls", "rm", "mkdir"
20
+ filesystem_shell_command(subcommand, args, options)
21
+ else
22
+ raise ArgumentError, "unknown fs command: #{subcommand || "(none)"}"
23
+ end
24
+ rescue Shell::TimeoutError => e
25
+ raise Shell::TimeoutError, "filesystem connection failed: #{e.message}"
26
+ end
27
+
28
+ def copy(args, options, recursive: false, command: "cp")
29
+ usage = command == "push" ? "rpremote fs push LOCAL_DIR :/REMOTE_DIR" : "rpremote fs cp SOURCE DESTINATION"
30
+ raise ArgumentError, "usage: #{usage} [options]" unless args.length == 2
31
+
32
+ source, destination = args
33
+ source_remote = RemotePath.remote?(source)
34
+ destination_remote = RemotePath.remote?(destination)
35
+ raise ArgumentError, "exactly one cp path must be remote (prefix remote paths with :)" if source_remote == destination_remote
36
+ return RecursiveCopy.new(output: stdout, serial: serial, device: device).call(source, destination, options) if recursive
37
+
38
+ ensure_filesystem_connection!(options)
39
+ if source_remote
40
+ data = with_modem(options) { |modem| modem.download(RemotePath.unwrap(source)) }
41
+ File.binwrite(local_destination(destination, source), data)
42
+ stdout.puts("downloaded #{data.bytesize} bytes: #{source} -> #{destination}")
43
+ else
44
+ data = File.binread(source)
45
+ with_modem(options) { |modem| modem.upload(RemotePath.unwrap(destination), data) }
46
+ stdout.puts("uploaded #{data.bytesize} bytes: #{source} -> #{destination}")
47
+ end
48
+ rescue Errno::ENOENT => e
49
+ raise ArgumentError, e.message
50
+ end
51
+
52
+ def cat(args, options)
53
+ raise ArgumentError, "usage: rpremote fs cat :/REMOTE/PATH [options]" unless args.length == 1
54
+ raise ArgumentError, "cat path must be remote (prefix it with :)" unless RemotePath.remote?(args.first)
55
+
56
+ stdout.write(with_modem(options) { |modem| modem.download(RemotePath.unwrap(args.first)) })
57
+ end
58
+
59
+ def filesystem_shell_command(command, args, options)
60
+ usage = "usage: rpremote fs #{command} :/REMOTE/PATH [options]"
61
+ raise ArgumentError, usage unless args.length == 1
62
+
63
+ path = RemotePath.validate(args.first)
64
+ stdout.puts("deleting remote path permanently: #{path}") if command == "rm"
65
+ output = with_shell(options) do |shell|
66
+ shell.execute("#{command} #{Shell.quote_argument(path)}")
67
+ end
68
+ ensure_filesystem_success!(command, output)
69
+ stdout.write(output)
70
+ end
71
+
72
+ def ensure_filesystem_success!(command, output)
73
+ failed = command == "ls" ? output.start_with?("ls:") : !output.empty?
74
+ raise Shell::CommandError, output.strip if failed
75
+ end
76
+
77
+ def ensure_filesystem_connection!(options)
78
+ output = with_shell(options) { |shell| shell.execute("ls '/'") }
79
+ ensure_filesystem_success!("ls", output)
80
+ end
81
+
82
+ def with_modem(options)
83
+ port_path = device.main_port(options[:port])
84
+ serial.open(port_path, baud: options[:baud]) do |port|
85
+ yield PicoModem.new(port, timeout: options[:timeout])
86
+ end
87
+ end
88
+
89
+ def with_shell(options)
90
+ port_path = device.main_port(options[:port])
91
+ serial.open(port_path, baud: options[:baud]) do |port|
92
+ shell = Shell.new(port, timeout: options[:timeout])
93
+ shell.synchronize!
94
+ yield shell
95
+ end
96
+ end
97
+
98
+ def local_destination(destination, source)
99
+ return destination unless File.directory?(destination)
100
+
101
+ File.join(destination, File.basename(RemotePath.unwrap(source)))
102
+ end
103
+ end
104
+ end
105
+ end
data/lib/rpremote/cli.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require "optparse"
4
4
  require_relative "build_command"
5
5
  require_relative "bootsel_command"
6
+ require_relative "cli/filesystem_commands"
6
7
  require_relative "config_show"
7
8
  require_relative "dfu_command"
8
9
  require_relative "deploy_command"
@@ -12,9 +13,10 @@ require_relative "mrbgems_command"
12
13
  require_relative "recursive_copy"
13
14
  require_relative "setup_command"
14
15
 
15
- # rubocop:disable Metrics/ClassLength
16
16
  module Rpremote
17
17
  class CLI
18
+ include FilesystemCommands
19
+
18
20
  def self.start(argv = ARGV, config: Config, **options)
19
21
  new(**options).run(argv, config: config)
20
22
  rescue OptionParser::ParseError, ArgumentError, SystemCallError, Rpremote::Error => e
@@ -136,44 +138,24 @@ module Rpremote
136
138
  ConfigShow.run(args, defaults: config_options, output: stdout)
137
139
  end
138
140
 
139
- def fs(args)
140
- subcommand = args.shift
141
- recursive = subcommand == "cp" && (args.delete("--recursive") || args.delete("-r"))
142
- options = parse_connection_options(args)
143
- case subcommand
144
- when "cp"
145
- copy(args, options, recursive: recursive)
146
- when "push"
147
- copy(args, options, recursive: true, command: "push")
148
- when "cat"
149
- cat(args, options)
150
- when "ls", "rm", "mkdir"
151
- filesystem_shell_command(subcommand, args, options)
152
- else
153
- raise ArgumentError, "unknown fs command: #{subcommand || "(none)"}"
154
- end
155
- rescue Shell::TimeoutError => e
156
- raise Shell::TimeoutError, "filesystem connection failed: #{e.message}"
157
- end
158
-
159
141
  def run_file(args)
160
142
  reset_on_timeout = !args.delete("--reset-on-timeout").nil?
161
- options = parse_connection_options(args)
143
+ options = parse_connection_options(args, mrbgems_lock: true)
162
144
  raise ArgumentError, "usage: rpremote run FILE [options]" unless args.length == 1
163
145
 
164
146
  source = args.first
165
147
  source = File.join(source, "main.rb") if File.directory?(source)
166
- data = prepend_mrbgem_requires(File.binread(source))
148
+ data = prepend_mrbgem_requires(File.binread(source), options[:mrbgems_lock])
167
149
  execute_temporary(data, options, output: stdout, reset_on_timeout: reset_on_timeout)
168
150
  rescue Errno::ENOENT => e
169
151
  raise ArgumentError, e.message
170
152
  end
171
153
 
172
154
  def execute_code(args)
173
- options = parse_connection_options(args)
155
+ options = parse_connection_options(args, mrbgems_lock: true)
174
156
  raise ArgumentError, "usage: rpremote exec CODE [options]" unless args.length == 1
175
157
 
176
- execute_temporary(prepend_mrbgem_requires(args.first), options, output: stdout)
158
+ execute_temporary(prepend_mrbgem_requires(args.first, options[:mrbgems_lock]), options, output: stdout)
177
159
  end
178
160
 
179
161
  def execute_temporary(data, options, output: nil, reset_on_timeout: false)
@@ -197,8 +179,13 @@ module Rpremote
197
179
  "#{timeout_error.message}; automatic reset failed: #{e.message}"
198
180
  end
199
181
 
200
- def prepend_mrbgem_requires(data)
201
- Mrbgems.new(cwd: Dir.pwd).prepend_requires(data)
182
+ def prepend_mrbgem_requires(data, lock_file)
183
+ return data if lock_file == false
184
+
185
+ path = lock_file || Mrbgems::DEFAULT_LOCK_PATH
186
+ raise ArgumentError, "mrbgems lock file does not exist: #{path}" if lock_file && !File.file?(path)
187
+
188
+ Mrbgems.new(cwd: Dir.pwd, lock_path: path).prepend_requires(data)
202
189
  end
203
190
 
204
191
  def interactive(args, repl: false)
@@ -227,18 +214,23 @@ module Rpremote
227
214
  stdout.puts("reset R2P2: #{port_path}")
228
215
  end
229
216
 
230
- def parse_connection_options(args, default_timeout: PicoModem::DEFAULT_TIMEOUT)
217
+ def parse_connection_options(args, default_timeout: PicoModem::DEFAULT_TIMEOUT, mrbgems_lock: false)
231
218
  options = {
232
219
  port: config_options[:port],
233
220
  baud: config_options.fetch(:baud, Serial::BAUD_RATE),
234
221
  timeout: config_options.fetch(:timeout, default_timeout),
235
222
  language: config_options.fetch(:language, Target::DEFAULT_LANGUAGE)
236
223
  }
224
+ options[:mrbgems_lock] = config_options[:mrbgems_lock] if mrbgems_lock
237
225
  parser = OptionParser.new do |opts|
238
226
  opts.on("--port PORT") { |value| options[:port] = value }
239
227
  opts.on("--baud RATE", Integer) { |value| options[:baud] = value }
240
228
  opts.on("--timeout SECONDS", Float) { |value| options[:timeout] = value }
241
229
  opts.on("--language LANGUAGE") { |value| options[:language] = value }
230
+ if mrbgems_lock
231
+ opts.on("--lockfile FILE") { |value| options[:mrbgems_lock] = value }
232
+ opts.on("--no-mrbgems") { options[:mrbgems_lock] = false }
233
+ end
242
234
  end
243
235
  parser.parse!(args)
244
236
  raise ArgumentError, "--baud must be positive" unless options[:baud].positive?
@@ -246,82 +238,5 @@ module Rpremote
246
238
 
247
239
  options
248
240
  end
249
-
250
- def copy(args, options, recursive: false, command: "cp")
251
- usage = command == "push" ? "rpremote fs push LOCAL_DIR :/REMOTE_DIR" : "rpremote fs cp SOURCE DESTINATION"
252
- raise ArgumentError, "usage: #{usage} [options]" unless args.length == 2
253
-
254
- source, destination = args
255
- source_remote = RemotePath.remote?(source)
256
- destination_remote = RemotePath.remote?(destination)
257
- raise ArgumentError, "exactly one cp path must be remote (prefix remote paths with :)" if source_remote == destination_remote
258
- return RecursiveCopy.new(output: stdout, serial: serial, device: device).call(source, destination, options) if recursive
259
-
260
- ensure_filesystem_connection!(options)
261
- if source_remote
262
- data = with_modem(options) { |modem| modem.download(RemotePath.unwrap(source)) }
263
- File.binwrite(local_destination(destination, source), data)
264
- stdout.puts("downloaded #{data.bytesize} bytes: #{source} -> #{destination}")
265
- else
266
- data = File.binread(source)
267
- with_modem(options) { |modem| modem.upload(RemotePath.unwrap(destination), data) }
268
- stdout.puts("uploaded #{data.bytesize} bytes: #{source} -> #{destination}")
269
- end
270
- rescue Errno::ENOENT => e
271
- raise ArgumentError, e.message
272
- end
273
-
274
- def cat(args, options)
275
- raise ArgumentError, "usage: rpremote fs cat :/REMOTE/PATH [options]" unless args.length == 1
276
- raise ArgumentError, "cat path must be remote (prefix it with :)" unless RemotePath.remote?(args.first)
277
-
278
- stdout.write(with_modem(options) { |modem| modem.download(RemotePath.unwrap(args.first)) })
279
- end
280
-
281
- def filesystem_shell_command(command, args, options)
282
- usage = "usage: rpremote fs #{command} :/REMOTE/PATH [options]"
283
- raise ArgumentError, usage unless args.length == 1
284
-
285
- path = RemotePath.validate(args.first)
286
- stdout.puts("deleting remote path permanently: #{path}") if command == "rm"
287
- output = with_shell(options) do |shell|
288
- shell.execute("#{command} #{Shell.quote_argument(path)}")
289
- end
290
- ensure_filesystem_success!(command, output)
291
- stdout.write(output)
292
- end
293
-
294
- def ensure_filesystem_success!(command, output)
295
- failed = command == "ls" ? output.start_with?("ls:") : !output.empty?
296
- raise Shell::CommandError, output.strip if failed
297
- end
298
-
299
- def ensure_filesystem_connection!(options)
300
- output = with_shell(options) { |shell| shell.execute("ls '/'") }
301
- ensure_filesystem_success!("ls", output)
302
- end
303
-
304
- def with_modem(options)
305
- port_path = device.main_port(options[:port])
306
- serial.open(port_path, baud: options[:baud]) do |port|
307
- yield PicoModem.new(port, timeout: options[:timeout])
308
- end
309
- end
310
-
311
- def with_shell(options)
312
- port_path = device.main_port(options[:port])
313
- serial.open(port_path, baud: options[:baud]) do |port|
314
- shell = Shell.new(port, timeout: options[:timeout])
315
- shell.synchronize!
316
- yield shell
317
- end
318
- end
319
-
320
- def local_destination(destination, source)
321
- return destination unless File.directory?(destination)
322
-
323
- File.join(destination, File.basename(RemotePath.unwrap(source)))
324
- end
325
241
  end
326
242
  end
327
- # rubocop:enable Metrics/ClassLength
@@ -16,17 +16,17 @@ module Rpremote
16
16
  baud: Integer,
17
17
  timeout: Numeric,
18
18
  language: String,
19
- mrbgems: [String, FalseClass].freeze
19
+ mrbgems_lock: [String, FalseClass].freeze
20
20
  }.freeze
21
21
  COMMAND_OPTIONS = {
22
22
  "setup" => %i[cache language language_version],
23
- "build" => %i[cache language language_version board firmware mrbgems],
23
+ "build" => %i[cache language language_version board firmware mrbgems_lock],
24
24
  "bootsel" => %i[mount port baud timeout],
25
- "deploy" => %i[cache language language_version board firmware mrbgems mount port baud timeout],
25
+ "deploy" => %i[cache language language_version board firmware mrbgems_lock mount port baud timeout],
26
26
  "dfu" => %i[cache language language_version port baud timeout],
27
27
  "flash" => %i[cache language language_version board firmware mount port timeout],
28
- "run" => %i[port baud timeout language],
29
- "exec" => %i[port baud timeout language],
28
+ "run" => %i[port baud timeout language mrbgems_lock],
29
+ "exec" => %i[port baud timeout language mrbgems_lock],
30
30
  "reset" => %i[port baud timeout],
31
31
  "monitor" => %i[port baud timeout],
32
32
  "repl" => %i[port baud timeout],
@@ -106,6 +106,7 @@ module Rpremote
106
106
  expected = OPTION_TYPES[key]
107
107
  raise Error, "unknown config option: #{key}" unless expected
108
108
  raise Error, "config option #{key} must be a #{type_name(expected)}" unless valid_value?(value, expected)
109
+
109
110
  next unless %i[baud timeout].include?(key)
110
111
  next if value.positive?
111
112
 
@@ -38,7 +38,7 @@ module Rpremote
38
38
  board: defaults.fetch(:board, Target::DEFAULT_BOARD),
39
39
  cache: defaults.fetch(:cache, Target::DEFAULT_CACHE_DIR),
40
40
  firmware: defaults[:firmware],
41
- mrbgems: defaults[:mrbgems],
41
+ mrbgems_lock: defaults[:mrbgems_lock],
42
42
  mount: defaults[:mount],
43
43
  port: defaults[:port],
44
44
  baud: defaults.fetch(:baud, Serial::BAUD_RATE),
@@ -53,8 +53,8 @@ module Rpremote
53
53
  opts.on("--board BOARD") { |value| options[:board] = value }
54
54
  opts.on("--cache DIR") { |value| options[:cache] = value }
55
55
  opts.on("--firmware FILE") { |value| options[:firmware] = value }
56
- opts.on("--mrbgems FILE") { |value| options[:mrbgems] = value }
57
- opts.on("--no-mrbgems") { options[:mrbgems] = false }
56
+ opts.on("--lockfile FILE") { |value| options[:mrbgems_lock] = value }
57
+ opts.on("--no-mrbgems") { options[:mrbgems_lock] = false }
58
58
  opts.on("--mount DIR") { |value| options[:mount] = value }
59
59
  opts.on("--port PORT") { |value| options[:port] = value }
60
60
  opts.on("--baud RATE", Integer) { |value| options[:baud] = value }
@@ -70,19 +70,27 @@ module Rpremote
70
70
  cache_dir: options[:cache],
71
71
  firmware: options[:firmware]
72
72
  )
73
+ print_target_options(target)
74
+ print_runtime_options(options)
75
+ end
76
+
77
+ def print_target_options(target)
73
78
  output.puts("language=#{target.language}")
74
79
  output.puts("language_version=#{target.language_version}")
75
80
  output.puts("board=#{target.board}")
76
81
  output.puts("cache=#{target.cache_dir}")
77
82
  output.puts("firmware=#{target.firmware_path}")
78
- output.puts("mrbgems=#{mrbgems_value(options[:mrbgems])}")
83
+ end
84
+
85
+ def print_runtime_options(options)
86
+ output.puts("mrbgems_lock=#{mrbgems_lock_value(options[:mrbgems_lock])}")
79
87
  output.puts("mount=#{options[:mount] || "auto"}")
80
88
  output.puts("port=#{options[:port] || "auto"}")
81
89
  output.puts("baud=#{options[:baud]}")
82
90
  output.puts("timeout=#{options[:timeout]}")
83
91
  end
84
92
 
85
- def mrbgems_value(value)
93
+ def mrbgems_lock_value(value)
86
94
  return "false" if value == false
87
95
 
88
96
  value || "auto"