Skip to content

scriptrun: Add generic script-runner utility#1276

Merged
abhinav merged 5 commits into
mainfrom
scriptrun-runner
Jun 14, 2026
Merged

scriptrun: Add generic script-runner utility#1276
abhinav merged 5 commits into
mainfrom
scriptrun-runner

Conversation

@abhinav

@abhinav abhinav commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Introduces a small, single-responsibility package for executing
user-configured shell scripts and capturing their output.

Scripts may be either plain shell snippets (passed to 'sh -c') or
self-contained executables starting with a shebang line (written to
a temp file and executed directly).

stdout and stderr are captured independently and returned alongside
the exit code. The package does not interpret script output; that's
the caller's responsibility. This keeps scriptrun reusable across
different output protocols (commit messages, conflict resolutions,
etc).

A non-zero exit is reported in the RunResult rather than as an error,
so callers can distinguish 'script ran and disagreed' from 'script
could not be run at all.'

Part of #1243

This intentionally narrows PR #1188 to only the core scriptrun
functionality described in issue #1243: the generic script runner and
its focused runner tests. It excludes resolver.go, env.go, parser
errors, .spice storage, and script-resolve configuration.

[skip changelog]: internal package extracted from PR #1188.

ed-irl and others added 5 commits June 13, 2026 16:32
Introduces a small, single-responsibility package for executing
user-configured shell scripts and capturing their output.

Scripts may be either plain shell snippets (passed to 'sh -c') or
self-contained executables starting with a shebang line (written to
a temp file and executed directly).

stdout and stderr are captured independently and returned alongside
the exit code. The package does not interpret script output; that's
the caller's responsibility. This keeps scriptrun reusable across
different output protocols (commit messages, conflict resolutions,
etc).

A non-zero exit is reported in the RunResult rather than as an error,
so callers can distinguish 'script ran and disagreed' from 'script
could not be run at all.'

Part of #1243

This commit intentionally narrows PR #1188 to only the core scriptrun
functionality described in issue #1243: the generic script runner and
its focused runner tests. It excludes resolver.go, env.go, parser
errors, .spice storage, and script-resolve configuration.

[skip changelog]: internal package extracted from PR #1188.
`Runner.Run` expects callers to provide a `RunRequest`.
Treating a nil request as a runtime error made that programmer fault look like
a recoverable script execution problem.

Use the repository assertion helper for the nil request check,
and mark `RunRequest.Script` as required so required-field linting can enforce
the request contract at construction sites.
`Runner.Args` represents the arguments passed to the script,
not the invoking process argument vector.
Including an argv0 value in that API shifted the first useful argument out of
`$1` for direct execution paths,
and forced shebang handling to special-case the first element.

Pass a synthetic `$0` only when adapting through `sh -c`.
Directly executed scripts now receive `Runner.Args` unchanged,
so shell snippets and executable scripts expose the same positional
parameters to user-configured script code.
User-configured script values can be shell snippets,
shebang script bodies,
or paths to executable scripts.
The editor command path uses direct execution when the configured command
resolves to an executable,
then falls back to `sh -c` for shell command strings.

Mirror that split for script execution with the narrower scriptrun rule:
shebang bodies are still written to a temporary file,
regular file paths are executed directly,
and all other values are passed to `sh -c`.
This keeps file paths with shell-significant characters from being parsed as
shell source before the script gets a chance to run.
Shebang scripts are written to a temporary file before execution.
Setup failures while writing,
closing,
or chmodding that file all need the same cleanup behavior.

Use named returns and one deferred cleanup check after temp-file creation.
That keeps failure cleanup in one place while preserving the successful
cleanup callback returned to the caller for command completion.
@abhinav

abhinav commented Jun 13, 2026

Copy link
Copy Markdown
Owner Author

This change is part of the following stack:

Change managed by git-spice.

@abhinav abhinav enabled auto-merge (squash) June 13, 2026 23:54
@abhinav abhinav merged commit d9949df into main Jun 14, 2026
22 checks passed
@abhinav abhinav deleted the scriptrun-runner branch June 14, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants