From c4df77bbc2daeeb46f0dd090da1b67df57bef29d Mon Sep 17 00:00:00 2001 From: PerishCode Date: Tue, 9 Jun 2026 15:49:22 +0800 Subject: [PATCH] test: harden estate seal smoke --- README.md | 7 ++++--- app/src/core/internal_help.rs | 6 ++++-- app/tests/fixtures/estate/ssh.seal | 7 +++++++ app/tests/internal_wrappers.rs | 16 ++++++++++++++++ app/tests/operator/estate.rs | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8fb235f..f0f7a26 100644 --- a/README.md +++ b/README.md @@ -245,9 +245,10 @@ The child working directory is not changed. A resolved wrapper receives: - `RUNSEAL_WRAPPER_FILE` Seal wrappers use the `.seal` suffix and are interpreted directly by runseal. -On Unix, shell wrappers use the `.sh` suffix and must be executable. On Windows, -runseal also checks `.exe`, `.cmd`, and `.bat` when the wrapper name has no -extension. +On Unix, shell wrappers use the `.sh` suffix and must be executable. +Extensionless files in `.runseal/wrappers` are not wrapper entrypoints; migrate +legacy wrappers to `.seal` or `.sh`. On Windows, runseal also +checks `.exe`, `.cmd`, and `.bat` when the wrapper name has no extension. ### Seal wrappers diff --git a/app/src/core/internal_help.rs b/app/src/core/internal_help.rs index 7de23ae..3154772 100644 --- a/app/src/core/internal_help.rs +++ b/app/src/core/internal_help.rs @@ -123,8 +123,10 @@ Lookup order: Profile-local wrappers shadow home wrappers with the same name. On Unix, wrapper shell files use the .sh suffix and must be executable. Seal wrappers use the -.seal suffix and are interpreted directly by runseal. On Windows, runseal also -checks .exe, .cmd, and .bat when the wrapper name has no extension. +.seal suffix and are interpreted directly by runseal. Extensionless files in a +wrappers directory are not wrapper entrypoints; migrate legacy wrappers to +.seal or .sh. On Windows, runseal also checks .exe, .cmd, and .bat +when the wrapper name has no extension. .seal wrappers are bash-runnable wrapper glue. They are intended for cross-platform repository operations where bash and PowerShell share a clear diff --git a/app/tests/fixtures/estate/ssh.seal b/app/tests/fixtures/estate/ssh.seal index 84248c5..c9c6ca4 100644 --- a/app/tests/fixtures/estate/ssh.seal +++ b/app/tests/fixtures/estate/ssh.seal @@ -24,6 +24,13 @@ if [ -z "$1" ]; then exit 0 fi +case "$1" in + -h|--help|help) + usage + exit 0 + ;; +esac + host=$1 shift diff --git a/app/tests/internal_wrappers.rs b/app/tests/internal_wrappers.rs index d23c274..18cb9c0 100644 --- a/app/tests/internal_wrappers.rs +++ b/app/tests/internal_wrappers.rs @@ -152,6 +152,22 @@ fn seal_wrapper_resolves() { assert!(stdout.contains("seal-tool.seal")); } +#[test] +#[cfg(unix)] +fn extensionless_is_ignored() { + let fx = fixture(); + make_wrapper(&fx.project_wrappers.join("legacy"), "legacy"); + + let output = run_in(&fx, &[":legacy"]); + + assert!(!output.status.success()); + let stderr = String::from_utf8(output.stderr).expect("stderr should be UTF-8"); + assert!(stderr.contains("wrapper not found: :legacy")); + assert!(stderr.contains("legacy.seal")); + assert!(stderr.contains("legacy.sh")); + assert!(!stderr.contains(".runseal/wrappers/legacy\n")); +} + #[test] fn seal_wrapper_runs_directly() { let fx = fixture(); diff --git a/app/tests/operator/estate.rs b/app/tests/operator/estate.rs index e34785b..1721d99 100644 --- a/app/tests/operator/estate.rs +++ b/app/tests/operator/estate.rs @@ -259,6 +259,21 @@ fn ssh_remote_args() { assert!(String::from_utf8_lossy(&denied.stderr).contains("host is not declared")); } +#[test] +fn ssh_help() { + let fx = fixture(); + + let output = run_wrapper(&fx, "ssh", &["--help"]); + + assert!(output.status.success()); + assert_eq!( + String::from_utf8(output.stdout).expect("stdout should be UTF-8"), + "Usage: runseal :ssh [--run