diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml index 7695e69d..9389e530 100644 --- a/.github/workflows/smoke-test.yml +++ b/.github/workflows/smoke-test.yml @@ -55,7 +55,7 @@ jobs: run: shopware-cli extension package plugin --disable-git --release - name: Validate Plugin - run: shopware-cli extension validate FroshTools.zip + run: shopware-cli extension validate FroshTools.zip --only sw-cli - name: Get Changelog run: shopware-cli extension get-changelog FroshTools.zip diff --git a/AGENTS.md b/AGENTS.md index 8831c9a0..faaf32cf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -116,4 +116,4 @@ The verifier registers tools through the name-only `Tool` interface. `CheckTool` - **Fixers**: Rector, ESLint, Stylelint, Symfony XML conversion - **Formatters**: PHP-CS-Fixer, Prettier -`extension validate` defaults to `sw-cli`; `--full` selects all checkers, and an explicit `--only` overrides that default. The extension commands report whether each tool was invoked or skipped; invocation does not guarantee that files were analyzed or changed. +`extension validate` runs all checkers by default. The deprecated `--full` flag remains accepted but has no effect; use `--only` or `--exclude` to select checkers. The extension commands report whether each tool was invoked or skipped; invocation does not guarantee that files were analyzed or changed. diff --git a/architecture.md b/architecture.md index 87b2350c..1de7f8af 100644 --- a/architecture.md +++ b/architecture.md @@ -34,7 +34,7 @@ A new command is just a new file: drop `cmd//.go` (`cmd/root. Each verifier tool registers a name and implements only the capabilities it supports: checking, fixing, formatting, or a combination. Commands select tools by capability, then apply `--only` and (where available) `--exclude`. An unsupported `--only` name is an error that lists the tools available to that command. -`extension validate` runs only the built-in `sw-cli` checker by default; `--full` selects all checkers, while an explicit `--only` takes precedence over `--full`. The format commands support `--dry-run`; the fix commands do not. +`extension validate` runs all checkers by default. The deprecated `--full` flag remains accepted but has no effect; use `--only` or `--exclude` to select checkers. The format commands support `--dry-run`; the fix commands do not. ```go type Tool interface { diff --git a/cmd/extension/extension_validate.go b/cmd/extension/extension_validate.go index e6821480..fe632565 100644 --- a/cmd/extension/extension_validate.go +++ b/cmd/extension/extension_validate.go @@ -23,7 +23,6 @@ var extensionValidateCmd = &cobra.Command{ Short: "Validate extension metadata, assets, and code quality", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - isFull, _ := cmd.Flags().GetBool("full") storeCompliance, _ := cmd.Flags().GetBool("store-compliance") reportingFormat, err := extensionValidationFormat(cmd) if err != nil { @@ -34,7 +33,7 @@ var extensionValidateCmd = &cobra.Command{ exclude, _ := cmd.Flags().GetString("exclude") noCopy, _ := cmd.Flags().GetBool("no-copy") - tools, statuses, err := selectExtensionValidationTools(isFull, only, exclude) + tools, statuses, err := selectExtensionValidationTools(only, exclude) if err != nil { return err } @@ -133,14 +132,10 @@ var extensionValidateCmd = &cobra.Command{ }, } -func selectExtensionValidationTools(full bool, only, exclude string) (verifier.ToolList[verifier.CheckTool], []validation.ToolInvocationStatus, error) { +func selectExtensionValidationTools(only, exclude string) (verifier.ToolList[verifier.CheckTool], []validation.ToolInvocationStatus, error) { validationTools := verifier.GetToolsOf[verifier.CheckTool]() - requested := only - if requested == "" && !full { - requested = "sw-cli" - } - requestedTools, err := validationTools.Only(requested) + requestedTools, err := validationTools.Only(only) if err != nil { return nil, nil, err } @@ -152,13 +147,7 @@ func selectExtensionValidationTools(full bool, only, exclude string) (verifier.T return nil, nil, errors.New("no validation checks selected after applying --exclude") } - statuses := extensionToolInvocationStatuses(validationTools, requestedTools, selected) - for i := range statuses { - if only == "" && statuses[i].Reason == "not selected by --only" { - statuses[i].Reason = "not selected; use --full or --only" - } - } - return selected, statuses, nil + return selected, extensionToolInvocationStatuses(validationTools, requestedTools, selected), nil } func requiresToolSetup(tool verifier.CheckTool) bool { @@ -185,15 +174,16 @@ func extensionValidationFormat(cmd *cobra.Command) (string, error) { func init() { extensionRootCmd.AddCommand(extensionValidateCmd) - extensionValidateCmd.PersistentFlags().Bool("full", false, "Run all validation checks by default (minus --exclude selections)") + extensionValidateCmd.PersistentFlags().Bool("full", false, "Run all validation checks") extensionValidateCmd.PersistentFlags().Bool("store-compliance", false, "Run the Extension Store compliance checks") extensionValidateCmd.PersistentFlags().String("format", "", "Reporting format (summary, json, github, gitlab, junit, markdown)") extensionValidateCmd.PersistentFlags().String("reporter", "", "Reporting format (summary, json, github, gitlab, junit, markdown)") extensionValidateCmd.PersistentFlags().String("check-against", "highest", "Check against Shopware Version (highest, lowest)") - extensionValidateCmd.PersistentFlags().String("only", "", "Run only these validation checks, regardless of --full (comma-separated, e.g. phpstan,eslint)") + extensionValidateCmd.PersistentFlags().String("only", "", "Run only these validation checks (comma-separated, e.g. phpstan,eslint)") extensionValidateCmd.PersistentFlags().String("exclude", "", "Exclude specific tools by name (comma-separated, e.g. phpstan,eslint)") extensionValidateCmd.PersistentFlags().Bool("no-copy", false, "Do not copy extension files to temporary directory") extensionValidateCmd.MarkFlagsMutuallyExclusive("format", "reporter") + _ = extensionValidateCmd.PersistentFlags().MarkDeprecated("full", "all validation checks now run by default; omit --full; to restore old behaviour use --only sw-cli") _ = extensionValidateCmd.PersistentFlags().MarkDeprecated("reporter", "use --format instead") _ = extensionValidateCmd.PersistentFlags().MarkHidden("reporter") extensionValidateCmd.PreRunE = func(cmd *cobra.Command, args []string) error { diff --git a/cmd/extension/extension_validate_selection_test.go b/cmd/extension/extension_validate_selection_test.go index 746dfd57..63e0e84d 100644 --- a/cmd/extension/extension_validate_selection_test.go +++ b/cmd/extension/extension_validate_selection_test.go @@ -23,16 +23,17 @@ func toolStatusByName(t *testing.T, statuses []validation.ToolInvocationStatus, } func TestExtensionValidationSelection(t *testing.T) { - t.Run("default runs only sw-cli", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(false, "", "") + t.Run("default runs all checkers", func(t *testing.T) { + tools, statuses, err := selectExtensionValidationTools("", "") require.NoError(t, err) - assert.Equal(t, []string{"sw-cli"}, toolNamesForValidation(tools)) - assert.False(t, slices.ContainsFunc(tools, requiresToolSetup)) - assert.Equal(t, "not selected; use --full or --only", toolStatusByName(t, statuses, "phpstan").Reason) + assert.Len(t, tools, 5) + assert.Len(t, statuses, len(tools)) + assert.True(t, slices.ContainsFunc(tools, requiresToolSetup)) + assert.Equal(t, "invoked", toolStatusByName(t, statuses, "phpstan").Status) }) - t.Run("only phpstan works without full", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(false, "phpstan", "") + t.Run("only phpstan", func(t *testing.T) { + tools, statuses, err := selectExtensionValidationTools("phpstan", "") require.NoError(t, err) assert.Equal(t, []string{"phpstan"}, toolNamesForValidation(tools)) assert.True(t, slices.ContainsFunc(tools, requiresToolSetup)) @@ -41,56 +42,41 @@ func TestExtensionValidationSelection(t *testing.T) { }) t.Run("Twig validation needs no external tools", func(t *testing.T) { - tools, _, err := selectExtensionValidationTools(false, "storefront-twig", "") + tools, _, err := selectExtensionValidationTools("storefront-twig", "") require.NoError(t, err) assert.Equal(t, []string{"storefront-twig"}, toolNamesForValidation(tools)) assert.False(t, slices.ContainsFunc(tools, requiresToolSetup)) }) - t.Run("full selects all validation checks", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(true, "", "") - require.NoError(t, err) - assert.Len(t, tools, 5) - assert.Len(t, statuses, len(tools)) - assert.True(t, slices.ContainsFunc(tools, requiresToolSetup)) - }) - - t.Run("only overrides full", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(true, "phpstan", "") - require.NoError(t, err) - assert.Equal(t, []string{"phpstan"}, toolNamesForValidation(tools)) - assert.Equal(t, "not selected by --only", toolStatusByName(t, statuses, "sw-cli").Reason) - }) - - t.Run("full exclusion is reported", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(true, "", "phpstan") + t.Run("default exclusion is reported", func(t *testing.T) { + tools, statuses, err := selectExtensionValidationTools("", "phpstan") require.NoError(t, err) assert.NotContains(t, toolNamesForValidation(tools), "phpstan") assert.Equal(t, "excluded by --exclude", toolStatusByName(t, statuses, "phpstan").Reason) }) t.Run("exclude applies after only", func(t *testing.T) { - tools, statuses, err := selectExtensionValidationTools(false, "phpstan,sw-cli", "sw-cli") + tools, statuses, err := selectExtensionValidationTools("phpstan,sw-cli", "sw-cli") require.NoError(t, err) assert.Equal(t, []string{"phpstan"}, toolNamesForValidation(tools)) assert.Equal(t, "excluded by --exclude", toolStatusByName(t, statuses, "sw-cli").Reason) }) t.Run("duplicate only values run once", func(t *testing.T) { - tools, _, err := selectExtensionValidationTools(false, "sw-cli,sw-cli", "") + tools, _, err := selectExtensionValidationTools("sw-cli,sw-cli", "") require.NoError(t, err) assert.Equal(t, []string{"sw-cli"}, toolNamesForValidation(tools)) }) t.Run("unsupported operation lists checkers", func(t *testing.T) { - _, _, err := selectExtensionValidationTools(false, "prettier", "") + _, _, err := selectExtensionValidationTools("prettier", "") require.ErrorContains(t, err, `tool with name "prettier" not found, possible tools:`) assert.NotContains(t, err.Error(), "prettier,") assert.Contains(t, err.Error(), "phpstan") }) t.Run("typo lists only checkers", func(t *testing.T) { - _, _, err := selectExtensionValidationTools(false, "phpsta", "") + _, _, err := selectExtensionValidationTools("phpsta", "") require.ErrorContains(t, err, `tool with name "phpsta" not found, possible tools:`) assert.Contains(t, err.Error(), "phpstan") assert.NotContains(t, err.Error(), "prettier") @@ -98,11 +84,17 @@ func TestExtensionValidationSelection(t *testing.T) { }) t.Run("empty selection fails", func(t *testing.T) { - _, _, err := selectExtensionValidationTools(false, "sw-cli", "sw-cli") + _, _, err := selectExtensionValidationTools("sw-cli", "sw-cli") require.EqualError(t, err, "no validation checks selected after applying --exclude") }) } +func TestExtensionValidateFullFlagDeprecated(t *testing.T) { + flag := extensionValidateCmd.PersistentFlags().Lookup("full") + require.NotNil(t, flag) + assert.NotEmpty(t, flag.Deprecated) +} + func toolNamesForValidation(tools verifier.ToolList[verifier.CheckTool]) []string { names := make([]string, 0, len(tools)) for _, tool := range tools { diff --git a/skills/shopware-cli-extension-store/SKILL.md b/skills/shopware-cli-extension-store/SKILL.md index 51269ec4..e94c3f34 100644 --- a/skills/shopware-cli-extension-store/SKILL.md +++ b/skills/shopware-cli-extension-store/SKILL.md @@ -17,14 +17,14 @@ Run both validations from the extension root and capture the full output **and** ```bash shopware-cli --version -shopware-cli extension validate . --format markdown -shopware-cli extension validate . --store-compliance --format markdown +shopware-cli extension validate . --only sw-cli --format markdown +shopware-cli extension validate . --only sw-cli --store-compliance --format markdown ``` - The **exit code** is the pass/fail signal (`0` = pass, non-zero = findings). The report goes to stdout; a usage block or error goes to stderr — do not read a validation failure as a usage error. - `--format markdown` gives a stable, quotable form. `--reporter` is a deprecated alias that prints a warning — use `--format`. - Treat the store-compliance run as a delta over the normal run: report only the lines it adds. -- With neither `--full` nor `--only`, `extension validate` runs only the built-in `sw-cli` checker — **not** PHPStan/ESLint/Stylelint. (`sw-cli` is that checker's name, not shorthand for the binary.) An explicit `--only` selects its named checkers even without `--full`. For the two commands above, report "the `sw-cli` checks passed", not "full validation passed". Source: `cmd/extension/extension_validate.go`, `selectExtensionValidationTools`. +- `extension validate` now runs all checkers by default. The two commands above explicitly select only the built-in `sw-cli` checker, not PHPStan/ESLint/Stylelint. (`sw-cli` is that checker's name, not shorthand for the binary.) Report "the `sw-cli` checks passed", not "full validation passed". Source: `cmd/extension/extension_validate.go`, `selectExtensionValidationTools`. - The Markdown report includes a checker table. `invoked` means the checker was called; it does not prove that files were analyzed or that a check passed. `skipped` means it was not selected or was excluded. Classify only finding lines, not checker-status lines. - Use one `shopware-cli` binary throughout, and state its version. Never mix binaries mid-answer. - Each error line ends with its result identifier — that identifier is the row's Source, and `L0` catches any line the table does not name explicitly. The CLI currently prints a missing icon twice; count a repeated line once. @@ -123,7 +123,7 @@ Eight invariants. Check each finding against all eight before writing it. | [`store-review-errors`](https://developer.shopware.com/docs/guides/development/testing/store/store-review-errors.html) | Common reasons reviewers reject a submission | user asks why a submission failed, or wants rejection risks | | [`not-allowed-store-behaviors`](https://developer.shopware.com/docs/guides/development/testing/store/not-allowed-store-behaviors.html) | Prohibited patterns | extension touches core internals, filesystem, or DB directly | | [`functionality-integration`](https://developer.shopware.com/docs/guides/development/testing/store/functionality-integration.html) | Correct integration with core, persistence, public APIs | extension has subscribers, entities, or API endpoints | -| [`code-quality`](https://developer.shopware.com/docs/guides/development/testing/store/code-quality.html) | Code standards reviewers apply | user asks about code quality, or `--full` validation was run | +| [`code-quality`](https://developer.shopware.com/docs/guides/development/testing/store/code-quality.html) | Code standards reviewers apply | user asks about code quality, or code-quality checkers were invoked | | [`installation-and-cleanup`](https://developer.shopware.com/docs/guides/development/testing/store/installation-and-cleanup.html) | Install/update/uninstall and data removal | extension implements lifecycle methods or creates tables | | [`cookies-and-privacy`](https://developer.shopware.com/docs/guides/development/testing/store/cookies-and-privacy.html) | Cookie registration, GDPR, subprocessors | extension sets cookies, tracks, or sends data to third parties | | [`seo-and-structured-data`](https://developer.shopware.com/docs/guides/development/testing/store/seo-and-structured-data.html) | SEO output and structured data | extension changes storefront markup, URLs, or meta tags | @@ -139,7 +139,7 @@ Preconditions here work like §2's: a page you had no trigger to read produces n - CLI binary and version - inspection timestamp -- sw-cli checks: pass/fail + exit code (state whether `--full` was run) +- sw-cli checks: pass/fail + exit code (state that `--only sw-cli` was used) - store-compliance checks: pass/fail + exit code - remote Store listing: inspected / not inspected - files modified: no diff --git a/skills/shopware-cli/SKILL.md b/skills/shopware-cli/SKILL.md index eecf448b..cf05add0 100644 --- a/skills/shopware-cli/SKILL.md +++ b/skills/shopware-cli/SKILL.md @@ -154,9 +154,9 @@ Normal extension validation runs the built-in checks implemented by the current Common flags include: -- `--only ` — run only the named checkers, independently of `--full` (comma-separated). +- `--only ` — run only the named checkers (comma-separated). - `--exclude ` — remove checkers from the selected set. -- `--full` — select all checkers by default, including PHPStan, ESLint, and Stylelint; explicit `--only` takes precedence. +- All checkers run by default, including PHPStan, ESLint, and Stylelint. `--full` is deprecated and has no effect. To do a quick validation use `--only sw-cli` - `--check-against ` — `highest` (default) or `lowest`: which supported Shopware version to check against. - `--store-compliance` — enable Store-compliance mode while the current CLI supports the flag. Prefer `validation.store_compliance: true` in `.shopware-extension.yml` for persistent Store intent. - `--format ` — choose an output format supported by the current CLI (`--reporter` is a deprecated alias).