From 58920b750d7f3fb45a01a5a280e0cf9d020efc43 Mon Sep 17 00:00:00 2001 From: us Date: Mon, 24 Aug 2026 14:23:17 +0300 Subject: [PATCH] fix(cli): keep --entrypoint a single token, matching Docker `run`, `create` and `compose run` split the `--entrypoint` value on spaces and spliced the extra tokens ahead of the command argv. Docker does not do this: docker/cli wraps the flag value in a single-element slice (`entrypoint = []string{copts.entrypoint}`), so `--entrypoint "/bin/sh -c"` is one executable path there and fails to launch. The splitting made mocker accept input Docker rejects, and broke the legitimate case of an entrypoint path that contains a space. Pass the value through untouched; the Docker way of supplying entrypoint args (`--entrypoint /bin/sh image -c "..."`) already works. Compose service `entrypoint:` handling is unaffected: it is a real list and still resolves through `ComposeOrchestrator.resolveExec`. --- Sources/Mocker/Commands/Compose.swift | 12 ++---------- Sources/Mocker/Commands/Create.swift | 12 ++---------- Sources/Mocker/Commands/Run.swift | 12 ++---------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/Sources/Mocker/Commands/Compose.swift b/Sources/Mocker/Commands/Compose.swift index 33fd097..a1c9ab2 100644 --- a/Sources/Mocker/Commands/Compose.swift +++ b/Sources/Mocker/Commands/Compose.swift @@ -1054,21 +1054,13 @@ struct ComposeRun: AsyncParsableCommand { environment[String(parts[0])] = String(parts[1]) } - // Docker treats `--entrypoint` as shell form: it is split on spaces, the - // first token overrides the executable and any remaining tokens lead the - // command argv. Apple's `container` CLI only accepts a single token here. - let exec = ComposeOrchestrator.resolveExec( - entrypoint: entrypoint?.split(separator: " ").map(String.init) ?? [], - command: command - ) - let containerConfig = ContainerConfig( image: image, - command: exec.command, + command: command, environment: environment, detach: detach, workingDir: workdir, - entrypoint: exec.entrypoint + entrypoint: entrypoint ) let container = try await engine.run(containerConfig) diff --git a/Sources/Mocker/Commands/Create.swift b/Sources/Mocker/Commands/Create.swift index 7910dee..1fba695 100644 --- a/Sources/Mocker/Commands/Create.swift +++ b/Sources/Mocker/Commands/Create.swift @@ -348,18 +348,10 @@ struct Create: AsyncParsableCommand { let restartPolicy = RestartPolicy(rawValue: restart) ?? .no - // Docker treats `--entrypoint` as shell form: it is split on spaces, the - // first token overrides the executable and any remaining tokens lead the - // command argv. Apple's `container` CLI only accepts a single token here. - let exec = ComposeOrchestrator.resolveExec( - entrypoint: entrypoint?.split(separator: " ").map(String.init) ?? [], - command: command - ) - let containerConfig = ContainerConfig( name: name, image: image, - command: exec.command, + command: command, environment: environment, ports: ports, volumes: volumes, @@ -372,7 +364,7 @@ struct Create: AsyncParsableCommand { hostname: hostname, restartPolicy: restartPolicy, user: user, - entrypoint: exec.entrypoint, + entrypoint: entrypoint, platform: platform, virtualization: virtualization, kernel: kernel, diff --git a/Sources/Mocker/Commands/Run.swift b/Sources/Mocker/Commands/Run.swift index 98b6365..fa22c5c 100644 --- a/Sources/Mocker/Commands/Run.swift +++ b/Sources/Mocker/Commands/Run.swift @@ -396,18 +396,10 @@ struct Run: AsyncParsableCommand { let restartPolicy = RestartPolicy(rawValue: restart) ?? .no - // Docker treats `--entrypoint` as shell form: it is split on spaces, the - // first token overrides the executable and any remaining tokens lead the - // command argv. Apple's `container` CLI only accepts a single token here. - let exec = ComposeOrchestrator.resolveExec( - entrypoint: entrypoint?.split(separator: " ").map(String.init) ?? [], - command: command - ) - let containerConfig = ContainerConfig( name: name, image: image, - command: exec.command, + command: command, environment: environment, ports: ports, volumes: volumes, @@ -420,7 +412,7 @@ struct Run: AsyncParsableCommand { hostname: hostname, restartPolicy: restartPolicy, user: user, - entrypoint: exec.entrypoint, + entrypoint: entrypoint, platform: platform, virtualization: virtualization, kernel: kernel,