feat: first release
build-and-release / release (push) Failing after 17m7s

This commit is contained in:
2026-06-22 16:51:18 +02:00
parent fe485dd86d
commit 2bf11dda91
29 changed files with 182 additions and 191 deletions
+44 -74
View File
@@ -7,7 +7,6 @@ import (
"bufio"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"log"
@@ -28,37 +27,51 @@ import (
const cmdTimeout = 60 * time.Second
// CommandRunner allows overriding the command execution function for testing.
// In tests, register a handler with SetMock; the runner translates the
// MockCommand into a /bin/sh script that reproduces the stdout/stderr/exit
// behavior — no helper process, no temp file.
var CommandRunner = func(ctx context.Context, name string, args ...string) *exec.Cmd {
mockMu.Lock()
handler, ok := mockCmds[name]
mockMu.Unlock()
if ok {
mockRes := handler(args)
tmpFile, err := os.CreateTemp("", "nadir-mock-*.json")
if err != nil {
log.Printf("oscmd mock: failed to create temp file: %v", err)
return exec.CommandContext(ctx, name, args...)
}
encoder := json.NewEncoder(tmpFile)
if err := encoder.Encode(mockRes); err != nil {
log.Printf("oscmd mock: failed to write json: %v", err)
tmpFile.Close()
return exec.CommandContext(ctx, name, args...)
}
tmpPath := tmpFile.Name()
tmpFile.Close()
cmd := exec.CommandContext(ctx, os.Args[0])
cmd.Env = append(os.Environ(),
"GO_WANT_HELPER_PROCESS=1",
"NADIR_MOCK_FILE="+tmpPath,
)
return cmd
if !ok {
return exec.CommandContext(ctx, name, args...)
}
return exec.CommandContext(ctx, "/bin/sh", "-c", mockScript(handler(args)))
}
return exec.CommandContext(ctx, name, args...)
// mockScript builds the shell script that emits a MockCommand's behavior.
// Uses printf so backslashes and percent signs in output pass through verbatim.
func mockScript(m MockCommand) string {
var b strings.Builder
if len(m.Lines) > 0 {
for _, line := range m.Lines {
b.WriteString("printf '%s\\n' ")
b.WriteString(shellQuote(line))
b.WriteByte('\n')
if m.DelayMs > 0 {
fmt.Fprintf(&b, "sleep %g\n", float64(m.DelayMs)/1000)
}
}
} else {
if m.Stdout != "" {
b.WriteString("printf '%s' ")
b.WriteString(shellQuote(m.Stdout))
b.WriteByte('\n')
}
if m.Stderr != "" {
b.WriteString("printf '%s' ")
b.WriteString(shellQuote(m.Stderr))
b.WriteString(" 1>&2\n")
}
}
fmt.Fprintf(&b, "exit %d\n", m.ExitCode)
return b.String()
}
// shellQuote returns s wrapped in single quotes, with embedded single quotes escaped.
func shellQuote(s string) string {
return "'" + strings.ReplaceAll(s, "'", `'\''`) + "'"
}
// Run executes name with args and returns trimmed stdout. On failure it wraps
@@ -283,11 +296,11 @@ func OK() *StatusOutput {
// MockCommand holds the behavior for a mocked command.
type MockCommand struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
Lines []string `json:"lines,omitempty"`
DelayMs int `json:"delay_ms,omitempty"`
Stdout string
Stderr string
ExitCode int
Lines []string
DelayMs int
}
var (
@@ -309,46 +322,3 @@ func ClearMocks() {
clear(mockCmds)
}
// RunHelperProcess executes the mock helper process logic if GO_WANT_HELPER_PROCESS is set.
// It returns true if it ran (and exits the process), false otherwise.
func RunHelperProcess() bool {
if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
return false
}
mockFile := os.Getenv("NADIR_MOCK_FILE")
if mockFile == "" {
os.Exit(1)
}
defer os.Remove(mockFile)
data, err := os.ReadFile(mockFile)
if err != nil {
fmt.Fprintf(os.Stderr, "mock helper: read failed: %v\n", err)
os.Exit(1)
}
var mock MockCommand
if err := json.Unmarshal(data, &mock); err != nil {
fmt.Fprintf(os.Stderr, "mock helper: unmarshal failed: %v\n", err)
os.Exit(1)
}
if len(mock.Lines) > 0 {
for _, line := range mock.Lines {
fmt.Fprintln(os.Stdout, line)
if mock.DelayMs > 0 {
time.Sleep(time.Duration(mock.DelayMs) * time.Millisecond)
}
}
} else {
if mock.Stdout != "" {
fmt.Fprint(os.Stdout, mock.Stdout)
}
if mock.Stderr != "" {
fmt.Fprint(os.Stderr, mock.Stderr)
}
}
os.Exit(mock.ExitCode)
return true
}
-8
View File
@@ -1,19 +1,11 @@
package oscmd
import (
"os"
"reflect"
"strings"
"testing"
)
func TestMain(m *testing.M) {
if RunHelperProcess() {
return
}
os.Exit(m.Run())
}
func TestRunTrimsStdout(t *testing.T) {
out, err := Run("echo", "hello")
if err != nil {