Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/CI.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Run all tests with coverage reports.

```sh {"id":"01J5XTG2WKVR4WG7B2FNPF6VZT","name":"ci-coverage","promptEnv":"no"}
unset RUNME_SESSION_STRATEGY RUNME_TLS_DIR RUNME_SERVER_ADDR
export SHELL="/bin/bash"
export TZ="UTC"
export TAGS="docker_enabled"
make test/coverage
Expand All @@ -25,7 +24,6 @@ Run txtar-based CLI e2e tests without coverage reports (Go's warnings are gettin

```sh {"id":"01JAJYWF198MWQXJBADFJVJGXM","name":"ci-txtar"}
unset RUNME_SESSION_STRATEGY RUNME_TLS_DIR RUNME_SERVER_ADDR
export SHELL="/bin/bash"
export TZ="UTC"
export TAGS="test_with_txtar"
export RUN="^TestRunme\w*"
Expand Down
2 changes: 0 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
SHELL := /bin/bash

GO_ROOT := $(shell go env GOROOT)
GIT_SHA := $(shell git rev-parse HEAD)
GIT_SHA_SHORT := $(shell git rev-parse --short HEAD)
Expand Down
4 changes: 2 additions & 2 deletions command/command_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ print("important message")

// Rust is like Python. Envs are user-local and need to be sourced.
cargoEnvCfg := &ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Script{
Script: `source "$HOME/.cargo/env"`,
Script: `[ ! -e "$HOME/.cargo/env" ] || . "$HOME/.cargo/env"`,
},
Mode: runnerv2.CommandMode_COMMAND_MODE_INLINE,
}
Expand Down
2 changes: 1 addition & 1 deletion command/command_inline_shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestInlineShellCommand_CollectEnv(t *testing.T) {
Commands: &runnerv2.ProgramConfig_CommandList{
Items: []string{
"export TEST_ENV=1",
"sleep 5",
"/usr/bin/env sleep infinity",
},
},
},
Expand Down
42 changes: 23 additions & 19 deletions command/command_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ func TestCommand(t *testing.T) {
{
name: "ShellScript",
cfg: &ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Script{
Script: "#!/usr/local/bin/bash\n\nset -x -e -o pipefail\n\necho -n test\n",
Script: "#!/usr/bin/env sh\n\nset -x -e\n\necho -n test\n",
},
Mode: runnerv2.CommandMode_COMMAND_MODE_INLINE,
},
expectedStdout: "test",
expectedStderr: "+ echo -n test\n+ __cleanup\n+ rv=0\n+ env -0\n+ exit 0\n",
expectedStderr: "+ echo -n test\n+ __cleanup\n+ rv=0\n+ " + envDumpCommand + "\n+ exit 0\n",
},
{
name: "Input",
cfg: &ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Script{
Script: "read line; echo $line | tr a-z A-Z",
Script: "read line; echo $line | /usr/bin/env tr a-z A-Z",
},
Mode: runnerv2.CommandMode_COMMAND_MODE_INLINE,
},
Expand All @@ -79,9 +79,9 @@ func TestCommand(t *testing.T) {
{
name: "InputInteractive",
cfg: &ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Script{
Script: "read line; echo $line | tr a-z A-Z",
Script: "read line; echo $line | /usr/bin/env tr a-z A-Z",
},
Interactive: true,
Mode: runnerv2.CommandMode_COMMAND_MODE_INLINE,
Expand All @@ -92,11 +92,11 @@ func TestCommand(t *testing.T) {
{
name: "StdoutStderr",
cfg: &runnerv2.ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Commands{
Commands: &runnerv2.ProgramConfig_CommandList{
Items: []string{
"echo test | tee >(cat >&2)",
"echo test && echo test >&2",
},
},
},
Expand Down Expand Up @@ -152,13 +152,13 @@ func TestCommand_FromCodeBlocks(t *testing.T) {
},
{
name: "ShellScript",
source: "```shellscript\n#!/usr/local/bin/bash\n\nset -x -e -o pipefail\n\necho -n test\n```",
source: "```shellscript\n#!/usr/bin/env sh\n\nset -x -e\n\necho -n test\n```",
expectedStdout: "test",
expectedStderr: "+ echo -n test\n", // due to -x
},
{
name: "ShellScriptInteractive",
source: "```shellscript {\"interactive\": true}\n#!/usr/local/bin/bash\n\nset -x -e -o pipefail\n\necho -n test\n```",
source: "```shellscript {\"interactive\": true}\n#!/bin/sh -i\n\nset -x -e\n\necho -n test\n```",
expectedStdout: "+ echo -n test\r\ntest", // due to -x
},
{
Expand All @@ -182,13 +182,13 @@ func TestCommand_FromCodeBlocks(t *testing.T) {
},
{
name: "WithInput",
source: "```bash\nread line; echo $line | tr a-z A-Z\n```",
source: "```sh\nread line; echo $line | /usr/bin/env tr a-z A-Z\n```",
input: []byte("test\n"),
expectedStdout: "TEST\n",
},
{
name: "WithInputInteractive",
source: "```bash {\"interactive\": true}\nread line; echo $line | tr a-z A-Z\n```",
source: "```sh {\"interactive\": true}\nread line; echo $line | /usr/bin/env tr a-z A-Z\n```",
input: []byte("test\n"),
expectedStdout: "TEST\r\n",
},
Expand All @@ -205,8 +205,8 @@ func TestCommand_FromCodeBlocks(t *testing.T) {
},
{
name: "FrontmatterShell",
source: "---\nshell: bash\n---\n```sh\necho -n $0 | xargs basename\n```",
expectedStdout: "bash\n",
source: "---\nshell: sh\n---\n```sh\necho -n \"${0##*/}\"\n```",
expectedStdout: "sh",
},
{
name: "DefaultToCat",
Expand Down Expand Up @@ -334,10 +334,14 @@ func TestCommand_SetWinsize(t *testing.T) {

cmd, err := factory.Build(
&ProgramConfig{
ProgramName: "bash",
ProgramName: "sh",
Source: &runnerv2.ProgramConfig_Commands{
Commands: &runnerv2.ProgramConfig_CommandList{
Items: []string{"sleep 1", "tput cols -T linux", "tput lines -T linux"},
Items: []string{
"/usr/bin/env sleep 1",
"/usr/bin/env tput cols -T linux",
"/usr/bin/env tput lines -T linux",
},
},
},
Interactive: true,
Expand Down Expand Up @@ -458,7 +462,7 @@ func TestCommand_Session(t *testing.T) {

func TestCommand_SimulateCtrlC(t *testing.T) {
idResolver := identity.NewResolver(identity.AllLifecycleIdentity)
doc := document.New([]byte("```sh {\"interactive\": true}\nbash\n```"), idResolver)
doc := document.New([]byte("```sh {\"interactive\": true}\n/bin/sh -i\n```"), idResolver)
node, err := doc.Root()
require.NoError(t, err)
blocks := document.CollectCodeBlocks(node)
Expand All @@ -484,7 +488,7 @@ func TestCommand_SimulateCtrlC(t *testing.T) {
defer close(errc)

time.Sleep(time.Millisecond * 500)
_, err = stdinW.Write([]byte("sleep 30\n"))
_, err = stdinW.Write([]byte("sleep infinity\n"))
errc <- err

// cancel sleep
Expand Down
9 changes: 8 additions & 1 deletion command/env_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"io"
"os"
"os/exec"
"path/filepath"
"strings"

Expand Down Expand Up @@ -35,7 +36,13 @@ var envDumpCommand = func() string {
// TODO(adamb): this can be made obsolete. runme must be built
// in the test environment and put into the PATH.
func SetEnvDumpCommandForTesting() {
envDumpCommand = "env -0"
env, err := exec.LookPath("env")
if err != nil {
panic(err)
}

envDumpCommand = env + " -0"

// When overriding [envDumpCommand], we disable the encryption.
// There is no reliable way at the moment to have encryption and
// not control the dump command.
Expand Down
4 changes: 2 additions & 2 deletions command/env_collector_fifo_unix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func Test_envCollectorFifo(t *testing.T) {
buf := new(bytes.Buffer)
err := collector.SetOnShell(buf)
require.NoError(t, err)
expected := " env -0 > " + collector.prePath() + "\n" +
" __cleanup() {\nrv=$?\nenv -0 > " + collector.postPath() + "\nexit $rv\n}\n" +
expected := " " + envDumpCommand + " > " + collector.prePath() + "\n" +
" __cleanup() {\nrv=$?\n" + envDumpCommand + " > " + collector.postPath() + "\nexit $rv\n}\n" +
" trap -- \"__cleanup\" EXIT\n"
require.Equal(t, expected, buf.String())
})
Expand Down
4 changes: 2 additions & 2 deletions command/env_collector_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func Test_envCollectorFile(t *testing.T) {
buf := new(bytes.Buffer)
err := collector.SetOnShell(buf)
require.NoError(t, err)
expected := " env -0 > " + collector.prePath() + "\n" +
" __cleanup() {\nrv=$?\nenv -0 > " + collector.postPath() + "\nexit $rv\n}\n" +
expected := " " + envDumpCommand + " > " + collector.prePath() + "\n" +
" __cleanup() {\nrv=$?\n" + envDumpCommand + " > " + collector.postPath() + "\nexit $rv\n}\n" +
" trap -- \"__cleanup\" EXIT\n"
require.Equal(t, expected, buf.String())
})
Expand Down
8 changes: 4 additions & 4 deletions command/env_shell_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ func TestScriptEnvSetter(t *testing.T) {

expected := "#!/bin/sh\n" +
"set -euxo pipefail\n" +
"env -0 > /tmp/pre-path\n" +
"__cleanup() {\nrv=$?\nenv -0 > /tmp/post-path\nexit $rv\n}\n" +
envDumpCommand + " > /tmp/pre-path\n" +
"__cleanup() {\nrv=$?\n" + envDumpCommand + " > /tmp/post-path\nexit $rv\n}\n" +
"trap -- \"__cleanup\" EXIT\n" +
"set +euxo pipefail\n"
require.EqualValues(t, expected, buf.String())
Expand All @@ -40,8 +40,8 @@ func TestScriptEnvSetter(t *testing.T) {
require.NoError(t, err)

expected := "#!/bin/sh\n" +
"env -0 > /tmp/pre-path\n" +
"__cleanup() {\nrv=$?\nenv -0 > /tmp/post-path\nexit $rv\n}\n" +
envDumpCommand + " > /tmp/pre-path\n" +
"__cleanup() {\nrv=$?\n" + envDumpCommand + " > /tmp/post-path\nexit $rv\n}\n" +
"trap -- \"__cleanup\" EXIT\n"
require.EqualValues(t, expected, buf.String())
})
Expand Down
1 change: 0 additions & 1 deletion docker/runme-build-env.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ LABEL org.opencontainers.image.title="Runme build environment"
LABEL org.opencontainers.image.description="An image to build and test runme."

ENV HOME=/root
ENV SHELL=/bin/bash
Copy link
Contributor

@sourishkrout sourishkrout Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this Dagger builds will fail. This might very well be an issue in the underlying container image. However, it deserves its own PR to address this because without it downstream pipelines will fail to build.


RUN apt-get update && apt-get install -y \
"bash" \
Expand Down
2 changes: 1 addition & 1 deletion examples/goexec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func main() {
cmd := exec.Cmd{
Path: "/usr/local/bin/bash",
Path: "/bin/sh",
Args: []string{"-l", "-c", "python"},
Stdin: os.Stdin,
Stdout: os.Stdout,
Expand Down
9 changes: 7 additions & 2 deletions runner/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ import (
)

func init() {
dumpCmd = "env -0"
envPath, err := exec.LookPath("env")
if err != nil {
panic(err)
}

dumpCmd = envPath + " -0"
}

func Test_command(t *testing.T) {
Expand Down Expand Up @@ -246,7 +251,7 @@ func Test_command(t *testing.T) {
Stdout: io.Discard,
Stderr: io.Discard,
CommandMode: CommandModeInlineShell,
Script: `source "$HOME/.cargo/env"`,
Script: `[ ! -e "$HOME/.cargo/env" ] || . "$HOME/.cargo/env"`,
Logger: logger,
},
)
Expand Down
2 changes: 0 additions & 2 deletions testdata/flags/fmt.txtar
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
env SHELL=/bin/bash
exec runme fmt --write
cmp README-FORMATTED.md README.md
! stderr .

env SHELL=/bin/bash
exec runme fmt reset --write
cmp LCID-all.md LCID-none.md
! stderr .
Expand Down
1 change: 0 additions & 1 deletion testdata/prompts/basic.txtar
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
env SHELL=/bin/bash
exec runme run --all --category=foo --filename=PROMPTS.md
cmp stdout foo-bar-list.txt
! stderr .
Expand Down
2 changes: 0 additions & 2 deletions testdata/runall/basic.txtar
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
env SHELL=/bin/bash
exec runme run --all --filename=README.md
cmp stdout all.txt
! stderr .

env SHELL=/bin/bash
exec runme run foo-command
cmp stdout skip.txt
! stderr .
Expand Down
4 changes: 0 additions & 4 deletions testdata/script/basic.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,18 @@ cmp stdout golden-list-allow-unnamed.txt
stderr 'failed to open file-based project \".*\/nonexistent.md\": file does not exist'
! stdout .

env SHELL=/bin/bash
exec runme run echo
stdout 'Hello, runme!'
! stderr .

env SHELL=/bin/bash
exec runme run --filename README.md --index 0
stdout 'Hello, runme!'
! stderr .

env SHELL=/bin/bash
exec runme run --filename README.md echo-1
stdout '1\n2\n3\n'
! stderr .

env SHELL=/bin/bash
exec runme run --allow-unnamed tempdir
stdout 'hi!'
! stderr .
Expand Down
5 changes: 0 additions & 5 deletions testdata/tags/categories.txtar
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
env SHELL=/bin/bash
exec runme run --all --category=foo --filename=CATEGORIES.md
cmp stdout foo-bar-list.txt
stderr 'Flag --category has been deprecated, use --tag instead'

env SHELL=/bin/bash
exec runme run --all --category=bar --filename=CATEGORIES.md
cmp stdout bar-list.txt
stderr 'Flag --category has been deprecated, use --tag instead'

env SHELL=/bin/bash
exec runme run -c buzz -c bar --filename=CATEGORIES.md
cmp stdout buzz-bar-list.txt
stderr 'Flag --category has been deprecated, use --tag instead'

env SHELL=/bin/bash
exec runme run --all --allow-unnamed -y --category solution-2
cmp stdout doc-category-with-unnamed.txt
stderr 'Flag --category has been deprecated, use --tag instead'

env SHELL=/bin/bash
exec runme run --all --skip-prompts --category solution-2
cmp stdout doc-category.txt
stderr 'Flag --category has been deprecated, use --tag instead'
Expand Down
Loading
Loading