Skip to content

Commit

Permalink
Allow relative path-dependencies from git dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
sigurdm authored Mar 14, 2024
1 parent e08f720 commit c60b1a0
Show file tree
Hide file tree
Showing 19 changed files with 298 additions and 90 deletions.
10 changes: 8 additions & 2 deletions lib/src/command/add.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import '../solver.dart';
import '../source/git.dart';
import '../source/hosted.dart';
import '../source/path.dart';
import '../source/root.dart';
import '../utils.dart';

/// Handles the `add` pub command. Adds a dependency to `pubspec.yaml` and gets
Expand Down Expand Up @@ -272,6 +273,7 @@ Specify multiple sdk packages with descriptors.''');
location: Uri.parse(entrypoint.pubspecPath),
overridesFileContents: overridesFileContents,
overridesLocation: Uri.file(overridesPath),
containingDescription: RootDescription(entrypoint.rootDir),
),
)
.acquireDependencies(
Expand Down Expand Up @@ -547,7 +549,11 @@ Specify multiple sdk packages with descriptors.''');
PathDescription(p.absolute(path), p.isRelative(path)),
);
} else if (argResults.sdk != null) {
ref = cache.sdk.parseRef(packageName, argResults.sdk);
ref = cache.sdk.parseRef(
packageName,
argResults.sdk,
containingDescription: RootDescription(p.current),
);
} else {
ref = PackageRef(
packageName,
Expand Down Expand Up @@ -634,7 +640,7 @@ Specify multiple sdk packages with descriptors.''');
},
cache.sources,
// Resolve relative paths relative to current, not where the pubspec.yaml is.
location: p.toUri(p.join(p.current, 'descriptor')),
containingDescription: RootDescription(p.current),
);
} on FormatException catch (e) {
usageException('Failed parsing package specification: ${e.message}');
Expand Down
2 changes: 2 additions & 0 deletions lib/src/command/dependency_services.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import '../solver.dart';
import '../solver/version_solver.dart';
import '../source/git.dart';
import '../source/hosted.dart';
import '../source/root.dart';
import '../system_cache.dart';
import '../utils.dart';

Expand Down Expand Up @@ -450,6 +451,7 @@ class DependencyServicesApplyCommand extends PubCommand {
updatedPubspec,
cache.sources,
location: toUri(entrypoint.pubspecPath),
containingDescription: RootDescription(entrypoint.rootDir),
),
entrypoint.rootDir,
entrypoint.root.workspaceChildren,
Expand Down
3 changes: 3 additions & 0 deletions lib/src/command/lish.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'dart:io';
import 'dart:typed_data';

import 'package:http/http.dart' as http;
import 'package:path/path.dart' as p;

import '../ascii_tree.dart' as tree;
import '../authentication/client.dart';
Expand All @@ -22,6 +23,7 @@ import '../oauth2.dart' as oauth2;
import '../pubspec.dart';
import '../solver/type.dart';
import '../source/hosted.dart' show validateAndNormalizeHostedUrl;
import '../source/root.dart';
import '../utils.dart';
import '../validator.dart';

Expand Down Expand Up @@ -346,6 +348,7 @@ the \$PUB_HOSTED_URL environment variable.''',
),
),
cache.sources,
containingDescription: RootDescription(p.dirname(archive)),
);
} on FormatException catch (e) {
dataError('Failed to read pubspec.yaml from archive: ${e.message}');
Expand Down
2 changes: 2 additions & 0 deletions lib/src/command/unpack.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import '../pubspec.dart';
import '../sdk.dart';
import '../solver/type.dart';
import '../source/hosted.dart';
import '../source/root.dart';
import '../utils.dart';

class UnpackCommand extends PubCommand {
Expand Down Expand Up @@ -182,6 +183,7 @@ in a directory `foo-<version>`.
cache.sources,
// Resolve relative paths relative to current, not where the pubspec.yaml is.
location: p.toUri(p.join(p.current, 'descriptor')),
containingDescription: RootDescription('.'),
);
} on FormatException catch (e) {
usageException('Failed parsing package specification: ${e.message}');
Expand Down
2 changes: 2 additions & 0 deletions lib/src/command/upgrade.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import '../pubspec_utils.dart';
import '../sdk.dart';
import '../solver.dart';
import '../source/hosted.dart';
import '../source/root.dart';
import '../utils.dart';

/// Handles the `upgrade` pub command.
Expand Down Expand Up @@ -399,6 +400,7 @@ be direct 'dependencies' or 'dev_dependencies', following packages are not:
location: Uri.parse(entrypoint.pubspecPath),
overridesFileContents: overridesFileContents,
overridesLocation: Uri.file(overridesPath),
containingDescription: RootDescription(entrypoint.rootDir),
);
}

Expand Down
3 changes: 2 additions & 1 deletion lib/src/global_packages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import 'source/cached.dart';
import 'source/git.dart';
import 'source/hosted.dart';
import 'source/path.dart';
import 'source/root.dart';
import 'system_cache.dart';
import 'utils.dart';

Expand Down Expand Up @@ -113,7 +114,7 @@ class GlobalPackages {
if (path != null) 'path': path,
if (ref != null) 'ref': ref,
},
containingDir: '.',
containingDescription: RootDescription(p.current),
);
} on FormatException catch (e) {
throw ApplicationException(e.message);
Expand Down
2 changes: 2 additions & 0 deletions lib/src/package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'io.dart';
import 'log.dart' as log;
import 'package_name.dart';
import 'pubspec.dart';
import 'source/root.dart';
import 'system_cache.dart';
import 'utils.dart';

Expand Down Expand Up @@ -134,6 +135,7 @@ class Package {
sources,
expectedName: name,
allowOverridesFile: withPubspecOverrides,
containingDescription: RootDescription(dir),
);
final workspacePackages = pubspec.workspace
.map((e) => Package.load(null, p.join(dir, e), sources))
Expand Down
42 changes: 20 additions & 22 deletions lib/src/pubspec.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import 'language_version.dart';
import 'package_name.dart';
import 'pubspec_parse.dart';
import 'sdk.dart';
import 'source.dart';
import 'source/root.dart';
import 'system_cache.dart';

export 'pubspec_parse.dart' hide PubspecBase;
Expand Down Expand Up @@ -58,11 +60,9 @@ class Pubspec extends PubspecBase {
/// This will be null if this was created using [Pubspec] or [Pubspec.empty].
final SourceRegistry _sources;

/// The location from which the pubspec was loaded.
///
/// This can be null if the pubspec was created in-memory or if its location
/// is unknown.
Uri? get _location => fields.span.sourceUrl;
/// It is used to resolve relative paths. And to resolve path-descriptions
/// from a git dependency as git-descriptions.
final Description _containingDescription;

/// Directories of packages that should resolve together with this package.
late List<String> workspace = () {
Expand Down Expand Up @@ -118,7 +118,7 @@ class Pubspec extends PubspecBase {
_sources,
languageVersion,
_packageName,
_location,
_containingDescription,
);

Map<String, PackageRange>? _dependencies;
Expand All @@ -131,7 +131,7 @@ class Pubspec extends PubspecBase {
_sources,
languageVersion,
_packageName,
_location,
_containingDescription,
);

Map<String, PackageRange>? _devDependencies;
Expand Down Expand Up @@ -163,7 +163,7 @@ class Pubspec extends PubspecBase {
_sources,
languageVersion,
_packageName,
_location,
_containingDescription,
fileType: _FileType.pubspecOverrides,
);
}
Expand All @@ -174,7 +174,7 @@ class Pubspec extends PubspecBase {
_sources,
languageVersion,
_packageName,
_location,
_containingDescription,
);
}

Expand Down Expand Up @@ -263,6 +263,7 @@ class Pubspec extends PubspecBase {
SourceRegistry sources, {
String? expectedName,
bool allowOverridesFile = false,
required Description containingDescription,
}) {
var pubspecPath = path.join(packageDir, pubspecYamlFilename);
var overridesPath = path.join(packageDir, pubspecOverridesFilename);
Expand All @@ -287,6 +288,7 @@ class Pubspec extends PubspecBase {
location: path.toUri(pubspecPath),
overridesFileContents: overridesFileContents,
overridesLocation: path.toUri(overridesPath),
containingDescription: containingDescription,
);
}

Expand Down Expand Up @@ -316,6 +318,9 @@ class Pubspec extends PubspecBase {
_sources = sources ??
((String? name) => throw StateError('No source registry given')),
_overridesFileFields = null,
// This is a dummy value.
// Dependencies should already be resolved, so we never need to do relative resolutions.
_containingDescription = RootDescription('.'),
super(
fields == null ? YamlMap() : YamlMap.wrap(fields),
name: name,
Expand All @@ -335,11 +340,13 @@ class Pubspec extends PubspecBase {
YamlMap? overridesFields,
String? expectedName,
Uri? location,
required Description containingDescription,
}) : _overridesFileFields = overridesFields,
_includeDefaultSdkConstraint = true,
_givenSdkConstraints = null,
dependencyOverridesFromOverridesFile = overridesFields != null &&
overridesFields.containsKey('dependency_overrides'),
_containingDescription = containingDescription,
super(
fields is YamlMap
? fields
Expand Down Expand Up @@ -368,6 +375,7 @@ class Pubspec extends PubspecBase {
Uri? location,
String? overridesFileContents,
Uri? overridesLocation,
required Description containingDescription,
}) {
late final YamlMap pubspecMap;
YamlMap? overridesFileMap;
Expand All @@ -388,6 +396,7 @@ class Pubspec extends PubspecBase {
overridesFields: overridesFileMap,
expectedName: expectedName,
location: location,
containingDescription: containingDescription,
);
}

Expand Down Expand Up @@ -484,7 +493,7 @@ Map<String, PackageRange> _parseDependencies(
SourceRegistry sources,
LanguageVersion languageVersion,
String? packageName,
Uri? location, {
Description containingDescription, {
_FileType fileType = _FileType.pubspec,
}) {
var dependencies = <String, PackageRange>{};
Expand Down Expand Up @@ -568,15 +577,10 @@ Map<String, PackageRange> _parseDependencies(
'description',
descriptionNode?.span,
() {
String? pubspecDir;
if (location != null && _isFileUri(location)) {
pubspecDir = path.dirname(path.fromUri(location));
}

return sources(sourceName).parseRef(
name,
descriptionNode?.value,
containingDir: pubspecDir,
containingDescription: containingDescription,
languageVersion: languageVersion,
);
},
Expand All @@ -592,12 +596,6 @@ Map<String, PackageRange> _parseDependencies(
return dependencies;
}

/// Returns whether [uri] is a file URI.
///
/// This is slightly more complicated than just checking if the scheme is
/// 'file', since relative URIs also refer to the filesystem on the VM.
bool _isFileUri(Uri uri) => uri.scheme == 'file' || uri.scheme == '';

/// Parses [node] to a [VersionConstraint].
///
/// If or [defaultUpperBoundConstraint] is specified then it will be set as the
Expand Down
8 changes: 3 additions & 5 deletions lib/src/source.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ abstract class Source {
/// hosted dependencies like `foo:` or `foo: ^1.2.3`, the [description] may
/// also be `null`.
///
/// [containingDir] is the path to the directory of the pubspec where this
/// description appears. It may be `null` if the description is coming from
/// some in-memory source (such as pulling down a pubspec from
/// pub.dev).
/// [containingDescription] describes the location of the pubspec where this
/// description appears.
///
/// [languageVersion] is the minimum Dart version parsed from the pubspec's
/// `environment` field. Source implementations may use this parameter to only
Expand All @@ -81,7 +79,7 @@ abstract class Source {
PackageRef parseRef(
String name,
Object? description, {
String? containingDir,
required Description containingDescription,
required LanguageVersion languageVersion,
});

Expand Down
7 changes: 6 additions & 1 deletion lib/src/source/cached.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ abstract class CachedSource extends Source {
Future<Pubspec> doDescribe(PackageId id, SystemCache cache) async {
var packageDir = getDirectoryInCache(id, cache);
if (fileExists(path.join(packageDir, 'pubspec.yaml'))) {
return Pubspec.load(packageDir, cache.sources, expectedName: id.name);
return Pubspec.load(
packageDir,
cache.sources,
expectedName: id.name,
containingDescription: id.description.description,
);
}

return await describeUncached(id, cache);
Expand Down
Loading

0 comments on commit c60b1a0

Please sign in to comment.