From 239fb4b40d1326a9d91b7208d4ce5c409860e723 Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 01:27:32 +0800 Subject: [PATCH 1/6] fix(apt): honor DryRun in Clean() to prevent silent destructive ops Previously, Clean() executed `apt autoclean` regardless of the DryRun option, silently defeating the safety mechanism users expect from dry-run mode. The YUM/Snap/Flatpak Clean implementations on main already honored DryRun; APT now matches that behavior. Add the early-return guard immediately after nil-opts defaulting (matching the pattern at yum/yum.go:467, snap/snap.go:295, flatpak/flatpak.go:300). Move context creation below the guard so the DryRun path doesn't allocate an unused context. Regression tests cover three contracts: - Clean(DryRun=true) makes zero underlying command calls - Clean(DryRun=false) does invoke `apt autoclean` (guards against the fix being implemented as a blanket no-op) - Clean(nil) preserves the existing nil-opts default behavior This is security-relevant: a user testing with `--dry-run` on shared or production hosts could trigger cache cleanup unexpectedly. Co-Authored-By: Claude Opus 4.7 --- manager/apt/apt.go | 13 ++++-- manager/apt/apt_clean_dryrun_test.go | 65 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 manager/apt/apt_clean_dryrun_test.go diff --git a/manager/apt/apt.go b/manager/apt/apt.go index 18a7071..2b90e05 100644 --- a/manager/apt/apt.go +++ b/manager/apt/apt.go @@ -378,9 +378,6 @@ func (a *PackageManager) UpgradeAll(opts *manager.Options) ([]manager.PackageInf // Clean cleans the local package cache used by the apt package manager. func (a *PackageManager) Clean(opts *manager.Options) error { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - defer cancel() - if opts == nil { opts = &manager.Options{ DryRun: false, @@ -388,6 +385,16 @@ func (a *PackageManager) Clean(opts *manager.Options) error { Verbose: false, } } + + // Handle dry run mode + if opts.DryRun { + log.Println("Dry run mode: would execute 'apt autoclean'") + return nil + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer cancel() + args := []string{"autoclean"} out, err := a.executeCommand(ctx, args, opts) if err != nil { diff --git a/manager/apt/apt_clean_dryrun_test.go b/manager/apt/apt_clean_dryrun_test.go new file mode 100644 index 0000000..7a41bac --- /dev/null +++ b/manager/apt/apt_clean_dryrun_test.go @@ -0,0 +1,65 @@ +package apt_test + +import ( + "testing" + + "github.com/bluet/syspkg/manager" + "github.com/bluet/syspkg/manager/apt" +) + +// TestCleanRespectsDryRun is the regression test for the security-relevant bug +// where Clean() executed `apt autoclean` even when opts.DryRun was true. +// Behavior contract: Clean(DryRun=true) MUST NOT execute any underlying command. +func TestCleanRespectsDryRun(t *testing.T) { + mockRunner := manager.NewMockCommandRunner() + pm := apt.NewPackageManagerWithCustomRunner(mockRunner) + + if err := pm.Clean(&manager.Options{DryRun: true}); err != nil { + t.Fatalf("Clean(DryRun=true) returned error: %v", err) + } + + if got := len(mockRunner.EnvCalls); got != 0 { + t.Errorf("Clean(DryRun=true) executed %d non-interactive command(s); expected 0. Calls: %v", + got, mockRunner.EnvCalls) + } + if got := len(mockRunner.InteractiveCalls); got != 0 { + t.Errorf("Clean(DryRun=true) executed %d interactive command(s); expected 0. Calls: %v", + got, mockRunner.InteractiveCalls) + } +} + +// TestCleanRunsWithoutDryRun guards against the Clean(DryRun) fix being +// implemented as a blanket no-op. Without DryRun, Clean MUST invoke +// `apt autoclean`. +func TestCleanRunsWithoutDryRun(t *testing.T) { + mockRunner := manager.NewMockCommandRunner() + mockRunner.AddCommand("apt", []string{"autoclean"}, []byte("Reading package lists...\n"), nil) + pm := apt.NewPackageManagerWithCustomRunner(mockRunner) + + if err := pm.Clean(&manager.Options{DryRun: false}); err != nil { + t.Fatalf("Clean(DryRun=false) returned error: %v", err) + } + + if _, ok := mockRunner.EnvCalls["apt autoclean"]; !ok { + t.Errorf("Clean(DryRun=false) didn't invoke 'apt autoclean'. Recorded calls: %v", + mockRunner.EnvCalls) + } +} + +// TestCleanRespectsDryRunWithNilOptsDefault verifies the nil-opts branch: +// when opts == nil, the code path defaults DryRun to false, so Clean +// SHOULD execute (proving the nil-opts default is preserved by the fix). +func TestCleanRunsWithNilOpts(t *testing.T) { + mockRunner := manager.NewMockCommandRunner() + mockRunner.AddCommand("apt", []string{"autoclean"}, []byte("Reading package lists...\n"), nil) + pm := apt.NewPackageManagerWithCustomRunner(mockRunner) + + if err := pm.Clean(nil); err != nil { + t.Fatalf("Clean(nil) returned error: %v", err) + } + + if _, ok := mockRunner.EnvCalls["apt autoclean"]; !ok { + t.Errorf("Clean(nil) didn't invoke 'apt autoclean'. Recorded calls: %v", + mockRunner.EnvCalls) + } +} From 16a87d4cdbeebbd85f21f3768e436805d50a1c7b Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 01:32:28 +0800 Subject: [PATCH 2/6] ci(docker): make test failures propagate + harden test-all service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The compose test entrypoints used `bash -c` with `&&` chains and trailing `|| true` on fixture-generation steps. Due to bash operator precedence, the trailing `|| true` caught failures from earlier in the chain — including `go test` itself — letting failed tests pass CI silently while only the (allowed-to-fail) fixture-generation step appeared to succeed. Switch to `bash -ec` with explicit `;` separators for required steps: - Required commands (go test, apt update) abort the script on non-zero exit (set -e via -e flag) - Fixture-generation lines retain `|| true` so they remain individually allowed to fail - Statements use `;` instead of `&&` so set -e can actually trigger on intermediate failures (set -e doesn't apply to commands inside `&&` lists except the final command) Applied to ubuntu-apt-test, rockylinux-yum-test, almalinux-yum-test. Defense-in-depth on the test-all aggregator service: - read_only: true (it only runs an echo, no writes needed) - security_opt: [no-new-privileges:true] The required services (apt/yum tests) need write access for fixture generation and don't get these constraints. Co-Authored-By: Claude Opus 4.7 --- testing/docker/docker-compose.test.yml | 49 +++++++++++++++++--------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/testing/docker/docker-compose.test.yml b/testing/docker/docker-compose.test.yml index d1955bd..dc82c2e 100644 --- a/testing/docker/docker-compose.test.yml +++ b/testing/docker/docker-compose.test.yml @@ -18,13 +18,19 @@ services: volumes: - ../..:/workspace working_dir: /workspace + # NOTE: bash -ec ensures any failed required command (test, apt update) + # exits immediately. The `|| true` on fixture-generation lines is the + # explicit opt-out — those steps are allowed to fail without failing the + # build. Previously this used `&&` chaining which silently masked test + # failures because trailing `|| true` caught failures from earlier in the + # chain. command: > - bash -c " - echo 'Running Ubuntu APT tests...' && - go test -v -tags='unit integration apt' ./manager/apt ./osinfo && - echo 'Generating APT fixtures...' && - apt update && - apt search vim > testing/fixtures/apt/search-vim-ubuntu22.txt 2>/dev/null || true && + bash -ec " + echo 'Running Ubuntu APT tests...'; + go test -v -tags='unit integration apt' ./manager/apt ./osinfo; + echo 'Generating APT fixtures...'; + apt update; + apt search vim > testing/fixtures/apt/search-vim-ubuntu22.txt 2>/dev/null || true; apt show vim > testing/fixtures/apt/show-vim-ubuntu22.txt 2>/dev/null || true " @@ -42,13 +48,14 @@ services: volumes: - ../..:/workspace working_dir: /workspace + # See ubuntu-apt-test for rationale on bash -ec + ; separators. command: > - bash -c " - echo 'Running Rocky Linux YUM tests...' && - go test -v -tags='unit integration yum' ./manager/yum ./osinfo && - echo 'Generating YUM fixtures...' && - yum search vim > testing/fixtures/yum/search-vim-rocky8.txt 2>/dev/null || true && - yum info vim-enhanced > testing/fixtures/yum/info-vim-rocky8.txt 2>/dev/null || true && + bash -ec " + echo 'Running Rocky Linux YUM tests...'; + go test -v -tags='unit integration yum' ./manager/yum ./osinfo; + echo 'Generating YUM fixtures...'; + yum search vim > testing/fixtures/yum/search-vim-rocky8.txt 2>/dev/null || true; + yum info vim-enhanced > testing/fixtures/yum/info-vim-rocky8.txt 2>/dev/null || true; yum list --installed > testing/fixtures/yum/list-installed-rocky8.txt 2>/dev/null || true " @@ -66,12 +73,13 @@ services: volumes: - ../..:/workspace working_dir: /workspace + # See ubuntu-apt-test for rationale on bash -ec + ; separators. command: > - bash -c " - echo 'Running AlmaLinux YUM tests...' && - go test -v -tags='unit integration yum' ./manager/yum ./osinfo && - echo 'Generating YUM fixtures...' && - yum search vim > testing/fixtures/yum/search-vim-alma8.txt 2>/dev/null || true && + bash -ec " + echo 'Running AlmaLinux YUM tests...'; + go test -v -tags='unit integration yum' ./manager/yum ./osinfo; + echo 'Generating YUM fixtures...'; + yum search vim > testing/fixtures/yum/search-vim-alma8.txt 2>/dev/null || true; yum info vim-enhanced > testing/fixtures/yum/info-vim-alma8.txt 2>/dev/null || true " @@ -131,6 +139,13 @@ services: - almalinux-yum-test # - fedora-dnf-test # TODO: Enable when DNF support is implemented # - alpine-apk-test # TODO: Enable when APK support is implemented + # Defense-in-depth: this aggregator service only runs an echo, so it can + # safely use a read-only root and no-new-privileges. Required services + # (ubuntu/rocky/alma) need write access for fixture generation, so they + # don't get these constraints. + read_only: true + security_opt: + - no-new-privileges:true volumes: - ../..:/workspace working_dir: /workspace From 3dd42ce925b106d248e3546ad6d5ff2078f3d68a Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 01:33:08 +0800 Subject: [PATCH 3/6] docs(changelog): add v0.1.7 entry Document the APT Clean DryRun safety fix, the docker-compose exit code propagation fix, the test-all defense-in-depth hardening, the PackageInfo JSON tags change (#40), and the go.mod toolchain version fix (#40). Also picks up pre-commit-mandated cleanup of pre-existing trailing whitespace and missing trailing newline. Co-Authored-By: Claude Opus 4.7 --- CHANGELOG.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3e29ef..ab096f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.1.7] - 2026-05-10 + +### Security +- **APT `Clean()` now respects `DryRun`**. Previously, `apt autoclean` executed regardless of the `DryRun` option, silently defeating the safety mechanism users expect from dry-run mode. The YUM/Snap/Flatpak Clean implementations already honored DryRun; APT now matches that behavior. Regression tests added in `manager/apt/apt_clean_dryrun_test.go`. +- **Docker test runners no longer mask test failures**. The compose entrypoints used `bash -c` with `&&` chains and trailing `|| true` on fixture-generation steps; due to bash operator precedence, the `|| true` caught failures from earlier in the chain (including `go test`), letting failed tests pass CI silently. Switched to `bash -ec` with explicit `;` separators so test failures abort immediately while fixture-generation steps remain individually allowed to fail. +- Added `read_only: true` and `no-new-privileges:true` to the `test-all` aggregator service for defense-in-depth. + +### Changed +- **`PackageInfo` JSON output now uses snake_case field names** (e.g. `package_manager`, `new_version`, `additional_data`) instead of Go's default PascalCase. Required fields (`name`, `status`, `package_manager`) are always emitted; optional fields use `omitempty`. Consumers parsing JSON output must update field names. (#40, thanks @aijanai) + +### Fixed +- `go.mod` now declares `go 1.23.0` (full version) instead of `go 1.23`, resolving Go toolchain download failures in some environments. (#40) + ## [0.1.6] - 2025-11-01 ### Added @@ -37,14 +50,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Technical debt cleanup and APT Upgrade method fix - APT Upgrade method now correctly uses `apt install` for specific packages -## Recent Achievements ✅ +## Recent Achievements ✅ ### Architecture & Code Quality - ✅ **CommandRunner Architecture**: Complete architectural consistency (Issue #20, PR #26) - ✅ **APT & YUM executeCommand Pattern**: Centralized command execution, eliminated code duplication - ✅ **Technical Debt Cleanup**: Fixed APT Upgrade method bug, removed misleading TODOs, verified no resource leaks -### Security Enhancements +### Security Enhancements - ✅ **Security Enhancements**: Input validation for package names (Issue #23, PR #25) - ✅ **Command Injection Prevention**: Comprehensive ValidatePackageName implementation across all package managers @@ -77,7 +90,7 @@ Current development focus areas (see [GitHub Issues](https://github.com/bluet/sy - **Security scanning with Snyk** - Add to CI/CD pipeline - **CommandRunner migration** - Complete Snap and Flatpak integration (Issues #28, #29) -### Medium Priority Pending +### Medium Priority Pending - **Test coverage improvements** - YUM gaps (Issue #32), Snap & Flatpak comprehensive suites - **CLI improvements** - Upgrade display (Issue #3), macOS apt conflict (Issue #2) - **Code quality** - Context support, custom error types, DRY principle improvements @@ -90,7 +103,7 @@ Current development focus areas (see [GitHub Issues](https://github.com/bluet/sy ### Currently Supported ✅ - **APT** (Ubuntu/Debian) - Full feature support -- **YUM** (Rocky Linux/AlmaLinux/RHEL) - Full feature support +- **YUM** (Rocky Linux/AlmaLinux/RHEL) - Full feature support - **Snap** (Universal packages) - Full feature support - **Flatpak** (Universal packages) - Full feature support @@ -101,4 +114,4 @@ Current development focus areas (see [GitHub Issues](https://github.com/bluet/sy ### Planned 📋 - **Homebrew** (macOS) - Planned for cross-platform expansion - **Chocolatey/Scoop/winget** (Windows) - Planned for Windows support -- **Zypper** (openSUSE) - Lower priority \ No newline at end of file +- **Zypper** (openSUSE) - Lower priority From 1e42e9754964a337aa495f810d7aa149ddb8cda3 Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 01:49:30 +0800 Subject: [PATCH 4/6] ci(docker): apply review feedback on test-all hardening Three small follow-ups to the test-all aggregator service from PR #67 review: - depends_on switched to long-form with `condition: service_completed_successfully` for each dependent service. The short form only waited for dependents to *start*, so test-all's `echo` could finish in milliseconds and abort the compose run (--abort-on-container-exit) before the real tests reported failure. Same class of CI-honesty bug the bash -ec change in this same release fixes one layer up. (gemini-code-assist HIGH) - /workspace bind mount made read-only (`:ro`). test-all only runs an echo, so the mount doesn't need write access. Defense-in-depth consistent with the existing read_only and security_opt. (CodeRabbit) - Quoted "no-new-privileges:true" to eliminate YAML-parser ambiguity around `key:value` parsing while preserving Docker's documented form. (gemini-code-assist SECURITY-MEDIUM) Verified via `docker compose config`: depends_on shows long-form with condition: service_completed_successfully; read_only: true on the bind mount; security_opt preserves the documented form. Co-Authored-By: Claude Opus 4.7 --- testing/docker/docker-compose.test.yml | 33 ++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/testing/docker/docker-compose.test.yml b/testing/docker/docker-compose.test.yml index dc82c2e..5c2ab02 100644 --- a/testing/docker/docker-compose.test.yml +++ b/testing/docker/docker-compose.test.yml @@ -133,21 +133,34 @@ services: # Test runner that runs all tests in parallel test-all: image: ubuntu:24.04 + # Long-form depends_on with service_completed_successfully so test-all + # waits for the actual tests to complete before running. With short-form, + # test-all's `echo` could finish in milliseconds and abort the compose + # run (--abort-on-container-exit) before the real tests had a chance to + # report failure — exactly the same class of CI-honesty bug the bash -ec + # change in this same release fixes one layer up. depends_on: - - ubuntu-apt-test - - rockylinux-yum-test - - almalinux-yum-test - # - fedora-dnf-test # TODO: Enable when DNF support is implemented - # - alpine-apk-test # TODO: Enable when APK support is implemented + ubuntu-apt-test: + condition: service_completed_successfully + rockylinux-yum-test: + condition: service_completed_successfully + almalinux-yum-test: + condition: service_completed_successfully + # fedora-dnf-test: # TODO: Enable when DNF support is implemented + # condition: service_completed_successfully + # alpine-apk-test: # TODO: Enable when APK support is implemented + # condition: service_completed_successfully # Defense-in-depth: this aggregator service only runs an echo, so it can - # safely use a read-only root and no-new-privileges. Required services - # (ubuntu/rocky/alma) need write access for fixture generation, so they - # don't get these constraints. + # safely use a read-only root, no-new-privileges, and a read-only bind + # mount. Required services (ubuntu/rocky/alma) need write access for + # fixture generation, so they don't get these constraints. read_only: true security_opt: - - no-new-privileges:true + # Quoted to avoid YAML parser ambiguity around `key:value` parsing + # while preserving Docker's documented `no-new-privileges:true` form. + - "no-new-privileges:true" volumes: - - ../..:/workspace + - ../..:/workspace:ro working_dir: /workspace command: > bash -c " From 55945810845929efcc08739f53380dd9fa04cef0 Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 01:58:05 +0800 Subject: [PATCH 5/6] ci(docker): switch to --abort-on-container-failure to stop killing slow tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `--abort-on-container-exit` aborts the compose run when ANY container exits — success or failure. With multi-service runs (`make test-docker`, `make test-docker-all`), the FASTEST test container's success would kill the slower siblings mid-test, masking failures and skipping most of the matrix. Long-form depends_on on `test-all` from the prior commit only addressed the test-all → dependents race; the test containers race against each other was still there. Switch to `--abort-on-container-failure` (Docker Compose v2.12+) which aborts only when a container exits non-zero. Now multi-service runs wait for all test containers to finish, fail fast on actual failure, and surface real CI signal. Applied uniformly across test-docker, test-docker-{ubuntu,rocky,alma}, test-fixtures, and the commented-out future targets. Catch from chatgpt-codex-connector P1 review on PR #67. Co-Authored-By: Claude Opus 4.7 --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 4476ec6..3e9fbc6 100644 --- a/Makefile +++ b/Makefile @@ -88,29 +88,29 @@ install-tools: # Docker testing targets test-docker: @echo "Running tests in Docker containers..." - docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-exit --remove-orphans + docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure --remove-orphans test-docker-ubuntu: @echo "Running Ubuntu APT tests..." - docker-compose -f testing/docker/docker-compose.test.yml up ubuntu-apt-test --abort-on-container-exit + docker-compose -f testing/docker/docker-compose.test.yml up ubuntu-apt-test --abort-on-container-failure test-docker-rocky: @echo "Running Rocky Linux YUM tests..." - docker-compose -f testing/docker/docker-compose.test.yml up rockylinux-yum-test --abort-on-container-exit + docker-compose -f testing/docker/docker-compose.test.yml up rockylinux-yum-test --abort-on-container-failure test-docker-alma: @echo "Running AlmaLinux YUM tests..." - docker-compose -f testing/docker/docker-compose.test.yml up almalinux-yum-test --abort-on-container-exit + docker-compose -f testing/docker/docker-compose.test.yml up almalinux-yum-test --abort-on-container-failure # TODO: Enable when DNF support is implemented # test-docker-fedora: # @echo "Running Fedora DNF tests..." -# docker-compose -f testing/docker/docker-compose.test.yml up fedora-dnf-test --abort-on-container-exit +# docker-compose -f testing/docker/docker-compose.test.yml up fedora-dnf-test --abort-on-container-failure # TODO: Enable when APK support is implemented # test-docker-alpine: # @echo "Running Alpine APK tests..." -# docker-compose -f testing/docker/docker-compose.test.yml up alpine-apk-test --abort-on-container-exit +# docker-compose -f testing/docker/docker-compose.test.yml up alpine-apk-test --abort-on-container-failure test-docker-all: test-docker @@ -118,7 +118,7 @@ test-docker-all: test-docker test-fixtures: @echo "Generating test fixtures from multiple OS..." @mkdir -p testing/fixtures/{apt,yum,dnf,apk} - docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-exit + docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure @echo "Test fixtures generated in testing/fixtures/" # Clean up Docker resources From 0b84517f4732a8403132213c3e998885a3272bb1 Mon Sep 17 00:00:00 2001 From: "Matthew (BlueT) Lien" Date: Sun, 10 May 2026 02:18:01 +0800 Subject: [PATCH 6/6] ci(docker): use Compose v2 syntax (`docker compose`) for new flag Docker Compose v1 (`docker-compose`, the standalone Python binary) was EOL'd June 2023 and does not support `--abort-on-container-failure` introduced in the prior commit. With the Makefile invoking the legacy hyphenated form, environments still using v1 would have all the `make test-docker*` targets fail before any tests run. Switch all 8 invocations from `docker-compose ...` to `docker compose ...` (v2 plugin / standalone v2 binary). Filenames containing `docker-compose` (e.g. `docker-compose.test.yml`) are unchanged. Verified locally: `make test-docker-ubuntu` exits 0 with the v2 command. Catch from chatgpt-codex-connector P2 review on PR #67. Co-Authored-By: Claude Opus 4.7 --- Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 3e9fbc6..01eecfe 100644 --- a/Makefile +++ b/Makefile @@ -88,29 +88,29 @@ install-tools: # Docker testing targets test-docker: @echo "Running tests in Docker containers..." - docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure --remove-orphans + docker compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure --remove-orphans test-docker-ubuntu: @echo "Running Ubuntu APT tests..." - docker-compose -f testing/docker/docker-compose.test.yml up ubuntu-apt-test --abort-on-container-failure + docker compose -f testing/docker/docker-compose.test.yml up ubuntu-apt-test --abort-on-container-failure test-docker-rocky: @echo "Running Rocky Linux YUM tests..." - docker-compose -f testing/docker/docker-compose.test.yml up rockylinux-yum-test --abort-on-container-failure + docker compose -f testing/docker/docker-compose.test.yml up rockylinux-yum-test --abort-on-container-failure test-docker-alma: @echo "Running AlmaLinux YUM tests..." - docker-compose -f testing/docker/docker-compose.test.yml up almalinux-yum-test --abort-on-container-failure + docker compose -f testing/docker/docker-compose.test.yml up almalinux-yum-test --abort-on-container-failure # TODO: Enable when DNF support is implemented # test-docker-fedora: # @echo "Running Fedora DNF tests..." -# docker-compose -f testing/docker/docker-compose.test.yml up fedora-dnf-test --abort-on-container-failure +# docker compose -f testing/docker/docker-compose.test.yml up fedora-dnf-test --abort-on-container-failure # TODO: Enable when APK support is implemented # test-docker-alpine: # @echo "Running Alpine APK tests..." -# docker-compose -f testing/docker/docker-compose.test.yml up alpine-apk-test --abort-on-container-failure +# docker compose -f testing/docker/docker-compose.test.yml up alpine-apk-test --abort-on-container-failure test-docker-all: test-docker @@ -118,13 +118,13 @@ test-docker-all: test-docker test-fixtures: @echo "Generating test fixtures from multiple OS..." @mkdir -p testing/fixtures/{apt,yum,dnf,apk} - docker-compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure + docker compose -f testing/docker/docker-compose.test.yml up --abort-on-container-failure @echo "Test fixtures generated in testing/fixtures/" # Clean up Docker resources test-docker-clean: @echo "Cleaning up Docker test resources..." - docker-compose -f testing/docker/docker-compose.test.yml down --volumes --remove-orphans + docker compose -f testing/docker/docker-compose.test.yml down --volumes --remove-orphans docker system prune -f --filter "label=com.docker.compose.project=syspkg-test" # Unit tests only (no integration/system tests)