rpremote 0.5.0 → 0.6.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: 4eb2ee018d6af469de77f435dd2a7d7021ae6e017d078655d5a7ca06e0735ac7
4
- data.tar.gz: 547f6b9d2c98deab27f1a67b9b37bd375a2c0bbfbb55e7f1a1faca156de67ada
3
+ metadata.gz: b30b1f27c4bdbb212d69bc30f79342bf2caa6ae5c6787125a9627e53f15a714a
4
+ data.tar.gz: a7ab212fa48b5f58aa11357ffdf52c2f5c8dbf47c2b00c6d3b7279c38a1431d3
5
5
  SHA512:
6
- metadata.gz: c732178d037299500ee01e6a9ba0dfbe3836372e543be0db1a2e156586043f153a8fdf45f47d435390996b9a840e399a3140c65e3159d16ca9302018308003a4
7
- data.tar.gz: fcca0bbaf3d04fd352fcd9ec00dbf08217c77dd23f2228cdfb17940d094d0c815d4bef14320d24641abb30a8dd6cdd8ce32858146bb3866f6e45f03d3f1f0089
6
+ metadata.gz: 6086af03b4459d2c96102e7f884cd888276735ae77d30132189a4191c66892366a7deb51676613966751d343d79d5b53519242ac5171cee9d60044d81a4f7225
7
+ data.tar.gz: dc2851099a3a6a3c019a3cbb8936b4b111f9359d964208163d688d4afb4b4cf27135286949304954f7ea685a215f6373f27e23a3c20c3aa4fb5382e93bec6620
data/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ Notable changes to the `rpremote` RubyGem will be documented in this file. Repos
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.6.0 - 2026-09-20
8
+
9
+ - Change the default PicoRuby version to `latest`, backed by the current `master` branch, while retaining `--language-version` for selecting a release tag.
10
+ - Replace the patched R2P2 `bootsel` executable with a temporary PicoModem script that calls `Machine.enter_bootsel` from the embedded `picoruby-bootsel` mrbgem.
11
+ - Support both the legacy `build/host/bin/mrbc` layout and the PicoRuby 4.0.4 `build/mrbc/default/bin/mrbc` layout when building custom firmware.
12
+ - Expand the human-readable executable specifications and validate bilingual documentation structure, links, command coverage, and safety warnings.
13
+
7
14
  ## 0.5.0 - 2026-09-12
8
15
 
9
16
  - Make `deploy PATH` flash the existing UF2 by default, and add `deploy PATH --build` for the previous build-and-deploy workflow.
data/README.ja.md CHANGED
@@ -1,4 +1,4 @@
1
- # rpremote CLIリファレンス
1
+ # rpremote
2
2
 
3
3
  [English](README.md)
4
4
 
@@ -26,7 +26,7 @@ gem install rpremote
26
26
  ```sh
27
27
  rpremote setup
28
28
  rpremote build
29
- rpremote flash --mount /Volumes/RP2350
29
+ rpremote flash
30
30
  rpremote run main.rb
31
31
  ```
32
32
 
@@ -39,7 +39,7 @@ rpremote deploy path/to/project
39
39
  rpremote deploy path/to/project --build
40
40
  ```
41
41
 
42
- 既定では`firmware/picoruby-4.0.3/`にソースを準備し、`firmware/picoruby-4.0.3-pico2.uf2`を生成します。対象ボードを明示する必要がある場合は、`rpremote ports`でR2P2のCDC 0ポートを確認してください。
42
+ 既定では`firmware/picoruby-latest/`にソースを準備し、`firmware/picoruby-latest-pico2.uf2`を生成します。対象ボードを明示する必要がある場合は、`rpremote ports`でR2P2のCDC 0ポートを確認してください。
43
43
 
44
44
  ## mrbgemを追加する
45
45
 
@@ -66,61 +66,43 @@ rpremote build
66
66
  ## 対象を選択する
67
67
 
68
68
  ```sh
69
- rpremote setup --language picoruby --language-version 3.4.2
70
- rpremote build --language picoruby --language-version 3.4.2 --board pico2
71
- rpremote flash --language picoruby --language-version 3.4.2 --board pico2 --mount /Volumes/RP2350
69
+ rpremote setup
70
+ rpremote build
71
+ rpremote flash
72
72
  ```
73
73
 
74
74
  コマンドラインオプションは`config/setting.json`より優先されます。現在実装されているのはPicoRubyです。将来のMicroPythonと追加Picoボード対応に備え、`language`と`board`はインターフェースに残しています。
75
75
 
76
- ## コマンド
77
-
78
- | コマンド | 説明 |
79
- | --- | --- |
80
- | `rpremote setup` | 設定を作成し、言語ソースを準備します。 |
81
- | `rpremote build` | mrbgemを含むカスタムUF2をビルドします。 |
82
- | `rpremote build clean` | 中間ビルドファイルを削除します。 |
83
- | `rpremote bootsel` | 実行中のR2P2へBOOTSEL移行を要求し、USBボリュームの出現を待ちます。 |
84
- | `rpremote deploy PATH` | 既存ファームウェアを書き込み、存在する場合は`PATH/lib/NAME`を`:/lib/NAME`へコピーしてから`PATH/main.rb`を一時実行します。ハードウェア出力は次のコマンドまで維持されます。 |
85
- | `rpremote deploy PATH --build` | ファームウェアをビルドして書き込んだ後、同じコピーと一時実行を行います。 |
86
- | `rpremote dfu app FILE` | PicoModem DFUでRubyまたは版を照合したバイトコードのアプリを更新します。 |
87
- | `rpremote dfu compile FILE` | DFU用にPicoRuby版と一致する`.mrb`を生成します。 |
88
- | `rpremote dfu status` | DFUのアクティブおよび起動候補スロットを表示します。 |
89
- | `rpremote dfu remove` | DFU起動アプリを両スロットから削除します。実行中のアプリを停止するには別途リセットします。 |
90
- | `rpremote mrbgems …` | mrbgemを検査、表示、固定、更新します。 |
91
- | `rpremote flash` | 選択したUF2をBOOTSEL経由で書き込みます。 |
92
- | `rpremote bootsel --reset-flash-memory` | BOOTSELへ移行し、Pico 2の外部フラッシュメモリ全体を消去します。 |
93
- | `rpremote config show` | 設定ファイルとコマンドラインオプションを反映した実効設定を表示します。 |
94
- | `rpremote ports` | R2P2シリアルポートを表示します。 |
95
- | `rpremote run FILE` | Rubyファイルを転送して実行します。ディレクトリ指定時は`main.rb`を実行し、出力をリアルタイム表示します。タイムアウトは無出力の継続時間として扱い、Ruby例外時は非0で終了します。`--reset-on-timeout`を指定すると実行タイムアウト後にR2P2をリセットします。 |
96
- | `rpremote exec CODE` | 短いRubyコードを実行します。Ruby例外時は非0で終了します。 |
97
- | `rpremote monitor` / `repl` | 対話型シリアルセッションを開きます。 |
98
- | `rpremote reset` | R2P2を再起動して再接続まで待ちます。 |
99
- | `rpremote fs cp/push/cat/ls/rm/mkdir` | R2P2ファイルシステムを操作します。 |
100
-
101
- コマンド一覧は`rpremote --help`で確認できます。コマンド固有の構文、既定値、影響は`rpremote <command> --help`で確認できます。
76
+ ## 作業を選ぶ
77
+
78
+ - `setup`でプロジェクトを準備し、`config show`で実効設定を確認します。最初のファームウェア導入には`build`と`flash`を使います。
79
+ - プロジェクト開発では`deploy PATH`を使います。選択したファームウェアを書き込み、存在する場合は`PATH/lib/NAME`をコピーして`PATH/main.rb`を実行します。先にファームウェアを再ビルドする場合は`--build`を付けます。
80
+ - Rubyを一時実行する場合は`run`または`exec`、対話型シリアル接続には`monitor`または`repl`を使います。`monitor`と`repl`は`Ctrl-]`で終了します。
81
+ - R2P2上へファイルを保持する場合は`fs`、再起動後も実行するA/B起動アプリには`dfu`を使います。
82
+
83
+ 完全なコマンド一覧は`rpremote --help`で確認します。現在の構文、既定値、処理順、影響についてはコマンドヘルプが実行可能なリファレンスです。
102
84
 
103
85
  ```sh
104
- rpremote flash --help
86
+ rpremote deploy --help
105
87
  rpremote dfu app --help
88
+ rpremote fs cp --help
106
89
  ```
107
90
 
108
- `monitor`と`repl`は`Ctrl-]`で終了します。
109
-
110
- `run`と`exec`の例外終了コードには、Ruby例外ステータスに対応したR2P2ファームウェアが必要です。[GitHubリポジトリ](https://github.com/ogom/rpremote)のPicoRubyソースから`rpremote build`で生成したUF2が対応しています。
111
-
112
- ## 操作モデル
91
+ ### 安全上の境界
113
92
 
114
- - `run`と`exec`はRubyコードを一時的に転送・実行して出力を表示し、一時リモートファイルを削除します。対応するR2P2ファームウェアがRuby例外を報告した場合は、非0で終了します。
115
- - `deploy PATH`はBOOTSELへ移行して既存の選択済みファームウェアを書き込んだ後、R2P2 Shellの起動完了を待ちます。存在する場合は`PATH/lib/NAME`を`:/lib/NAME`へコピーし、実行直前に読み込んだ`PATH/main.rb`を一時実行します。`deploy PATH --build`は同じ処理の前にファームウェアをビルドします。Shellジョブを保持するため、ハードウェア出力は次のコマンドまで維持されます。正常終了と出力バイト数を表示し、R2P2のRuby例外はコマンド失敗として扱います。ライブラリディレクトリがない場合、コピー処理はスキップします。PicoRuby 4系のファームウェアが必要です。
116
- - `flash`はUF2をRP2350 BOOTSELボリュームへコピーし、永続的なR2P2ファームウェアを置き換えます。
117
- - `dfu app`はRubyソースまたは対応するバイトコードのアプリを非アクティブDFUスロットへ登録します。R2P2を再起動して試行し、正常に起動したアプリは`DFU.confirm`を呼び出します。
118
- - `dfu remove`はDFUのA/B両アプリスロットを完全に空にします。RAM上ですでに動作しているアプリは`rpremote reset`を実行するまで継続するため、起動アプリのログを混ぜずに`rpremote run`を使う場合は両方のコマンドを実行します。その他の`/home`ファイルとR2P2ファームウェアは削除しません。
119
- - リモートパスには`:/REMOTE/PATH`を使います。`fs cp`はローカルパスとリモートパスの間で転送します。`fs push LOCAL_DIR :/REMOTE_DIR`は`fs cp --recursive`の別名で、不足しているリモートディレクトリを作成し、ローカルディレクトリの内容を一括転送します。リモートにだけ存在するファイルは削除しません。`fs rm`は指定したリモートパスを完全に削除します。
93
+ - `flash`は永続的なR2P2ファームウェアを置き換えます。`bootsel --reset-flash-memory`はPico 2の外部フラッシュ全体を消去するため、実行後にR2P2を再度書き込む必要があります。
94
+ - `dfu remove`はDFUのA/B両アプリスロットを完全に空にします。RAM上ですでに動作しているアプリを停止するには、別途リセットします。
95
+ - `fs rm`は指定したリモートパスを完全に削除します。再帰転送ではボード上だけに存在するファイルを削除しません。
96
+ - `run`と`exec`は一時リモートファイルを削除します。Ruby例外時の非0終了には対応するR2P2ファームウェアが必要で、このリポジトリからビルドしたUF2は対応しています。
120
97
 
121
98
  ## ドキュメントとサンプル
122
99
 
123
- [GitHubリポジトリ](https://github.com/ogom/rpremote)に、英語・日本語のガイド、設定リファレンス、Mrbgems.lockの解説、カスタムファームウェア手順、電子工作サンプルがあります。
100
+ - [作業に応じてコマンドを選ぶ](https://github.com/ogom/rpremote/blob/main/docs/command.ja.md)
101
+ - [プロジェクトを設定する](https://github.com/ogom/rpremote/blob/main/docs/config.ja.md)
102
+ - [カスタムファームウェアをビルドする](https://github.com/ogom/rpremote/blob/main/docs/firmware.ja.md)
103
+ - [MrbgemsとMrbgems.lockを管理する](https://github.com/ogom/rpremote/blob/main/docs/mrbgems.ja.md)
104
+ - [PicoModem DFUで起動アプリを更新する](https://github.com/ogom/rpremote/blob/main/docs/dfu.ja.md)
105
+ - [電子工作サンプルを見る](https://github.com/ogom/rpremote/tree/main/examples)
124
106
 
125
107
  ## 関連プロジェクト
126
108
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rpremote CLI reference
1
+ # rpremote
2
2
 
3
3
  [日本語](README.ja.md)
4
4
 
@@ -26,7 +26,7 @@ Run these commands in a project directory:
26
26
  ```sh
27
27
  rpremote setup
28
28
  rpremote build
29
- rpremote flash --mount /Volumes/RP2350
29
+ rpremote flash
30
30
  rpremote run main.rb
31
31
  ```
32
32
 
@@ -39,7 +39,7 @@ rpremote deploy path/to/project
39
39
  rpremote deploy path/to/project --build
40
40
  ```
41
41
 
42
- The defaults prepare `firmware/picoruby-4.0.3/` and create `firmware/picoruby-4.0.3-pico2.uf2`. Use `rpremote ports` to locate the R2P2 CDC 0 port when a board must be selected explicitly.
42
+ The defaults prepare `firmware/picoruby-latest/` and create `firmware/picoruby-latest-pico2.uf2`. Use `rpremote ports` to locate the R2P2 CDC 0 port when a board must be selected explicitly.
43
43
 
44
44
  ## Add mrbgems
45
45
 
@@ -66,62 +66,43 @@ Set `auto_require: false` for a gem that should remain embedded in firmware with
66
66
  ## Select a target
67
67
 
68
68
  ```sh
69
- rpremote setup --language picoruby --language-version 3.4.2
70
- rpremote build --language picoruby --language-version 3.4.2 --board pico2
71
- rpremote flash --language picoruby --language-version 3.4.2 --board pico2 --mount /Volumes/RP2350
69
+ rpremote setup
70
+ rpremote build
71
+ rpremote flash
72
72
  ```
73
73
 
74
74
  Command-line options override `config/setting.json`. PicoRuby is implemented today; `language` and `board` are retained for planned MicroPython and additional Pico board support.
75
75
 
76
- ## Commands
77
-
78
- | Command | Description |
79
- | --- | --- |
80
- | `rpremote setup` | Create configuration and prepare language sources. |
81
- | `rpremote build` | Build a custom UF2 with project mrbgems. |
82
- | `rpremote build clean` | Remove intermediate build files. |
83
- | `rpremote bootsel` | Ask the running R2P2 firmware to enter BOOTSEL and wait for its USB volume. |
84
- | `rpremote deploy PATH` | Flash existing firmware, copy `PATH/lib/NAME` to `:/lib/NAME` when present, then temporarily run `PATH/main.rb` while preserving its hardware output until the next command. |
85
- | `rpremote deploy PATH --build` | Build and flash firmware, then perform the same copy and temporary run workflow. |
86
- | `rpremote dfu app FILE` | Stage a Ruby or version-checked bytecode app through PicoModem DFU. |
87
- | `rpremote dfu compile FILE` | Compile `.rb` to matching PicoRuby bytecode for DFU. |
88
- | `rpremote dfu status` | Show the active and candidate DFU slots. |
89
- | `rpremote dfu remove` | Remove both DFU boot applications; reset separately to stop one already running. |
90
- | `rpremote mrbgems …` | Check, list, lock, or update mrbgems. |
91
- | `rpremote flash` | Flash the selected UF2 through BOOTSEL. |
92
- | `rpremote bootsel --reset-flash-memory` | Enter BOOTSEL and erase all Pico 2 external flash memory. |
93
- | `rpremote config show` | Show the effective configuration after file and command-line options are resolved. |
94
- | `rpremote ports` | List detected R2P2 serial ports. |
95
- | `rpremote run FILE` | Upload and run a Ruby file, or `main.rb` when FILE is a directory, with real-time output; exit nonzero on a Ruby exception. The timeout measures idle time without output. Use `--reset-on-timeout` to reset R2P2 after a run timeout. |
96
- | `rpremote exec CODE` | Run short Ruby code and exit nonzero on a Ruby exception. |
97
- | `rpremote monitor` / `repl` | Open an interactive serial session. |
98
- | `rpremote reset` | Reboot R2P2 and wait for reconnection. |
99
- | `rpremote fs cp/push/cat/ls/rm/mkdir` | Operate on the R2P2 filesystem. |
100
-
101
- Run `rpremote --help` for the complete command list. Run `rpremote <command> --help` for command-specific syntax, defaults, and effects.
76
+ ## Choose a workflow
77
+
78
+ - Prepare a project with `setup`, inspect resolved settings with `config show`, then use `build` and `flash` for the first firmware installation.
79
+ - Use `deploy PATH` during project development. It flashes the selected firmware, copies `PATH/lib/NAME` when present, and runs `PATH/main.rb`; add `--build` when the firmware must be rebuilt first.
80
+ - Use `run` or `exec` for temporary Ruby execution, and `monitor` or `repl` for an interactive serial session. `monitor` and `repl` exit with `Ctrl-]`.
81
+ - Use `fs` commands for persistent R2P2 files, and use `dfu` commands when an A/B boot application must survive a restart.
82
+
83
+ Run `rpremote --help` for the complete command list. Command help is the executable reference for current syntax, defaults, processing order, and effects.
102
84
 
103
85
  ```sh
104
- rpremote flash --help
86
+ rpremote deploy --help
105
87
  rpremote dfu app --help
88
+ rpremote fs cp --help
106
89
  ```
107
90
 
108
- `monitor` and `repl` exit with `Ctrl-]`.
109
-
110
- Ruby-exception exit statuses for `run` and `exec` require R2P2 firmware with Ruby exception status support.
111
- UF2 files built with `rpremote build` from the [GitHub repository](https://github.com/ogom/rpremote) include that support.
112
-
113
- ## Operation model
91
+ ### Safety boundaries
114
92
 
115
- - `run` and `exec` upload Ruby code temporarily, relay output, then remove the temporary remote file. A Ruby exception reported by compatible R2P2 firmware makes the command exit nonzero.
116
- - `deploy PATH` enters BOOTSEL, flashes the existing selected firmware, waits until the R2P2 Shell is ready, copies `PATH/lib/NAME` to `:/lib/NAME` when present, then temporarily runs the current contents of `PATH/main.rb`. `deploy PATH --build` builds that firmware before the same workflow. The Shell job is retained so hardware output remains active until the next command. It reports successful completion and the output byte count; an R2P2 Ruby exception remains a command failure. If the library directory is absent, the copy step is skipped. It requires PicoRuby 4.x firmware.
117
- - `flash` copies a UF2 to the RP2350 BOOTSEL volume and replaces persistent R2P2 firmware.
118
- - `dfu app` stages a Ruby source or matching bytecode app in the inactive DFU slot. Restart R2P2 to try it; a successful app must call `DFU.confirm`.
119
- - `dfu remove` permanently clears both DFU A/B application slots. The application already loaded in RAM continues until you run `rpremote reset`; use both commands before `rpremote run` when boot-app output would be unwanted. It does not remove other `/home` files or R2P2 firmware.
120
- - Remote paths use `:/REMOTE/PATH`. `fs cp` transfers between one local and one remote path. `fs push LOCAL_DIR :/REMOTE_DIR` is an alias of `fs cp --recursive`; it creates missing remote directories and uploads the local directory contents. It does not delete remote files. `fs rm` permanently deletes the selected remote path.
93
+ - `flash` replaces persistent R2P2 firmware. `bootsel --reset-flash-memory` erases all Pico 2 external flash and requires R2P2 to be flashed again.
94
+ - `dfu remove` permanently clears both DFU A/B application slots. Reset separately to stop an application already running in RAM.
95
+ - `fs rm` permanently deletes the selected remote path. Recursive uploads do not delete files that exist only on the board.
96
+ - `run` and `exec` remove their temporary remote file. Their nonzero Ruby-exception status requires compatible R2P2 firmware; UF2 files built from this repository include that support.
121
97
 
122
98
  ## Documentation and examples
123
99
 
124
- The [GitHub repository](https://github.com/ogom/rpremote) contains the full English and Japanese guides, configuration reference, Mrbgems.lock reference, custom firmware guide, and electronic-craft examples.
100
+ - [Choose commands by workflow](https://github.com/ogom/rpremote/blob/main/docs/command.md)
101
+ - [Configure a project](https://github.com/ogom/rpremote/blob/main/docs/config.md)
102
+ - [Build custom firmware](https://github.com/ogom/rpremote/blob/main/docs/firmware.md)
103
+ - [Manage Mrbgems and Mrbgems.lock](https://github.com/ogom/rpremote/blob/main/docs/mrbgems.md)
104
+ - [Update a boot application with PicoModem DFU](https://github.com/ogom/rpremote/blob/main/docs/dfu.md)
105
+ - [Browse electronic-craft examples](https://github.com/ogom/rpremote/tree/main/examples)
125
106
 
126
107
  ## Related projects
127
108
 
@@ -7,6 +7,8 @@ module Rpremote
7
7
  SHELL_READY_TIMEOUT = 2.0
8
8
  RETRY_INTERVAL = 0.25
9
9
  RESET_FLASH_FIRMWARE = File.join("firmware", "nuke_universal.uf2").freeze
10
+ REMOTE_SCRIPT_PATH = "/home/.rpremote-bootsel.rb"
11
+ REMOTE_SCRIPT = "require \"bootsel\"\nMachine.enter_bootsel\n".b.freeze
10
12
 
11
13
  class Error < Rpremote::Error; end
12
14
 
@@ -47,7 +49,8 @@ module Rpremote
47
49
 
48
50
  request_bootsel(
49
51
  port: port, baud: baud, deadline: deadline, output: output,
50
- serial: serial, device: device, shell: shell, sleeper: sleeper, clock: clock
52
+ serial: serial, device: device, shell: shell, modem: services.fetch(:modem) { PicoModem },
53
+ sleeper: sleeper, clock: clock
51
54
  )
52
55
 
53
56
  remaining = deadline - clock.call
@@ -66,6 +69,7 @@ module Rpremote
66
69
  serial = context.fetch(:serial)
67
70
  device = context.fetch(:device)
68
71
  shell = context.fetch(:shell)
72
+ modem = context.fetch(:modem) { PicoModem }
69
73
  sleeper = context.fetch(:sleeper)
70
74
  clock = context.fetch(:clock)
71
75
  announced = false
@@ -84,11 +88,9 @@ module Rpremote
84
88
 
85
89
  remote_shell = shell.new(connection, timeout: [remaining, SHELL_READY_TIMEOUT].min)
86
90
  remote_shell.synchronize!
87
- unless remote_shell.execute("type bootsel").include?("bootsel is")
88
- raise Error, "connected R2P2 firmware does not support BOOTSEL reset; flash a current rpremote UF2 once while holding BOOTSEL"
89
- end
90
-
91
- remote_shell.send_command("bootsel")
91
+ modem.new(connection, timeout: remaining).upload(REMOTE_SCRIPT_PATH, REMOTE_SCRIPT)
92
+ remote_shell.synchronize!
93
+ remote_shell.send_command("./#{File.basename(REMOTE_SCRIPT_PATH)}")
92
94
  requested = true
93
95
  end
94
96
  break if requested
@@ -97,7 +97,7 @@ module Rpremote
97
97
  def mrbgems_config_language(vm_name, language, version)
98
98
  return language unless vm_name
99
99
 
100
- modern = Gem::Version.new(version) >= Gem::Version.new("4.0.0")
100
+ modern = version == "latest" || Gem::Version.new(version) >= Gem::Version.new("4.0.0")
101
101
  return modern ? "femtoruby" : "picoruby" if vm_name == :mrubyc
102
102
 
103
103
  modern ? "picoruby" : "microruby"
@@ -11,7 +11,6 @@ module Rpremote
11
11
 
12
12
  class Error < Rpremote::Error; end
13
13
 
14
- # The command intentionally keeps the deployment stages visible in execution order.
15
14
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
16
15
  def self.run(args, defaults:, output: $stdout, error: $stderr, services: {})
17
16
  options = parse_options(args, defaults)
data/lib/rpremote/help.rb CHANGED
@@ -75,7 +75,7 @@ module Rpremote
75
75
  --force download the PicoRuby source again during setup
76
76
  --build build the selected firmware before deploy flashes it
77
77
  --language-version VERSION
78
- use R2P2/PicoRuby 4.0.3 or 3.4.2 (default: 4.0.3)
78
+ use a PicoRuby tag or latest (default: latest)
79
79
  --cache DIR use another project cache directory
80
80
  --mrbgems FILE use an explicit Mrbgems definition during build or deploy
81
81
  --no-mrbgems build or deploy without the automatically detected Mrbgems
@@ -126,7 +126,7 @@ module Rpremote
126
126
  Usage: #{COMMAND_USAGE.fetch(:setup)}
127
127
 
128
128
  Creates config/setting.json when it does not exist, then downloads and prepares PicoRuby source and the official Raspberry Pi nuke_universal.uf2 firmware.
129
- Options: --language LANGUAGE (picoruby), --language-version VERSION (4.0.3), --cache DIR (firmware), --force.
129
+ Options: --language LANGUAGE (picoruby), --language-version VERSION (latest), --cache DIR (firmware), --force.
130
130
  This changes the project configuration and source cache but does not connect to a board.
131
131
  HELP
132
132
  end
@@ -157,7 +157,7 @@ module Rpremote
157
157
  With --build, builds the selected custom UF2 before entering BOOTSEL and flashing it.
158
158
  If PATH/lib/NAME exists, it copies it to :/lib/NAME, where NAME is the final component of PATH. It then runs PATH/main.rb and preserves its Shell job, so hardware output remains active until the next command.
159
159
  The stages run in order and stop at the first failure. Flashing replaces persistent board firmware.
160
- deploy requires PicoRuby 4.x firmware (currently 4.0.3).
160
+ deploy requires current PicoRuby 4.x firmware.
161
161
  Options combine build, BOOTSEL, flash, library-copy, and run settings. The first install of firmware with automatic BOOTSEL still requires holding BOOTSEL.
162
162
  HELP
163
163
  end
@@ -242,7 +242,7 @@ module Rpremote
242
242
  Usage: #{COMMAND_USAGE.fetch(:flash)}
243
243
 
244
244
  Copies the selected UF2 to an RP2350 BOOTSEL volume and waits for R2P2 to reconnect. It replaces persistent board firmware.
245
- Defaults select pico2, firmware/picoruby-4.0.3-pico2.uf2, an automatic BOOTSEL mount and CDC 0 port, and 20 seconds.
245
+ Defaults select pico2, firmware/picoruby-latest-pico2.uf2, an automatic BOOTSEL mount and CDC 0 port, and 20 seconds.
246
246
  HELP
247
247
  end
248
248
 
@@ -36,6 +36,7 @@ module Rpremote
36
36
  unless File.directory?(source_dir) && !force
37
37
  FileUtils.rm_rf(source_dir) if force
38
38
  extractor.call(archive_path, cache_dir)
39
+ normalize_extracted_source
39
40
  end
40
41
  raise ExtractError, "PicoRuby source was not extracted: #{source_dir}" unless File.directory?(source_dir)
41
42
 
@@ -45,7 +46,7 @@ module Rpremote
45
46
  end
46
47
 
47
48
  def archive_url
48
- "https://github.com/picoruby/picoruby/archive/refs/tags/#{version}.zip"
49
+ "https://github.com/picoruby/picoruby/archive/refs/#{source_ref}.zip"
49
50
  end
50
51
 
51
52
  def archive_path
@@ -60,6 +61,22 @@ module Rpremote
60
61
 
61
62
  attr_reader :fetcher, :extractor, :preparer, :patcher
62
63
 
64
+ def source_ref
65
+ version == "latest" ? "heads/master" : "tags/#{version}"
66
+ end
67
+
68
+ def extracted_source_dir
69
+ return source_dir unless version == "latest"
70
+
71
+ File.join(cache_dir, "picoruby-master")
72
+ end
73
+
74
+ def normalize_extracted_source
75
+ return if extracted_source_dir == source_dir || !File.directory?(extracted_source_dir)
76
+
77
+ FileUtils.mv(extracted_source_dir, source_dir)
78
+ end
79
+
63
80
  def fetch_archive
64
81
  temporary = "#{archive_path}.part"
65
82
  File.binwrite(temporary, fetcher.call(archive_url))
@@ -88,7 +105,7 @@ module Rpremote
88
105
  commands << ["git", "remote", "add", "origin", "https://github.com/picoruby/picoruby.git"]
89
106
  end
90
107
  commands.push(
91
- ["git", "fetch", "--depth", "1", "origin", "refs/tags/#{version}"],
108
+ ["git", "fetch", "--depth", "1", "origin", source_ref],
92
109
  ["git", "checkout", "--force", "FETCH_HEAD"],
93
110
  ["git", "submodule", "update", "--init", "--recursive", "--depth", "1"]
94
111
  )
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Rpremote
6
+ class PicoRubyCompiler
7
+ class Error < StandardError; end
8
+
9
+ CANDIDATES = %w[
10
+ build/mrbc/default/bin/mrbc
11
+ build/host/bin/mrbc
12
+ ].freeze
13
+
14
+ def self.ensure_legacy_path!(root)
15
+ root = File.expand_path(root)
16
+ legacy_path = File.join(root, "bin/mrbc")
17
+ return legacy_path if File.executable?(legacy_path)
18
+
19
+ compiler = CANDIDATES.map { |path| File.join(root, path) }.find { |path| File.executable?(path) }
20
+ raise Error, "PicoRuby mrbc was not built under #{root}" unless compiler
21
+
22
+ FileUtils.mkdir_p(File.dirname(legacy_path))
23
+ relative = File.join("..", compiler.delete_prefix("#{root}/"))
24
+ FileUtils.ln_sf(relative, legacy_path)
25
+ legacy_path
26
+ end
27
+ end
28
+ end
@@ -3,7 +3,6 @@
3
3
  module Rpremote
4
4
  class PicoRubySourcePatch
5
5
  JOB_PATH = "mrbgems/picoruby-shell/mrblib/job.rb"
6
- BOOTSEL_PATH = "mrbgems/picoruby-machine/include/machine.h"
7
6
  PWM_PATH = "mrbgems/picoruby-pwm/ports/rp2040/pwm.c"
8
7
  PATCH_ALIASES = { "3.4.2" => "3.4.5" }.freeze
9
8
 
@@ -21,8 +20,6 @@ module Rpremote
21
20
  patch_version = PATCH_ALIASES.fetch(version, version)
22
21
  patches(patch_version).each do |patch, prerequisite|
23
22
  next unless File.file?(patch) && File.file?(File.join(source, prerequisite))
24
- next if prerequisite == BOOTSEL_PATH && File.read(File.join(source, prerequisite)).include?("Machine_bootsel")
25
-
26
23
  next if git_apply?(source, patch, "--reverse", "--check")
27
24
 
28
25
  raise Error, "cannot apply rpremote patch to PicoRuby #{version}" unless git_apply?(source, patch, "--check")
@@ -36,7 +33,6 @@ module Rpremote
36
33
  def patches(patch_version)
37
34
  definitions = {
38
35
  "ruby-exception-status" => JOB_PATH,
39
- "bootsel" => BOOTSEL_PATH,
40
36
  "pwm-sleep-clock" => PWM_PATH
41
37
  }
42
38
  definitions.map do |name, prerequisite|
@@ -3,7 +3,7 @@
3
3
  module Rpremote
4
4
  class Target
5
5
  DEFAULT_LANGUAGE = "picoruby"
6
- DEFAULT_LANGUAGE_VERSION = "4.0.3"
6
+ DEFAULT_LANGUAGE_VERSION = "latest"
7
7
  DEFAULT_BOARD = "pico2"
8
8
  DEFAULT_CACHE_DIR = "firmware"
9
9
  IDENTIFIER_PATTERN = /\A[a-zA-Z0-9][a-zA-Z0-9._-]*\z/
@@ -75,8 +75,6 @@ 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
78
  def normalize_line_endings(data)
81
79
  normalized = +"".b
82
80
  data.each_byte do |byte|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rpremote
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
data/lib/rpremote.rb CHANGED
@@ -21,6 +21,7 @@ require_relative "rpremote/runner"
21
21
  require_relative "rpremote/resetter"
22
22
  require_relative "rpremote/recursive_copy"
23
23
  require_relative "rpremote/picoruby_source_patch"
24
+ require_relative "rpremote/picoruby_compiler"
24
25
  require_relative "rpremote/language_source"
25
26
  require_relative "rpremote/nuke_firmware"
26
27
  require_relative "rpremote/mrbgems"
data/sig/rpremote.rbs CHANGED
@@ -188,6 +188,15 @@ module Rpremote
188
188
  def apply: (String source) -> void
189
189
  end
190
190
 
191
+ class PicoRubyCompiler
192
+ CANDIDATES: Array[String]
193
+
194
+ class Error < StandardError
195
+ end
196
+
197
+ def self.ensure_legacy_path!: (String root) -> String
198
+ end
199
+
191
200
  class Builder
192
201
  class Error < Rpremote::Error
193
202
  end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "fileutils"
5
+ require_relative "../lib/rpremote/picoruby_compiler"
5
6
 
6
7
  REPOSITORY_ROOT = File.expand_path(ENV.fetch("RPREMOTE_ROOT", File.expand_path("../..", __dir__)))
7
8
  DEFAULT_BOARD = "pico2"
@@ -14,7 +15,7 @@ def command!(*command, chdir:, env: {})
14
15
  end
15
16
 
16
17
  language = ENV.fetch("RPREMOTE_LANGUAGE", "picoruby")
17
- target_version = ENV.fetch("RPREMOTE_LANGUAGE_VERSION", "4.0.3")
18
+ target_version = ENV.fetch("RPREMOTE_LANGUAGE_VERSION", "latest")
18
19
  board = ENV.fetch("RPREMOTE_BOARD", DEFAULT_BOARD)
19
20
  abort "Unsupported language: #{language}" unless language == "picoruby"
20
21
  abort "Unsupported board: #{board}" unless SUPPORTED_BOARDS.include?(board)
@@ -43,7 +44,8 @@ command!("rake", "r2p2:setup", chdir: picoruby_root) unless File.directory?(pico
43
44
  version_header = File.join(picoruby_root, "include/version.h")
44
45
  version = File.read(version_header)[/#define PICORUBY_VERSION "(.+?)"/, 1]
45
46
  abort "Could not determine PicoRuby version from #{version_header}" unless version
46
- abort "PicoRuby source is #{version}, but #{target_version} was requested." unless version == target_version
47
+ abort "PicoRuby source is #{version}, but #{target_version} was requested." \
48
+ unless target_version == "latest" || version == target_version
47
49
 
48
50
  cache_file = File.join(output_dir, "CMakeCache.txt")
49
51
  if File.file?(cache_file) && !File.read(cache_file).include?("CMAKE_HOME_DIRECTORY:INTERNAL=#{cmake_source_dir}")
@@ -64,6 +66,12 @@ if fingerprint && File.directory?(mruby_build_dir)
64
66
  FileUtils.rm_rf(mruby_build_dir)
65
67
  end
66
68
  command!("rake", chdir: picoruby_root, env: build_env)
69
+ begin
70
+ compiler = Rpremote::PicoRubyCompiler.ensure_legacy_path!(picoruby_root)
71
+ puts "Using PicoRuby compiler: #{compiler}"
72
+ rescue Rpremote::PicoRubyCompiler::Error => e
73
+ abort e.message
74
+ end
67
75
 
68
76
  cmake_definitions = [
69
77
  "-D", "PICORUBY_ROOT=#{picoruby_root}",
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.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ogom
@@ -46,6 +46,7 @@ files:
46
46
  - lib/rpremote/mrbgems_command.rb
47
47
  - lib/rpremote/nuke_firmware.rb
48
48
  - lib/rpremote/picomodem.rb
49
+ - lib/rpremote/picoruby_compiler.rb
49
50
  - lib/rpremote/picoruby_source_patch.rb
50
51
  - lib/rpremote/recursive_copy.rb
51
52
  - lib/rpremote/remote_path.rb
@@ -57,9 +58,7 @@ files:
57
58
  - lib/rpremote/target.rb
58
59
  - lib/rpremote/terminal.rb
59
60
  - lib/rpremote/version.rb
60
- - patches/picoruby-3.4.5-bootsel.patch
61
61
  - patches/picoruby-3.4.5-ruby-exception-status.patch
62
- - patches/picoruby-4.0.3-bootsel.patch
63
62
  - patches/picoruby-4.0.3-pwm-sleep-clock.patch
64
63
  - patches/picoruby-4.0.3-ruby-exception-status.patch
65
64
  - sig/rpremote.rbs
@@ -1,71 +0,0 @@
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
@@ -1,71 +0,0 @@
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