Skip to content

feat(env): PLAN03-1 PR2 devbase env import#15

Open
takemi-ohama wants to merge 7 commits into
release/PLAN03-1from
feature/PLAN03-1-import-local
Open

feat(env): PLAN03-1 PR2 devbase env import#15
takemi-ohama wants to merge 7 commits into
release/PLAN03-1from
feature/PLAN03-1-import-local

Conversation

@takemi-ohama
Copy link
Copy Markdown
Contributor

Summary

スコープ

  • lib/devbase/env/io_import.py 新設
  • merge セマンティクス
    • --merge keep-existing (既定): 既存キーを保持、新規キーのみ追加
    • --merge prefer-incoming: バンドル側の値で上書き
    • --replace-keys KEY,...: 指定キーのみ上書き
    • --replace: 対象 .env を丸ごと差し替え (backup 取得)
  • --dry-run で差分プレビュー
  • 2 フェーズ書き出し (prepare → commit) で部分適用を最小化
  • --backup-dir / --keep-last N (既定 10) で backup GC
  • .env.sources.yml 取り扱いポリシー
    • 既定: 上書きせず参照用 copy のみ
    • --no-metadata: 完全無視
    • --merge-metadata: 新規 source のみ追加 (マシン固有値は再計算)
  • CLI バリデーション
    • SOURCE='-'--passphrase-stdin の併用拒否
    • 未知 manifest version のバンドル拒否

Test plan

  • export → import の round-trip で .env 完全一致
  • --dry-run.env を変更しないこと
  • --replace で backup ディレクトリが作成されること
  • import 後も対象ファイルのパーミッションが 0600 を維持すること
  • LF / 末尾改行が保持されること
  • 未知の manifest version を含むバンドルの import が拒否されること
  • --keep-last N 後に古い backup が削除されていること
  • merge セマンティクス (衝突あり/なし、空ファイル、存在しないプロジェクト) の表テスト

`devbase env import` を追加し、export で生成したバンドル (age 暗号化済み or
平文 tar.gz) から `.env` 群を復元できるようにする。

主な機能:
- merge セマンティクス: --merge keep-existing (既定) / prefer-incoming
- --replace-keys: 指定キーのみ上書き
- --replace: 対象 .env を丸ごと差し替え (backup 取得)
- --dry-run: 差分プレビュー (書き込みなし)
- 2 フェーズ書き出し (prepare → commit) で部分適用を最小化、失敗時は
  backup から best-effort で rollback
- --backup-dir / --keep-last N (既定 10) で backup を GC
- .env.sources.yml は既定で上書きせず参照用コピーのみ、--merge-metadata で
  新規 source エントリのみ追加、--no-metadata で完全無視
- 暗号化判定: gzip magic で平文 / age 暗号化を識別
- 引数バリデーション: SOURCE='-' と --passphrase-stdin の併用拒否、
  --passphrase-env と --passphrase-stdin の併用拒否、--replace と
  --replace-keys の併用拒否
- 既定 identity: ~/.ssh/id_ed25519 → ~/.ssh/id_rsa の順で探索

テスト (tests/cli/test_env_import.py, 17 ケース):
- export → import の round-trip、0600 permission 保持、LF 保持
- merge モード別の挙動 (keep-existing / prefer-incoming / replace-keys /
  replace)、dry-run が変更しないこと、replace 時の backup 作成
- --include-project / --no-metadata / --merge-metadata の挙動
- 未知 manifest version のバンドル拒否、--keep-last による古い backup GC
- 平文バンドル import、passphrase round-trip

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@takemi-ohama takemi-ohama marked this pull request as ready for review May 21, 2026 11:26
@takemi-ohama takemi-ohama marked this pull request as draft May 21, 2026 11:27
@takemi-ohama takemi-ohama marked this pull request as ready for review May 21, 2026 11:53
Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 1 | codex | REQUEST_CHANGES

上記のデータ損失、部分適用、merge セマンティクスの修正が必要です。

Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py
Comment thread lib/devbase/env/io_import.py
Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 1 | gemini | REQUEST_CHANGES

本PRは env import 機能を追加するものですが、バックアップの自動削除ロジックにおける安全性や、特定キー上書き時のマージ挙動に重大な問題が見つかりました。以下の指摘事項の修正をお願いします。

Comment thread lib/devbase/env/io_import.py
Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py
cross-review round 1 で指摘されたデータ損失・部分適用・merge 不整合を修正:

- --replace-keys 指定外でも既存に無い incoming 新規キーは追加するように修正
  (CLI help の "other keys behave like keep-existing" に整合)
- _rollback で op='create' なターゲットは backup が無くても unlink し、
  commit 途中失敗時の部分適用残骸を消す
- _gc_backups は devbase が生成する timestamp 形式 (YYYYMMDD-HHMMSS) の
  ディレクトリのみを削除対象にし、--backup-dir 親に置かれた無関係なファイル
  /ディレクトリを誤って消さないようにする
- EnvFile.parse_bytes(data) を新設し、io_import の bytes パースを
  一時ファイル経由から直接パースに置き換え (I/O 削減 + 例外安全)
- 上記 3 件分の回帰テストを追加

Refs: codex review #4336666744 / gemini review #4336672519
@takemi-ohama
Copy link
Copy Markdown
Contributor Author

fix-pr round 1 サマリ (--defer-nit)

cross-review round 1 (codex review #4336666744 / gemini review #4336672519) で指摘された全 7 件に対応しました。

重要度別件数 (独自再判定後)

修正内容 (commit 62363d7)

  1. _plan_env_merge (--replace-keys 分岐): 指定外でも既存に無い incoming キーは追加 (CLI help の "other keys behave like keep-existing" に整合)
  2. _rollback: op='create' の target は backup 無くても unlink して部分適用を回避
  3. _gc_backups: 削除対象を devbase 生成の timestamp 形式 (YYYYMMDD-HHMMSS) ディレクトリのみに限定
  4. EnvFile.parse_bytes を追加し _parse_env_bytes から tempfile 経由を撤廃 (I/O 削減)
  5. 上記 1〜3 の回帰テストを追加 (test_import_replace_keys_adds_unspecified_new_keys / test_rollback_unlinks_newly_created_files_on_commit_failure / test_gc_backups_only_removes_timestamp_dirs)

重複指摘の集約

  • codex #3280948693 ≒ gemini #3280953832 (--replace-keys merge 不整合)
  • codex #3280948695 ≒ gemini #3280953842 (rollback create 残存)
  • codex #3280948700 ≒ gemini #3280953827 (GC 親ディレクトリ全体)

いずれも対応コミットを同一 reply で全 thread に通知し、修正済み thread を Resolve しました。

テスト

  • ローカル uv run pytest: 92 passed
  • python -m compileall lib bin: pass
  • ruff check --select=E9,F63,F7,F82 lib: pass

CI 状態 (push 時点スナップショット)

  • gh pr checks 15: no checks reported (PENDING / これから走る)
  • 再実行待ちはこのループでは行いません

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 2 | gemini | REQUEST_CHANGES

ロールバック時の新規ファイル削除(sources.yml 対応)と、失敗時の一時ファイルクリーンアップの徹底を提案します。

Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py
Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 2 | codex | REQUEST_CHANGES

import は .env の値を変更せず復元できることが中核要件なので、merge/create 経路の parser/formatter round-trip を修正してください。あわせて CLI 追加分の completion と、バックアップディレクトリ名の衝突回避も対応が必要です。

Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/cli.py
Comment thread lib/devbase/env/io_import.py Outdated
PR #15 round 2 のクロスレビュー指摘 (codex 3 件 + gemini 2 件) に対応。

* EnvFile.parse_bytes に double-quote 内 escape の逆変換 (state machine) を
  追加し、save / _format_env_bytes との round-trip を成立させる。これにより
  backslash / quote / 改行を含む値が import → export を経て二重エスケープ
  される問題を解消する。
* _plan_env_merge の create パスでは _format_env_bytes による再シリアライズを
  避け、incoming_bytes をそのまま採用する。バンドル側のバイト列を完全に
  保持し、parse/format に潜む副作用を確実に排除する。
* _rollback で「backup が無い = 元ファイル不在」のケースを op に関係なく
  unlink するように変更。op='sources-merge' で sources.yml を新規作成した
  ロールバックでも残骸が残らなくなる。
* _commit 失敗時に、まだ rename されていない .import.tmp ファイルを
  try-finally で確実に削除する。
* _make_backup_dir に microsecond + 連番フォールバックを付与し、同一秒内に
  import が複数回走っても backup ディレクトリが衝突しない。
* etc/devbase-completion.bash と etc/_devbase の env サブコマンド一覧に
  import を追加し、各オプションも補完できるようにする。

テストでは parse_bytes round-trip / create 経路の byte preservation /
sources.yml rollback unlink / tmp cleanup / backup 衝突回避を検証する。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@takemi-ohama
Copy link
Copy Markdown
Contributor Author

Round 2 修正サマリ (PR #15)

クロスレビュー round 2 で挙がった codex 3 件 + gemini 2 件、計 5 件にすべて対応しました。

修正コミット

  • 6125737 fix(env): import の二重エスケープ / rollback / tmp 残骸 / completion を修正

対応内訳 (5/5 修正済み, deferred: 0, rejected: 0)

# severity source summary 対応
1 major codex _format_env_bytes 再シリアライズによる二重エスケープ EnvFile.parse_bytes に state machine による unescape を追加、create 経路は incoming_bytes をそのまま採用
2 major gemini op="sources-merge" 新規作成時の rollback で sources.yml が残る _rollback の no-backup 分岐を op 非依存の unlink に変更
3 minor codex bash/zsh completion に env import 未登録 etc/devbase-completion.bash / etc/_devbase 双方に import + 全オプションを追加
4 minor codex backup ディレクトリ名が秒精度で衝突 %Y%m%d-%H%M%S-%f + -NN 連番フォールバック、_BACKUP_DIR_NAME_RE も拡張
5 minor gemini _commit 失敗時に .import.tmp が残る try-finally で _cleanup_tmps を確実に呼ぶように変更

追加テスト (6 件)

  • test_import_preserves_escaped_values_no_double_escape — backslash / quote / newline / space を含む値の create 経路 byte preservation
  • test_import_merge_round_trips_escaped_values — merge 経路 (prefer-incoming) で値が二重エスケープされないこと
  • test_envfile_parse_bytes_round_trip_with_escapes — リテラル \\n と改行を区別する state machine の検証
  • test_rollback_unlinks_newly_created_sources_yml — sources.yml 新規作成中の commit 失敗で rollback が unlink すること
  • test_commit_failure_cleans_remaining_import_tmp_files — _commit 途中失敗で .import.tmp 残骸が無いこと
  • test_backup_dir_collision_avoidance — 同一秒内連続 import で backup ディレクトリが別々に作られること

ローカル品質チェック

  • uv run pytest tests/98 passed
  • uv run python -m compileall lib bin → OK
  • uvx ruff check --select=E9,F63,F7,F82 lib → All checks passed

reviewer (@codex / @gemini) には再レビューをお願いします。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 3 | codex | APPROVE

修正必須の指摘はありません。対象テストは uv run pytest /tmp/devbase-worktrees/pr15/tests/env /tmp/devbase-worktrees/pr15/tests/cli/test_env_export.py /tmp/devbase-worktrees/pr15/tests/cli/test_env_import.py /tmp/devbase-worktrees/pr15/tests/cli/test_prefix_resolution.py で 98 passed です。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 3 | gemini | REQUEST_CHANGES

env import における既存の .env ファイルのマージ処理とエスケープ処理に、データの正確性を損なう可能性のある問題が見つかりました。特に、マージ時に既存のコメントや空行がすべて削除されてしまう点と、シェル変数展開を防ぐための $ のエスケープが不足している点は、破壊的な影響を及ぼす可能性があるため修正が必要です。

Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py Outdated
- ``EnvFile.parse_entries`` を追加し、コメント / 空行 / kv を行単位で
  トークン化できるようにする (PR #15 gemini 指摘)。
- ``_merge_into_existing_bytes`` で既存 ``.env`` のコメント・空行・キー順を
  保持したまま値を差し替えるよう merge 経路を変更。``EnvFile.dump_bytes``
  への単純差し替えではコメントが失われていた。
- ダブルクオート値に含まれる ``$`` を ``\$`` にエスケープし、``parse_bytes``
  側でも ``\$`` を ``$`` に戻すように round-trip 対応 (シェル ``source`` 時の
  意図しない変数展開を防止 / PR #15 gemini 指摘)。
- ``EnvFile.dump_bytes`` / ``EnvFile.dump_entries_bytes`` にフォーマット
  ロジックを集約し、``io_import._format_env_bytes`` を廃止。``EnvFile.save``
  も ``dump_bytes`` 経由に統一して二重実装を解消 (PR #15 gemini 指摘)。
- 新規テスト: コメント保持マージ (prefer-incoming / keep-existing)、
  ``$`` の round-trip、``EnvFile.dump_bytes`` のエスケープ仕様を追加。
@takemi-ohama
Copy link
Copy Markdown
Contributor Author

ndf:fix round 3 サマリ

gemini round 3 の指摘 3 件 (major×2, minor×1) を全て対応しました。codex round 3 は APPROVE で対象なし。

修正コミット

  • fbfbe88 fix(env): import の merge でコメントを保持し $ をエスケープする

対応内容

# 重要度 ファイル / comment 内容
1 major lib/devbase/env/io_import.py (#3281094455) merge 時に既存 .env のコメント/空行が失われる問題を修正。EnvFile.parse_entries で行単位トークン化し、_merge_into_existing_bytes既存のコメント・空行・キー順を保持 したまま値だけ差し替えるよう変更
2 major lib/devbase/env/io_import.py (#3281094461) ダブルクオート値内の $\$ にエスケープし、parse_bytes 側でも \$$ に戻すよう round-trip 対応。シェルで .env を source した際の意図しない変数展開を防止
3 minor lib/devbase/env/store.py (#3281094466) EnvFile.dump_bytes / EnvFile.dump_entries_bytes にフォーマットロジックを集約し、io_import._format_env_bytes を廃止。EnvFile.savedump_bytes 経由に統一して二重実装を解消

新規テスト

  • test_envfile_dollar_escape_round_trip$ を含む値の dump → parse round-trip 検証 (裸の $ が出力されないことを assert)
  • test_env_import_merge_preserves_comments_and_blanksprefer-incoming でコメント/空行/既存キー保持
  • test_env_import_keep_existing_preserves_commentskeep-existing でもコメント保持
  • test_env_import_dollar_value_is_escaped_after_merge — merge 後の .env 上で $ が必ず \$ 形式になっていること

ローカル検証

  • uv run pytest: 102 passed
  • uv run python -m compileall lib bin: 全ファイル OK
  • uvx ruff check --select=E9,F63,F7,F82 lib: All checks passed

Resolve 済み thread

  • PRRT_kwDOSHX-a86Dyyi9 (comment 3281094455 / コメント保持)
  • PRRT_kwDOSHX-a86DyyjG (comment 3281094461 / $ エスケープ)
  • PRRT_kwDOSHX-a86DyyjJ (comment 3281094466 / フォーマット共通化)

deferred / rejected はなし。再レビューをお願いします。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 4 | codex | APPROVE

修正要求に該当する指摘はありません。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 4 | gemini | REQUEST_CHANGES

PR #15 では、.env ファイルのマージ時にコメントや空行を保持する仕組みが導入され、全体の堅牢性が向上しています。特に $ のエスケープ対応はシェル環境での安全な利用に寄与する重要な改善です。

一方で、実装面でコードの重複がいくつか見受けられます。保守性の観点から、共通処理の括り出しを検討してください。

Comment thread lib/devbase/env/io_import.py Outdated
各マージ戦略 (replace_keys / keep-existing / prefer-incoming) で個別に書かれていた
new_bytes 生成と _Plan 構築を `_build_merge_plan` にまとめた。各分岐は
merged / added / overwritten / skipped の計算だけを担当するように整理。
動作変更なし (PR #15 gemini round4 指摘 / 既存テスト 102 件 PASS)。
@takemi-ohama
Copy link
Copy Markdown
Contributor Author

fix round 4 サマリ

このラウンドの対応

  • 対応: 1 件 (major: 1 / minor: 0 / nit: 0)
  • deferred: 0 件
  • rejected: 0 件
  • 修正コミット: 7ab664c

レビュー結果

  • codex round 4: APPROVE (0 comments)
  • gemini round 4: REQUEST_CHANGES (1 件 / major=1) — 本ラウンドで対応済み

対応内容

  • lib/devbase/env/io_import.py_plan_env_merge 内で重複していた new_bytes 生成と _Plan 構築を _build_merge_plan ヘルパーに共通化
    • 3 つの merge 分岐 (replace_keys / keep-existing / prefer-incoming) は merged / added / overwritten / skipped の決定のみを担当する形に整理
    • replace は別系統 (incoming_bytes をそのまま採用) なのでインライン維持
    • 動作変更なし。既存テスト 102 件全 PASS

ローカル品質チェック

  • uv run pytest: 102 passed (10.01s)
  • uv run python -m compileall lib bin: OK
  • uvx ruff check --select=E9,F63,F7,F82 lib: All checks passed

解決済みスレッド

  • PRRT_kwDOSHX-a86Dy_R_ — lib/devbase/env/io_import.py:286 (gemini round4: 重複コード排除)

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 5 | gemini | REQUEST_CHANGES

共通処理の _build_merge_plan への括り出しによりコードの見通しは改善されましたが、ファイルの存在判定に existing (パース済み KV 辞書) を使用している箇所に重大なバグがあります。コメントのみの .env ファイルに対してマージを行う際、既存のコメントが全て失われる設計になっています。

Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py Outdated
Comment thread lib/devbase/env/io_import.py Outdated
Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 5 | codex | REQUEST_CHANGES

既存prefix互換とコメント保持の回帰があるため、該当箇所の修正をお願いします。

Comment thread lib/devbase/cli.py
Comment thread lib/devbase/env/io_import.py Outdated
- _build_merge_plan / _plan_env_merge / replace ブランチの op 判定を
  existing (key=value dict) の有無から target.exists() に変更。
  コメント / 空行のみで構成された既存 .env が「create」と誤判定されて
  incoming_bytes で上書きされ既存コメントが失われる問題を修正
  (PR #15 round5 codex/gemini 指摘)。
- SUBCMD_PREFIX_PREFERENCES に i: init を追加。import 追加で
  devbase env i が init / import の両方にマッチして ambiguous に
  なっていたため、既存ショートカット (devbase env i → init) を維持する
  (PR #15 round5 codex 指摘)。
- 回帰テスト追加:
  - tests/cli/test_env_import.py: コメント/空行のみの既存 .env が
    prefer-incoming / keep-existing / replace-keys でコメント保持される
    こと。--replace ブランチでも op='replace' として報告され backup が
    取られること
  - tests/cli/test_prefix_resolution.py: devbase env i → init,
    devbase env im → import, devbase env in → init

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@takemi-ohama
Copy link
Copy Markdown
Contributor Author

PR #15 Round 5 修正対応サマリ

cross-review round 5 で挙がった指摘 (gemini critical/major/minor + codex minor x2、計 5 thread) に対応しました。実体は 2 個のバグ (バグ A は 4 thread 重複指摘):

修正コミット

  • 73e6697 fix(env): コメントのみ既存 .env を merge 経路に通す + env i 短縮維持

バグ A: コメント / 空行のみの既存 .env が create 扱いされる (4 thread)

_plan_env_merge / _build_merge_plan / replace ブランチで op 判定を existing (key=value dict) の空有無で行っていたため、コメント / 空行だけで構成された既存 .env が「新規作成」扱いとなり incoming_bytes で上書きされ既存コメントが失われていました。

判定基準を target.exists() に変更し、コメント / 空行のみの既存ファイルでも _merge_into_existing_bytes を通る merge 経路に入るようにしました。--replace ブランチも op='replace' として正しく報告されるようになり、_backup_existing で既存ファイルがバックアップされる挙動が保たれます。

回帰テストを tests/cli/test_env_import.py に 3 件追加:

  • test_env_import_comment_only_existing_preserves_comments_on_merge (parametrize: prefer-incoming / keep-existing)
  • test_env_import_comment_only_existing_preserves_comments_on_replace_keys
  • test_env_import_comment_only_existing_replace_reports_op_replace (op 表記 + backup 取得確認)

バグ B: devbase env iinit の後方互換喪失 (1 thread)

import 追加で devbase env iinit / import の両方にマッチし ambiguous になっていたため、SUBCMD_PREFIX_PREFERENCES[('env',)]'i': 'init' を追加して既存ショートカットを維持しました。

回帰テストを tests/cli/test_prefix_resolution.py に 3 件追加:

  • test_expand_argv_env_i_resolves_to_init
  • test_expand_argv_env_im_resolves_to_import
  • test_expand_argv_env_in_resolves_to_init

件数サマリ

区分 件数
対応 (critical) 1
対応 (major) 1
対応 (minor) 3
deferred (nit) 0
rejected 0
合計 thread 5 (resolve 済み)

ローカル品質チェック

  • uv run pytest: 109 passed
  • uv run python -m compileall lib bin: OK
  • uvx ruff check --select=E9,F63,F7,F82 lib: All checks passed

CI 状態: PR にはチェックが登録されていない (gh pr checks 15 → no checks reported)。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 6 | codex | APPROVE

修正が必要な指摘はありません。

Copy link
Copy Markdown
Contributor Author

@takemi-ohama takemi-ohama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 cross-review | round 6 | gemini | APPROVE

PR #15 の実装を確認しました。env import の機能追加、アトミックな書き換えとロールバック、コメント・空行の保持ロジックは非常に堅牢に実装されており、テストも網羅的です。既存の env export (release/PLAN03-1 で実装済み) との round-trip 整合性も確保されています。

以下の 2 点、軽微な改善提案がありますが、機能自体は完成しているため APPROVE とします。

raise ImportError(f"環境変数 {opts.passphrase_env} が空または未設定です")
return value
if opts.passphrase_stdin:
import sys
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor / メンテナンス性] import sys はファイル先頭のインポートセクションに移動することを検討してください。

import sys
if sys.stdin.isatty():
print("passphrase: ", end='', file=sys.stderr, flush=True)
line = sys.stdin.readline()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[minor / セキュリティ] TTY の場合、パスフレーズ入力時のエコーバックを避けるために getpass.getpass() の使用を検討してください。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant