|
| 1 | +# drupalorg-cli |
| 2 | + |
| 3 | +PHP 8.1+ Symfony Console CLI that wraps Drupal.org's REST and JSON:API endpoints. Distributed as a phar. |
| 4 | + |
| 5 | +## Key Commands |
| 6 | + |
| 7 | +| Command | Aliases | Description | |
| 8 | +|---|---|---| |
| 9 | +| `cache:clear` | `cc` | Clears local API cache | |
| 10 | +| `issue:apply` | | Applies latest patch from a Drupal.org issue | |
| 11 | +| `issue:branch` | | Creates a local branch for an issue | |
| 12 | +| `issue:patch` | | Generates a patch from committed changes | |
| 13 | +| `issue:interdiff` | | Generates interdiff between two commits | |
| 14 | +| `issue:link` | | Opens issue in browser | |
| 15 | +| `issue:show` | | Displays issue details | |
| 16 | +| `drupalci:list` | `ci:l` | Lists CI results for an issue | |
| 17 | +| `drupalci:watch` | `ci:w` | Polls a CI job until complete | |
| 18 | +| `maintainer:issues` | `mi` | Lists issues for a user | |
| 19 | +| `maintainer:release-notes` | `rn`, `mrn` | Generates release notes from git log | |
| 20 | +| `project:issues` | `pi` | Lists issues for a project | |
| 21 | +| `project:releases` | | Lists available releases | |
| 22 | +| `project:release-notes` | `prn` | Displays release notes for a release | |
| 23 | +| `project:link` | | Opens project page in browser | |
| 24 | +| `project:kanban` | | Opens project kanban in browser | |
| 25 | +| `travisci:list` | `tci:l` | Lists Travis CI results for an issue | |
| 26 | +| `travisci:watch` | `tci:w` | Polls a Travis CI job until complete | |
| 27 | + |
| 28 | +## Architecture |
| 29 | + |
| 30 | +- `src/Api/Client.php` — Guzzle client with cache + retry middleware; `getGuzzleClient()` exposes it for async use |
| 31 | +- `src/Api/DrupalOrg.php` — concurrent async requests (JSON:API contributors, issue details, change records) via `GuzzleHttp\Promise\Utils::settle()` |
| 32 | +- `src/Api/CommitParser.php` — extracts usernames from classic `by user:` format and Git trailers (`Co-authored-by:` etc.), extracts NIDs from commit titles |
| 33 | +- `src/Api/Request.php` / `Response.php` / `RawResponse.php` — request builder and JSON response wrappers |
| 34 | +- `src/Cli/Command/Command.php` — base class; provides `$this->client` (Client), `$this->stdOut/stdErr/stdIn`, `runProcess()` |
| 35 | + |
| 36 | +## Development Commands |
| 37 | + |
| 38 | +```bash |
| 39 | +vendor/bin/phpcs src # PSR-2 code style (line length excluded) |
| 40 | +vendor/bin/phpstan analyse src # Static analysis, level 6 |
| 41 | +vendor/bin/phpunit # Unit tests (tests/src/) |
| 42 | +composer box-install && composer box-build # Build phar |
| 43 | +``` |
| 44 | + |
| 45 | +## Key Conventions |
| 46 | + |
| 47 | +- PSR-2 code style (line length not enforced) |
| 48 | +- PHPStan level 6 with strict + deprecation rules |
| 49 | +- Never edit `composer.lock` directly — use `composer require` / `composer update` |
| 50 | +- Use concurrent async Guzzle requests (`requestAsync` + `Utils::settle()`) when fetching multiple Drupal.org nodes |
| 51 | + |
| 52 | +## Skills |
| 53 | + |
| 54 | +- `/phpstan-fix` — Run PHPStan and fix all reported errors in `src/` |
| 55 | +- `/pr-check` — Run the full local CI suite before opening a PR |
0 commit comments