From d16281716d953e0cd6f2bbb3357b5d3e7f6a2927 Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Wed, 24 Aug 2022 11:37:50 -0300 Subject: [PATCH 1/6] adding an option to redirect all not found to a specific asset --- build_runner/lib/src/entrypoint/options.dart | 76 ++++++++++--------- build_runner/lib/src/entrypoint/serve.dart | 5 +- build_runner/lib/src/generate/build.dart | 4 +- build_runner/lib/src/generate/watch_impl.dart | 15 +++- build_runner/lib/src/server/server.dart | 25 +++++- .../test/server/serve_handler_test.dart | 19 ++++- 6 files changed, 99 insertions(+), 45 deletions(-) diff --git a/build_runner/lib/src/entrypoint/options.dart b/build_runner/lib/src/entrypoint/options.dart index f78a844cc..62dadc74c 100644 --- a/build_runner/lib/src/entrypoint/options.dart +++ b/build_runner/lib/src/entrypoint/options.dart @@ -26,6 +26,7 @@ const liveReloadOption = 'live-reload'; const logPerformanceOption = 'log-performance'; const logRequestsOption = 'log-requests'; const lowResourcesModeOption = 'low-resources-mode'; +const notFoundDefaultsToOption = 'not-found-defaults-to'; const outputOption = 'output'; const releaseOption = 'release'; const trackPerformanceOption = 'track-performance'; @@ -276,41 +277,45 @@ class ServeOptions extends WatchOptions { final bool logRequests; final List serveTargets; - ServeOptions._({ - required this.hostName, - required this.buildUpdates, - required this.logRequests, - required this.serveTargets, - required Set buildFilters, - required bool deleteFilesByDefault, - required bool enableLowResourcesMode, - required String? configKey, - required Set buildDirs, - required bool outputSymlinksOnly, - required bool trackPerformance, - required bool skipBuildScriptCheck, - required bool verbose, - required Map> builderConfigOverrides, - required bool isReleaseBuild, - required String? logPerformanceDir, - required bool usePollingWatcher, - required List enableExperiments, - }) : super._( - buildFilters: buildFilters, - deleteFilesByDefault: deleteFilesByDefault, - enableLowResourcesMode: enableLowResourcesMode, - configKey: configKey, - buildDirs: buildDirs, - outputSymlinksOnly: outputSymlinksOnly, - trackPerformance: trackPerformance, - skipBuildScriptCheck: skipBuildScriptCheck, - verbose: verbose, - builderConfigOverrides: builderConfigOverrides, - isReleaseBuild: isReleaseBuild, - logPerformanceDir: logPerformanceDir, - usePollingWatcher: usePollingWatcher, - enableExperiments: enableExperiments, - ); + // An [AssetId] path to redirect when the file is not found by + // the web server + final String? notFoundDefaultsTo; + + ServeOptions._( + {required this.hostName, + required this.buildUpdates, + required this.logRequests, + required this.serveTargets, + required Set buildFilters, + required bool deleteFilesByDefault, + required bool enableLowResourcesMode, + required String? configKey, + required Set buildDirs, + required bool outputSymlinksOnly, + required bool trackPerformance, + required bool skipBuildScriptCheck, + required bool verbose, + required Map> builderConfigOverrides, + required bool isReleaseBuild, + required String? logPerformanceDir, + required bool usePollingWatcher, + required List enableExperiments, + this.notFoundDefaultsTo}) + : super._( + buildFilters: buildFilters, + deleteFilesByDefault: deleteFilesByDefault, + enableLowResourcesMode: enableLowResourcesMode, + configKey: configKey, + buildDirs: buildDirs, + outputSymlinksOnly: outputSymlinksOnly, + trackPerformance: trackPerformance, + skipBuildScriptCheck: skipBuildScriptCheck, + verbose: verbose, + builderConfigOverrides: builderConfigOverrides, + isReleaseBuild: isReleaseBuild, + logPerformanceDir: logPerformanceDir, + usePollingWatcher: usePollingWatcher, + enableExperiments: enableExperiments); factory ServeOptions.fromParsedArgs(ArgResults argResults, Iterable positionalArgs, String rootPackage, Command command) { @@ -381,6 +386,7 @@ class ServeOptions extends WatchOptions { logPerformanceDir: argResults[logPerformanceOption] as String?, usePollingWatcher: argResults[usePollingWatcherOption] as bool, enableExperiments: argResults[enableExperimentOption] as List, + notFoundDefaultsTo: argResults[notFoundDefaultsToOption] as String?, ); } } diff --git a/build_runner/lib/src/entrypoint/serve.dart b/build_runner/lib/src/entrypoint/serve.dart index cfcc2d1d9..b401f4c65 100644 --- a/build_runner/lib/src/entrypoint/serve.dart +++ b/build_runner/lib/src/entrypoint/serve.dart @@ -31,7 +31,9 @@ class ServeCommand extends WatchCommand { ..addFlag(liveReloadOption, defaultsTo: false, negatable: false, - help: 'Enables automatic page reloading on rebuilds. '); + help: 'Enables automatic page reloading on rebuilds. ') + ..addOption(notFoundDefaultsToOption, + help: 'Redirect not found to a specific asset.'); } @override @@ -98,6 +100,7 @@ class ServeCommand extends WatchCommand { logPerformanceDir: options.logPerformanceDir, directoryWatcherFactory: options.directoryWatcherFactory, buildFilters: options.buildFilters, + notFoundDefaultsTo: options.notFoundDefaultsTo ); servers.forEach((target, server) { diff --git a/build_runner/lib/src/generate/build.dart b/build_runner/lib/src/generate/build.dart index 93391c439..abe13400b 100644 --- a/build_runner/lib/src/generate/build.dart +++ b/build_runner/lib/src/generate/build.dart @@ -165,7 +165,8 @@ Future watch(List builders, bool? isReleaseBuild, Map>? builderConfigOverrides, String? logPerformanceDir, - Set? buildFilters}) => + Set? buildFilters, + String? notFoundDefaultsTo}) => watch_impl.watch( builders, assumeTty: assumeTty, @@ -190,4 +191,5 @@ Future watch(List builders, isReleaseBuild: isReleaseBuild, logPerformanceDir: logPerformanceDir, buildFilters: buildFilters, + notFoundDefaultsTo: notFoundDefaultsTo ); diff --git a/build_runner/lib/src/generate/watch_impl.dart b/build_runner/lib/src/generate/watch_impl.dart index a85d307e2..59b40d617 100644 --- a/build_runner/lib/src/generate/watch_impl.dart +++ b/build_runner/lib/src/generate/watch_impl.dart @@ -55,6 +55,7 @@ Future watch( bool? isReleaseBuild, String? logPerformanceDir, Set? buildFilters, + String? notFoundDefaultsTo }) async { builderConfigOverrides ??= const {}; buildDirs ??= {}; @@ -105,7 +106,8 @@ Future watch( .any((target) => target.outputLocation?.path.isNotEmpty ?? false), buildDirs, buildFilters, - isReleaseMode: isReleaseBuild ?? false); + isReleaseMode: isReleaseBuild ?? false, + notFoundDefaultsTo: notFoundDefaultsTo); unawaited(watch.buildResults.drain().then((_) async { await terminator.cancel(); @@ -134,7 +136,8 @@ WatchImpl _runWatch( bool willCreateOutputDirs, Set buildDirs, Set buildFilters, - {bool isReleaseMode = false}) => + {bool isReleaseMode = false, + String? notFoundDefaultsTo}) => WatchImpl( options, environment, @@ -146,7 +149,8 @@ WatchImpl _runWatch( willCreateOutputDirs, buildDirs, buildFilters, - isReleaseMode: isReleaseMode); + isReleaseMode: isReleaseMode, + notFoundDefaultsTo: notFoundDefaultsTo); class WatchImpl implements BuildState { BuildImpl? _build; @@ -172,6 +176,9 @@ class WatchImpl implements BuildState { /// The [PackageGraph] for the current program. final PackageGraph packageGraph; + // An asset path to redirect when the file is not found by the web server + final String? notFoundDefaultsTo; + /// The directories to build upon file changes and where to output them. final Set _buildDirs; @@ -200,7 +207,7 @@ class WatchImpl implements BuildState { this._willCreateOutputDirs, this._buildDirs, this._buildFilters, - {bool isReleaseMode = false}) + {bool isReleaseMode = false, this.notFoundDefaultsTo}) : _debounceDelay = options.debounceDelay, packageGraph = options.packageGraph { buildResults = _run( diff --git a/build_runner/lib/src/server/server.dart b/build_runner/lib/src/server/server.dart index d2d28e8c8..01edc4286 100644 --- a/build_runner/lib/src/server/server.dart +++ b/build_runner/lib/src/server/server.dart @@ -47,8 +47,10 @@ ServeHandler createServeHandler(WatchImpl watch) { var rootPackage = watch.packageGraph.root.name; var assetGraphHanderCompleter = Completer(); var assetHandlerCompleter = Completer(); + watch.reader.then((reader) async { - assetHandlerCompleter.complete(AssetHandler(reader, rootPackage)); + assetHandlerCompleter.complete(AssetHandler(reader, rootPackage, + notFoundDefaultsTo: watch.notFoundDefaultsTo)); assetGraphHanderCompleter .complete(AssetGraphHandler(reader, rootPackage, watch.assetGraph!)); }).catchError((_) {}); // These errors are separately handled. @@ -300,10 +302,19 @@ window.\$dartLoader.forceLoadModule('packages/build_runner/src/server/build_upda class AssetHandler { final FinalizedReader _reader; final String _rootPackage; + late final AssetId _notFoundDefaultsTo; + late final bool _redirectNotFound; final _typeResolver = MimeTypeResolver(); - AssetHandler(this._reader, this._rootPackage); + AssetHandler(this._reader, this._rootPackage, {String? notFoundDefaultsTo}) { + _redirectNotFound = + notFoundDefaultsTo != null && notFoundDefaultsTo.isNotEmpty; + + if (_redirectNotFound) { + _notFoundDefaultsTo = AssetId(_rootPackage, notFoundDefaultsTo!); + } + } Future handle(shelf.Request request, {String rootDir = ''}) => (request.url.path.endsWith('/') || request.url.path.isEmpty) @@ -332,6 +343,16 @@ class AssetHandler { return shelf.Response.notFound( await _findDirectoryList(assetId)); } + + if (_redirectNotFound) { + final pathSegments = assetId.pathSegments; + + if (!pathSegments.contains('package') && + !pathSegments.contains('lib')) { + return _handle(request, _notFoundDefaultsTo); + } + } + return shelf.Response.notFound('Not Found'); default: return shelf.Response.notFound('Not Found'); diff --git a/build_runner/test/server/serve_handler_test.dart b/build_runner/test/server/serve_handler_test.dart index d4a7d1b92..6fc28b3e6 100644 --- a/build_runner/test/server/serve_handler_test.dart +++ b/build_runner/test/server/serve_handler_test.dart @@ -24,6 +24,7 @@ import 'package:web_socket_channel/web_socket_channel.dart'; void main() { late ServeHandler serveHandler; + late ServeHandler serveSpaHandler; late InMemoryRunnerAssetReader reader; late MockWatchImpl watchImpl; late AssetGraph assetGraph; @@ -38,6 +39,9 @@ void main() { packageGraph, assetGraph); serveHandler = createServeHandler(watchImpl); + + watchImpl.notFoundDefaultsTo = 'web/index.html'; + serveSpaHandler = createServeHandler(watchImpl); watchImpl .addFutureResult(Future.value(BuildResult(BuildStatus.success, []))); }); @@ -58,6 +62,13 @@ void main() { expect(await response.readAsString(), 'content'); }); + test('retrieve default asset when not found', () async { + _addSource('a|web/index.html', 'content'); + var response = await serveSpaHandler.handlerFor('web')( + Request('GET', Uri.parse('http://server.com/foo.html'))); + expect(await response.readAsString(), 'content'); + }); + test('caching with etags works', () async { _addSource('a|web/index.html', 'content'); var handler = serveHandler.handlerFor('web'); @@ -442,6 +453,9 @@ class MockWatchImpl implements WatchImpl { Future? _currentBuild; + @override + String? notFoundDefaultsTo; + @override Future? get currentBuild => _currentBuild; @override @@ -449,7 +463,7 @@ class MockWatchImpl implements WatchImpl { throw UnsupportedError('unsupported!'); final _futureBuildResultsController = StreamController>(); - final _buildResultsController = StreamController(); + final _buildResultsController = StreamController.broadcast(); @override Stream get buildResults => _buildResultsController.stream; @@ -467,7 +481,8 @@ class MockWatchImpl implements WatchImpl { _futureBuildResultsController.add(result); } - MockWatchImpl(this.reader, this.packageGraph, this.assetGraph) { + MockWatchImpl(this.reader, this.packageGraph, this.assetGraph, + {this.notFoundDefaultsTo}) { var firstBuild = Completer(); _currentBuild = firstBuild.future; _futureBuildResultsController.stream.listen((futureBuildResult) { From 768574cfb520fabccc04f5dbf83197992b68afb2 Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Wed, 24 Aug 2022 11:48:33 -0300 Subject: [PATCH 2/6] changelog entry --- build_runner/CHANGELOG.md | 5 +++++ build_runner/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md index 1ccd0ec99..dbf93da23 100644 --- a/build_runner/CHANGELOG.md +++ b/build_runner/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2.2.1-1-dev + + - Added a flag to redirect all not found to a specific + asset: not-found-defaults-to + ## 2.2.1-dev - Stop ignoring the no_leading_underscores_for_library_prefixes lint in diff --git a/build_runner/pubspec.yaml b/build_runner/pubspec.yaml index d469841dc..6969f8942 100644 --- a/build_runner/pubspec.yaml +++ b/build_runner/pubspec.yaml @@ -1,5 +1,5 @@ name: build_runner -version: 2.2.1-dev +version: 2.2.1-1-dev description: A build system for Dart code generation and modular compilation. repository: https://github.com/dart-lang/build/tree/master/build_runner From 7d998cc85681452582f1c5b5312a5cf02bdf9205 Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Wed, 24 Aug 2022 13:53:38 -0300 Subject: [PATCH 3/6] code review --- build_runner/lib/src/daemon/asset_server.dart | 2 +- build_runner/lib/src/entrypoint/options.dart | 2 +- build_runner/lib/src/server/server.dart | 28 +++++++++---------- .../test/server/asset_handler_test.dart | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/build_runner/lib/src/daemon/asset_server.dart b/build_runner/lib/src/daemon/asset_server.dart index 99f946c30..9bd710c80 100644 --- a/build_runner/lib/src/daemon/asset_server.dart +++ b/build_runner/lib/src/daemon/asset_server.dart @@ -34,7 +34,7 @@ class AssetServer { var cascade = Cascade().add((_) async { await builder.building; return Response.notFound(''); - }).add(AssetHandler(builder.reader, rootPackage).handle); + }).add(AssetHandler(builder.reader, rootPackage, null).handle); var pipeline = Pipeline(); if (options.logRequests) { diff --git a/build_runner/lib/src/entrypoint/options.dart b/build_runner/lib/src/entrypoint/options.dart index 62dadc74c..7d88ed3b8 100644 --- a/build_runner/lib/src/entrypoint/options.dart +++ b/build_runner/lib/src/entrypoint/options.dart @@ -300,7 +300,7 @@ class ServeOptions extends WatchOptions { required String? logPerformanceDir, required bool usePollingWatcher, required List enableExperiments, - this.notFoundDefaultsTo}) + required this.notFoundDefaultsTo}) : super._( buildFilters: buildFilters, deleteFilesByDefault: deleteFilesByDefault, diff --git a/build_runner/lib/src/server/server.dart b/build_runner/lib/src/server/server.dart index 01edc4286..7c24dd09c 100644 --- a/build_runner/lib/src/server/server.dart +++ b/build_runner/lib/src/server/server.dart @@ -49,8 +49,14 @@ ServeHandler createServeHandler(WatchImpl watch) { var assetHandlerCompleter = Completer(); watch.reader.then((reader) async { - assetHandlerCompleter.complete(AssetHandler(reader, rootPackage, - notFoundDefaultsTo: watch.notFoundDefaultsTo)); + final notFoundDefaultsToPath = watch.notFoundDefaultsTo; + final notFoundDefaultsTo = + notFoundDefaultsToPath != null && notFoundDefaultsToPath.isNotEmpty + ? AssetId(rootPackage, notFoundDefaultsToPath) + : null; + + assetHandlerCompleter + .complete(AssetHandler(reader, rootPackage, notFoundDefaultsTo)); assetGraphHanderCompleter .complete(AssetGraphHandler(reader, rootPackage, watch.assetGraph!)); }).catchError((_) {}); // These errors are separately handled. @@ -302,19 +308,11 @@ window.\$dartLoader.forceLoadModule('packages/build_runner/src/server/build_upda class AssetHandler { final FinalizedReader _reader; final String _rootPackage; - late final AssetId _notFoundDefaultsTo; - late final bool _redirectNotFound; + final AssetId? notFoundDefaultsTo; final _typeResolver = MimeTypeResolver(); - AssetHandler(this._reader, this._rootPackage, {String? notFoundDefaultsTo}) { - _redirectNotFound = - notFoundDefaultsTo != null && notFoundDefaultsTo.isNotEmpty; - - if (_redirectNotFound) { - _notFoundDefaultsTo = AssetId(_rootPackage, notFoundDefaultsTo!); - } - } + AssetHandler(this._reader, this._rootPackage, this.notFoundDefaultsTo); Future handle(shelf.Request request, {String rootDir = ''}) => (request.url.path.endsWith('/') || request.url.path.isEmpty) @@ -344,12 +342,14 @@ class AssetHandler { await _findDirectoryList(assetId)); } - if (_redirectNotFound) { + final notFoundDefaultsTo = this.notFoundDefaultsTo; + + if (notFoundDefaultsTo != null) { final pathSegments = assetId.pathSegments; if (!pathSegments.contains('package') && !pathSegments.contains('lib')) { - return _handle(request, _notFoundDefaultsTo); + return _handle(request, notFoundDefaultsTo); } } diff --git a/build_runner/test/server/asset_handler_test.dart b/build_runner/test/server/asset_handler_test.dart index 3de52a4f3..8b216b29c 100644 --- a/build_runner/test/server/asset_handler_test.dart +++ b/build_runner/test/server/asset_handler_test.dart @@ -25,7 +25,7 @@ void main() { buildPackageGraph({rootPackage('foo'): []}), FakeAssetReader()); delegate = InMemoryRunnerAssetReader(); reader = FinalizedReader(delegate, graph, [], 'a'); - handler = AssetHandler(reader, 'a'); + handler = AssetHandler(reader, 'a', null); }); void _addAsset(String id, String content, {bool deleted = false}) { From c160b74e3f8a1a2b648d0f2a68890afa0a8e66c8 Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Wed, 24 Aug 2022 13:58:59 -0300 Subject: [PATCH 4/6] code review changelog --- build_runner/CHANGELOG.md | 7 ++----- build_runner/pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md index dbf93da23..0ef753133 100644 --- a/build_runner/CHANGELOG.md +++ b/build_runner/CHANGELOG.md @@ -1,12 +1,9 @@ -## 2.2.1-1-dev - - - Added a flag to redirect all not found to a specific - asset: not-found-defaults-to - ## 2.2.1-dev - Stop ignoring the no_leading_underscores_for_library_prefixes lint in generated build scripts, code_builder now does this for you. +- Added a flag to redirect all not found to a specific + asset: ` not-found-defaults-to` ## 2.2.0 diff --git a/build_runner/pubspec.yaml b/build_runner/pubspec.yaml index 6969f8942..d469841dc 100644 --- a/build_runner/pubspec.yaml +++ b/build_runner/pubspec.yaml @@ -1,5 +1,5 @@ name: build_runner -version: 2.2.1-1-dev +version: 2.2.1-dev description: A build system for Dart code generation and modular compilation. repository: https://github.com/dart-lang/build/tree/master/build_runner From 37fef6939c5b133417a743d3221451b42e7aa67e Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Wed, 23 Nov 2022 16:15:12 -0300 Subject: [PATCH 5/6] changed the version --- build_runner/CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/build_runner/CHANGELOG.md b/build_runner/CHANGELOG.md index 30e3e96a7..f19d13968 100644 --- a/build_runner/CHANGELOG.md +++ b/build_runner/CHANGELOG.md @@ -8,17 +8,16 @@ - Upgrade to `frontend_service_client` version 3. -## 2.3.0 - +## 2.3.3-dev - Add `-d` as a shorthand for `--delete-conflicting-outputs`. +- Added a flag to redirect all not found to a specific + asset: ` not-found-defaults-to` ## 2.2.1 - Allow the latest `package:analyzer`. - Stop ignoring the no_leading_underscores_for_library_prefixes lint in generated build scripts, code_builder now does this for you. -- Added a flag to redirect all not found to a specific - asset: ` not-found-defaults-to` ## 2.2.0 From 6aafa880666fe3f77b3a79fff778f8f5bc39e9d5 Mon Sep 17 00:00:00 2001 From: Jonathan Rezende Date: Thu, 18 May 2023 17:15:28 -0300 Subject: [PATCH 6/6] t --- build_runner/lib/src/build_script_generate/bootstrap.dart | 1 + build_runner/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/build_runner/lib/src/build_script_generate/bootstrap.dart b/build_runner/lib/src/build_script_generate/bootstrap.dart index 5f4783178..78928dc1b 100644 --- a/build_runner/lib/src/build_script_generate/bootstrap.dart +++ b/build_runner/lib/src/build_script_generate/bootstrap.dart @@ -158,6 +158,7 @@ Future _createKernelIfNeeded(Logger logger) async { scriptKernelCachedLocation, 'lib/_internal/vm_platform_strong.dill', printIncrementalDependencies: false, + enabledExperiments: ['records', 'patterns', 'inline-class'] ); var hadOutput = false; diff --git a/build_runner/pubspec.yaml b/build_runner/pubspec.yaml index 036bd2a39..7d34efe0a 100644 --- a/build_runner/pubspec.yaml +++ b/build_runner/pubspec.yaml @@ -4,7 +4,7 @@ description: A build system for Dart code generation and modular compilation. repository: https://github.com/dart-lang/build/tree/master/build_runner environment: - sdk: ">=3.0.0-134.0.dev <4.0.0" + sdk: ">=3.0.0-263.0.dev <4.0.0" platforms: linux: