From 57dcbd8e16fe35af636c594fe5db8e8071f037e6 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 17:34:53 +0200 Subject: [PATCH 1/6] Fix CI --- .github/workflows/build-and-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6ff3d8b..005bffc 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -11,12 +11,12 @@ jobs: # Run tests on all OS's and HHVM versions, even if one fails fail-fast: false matrix: - os: [ ubuntu ] + os: [ ubuntu-20.04 ] hhvm: - '4.128' - - latest - - nightly - runs-on: ${{matrix.os}}-latest + - '4.153' + - '4.168' + runs-on: ${{matrix.os}} steps: - uses: actions/checkout@v2 - uses: hhvm/actions/hack-lint-test@master From 1f4a1bcb3d9fe4fae526d72b4c5da29979d2985a Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 17:35:05 +0200 Subject: [PATCH 2/6] emove unused hhast override --- hhast-lint.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/hhast-lint.json b/hhast-lint.json index 3082049..38a0ce2 100644 --- a/hhast-lint.json +++ b/hhast-lint.json @@ -9,12 +9,6 @@ { "patterns": [ "tests/examples/codegen/*" ], "disableAllAutoFixes": true - }, - { - "patterns": [ "tests/examples/codegen/lookup-path.php" ], - "disabledLinters": [ - "Facebook\\HHAST\\Linters\\StrictModeOnlyLinter" - ] } ] } From 6dc6640e1a4695d077687e1233d0aef9855a0355 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 17:35:37 +0200 Subject: [PATCH 3/6] Expose an async variant of Codegen::forTree() --- README.md | 5 +++-- src/Codegen.hack | 12 +++++++++--- tests/CodegenTestCase.hack | 4 ++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9da0edf..d6a13ed 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ use \Facebook\HackRouter\Codegen; final class UpdateCodegen { public function main(): void { - Codegen::forTree( + $codegen = await Codegen::forTree( __DIR__.'/../src/', shape( 'controllerBase' => WebController::class, @@ -32,7 +32,8 @@ final class UpdateCodegen { 'class' => 'Router', ), ), - )->build; + ); + $codegen->build(); } } ``` diff --git a/src/Codegen.hack b/src/Codegen.hack index f0da82a..a3a4fe6 100644 --- a/src/Codegen.hack +++ b/src/Codegen.hack @@ -96,9 +96,15 @@ final class Codegen { self::TCodegenConfig $config, ): Codegen { // leaving for now as it's a public API - /* HHAST_IGNORE_ERROR[DontUseAsioJoin] fix before final release */ - return - new self(\HH\Asio\join(TreeParser::fromPathAsync($source_root)), $config); + /* HHAST_IGNORE_ERROR[DontUseAsioJoin] Kept for backward compatibility. */ + return \HH\Asio\join(static::forTreeAsync($source_root, $config)); + } + + public static async function forTreeAsync( + string $source_root, + self::TCodegenConfig $config, + ): Awaitable { + return new self(await TreeParser::fromPathAsync($source_root), $config); } <<__Memoize>> diff --git a/tests/CodegenTestCase.hack b/tests/CodegenTestCase.hack index 8b2a629..db1b708 100644 --- a/tests/CodegenTestCase.hack +++ b/tests/CodegenTestCase.hack @@ -11,9 +11,9 @@ namespace Facebook\HackRouter; use function Facebook\FBExpect\expect; final class CodegenTestCase extends \Facebook\HackTest\HackTest { - public function testCanCreateForTree(): void { + public async function testCanCreateForTreeAsync(): Awaitable { // Just test it parses and we can create an instance - $codegen = Codegen::forTree(__DIR__.'/examples/', shape()); + $codegen = await Codegen::forTreeAsync(__DIR__.'/examples/', shape()); expect($codegen)->toBeInstanceOf(Codegen::class); } } From 346402811e24b4efcc0732ab86cdf7f90071e76c Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 17:46:54 +0200 Subject: [PATCH 4/6] Support urls in the cli lookup utility --- src/RouterCLILookupCodegenBuilder.hack | 6 ++++-- tests/examples/codegen/lookup-path.php | 12 +++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/RouterCLILookupCodegenBuilder.hack b/src/RouterCLILookupCodegenBuilder.hack index 7badf35..73324d3 100644 --- a/src/RouterCLILookupCodegenBuilder.hack +++ b/src/RouterCLILookupCodegenBuilder.hack @@ -80,7 +80,7 @@ final class RouterCLILookupCodegenBuilder { ->setBodyf( "%s\n". '$argv = '. - '\\Facebook\\TypeAssert\\matches>('. + '\\Facebook\\TypeAssert\\matches>('. "\\HH\\global_get('argv'));\n". "(new %s())->main(\$argv);\n", $this->getInitCode(), @@ -216,7 +216,7 @@ final class RouterCLILookupCodegenBuilder { private function getMainMethod(): CodegenMethod { return $this->cg->codegenMethod('main') - ->addParameter('KeyedContainer $argv') + ->addParameter('vec $argv') ->setReturnType('void') ->setBody( $this->cg->codegenHackBuilder() @@ -229,6 +229,8 @@ final class RouterCLILookupCodegenBuilder { ->addLine('\\fprintf(\\STDERR, "Usage: %s PATH\n", $argv[0]);') ->addLine('exit(1);') ->endIfBlock() + ->addInlineComment('The parser is very lenient, `?: $path` is almost never needed.') + ->addLine('$path = \parse_url($path, \PHP_URL_PATH) ?: $path;') ->addAssignment( '$controllers', '$this->getControllersForPath($path)', diff --git a/tests/examples/codegen/lookup-path.php b/tests/examples/codegen/lookup-path.php index dc17654..ae42980 100644 --- a/tests/examples/codegen/lookup-path.php +++ b/tests/examples/codegen/lookup-path.php @@ -7,7 +7,7 @@ * To re-generate this file run vendor/hhvm/hacktest/bin/hacktest * * - * @partially-generated SignedSource<> + * @partially-generated SignedSource<<4f5a85f07322ab422aee3e53f62a7432>> */ namespace Facebook\HackRouter\CodeGen\Tests\Generated; @@ -15,12 +15,12 @@ function hack_router_cli_lookup_generated_main(): void { /* BEGIN MANUAL SECTION init */ $autoloader = null; - $autoloader_candidates = ImmSet { + $autoloader_candidates = vec[ __DIR__.'/vendor/autoload.hack', __DIR__.'/../vendor/autoload.hack', __DIR__.'/../../vendor/autoload.hack', __DIR__.'/../../../vendor/autoload.hack', - }; + ]; foreach ($autoloader_candidates as $candidate) { if (\file_exists($candidate)) { $autoloader = $candidate; @@ -35,7 +35,7 @@ function hack_router_cli_lookup_generated_main(): void { \Facebook\AutoloadMap\initialize(); /* END MANUAL SECTION */ - $argv = \Facebook\TypeAssert\matches>(\HH\global_get('argv')); + $argv = \Facebook\TypeAssert\matches>(\HH\global_get('argv')); (new MySiteRouterCLILookup())->main($argv); } @@ -75,12 +75,14 @@ private function getControllersForPath( } } - public function main(KeyedContainer $argv): void { + public function main(vec $argv): void { $path = $argv[1] ?? null; if ($path === null) { \fprintf(\STDERR, "Usage: %s PATH\n", $argv[0]); exit(1); } + // The parser is very lenient, `?: $path` is almost never needed. + $path = \parse_url($path, \PHP_URL_PATH) ?: $path; $controllers = $this->getControllersForPath($path); if ($controllers->isEmpty()) { \printf("No controller found for '%s'.\n", $path); From 4695d8854dfe6deb82b58e01ef53b5c816cd9357 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 19:44:02 +0200 Subject: [PATCH 5/6] Add explanation docblock to CLI lookup utility --- src/RouterCLILookupCodegenBuilder.hack | 29 +++++++++++++++++++++++ tests/examples/codegen/lookup-path.php | 32 +++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/RouterCLILookupCodegenBuilder.hack b/src/RouterCLILookupCodegenBuilder.hack index 73324d3..efcf1b6 100644 --- a/src/RouterCLILookupCodegenBuilder.hack +++ b/src/RouterCLILookupCodegenBuilder.hack @@ -25,6 +25,34 @@ final class RouterCLILookupCodegenBuilder { private CodegenGeneratedFrom $generatedFrom; private HackCodegenFactory $cg; + const string CLI_LOOKUP_UTILITY_DOC_TEXT = <<<'TEXT' +A quick way to validate that a path or url routes to the controller you expect. + +Usage: path/to/this/utility <%path or url%>. +The output will look something like this: + +``` +$ tests/examples/codegen/lookup-path.php /a-string/123/derp +HEAD: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController +GET: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController +``` + +You may also copy paste the whole url: +``` +$ tests/examples/codegen/lookup-path.php http://localhost:8080/a-string/123/derp?query=abcd#fragment +HEAD: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController +GET: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController +``` + +If the given path does not match any controllers, you'll get the following result: +``` +$ tests/examples/codegen/lookup-path.php /a/b/c +No controller found for '/a/b/c'. +``` + +You can edit the manual sections to change the router and formatter used. +TEXT; + public function __construct( private IHackCodegenConfig $codegenConfig, ) { @@ -75,6 +103,7 @@ final class RouterCLILookupCodegenBuilder { ->addClass($this->getCodegenClass($router_classname, $utility_classname)) ->addFunction( $this->cg->codegenFunction('hack_router_cli_lookup_generated_main') + ->setDocBlock(static::CLI_LOOKUP_UTILITY_DOC_TEXT) ->addEmptyUserAttribute('__EntryPoint') ->setReturnType('void') ->setBodyf( diff --git a/tests/examples/codegen/lookup-path.php b/tests/examples/codegen/lookup-path.php index ae42980..6aab771 100644 --- a/tests/examples/codegen/lookup-path.php +++ b/tests/examples/codegen/lookup-path.php @@ -7,10 +7,40 @@ * To re-generate this file run vendor/hhvm/hacktest/bin/hacktest * * - * @partially-generated SignedSource<<4f5a85f07322ab422aee3e53f62a7432>> + * @partially-generated SignedSource<<61e1a0bcff805162c34d005bb526d587>> */ namespace Facebook\HackRouter\CodeGen\Tests\Generated; +/** + * A quick way to validate that a path or url routes to the controller you + * expect. + * + * Usage: path/to/this/utility <%path or url%>. + * The output will look something like this: + * + * ``` + * $ tests/examples/codegen/lookup-path.php /a-string/123/derp + * HEAD: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController + * GET: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController + * ``` + * + * You may also copy paste the whole url: + * ``` + * $ tests/examples/codegen/lookup-path.php + * http://localhost:8080/a-string/123/derp?query=abcd#fragment + * HEAD: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController + * GET: Facebook\HackRouter\CodeGen\Tests\GetRequestExampleController + * ``` + * + * If the given path does not match any controllers, you'll get the following + * result: + * ``` + * $ tests/examples/codegen/lookup-path.php /a/b/c + * No controller found for '/a/b/c'. + * ``` + * + * You can edit the manual sections to change the router and formatter used. + */ <<__EntryPoint>> function hack_router_cli_lookup_generated_main(): void { /* BEGIN MANUAL SECTION init */ From 33244ffb66b160ef7c920bd71401b54c4816fa20 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Mon, 29 May 2023 19:47:12 +0200 Subject: [PATCH 6/6] Deprecate Codegen::forTree() --- src/Codegen.hack | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Codegen.hack b/src/Codegen.hack index a3a4fe6..abbd840 100644 --- a/src/Codegen.hack +++ b/src/Codegen.hack @@ -91,6 +91,9 @@ final class Codegen { ?'discardChanges' => bool, ); + /** + * @deprecated, use forTreeAsync() instead. + */ public static function forTree( string $source_root, self::TCodegenConfig $config,