Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
feat(env): PLAN03-1 PR1 devbase env export (Local + Stdio)#14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Uh oh!
There was an error while loading. Please reload this page.
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
5e5b156
chore(PLAN03-1-export-local): Draft PR 作成
takemi-ohama c3de981
feat(env): devbase env export を追加 (PLAN03-1 PR1)
takemi-ohama f406c8c
fix(env): レビュー指摘の修正 (storage/bundle/cipher)
takemi-ohama 8baca0c
fix(env): round 2 レビュー指摘の修正 (堅牢性 + test 追加)
takemi-ohama cbb98ca
fix(env): sha256 必須化と ed25519 デフォルト鍵対応 (round 3)
takemi-ohama 2c09ae7
fix(env): round 4 レビュー指摘の修正 (異常系の堅牢化)
takemi-ohama 776cb8d
fix(env): _resolve_identity の OSError を CipherError に包む (round 5)
takemi-ohama d357e86
fix(env): round 6 レビュー指摘の修正 (決定性 + 完全性 + 堅牢性)
takemi-ohama c07b1a7
fix(env): @PATH 参照ファイルのコメント・空行をスキップする (round 6 追加)
takemi-ohama 521c28d
fix(env): round 1 レビュー指摘の修正 (TOCTOU + BundleError 統一 + prefix 互換 + co…
takemi-ohama 01b2208
fix(env): round 2 advisory レビュー指摘の修正 (docstring / help / stdin prompt)
takemi-ohama File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -36,11 +36,20 @@ | ||
| # Subcommand map for prefix resolution: {(aliases...): [subcmds]} | ||
| SUBCMD_MAP = { | ||
| ('container', 'ct'): ['up', 'down', 'ps', 'login', 'logs', 'scale', 'build'], | ||
| ('env',): ['init', 'sync', 'list', 'set', 'get', 'delete', 'edit', 'project'], | ||
| ('env',): ['init', 'sync', 'list', 'set', 'get', 'delete', 'edit', 'project', 'export'], | ||
| ('plugin', 'pl'): ['list', 'install', 'uninstall', 'update', 'info', 'sync', 'repo'], | ||
| ('snapshot', 'ss'): ['create', 'list', 'restore', 'copy', 'delete', 'rotate'], | ||
| } | ||
| # 後方互換: prefix が複数候補にマッチする場合に、特定の入力を特定のサブコマンドに | ||
| # 優先的に解決させる。例えば `devbase env e` は従来 `edit` のみに解決されていたが、 | ||
| # `export` 追加後は ambiguous になるため、既存ショートカットを維持するために維持先を明示する。 | ||
| SUBCMD_PREFIX_PREFERENCES = { | ||
| ('env',): { | ||
| 'e': 'edit', | ||
| }, | ||
| } | ||
| def _require_devbase_root() -> Path: | ||
| """Get DEVBASE_ROOT from environment, exiting if not set.""" | ||
| @@ -109,6 +118,37 @@ def _add_env_parser(subparsers): | ||
| env_sub.add_parser('edit', help='Open .env in editor') | ||
| env_sub.add_parser('project', help='Setup project-specific variables') | ||
| env_export = env_sub.add_parser( | ||
| 'export', | ||
takemi-ohama marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| help='Export .env files as an encrypted bundle (age)', | ||
| ) | ||
| env_export.add_argument('dest', nargs='?', default=None, | ||
| help="Output path (default: ./devbase-env-<TS>.dbenv, '-' for stdout)") | ||
| env_export.add_argument('--include-project', action='append', default=None, | ||
| metavar='NAME', dest='include_projects', | ||
| help='Limit to specified project (repeatable)') | ||
| env_export.add_argument('--exclude-project', action='append', default=[], | ||
| metavar='NAME', dest='exclude_projects', | ||
| help='Exclude project (repeatable)') | ||
| env_export.add_argument('--no-global', action='store_true', | ||
| help='Exclude $DEVBASE_ROOT/.env') | ||
| env_export.add_argument('--no-metadata', action='store_true', | ||
| help='Exclude $DEVBASE_ROOT/.env.sources.yml') | ||
| env_export.add_argument('--recipient', action='append', default=[], | ||
| metavar='KEY', dest='recipients', | ||
| help=("age / OpenSSH public key (repeatable). " | ||
| "Formats: 'age1...', 'ssh-ed25519 AAAA...', 'ssh-rsa AAAA...', " | ||
| "'@PATH' for file reference. " | ||
| "Default: ~/.ssh/id_ed25519.pub, then ~/.ssh/id_rsa.pub " | ||
| "(first existing one)")) | ||
| env_export.add_argument('--passphrase-env', metavar='VAR', default=None, | ||
| help='Read passphrase from environment variable VAR') | ||
| env_export.add_argument('--passphrase-stdin', action='store_true', | ||
| help='Read passphrase from the first line of stdin') | ||
| env_export.add_argument('--force-unencrypted', action='store_true', | ||
| help='Write as plaintext tar.gz (rejected by default; ' | ||
| 'warns when sensitive keys are detected)') | ||
| def _add_plugin_parser(subparsers): | ||
| """Plugin group parser""" | ||
| @@ -250,14 +290,22 @@ def _create_parser(): | ||
| return parser | ||
| def _resolve_prefix(input_cmd, candidates): | ||
| def _resolve_prefix(input_cmd, candidates, preferences=None): | ||
| """Resolve an abbreviated command to its full name via unique prefix matching. | ||
| Returns the full command name if exactly one candidate matches, | ||
| otherwise returns the input as-is (ambiguous or no match). | ||
| Returns the full command name if exactly one candidate matches. | ||
| If ambiguous, falls back to `preferences[input_cmd]` (if provided) to keep | ||
| backward compatibility with previously-unique abbreviations. | ||
| Otherwise returns the input as-is. | ||
| """ | ||
| matches = [c for c in candidates if c.startswith(input_cmd)] | ||
| return matches[0] if len(matches) == 1 else input_cmd | ||
| if len(matches) == 1: | ||
| return matches[0] | ||
| if preferences and input_cmd in preferences: | ||
| preferred = preferences[input_cmd] | ||
| if preferred in matches: | ||
| return preferred | ||
| return input_cmd | ||
| def _expand_argv(): | ||
| @@ -273,7 +321,8 @@ def _expand_argv(): | ||
| cmd = sys.argv[1] | ||
| for aliases, subcmds in SUBCMD_MAP.items(): | ||
| if cmd in aliases: | ||
| sys.argv[2] = _resolve_prefix(sys.argv[2], subcmds) | ||
| preferences = SUBCMD_PREFIX_PREFERENCES.get(aliases) | ||
| sys.argv[2] = _resolve_prefix(sys.argv[2], subcmds, preferences) | ||
| break | ||
| # plugin repo sub-subcommand | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.