moonraker-bosun 0.1.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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE +21 -0
  4. data/README.ja.md +467 -0
  5. data/README.md +124 -0
  6. data/docs/design.md +358 -0
  7. data/docs/moonraker-api.md +108 -0
  8. data/exe/bosun +7 -0
  9. data/lib/moonraker/bosun/cli.rb +64 -0
  10. data/lib/moonraker/bosun/client.rb +147 -0
  11. data/lib/moonraker/bosun/commands/add.rb +38 -0
  12. data/lib/moonraker/bosun/commands/audit.rb +48 -0
  13. data/lib/moonraker/bosun/commands/backup.rb +135 -0
  14. data/lib/moonraker/bosun/commands/base.rb +61 -0
  15. data/lib/moonraker/bosun/commands/diff.rb +29 -0
  16. data/lib/moonraker/bosun/commands/export.rb +103 -0
  17. data/lib/moonraker/bosun/commands/fetching.rb +76 -0
  18. data/lib/moonraker/bosun/commands/forget.rb +26 -0
  19. data/lib/moonraker/bosun/commands/get.rb +57 -0
  20. data/lib/moonraker/bosun/commands/ls.rb +43 -0
  21. data/lib/moonraker/bosun/commands/pull.rb +52 -0
  22. data/lib/moonraker/bosun/commands/push.rb +136 -0
  23. data/lib/moonraker/bosun/commands/removing.rb +38 -0
  24. data/lib/moonraker/bosun/commands/rm.rb +105 -0
  25. data/lib/moonraker/bosun/commands/roots.rb +31 -0
  26. data/lib/moonraker/bosun/commands/status.rb +22 -0
  27. data/lib/moonraker/bosun/commands/status_report.rb +75 -0
  28. data/lib/moonraker/bosun/config.rb +31 -0
  29. data/lib/moonraker/bosun/context.rb +26 -0
  30. data/lib/moonraker/bosun/error.rb +8 -0
  31. data/lib/moonraker/bosun/file_rules.rb +37 -0
  32. data/lib/moonraker/bosun/git.rb +139 -0
  33. data/lib/moonraker/bosun/host_tracking.rb +214 -0
  34. data/lib/moonraker/bosun/messages/catalog.rb +837 -0
  35. data/lib/moonraker/bosun/messages.rb +42 -0
  36. data/lib/moonraker/bosun/push_plan.rb +89 -0
  37. data/lib/moonraker/bosun/sync_status.rb +130 -0
  38. data/lib/moonraker/bosun/version.rb +7 -0
  39. data/lib/moonraker/bosun.rb +31 -0
  40. metadata +86 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3bec63541f4e1791a77fca0a6956e2e431029e9ffcc094122486bcad112cef7e
4
+ data.tar.gz: e661ba46bd679ee151f30508a94215ddafd3f7aafba00f31ef42d3dde7c6b7d1
5
+ SHA512:
6
+ metadata.gz: 9bc7976e16540b24fbd69606e4b941d7d8f7cb9860c1d5addd04f3a9bbcbb5d6f6ed5090612409f40c3fb0ec9ff9107bce6192ad4bdf819a0eeb4e1adbd65db3
7
+ data.tar.gz: '019ab618e932e6f34f8cc4b6b599afd6458ece1b9bee58d6a587d42f93a16b0aa013973ed831dffcf3d36fbc36c89ff4dc3afe1c7b91d3c20ce0d2e852ff2eff'
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2026-10-11
4
+
5
+ ### 機能
6
+
7
+ - Moonraker APIを通して、ホストの設定ファイルを取得し、gitで管理する(`host-tracking`ブランチに記録する)
8
+ - ホストのRootディレクトリ、ファイルの一覧の表示と、ファイルの取得(`roots`、`ls`、`get`)
9
+ - トラッキングの開始と、ホストでの変更の取り込み(`add`、`pull`)
10
+ - ホストとローカルの状態の表示と、内容まで比べた検査(`status`、`audit`)
11
+ - ローカルでの変更の確認と、ホストへの反映(`diff`、`push`)
12
+ - ホストで変更されていないこと、印刷中でないことを確かめてから反映する
13
+ - トラッキングの終了と、ホストのファイルの削除(`forget`、`rm`)
14
+ - Moonraker DBのバックアップ(`backup`)
15
+ - ある時点で取得していたファイルの書き出し(`export`)
16
+ - 日本語と英語のメッセージ(`LC_ALL`、`LC_MESSAGES`、`LANG`で切り替える)
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 akira yamada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.ja.md ADDED
@@ -0,0 +1,467 @@
1
+ # moonraker-bosun
2
+
3
+ [English](README.md)
4
+
5
+ Klipperのホストにある設定ファイルとMoonraker DBの内容を、Moonraker APIを通して取得し、gitで管理するためのツールです。
6
+ コマンド名は`bosun`です。
7
+
8
+ * ホストから取得した内容を、専用のブランチ`host-tracking`に記録します
9
+ * ローカルで編集した設定を、ホストで変更されていないことを確かめてから反映します
10
+ * 印刷中はホストに書き込みません。Klipperの再起動(RESTARTなど)も行いません
11
+ * Mainsail、FluiddなどのWeb UIや、MainsailOSなどの環境には依存しません(Moonraker APIだけを使います)
12
+
13
+ gitの運用方法(トラッキングの設計)は[docs/design.md](docs/design.md)を参照してください。
14
+
15
+ ## 必要なもの
16
+
17
+ * Ruby 3.4以降
18
+ * git
19
+ * Moonraker API(認証なしで接続できること)
20
+ * Moonrakerの認証(APIキーなど)にはまだ対応していません。ローカルネットワークやVPN(Tailscaleなど)の中で使うことを想定しています
21
+
22
+ ## インストール
23
+
24
+ ```bash
25
+ gem install moonraker-bosun
26
+ ```
27
+
28
+ ソースからインストールする場合:
29
+
30
+ ```bash
31
+ git clone <このリポジトリ>
32
+ cd moonraker-bosun
33
+ bundle install
34
+ bundle exec rake install
35
+ ```
36
+
37
+ ## 使い方
38
+
39
+ 設定を管理するためのgitリポジトリを用意し、その中で実行します。
40
+ `bosun`は、カレントディレクトリを含むgitリポジトリの`config/`と`backup/`を使います。
41
+
42
+ ```bash
43
+ mkdir my-printer && cd my-printer
44
+ git init
45
+ git commit --allow-empty -m "初期化" # bosunはHEADにコミットがあることを前提にします
46
+
47
+ export MOONRAKER_BASE_URL=http://<ホスト名>:7125
48
+ bosun ls # ホストの設定ファイルの一覧
49
+ bosun add printer.cfg moonraker.conf # トラッキングを始める
50
+ bosun backup # Moonraker DB(Web UIの設定など)のバックアップ
51
+ ```
52
+
53
+ その後は、次のように使います。
54
+
55
+ ```bash
56
+ bosun status # ホストとローカルの状態を確認する
57
+ bosun pull # ホストでの変更(SAVE_CONFIGなど)を取り込む
58
+ vi config/printer.cfg && git commit -am "設定を変更"
59
+ bosun push -n # ホストに反映する内容を確認する
60
+ bosun push # ホストに反映する
61
+ ```
62
+
63
+ ### 接続先の指定
64
+
65
+ Moonraker APIの接続先のベースURLを、環境変数`MOONRAKER_BASE_URL`で指定します。
66
+
67
+ ```bash
68
+ export MOONRAKER_BASE_URL=http://mainsailos.local:7125
69
+ ```
70
+
71
+ ### メッセージの言語
72
+
73
+ メッセージは日本語と英語で表示できます。
74
+ 環境変数`LC_ALL`、`LC_MESSAGES`、`LANG`の順に見て、最初に設定されている値が`ja`で始まれば日本語、それ以外は英語で表示します。
75
+ このREADMEの出力例は日本語の場合のものです。
76
+
77
+ ```bash
78
+ export LANG=ja_JP.UTF-8
79
+ ```
80
+
81
+ gitに記録するメッセージ(マージコミットなど)は、表示の言語によらず英語です。
82
+
83
+ ## 機能
84
+
85
+ ### 共通
86
+
87
+ * `-r ROOT`、`--root ROOT`で対象のRootディレクトリ(`config`、`logs`、`config_examples`など)を指定する
88
+ * 省略時は`config`
89
+ * `bosun <コマンド> --help`で、コマンドごとの説明を表示する
90
+
91
+ ### 対象から除外するファイル
92
+
93
+ Root `config`の次のファイルは、`ls`で表示しない。
94
+ 他のRootでは除外しない。
95
+
96
+ * Moonrakerが`permissions`を`rw`と報告しないファイル(シンボリックリンクなど)
97
+ * ホスト側で作られるバックアップファイル
98
+ * Klipperの`SAVE_CONFIG`によるもの: `<名前>-YYYYMMDD_HHMMSS.cfg`
99
+ * Moonrakerによるもの: `.<名前>.bkp`
100
+
101
+ ### `bosun roots`
102
+
103
+ ホストのRootディレクトリの一覧を表示する。
104
+
105
+ ```bash
106
+ bosun roots [-l]
107
+ ```
108
+
109
+ * Moonrakerが返す順(`config`が先頭)に、1行に1つ表示する
110
+ * `-l`、`--long`: 権限とホスト側のパスも表示する
111
+
112
+ ```
113
+ $ bosun roots -l
114
+ rw config /home/a/printer_data/config
115
+ r logs /home/a/printer_data/logs
116
+ rw gcodes /home/a/printer_data/gcodes
117
+ r config_examples /home/a/klipper/config
118
+ r docs /home/a/klipper/docs
119
+ ```
120
+
121
+ ### `bosun ls`
122
+
123
+ ホストのファイル一覧を表示する。
124
+
125
+ ```bash
126
+ bosun ls [-r ROOT] [-a] [-l]
127
+ ```
128
+
129
+ * パスの順に並べて、1行に1ファイルを表示する
130
+ * `-a`、`--all`: 除外しているファイルも表示する
131
+ * `-l`、`--long`: 権限、サイズ、更新日時も表示する
132
+ * `-a`と組み合わせると、除外しているファイルに理由を付けて表示する
133
+
134
+ ```
135
+ $ bosun ls -la
136
+ rw 1307 2026-09-30 15:45:55 .moonraker.conf.bkp (除外: バックアップファイル)
137
+ rw 2507 2026-05-07 04:58:34 crowsnest.conf
138
+ r 16493 2026-05-07 04:58:26 mainsail.cfg (除外: rwでない)
139
+ rw 2767 2026-10-11 14:11:06 printer.cfg
140
+ ```
141
+
142
+ ### `bosun get`
143
+
144
+ ホストのファイルを、git管理下に置かずにカレントディレクトリに取得する。
145
+
146
+ ```bash
147
+ bosun get [-r ROOT] ファイル...
148
+ ```
149
+
150
+ * 除外しているファイルも取得できる
151
+ * シンボリックリンクは、リンク先の内容を取得する
152
+ * サブディレクトリのファイルは、ファイル名だけで保存する(`macros/a.cfg`は`a.cfg`になる)
153
+ * 次の場合は、何も保存せずに中止する
154
+ * カレントディレクトリに同名のファイルがある
155
+ * 保存するファイル名が重複している
156
+ * 指定したファイルのいずれかがホストにない
157
+
158
+ ### `bosun add`
159
+
160
+ Root `config`のファイルを取得して、トラッキングを始める。
161
+
162
+ ```bash
163
+ bosun add ファイル...
164
+ ```
165
+
166
+ * ホストから取得した内容を`host-tracking`ブランチにコミットし、現在のブランチにマージする
167
+ * リポジトリ上のパスは`config/<ファイル>`になる
168
+ * gitの運用方法は[docs/design.md](docs/design.md)を参照
169
+ * トラッキング中のファイルを指定した場合は、取得し直す
170
+ * 内容が変わっていなければ、コミットしない
171
+ * 除外しているファイル(`bosun ls`で表示しないファイル)は指定できない
172
+ * 次の場合は、ホストから取得する前に中止する
173
+ * detached HEADの場合、`host-tracking`ブランチの場合、マージの途中の場合
174
+ * ステージ済みの変更がある場合
175
+ * 指定したファイルなどに、未コミットの変更やgit管理外のファイルがある場合
176
+ * マージで衝突した場合は、衝突を解決して`git commit`するか、`git merge --abort`で中止する
177
+ * `host-tracking`へのコミットは完了しているので、取得し直す必要はない
178
+
179
+ ```
180
+ $ bosun add printer.cfg moonraker.conf
181
+ 取得しました: config/printer.cfg
182
+ 取得しました: config/moonraker.conf
183
+ host-trackingにコミットしました: 374ed20
184
+ 変更: config/moonraker.conf
185
+ 変更: config/printer.cfg
186
+ mainにマージしました
187
+ ```
188
+
189
+ ### `bosun pull`
190
+
191
+ トラッキング中のファイルを、ホストから一括で取得する。
192
+
193
+ ```bash
194
+ bosun pull
195
+ ```
196
+
197
+ * `add`と同様に、`host-tracking`ブランチにコミットし、現在のブランチにマージする
198
+ * 内容が変わったファイルがなければ、コミットしない
199
+ * `host-tracking`に未マージのコミットがあれば、変更がなくてもマージする
200
+ * 次のファイルは取得せず、警告して手順を案内する
201
+ * ホストで削除されたファイル(トラッキングは続ける。やめる場合は`bosun forget`)
202
+ * ホストで`rw`でなくなったファイル
203
+ * トラッキングしていないファイル
204
+ * 中止する条件やマージで衝突した場合の扱いは、`add`と同じ
205
+ * 未コミットの変更などを確認する対象は、トラッキング中のすべてのファイル
206
+
207
+ ```
208
+ $ bosun pull
209
+ 取得しました: config/crowsnest.conf
210
+ 取得しました: config/moonraker.conf
211
+ 取得しました: config/printer.cfg
212
+ 取得しました: config/sonar.conf
213
+ host-trackingにコミットしました: 6edaa72
214
+ 変更: config/printer.cfg
215
+ mainにマージしました
216
+ ```
217
+
218
+ ### `bosun status`
219
+
220
+ ホスト、`host-tracking`(最後に取得した内容)、`HEAD`の3つを比べて、Root `config`のファイルの状態を表示する。
221
+
222
+ ```bash
223
+ bosun status
224
+ ```
225
+
226
+ * 同期済みでないファイルを状態ごとにまとめ、解消するための手順を案内する
227
+ * 状態の一覧は[docs/design.md](docs/design.md)の「状態の判定」を参照
228
+ * ホストで削除されたファイルと同じ内容のトラッキングしていないファイルがあれば、名前の変更の可能性として表示する
229
+ * `HEAD`の内容で判定する。`config/`の未コミットの変更は、別に表示する
230
+ * `host-tracking`に、まだ現在のブランチに取り込んでいないコミットがあれば警告する
231
+ * ホストの内容は、ファイル一覧の更新日時とサイズで判定する
232
+ * 更新日時だけが変わったファイルは、取得して内容を比べる
233
+ * 更新日時とサイズが同じまま内容が変わった場合は検知できない(`bosun audit`で検知する)
234
+
235
+ ```
236
+ $ bosun status
237
+ host-tracking: 388820b (2026-10-11 14:46:50)
238
+
239
+ ローカルで変更:
240
+ moonraker.conf
241
+ → bosun push でホストに反映する
242
+
243
+ ホストで削除:
244
+ bosun-probe.cfg
245
+ → トラッキングをやめるなら bosun forget <ファイル>
246
+
247
+ 同期済み: 3件
248
+ ```
249
+
250
+ ### `bosun audit`
251
+
252
+ `status`と同じ内容を、トラッキング中のすべてのファイルを取得して厳密に判定する。
253
+ あわせて、`host-tracking`ブランチの不変条件を検査する。
254
+
255
+ ```bash
256
+ bosun audit
257
+ ```
258
+
259
+ * 不変条件は、`host-tracking`のすべてのコミットについて次のことを検査する
260
+ * マージコミットでないこと
261
+ * `Host-Op`があり、既知の操作であること(`bosun`以外で作られたコミットがないこと)
262
+ * `config/`と`backup/`以外のファイルがないこと
263
+ * `Host-File`に記録したファイルがツリーにあり、サイズが一致すること
264
+ * `Host-File`に削除と記録したファイルが、ツリーにないこと
265
+ * `Host-DB`に記録したファイルがツリーにあること
266
+ * 問題があれば終了コードを1にする
267
+ * 不変条件の違反、同期済みでないファイル、名前の変更の可能性、`host-tracking`の未マージのコミット
268
+ * トラッキングしていないファイルは表示するが、問題としない(あえてトラッキングしないこともあるため)
269
+ * 未コミットの変更は表示するが、問題としない
270
+
271
+ ```
272
+ $ bosun audit
273
+ host-tracking: 3d7e0ff (2026-10-11 14:42:16)
274
+
275
+ すべて同期済みです(4件)
276
+
277
+ host-trackingの不変条件: 問題なし
278
+
279
+ 問題はありません
280
+ ```
281
+
282
+ ### `bosun diff`
283
+
284
+ 最後に取得した内容(`host-tracking`)と、ローカル(`HEAD`)の内容の差分を表示する。
285
+ `bosun push`で反映される内容の確認に使う。
286
+
287
+ ```bash
288
+ bosun diff [--stat] [ファイル...]
289
+ ```
290
+
291
+ * `git diff host-tracking HEAD -- config/`と同じ
292
+ * ホストの現在の内容との差分ではない(ホストでの変更は`bosun status`で確認する)
293
+ * 未コミットの変更は含めない
294
+ * ファイルを指定すると、そのファイルに限る
295
+ * `--stat`: 変更の概要だけを表示する
296
+
297
+ ### `bosun push`
298
+
299
+ ローカル(`HEAD`)での変更を、ホストに反映する。
300
+
301
+ ```bash
302
+ bosun push [-n]
303
+ ```
304
+
305
+ * `HEAD`にあり、最後に取得した内容と異なるファイルを反映の対象にする
306
+ * 最後に取得した内容にあれば更新、なければ作成
307
+ * 反映する内容は`bosun diff`で確認できる
308
+ * `-n`、`--dry-run`: 反映する内容を表示するだけで、ホストには書き込まない
309
+ * 次の場合は、何も反映せずに中止する(終了コードは1)
310
+ * 印刷中(`print_stats.state`が`printing`または`paused`)
311
+ * `config/`に未コミットの変更やgit管理外のファイルがある、ステージ済みの変更がある、`host-tracking`に未マージのコミットがある
312
+ * 反映できないファイルが1件でもある
313
+ * 共通: 通常のファイル(gitのモードが`100644`)でない(シンボリックリンク、実行可能ファイルなど)
314
+ * 更新: ホストで変更されている(内容を取得して確認する)、ホストで削除されている、`rw`でない
315
+ * 作成: ホストに同名のファイルがある、ホスト側のバックアップファイルと同じ形式の名前
316
+ * 確認の後、書き込む直前までにホストでファイルが変わった
317
+ * ローカルで削除したファイルや、ホストだけで変更されたファイルは反映せず、状態と手順を案内する
318
+ * 反映した後、ホストから取得し直して`host-tracking`にコミットし、現在のブランチにマージする
319
+ * アップロードの途中で失敗した場合や、Ctrl-Cで中断した場合も、反映できたファイルは記録する
320
+ * 設定を有効にするための再起動(KlipperのRESTARTなど)は行わない
321
+
322
+ ```
323
+ $ bosun push
324
+ 作成: macros.cfg
325
+ 更新: printer.cfg
326
+
327
+ アップロードしました: macros.cfg
328
+ アップロードしました: printer.cfg
329
+ 取得しました: config/macros.cfg
330
+ 取得しました: config/printer.cfg
331
+ host-trackingにコミットしました: b98b680
332
+ 変更: config/macros.cfg
333
+ 変更: config/printer.cfg
334
+ mainにマージしました
335
+
336
+ 反映した設定を有効にするには、Web UIなどから再起動(KlipperならRESTART)を行ってください(bosunでは行いません)
337
+ ```
338
+
339
+ ### `bosun forget`
340
+
341
+ ホストのファイルを残したまま、トラッキングをやめる。
342
+
343
+ ```bash
344
+ bosun forget ファイル...
345
+ ```
346
+
347
+ * `host-tracking`からファイルを除いてコミットし、現在のブランチにマージする(ローカルからも削除される)
348
+ * ホストには接続しない(ホストがオフラインでも実行できる)
349
+ * 次の場合は中止する
350
+ * トラッキングしていないファイルを指定した
351
+ * 未コミットの変更などがある(`add`と同じ)
352
+ * ローカル(`HEAD`)で変更されている
353
+ * 変更を戻すか、ローカルで削除してから実行する
354
+
355
+ ```
356
+ $ bosun forget crowsnest.conf
357
+ host-trackingにコミットしました: 0531f23
358
+ 削除: config/crowsnest.conf
359
+ mainにマージしました
360
+
361
+ ホストのファイルは削除していません
362
+ ```
363
+
364
+ ### `bosun rm`
365
+
366
+ ホストのファイルを削除し、トラッキングをやめる。
367
+
368
+ ```bash
369
+ bosun rm [-n] ファイル...
370
+ ```
371
+
372
+ * `forget`と同じ確認に加えて、次の場合は何も削除せずに中止する
373
+ * 印刷中
374
+ * ホストで変更されている(内容を取得して確認する)、ホストで削除されている、`rw`でない
375
+ * 確認の後、削除する直前までにホストでファイルが変わった
376
+ * ホストのファイルを削除した後、`host-tracking`から除いてコミットし、現在のブランチにマージする
377
+ * `-n`、`--dry-run`: 削除するファイルを表示するだけで、ホストのファイルは削除しない
378
+
379
+ ```
380
+ $ bosun rm old-macros.cfg
381
+ 削除: old-macros.cfg
382
+
383
+ 削除しました: old-macros.cfg
384
+ host-trackingにコミットしました: 47a9d3f
385
+ 削除: config/old-macros.cfg
386
+ mainにマージしました
387
+ ```
388
+
389
+ ### `bosun backup`
390
+
391
+ Moonraker DBの内容(Mainsailの設定など)を、`backup/moonraker-db/<namespace>.json`に取得する。
392
+
393
+ ```bash
394
+ bosun backup [namespace...]
395
+ bosun backup --status
396
+ ```
397
+
398
+ * `add`や`pull`と同じく、`host-tracking`ブランチにコミットし、現在のブランチにマージする
399
+ * キーを辞書順に並べた、整形したJSONで保存する
400
+ * 内容が変わらなければコミットしない
401
+ * `bosun backup <namespace>...`: 指定したnamespaceを取得し、バックアップを始める
402
+ * `bosun backup`: バックアップしているnamespaceをすべて取得し直す
403
+ * まだ何もバックアップしていない場合は、`mainsail`、`fluidd`、`mobileraker`、`maintenance`、`webcams`、`timelapse`のうち、ホストにあるものを取得する
404
+ * これらのうち、まだバックアップしていないものがホストにあれば案内する
405
+ * `-s`、`--status`: namespaceごとに、バックアップしているか(バックアップ中、推奨、ホストにない)を表示する
406
+ * ホストへの書き戻し(復元)は行わない
407
+ * `status`と`audit`の同期の状態の判定には含めない
408
+
409
+ ```
410
+ $ bosun backup
411
+ まだ何もバックアップしていないので、次のnamespaceのうちホストにあるものをバックアップします: mainsail, fluidd, mobileraker, maintenance, webcams, timelapse
412
+ 取得しました: backup/moonraker-db/mainsail.json
413
+ 取得しました: backup/moonraker-db/maintenance.json
414
+ host-trackingにコミットしました: a1c9d88
415
+ 変更: backup/moonraker-db/mainsail.json
416
+ 変更: backup/moonraker-db/maintenance.json
417
+ mainにマージしました
418
+ ```
419
+
420
+ ### `bosun export`
421
+
422
+ ある時点で取得していたファイル(スナップショット)を、ディレクトリに書き出す。
423
+ ホストにも作業ツリーにも書き込まない。
424
+
425
+ ```bash
426
+ bosun export [--at 日時 | --rev コミット] [-o ディレクトリ] [ファイル...]
427
+ ```
428
+
429
+ * 時点の指定(省略時は最後に取得した時点)
430
+ * `--at 日時`: その日時より前で、最も新しい取得の時点(例: `--at "2026-10-11 15:00"`)
431
+ * `--rev コミット`: そのコミットの時点で取り込んでいた、最新の取得の時点
432
+ * `main`のコミットも、`host-tracking`のコミットも指定できる
433
+ * `-o`、`--output`: 書き出すディレクトリ
434
+ * 省略時は、カレントディレクトリの`export-<日時>-<コミット>/`
435
+ * すでにある場合は中止する
436
+ * ファイルを指定すると、そのファイルだけを書き出す(`printer.cfg`のようなRoot `config`からのパスか、`backup/moonraker-db/mainsail.json`のようなリポジトリ上のパス)
437
+ * 書き出すのは「その時点までに最後に取得した内容の集まり」であり、「その時点でホストにあったすべてのファイル」ではない
438
+ * `bosun add`は指定したファイルだけを取得するため
439
+ * ローカルでの変更は含まれない
440
+
441
+ ```
442
+ $ bosun export --rev b16ee8d -o /tmp/snapshot
443
+ host-tracking: 3d7e0ff (2026-10-11 14:42:16) add: 4 files
444
+ 書き出しました: /tmp/snapshot
445
+ config/crowsnest.conf
446
+ config/moonraker.conf
447
+ config/printer.cfg
448
+ config/sonar.conf
449
+ ```
450
+
451
+ ## 開発
452
+
453
+ Ruby 3.4以降に対応しています。実行時には標準ライブラリだけを使い、開発時に使うgem(minitest、RuboCop、WEBrickなど)は`Gemfile`で管理しています。
454
+ 開発環境はRuby 3.4.11(`.ruby-version`)で、Bundlerは3.4.11に同梱のもの(2.6.9)を使います。
455
+
456
+ ```bash
457
+ bundle install
458
+ bundle exec rake # テストとRuboCop
459
+ bundle exec rake test # テスト
460
+ bundle exec rake rubocop # RuboCop
461
+ bundle exec rake build # pkg/にgemを作る
462
+ bundle exec rake install # gemを作ってインストールする
463
+ ```
464
+
465
+ ## ライセンス
466
+
467
+ [MIT License](LICENSE)
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # moonraker-bosun
2
+
3
+ [日本語](README.ja.md)
4
+
5
+ A tool to track Klipper configuration files and Moonraker database contents in git, through the Moonraker API.
6
+ The command name is `bosun`.
7
+
8
+ * Records the contents fetched from the host in a dedicated branch, `host-tracking`
9
+ * Applies locally edited configuration to the host only after checking that nothing has changed there
10
+ * Never writes to the host while printing, and never restarts Klipper (no `RESTART`)
11
+ * Depends only on the Moonraker API, not on any web UI (Mainsail, Fluidd, ...) or distribution (MainsailOS, ...)
12
+
13
+ This README is a summary. The full specification of each command is in [README.ja.md](README.ja.md) (Japanese),
14
+ and the design of the tracking (how git is used) is in [docs/design.md](docs/design.md) (Japanese).
15
+
16
+ ## Requirements
17
+
18
+ * Ruby 3.4 or later
19
+ * git
20
+ * Moonraker API reachable without authentication
21
+ * Moonraker authentication (API keys, etc.) is not supported yet. bosun is meant to be used within a local network or a VPN (Tailscale, etc.)
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ gem install moonraker-bosun
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ Prepare a git repository to manage the configuration, and run `bosun` inside it.
32
+ `bosun` uses `config/` and `backup/` of the git repository containing the current directory.
33
+
34
+ ```bash
35
+ mkdir my-printer && cd my-printer
36
+ git init
37
+ git commit --allow-empty -m "Initialize" # bosun expects HEAD to have a commit
38
+
39
+ export MOONRAKER_BASE_URL=http://<host>:7125
40
+ bosun ls # list configuration files on the host
41
+ bosun add printer.cfg moonraker.conf # start tracking
42
+ bosun backup # back up the Moonraker DB (web UI settings, etc.)
43
+ ```
44
+
45
+ After that:
46
+
47
+ ```bash
48
+ bosun status # show the state of the host and local files
49
+ bosun pull # fetch changes made on the host (SAVE_CONFIG, etc.)
50
+ vi config/printer.cfg && git commit -am "Change configuration"
51
+ bosun push -n # show what would be applied to the host
52
+ bosun push # apply to the host
53
+ ```
54
+
55
+ ```
56
+ $ bosun push
57
+ Update: printer.cfg
58
+
59
+ Uploaded: printer.cfg
60
+ Fetched: config/printer.cfg
61
+ Committed to host-tracking: b98b680
62
+ changed: config/printer.cfg
63
+ Merged into main
64
+
65
+ To activate the applied configuration, restart from the web UI or elsewhere (RESTART for Klipper). bosun does not restart
66
+ ```
67
+
68
+ ### Environment variables
69
+
70
+ * `MOONRAKER_BASE_URL`: the base URL of the Moonraker API (e.g. `http://mainsailos.local:7125`)
71
+ * `LC_ALL`, `LC_MESSAGES`, `LANG`: messages are shown in Japanese if the first one set starts with `ja`, and in English otherwise
72
+ * Messages recorded in git (merge commits, etc.) are always in English
73
+
74
+ ## Commands
75
+
76
+ | Command | Description |
77
+ | --- | --- |
78
+ | `bosun roots` | List root directories on the host |
79
+ | `bosun ls` | List files on the host |
80
+ | `bosun get FILE...` | Download files from the host into the current directory (without tracking) |
81
+ | `bosun add FILE...` | Fetch files from the host and start tracking them |
82
+ | `bosun pull` | Fetch all tracked files from the host |
83
+ | `bosun status` | Show the state of configuration files on the host and locally |
84
+ | `bosun audit` | Check sync states by comparing contents, and check the invariants of `host-tracking` |
85
+ | `bosun diff` | Show differences between the last fetched contents and local (`HEAD`), i.e. what `push` would apply |
86
+ | `bosun push` | Apply local changes to the host |
87
+ | `bosun forget FILE...` | Stop tracking files, keeping them on the host |
88
+ | `bosun rm FILE...` | Delete files on the host and stop tracking them |
89
+ | `bosun backup` | Back up Moonraker DB contents into `backup/moonraker-db/` |
90
+ | `bosun export` | Write the files fetched as of a point in time to a directory |
91
+
92
+ Run `bosun <command> --help` for the options of each command.
93
+
94
+ ### How tracking works
95
+
96
+ * `add`, `pull`, `push`, `forget`, `rm` and `backup` commit what was fetched from the host to the `host-tracking` branch,
97
+ then merge it into the current branch
98
+ * `host-tracking` contains only what was actually fetched from the host
99
+ * Edit files on your working branch (e.g. `main`) and apply them with `push`
100
+ * If a merge conflicts, resolve it and `git commit`, or abort it with `git merge --abort`
101
+ * Push `host-tracking` to your remote together with `main` (`git push origin main host-tracking`); bosun does not push
102
+
103
+ ### Writing to the host
104
+
105
+ * bosun writes only to files that Moonraker reports as `rw` (symbolic links such as `mainsail.cfg` are not)
106
+ * `push` and `rm` abort if the printer is printing, or if the files on the host have changed since they were last fetched
107
+ * Files are deleted on the host only by `bosun rm`
108
+
109
+ ## Development
110
+
111
+ Ruby 3.4 or later is supported. Only the standard library is used at runtime; gems for development
112
+ (minitest, RuboCop, WEBrick, ...) are managed with `Gemfile`.
113
+ The development environment is Ruby 3.4.11 (`.ruby-version`) with its bundled Bundler (2.6.9).
114
+
115
+ ```bash
116
+ bundle install
117
+ bundle exec rake # tests and RuboCop
118
+ bundle exec rake test # tests
119
+ bundle exec rake rubocop # RuboCop
120
+ ```
121
+
122
+ ## License
123
+
124
+ [MIT License](LICENSE)