rpremote 0.2.0 → 0.3.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.
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rpremote
4
+ class RecursiveCopy
5
+ def initialize(output:, serial: Serial, device: Device)
6
+ @output = output
7
+ @serial = serial
8
+ @device = device
9
+ end
10
+
11
+ def call(source, destination, options)
12
+ validate!(source, destination)
13
+ remote_root = RemotePath.validate(destination)
14
+ directories, files = collect(source, remote_root)
15
+ create_directories(directories, options)
16
+ upload_files(files, options)
17
+ output.puts("uploaded #{files.length} files: #{source} -> #{destination}")
18
+ rescue Errno::ENOENT => e
19
+ raise ArgumentError, e.message
20
+ end
21
+
22
+ private
23
+
24
+ attr_reader :output, :serial, :device
25
+
26
+ def validate!(source, destination)
27
+ raise ArgumentError, "recursive cp only supports a local source and remote destination" if RemotePath.remote?(source)
28
+ raise ArgumentError, "recursive cp source must be a directory: #{source}" unless File.directory?(source)
29
+
30
+ RemotePath.validate(destination)
31
+ end
32
+
33
+ def collect(source, remote_root)
34
+ directories = [remote_root]
35
+ files = []
36
+ local_entries(source).each do |path|
37
+ remote_path = File.join(remote_root, path.delete_prefix("#{source}/"))
38
+ File.directory?(path) ? directories << remote_path : files << [path, remote_path]
39
+ end
40
+ [directories.sort_by { |path| [path.count("/"), path] }.uniq, files.sort]
41
+ end
42
+
43
+ def local_entries(source)
44
+ entries = Dir.glob(File.join(source, "**", "*"), File::FNM_DOTMATCH).reject do |path|
45
+ %w[. ..].include?(File.basename(path))
46
+ end
47
+ symbolic_link = entries.find { |path| File.symlink?(path) }
48
+ raise ArgumentError, "recursive cp does not support symbolic links: #{symbolic_link}" if symbolic_link
49
+
50
+ entries
51
+ end
52
+
53
+ def create_directories(directories, options)
54
+ with_port(options) do |port|
55
+ shell = Shell.new(port, timeout: options[:timeout])
56
+ shell.synchronize!
57
+ directories.each do |path|
58
+ quoted_path = Shell.quote_argument(path)
59
+ next unless shell.execute("ls #{quoted_path}").start_with?("ls:")
60
+
61
+ result = shell.execute("mkdir #{quoted_path}")
62
+ raise Shell::CommandError, result.strip unless result.empty?
63
+
64
+ output.puts("created remote directory: :#{path}")
65
+ end
66
+ end
67
+ end
68
+
69
+ def upload_files(files, options)
70
+ with_port(options) do |port|
71
+ modem = PicoModem.new(port, timeout: options[:timeout])
72
+ files.each do |local_path, remote_path|
73
+ size = modem.upload(remote_path, File.binread(local_path))
74
+ output.puts("uploaded #{size} bytes: #{local_path} -> :#{remote_path}")
75
+ end
76
+ end
77
+ end
78
+
79
+ def with_port(options, &)
80
+ port_path = device.main_port(options[:port])
81
+ serial.open(port_path, baud: options[:baud], &)
82
+ end
83
+ end
84
+ end
@@ -3,6 +3,8 @@
3
3
  module Rpremote
4
4
  class Runner
5
5
  REMOTE_DIRECTORY = "/home"
6
+ RUN_REMOTE_PATH = "#{REMOTE_DIRECTORY}/.rpremote-run.rb".freeze
7
+ DEPLOY_REMOTE_PATH = "#{REMOTE_DIRECTORY}/.rpremote-deploy.rb".freeze
6
8
 
7
9
  attr_reader :io, :timeout
8
10
 
@@ -20,16 +22,33 @@ module Rpremote
20
22
  @path_factory = path_factory || method(:temporary_path)
21
23
  end
22
24
 
23
- def run(data, output: nil)
24
- remote_path = @path_factory.call
25
+ def run(data, output: nil, cleanup: true, remote_path: nil, diagnostics: nil)
26
+ remote_path ||= @path_factory.call
25
27
  shell = @shell_class.new(io, timeout: timeout)
28
+ trace(diagnostics, "SYNC_BEFORE_UPLOAD_START")
26
29
  shell.synchronize!
30
+ trace(diagnostics, "SYNC_BEFORE_UPLOAD_DONE")
31
+ trace(diagnostics, "UPLOAD_START", "bytes=#{data.bytesize},path=#{remote_path}")
27
32
  @modem_class.new(io, timeout: timeout).upload(remote_path, data)
33
+ trace(diagnostics, "UPLOAD_DONE")
34
+ trace(diagnostics, "SYNC_BEFORE_RUN_START")
28
35
  shell.synchronize!
36
+ trace(diagnostics, "SYNC_BEFORE_RUN_DONE")
29
37
  shell_ready = true
30
- output ? shell.execute("./#{File.basename(remote_path)}", output: output) : shell.execute("./#{File.basename(remote_path)}")
38
+ command = "./#{File.basename(remote_path)}"
39
+ trace(diagnostics, "EXECUTE_START", "command=#{command}")
40
+ result = output ? shell.execute(command, output: output, idle_timeout: true) : shell.execute(command, idle_timeout: true)
41
+ trace(diagnostics, "EXECUTE_DONE", "bytes=#{result.to_s.bytesize}")
42
+ result
43
+ rescue StandardError => e
44
+ trace(diagnostics, "ERROR", "class=#{e.class},message=#{e.message.to_s.gsub("\n", " ")}")
45
+ raise
31
46
  ensure
32
- cleanup(shell, remote_path) if shell_ready && remote_path
47
+ if cleanup && shell_ready && remote_path
48
+ trace(diagnostics, "CLEANUP_START", "path=#{remote_path}")
49
+ cleanup(shell, remote_path)
50
+ trace(diagnostics, "CLEANUP_DONE")
51
+ end
33
52
  end
34
53
 
35
54
  private
@@ -40,9 +59,17 @@ module Rpremote
40
59
  nil
41
60
  end
42
61
 
62
+ def trace(diagnostics, event, details = nil)
63
+ return unless diagnostics
64
+
65
+ line = "rpremote: run event=#{event}"
66
+ line += ",#{details}" if details
67
+ diagnostics.puts(line)
68
+ diagnostics.flush if diagnostics.respond_to?(:flush)
69
+ end
70
+
43
71
  def temporary_path
44
- stamp = (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1_000_000).to_i
45
- "#{REMOTE_DIRECTORY}/.rpremote-run-#{Process.pid}-#{stamp}.rb"
72
+ RUN_REMOTE_PATH
46
73
  end
47
74
  end
48
75
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "optparse"
4
+ require_relative "nuke_firmware"
4
5
 
5
6
  module Rpremote
6
7
  class SetupCommand
7
- def self.run(args, defaults:, config:, config_filename:, output: $stdout)
8
+ def self.run(args, defaults:, config:, config_filename:, output: $stdout, nuke_firmware: NukeFirmware)
8
9
  options = {
9
10
  force: false,
10
11
  cache_dir: defaults.fetch(:cache, Target::DEFAULT_CACHE_DIR),
@@ -29,6 +30,8 @@ module Rpremote
29
30
  cache_dir: target.cache_dir
30
31
  ).setup(force: options[:force])
31
32
  output.puts("installed #{target.language} #{target.language_version}: #{path}")
33
+ nuke_path = nuke_firmware.new.setup(force: options[:force])
34
+ output.puts("installed Raspberry Pi nuke firmware: #{nuke_path}")
32
35
  end
33
36
  end
34
37
  end
@@ -29,11 +29,12 @@ module Rpremote
29
29
 
30
30
  attr_reader :io, :timeout
31
31
 
32
- def initialize(io, timeout: DEFAULT_TIMEOUT)
32
+ def initialize(io, timeout: DEFAULT_TIMEOUT, clock: nil)
33
33
  raise ArgumentError, "timeout must be positive" unless timeout.positive?
34
34
 
35
35
  @io = io
36
36
  @timeout = timeout
37
+ @clock = clock || -> { Process.clock_gettime(Process::CLOCK_MONOTONIC) }
37
38
  end
38
39
 
39
40
  def synchronize!
@@ -43,12 +44,14 @@ module Rpremote
43
44
  nil
44
45
  end
45
46
 
46
- def execute(command, output: nil)
47
+ def execute(command, output: nil, idle_timeout: false)
47
48
  command = validate_command(command)
48
49
  send_command(command)
49
50
  echo = ECHO_START + command.b + ERASE_LINE
50
51
  stream_state = {}
51
- response = read_until_prompt(after: echo) { |buffer| stream_output(output, buffer, echo, stream_state) }
52
+ response = read_until_prompt(after: echo, idle_timeout: idle_timeout) do |buffer|
53
+ stream_output(output, buffer, echo, stream_state)
54
+ end
52
55
  command_output = extract_output(response, command)
53
56
  ruby_exception = command_output.include?(RUBY_EXCEPTION_STATUS)
54
57
  command_output = remove_ruby_exception_status(command_output)
@@ -76,7 +79,7 @@ module Rpremote
76
79
  command
77
80
  end
78
81
 
79
- def read_until_prompt(wait: timeout, after: nil)
82
+ def read_until_prompt(wait: timeout, after: nil, idle_timeout: false)
80
83
  deadline = monotonic_time + wait
81
84
  buffer = +"".b
82
85
  loop do
@@ -85,6 +88,7 @@ module Rpremote
85
88
  return buffer if prompt_at && buffer.index(PROMPT_END, prompt_at + PROMPT_START.bytesize)
86
89
 
87
90
  buffer << read_available(deadline)
91
+ deadline = monotonic_time + wait if idle_timeout
88
92
  answer_terminal_queries(buffer)
89
93
  yield buffer if block_given?
90
94
  end
@@ -186,7 +190,7 @@ module Rpremote
186
190
  end
187
191
 
188
192
  def monotonic_time
189
- Process.clock_gettime(Process::CLOCK_MONOTONIC)
193
+ @clock.call
190
194
  end
191
195
  end
192
196
  end
@@ -49,7 +49,7 @@ module Rpremote
49
49
  data = serial_io.read_nonblock(BUFFER_SIZE)
50
50
  return false if data.nil? || data.empty?
51
51
 
52
- output.write(data)
52
+ output.write(normalize_line_endings(data))
53
53
  output.flush if output.respond_to?(:flush)
54
54
  true
55
55
  else
@@ -75,6 +75,18 @@ module Rpremote
75
75
  true
76
76
  end
77
77
 
78
+ # input.raw disables the terminal's usual LF-to-CRLF output conversion.
79
+ # Preserve device CRLF while making a bare LF start at the left margin.
80
+ def normalize_line_endings(data)
81
+ normalized = +"".b
82
+ data.each_byte do |byte|
83
+ normalized << "\r" if byte == 0x0A && !@previous_output_was_cr
84
+ normalized << byte
85
+ @previous_output_was_cr = byte == 0x0D
86
+ end
87
+ normalized
88
+ end
89
+
78
90
  def selectable_serial
79
91
  @selectable_serial ||= serial_io.respond_to?(:to_io) ? serial_io.to_io : serial_io
80
92
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rpremote
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/rpremote.rb CHANGED
@@ -19,8 +19,10 @@ require_relative "rpremote/terminal"
19
19
  require_relative "rpremote/shell"
20
20
  require_relative "rpremote/runner"
21
21
  require_relative "rpremote/resetter"
22
+ require_relative "rpremote/recursive_copy"
22
23
  require_relative "rpremote/picoruby_source_patch"
23
24
  require_relative "rpremote/language_source"
25
+ require_relative "rpremote/nuke_firmware"
24
26
  require_relative "rpremote/mrbgems"
25
27
  require_relative "rpremote/mrbgems_command"
26
28
  require_relative "rpremote/flasher"
@@ -29,3 +31,5 @@ require_relative "rpremote/dfu_command"
29
31
  require_relative "rpremote/setup_command"
30
32
  require_relative "rpremote/build_command"
31
33
  require_relative "rpremote/flash_command"
34
+ require_relative "rpremote/bootsel_command"
35
+ require_relative "rpremote/deploy_command"
@@ -0,0 +1,71 @@
1
+ diff --git a/mrbgems/picoruby-machine/include/machine.h b/mrbgems/picoruby-machine/include/machine.h
2
+ --- a/mrbgems/picoruby-machine/include/machine.h
3
+ +++ b/mrbgems/picoruby-machine/include/machine.h
4
+ @@ -48,1 +48,2 @@
5
+ void Machine_reboot(void);
6
+ +void Machine_bootsel(void);
7
+ diff --git a/mrbgems/picoruby-machine/mrblib/machine.rb b/mrbgems/picoruby-machine/mrblib/machine.rb
8
+ --- a/mrbgems/picoruby-machine/mrblib/machine.rb
9
+ +++ b/mrbgems/picoruby-machine/mrblib/machine.rb
10
+ @@ -22,0 +23,4 @@
11
+ + def self.bootsel
12
+ + self._bootsel
13
+ + end
14
+ +
15
+ diff --git a/mrbgems/picoruby-machine/ports/rp2040/machine.c b/mrbgems/picoruby-machine/ports/rp2040/machine.c
16
+ --- a/mrbgems/picoruby-machine/ports/rp2040/machine.c
17
+ +++ b/mrbgems/picoruby-machine/ports/rp2040/machine.c
18
+ @@ -12,0 +13,1 @@
19
+ +#include "pico/bootrom.h"
20
+ @@ -32,0 +34,6 @@
21
+ +void
22
+ +Machine_bootsel(void)
23
+ +{
24
+ + rom_reset_usb_boot(0, 0);
25
+ +}
26
+ +
27
+ diff --git a/mrbgems/picoruby-machine/src/mruby/machine.c b/mrbgems/picoruby-machine/src/mruby/machine.c
28
+ --- a/mrbgems/picoruby-machine/src/mruby/machine.c
29
+ +++ b/mrbgems/picoruby-machine/src/mruby/machine.c
30
+ @@ -417,0 +418,11 @@
31
+ +static mrb_value
32
+ +mrb_s__bootsel(mrb_state *mrb, mrb_value self)
33
+ +{
34
+ +#if !defined(PICORB_PLATFORM_POSIX)
35
+ + Machine_bootsel();
36
+ +#else
37
+ + mrb_raise(mrb, E_NOTIMP_ERROR, "Machine._bootsel is not available on this platform");
38
+ +#endif
39
+ + return mrb_nil_value();
40
+ +}
41
+ +
42
+ @@ -443,0 +455,1 @@
43
+ + mrb_define_class_method_id(mrb, module_Machine, MRB_SYM(_bootsel), mrb_s__bootsel, MRB_ARGS_NONE());
44
+ diff --git a/mrbgems/picoruby-machine/src/mrubyc/machine.c b/mrbgems/picoruby-machine/src/mrubyc/machine.c
45
+ --- a/mrbgems/picoruby-machine/src/mrubyc/machine.c
46
+ +++ b/mrbgems/picoruby-machine/src/mrubyc/machine.c
47
+ @@ -252,0 +253,11 @@
48
+ +static void
49
+ +c_Machine__bootsel(mrbc_vm *vm, mrbc_value *v, int argc)
50
+ +{
51
+ +#if !defined(PICORB_PLATFORM_POSIX)
52
+ + Machine_bootsel();
53
+ +#else
54
+ + mrbc_raise(vm, MRBC_CLASS(RuntimeError), "Machine.bootsel is not available on this platform.");
55
+ +#endif
56
+ + SET_NIL_RETURN();
57
+ +}
58
+ +
59
+ @@ -439,0 +451,1 @@
60
+ + mrbc_define_method(vm, module_Machine, "_bootsel", c_Machine__bootsel);
61
+ diff --git a/mrbgems/picoruby-shell/shell_executables/_path.txt b/mrbgems/picoruby-shell/shell_executables/_path.txt
62
+ --- a/mrbgems/picoruby-shell/shell_executables/_path.txt
63
+ +++ b/mrbgems/picoruby-shell/shell_executables/_path.txt
64
+ @@ -16,0 +17,1 @@
65
+ +/bin/bootsel
66
+ diff --git a/mrbgems/picoruby-shell/shell_executables/bootsel.rb b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
67
+ new file mode 100644
68
+ --- /dev/null
69
+ +++ b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
70
+ @@ -0,0 +1 @@
71
+ +Machine.bootsel
@@ -0,0 +1,71 @@
1
+ diff --git a/mrbgems/picoruby-machine/include/machine.h b/mrbgems/picoruby-machine/include/machine.h
2
+ --- a/mrbgems/picoruby-machine/include/machine.h
3
+ +++ b/mrbgems/picoruby-machine/include/machine.h
4
+ @@ -68,1 +68,2 @@
5
+ void Machine_reboot(void);
6
+ +void Machine_bootsel(void);
7
+ diff --git a/mrbgems/picoruby-machine/mrblib/machine.rb b/mrbgems/picoruby-machine/mrblib/machine.rb
8
+ --- a/mrbgems/picoruby-machine/mrblib/machine.rb
9
+ +++ b/mrbgems/picoruby-machine/mrblib/machine.rb
10
+ @@ -22,0 +23,4 @@
11
+ + def self.bootsel
12
+ + self._bootsel
13
+ + end
14
+ +
15
+ diff --git a/mrbgems/picoruby-machine/ports/rp2040/machine.c b/mrbgems/picoruby-machine/ports/rp2040/machine.c
16
+ --- a/mrbgems/picoruby-machine/ports/rp2040/machine.c
17
+ +++ b/mrbgems/picoruby-machine/ports/rp2040/machine.c
18
+ @@ -10,0 +11,1 @@
19
+ +#include "pico/bootrom.h"
20
+ @@ -42,0 +44,6 @@
21
+ +void
22
+ +Machine_bootsel(void)
23
+ +{
24
+ + rom_reset_usb_boot(0, 0);
25
+ +}
26
+ +
27
+ diff --git a/mrbgems/picoruby-machine/src/mruby/machine.c b/mrbgems/picoruby-machine/src/mruby/machine.c
28
+ --- a/mrbgems/picoruby-machine/src/mruby/machine.c
29
+ +++ b/mrbgems/picoruby-machine/src/mruby/machine.c
30
+ @@ -496,0 +497,11 @@
31
+ +static mrb_value
32
+ +mrb_s__bootsel(mrb_state *mrb, mrb_value self)
33
+ +{
34
+ +#if !defined(PICORB_PLATFORM_POSIX)
35
+ + Machine_bootsel();
36
+ +#else
37
+ + mrb_raise(mrb, E_NOTIMP_ERROR, "Machine._bootsel is not available on this platform");
38
+ +#endif
39
+ + return mrb_nil_value();
40
+ +}
41
+ +
42
+ @@ -529,0 +541,1 @@
43
+ + mrb_define_class_method_id(mrb, module_Machine, MRB_SYM(_bootsel), mrb_s__bootsel, MRB_ARGS_NONE());
44
+ diff --git a/mrbgems/picoruby-machine/src/mrubyc/machine.c b/mrbgems/picoruby-machine/src/mrubyc/machine.c
45
+ --- a/mrbgems/picoruby-machine/src/mrubyc/machine.c
46
+ +++ b/mrbgems/picoruby-machine/src/mrubyc/machine.c
47
+ @@ -316,0 +317,11 @@
48
+ +static void
49
+ +c_Machine__bootsel(mrbc_vm *vm, mrbc_value *v, int argc)
50
+ +{
51
+ +#if !defined(PICORB_PLATFORM_POSIX)
52
+ + Machine_bootsel();
53
+ +#else
54
+ + mrbc_raise(vm, MRBC_CLASS(RuntimeError), "Machine.bootsel is not available on this platform.");
55
+ +#endif
56
+ + SET_NIL_RETURN();
57
+ +}
58
+ +
59
+ @@ -546,0 +558,1 @@
60
+ + mrbc_define_method(vm, module_Machine, "_bootsel", c_Machine__bootsel);
61
+ diff --git a/mrbgems/picoruby-shell/shell_executables/_path.txt b/mrbgems/picoruby-shell/shell_executables/_path.txt
62
+ --- a/mrbgems/picoruby-shell/shell_executables/_path.txt
63
+ +++ b/mrbgems/picoruby-shell/shell_executables/_path.txt
64
+ @@ -17,0 +18,1 @@
65
+ +/bin/bootsel
66
+ diff --git a/mrbgems/picoruby-shell/shell_executables/bootsel.rb b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
67
+ new file mode 100644
68
+ --- /dev/null
69
+ +++ b/mrbgems/picoruby-shell/shell_executables/bootsel.rb
70
+ @@ -0,0 +1 @@
71
+ +Machine.bootsel
data/sig/rpremote.rbs CHANGED
@@ -166,6 +166,15 @@ module Rpremote
166
166
  def source_dir: () -> String
167
167
  end
168
168
 
169
+ class NukeFirmware
170
+ URL: String
171
+ FILENAME: String
172
+ MAX_REDIRECTS: Integer
173
+
174
+ def initialize: (?directory: String, ?fetcher: untyped) -> void
175
+ def setup: (?force: bool) -> String
176
+ end
177
+
169
178
  class PicoRubySourcePatch
170
179
  JOB_PATH: String
171
180
  PATCH_ALIASES: Hash[String, String]
@@ -310,6 +319,11 @@ module Rpremote
310
319
  def run: (String data, ?output: IO?) -> String
311
320
  end
312
321
 
322
+ class RecursiveCopy
323
+ def initialize: (output: IO, ?serial: untyped, ?device: untyped) -> void
324
+ def call: (String source, String destination, Hash[Symbol, untyped] options) -> void
325
+ end
326
+
313
327
  class Resetter
314
328
  DEFAULT_TIMEOUT: Float
315
329
  RETRY_INTERVAL: Float
@@ -337,7 +351,7 @@ module Rpremote
337
351
  class Result < Data
338
352
  attr_reader mount: String
339
353
  attr_reader destination: String
340
- attr_reader port: String
354
+ attr_reader port: String?
341
355
  end
342
356
 
343
357
  class Error < Rpremote::Error
@@ -362,8 +376,10 @@ module Rpremote
362
376
  ?port_probe: untyped,
363
377
  ?sleeper: untyped
364
378
  ) -> void
365
- def flash: (String uf2_path, ?mount: String?, ?port: String?) -> Result
379
+ def flash: (String uf2_path, ?mount: String?, ?port: String?, ?wait_for_port: bool) -> Result
366
380
  def find_mount: (?String? explicit_mount) -> String
381
+ def find_mounted: (?String? explicit_mount) -> String?
382
+ def wait_for_mount: (?mount: String?) -> String
367
383
  end
368
384
 
369
385
  class DfuCommand
@@ -415,4 +431,36 @@ module Rpremote
415
431
  ?flasher: untyped
416
432
  ) -> void
417
433
  end
434
+
435
+ class DeployCommand
436
+ def self.run: (
437
+ Array[String] args,
438
+ defaults: Hash[Symbol, untyped],
439
+ ?output: IO,
440
+ ?error: IO,
441
+ ?services: Hash[Symbol, untyped]
442
+ ) -> void
443
+ end
444
+
445
+ class BootselCommand
446
+ RESET_FLASH_FIRMWARE: String
447
+
448
+ class Error < Rpremote::Error
449
+ end
450
+
451
+ def self.run: (
452
+ Array[String] args,
453
+ defaults: Hash[Symbol, untyped],
454
+ ?output: IO,
455
+ ?services: Hash[Symbol, untyped]
456
+ ) -> void
457
+ def self.enter: (
458
+ mount: String?,
459
+ port: String?,
460
+ baud: Integer,
461
+ timeout: Numeric,
462
+ output: IO,
463
+ ?services: Hash[Symbol, untyped]
464
+ ) -> String
465
+ end
418
466
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpremote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ogom
@@ -26,12 +26,14 @@ files:
26
26
  - THIRD_PARTY_NOTICES.md
27
27
  - exe/rpremote
28
28
  - lib/rpremote.rb
29
+ - lib/rpremote/bootsel_command.rb
29
30
  - lib/rpremote/build_command.rb
30
31
  - lib/rpremote/builder.rb
31
32
  - lib/rpremote/checksum.rb
32
33
  - lib/rpremote/cli.rb
33
34
  - lib/rpremote/config.rb
34
35
  - lib/rpremote/config_show.rb
36
+ - lib/rpremote/deploy_command.rb
35
37
  - lib/rpremote/device.rb
36
38
  - lib/rpremote/dfu_command.rb
37
39
  - lib/rpremote/dfu_compiler.rb
@@ -42,8 +44,10 @@ files:
42
44
  - lib/rpremote/language_source.rb
43
45
  - lib/rpremote/mrbgems.rb
44
46
  - lib/rpremote/mrbgems_command.rb
47
+ - lib/rpremote/nuke_firmware.rb
45
48
  - lib/rpremote/picomodem.rb
46
49
  - lib/rpremote/picoruby_source_patch.rb
50
+ - lib/rpremote/recursive_copy.rb
47
51
  - lib/rpremote/remote_path.rb
48
52
  - lib/rpremote/resetter.rb
49
53
  - lib/rpremote/runner.rb
@@ -53,7 +57,9 @@ files:
53
57
  - lib/rpremote/target.rb
54
58
  - lib/rpremote/terminal.rb
55
59
  - lib/rpremote/version.rb
60
+ - patches/picoruby-3.4.5-bootsel.patch
56
61
  - patches/picoruby-3.4.5-ruby-exception-status.patch
62
+ - patches/picoruby-4.0.3-bootsel.patch
57
63
  - patches/picoruby-4.0.3-ruby-exception-status.patch
58
64
  - sig/rpremote.rbs
59
65
  - tasks/firmware_build.rb