diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3a8e7cb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Jordan Partridge + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/Commands/InspireCommand.php b/app/Commands/InspireCommand.php deleted file mode 100644 index 934fe72..0000000 --- a/app/Commands/InspireCommand.php +++ /dev/null @@ -1,48 +0,0 @@ - -
Laravel Zero
- - Simplicity is the ultimate sophistication. - - - HTML); - } - - /** - * Define the command's schedule. - */ - public function schedule(Schedule $schedule): void - { - // $schedule->command(static::class)->everyMinute(); - } -} diff --git a/composer.json b/composer.json index 69c29ae..56e74c3 100644 --- a/composer.json +++ b/composer.json @@ -34,9 +34,7 @@ }, "autoload": { "psr-4": { - "App\\": "app/", - "Database\\Factories\\": "database/factories/", - "Database\\Seeders\\": "database/seeders/" + "App\\": "app/" } }, "autoload-dev": { diff --git a/config/app.php b/config/app.php index 802e2c1..1a14cd7 100644 --- a/config/app.php +++ b/config/app.php @@ -15,7 +15,7 @@ | */ - 'name' => 'Cf', + 'name' => 'Cloudflare', /* |-------------------------------------------------------------------------- diff --git a/specs/scaffold-cleanup/spec.md b/specs/scaffold-cleanup/spec.md new file mode 100644 index 0000000..ac64611 --- /dev/null +++ b/specs/scaffold-cleanup/spec.md @@ -0,0 +1,43 @@ +# SPEC: Scaffold cleanup (LICENSE, drop Inspire, app name Cloudflare) + +Status: DRAFT + +**Story:** README and `composer.json` say this is a Cloudflare CLI under MIT. `cf list` still ships Laravel Zero's `inspire` and the app name `Cf`, and there is no `LICENSE` file. Cursor PR https://github.com/conduit-ui/cloudflare/pull/3 almost fixed that, then sat one commit behind `#17` (quality-runners) with a body that still claims a CI/lock rewrite. + +## Locked + +- Apply the cleanup **on current `main`** (`e60415d` / `#17`). Rebase, do not replay the pre-`#17` tree. +- Add MIT `LICENSE` (Copyright (c) 2026 Jordan Partridge). +- Delete `app/Commands/InspireCommand.php` and `tests/Feature/InspireCommandTest.php`. +- `config/app.php` `'name'` → `Cloudflare`. Binary stays `cf`. Keep the `#17` `AppServiceProvider` import. +- Drop nonexistent `Database\\Factories\\` / `Database\\Seeders\\` autoload paths. There is no `database/` directory. +- Replace `tests/Unit/ExampleTest.php` with a `CloudflareConnector` smoke test. +- `composer.json` `config.platform.php` stays `"8.3.33"`. `composer.lock` `platform-overrides.php` stays `"8.3.33"`. Host PHP here is 8.5.x; unconstrained `composer update` resolves past 8.3 and breaks the 8.3 CI runner (closed PR `#12`). +- Keep `phpstan/phpstan` and `rector/rector` in `require-dev` (added by `#17` for `./bin/ci`). Autoload-only edits do **not** change Composer content-hash; do not regenerate the lock. +- Keep `tunnel:expose`: `app/Commands/TunnelExposeCommand.php` + `tests/Feature/TunnelExposeCommandTest.php`. +- Keep `tests/Feature/QualityRunnersCiTest.php` and the residual `.github/workflows/ci.yml` from `#17` (Pint `--test` + Pest; not a fake `quality-runners/gate` job). +- Research owns `specs/` and `~/.grok/tmp/3-notes.md`. Build owns LICENSE / Inspire delete / `config/app.php` / composer autoload. Test owns `tests/Unit/CloudflareConnectorTest.php`. +- Do not merge. Do not deploy. + +## Done when + +- [ ] `test ! -f app/Commands/InspireCommand.php && test ! -f tests/Feature/InspireCommandTest.php` +- [ ] `python3 -c "import json; assert json.load(open('composer.json'))['config']['platform']['php']=='8.3.33'"` +- [ ] `python3 -c "import json; c=json.load(open('composer.json')); assert 'phpstan/phpstan' in c['require-dev'] and 'rector/rector' in c['require-dev']"` +- [ ] `test -f app/Commands/TunnelExposeCommand.php && test -f tests/Feature/TunnelExposeCommandTest.php && test -f tests/Feature/QualityRunnersCiTest.php && test -f LICENSE` +- [ ] `rg -n "'name' => 'Cloudflare'" config/app.php` +- [ ] After `composer install`: `vendor/bin/pest --compact` exits 0. `php cf list` does not show `inspire`. `php cf tunnel:expose --help` exits 0. + +## Out of scope + +- Merging PR `#3` or deploying a PHAR +- Regenerating `composer.lock`, bumping Symfony, pinning PHP 8.4/8.5 +- Restoring a full GHA quality workflow (PR body is stale; `#17` already retired that) +- `dns:upsert` / `tunnel:status` / `--dry-run` (open issues `#14` `#15` `#16`) +- Daily clone under `~/Projects/conduit-ui/repos/cloudflare` + +## Open decisions + +- `tests/Feature/.gitkeep` is empty noise (`fc7ba34` commit message still says "regenerate composer.lock"; the file is the whole commit). Optional delete. Do not empty `tests/Feature/` to justify it. +- Smoke test title says "auth header" but only asserts base URL + account id. Optional rename or assert `Authorization` via Saloon public headers. Not blocking. +- PR body still claims "Add CI workflow" and "Refresh composer.lock". Update the body; do not implement those claims. diff --git a/tests/Feature/.gitkeep b/tests/Feature/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/Feature/InspireCommandTest.php b/tests/Feature/InspireCommandTest.php deleted file mode 100755 index 57642b2..0000000 --- a/tests/Feature/InspireCommandTest.php +++ /dev/null @@ -1,5 +0,0 @@ -artisan('inspire')->assertExitCode(0); -}); diff --git a/tests/Feature/TunnelExposeListedTest.php b/tests/Feature/TunnelExposeListedTest.php new file mode 100644 index 0000000..c96ecf5 --- /dev/null +++ b/tests/Feature/TunnelExposeListedTest.php @@ -0,0 +1,19 @@ +toBe(0) + ->and(Artisan::output())->toContain('tunnel:expose'); +}); + +it('prints tunnel:expose help', function () { + $exit = Artisan::call('tunnel:expose', ['--help' => true]); + + expect($exit)->toBe(0) + ->and(Artisan::output())->toContain('Create a tunnel and print cloudflared steps to expose a local app'); +}); diff --git a/tests/Unit/CloudflareConnectorTest.php b/tests/Unit/CloudflareConnectorTest.php new file mode 100644 index 0000000..c481ee0 --- /dev/null +++ b/tests/Unit/CloudflareConnectorTest.php @@ -0,0 +1,22 @@ +resolveBaseUrl())->toBe('https://api.cloudflare.com/client/v4') + ->and($connector->getAccountId())->toBe('acct-123'); +}); + +it('does not ship the Laravel Zero InspireCommand scaffold', function () { + expect(is_file(dirname(__DIR__, 2).'/app/Commands/InspireCommand.php'))->toBeFalse(); +}); + +it('pins composer platform php to 8.3.33', function () { + $composer = json_decode((string) file_get_contents(dirname(__DIR__, 2).'/composer.json'), true, 512, JSON_THROW_ON_ERROR); + + expect($composer['config']['platform']['php'])->toBe('8.3.33'); +}); diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php deleted file mode 100644 index 61cd84c..0000000 --- a/tests/Unit/ExampleTest.php +++ /dev/null @@ -1,5 +0,0 @@ -toBeTrue(); -});