diff --git a/.gitignore b/.gitignore index 17d453872..9bdb0751f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea -.vscode/settings.json +.vscode/ .DS_Store diff --git a/bricks/dart_frog_prod_server/__brick__/build/bin/server.dart b/bricks/dart_frog_prod_server/__brick__/build/bin/server.dart index 7107f9e5c..9cd1cf4d5 100644 --- a/bricks/dart_frog_prod_server/__brick__/build/bin/server.dart +++ b/bricks/dart_frog_prod_server/__brick__/build/bin/server.dart @@ -12,7 +12,7 @@ import 'package:dart_frog/dart_frog.dart'; {{/middleware}} void main() async { final address = InternetAddress.anyIPv6; - final port = int.tryParse(Platform.environment['PORT'] ?? '8080') ?? 8080;{{#invokeCustomInit}} + final port = int.tryParse(Platform.environment['PORT'] ?? '{{{port}}}') ?? {{{port}}};{{#invokeCustomInit}} await entrypoint.init(address, port);{{/invokeCustomInit}} createServer(address, port); } diff --git a/packages/dart_frog_cli/lib/src/commands/build/build.dart b/packages/dart_frog_cli/lib/src/commands/build/build.dart index a6de875a2..2cfbc7de6 100644 --- a/packages/dart_frog_cli/lib/src/commands/build/build.dart +++ b/packages/dart_frog_cli/lib/src/commands/build/build.dart @@ -18,12 +18,19 @@ class BuildCommand extends DartFrogCommand { }) : _generator = generator ?? MasonGenerator.fromBundle, _prodServerBuilderConstructor = prodServerBuilderConstructor ?? ProdServerBuilder.new { - argParser.addOption( - 'dart-version', - defaultsTo: 'stable', - help: 'The Dart SDK version used to build the Dockerfile, defaults to' - ' stable.', - ); + argParser + ..addOption( + 'dart-version', + defaultsTo: 'stable', + help: 'The Dart SDK version used to build the Dockerfile, defaults to' + ' stable.', + ) + ..addOption( + 'port', + abbr: 'p', + defaultsTo: '8080', + help: 'Which port number the server should start on.', + ); } final GeneratorBuilder _generator; @@ -38,11 +45,14 @@ class BuildCommand extends DartFrogCommand { @override Future run() async { final dartVersion = results['dart-version'] as String; + final port = (results['port'] as String?) ?? '8080'; + final generator = await _generator(dartFrogProdServerBundle); final builder = _prodServerBuilderConstructor( logger: logger, dartVersion: dartVersion, + port: port, workingDirectory: cwd, prodServerBundleGenerator: generator, ); diff --git a/packages/dart_frog_cli/lib/src/commands/build/templates/dart_frog_prod_server_bundle.dart b/packages/dart_frog_cli/lib/src/commands/build/templates/dart_frog_prod_server_bundle.dart index f56661813..afe1d6572 100644 --- a/packages/dart_frog_cli/lib/src/commands/build/templates/dart_frog_prod_server_bundle.dart +++ b/packages/dart_frog_cli/lib/src/commands/build/templates/dart_frog_prod_server_bundle.dart @@ -14,7 +14,7 @@ final dartFrogProdServerBundle = MasonBundle.fromJson({ { "path": "build/bin/server.dart", "data": - "Ly8gR0VORVJBVEVEIENPREUgLSBETyBOT1QgTU9ESUZZIEJZIEhBTkQKLy8gaWdub3JlX2Zvcl9maWxlOiB0eXBlPWxpbnQsIGltcGxpY2l0X2R5bmFtaWNfbGlzdF9saXRlcmFsCgppbXBvcnQgJ2RhcnQ6aW8nOwoKaW1wb3J0ICdwYWNrYWdlOmRhcnRfZnJvZy9kYXJ0X2Zyb2cuZGFydCc7Cgp7eyNpbnZva2VDdXN0b21FbnRyeXBvaW50fX1pbXBvcnQgJy4uL21haW4uZGFydCcgYXMgZW50cnlwb2ludDt7ey9pbnZva2VDdXN0b21FbnRyeXBvaW50fX0Ke3sjcm91dGVzfX1pbXBvcnQgJ3t7e3BhdGh9fX0nIGFzIHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Owp7ey9yb3V0ZXN9fQp7eyNtaWRkbGV3YXJlfX1pbXBvcnQgJ3t7e3BhdGh9fX0nIGFzIHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Owp7ey9taWRkbGV3YXJlfX0Kdm9pZCBtYWluKCkgYXN5bmMgewogIGZpbmFsIGFkZHJlc3MgPSBJbnRlcm5ldEFkZHJlc3MuYW55SVB2NjsKICBmaW5hbCBwb3J0ID0gaW50LnRyeVBhcnNlKFBsYXRmb3JtLmVudmlyb25tZW50WydQT1JUJ10gPz8gJzgwODAnKSA/PyA4MDgwO3t7I2ludm9rZUN1c3RvbUluaXR9fQogIGF3YWl0IGVudHJ5cG9pbnQuaW5pdChhZGRyZXNzLCBwb3J0KTt7ey9pbnZva2VDdXN0b21Jbml0fX0KICBjcmVhdGVTZXJ2ZXIoYWRkcmVzcywgcG9ydCk7Cn0KCkZ1dHVyZTxIdHRwU2VydmVyPiBjcmVhdGVTZXJ2ZXIoSW50ZXJuZXRBZGRyZXNzIGFkZHJlc3MsIGludCBwb3J0KSBhc3luYyB7CiAgZmluYWwgaGFuZGxlciA9IENhc2NhZGUoKXt7I3NlcnZlU3RhdGljRmlsZXN9fS5hZGQoY3JlYXRlU3RhdGljRmlsZUhhbmRsZXIoKSl7ey9zZXJ2ZVN0YXRpY0ZpbGVzfX0uYWRkKGJ1aWxkUm9vdEhhbmRsZXIoKSkuaGFuZGxlcjsKICBmaW5hbCBzZXJ2ZXIgPSBhd2FpdCB7eyNpbnZva2VDdXN0b21FbnRyeXBvaW50fX1lbnRyeXBvaW50LnJ1bihoYW5kbGVyLCBhZGRyZXNzLCBwb3J0KXt7L2ludm9rZUN1c3RvbUVudHJ5cG9pbnR9fXt7Xmludm9rZUN1c3RvbUVudHJ5cG9pbnR9fXNlcnZlKGhhbmRsZXIsIGFkZHJlc3MsIHBvcnQpe3svaW52b2tlQ3VzdG9tRW50cnlwb2ludH19OwogIHByaW50KCdceDFCWzkybeKck1x4MUJbMG0gUnVubmluZyBvbiBodHRwOi8vJHtzZXJ2ZXIuYWRkcmVzcy5ob3N0fToke3NlcnZlci5wb3J0fScpOwogIHJldHVybiBzZXJ2ZXI7Cn0KCkhhbmRsZXIgYnVpbGRSb290SGFuZGxlcigpIHsKICBmaW5hbCBwaXBlbGluZSA9IGNvbnN0IFBpcGVsaW5lKCl7eyNnbG9iYWxNaWRkbGV3YXJlfX0uYWRkTWlkZGxld2FyZSh7eyNzbmFrZUNhc2V9fXt7e25hbWV9fX17ey9zbmFrZUNhc2V9fS5taWRkbGV3YXJlKXt7L2dsb2JhbE1pZGRsZXdhcmV9fTsKICBmaW5hbCByb3V0ZXIgPSBSb3V0ZXIoKXt7I2RpcmVjdG9yaWVzfX0KICAgIC4ubW91bnQoJ3t7e3JvdXRlfX19JywgKGNvbnRleHR7eyNkaXJlY3RvcnlfcGFyYW1zLjB9fSx7eyNkaXJlY3RvcnlfcGFyYW1zfX17ey59fSx7ey9kaXJlY3RvcnlfcGFyYW1zfX17ey9kaXJlY3RvcnlfcGFyYW1zLjB9fSkgPT4gYnVpbGR7eyNwYXNjYWxDYXNlfX17e3tuYW1lfX19e3svcGFzY2FsQ2FzZX19SGFuZGxlcih7eyNkaXJlY3RvcnlfcGFyYW1zfX17ey59fSx7ey9kaXJlY3RvcnlfcGFyYW1zfX0pKGNvbnRleHQpKXt7L2RpcmVjdG9yaWVzfX07CiAgcmV0dXJuIHBpcGVsaW5lLmFkZEhhbmRsZXIocm91dGVyKTsKfQp7eyNkaXJlY3Rvcmllc319CkhhbmRsZXIgYnVpbGR7eyNwYXNjYWxDYXNlfX17e3tuYW1lfX19e3svcGFzY2FsQ2FzZX19SGFuZGxlcih7eyNkaXJlY3RvcnlfcGFyYW1zfX1TdHJpbmcge3sufX0se3svZGlyZWN0b3J5X3BhcmFtc319KSB7CiAgZmluYWwgcGlwZWxpbmUgPSBjb25zdCBQaXBlbGluZSgpe3sjbWlkZGxld2FyZS4wfX17eyNtaWRkbGV3YXJlfX0uYWRkTWlkZGxld2FyZSh7eyNzbmFrZUNhc2V9fXt7e25hbWV9fX17ey9zbmFrZUNhc2V9fS5taWRkbGV3YXJlKXt7L21pZGRsZXdhcmV9fXt7L21pZGRsZXdhcmUuMH19OwogIGZpbmFsIHJvdXRlciA9IFJvdXRlcigpCiAgICB7eyNmaWxlc319e3sjd2lsZGNhcmR9fS4ubW91bnQoJ3t7e3JvdXRlfX19JywgKGNvbnRleHQpID0+IHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Lm9uUmVxdWVzdChjb250ZXh0LGNvbnRleHQucmVxdWVzdC51cmwucGF0aCkpe3svd2lsZGNhcmR9fXt7XndpbGRjYXJkfX0uLmFsbCgne3t7cm91dGV9fX0nLCAoY29udGV4dHt7I2ZpbGVfcGFyYW1zLjB9fSx7eyNmaWxlX3BhcmFtc319e3sufX0se3svZmlsZV9wYXJhbXN9fXt7L2ZpbGVfcGFyYW1zLjB9fSkgPT4ge3sjc25ha2VDYXNlfX17e3tuYW1lfX19e3svc25ha2VDYXNlfX0ub25SZXF1ZXN0KGNvbnRleHQse3sjZGlyZWN0b3J5X3BhcmFtc319e3sufX0se3svZGlyZWN0b3J5X3BhcmFtc319e3sjZmlsZV9wYXJhbXN9fXt7Ln19LHt7L2ZpbGVfcGFyYW1zfX0pKXt7L3dpbGRjYXJkfX17ey9maWxlc319OwogIHJldHVybiBwaXBlbGluZS5hZGRIYW5kbGVyKHJvdXRlcik7Cn0Ke3svZGlyZWN0b3JpZXN9fQo=", + "Ly8gR0VORVJBVEVEIENPREUgLSBETyBOT1QgTU9ESUZZIEJZIEhBTkQKLy8gaWdub3JlX2Zvcl9maWxlOiB0eXBlPWxpbnQsIGltcGxpY2l0X2R5bmFtaWNfbGlzdF9saXRlcmFsCgppbXBvcnQgJ2RhcnQ6aW8nOwoKaW1wb3J0ICdwYWNrYWdlOmRhcnRfZnJvZy9kYXJ0X2Zyb2cuZGFydCc7Cgp7eyNpbnZva2VDdXN0b21FbnRyeXBvaW50fX1pbXBvcnQgJy4uL21haW4uZGFydCcgYXMgZW50cnlwb2ludDt7ey9pbnZva2VDdXN0b21FbnRyeXBvaW50fX0Ke3sjcm91dGVzfX1pbXBvcnQgJ3t7e3BhdGh9fX0nIGFzIHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Owp7ey9yb3V0ZXN9fQp7eyNtaWRkbGV3YXJlfX1pbXBvcnQgJ3t7e3BhdGh9fX0nIGFzIHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Owp7ey9taWRkbGV3YXJlfX0Kdm9pZCBtYWluKCkgYXN5bmMgewogIGZpbmFsIGFkZHJlc3MgPSBJbnRlcm5ldEFkZHJlc3MudHJ5UGFyc2UoJ3t7e2hvc3R9fX0nKSA/PyBJbnRlcm5ldEFkZHJlc3MuYW55SVB2NjsKICBmaW5hbCBwb3J0ID0gaW50LnRyeVBhcnNlKFBsYXRmb3JtLmVudmlyb25tZW50WydQT1JUJ10gPz8gJ3t7e3BvcnR9fX0nKSA/PyB7e3twb3J0fX19O3t7I2ludm9rZUN1c3RvbUluaXR9fQogIGF3YWl0IGVudHJ5cG9pbnQuaW5pdChhZGRyZXNzLCBwb3J0KTt7ey9pbnZva2VDdXN0b21Jbml0fX0KICBob3RSZWxvYWQoKCkgPT4gY3JlYXRlU2VydmVyKGFkZHJlc3MsIHBvcnQpKTsKfQoKRnV0dXJlPEh0dHBTZXJ2ZXI+IGNyZWF0ZVNlcnZlcihJbnRlcm5ldEFkZHJlc3MgYWRkcmVzcywgaW50IHBvcnQpIHsKICBmaW5hbCBoYW5kbGVyID0gQ2FzY2FkZSgpe3sjc2VydmVTdGF0aWNGaWxlc319LmFkZChjcmVhdGVTdGF0aWNGaWxlSGFuZGxlcigpKXt7L3NlcnZlU3RhdGljRmlsZXN9fS5hZGQoYnVpbGRSb290SGFuZGxlcigpKS5oYW5kbGVyOwogIHt7I2ludm9rZUN1c3RvbUVudHJ5cG9pbnR9fXJldHVybiBlbnRyeXBvaW50LnJ1bihoYW5kbGVyLCBhZGRyZXNzLCBwb3J0KTt7ey9pbnZva2VDdXN0b21FbnRyeXBvaW50fX17e15pbnZva2VDdXN0b21FbnRyeXBvaW50fX1yZXR1cm4gc2VydmUoaGFuZGxlciwgYWRkcmVzcywgcG9ydCk7e3svaW52b2tlQ3VzdG9tRW50cnlwb2ludH19Cn0KCkhhbmRsZXIgYnVpbGRSb290SGFuZGxlcigpIHsKICBmaW5hbCBwaXBlbGluZSA9IGNvbnN0IFBpcGVsaW5lKCl7eyNnbG9iYWxNaWRkbGV3YXJlfX0uYWRkTWlkZGxld2FyZSh7eyNzbmFrZUNhc2V9fXt7e25hbWV9fX17ey9zbmFrZUNhc2V9fS5taWRkbGV3YXJlKXt7L2dsb2JhbE1pZGRsZXdhcmV9fTsKICBmaW5hbCByb3V0ZXIgPSBSb3V0ZXIoKXt7I2RpcmVjdG9yaWVzfX0KICAgIC4ubW91bnQoJ3t7e3JvdXRlfX19JywgKGNvbnRleHR7eyNkaXJlY3RvcnlfcGFyYW1zLjB9fSx7eyNkaXJlY3RvcnlfcGFyYW1zfX17ey59fSx7ey9kaXJlY3RvcnlfcGFyYW1zfX17ey9kaXJlY3RvcnlfcGFyYW1zLjB9fSkgPT4gYnVpbGR7eyNwYXNjYWxDYXNlfX17e3tuYW1lfX19e3svcGFzY2FsQ2FzZX19SGFuZGxlcih7eyNkaXJlY3RvcnlfcGFyYW1zfX17ey59fSx7ey9kaXJlY3RvcnlfcGFyYW1zfX0pKGNvbnRleHQpKXt7L2RpcmVjdG9yaWVzfX07CiAgcmV0dXJuIHBpcGVsaW5lLmFkZEhhbmRsZXIocm91dGVyKTsKfQp7eyNkaXJlY3Rvcmllc319CkhhbmRsZXIgYnVpbGR7eyNwYXNjYWxDYXNlfX17e3tuYW1lfX19e3svcGFzY2FsQ2FzZX19SGFuZGxlcih7eyNkaXJlY3RvcnlfcGFyYW1zfX1TdHJpbmcge3sufX0se3svZGlyZWN0b3J5X3BhcmFtc319KSB7CiAgZmluYWwgcGlwZWxpbmUgPSBjb25zdCBQaXBlbGluZSgpe3sjbWlkZGxld2FyZS4wfX17eyNtaWRkbGV3YXJlfX0uYWRkTWlkZGxld2FyZSh7eyNzbmFrZUNhc2V9fXt7e25hbWV9fX17ey9zbmFrZUNhc2V9fS5taWRkbGV3YXJlKXt7L21pZGRsZXdhcmV9fXt7L21pZGRsZXdhcmUuMH19OwogIGZpbmFsIHJvdXRlciA9IFJvdXRlcigpCiAgICB7eyNmaWxlc319e3sjd2lsZGNhcmR9fS4ubW91bnQoJ3t7e3JvdXRlfX19JywgKGNvbnRleHQpID0+IHt7I3NuYWtlQ2FzZX19e3t7bmFtZX19fXt7L3NuYWtlQ2FzZX19Lm9uUmVxdWVzdChjb250ZXh0LGNvbnRleHQucmVxdWVzdC51cmwucGF0aCkpe3svd2lsZGNhcmR9fXt7XndpbGRjYXJkfX0uLmFsbCgne3t7cm91dGV9fX0nLCAoY29udGV4dHt7I2ZpbGVfcGFyYW1zLjB9fSx7eyNmaWxlX3BhcmFtc319e3sufX0se3svZmlsZV9wYXJhbXN9fXt7L2ZpbGVfcGFyYW1zLjB9fSkgPT4ge3sjc25ha2VDYXNlfX17e3tuYW1lfX19e3svc25ha2VDYXNlfX0ub25SZXF1ZXN0KGNvbnRleHQse3sjZGlyZWN0b3J5X3BhcmFtc319e3sufX0se3svZGlyZWN0b3J5X3BhcmFtc319e3sjZmlsZV9wYXJhbXN9fXt7Ln19LHt7L2ZpbGVfcGFyYW1zfX0pKXt7L3dpbGRjYXJkfX17ey9maWxlc319OwogIHJldHVybiBwaXBlbGluZS5hZGRIYW5kbGVyKHJvdXRlcik7Cn0Ke3svZGlyZWN0b3JpZXN9fQo=", "type": "text" }, { diff --git a/packages/dart_frog_cli/lib/src/prod_server_builder/prod_server_builder.dart b/packages/dart_frog_cli/lib/src/prod_server_builder/prod_server_builder.dart index 34c5d387f..7c3df886f 100644 --- a/packages/dart_frog_cli/lib/src/prod_server_builder/prod_server_builder.dart +++ b/packages/dart_frog_cli/lib/src/prod_server_builder/prod_server_builder.dart @@ -8,6 +8,7 @@ import 'package:meta/meta.dart'; typedef ProdServerBuilderConstructor = ProdServerBuilder Function({ required Logger logger, required String dartVersion, + required String port, required io.Directory workingDirectory, required MasonGenerator prodServerBundleGenerator, }); @@ -28,6 +29,7 @@ class ProdServerBuilder { required this.dartVersion, required this.workingDirectory, required this.prodServerBundleGenerator, + this.port = '8080', @visibleForTesting RuntimeCompatibilityCallback? runtimeCompatibilityCallback, }) : _ensureRuntimeCompatibility = @@ -36,6 +38,9 @@ class ProdServerBuilder { /// The Dart SDK version used to build the Dockerfile. final String dartVersion; + /// The port number the server should start on. + final String port; + /// [Logger] instance used to wrap stdout. final Logger logger; @@ -51,15 +56,16 @@ class ProdServerBuilder { Future build() async { _ensureRuntimeCompatibility(workingDirectory); - var vars = { + final vars = { 'dartVersion': dartVersion, + 'port': port, }; logger.detail('[codegen] running pre-gen...'); await prodServerBundleGenerator.hooks.preGen( vars: vars, workingDirectory: workingDirectory.path, - onVarsChanged: (v) => vars = v, + onVarsChanged: (v) => vars..addAll(v), ); logger.detail('[codegen] running generate...'); diff --git a/packages/dart_frog_cli/test/src/commands/build/build_test.dart b/packages/dart_frog_cli/test/src/commands/build/build_test.dart index 3a5aa3f79..6b55187d6 100644 --- a/packages/dart_frog_cli/test/src/commands/build/build_test.dart +++ b/packages/dart_frog_cli/test/src/commands/build/build_test.dart @@ -57,6 +57,7 @@ void main() { prodServerBuilderConstructor: ({ required Logger logger, required String dartVersion, + required String port, required Directory workingDirectory, required MasonGenerator prodServerBundleGenerator, }) { @@ -87,6 +88,7 @@ void main() { prodServerBuilderConstructor: ({ required Logger logger, required String dartVersion, + required String port, required Directory workingDirectory, required MasonGenerator prodServerBundleGenerator, }) => diff --git a/packages/dart_frog_cli/test/src/prod_server_builder/prod_server_builder_test.dart b/packages/dart_frog_cli/test/src/prod_server_builder/prod_server_builder_test.dart index f90a9c215..c9f667ec3 100644 --- a/packages/dart_frog_cli/test/src/prod_server_builder/prod_server_builder_test.dart +++ b/packages/dart_frog_cli/test/src/prod_server_builder/prod_server_builder_test.dart @@ -64,19 +64,19 @@ void main() { final generatorHooks = _MockGeneratorHooks(); when( () => generatorHooks.preGen( - vars: {'dartVersion': 'stable'}, + vars: {'dartVersion': 'stable', 'port': '8080'}, workingDirectory: any(named: 'workingDirectory'), onVarsChanged: any(named: 'onVarsChanged'), ), ).thenAnswer((invocation) async { (invocation.namedArguments[const Symbol('onVarsChanged')] as void Function(Map)) - .call({'dartVersion': 'stable'}); + .call({'dartVersion': 'stable', 'port': '8080'}); }); when( () => generator.generate( any(), - vars: {'dartVersion': 'stable'}, + vars: {'dartVersion': 'stable', 'port': '8080'}, fileConflictResolution: FileConflictResolution.overwrite, ), ).thenAnswer((_) async => []);