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
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"atoum/atoum": "Lets GrumPHP run your unit tests.",
"behat/behat": "Lets GrumPHP validate your project features.",
"brianium/paratest": "Lets GrumPHP run PHPUnit in parallel.",
"carthage-software/mago": "Lets GrumPHP help you write better PHP code.",
"codeception/codeception": "Lets GrumPHP run your project's full stack tests",
"consolidation/robo": "Lets GrumPHP run your automated PHP tasks.",
"designsecurity/progpilot": "Lets GrumPHP be sure that there are no vulnerabilities in your code.",
Expand Down
9 changes: 9 additions & 0 deletions doc/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ grumphp:
infection: ~
jsonlint: ~
kahlan: ~
mago_analyze: ~
mago_format: ~
mago_guard: ~
mago_lint: ~
make: ~
npm_script: ~
paratest: ~
Expand Down Expand Up @@ -99,6 +103,11 @@ Every task has its own default configuration. It is possible to overwrite the pa
- [Infection](tasks/infection.md)
- [JsonLint](tasks/jsonlint.md)
- [Kahlan](tasks/kahlan.md)
- [Mago](tasks/mago.md)
- [Mago Analyzer](tasks/mago/analyzer.md)
- [Mago Formatter](tasks/mago/formatter.md)
- [Mago Guard](tasks/mago/guard.md)
- [Mago Linter](tasks/mago/linter.md)
- [Make](tasks/make.md)
- [NPM script](tasks/npm_script.md)
- [Paratest](tasks/paratest.md)
Expand Down
36 changes: 36 additions & 0 deletions doc/tasks/mago.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Mago

[Mago](https://mago.carthage.software/) is a fast PHP toolchain written in Rust. It bundles a
formatter, a linter, a static analyzer and an architectural guard. GrumPHP exposes each of these as
its own task so you can enable only what you need and configure them independently.

## Composer

```bash
composer require --dev carthage-software/mago
```

Mago is configured through a single `mago.toml` file in your project root. You can scaffold one with:

```bash
vendor/bin/mago init
```

## Tasks

| Task | Description |
| --- | --- |
| [`mago_format`](mago/formatter.md) | Format PHP code to match your configured style. |
| [`mago_lint`](mago/linter.md) | Run linting rules to catch style violations, code smells and likely bugs. |
| [`mago_analyze`](mago/analyzer.md) | Deep static analysis: type checking, control-flow and logical-error detection. |
| [`mago_guard`](mago/guard.md) | Enforce architectural rules and layer dependencies. |

## Behavior

`mago_format`, `mago_lint` and `mago_analyze` run read-only by default and, when they fail, GrumPHP
offers to re-run them with fixes applied. `mago_guard` has no auto-fix — architectural violations
cannot be fixed automatically, so it only reports them.

Each task scopes its work to the relevant files per context (pre-commit vs run). The exact behavior
differs per task because of how Mago's CLI works — see each task's page below for the details and its
full set of configurable options.
73 changes: 73 additions & 0 deletions doc/tasks/mago/analyzer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Mago Analyzer

Perform deep static analysis on PHP code including type checking, control flow analysis, and detection of logical errors.

## Composer

```bash
composer require --dev carthage-software/mago
```

## Behavior

The task runs `mago analyze` directly to get full diagnostic output. When running in a `git pre-commit` context, only staged files are analyzed (`--staged`). In a `run` context, all files are analyzed.

If the task fails, GrumPHP will offer to re-run with `--fix` applied. The fix mode can be configured via `fix-mode`.

## Config

The task lives under the `mago_analyze` namespace and has following configurable parameters:

```yaml
# grumphp.yml
grumphp:
tasks:
mago_analyze:
no-stubs: ~
retain-codes: []
ignore-baseline: ~
sort: ~
fix-mode: safe
minimum-report-level: ~
```

**no-stubs**

*Type: bool*

Disable built-in PHP and library stubs for analysis. By default, the analyzer uses stubs for built-in PHP functions and popular libraries to provide accurate type information. Disabling this may result in more reported issues when external symbols can't be resolved.

**retain-codes**

*Type: string[] — Default: []*

Reporting filter: only display issues matching the specified rule codes (e.g. `invalid-argument`, `semantics`). All rules still run; only the output is filtered. Can be specified multiple times.

**ignore-baseline**

*Type: bool*

Ignore the baseline file and report all issues, including those currently suppressed. The baseline file must be generated manually via `mago analyze --generate-baseline`.

**sort**

*Type: bool*

Sort reported issues by severity level, rule code, and file location. By default, issues are reported in the order they appear in files.

**fix-mode**

*Default: safe — Possible values: `safe`, `potentially-unsafe`, `unsafe`*

Controls which fixes are applied when GrumPHP offers to auto-fix:

- `safe` — apply only safe fixes (default)
- `potentially-unsafe` — also apply fixes that may require manual review
- `unsafe` — also apply fixes that might change code behavior

**minimum-report-level**

*Default: null (mago default: all levels)*

Minimum severity level to display in the report. Issues below this level are not shown. Possible values: `note`, `help`, `warning`, `error`

28 changes: 28 additions & 0 deletions doc/tasks/mago/formatter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Mago Formatter

Automatically format PHP code to match the configured style preferences.

## Composer

```bash
composer require --dev carthage-software/mago
```

## Behavior

The task always runs in `--dry-run` mode: it previews formatting changes without modifying any files, and fails if any file would be changed.

In a `run` context the whole project is checked (Mago uses the paths from your `mago.toml`). In a `git pre-commit` context the staged `.php` files are passed to Mago explicitly so only those files are checked. (`mago format --staged` cannot be combined with `--dry-run`, so the staged files are passed as paths instead — note this overrides the `source`/`excludes` config in `mago.toml` for those files, the same trade-off other file-based GrumPHP tasks make.)

If the task fails, GrumPHP will offer to re-run without `--dry-run` to apply the formatting in-place.

## Config

The task lives under the `mago_format` namespace and has no configurable parameters:

```yaml
# grumphp.yml
grumphp:
tasks:
mago_format: ~
```
72 changes: 72 additions & 0 deletions doc/tasks/mago/guard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Mago Guard

Enforce architectural rules and layer dependencies. Checks that code follows defined architectural constraints, such as ensuring that certain layers don't depend on others.

## Composer

```bash
composer require --dev carthage-software/mago
```

## Behavior

The task runs `mago guard` and fails when an architectural violation is found. It runs on all files in both `git pre-commit` and `run` contexts (guard has no `--staged` mode, and architectural rules are evaluated against the whole project). Because every pre-commit run scans the full project, consider whether `mago_guard` is fast enough for your codebase before enabling it as a pre-commit task.

Guard does not offer an auto-fix: architectural violations cannot be fixed automatically, so the task only reports them.

## Config

The task lives under the `mago_guard` namespace and has following configurable parameters:

```yaml
# grumphp.yml
grumphp:
tasks:
mago_guard:
mode: ~
no-stubs: ~
retain-codes: []
ignore-baseline: ~
sort: ~
minimum-report-level: ~
```

**mode**

*Default: null — Possible values: `structural`, `perimeter`*

Selects which guard checks run. These are mutually exclusive in Mago, so a single option is used instead of separate flags:

- `~` (not set) — run both structural and perimeter checks (Mago's default)
- `structural` — run only structural checks (naming conventions, modifiers, inheritance constraints)
- `perimeter` — run only perimeter checks (dependency boundaries, layer restrictions)

**no-stubs**

*Type: bool*

Disable built-in PHP and library stubs. By default, guard uses stubs for built-in PHP functions and popular libraries to provide accurate symbol information. Disabling this may result in more warnings when external symbols can't be resolved.

**retain-codes**

*Type: string[] — Default: []*

Reporting filter: only display issues matching the specified rule codes. All rules still run; only the output is filtered. Can be specified multiple times.

**ignore-baseline**

*Type: bool*

Ignore the baseline file and report all issues, including those currently suppressed. The baseline file must be generated manually via `mago guard --generate-baseline`.

**sort**

*Type: bool*

Sort reported issues by severity level, rule code, and file location. By default, issues are reported in the order they appear in files.

**minimum-report-level**

*Default: null (mago default: all levels)*

Minimum severity level to display in the report. Issues below this level are not shown. Possible values: `note`, `help`, `warning`, `error`
89 changes: 89 additions & 0 deletions doc/tasks/mago/linter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Mago Linter

Run linting rules on PHP code to identify style violations, code smells, and potential bugs.

## Composer

```bash
composer require --dev carthage-software/mago
```

## Behavior

The task always runs in `--fix --dry-run` mode: it previews what automatic fixes would be applied without modifying any files, and fails if issues are found. When running in a `git pre-commit` context, only staged files are linted (`--staged`). In a `run` context, all files are linted.

If the task fails, GrumPHP will offer to re-run with `--fix` applied. The fix mode can be configured via `fix-mode`.

## Config

The task lives under the `mago_lint` namespace and has following configurable parameters:

```yaml
# grumphp.yml
grumphp:
tasks:
mago_lint:
semantics: ~
pedantic: ~
only: []
retain-codes: []
ignore-baseline: ~
sort: ~
fix-mode: safe
minimum-report-level: ~
```

**semantics**

*Type: bool*

Skip linter rules and only perform basic syntax and semantic validation. Checks that your PHP code parses correctly and has valid semantic structure, without applying any style or quality rules. Useful for quick syntax validation.

**pedantic**

*Type: bool*

Enable every available linter rule for maximum thoroughness. Overrides your configuration and enables all rules, including those disabled by default. The output will be extremely verbose and is not recommended for regular use. Useful for comprehensive code audits.

**only**

*Type: string[] — Default: []*

Run only the specified rules, ignoring the configuration file. Provide a list of rule codes (e.g. `invalid-argument`, `semantics`). Overrides your `mago.toml` configuration and is useful for targeted analysis.

**retain-codes**

*Type: string[] — Default: []*

Reporting filter: only display issues matching the specified rule codes (e.g. `invalid-argument`, `semantics`). All rules still run; only the output is filtered. Can be specified multiple times.

Note: this differs from `only`, which restricts which rules are executed.

**ignore-baseline**

*Type: bool*

Ignore the baseline file and report all issues, including those currently suppressed. The baseline file must be generated manually via `mago lint --generate-baseline`.

**sort**

*Type: bool*

Sort reported issues by severity level, rule code, and file location. By default, issues are reported in the order they appear in files.

**fix-mode**

*Default: safe — Possible values: `safe`, `potentially-unsafe`, `unsafe`*

Controls which fixes are applied when GrumPHP offers to auto-fix:

- `safe` — apply only safe fixes (default)
- `potentially-unsafe` — also apply fixes that may require manual review
- `unsafe` — also apply fixes that might change code behavior

**minimum-report-level**

*Default: null (mago default: all levels)*

Minimum severity level to display in the report. Issues below this level are not shown. Possible values: `note`, `help`, `warning`, `error`

28 changes: 28 additions & 0 deletions resources/config/tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,34 @@ services:
tags:
- {name: grumphp.task, task: kahlan}

GrumPHP\Task\MagoAnalyzer:
arguments:
- '@process_builder'
- '@formatter.raw_process'
tags:
- {name: grumphp.task, task: mago_analyze}

GrumPHP\Task\MagoFormatter:
arguments:
- '@process_builder'
- '@formatter.raw_process'
tags:
- {name: grumphp.task, task: mago_format}

GrumPHP\Task\MagoGuard:
arguments:
- '@process_builder'
- '@formatter.raw_process'
tags:
- {name: grumphp.task, task: mago_guard}

GrumPHP\Task\MagoLinter:
arguments:
- '@process_builder'
- '@formatter.raw_process'
tags:
- {name: grumphp.task, task: mago_lint}

GrumPHP\Task\Make:
arguments:
- '@process_builder'
Expand Down
Loading