diff --git a/bricks/dart_frog_prod_server/hooks/lib/dart_frog_prod_server_hooks.dart b/bricks/dart_frog_prod_server/hooks/lib/dart_frog_prod_server_hooks.dart index f16808f88..a1494eb95 100644 --- a/bricks/dart_frog_prod_server/hooks/lib/dart_frog_prod_server_hooks.dart +++ b/bricks/dart_frog_prod_server/hooks/lib/dart_frog_prod_server_hooks.dart @@ -10,6 +10,7 @@ export 'src/get_package_graph.dart'; export 'src/get_pubspec_lock.dart'; export 'src/get_workspace_root.dart'; export 'src/package_graph/package_graph.dart'; +export 'src/path_dependency.dart'; export 'src/uses_workspace_resolution.dart'; /// A void callback function (e.g. `void Function()`). diff --git a/bricks/dart_frog_prod_server/hooks/lib/src/create_external_packages_folder.dart b/bricks/dart_frog_prod_server/hooks/lib/src/create_external_packages_folder.dart index 6bf3bec91..52ab775f0 100644 --- a/bricks/dart_frog_prod_server/hooks/lib/src/create_external_packages_folder.dart +++ b/bricks/dart_frog_prod_server/hooks/lib/src/create_external_packages_folder.dart @@ -27,13 +27,13 @@ Future> createExternalPackagesFolder({ final isExternal = !pathResolver.isWithin('', pathDescription.path); if (!isExternal) return null; - return _ExternalPathDependency( + return ExternalPathDependency( name: dependency.name, path: path.join(projectDirectory.path, pathDescription.path), ); }, ) - .whereType<_ExternalPathDependency>() + .whereType() .toList(); if (externalPathDependencies.isEmpty) return []; @@ -63,59 +63,13 @@ Future> createExternalPackagesFolder({ ), ); - File( - pathResolver.join(buildDirectory.path, 'pubspec_overrides.yaml'), - ).writeAsStringSync( - ''' -resolution: null -dependency_overrides: -${copiedExternalPathDependencies.map( - (dependency) { - final name = dependency.name; - final path = - pathResolver.relative(dependency.path, from: buildDirectory.path); - return ' $name:\n path: $path'; - }, - ).join('\n')} -''', + overrideResolutionInPubspecOverrides(buildDirectory.path); + writePathDependencyOverrides( + projectDirectory: buildDirectory.path, + pathDependencies: copiedExternalPathDependencies, ); return copiedExternalPathDependencies .map((dependency) => dependency.path) .toList(); } - -/// {@template external_path_dependency} -/// A path dependency that is not within the bundled Dart Frog project -/// directory. -/// -/// For example: -/// ```yaml -/// name: my_dart_frog_project -/// dependencies: -/// my_package: -/// path: ../my_package -/// ``` -/// {@endtemplate} -class _ExternalPathDependency { - /// {@macro external_path_dependency} - const _ExternalPathDependency({ - required this.name, - required this.path, - }); - - /// The name of the package. - final String name; - - /// The absolute path to the package. - final String path; - - /// Copies the [_ExternalPathDependency] to [targetDirectory]. - Future<_ExternalPathDependency> copyTo({ - required Directory targetDirectory, - CopyPath copyPath = io.copyPath, - }) async { - await copyPath(path, targetDirectory.path); - return _ExternalPathDependency(name: name, path: targetDirectory.path); - } -} diff --git a/bricks/dart_frog_prod_server/hooks/lib/src/disable_workspace_resolution.dart b/bricks/dart_frog_prod_server/hooks/lib/src/disable_workspace_resolution.dart index 4e3376b60..170ff079c 100644 --- a/bricks/dart_frog_prod_server/hooks/lib/src/disable_workspace_resolution.dart +++ b/bricks/dart_frog_prod_server/hooks/lib/src/disable_workspace_resolution.dart @@ -86,9 +86,9 @@ void overridePathDependenciesInPubspecOverrides({ packageGraph: packageGraph, ); - final pathDependencies = packageConfig.packages.where( - (package) => package.relativeRoot && productionDeps.contains(package.name), - ); + final pathDependencies = packageConfig.packages + .where((p) => p.relativeRoot && productionDeps.contains(p.name)) + .map((p) => PathDependency(name: p.name, path: p.root.path)); writePathDependencyOverrides( projectDirectory: projectDirectory, @@ -98,7 +98,7 @@ void overridePathDependenciesInPubspecOverrides({ void writePathDependencyOverrides({ required String projectDirectory, - required Iterable pathDependencies, + required Iterable pathDependencies, }) { final pubspecOverridesFile = File( path.join(projectDirectory, 'pubspec_overrides.yaml'), @@ -112,7 +112,7 @@ void writePathDependencyOverrides({ for (final package in pathDependencies) { editor.update( ['dependency_overrides', package.name], - {'path': path.relative(package.root.path, from: projectDirectory)}, + {'path': path.relative(package.path, from: projectDirectory)}, ); } pubspecOverridesFile.writeAsStringSync(editor.toString()); diff --git a/bricks/dart_frog_prod_server/hooks/lib/src/path_dependency.dart b/bricks/dart_frog_prod_server/hooks/lib/src/path_dependency.dart new file mode 100644 index 000000000..0f2dcaa85 --- /dev/null +++ b/bricks/dart_frog_prod_server/hooks/lib/src/path_dependency.dart @@ -0,0 +1,52 @@ +import 'dart:io'; + +import 'package:dart_frog_prod_server_hooks/dart_frog_prod_server_hooks.dart'; +import 'package:io/io.dart' as io; + +/// {@template path_dependency} +/// A path dependency that the Dart Frog project relies on. +/// +/// For example: +/// ```yaml +/// name: my_dart_frog_project +/// dependencies: +/// my_package: +/// path: ./my_package +/// ``` +/// {@endtemplate} +class PathDependency { + /// {@macro path_dependency} + const PathDependency({required this.name, required this.path}); + + /// The name of the package. + final String name; + + /// The absolute path to the package. + final String path; +} + +/// {@template external_path_dependency} +/// A path dependency that is not within the bundled Dart Frog project +/// directory. +/// +/// For example: +/// ```yaml +/// name: my_dart_frog_project +/// dependencies: +/// my_package: +/// path: ../my_package +/// ``` +/// {@endtemplate} +class ExternalPathDependency extends PathDependency { + /// {@macro external_path_dependency} + const ExternalPathDependency({required super.name, required super.path}); + + /// Copies the [ExternalPathDependency] to [targetDirectory]. + Future copyTo({ + required Directory targetDirectory, + CopyPath copyPath = io.copyPath, + }) async { + await copyPath(path, targetDirectory.path); + return ExternalPathDependency(name: name, path: targetDirectory.path); + } +} diff --git a/bricks/dart_frog_prod_server/hooks/test/src/create_external_packages_folder_test.dart b/bricks/dart_frog_prod_server/hooks/test/src/create_external_packages_folder_test.dart index dd14e05ad..2b5dd5154 100644 --- a/bricks/dart_frog_prod_server/hooks/test/src/create_external_packages_folder_test.dart +++ b/bricks/dart_frog_prod_server/hooks/test/src/create_external_packages_folder_test.dart @@ -75,5 +75,51 @@ void main() { ); expect(copyCalls, ['$from -> $to']); }); + + test("doesn't overwrite existing overrides", () async { + const existingOverrides = ''' +dependency_overrides: + dart_frog: + git: + url: https://github.com/dart-frog-dev/dart_frog + path: packages/dart_frog +'''; + final projectDirectory = Directory.systemTemp.createTempSync(); + File( + path.join(projectDirectory.path, 'build', 'pubspec_overrides.yaml'), + ) + ..createSync(recursive: true) + ..writeAsStringSync(existingOverrides); + File( + path.join(projectDirectory.path, 'pubspec.lock'), + ).writeAsStringSync(fooPathWithInternalDependency); + final copyCalls = []; + + await createExternalPackagesFolder( + projectDirectory: projectDirectory, + buildDirectory: Directory(path.join(projectDirectory.path, 'build')), + copyPath: (from, to) async { + copyCalls.add('$from -> $to'); + File( + path.join(to, 'pubspec_overrides.yaml'), + ).createSync(recursive: true); + }, + ); + + final from = path.join(projectDirectory.path, '../../foo'); + final to = path.join( + projectDirectory.path, + 'build', + '.dart_frog_path_dependencies', + 'foo', + ); + expect(copyCalls, ['$from -> $to']); + expect( + File( + path.join(projectDirectory.path, 'build', 'pubspec_overrides.yaml'), + ).readAsStringSync(), + contains(existingOverrides), + ); + }); }); }