in lib/src/command/add.dart [297:435]
_ParseResult _parsePackage(String package, LanguageVersion languageVersion) {
final _conflictingFlagSets = [
['git-url', 'git-ref', 'git-path'],
['hosted-url'],
['path'],
['sdk'],
];
for (final flag
in _conflictingFlagSets.expand((s) => s).where(argResults.wasParsed)) {
final conflictingFlag = _conflictingFlagSets
.where((s) => !s.contains(flag))
.expand((s) => s)
.firstWhereOrNull(argResults.wasParsed);
if (conflictingFlag != null) {
usageException(
'Packages can only have one source, "pub add" flags "--$flag" and '
'"--$conflictingFlag" are conflicting.');
}
}
/// The package to be added, along with the user-defined package constraints
/// if present.
PackageRange packageRange;
/// The entry to be added to the pubspec. Assigned dynamic because it can
/// take on either a string for simple version constraints or a map for
/// more complicated hosted/git options.
dynamic pubspecInformation;
final splitPackage = package.split(':');
final packageName = splitPackage[0];
/// There shouldn't be more than one `:` in the package information
if (splitPackage.length > 2) {
usageException('Invalid package and version constraint: $package');
}
/// We want to allow for [constraint] to take on a `null` value here to
/// preserve the fact that the user did not specify a constraint.
VersionConstraint? constraint;
try {
constraint = splitPackage.length == 2
? VersionConstraint.parse(splitPackage[1])
: null;
} on FormatException catch (e) {
usageException('Invalid version constraint: ${e.message}');
}
/// Determine the relevant [packageRange] and [pubspecInformation] depending
/// on the type of package.
var path = this.path;
if (hasGitOptions) {
dynamic git;
if (gitUrl == null) {
usageException('The `--git-url` is required for git dependencies.');
}
Uri parsed;
try {
parsed = Uri.parse(gitUrl!);
} on FormatException catch (e) {
usageException('The --git-url must be a valid url: ${e.message}.');
}
final urlRelativeToEntrypoint = parsed.isAbsolute
? parsed.toString()
:
// Turn the relative url from current working directory into a relative
// url from the entrypoint.
p.url.relative(
p.url.join(Uri.file(p.absolute(p.current)).toString(),
parsed.toString()),
from: p.toUri(p.absolute(entrypoint.root.dir)).toString());
/// Process the git options to return the simplest representation to be
/// added to the pubspec.
if (gitRef == null && gitPath == null) {
git = urlRelativeToEntrypoint;
} else {
git = {'url': urlRelativeToEntrypoint, 'ref': gitRef, 'path': gitPath};
git.removeWhere((key, value) => value == null);
}
packageRange = cache.sources.git
.parseRef(packageName, git, containingPath: entrypoint.pubspecPath)
.withConstraint(constraint ?? VersionConstraint.any);
pubspecInformation = {'git': git};
} else if (path != null) {
final relativeToEntryPoint = p.isRelative(path)
? PathSource.relativePathWithPosixSeparators(
p.relative(path, from: entrypoint.root.dir))
: path;
packageRange = cache.sources.path
.parseRef(packageName, relativeToEntryPoint,
containingPath: entrypoint.pubspecPath)
.withConstraint(constraint ?? VersionConstraint.any);
pubspecInformation = {'path': relativeToEntryPoint};
} else if (sdk != null) {
packageRange = cache.sources.sdk
.parseRef(packageName, sdk)
.withConstraint(constraint ?? VersionConstraint.any);
pubspecInformation = {'sdk': sdk};
} else {
// Hosted
final Object? hostInfo;
if (hasHostOptions) {
hostInfo = languageVersion.supportsShorterHostedSyntax
? hostUrl
: {'url': hostUrl, 'name': packageName};
pubspecInformation = {
'hosted': hostInfo,
};
} else {
hostInfo = null;
pubspecInformation = constraint?.toString();
}
packageRange = cache.hosted.source
.parseRef(
packageName,
hostInfo,
languageVersion: entrypoint.root.pubspec.languageVersion,
)
.withConstraint(constraint ?? VersionConstraint.any);
}
if (pubspecInformation is Map && constraint != null) {
/// We cannot simply assign the value of version since it is likely that
/// [pubspecInformation] takes on the type
/// [Map<String, Map<String, String>>]
pubspecInformation = {
...pubspecInformation,
'version': constraint.toString()
};
}
return _ParseResult(packageRange, pubspecInformation);
}