|
| 1 | +# WSL Docker Wrapper Spec |
| 2 | + |
| 3 | +> 本规范记录 `psutils/modules/docker.psm1` 中 WSL Docker wrapper 的路径转换与测试契约。 |
| 4 | +
|
| 5 | +## Scenario: WSL Docker Path Conversion |
| 6 | + |
| 7 | +### 1. Scope / Trigger |
| 8 | + |
| 9 | +- Trigger: 修改 `ConvertTo-WslDockerPath`、`ConvertTo-WslDockerArgument`、`Invoke-WslDocker`、`Enable-WslDockerWrapper` 或 `psutils/tests/docker.Tests.ps1`。 |
| 10 | +- Scope: Windows PowerShell 会话把 `docker` 命令代理到 WSL 发行版内的 Docker Engine,期间只转换需要进入 WSL 的宿主机路径。 |
| 11 | +- Design intent: wrapper 必须支持 Windows 调用场景,同时 Pester 测试要能在 Windows、Linux、macOS CI 上稳定验证同一契约。 |
| 12 | + |
| 13 | +### 2. Signatures |
| 14 | + |
| 15 | +- `ConvertTo-WslDockerPath -Path <string> [-WslCommand <string>] [-Distro <string>]` |
| 16 | +- `ConvertTo-WslDockerVolumeSpec -VolumeSpec <string> [-WslCommand <string>] [-Distro <string>]` |
| 17 | +- `ConvertTo-WslDockerMountSpec -MountSpec <string> [-WslCommand <string>] [-Distro <string>]` |
| 18 | +- `ConvertTo-WslDockerArgument -Arguments <object[]> -Distro <string> [-WslCommand <string>]` |
| 19 | +- `Invoke-WslDocker -Distro <string> -Arguments <object[]> [-WslCommand <string>]` |
| 20 | + |
| 21 | +### 3. Contracts |
| 22 | + |
| 23 | +- Windows drive paths like `C:\data` and UNC paths must be converted through `wslpath -a`. |
| 24 | +- Existing relative paths must first resolve against the current PowerShell location. |
| 25 | +- If the resolved path is still POSIX style, return that absolute POSIX path directly instead of calling `wslpath`. |
| 26 | +- Non-existing relative values remain unchanged so service names, image names and container names are not treated as paths. |
| 27 | +- `-f`、`--file`、`--env-file`、`--project-directory` accept path values. |
| 28 | +- `-v`、`--volume` convert only the host source side. |
| 29 | +- `--mount` and `type=bind,...` convert only `src=` or `source=`. |
| 30 | +- `Invoke-WslDocker` passes the converted current location through `wsl.exe -d <distro> --cd <path> -- docker ...`; if conversion leaves a Windows drive path, fallback working directory is `~`. |
| 31 | + |
| 32 | +### 4. Validation & Error Matrix |
| 33 | + |
| 34 | +| Condition | Expected Behavior | |
| 35 | +|-----------|-------------------| |
| 36 | +| `Path` is null, empty or whitespace | Return original value | |
| 37 | +| Existing relative path on Windows | Resolve to absolute Windows path, then call `wslpath -a` | |
| 38 | +| Existing relative path on Linux/macOS CI | Resolve to absolute POSIX path and return it directly | |
| 39 | +| POSIX absolute path | Return original POSIX path | |
| 40 | +| Non-existing relative token | Return original token | |
| 41 | +| `wslpath` throws or exits non-zero | Write verbose diagnostic and return original input | |
| 42 | +| Working directory stays Windows drive path | Use `~` for `--cd` | |
| 43 | + |
| 44 | +### 5. Good/Base/Bad Cases |
| 45 | + |
| 46 | +- Good: `docker compose -f .\docker-compose.yml --env-file=.env -v .\data:/data:ro` converts the three host paths on Windows and returns absolute POSIX paths unchanged on Linux/macOS CI. |
| 47 | +- Base: `docker compose restart api` keeps `api` unchanged even if a file with that name exists. |
| 48 | +- Bad: Treating every slash-prefixed path as Windows input creates invalid values like `/mnt//tmp/...` in non-Windows CI. |
| 49 | + |
| 50 | +### 6. Tests Required |
| 51 | + |
| 52 | +- `psutils/tests/docker.Tests.ps1` must cover wrapper enablement, raw `docker run`, compose file/env/volume/mount conversion, env path forwarding, and non-path positional arguments. |
| 53 | +- Path conversion tests must derive expected current working directory through `ConvertTo-WslDockerPath` instead of hard-coding one OS-specific path. |
| 54 | +- Test doubles for `wsl.exe` must model Windows drive paths and POSIX paths separately. |
| 55 | + |
| 56 | +### 7. Wrong vs Correct |
| 57 | + |
| 58 | +#### Wrong |
| 59 | + |
| 60 | +```powershell |
| 61 | +# 在 Linux/macOS CI 中会把 /tmp/demo 错转成 /mnt//mp/demo |
| 62 | +& wsl.exe -d Ubuntu-24.04 -- wslpath -a '/tmp/demo' |
| 63 | +``` |
| 64 | + |
| 65 | +问题:POSIX 路径不是 Windows 宿主机路径,不能交给按盘符模拟的 `wslpath` 测试替身。 |
| 66 | + |
| 67 | +#### Correct |
| 68 | + |
| 69 | +```powershell |
| 70 | +$resolvedPath = Resolve-Path -LiteralPath '.\data' |
| 71 | +if ($resolvedPath.Path -match '^[A-Za-z]:[\\/]' -or $resolvedPath.Path -match '^\\\\') { |
| 72 | + & wsl.exe -d Ubuntu-24.04 -- wslpath -a $resolvedPath.Path |
| 73 | +} |
| 74 | +else { |
| 75 | + $resolvedPath.Path |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +理由:只转换 Windows 宿主机路径,跨平台 CI 里的 POSIX 路径保持原生形态。 |
0 commit comments