From 37b6e3fbbd8daf16bb15cb1844ffecf075e7051e Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sun, 21 Jun 2026 05:17:37 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat(up):=20devbase=20up=20=E6=99=82?= =?UTF-8?q?=E3=81=AE=20.vscode/tasks.json=20=E8=87=AA=E5=8B=95=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E3=82=92=E5=BB=83=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 統合ターミナル自動表示用の folderOpen tasks.json をユーザのワークスペースへ 自動配置する挙動は余計だったため削除する。VS Code 自動オープン (PR #69/#70) はそのまま維持する。 - opener: build_folder_open_tasks_json() / is_open_terminal_enabled() を削除 - container: _maybe_place_terminal_task() と cmd_up/dispatch の open_terminal 引数を削除 - cli: --open-terminal / --no-open-terminal フラグを削除 - keys: DEVBASE_OPEN_TERMINAL 定数を削除 - docs: DEVBASE_OPEN_TERMINAL の記述を削除 - tests: 関連テストを削除 Co-Authored-By: Claude Opus 4.8 --- docs/user/environment-variables.md | 14 +---- lib/devbase/cli.py | 7 --- lib/devbase/commands/container.py | 78 +++------------------------ lib/devbase/editor/opener.py | 50 ----------------- lib/devbase/env/keys.py | 1 - tests/cli/test_project_dispatch.py | 87 +++--------------------------- tests/editor/test_opener.py | 29 ---------- 7 files changed, 13 insertions(+), 253 deletions(-) diff --git a/docs/user/environment-variables.md b/docs/user/environment-variables.md index 9ba8a6a..9c346c3 100644 --- a/docs/user/environment-variables.md +++ b/docs/user/environment-variables.md @@ -151,20 +151,8 @@ devbase はホストマシンの認証情報を自動収集し、コンテナ内 | `DEVBASE_OPEN_INDEX` | scale 時に開く dev インスタンス番号(既定: `1`) | | `DEVBASE_EDITOR_SSH_HOST` | Remote-SSH 跨ホスト構成での ssh-remote ホスト名(例 `mac2`)。**通常は `~/.vscode-server` から自動検出**され不要。検出が外れる場合のみ明示。下記「跨ホスト」参照 | | `DEVBASE_EDITOR_DOCKER_CONTEXT` | 跨ホスト時に ssh 先で使う docker context(既定: ホストの `docker context show`) | -| `DEVBASE_OPEN_TERMINAL` | 真で `up` 後に folderOpen ターミナル用 `.vscode/tasks.json` を配置(**既定: ON**) | -都度の上書きは CLI フラグで行います: `devbase up --open` / `--no-open` / `--open-index N` / `--open-terminal` / `--no-open-terminal`(env より優先)。 - -### 起動時に統合ターミナルを自動表示(`DEVBASE_OPEN_TERMINAL`) - -`up` 時に、開く dev コンテナのワークスペース(`/work/$GIT_REPO`)へ folderOpen タスク(`.vscode/tasks.json`)を `docker exec` で配置します(既存があれば変更しません)。VS Code はフォルダを開いた時にこのタスクで統合ターミナルを前面表示します。 - -VS Code 公式には「起動時にターミナルを開く」専用設定が無く、folderOpen タスクが唯一の方法です。なお自動実行には次の 2 つの **VS Code クライアント側ユーザー設定**が関わり、devbase からは制御できません(いずれも application/user スコープ専用): - -- **Workspace Trust**: 信頼していないフォルダではタスクは自動実行されません(初回は「フォルダを信頼」が必要)。 -- **`task.allowAutomaticTasks`**: 既定 `off` ではフォルダごとに 1 回「自動タスクを許可」を尋ねます。`on` にするとプロンプト無しで実行されます。 - -→ 実際は「初回のみ信頼(+許可)クリック、以降は自動でターミナルが開く」挙動になります。無効化は `DEVBASE_OPEN_TERMINAL=0` または `devbase up --no-open-terminal`。 +都度の上書きは CLI フラグで行います: `devbase up --open` / `--no-open` / `--open-index N`(env より優先)。 ### 実行コンテキスト別の挙動 diff --git a/lib/devbase/cli.py b/lib/devbase/cli.py index 31c9702..5248bdf 100644 --- a/lib/devbase/cli.py +++ b/lib/devbase/cli.py @@ -112,13 +112,6 @@ def _add_open_args(parser): parser.add_argument('--open-index', dest='open_index', type=int, default=None, metavar='N', help='Container index to open (default: 1)') - parser.add_argument('--open-terminal', dest='open_terminal', action='store_true', - default=None, - help='Place .vscode/tasks.json so the integrated terminal ' - 'auto-opens on folder open (overrides DEVBASE_OPEN_TERMINAL)') - parser.add_argument('--no-open-terminal', dest='open_terminal', action='store_false', - help='Do not place the folderOpen terminal tasks.json ' - '(overrides DEVBASE_OPEN_TERMINAL)') return parser diff --git a/lib/devbase/commands/container.py b/lib/devbase/commands/container.py index c9bee9a..8d60606 100644 --- a/lib/devbase/commands/container.py +++ b/lib/devbase/commands/container.py @@ -327,8 +327,7 @@ def _dispatch_lifecycle(args) -> int: 'up': lambda: cmd_up(project_name=project_name, scale=getattr(args, 'scale', None), open_editor=getattr(args, 'open_editor', None), - open_index=getattr(args, 'open_index', None), - open_terminal=getattr(args, 'open_terminal', None)), + open_index=getattr(args, 'open_index', None)), 'down': lambda: cmd_down(), 'login': lambda: cmd_login(index=getattr(args, 'index', '1')), 'ps': lambda: cmd_ps(all_containers=getattr(args, 'all', False)), @@ -397,8 +396,8 @@ def _resolve_open_index(open_index: Optional[int], scale: int) -> int: """開く dev インスタンス番号を解決する (CLI 引数 → env ``DEVBASE_OPEN_INDEX`` → 既定 1)。 ``1..scale`` の範囲外 (0・負数・``scale`` 超過) は存在しないコンテナを指し原因不明な - 起動失敗を招くため、警告を出して 1 へフォールバックする。:func:`_maybe_place_terminal_task` - と :func:`_maybe_open_editor` で共有し env フォールバック・範囲チェックの重複を避ける。 + 起動失敗を招くため、警告を出して 1 へフォールバックする。:func:`_maybe_open_editor` + で env フォールバック・範囲チェックを共有する。 """ if open_index is None: raw = os.environ.get('DEVBASE_OPEN_INDEX') @@ -432,8 +431,7 @@ def _maybe_open_editor(project_name: str, open_flag: Optional[bool], 未指定なら ``.docker-compose.scale.yml`` が存在すればそれ、無ければ None。 ``container_name`` が渡されれば :func:`opener.open_editor` 内の - ``resolve_container_name`` (= ``docker compose ps``) をスキップして再利用する - (``_maybe_place_terminal_task`` が既に解決済みの名前を使い回し二重実行を避ける)。 + ``resolve_container_name`` (= ``docker compose ps``) をスキップして再利用する。 """ from devbase.editor import opener @@ -464,69 +462,9 @@ def _maybe_open_editor(project_name: str, open_flag: Optional[bool], logger.warning("エディタの自動オープンに失敗しましたがデプロイは成功しています: %s", e) -def _maybe_place_terminal_task(project_name: str, open_flag: Optional[bool], - open_index: Optional[int], scale: int, - compose_file=None) -> Optional[str]: - """`up` 後、開く dev コンテナの作業ディレクトリへ folderOpen ターミナル tasks.json を配置。 - - フォルダを開いた時に統合ターミナルを自動表示するための ``.vscode/tasks.json`` を、 - 対象 dev インスタンスのワークスペース (``/work/$GIT_REPO``) に置く。作業ディレクトリは - コンテナ内 (named volume) のためホストから直接書けず、起動済みコンテナへ ``docker exec`` - で書き込む。**既存の ``.vscode/tasks.json`` があれば一切触らない**。 - - 有効判定は ``open_flag`` (CLI ``--open-terminal``/``--no-open-terminal``) が優先、None なら - env ``DEVBASE_OPEN_TERMINAL`` (既定 ON)。配置失敗は warning に握り潰し ``up`` を倒さない。 - ``open_index`` は開くインスタンスに合わせる (範囲外は 1 へフォールバック)。 - - 解決した実コンテナ名を返す (無効時は None)。直後の :func:`_maybe_open_editor` へ渡して - ``resolve_container_name`` (= ``docker compose ps``) の二重実行を避けるため。 - """ - from devbase.editor import opener - - enabled = open_flag if open_flag is not None else opener.is_open_terminal_enabled() - if not enabled: - return None - - open_index = _resolve_open_index(open_index, scale) - - if compose_file is None and _SCALE_COMPOSE_FILE.exists(): - compose_file = _SCALE_COMPOSE_FILE - - dev_service_name = get_dev_service_name() - container = opener.resolve_container_name(dev_service_name, project_name, - open_index, compose_file=compose_file) - workdir = opener.resolve_workdir(os.environ, project_name) - content = opener.build_folder_open_tasks_json() - - # 既存があれば書かず、無ければ stdin から書き込む (冪等)。workdir は引数で渡し - # シェル内クォートを避ける ($1)。 - script = ( - 'set -e; d="$1/.vscode"; mkdir -p "$d"; ' - 'if [ -e "$d/tasks.json" ]; then echo keep; ' - 'else cat > "$d/tasks.json"; echo placed; fi' - ) - try: - proc = subprocess.run( - ["docker", "exec", "-i", container, "sh", "-c", script, "_", workdir], - input=content, text=True, capture_output=True, timeout=15, - ) - except Exception as e: # noqa: BLE001 - 配置失敗で up を倒さない - logger.warning("ターミナル用 tasks.json の配置に失敗しましたが続行します: %s", e) - return container # 名前解決は済んでいるのでエディタ側で再利用させる - if proc.returncode != 0: - logger.warning("ターミナル用 tasks.json の配置に失敗しましたが続行します: %s", - (proc.stderr or "").strip()) - return container - if (proc.stdout or "").strip() == "placed": - logger.info("[6/6] 統合ターミナル自動表示用 tasks.json を配置: %s/.vscode/tasks.json", - workdir) - return container - - def cmd_up(project_name: str = None, scale: int = None, open_editor: Optional[bool] = None, - open_index: Optional[int] = None, - open_terminal: Optional[bool] = None) -> int: + open_index: Optional[int] = None) -> int: """Deploy containers with specified scale""" if project_name is None: project_name = get_project_name() @@ -593,12 +531,8 @@ def cmd_up(project_name: str = None, scale: int = None, if deploy_script.exists() and deploy_script.is_file(): _run_deploy_script_for_instances(deploy_script, range(1, scale + 1)) - # エディタを開く前に tasks.json を置く (開いた瞬間に folderOpen が効くように)。 - # 解決済みコンテナ名を editor 側へ渡し docker compose ps の二重実行を避ける。 - dev_container = _maybe_place_terminal_task(project_name, open_terminal, open_index, - scale, compose_file=override_file) _maybe_open_editor(project_name, open_editor, open_index, scale, - compose_file=override_file, container_name=dev_container) + compose_file=override_file) logger.info("=== Deploy completed successfully ===") return 0 diff --git a/lib/devbase/editor/opener.py b/lib/devbase/editor/opener.py index 7992664..6a6374a 100644 --- a/lib/devbase/editor/opener.py +++ b/lib/devbase/editor/opener.py @@ -128,56 +128,6 @@ def is_open_enabled(environ=None) -> bool: return value.strip().lower() in _TRUTHY -def is_open_terminal_enabled(environ=None) -> bool: - """``DEVBASE_OPEN_TERMINAL`` env が真か (**未設定は True = 既定 ON**)。 - - ``DEVBASE_OPEN_EDITOR`` (既定 OFF) と既定が逆である点に注意。up 時の tasks.json 配置は - 暴発リスクが低く、ユーザ要望で既定 ON とする (PLAN31_3)。 - """ - env = os.environ if environ is None else environ - value = env.get("DEVBASE_OPEN_TERMINAL") - if value is None: - return True - return value.strip().lower() in _TRUTHY - - -def build_folder_open_tasks_json() -> str: - """フォルダを開いた時に統合ターミナルを表示する folderOpen タスク (.vscode/tasks.json)。 - - VS Code 公式には「起動時にターミナルを開く」単独設定が無く (``hideOnStartup`` は復元 - された永続セッションを隠すか否かに過ぎず新規生成はしない)、``runOn: folderOpen`` の - タスクが新規ターミナルを出せる唯一の方法 (docs/terminal/*, docs/debugtest/tasks)。 - ``reveal: always`` でパネルを前面に出し対話シェルを起動する。``type: process`` で - ``/bin/sh -lc 'exec "${SHELL:-/bin/sh}"'`` を直接起動し、``$SHELL`` 未設定のコンテナでも - ``/bin/sh`` にフォールバックして必ずシェルが立ち上がるようにする (``type: shell`` + - ``${env:SHELL}`` だと未設定時に command が空になりタスクが即失敗する)。 - - .. note:: 自動実行には2つの user 設定ゲートがあり devbase からは制御できない: - Workspace Trust (信頼済みフォルダのみ自動実行) と ``task.allowAutomaticTasks`` - (既定 off = フォルダ毎に1回許可確認)。いずれも application/user スコープ専用。 - """ - tasks = { - "version": "2.0.0", - "tasks": [ - { - "label": "devbase: open terminal", - "type": "process", - "command": "/bin/sh", - "args": ["-lc", 'exec "${SHELL:-/bin/sh}"'], - "isBackground": True, - "problemMatcher": [], - "presentation": { - "reveal": "always", - "panel": "dedicated", - "focus": True, - }, - "runOptions": {"runOn": "folderOpen"}, - } - ], - } - return json.dumps(tasks, indent=2, ensure_ascii=False) + "\n" - - def resolve_editor_cmd(environ=None) -> Optional[list]: """起動に使うエディタコマンド (argv list) を解決する。 diff --git a/lib/devbase/env/keys.py b/lib/devbase/env/keys.py index 62f76b3..0a61cd1 100644 --- a/lib/devbase/env/keys.py +++ b/lib/devbase/env/keys.py @@ -61,4 +61,3 @@ def gcp_credentials_key(profile: str) -> str: # Remote-SSH 跨ホスト構成 (Windows VS Code → ssh → Mac のコンテナ) 用。 DEVBASE_EDITOR_SSH_HOST = "DEVBASE_EDITOR_SSH_HOST" # 任意。ssh-remote ホスト名 (例 mac2)。通常は ~/.vscode-server から自動検出 DEVBASE_EDITOR_DOCKER_CONTEXT = "DEVBASE_EDITOR_DOCKER_CONTEXT" # 任意。ssh 先 docker context (既定: docker context show) -DEVBASE_OPEN_TERMINAL = "DEVBASE_OPEN_TERMINAL" # 真偽。up 後に folderOpen ターミナル tasks.json を配置 (既定 ON) diff --git a/tests/cli/test_project_dispatch.py b/tests/cli/test_project_dispatch.py index 6b6ea4b..679e791 100644 --- a/tests/cli/test_project_dispatch.py +++ b/tests/cli/test_project_dispatch.py @@ -340,19 +340,17 @@ def test_up_parser_open_flags_tri_state(): def test_lifecycle_propagates_open_args_to_cmd_up(monkeypatch): - """up の open_editor / open_index / open_terminal が cmd_up まで伝播する。""" + """up の open_editor / open_index が cmd_up まで伝播する。""" from devbase.commands import container captured = {} monkeypatch.setattr( container, 'cmd_up', - lambda project_name=None, scale=None, open_editor=None, open_index=None, - open_terminal=None: captured.update( - open_editor=open_editor, open_index=open_index, - open_terminal=open_terminal) or 0) - args = _args(subcommand='up', scale=None, open_editor=True, open_index=2, - open_terminal=False) + lambda project_name=None, scale=None, open_editor=None, + open_index=None: captured.update( + open_editor=open_editor, open_index=open_index) or 0) + args = _args(subcommand='up', scale=None, open_editor=True, open_index=2) assert container._dispatch_lifecycle(args) == 0 - assert captured == {'open_editor': True, 'open_index': 2, 'open_terminal': False} + assert captured == {'open_editor': True, 'open_index': 2} def test_maybe_open_editor_disabled_by_default(monkeypatch): @@ -423,79 +421,6 @@ def test_maybe_open_editor_valid_index_within_scale(monkeypatch): assert called[0]['index'] == 2 -class _DockerProc: - """subprocess.run 互換スタブ (docker exec 用)。""" - def __init__(self, returncode=0, stdout="placed", stderr=""): - self.returncode = returncode - self.stdout = stdout - self.stderr = stderr - - -def test_maybe_place_terminal_task_disabled(monkeypatch): - """DEVBASE_OPEN_TERMINAL 無効時は docker exec を呼ばない。""" - from devbase.commands import container - from devbase.editor import opener - monkeypatch.setattr(opener, 'is_open_terminal_enabled', lambda environ=None: False) - calls = [] - monkeypatch.setattr(container.subprocess, 'run', - lambda *a, **k: calls.append(a) or _DockerProc()) - container._maybe_place_terminal_task('carmo', None, None, 1) - assert calls == [] - - -def test_maybe_place_terminal_task_flag_off_overrides_env(monkeypatch): - """open_flag=False なら env が ON でも置かない。""" - from devbase.commands import container - from devbase.editor import opener - monkeypatch.setattr(opener, 'is_open_terminal_enabled', lambda environ=None: True) - calls = [] - monkeypatch.setattr(container.subprocess, 'run', - lambda *a, **k: calls.append(a) or _DockerProc()) - container._maybe_place_terminal_task('carmo', False, None, 1) - assert calls == [] - - -def test_maybe_place_terminal_task_runs_docker_exec(monkeypatch): - """既定 ON で docker exec -i へ tasks.json を stdin 投入する。""" - from devbase.commands import container - from devbase.editor import opener - monkeypatch.setattr(opener, 'is_open_terminal_enabled', lambda environ=None: True) - monkeypatch.setattr(opener, 'resolve_container_name', lambda *a, **k: 'carmo-dev-1') - monkeypatch.setattr(opener, 'resolve_workdir', lambda *a, **k: '/work/carmo') - monkeypatch.setattr(container, 'get_dev_service_name', lambda: 'dev') - captured = {} - - def fake_run(cmd, **kw): - captured['cmd'] = cmd - captured['input'] = kw.get('input') - return _DockerProc(returncode=0, stdout="placed") - - monkeypatch.setattr(container.subprocess, 'run', fake_run) - result = container._maybe_place_terminal_task('carmo', None, 1, 1) - cmd = captured['cmd'] - assert cmd[:4] == ['docker', 'exec', '-i', 'carmo-dev-1'] - assert cmd[-1] == '/work/carmo' # workdir は $1 として末尾に渡す - assert '"runOn": "folderOpen"' in captured['input'] - # 解決済みコンテナ名を返し editor 側で再利用させる (docker compose ps 二重実行回避) - assert result == 'carmo-dev-1' - - -def test_maybe_place_terminal_task_failure_does_not_raise(monkeypatch): - """docker exec が例外でも up を倒さない (握り潰す)。""" - from devbase.commands import container - from devbase.editor import opener - monkeypatch.setattr(opener, 'is_open_terminal_enabled', lambda environ=None: True) - monkeypatch.setattr(opener, 'resolve_container_name', lambda *a, **k: 'carmo-dev-1') - monkeypatch.setattr(opener, 'resolve_workdir', lambda *a, **k: '/work/carmo') - monkeypatch.setattr(container, 'get_dev_service_name', lambda: 'dev') - - def boom(*a, **k): - raise OSError("docker missing") - - monkeypatch.setattr(container.subprocess, 'run', boom) - container._maybe_place_terminal_task('carmo', None, 1, 1) # 例外が出なければ OK - - def test_maybe_open_editor_forwards_compose_file(monkeypatch): """compose_file 引数が open_editor まで伝播する (実コンテナ名問い合わせ用)。""" from devbase.commands import container diff --git a/tests/editor/test_opener.py b/tests/editor/test_opener.py index 155a10c..354630e 100644 --- a/tests/editor/test_opener.py +++ b/tests/editor/test_opener.py @@ -290,35 +290,6 @@ def boom(cmd, **kw): assert opener.resolve_docker_context({}, runner=boom) is None -# --------------------------------------------------------------------------- -# is_open_terminal_enabled (既定 ON) -# --------------------------------------------------------------------------- - -@pytest.mark.parametrize("value,expected", [ - (None, True), ("", False), ("0", False), ("false", False), ("no", False), - ("1", True), ("true", True), ("on", True), ("YES", True), -]) -def test_is_open_terminal_enabled(value, expected): - env = {} if value is None else {"DEVBASE_OPEN_TERMINAL": value} - assert opener.is_open_terminal_enabled(env) is expected - - -# --------------------------------------------------------------------------- -# build_folder_open_tasks_json -# --------------------------------------------------------------------------- - -def test_build_folder_open_tasks_json_is_valid_folderopen_task(): - data = json.loads(opener.build_folder_open_tasks_json()) - assert data["version"] == "2.0.0" - task = data["tasks"][0] - assert task["runOptions"]["runOn"] == "folderOpen" - assert task["presentation"]["reveal"] == "always" - # SHELL 未設定でも /bin/sh にフォールバックして必ずシェルを起動する (空 command 回避) - assert task["type"] == "process" - assert task["command"] == "/bin/sh" - assert "SHELL:-/bin/sh" in " ".join(task["args"]) - - # --------------------------------------------------------------------------- # resolve_container_name / resolve_workdir # --------------------------------------------------------------------------- From 3e1b0f66060e4e09addfd1e8fc72990c90ce6cad Mon Sep 17 00:00:00 2001 From: "takemi.ohama" Date: Sun, 21 Jun 2026 05:25:38 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor(editor):=20tasks.json=20=E5=BB=83?= =?UTF-8?q?=E6=AD=A2=E3=81=A7=20dead=20code=20=E5=8C=96=E3=81=97=E3=81=9F?= =?UTF-8?q?=20container=5Fname=20=E5=BC=95=E6=95=B0=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _maybe_place_terminal_task 削除により container_name の唯一の供給元が消え、 _maybe_open_editor / open_editor の container_name 引数は常に None となる dead code になっていた。gemini レビュー指摘に従い以下を整理する。 - _maybe_open_editor: container_name 引数と docstring 説明・open_editor への伝播を削除 - open_editor: container_name 引数と docstring 説明を削除し container = resolve_container_name(...) に簡約 - test_open_editor_uses_given_container_name テストを削除 build_attach_uri / resolve_container_name / _query_container_name は別物のため不変更。 Co-Authored-By: Claude Opus 4.8 --- lib/devbase/commands/container.py | 6 +----- lib/devbase/editor/opener.py | 6 ++---- tests/editor/test_opener.py | 19 ------------------- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/lib/devbase/commands/container.py b/lib/devbase/commands/container.py index 8d60606..f3d7861 100644 --- a/lib/devbase/commands/container.py +++ b/lib/devbase/commands/container.py @@ -416,7 +416,7 @@ def _resolve_open_index(open_index: Optional[int], scale: int) -> int: def _maybe_open_editor(project_name: str, open_flag: Optional[bool], open_index: Optional[int], scale: int, - compose_file=None, container_name: Optional[str] = None) -> None: + compose_file=None) -> None: """`up` 完了後に dev コンテナへ接続したエディタを開く ([6/6])。 有効判定は ``open_flag`` (CLI ``--open``/``--no-open``) が優先、None なら env @@ -429,9 +429,6 @@ def _maybe_open_editor(project_name: str, open_flag: Optional[bool], ``compose_file`` は実コンテナ名問い合わせ用の override compose。``up`` 起動時と 同じファイルを渡さないと ``{dev}-{index}`` サービスが見えず実名取得に失敗する。 未指定なら ``.docker-compose.scale.yml`` が存在すればそれ、無ければ None。 - - ``container_name`` が渡されれば :func:`opener.open_editor` 内の - ``resolve_container_name`` (= ``docker compose ps``) をスキップして再利用する。 """ from devbase.editor import opener @@ -456,7 +453,6 @@ def _maybe_open_editor(project_name: str, open_flag: Optional[bool], workdir=workdir, index=open_index, compose_file=compose_file, - container_name=container_name, ) except Exception as e: # noqa: BLE001 - エディタ起動で up を倒さない logger.warning("エディタの自動オープンに失敗しましたがデプロイは成功しています: %s", e) diff --git a/lib/devbase/editor/opener.py b/lib/devbase/editor/opener.py index 6a6374a..5ad20bf 100644 --- a/lib/devbase/editor/opener.py +++ b/lib/devbase/editor/opener.py @@ -462,7 +462,7 @@ def _launch(cmd: list, env: dict) -> None: def open_editor(*, project_name: str, dev_service_name: str, workdir: str, - index: int = 1, compose_file=None, container_name: Optional[str] = None, + index: int = 1, compose_file=None, environ=None, isatty: Optional[bool] = None, system: Optional[str] = None, launcher: Optional[Callable[[list, dict], None]] = None) -> str: @@ -472,8 +472,6 @@ def open_editor(*, project_name: str, dev_service_name: str, workdir: str, 握り潰して warning にし、``up`` 本体を絶対に失敗させない。``isatty`` / ``system`` は :func:`detect_context` への差し替え口 (テスト用)。``compose_file`` は実コンテナ名問い合わせ時に起動と同じ override compose を ``-f`` で渡すため。 - ``container_name`` が渡されれば :func:`resolve_container_name` (= ``docker compose - ps``) をスキップしてそれを使う (呼び出し側で解決済みの名前を使い回す)。 """ env = os.environ if environ is None else environ ctx = detect_context(env, isatty=isatty, system=system) @@ -487,7 +485,7 @@ def open_editor(*, project_name: str, dev_service_name: str, workdir: str, logger.info("エディタの自動オープンをスキップ: %s", plan.reason) return "skip" - container = container_name or resolve_container_name( + container = resolve_container_name( dev_service_name, project_name, index, compose_file=compose_file) # SSH コンテキストでのみネスト authority (@ssh-remote+host) を組む。自動推測は # VS Code Remote-SSH 統合端末 (in_vscode) の時だけ有効にする — plain SSH (VS Code 外) diff --git a/tests/editor/test_opener.py b/tests/editor/test_opener.py index 354630e..7770b3a 100644 --- a/tests/editor/test_opener.py +++ b/tests/editor/test_opener.py @@ -508,25 +508,6 @@ def test_open_editor_flat_uri_when_ssh_host_unset(monkeypatch): assert "@ssh-remote" not in calls[0][2] -def test_open_editor_uses_given_container_name(monkeypatch): - """container_name を渡すと resolve_container_name を呼ばずそれを使う。""" - monkeypatch.setattr(opener.shutil, "which", lambda c: "/usr/bin/code") - - def boom(*a, **k): - raise AssertionError("resolve_container_name should not be called") - - monkeypatch.setattr(opener, "resolve_container_name", boom) - calls = [] - opener.open_editor( - project_name="carmo", dev_service_name="dev", workdir="/work/carmo", - container_name="preresolved-dev-1", environ={}, isatty=True, - launcher=lambda cmd, env: calls.append(cmd), - ) - uri = calls[0][2] - hexpart = uri.split("attached-container+")[1].split("/work")[0] - assert json.loads(bytes.fromhex(hexpart).decode())["containerName"] == "/preresolved-dev-1" - - def test_open_editor_skip_when_no_editor(monkeypatch): monkeypatch.setattr(opener.shutil, "which", lambda c: None) calls = []