prremote 0.1.2 → 0.1.5
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/README.md +27 -11
- data/VERSION +1 -0
- data/lib/prremote/cli.rb +29 -15
- data/lib/prremote/commands/deploy.rb +22 -18
- data/lib/prremote/commands/install.rb +1 -1
- data/lib/prremote/commands/ls.rb +61 -0
- data/lib/prremote/commands/run.rb +16 -13
- data/lib/prremote/commands/serial_helpers.rb +21 -0
- data/lib/prremote/commands/watch.rb +13 -12
- data/lib/prremote/version.rb +1 -2
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5d636b2157c9ef1ede45b69b9df264da77cb142529f0c93d0857e23cb681bca
|
|
4
|
+
data.tar.gz: e2683165f9b9c91ab1c063295eb06fa3c04b062ab8fbe7f2b574b3dc1593dfe5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57617c04aa3320602e05f2f3080c4abad1cbc2639ad3a2c1017f90747ff3c5653b588280984cc0a617e0560072059ae89bb2389a460e172cfe41bb926b5589ec
|
|
7
|
+
data.tar.gz: 16c446180dda99c3a61a80145281cad1732321aa94016e260c6e05fba30775f874cfad3b8e3ea945cb5cc3aff0079b6beb9751fa4c2d349213966fc6bdda2511
|
data/README.md
CHANGED
|
@@ -6,11 +6,17 @@
|
|
|
6
6
|
|
|
7
7
|
Inspired by [mpremote](https://docs.micropython.org/en/latest/reference/mpremote.html) for MicroPython.
|
|
8
8
|
|
|
9
|
+
|
|
10
|
+
[](https://rubygems.org/gems/prremote)
|
|
11
|
+
[](https://github.com/lumbermill/prremote/actions/workflows/ci.yml)
|
|
12
|
+
[](https://opensource.org/licenses/MIT)
|
|
13
|
+
[](https://github.com/lumbermill/prremote)
|
|
14
|
+
|
|
9
15
|
---
|
|
10
16
|
|
|
11
17
|
## Requirements
|
|
12
18
|
|
|
13
|
-
- Ruby 3.
|
|
19
|
+
- Ruby 3.4 or later
|
|
14
20
|
- Raspberry Pi Pico W
|
|
15
21
|
- `mrbc` (mruby 4.x) for `run`, `deploy`, and `eval`
|
|
16
22
|
- macOS: `brew install mruby`
|
|
@@ -63,25 +69,34 @@ Put the device into BOOTSEL mode (hold BOOTSEL, connect USB, release) when promp
|
|
|
63
69
|
|
|
64
70
|
---
|
|
65
71
|
|
|
66
|
-
### `run FILE`
|
|
72
|
+
### `run FILE [FILE ...]`
|
|
67
73
|
|
|
68
|
-
Compile
|
|
74
|
+
Compile one or more local `.rb` files to mruby bytecode and run them on the device immediately (one-shot).
|
|
69
75
|
|
|
70
76
|
```bash
|
|
71
77
|
prremote run app.rb
|
|
72
78
|
prremote run blink.rb --port /dev/tty.usbmodem101
|
|
73
79
|
```
|
|
74
80
|
|
|
81
|
+
Multiple files are compiled in order into a single `.mrb`. Classes and methods defined in earlier files are available to later ones — this is the recommended alternative to `require`, which is not available in mruby/c.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
prremote run lib.rb main.rb
|
|
85
|
+
```
|
|
86
|
+
|
|
75
87
|
The device responds with `RUNNING`, streams any output, then `DONE`.
|
|
76
88
|
|
|
89
|
+
You can find some examples in [test/samples](test/samples/).
|
|
90
|
+
|
|
77
91
|
---
|
|
78
92
|
|
|
79
|
-
### `deploy FILE`
|
|
93
|
+
### `deploy FILE [FILE ...]`
|
|
80
94
|
|
|
81
|
-
Compile
|
|
95
|
+
Compile one or more local `.rb` files and save them to the device's flash. The script runs automatically on every boot.
|
|
82
96
|
|
|
83
97
|
```bash
|
|
84
98
|
prremote deploy app.rb
|
|
99
|
+
prremote deploy lib.rb main.rb
|
|
85
100
|
```
|
|
86
101
|
|
|
87
102
|
The device responds with `DEPLOYED` when the write is complete.
|
|
@@ -119,15 +134,16 @@ prremote reset
|
|
|
119
134
|
|
|
120
135
|
---
|
|
121
136
|
|
|
122
|
-
### `watch FILE`
|
|
137
|
+
### `watch FILE [FILE ...]`
|
|
123
138
|
|
|
124
|
-
Watch
|
|
139
|
+
Watch one or more local files for changes and automatically re-run them on the device on every save.
|
|
125
140
|
|
|
126
141
|
```bash
|
|
127
142
|
prremote watch app.rb
|
|
143
|
+
prremote watch lib.rb main.rb
|
|
128
144
|
```
|
|
129
145
|
|
|
130
|
-
Useful during development — save
|
|
146
|
+
Useful during development — save any watched file and the device immediately runs the updated code.
|
|
131
147
|
|
|
132
148
|
---
|
|
133
149
|
|
|
@@ -147,9 +163,9 @@ Show the gem version, mrbc version, and the connected device's runtime version.
|
|
|
147
163
|
|
|
148
164
|
```bash
|
|
149
165
|
prremote version
|
|
150
|
-
# prremote: 0.1.
|
|
151
|
-
#
|
|
152
|
-
#
|
|
166
|
+
# prremote: 0.1.5
|
|
167
|
+
# runtime: 0.1.5 (/dev/tty.usbmodem101)
|
|
168
|
+
# mrbc: mruby 4.0.0 (2026-04-20) (/opt/homebrew/bin/mrbc)
|
|
153
169
|
```
|
|
154
170
|
|
|
155
171
|
---
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.5
|
data/lib/prremote/cli.rb
CHANGED
|
@@ -7,6 +7,7 @@ require_relative 'runtime_manager'
|
|
|
7
7
|
require_relative 'commands/install'
|
|
8
8
|
require_relative 'commands/deploy'
|
|
9
9
|
require_relative 'commands/undeploy'
|
|
10
|
+
require_relative 'commands/ls'
|
|
10
11
|
require_relative 'commands/run'
|
|
11
12
|
require_relative 'commands/eval_cmd'
|
|
12
13
|
require_relative 'commands/watch'
|
|
@@ -23,10 +24,10 @@ module Prremote
|
|
|
23
24
|
remove_command :tree
|
|
24
25
|
|
|
25
26
|
desc 'install', 'Flash prremote runtime firmware to Pico W or Pico'
|
|
26
|
-
option :version, type: :string, desc: "Firmware version to install (default: #{
|
|
27
|
+
option :version, type: :string, desc: "Firmware version to install (default: #{VERSION})"
|
|
27
28
|
option :board, type: :string, desc: 'Board type: pico or picow (default: picow)'
|
|
28
29
|
def install
|
|
29
|
-
version = options[:version] ||
|
|
30
|
+
version = options[:version] || VERSION
|
|
30
31
|
board = options[:board] || 'picow'
|
|
31
32
|
unless RuntimeManager::BOARDS.include?(board)
|
|
32
33
|
raise Thor::Error, "Unknown board '#{board}'. Valid values: #{RuntimeManager::BOARDS.join(', ')}"
|
|
@@ -37,19 +38,31 @@ module Prremote
|
|
|
37
38
|
raise Thor::Error, e.message
|
|
38
39
|
end
|
|
39
40
|
|
|
40
|
-
desc 'run FILE', 'Compile and run
|
|
41
|
-
def run_script(
|
|
41
|
+
desc 'run FILE [FILE ...]', 'Compile and run Ruby scripts on the device (one-shot)'
|
|
42
|
+
def run_script(*files)
|
|
43
|
+
raise Thor::Error, 'At least one file is required.' if files.empty?
|
|
44
|
+
|
|
42
45
|
port = resolve_port
|
|
43
|
-
Commands::Run.new(port: port, baud: options[:baud]).call(
|
|
46
|
+
Commands::Run.new(port: port, baud: options[:baud]).call(*files)
|
|
44
47
|
rescue StandardError => e
|
|
45
48
|
raise Thor::Error, e.message
|
|
46
49
|
end
|
|
47
50
|
map 'run' => :run_script
|
|
48
51
|
|
|
49
|
-
desc 'deploy FILE', 'Compile and save
|
|
50
|
-
def deploy(
|
|
52
|
+
desc 'deploy FILE [FILE ...]', 'Compile and save Ruby scripts to flash (auto-runs on boot)'
|
|
53
|
+
def deploy(*files)
|
|
54
|
+
raise Thor::Error, 'At least one file is required.' if files.empty?
|
|
55
|
+
|
|
51
56
|
port = resolve_port
|
|
52
|
-
Commands::Deploy.new(port: port, baud: options[:baud]).call(
|
|
57
|
+
Commands::Deploy.new(port: port, baud: options[:baud]).call(*files)
|
|
58
|
+
rescue StandardError => e
|
|
59
|
+
raise Thor::Error, e.message
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
desc 'ls', 'Show the script deployed to flash (use `reset` first if a script is running)'
|
|
63
|
+
def ls
|
|
64
|
+
port = resolve_port
|
|
65
|
+
Commands::Ls.new(port: port, baud: options[:baud]).call
|
|
53
66
|
rescue StandardError => e
|
|
54
67
|
raise Thor::Error, e.message
|
|
55
68
|
end
|
|
@@ -70,10 +83,12 @@ module Prremote
|
|
|
70
83
|
raise Thor::Error, e.message
|
|
71
84
|
end
|
|
72
85
|
|
|
73
|
-
desc 'watch FILE', 'Watch
|
|
74
|
-
def watch(
|
|
86
|
+
desc 'watch FILE [FILE ...]', 'Watch Ruby files for changes and re-run on the device automatically'
|
|
87
|
+
def watch(*files)
|
|
88
|
+
raise Thor::Error, 'At least one file is required.' if files.empty?
|
|
89
|
+
|
|
75
90
|
port = resolve_port
|
|
76
|
-
Commands::Watch.new(port: port, baud: options[:baud]).call(
|
|
91
|
+
Commands::Watch.new(port: port, baud: options[:baud]).call(*files)
|
|
77
92
|
rescue StandardError => e
|
|
78
93
|
raise Thor::Error, e.message
|
|
79
94
|
end
|
|
@@ -104,10 +119,11 @@ module Prremote
|
|
|
104
119
|
desc 'version', 'Show prremote, mrbc, and device firmware version'
|
|
105
120
|
def version
|
|
106
121
|
puts "prremote: #{VERSION}"
|
|
122
|
+
puts "runtime: #{fetch_runtime_version}"
|
|
107
123
|
|
|
108
124
|
begin
|
|
109
125
|
major = Mrbc.major_version
|
|
110
|
-
puts "mrbc:
|
|
126
|
+
puts "mrbc: #{Mrbc.version} (#{Mrbc.bin})"
|
|
111
127
|
unless major && major >= Mrbc::REQUIRED_MAJOR
|
|
112
128
|
puts " ** mrbc is too old (need #{Mrbc::REQUIRED_MAJOR}.x) **"
|
|
113
129
|
puts " Hint: the path can be set via MRBC environment variable."
|
|
@@ -115,8 +131,6 @@ module Prremote
|
|
|
115
131
|
rescue StandardError => e
|
|
116
132
|
puts "mrbc: (#{e.message})"
|
|
117
133
|
end
|
|
118
|
-
|
|
119
|
-
puts "runtime: #{fetch_runtime_version}"
|
|
120
134
|
end
|
|
121
135
|
|
|
122
136
|
private
|
|
@@ -160,7 +174,7 @@ module Prremote
|
|
|
160
174
|
next
|
|
161
175
|
end
|
|
162
176
|
|
|
163
|
-
return ::Regexp.last_match(1) if buf =~ %r{READY prremote-runtime/([\d.]+)}
|
|
177
|
+
return "#{::Regexp.last_match(1)} (#{port})" if buf =~ %r{READY prremote-runtime/([\d.]+)}
|
|
164
178
|
return '(not responding)' if Time.now > deadline
|
|
165
179
|
|
|
166
180
|
sleep 0.05
|
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
require 'open3'
|
|
2
2
|
require 'tempfile'
|
|
3
3
|
require_relative '../mrbc'
|
|
4
|
+
require_relative 'serial_helpers'
|
|
4
5
|
|
|
5
6
|
module Prremote
|
|
6
7
|
module Commands
|
|
7
8
|
class Deploy
|
|
9
|
+
include SerialHelpers
|
|
10
|
+
|
|
8
11
|
DEPLOY_MAGIC = 'DPLY'.freeze
|
|
12
|
+
META_MAGIC = 'META'.freeze
|
|
9
13
|
|
|
10
14
|
def initialize(port:, baud:)
|
|
11
15
|
@port = port
|
|
12
16
|
@baud = baud
|
|
13
17
|
end
|
|
14
18
|
|
|
15
|
-
def call(
|
|
16
|
-
raise "File not found: #{
|
|
19
|
+
def call(*rb_paths)
|
|
20
|
+
rb_paths.each { |f| raise "File not found: #{f}" unless File.exist?(f) }
|
|
17
21
|
|
|
18
|
-
warn "Compiling #{
|
|
19
|
-
mrb_data = compile(
|
|
22
|
+
warn "Compiling #{rb_paths.map { |f| File.basename(f) }.join(', ')}..."
|
|
23
|
+
mrb_data = compile(*rb_paths)
|
|
20
24
|
|
|
21
25
|
warn 'Deploying to flash...'
|
|
22
|
-
deploy_to_device(mrb_data)
|
|
26
|
+
deploy_to_device(mrb_data, rb_paths)
|
|
23
27
|
warn 'Deployed. Script will run automatically on next boot.'
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
private
|
|
27
31
|
|
|
28
|
-
def compile(
|
|
32
|
+
def compile(*rb_paths)
|
|
29
33
|
Mrbc.check_version!
|
|
30
34
|
tmp = Tempfile.new(['prremote', '.mrb'])
|
|
31
|
-
out, status = Open3.capture2e(Mrbc.bin, '-o', tmp.path,
|
|
35
|
+
out, status = Open3.capture2e(Mrbc.bin, '-o', tmp.path, *rb_paths)
|
|
32
36
|
raise "mrbc failed:\n#{out.chomp}" unless status.success?
|
|
33
37
|
|
|
34
38
|
File.binread(tmp.path)
|
|
@@ -36,19 +40,23 @@ module Prremote
|
|
|
36
40
|
tmp&.close!
|
|
37
41
|
end
|
|
38
42
|
|
|
39
|
-
def deploy_to_device(mrb_data)
|
|
43
|
+
def deploy_to_device(mrb_data, rb_paths)
|
|
40
44
|
serial = Serial.new(@port, @baud)
|
|
41
|
-
|
|
42
|
-
serial.
|
|
43
|
-
|
|
44
|
-
serial.write(DEPLOY_MAGIC + mrb_data)
|
|
45
|
-
debug "sent DPLY + #{mrb_data.bytesize} bytes"
|
|
46
|
-
|
|
45
|
+
wait_for_ready(serial)
|
|
46
|
+
serial.write(DEPLOY_MAGIC + build_meta_packet(rb_paths) + mrb_data)
|
|
47
47
|
wait_for_deployed(serial)
|
|
48
48
|
ensure
|
|
49
49
|
serial&.close
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
+
def build_meta_packet(rb_paths)
|
|
53
|
+
names_bytes = rb_paths.map { |f| File.basename(f) }.join(' ').encode('UTF-8').b
|
|
54
|
+
name_len = [names_bytes.bytesize, 240].min
|
|
55
|
+
ts = Time.now.to_i
|
|
56
|
+
debug "meta: #{name_len} bytes, ts=#{ts}"
|
|
57
|
+
META_MAGIC + [name_len].pack('C') + names_bytes[0, name_len] + [ts].pack('N')
|
|
58
|
+
end
|
|
59
|
+
|
|
52
60
|
def wait_for_deployed(serial)
|
|
53
61
|
buf = +''
|
|
54
62
|
deadline = Time.now + 30
|
|
@@ -64,10 +72,6 @@ module Prremote
|
|
|
64
72
|
end
|
|
65
73
|
end
|
|
66
74
|
|
|
67
|
-
def normalize(str)
|
|
68
|
-
str.gsub("\r\n", "\n").gsub("\r", '')
|
|
69
|
-
end
|
|
70
|
-
|
|
71
75
|
def debug(msg)
|
|
72
76
|
warn "[debug] #{msg}" if ENV['PRREMOTE_DEBUG']
|
|
73
77
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require_relative 'serial_helpers'
|
|
2
|
+
|
|
3
|
+
module Prremote
|
|
4
|
+
module Commands
|
|
5
|
+
class Ls
|
|
6
|
+
include SerialHelpers
|
|
7
|
+
|
|
8
|
+
QUERY_MAGIC = 'QURY'.freeze
|
|
9
|
+
|
|
10
|
+
def initialize(port:, baud:)
|
|
11
|
+
@port = port
|
|
12
|
+
@baud = baud
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def call
|
|
16
|
+
result = query_device
|
|
17
|
+
if result
|
|
18
|
+
ts_str = if result[:timestamp].positive?
|
|
19
|
+
Time.at(result[:timestamp]).strftime('%Y-%m-%d %H:%M:%S')
|
|
20
|
+
else
|
|
21
|
+
'(unknown)'
|
|
22
|
+
end
|
|
23
|
+
puts 'Deployed script:'
|
|
24
|
+
puts " Files: #{result[:names]}"
|
|
25
|
+
puts " Deployed: #{ts_str}"
|
|
26
|
+
else
|
|
27
|
+
puts 'No script deployed.'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def query_device
|
|
34
|
+
serial = Serial.new(@port, @baud)
|
|
35
|
+
wait_for_ready(serial)
|
|
36
|
+
serial.write(QUERY_MAGIC)
|
|
37
|
+
|
|
38
|
+
buf = +''
|
|
39
|
+
deadline = Time.now + 5
|
|
40
|
+
loop do
|
|
41
|
+
chunk = normalize(serial.read(256) || '')
|
|
42
|
+
buf << chunk
|
|
43
|
+
|
|
44
|
+
if (m = buf.match(/^DEPLOYED (\d+) (.+)\n/))
|
|
45
|
+
return { timestamp: m[1].to_i, names: m[2].strip }
|
|
46
|
+
end
|
|
47
|
+
return nil if buf.include?("NONE\n")
|
|
48
|
+
|
|
49
|
+
if Time.now > deadline
|
|
50
|
+
raise 'Timeout waiting for device response. ' \
|
|
51
|
+
'If a script is running, use `prremote reset` first.'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
sleep 0.05
|
|
55
|
+
end
|
|
56
|
+
ensure
|
|
57
|
+
serial&.close
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
require 'open3'
|
|
2
2
|
require 'tempfile'
|
|
3
3
|
require_relative '../mrbc'
|
|
4
|
+
require_relative 'serial_helpers'
|
|
4
5
|
|
|
5
6
|
module Prremote
|
|
6
7
|
module Commands
|
|
7
8
|
class Run
|
|
9
|
+
include SerialHelpers
|
|
10
|
+
|
|
8
11
|
def initialize(port:, baud:)
|
|
9
12
|
@port = port
|
|
10
13
|
@baud = baud
|
|
11
14
|
end
|
|
12
15
|
|
|
13
|
-
def call(
|
|
14
|
-
raise "File not found: #{
|
|
16
|
+
def call(*rb_paths)
|
|
17
|
+
rb_paths.each { |f| raise "File not found: #{f}" unless File.exist?(f) }
|
|
15
18
|
|
|
16
|
-
warn "Compiling #{
|
|
17
|
-
mrb_data = compile(
|
|
19
|
+
warn "Compiling #{rb_paths.map { |f| File.basename(f) }.join(', ')}..."
|
|
20
|
+
mrb_data = compile(*rb_paths)
|
|
18
21
|
|
|
19
22
|
warn 'Running...'
|
|
20
23
|
run_on_device(mrb_data)
|
|
24
|
+
rescue Interrupt
|
|
25
|
+
warn ''
|
|
21
26
|
end
|
|
22
27
|
|
|
23
28
|
private
|
|
24
29
|
|
|
25
|
-
def compile(
|
|
30
|
+
def compile(*rb_paths)
|
|
26
31
|
Mrbc.check_version!
|
|
27
32
|
tmp = Tempfile.new(['prremote', '.mrb'])
|
|
28
|
-
out, status = Open3.capture2e(Mrbc.bin, '-o', tmp.path,
|
|
33
|
+
out, status = Open3.capture2e(Mrbc.bin, '-o', tmp.path, *rb_paths)
|
|
29
34
|
raise "mrbc failed:\n#{out.chomp}" unless status.success?
|
|
30
35
|
|
|
31
36
|
File.binread(tmp.path)
|
|
@@ -35,15 +40,17 @@ module Prremote
|
|
|
35
40
|
|
|
36
41
|
def run_on_device(mrb_data)
|
|
37
42
|
serial = Serial.new(@port, @baud)
|
|
38
|
-
|
|
39
|
-
drained = serial.read(4096) || ''
|
|
40
|
-
debug "drained #{drained.bytesize} bytes: #{drained.inspect}"
|
|
43
|
+
wait_for_ready(serial)
|
|
41
44
|
|
|
42
45
|
serial.write(mrb_data)
|
|
43
46
|
debug "sent #{mrb_data.bytesize} bytes (first 4: #{mrb_data[0, 4].inspect})"
|
|
44
47
|
|
|
45
48
|
post_running = wait_for_running(serial)
|
|
46
49
|
stream_until_done(serial, post_running)
|
|
50
|
+
rescue Interrupt
|
|
51
|
+
serial&.write("\x03")
|
|
52
|
+
sleep 0.1
|
|
53
|
+
raise
|
|
47
54
|
ensure
|
|
48
55
|
serial&.close
|
|
49
56
|
end
|
|
@@ -91,10 +98,6 @@ module Prremote
|
|
|
91
98
|
end
|
|
92
99
|
end
|
|
93
100
|
|
|
94
|
-
def normalize(str)
|
|
95
|
-
str.gsub("\r\n", "\n").gsub("\r", '')
|
|
96
|
-
end
|
|
97
|
-
|
|
98
101
|
def debug(msg)
|
|
99
102
|
warn "[debug] #{msg}" if ENV['PRREMOTE_DEBUG']
|
|
100
103
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Prremote
|
|
2
|
+
module Commands
|
|
3
|
+
module SerialHelpers
|
|
4
|
+
def wait_for_ready(serial)
|
|
5
|
+
buf = +''
|
|
6
|
+
deadline = Time.now + 10
|
|
7
|
+
loop do
|
|
8
|
+
buf << normalize(serial.read(256) || '')
|
|
9
|
+
return if buf.include?('READY ')
|
|
10
|
+
raise 'Timeout waiting for device. Run `prremote reset` if a script is running.' if Time.now > deadline
|
|
11
|
+
|
|
12
|
+
sleep 0.05
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def normalize(str)
|
|
17
|
+
str.gsub("\r\n", "\n").gsub("\r", '')
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -10,21 +10,22 @@ module Prremote
|
|
|
10
10
|
@baud = baud
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def call(
|
|
14
|
-
raise "File not found: #{
|
|
13
|
+
def call(*rb_paths)
|
|
14
|
+
rb_paths.each { |f| raise "File not found: #{f}" unless File.exist?(f) }
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
label = rb_paths.map { |f| File.basename(f) }.join(', ')
|
|
17
|
+
warn "Watching #{label} (Ctrl+C to stop)..."
|
|
18
|
+
mtimes = rb_paths.map { |f| File.mtime(f) }
|
|
19
|
+
run(*rb_paths)
|
|
19
20
|
|
|
20
21
|
loop do
|
|
21
22
|
sleep POLL_INTERVAL
|
|
22
|
-
|
|
23
|
-
next if
|
|
23
|
+
new_mtimes = rb_paths.map { |f| File.mtime(f) }
|
|
24
|
+
next if new_mtimes == mtimes
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
warn "\n--- #{
|
|
27
|
-
run(
|
|
26
|
+
mtimes = new_mtimes
|
|
27
|
+
warn "\n--- #{label} changed, re-running ---"
|
|
28
|
+
run(*rb_paths)
|
|
28
29
|
end
|
|
29
30
|
rescue Interrupt
|
|
30
31
|
warn "\nStopped watching."
|
|
@@ -32,8 +33,8 @@ module Prremote
|
|
|
32
33
|
|
|
33
34
|
private
|
|
34
35
|
|
|
35
|
-
def run(
|
|
36
|
-
Run.new(port: @port, baud: @baud).call(
|
|
36
|
+
def run(*rb_paths)
|
|
37
|
+
Run.new(port: @port, baud: @baud).call(*rb_paths)
|
|
37
38
|
rescue StandardError => e
|
|
38
39
|
warn "Error: #{e.message}"
|
|
39
40
|
end
|
data/lib/prremote/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: prremote
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ITO Yosei
|
|
@@ -103,13 +103,16 @@ extra_rdoc_files: []
|
|
|
103
103
|
files:
|
|
104
104
|
- LICENSE
|
|
105
105
|
- README.md
|
|
106
|
+
- VERSION
|
|
106
107
|
- bin/prremote
|
|
107
108
|
- lib/prremote.rb
|
|
108
109
|
- lib/prremote/cli.rb
|
|
109
110
|
- lib/prremote/commands/deploy.rb
|
|
110
111
|
- lib/prremote/commands/eval_cmd.rb
|
|
111
112
|
- lib/prremote/commands/install.rb
|
|
113
|
+
- lib/prremote/commands/ls.rb
|
|
112
114
|
- lib/prremote/commands/run.rb
|
|
115
|
+
- lib/prremote/commands/serial_helpers.rb
|
|
113
116
|
- lib/prremote/commands/undeploy.rb
|
|
114
117
|
- lib/prremote/commands/watch.rb
|
|
115
118
|
- lib/prremote/detector.rb
|