Commit e0408b0
fix(plugin): copy_plugin で rmtree+copytree を rsync 同期に置換 (#17)
* fix(plugin): copy_plugin で rmtree+copytree を rsync 同期に置換
ユーザが `projects/<name>` シンボリックリンク経由で `plugins/<plugin>/projects/<name>/`
内部に `cd` した状態で `devbase plugin update` を実行すると、`copy_plugin()` の
`shutil.rmtree(dest); shutil.copytree(plugin_path, dest)` がプラグインディレクトリの
inode ごと置換し、ユーザのシェル CWD が "宙ぶらりんの旧 inode" を掴んだままになって
ファイルが消えたように見える問題があった。
`_sync_dir(src, dst)` を新設し、rmtree せずに既存ディレクトリの inode を保ったまま
ファイル差分を反映する (rsync 風)。差分は:
- src に存在しない dst エントリは削除 (orphan)
- src の symlink は再生成 (target が変わっていれば追従)
- src の dir は再帰的に同期 (両方に存在する dir は inode 維持)
- src の file は shutil.copy2 で上書き
これにより、ユーザの CWD が更新対象プラグイン配下にあっても、シェルは引き続き
同じ inode を参照し続け、`ll` で正しく中身を表示できる。
linked プラグインで dest が symlink の場合は従来どおり unlink + copytree。
新規インストールも従来どおり copytree。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(plugin): _sync_dir をユーザ編集保護セマンティクスに変更
前コミットの rsync 同期は inode は保つが、ユーザがプラグイン配下で編集
したファイル (`compose.yml`, `env` 等) や独自に置いたファイル (`.env`,
ログ等) をそのまま上書き / 削除していた。これは旧 rmtree+copytree と
同等の data-loss セマンティクスで、UX 改善としては不十分。
挙動を以下の保守的なものに置き換える:
| src | dst | content | action |
|---|---|---|---|
| 存在 | 無し | - | コピー (added) |
| 存在 | 存在 | 同じ | no-op |
| 存在 | 存在 | 違う | dst 維持、src を `<name>.new` に並置 (kept_local) |
| 無し | 存在 | - | dst 残す (preserved_orphans) |
これにより:
- `.env` 等 upstream に無いファイルは保持
- ユーザが手で書き換えた `compose.yml` も保持、upstream 版は
`compose.yml.new` として手元で diff/merge できる
- 内容が変わっていなければ `.new` も生成されない (ノイズなし)
- 既存の `.new` (前回の sync で残った) は次回 sync 時に再生成 (常に
最新の upstream を反映)
- ファイル/dir/symlink の type mismatch は upstream 側を `.new` 経由で
並置 (ユーザ側を壊さない)
`copy_plugin()` は同期後に `kept_local` / `preserved_orphans` 件数を
ログ出力し、ユーザに `.new` の存在と "merge の余地" を伝える。
NOTE: `plugin.yml` もユーザ編集として扱われるため、ユーザが意図せず
触っていた場合 registry に古い version が記録され得る。実害は表示が
古くなるだけで、`.new` が並置されるので気付ける。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(plugin): plugin.yml は _sync_dir で常時上書きする
`_sync_dir` のユーザ編集保護セマンティクスにより、ユーザが
意図せず `plugin.yml` を編集していた場合に registry の version /
description 表示が upstream と desync する可能性があった。
`plugin.yml` はプラグインのメタデータでありユーザ編集対象では
ないため、プラグインルート直下の `plugin.yml` のみ常時 upstream
で上書きする例外を `_ALWAYS_OVERWRITE_AT_ROOT` で表現する。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent aca7927 commit e0408b0
1 file changed
Lines changed: 167 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
3 | 5 | | |
4 | 6 | | |
5 | 7 | | |
6 | 8 | | |
| 9 | + | |
7 | 10 | | |
8 | 11 | | |
9 | 12 | | |
| |||
259 | 262 | | |
260 | 263 | | |
261 | 264 | | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
262 | 398 | | |
263 | 399 | | |
264 | 400 | | |
265 | 401 | | |
266 | 402 | | |
267 | 403 | | |
268 | 404 | | |
269 | | - | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
270 | 412 | | |
271 | 413 | | |
272 | 414 | | |
273 | 415 | | |
274 | 416 | | |
275 | 417 | | |
276 | 418 | | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
282 | 443 | | |
283 | 444 | | |
284 | 445 | | |
| |||
0 commit comments