diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0c8b086..f83ec87 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,30 +7,79 @@ on: branches: [ main ] jobs: - build: - name: Build + test: + name: Test + strategy: + matrix: + go-version: [1.22.x, 1.23.x] + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go ${{ matrix.go-version }} + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + cache: true + + - name: Download dependencies + run: go mod download + + - name: Verify dependencies + run: go mod verify + + - name: Build + run: go build -v ./... + + - name: Run tests (with coverage) + if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23.x' + run: go test -race -v -coverprofile=./coverage.out ./... + + - name: Run tests (without coverage) + if: matrix.os != 'ubuntu-latest' || matrix.go-version != '1.23.x' + run: go test -race -v ./... + + - name: Upload coverage to Codecov + if: matrix.os == 'ubuntu-latest' && matrix.go-version == '1.23.x' + uses: codecov/codecov-action@v4 + with: + file: ./coverage.out + fail_ci_if_error: false + verbose: true + continue-on-error: true + + lint: + name: Lint runs-on: ubuntu-latest steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 with: - go-version: ^1.17 - id: go + go-version: 1.23.x + cache: true - - name: Set up linter - run: go get -u github.com/mgechev/revive + - name: Add Go bin to PATH + run: echo "$(go env GOPATH)/bin" >> $GITHUB_PATH - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Download dependencies + run: go mod download - - name: Get dependencies - run: go get -v -t -d ./... + - name: Install revive + run: go install github.com/mgechev/revive@latest - - name: Lint + - name: Lint with revive run: revive -config revive.toml -formatter stylish -exclude ./vendor/... ./... - - name: Vet + - name: Run go vet run: go vet ./... - - name: Test - run: go test -v ./... + - name: Install staticcheck + run: go install honnef.co/go/tools/cmd/staticcheck@latest + + - name: Run staticcheck + run: staticcheck ./... diff --git a/go.mod b/go.mod index ffd46dd..6288811 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module github.com/go-waitfor/waitfor-proc -go 1.17 +go 1.23 require ( github.com/go-waitfor/waitfor v1.0.0 github.com/mitchellh/go-ps v1.0.0 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.11.1 ) require ( github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/davecgh/go-spew v1.1.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index f0b125d..c453609 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,16 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-waitfor/waitfor v1.0.0 h1:KX6SpTtEM2OOwJu5QP6MXvdi0Llq55d8dywSSZD+gSI= github.com/go-waitfor/waitfor v1.0.0/go.mod h1:a5e6B1hss5InR3moU7xAOP2thPsbjbTArD5+Kud4YaQ= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/proc_test.go b/proc_test.go index d7732d1..4241c9c 100644 --- a/proc_test.go +++ b/proc_test.go @@ -2,9 +2,7 @@ package proc_test import ( "context" - "errors" "net/url" - "os/exec" "testing" "time" @@ -14,32 +12,6 @@ import ( "github.com/go-waitfor/waitfor-proc" ) -type TestCommand struct { - cmd *exec.Cmd -} - -func NewTestCommand() (*TestCommand, error) { - cmd := exec.Command("man", "cat") - - if err := cmd.Start(); err != nil { - return nil, err - } - - if cmd.Process == nil { - return nil, errors.New("failed to start the test process") - } - - return &TestCommand{cmd}, nil -} - -func (c *TestCommand) Name() string { - return "man" -} - -func (c *TestCommand) Kill() { - _ = c.cmd.Process.Kill() -} - func TestProcess_Use(t *testing.T) { cmd, err := NewTestCommand() diff --git a/testcmd_unix_test.go b/testcmd_unix_test.go new file mode 100644 index 0000000..117ac8e --- /dev/null +++ b/testcmd_unix_test.go @@ -0,0 +1,36 @@ +//go:build !windows + +package proc_test + +import ( + "errors" + "os/exec" +) + +type TestCommand struct { + cmd *exec.Cmd +} + +func NewTestCommand() (*TestCommand, error) { + // Use cross-platform compatible sleep command on Unix-like systems + cmd := exec.Command("sleep", "10") + + if err := cmd.Start(); err != nil { + return nil, err + } + + if cmd.Process == nil { + return nil, errors.New("failed to start the test process") + } + + return &TestCommand{cmd}, nil +} + +func (c *TestCommand) Name() string { + // On Unix-like systems, sleep appears as "sleep" in process list + return "sleep" +} + +func (c *TestCommand) Kill() { + _ = c.cmd.Process.Kill() +} \ No newline at end of file diff --git a/testcmd_windows_test.go b/testcmd_windows_test.go new file mode 100644 index 0000000..06c3a55 --- /dev/null +++ b/testcmd_windows_test.go @@ -0,0 +1,37 @@ +//go:build windows + +package proc_test + +import ( + "errors" + "os/exec" +) + +type TestCommand struct { + cmd *exec.Cmd +} + +func NewTestCommand() (*TestCommand, error) { + // Use timeout command on Windows as it's always available and waits for specified time + // timeout /t 10 waits for 10 seconds but doesn't accept input + cmd := exec.Command("timeout", "/t", "10", "/nobreak") + + if err := cmd.Start(); err != nil { + return nil, err + } + + if cmd.Process == nil { + return nil, errors.New("failed to start the test process") + } + + return &TestCommand{cmd}, nil +} + +func (c *TestCommand) Name() string { + // On Windows, timeout appears as "timeout.exe" in process list + return "timeout.exe" +} + +func (c *TestCommand) Kill() { + _ = c.cmd.Process.Kill() +} \ No newline at end of file