Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:io'; | 5 import 'dart:io'; |
| 6 | 6 |
| 7 import 'package:barback/barback.dart'; | 7 import 'package:barback/barback.dart'; |
| 8 import 'package:path/path.dart' as p; | 8 import 'package:path/path.dart' as p; |
| 9 import 'package:pub_semver/pub_semver.dart'; | 9 import 'package:pub_semver/pub_semver.dart'; |
| 10 | 10 |
| 11 import 'barback/transformer_id.dart'; | 11 import 'barback/transformer_id.dart'; |
| 12 import 'io.dart'; | 12 import 'io.dart'; |
| 13 import 'git.dart' as git; | 13 import 'git.dart' as git; |
| 14 import 'pubspec.dart'; | 14 import 'pubspec.dart'; |
| 15 import 'source_registry.dart'; | 15 import 'source_registry.dart'; |
| 16 import 'source.dart'; | |
| 16 import 'utils.dart'; | 17 import 'utils.dart'; |
| 17 | 18 |
| 18 final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false); | 19 final _README_REGEXP = new RegExp(r"^README($|\.)", caseSensitive: false); |
| 19 | 20 |
| 20 /// A named, versioned, unit of code and resource reuse. | 21 /// A named, versioned, unit of code and resource reuse. |
| 21 class Package { | 22 class Package { |
| 22 /// Compares [a] and [b] orders them by name then version number. | 23 /// Compares [a] and [b] orders them by name then version number. |
| 23 /// | 24 /// |
| 24 /// This is normally used as a [Comparator] to pass to sort. This does not | 25 /// This is normally used as a [Comparator] to pass to sort. This does not |
| 25 /// take a package's description or root directory into account, so multiple | 26 /// take a package's description or root directory into account, so multiple |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 | 314 |
| 314 // Re-write the paths so they're underneath the symlink. | 315 // Re-write the paths so they're underneath the symlink. |
| 315 return targetFiles.map((targetFile) => | 316 return targetFiles.map((targetFile) => |
| 316 p.join(link, p.relative(targetFile, from: target))); | 317 p.join(link, p.relative(targetFile, from: target))); |
| 317 } | 318 } |
| 318 | 319 |
| 319 /// Returns a debug string for the package. | 320 /// Returns a debug string for the package. |
| 320 String toString() => '$name $version ($dir)'; | 321 String toString() => '$name $version ($dir)'; |
| 321 } | 322 } |
| 322 | 323 |
| 323 /// This is the private base class of [PackageRef], [PackageID], and | 324 /// The base class of [PackageRef], [PackageId], and [PackageDep]. |
| 324 /// [PackageDep]. | 325 abstract class PackageName { |
| 325 /// | |
| 326 /// It contains functionality and state that those classes share but is private | |
| 327 /// so that from outside of this library, there is no type relationship between | |
| 328 /// those three types. | |
| 329 class _PackageName { | |
| 330 _PackageName(this.name, this.source, this.description) | |
| 331 : isMagic = false; | |
| 332 | |
| 333 _PackageName.magic(this.name) | |
| 334 : source = null, | |
| 335 description = null, | |
| 336 isMagic = true; | |
| 337 | |
| 338 /// The name of the package being identified. | 326 /// The name of the package being identified. |
| 339 final String name; | 327 final String name; |
| 340 | 328 |
| 341 /// The name of the [Source] used to look up this package given its | 329 /// The [Source] used to look up this package. |
| 342 /// [description]. | |
| 343 /// | 330 /// |
| 344 /// If this is a root package, this will be `null`. | 331 /// If this is a root package, this will be `null`. |
| 345 final String source; | 332 final Source source; |
| 346 | 333 |
| 347 /// The metadata used by the package's [source] to identify and locate it. | 334 /// The metadata used by the package's [source] to identify and locate it. |
| 348 /// | 335 /// |
| 349 /// It contains whatever [Source]-specific data it needs to be able to get | 336 /// It contains whatever [Source]-specific data it needs to be able to get |
| 350 /// the package. For example, the description of a git sourced package might | 337 /// the package. For example, the description of a git sourced package might |
| 351 /// by the URL "git://github.com/dart/uilib.git". | 338 /// by the URL "git://github.com/dart/uilib.git". |
| 352 final description; | 339 final description; |
| 353 | 340 |
| 354 /// Whether this is a name for a magic package. | 341 /// Whether this is a name for a magic package. |
| 355 /// | 342 /// |
| 356 /// Magic packages are unversioned pub constructs that have special semantics. | 343 /// Magic packages are unversioned pub constructs that have special semantics. |
| 357 /// For example, a magic package named "pub itself" is inserted into the | 344 /// For example, a magic package named "pub itself" is inserted into the |
| 358 /// dependency graph when any package depends on barback. This packages has | 345 /// dependency graph when any package depends on barback. This packages has |
| 359 /// dependencies that represent the versions of barback and related packages | 346 /// dependencies that represent the versions of barback and related packages |
| 360 /// that pub is compatible with. | 347 /// that pub is compatible with. |
| 361 final bool isMagic; | 348 final bool isMagic; |
| 362 | 349 |
| 363 /// Whether this package is the root package. | 350 /// Whether this package is the root package. |
| 364 bool get isRoot => source == null && !isMagic; | 351 bool get isRoot => source == null && !isMagic; |
| 365 | 352 |
| 353 PackageName._(this.name, this.source, this.description) | |
| 354 : isMagic = false; | |
| 355 | |
| 356 PackageName._magic(this.name) | |
| 357 : source = null, | |
| 358 description = null, | |
| 359 isMagic = true; | |
| 360 | |
| 366 String toString() { | 361 String toString() { |
| 367 if (isRoot) return "$name (root)"; | 362 if (isRoot) return "$name (root)"; |
| 368 if (isMagic) return name; | 363 if (isMagic) return name; |
| 369 return "$name from $source"; | 364 return "$name from $source"; |
| 370 } | 365 } |
| 371 | 366 |
| 372 /// Returns a [PackageRef] with this one's [name], [source], and | 367 /// Returns a [PackageRef] with this one's [name], [source], and |
| 373 /// [description]. | 368 /// [description]. |
| 374 PackageRef toRef() => isMagic | 369 PackageRef toRef() => isMagic |
| 375 ? new PackageRef.magic(name) | 370 ? new PackageRef.magic(name) |
| 376 : new PackageRef(name, source, description); | 371 : new PackageRef(name, source, description); |
| 377 | 372 |
| 378 /// Returns a [PackageDep] for this package with the given version constraint. | 373 /// Returns a [PackageDep] for this package with the given version constraint. |
| 379 PackageDep withConstraint(VersionConstraint constraint) => | 374 PackageDep withConstraint(VersionConstraint constraint) => |
| 380 new PackageDep(name, source, constraint, description); | 375 new PackageDep(name, source, constraint, description); |
| 376 | |
| 377 /// Returns whether this refers to the same package as [other]. | |
| 378 /// | |
| 379 /// This doesn't compare any constraint information; it's equivalent to | |
| 380 /// `this.toRef() == other.toRef()`. | |
| 381 bool samePackage(PackageName other) { | |
| 382 if (other.name != name) return false; | |
| 383 if (source == null) return other.source == null; | |
| 384 | |
| 385 return other.source == source && | |
| 386 source.descriptionsEqual(description, other.description); | |
| 387 } | |
| 388 | |
| 389 int get hashCode { | |
| 390 if (source == null) return name.hashCode; | |
| 391 return name.hashCode ^ | |
| 392 source.hashCode ^ | |
| 393 source.hashDescription(description); | |
| 394 } | |
| 381 } | 395 } |
| 382 | 396 |
| 383 /// A reference to a [Package], but not any particular version(s) of it. | 397 /// A reference to a [Package], but not any particular version(s) of it. |
| 384 class PackageRef extends _PackageName { | 398 class PackageRef extends PackageName { |
| 385 /// Creates a reference to a package with the given [name], [source], and | 399 /// Creates a reference to a package with the given [name], [source], and |
| 386 /// [description]. | 400 /// [description]. |
| 387 /// | 401 /// |
| 388 /// Since an ID's description is an implementation detail of its source, this | 402 /// Since an ID's description is an implementation detail of its source, this |
| 389 /// should generally not be called outside of [Source] subclasses. A reference | 403 /// should generally not be called outside of [Source] subclasses. A reference |
| 390 /// can be obtained from a user-supplied description using [Source.parseRef]. | 404 /// can be obtained from a user-supplied description using [Source.parseRef]. |
| 391 PackageRef(String name, String source, description) | 405 PackageRef(String name, Source source, description) |
| 392 : super(name, source, description); | 406 : super._(name, source, description); |
| 393 | 407 |
| 394 /// Creates a reference to a magic package (see [isMagic]). | 408 /// Creates a reference to a magic package (see [isMagic]). |
| 395 PackageRef.magic(String name) | 409 PackageRef.magic(String name) |
| 396 : super.magic(name); | 410 : super._magic(name); |
| 397 | 411 |
| 398 int get hashCode => name.hashCode ^ source.hashCode; | 412 bool operator ==(other) => other is PackageRef && samePackage(other); |
| 399 | |
| 400 bool operator ==(other) { | |
| 401 // TODO(rnystrom): We're assuming here that we don't need to delve into the | |
| 402 // description. | |
| 403 return other is PackageRef && | |
| 404 other.name == name && | |
| 405 other.source == source; | |
| 406 } | |
| 407 } | 413 } |
| 408 | 414 |
| 409 /// A reference to a specific version of a package. | 415 /// A reference to a specific version of a package. |
| 410 /// | 416 /// |
| 411 /// A package ID contains enough information to correctly get the package. | 417 /// A package ID contains enough information to correctly get the package. |
| 412 /// | 418 /// |
| 413 /// It's possible for multiple distinct package IDs to point to different | 419 /// It's possible for multiple distinct package IDs to point to different |
| 414 /// packages that have identical contents. For example, the same package may be | 420 /// packages that have identical contents. For example, the same package may be |
| 415 /// available from multiple sources. As far as Pub is concerned, those packages | 421 /// available from multiple sources. As far as Pub is concerned, those packages |
| 416 /// are different. | 422 /// are different. |
| 417 /// | 423 /// |
| 418 /// Note that a package ID's [description] field has a different structure than | 424 /// Note that a package ID's [description] field has a different structure than |
| 419 /// the [PackageRef.description] or [PackageDep.description] fields for some | 425 /// the [PackageRef.description] or [PackageDep.description] fields for some |
| 420 /// sources. For example, the `git` source adds revision information to the | 426 /// sources. For example, the `git` source adds revision information to the |
| 421 /// description to ensure that the same ID always points to the same source. | 427 /// description to ensure that the same ID always points to the same source. |
| 422 class PackageId extends _PackageName { | 428 class PackageId extends PackageName { |
| 423 /// The package's version. | 429 /// The package's version. |
| 424 final Version version; | 430 final Version version; |
| 425 | 431 |
| 426 /// Creates an ID for a package with the given [name], [source], [version], | 432 /// Creates an ID for a package with the given [name], [source], [version], |
| 427 /// and [description]. | 433 /// and [description]. |
| 428 /// | 434 /// |
| 429 /// Since an ID's description is an implementation detail of its source, this | 435 /// Since an ID's description is an implementation detail of its source, this |
| 430 /// should generally not be called outside of [Source] subclasses. | 436 /// should generally not be called outside of [Source] subclasses. |
| 431 PackageId(String name, String source, this.version, description) | 437 PackageId(String name, Source source, this.version, description) |
| 432 : super(name, source, description); | 438 : super._(name, source, description); |
| 433 | 439 |
| 434 /// Creates an ID for a magic package (see [isMagic]). | 440 /// Creates an ID for a magic package (see [isMagic]). |
| 435 PackageId.magic(String name) | 441 PackageId.magic(String name) |
| 436 : super.magic(name), | 442 : super._magic(name), |
| 437 version = Version.none; | 443 version = Version.none; |
| 438 | 444 |
| 439 /// Creates an ID for the given root package. | 445 /// Creates an ID for the given root package. |
| 440 PackageId.root(Package package) | 446 PackageId.root(Package package) |
| 441 : version = package.version, | 447 : version = package.version, |
| 442 super(package.name, null, package.name); | 448 super._(package.name, null, package.name); |
| 443 | 449 |
| 444 int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode; | 450 int get hashCode => super.hashCode ^ version.hashCode; |
| 445 | 451 |
| 446 bool operator ==(other) { | 452 bool operator ==(other) => |
| 447 // TODO(rnystrom): We're assuming here that we don't need to delve into the | 453 other is PackageId && samePackage(other) && other.version == version; |
| 448 // description. | |
| 449 return other is PackageId && | |
| 450 other.name == name && | |
| 451 other.source == source && | |
| 452 other.version == version; | |
| 453 } | |
| 454 | 454 |
| 455 String toString() { | 455 String toString() { |
| 456 if (isRoot) return "$name $version (root)"; | 456 if (isRoot) return "$name $version (root)"; |
| 457 if (isMagic) return name; | 457 if (isMagic) return name; |
| 458 return "$name $version from $source"; | 458 return "$name $version from $source"; |
| 459 } | 459 } |
| 460 } | 460 } |
| 461 | 461 |
| 462 /// A reference to a constrained range of versions of one package. | 462 /// A reference to a constrained range of versions of one package. |
| 463 class PackageDep extends _PackageName { | 463 class PackageDep extends PackageName { |
| 464 /// The allowed package versions. | 464 /// The allowed package versions. |
| 465 final VersionConstraint constraint; | 465 final VersionConstraint constraint; |
| 466 | 466 |
| 467 /// Creates a reference to package with the given [name], [source], | 467 /// Creates a reference to package with the given [name], [source], |
| 468 /// [constraint], and [description]. | 468 /// [constraint], and [description]. |
| 469 /// | 469 /// |
| 470 /// Since an ID's description is an implementation detail of its source, this | 470 /// Since an ID's description is an implementation detail of its source, this |
| 471 /// should generally not be called outside of [Source] subclasses. | 471 /// should generally not be called outside of [Source] subclasses. |
| 472 PackageDep(String name, String source, this.constraint, description) | 472 PackageDep(String name, Source source, this.constraint, description) |
| 473 : super(name, source, description); | 473 : super._(name, source, description); |
| 474 | 474 |
| 475 PackageDep.magic(String name) | 475 PackageDep.magic(String name) |
| 476 : super.magic(name), | 476 : super._magic(name), |
| 477 constraint = Version.none; | 477 constraint = Version.none; |
| 478 | 478 |
| 479 String toString() { | 479 String toString() { |
| 480 if (isRoot) return "$name $constraint (root)"; | 480 if (isRoot) return "$name $constraint (root)"; |
| 481 if (isMagic) return name; | 481 if (isMagic) return name; |
| 482 return "$name $constraint from $source ($description)"; | 482 return "$name $constraint from $source ($description)"; |
| 483 } | 483 } |
| 484 | 484 |
| 485 int get hashCode => name.hashCode ^ source.hashCode ^ constraint.hashCode; | 485 /// Whether [id] satisfies this dependency. |
| 486 /// | |
| 487 /// Specifically, whether [id] refers to the same package as [this] *and* | |
| 488 /// [constraint] allows `id.version`. | |
| 489 bool allowsID(PackageId id) => | |
|
Bob Nystrom
2016/06/23 20:29:49
Can this just be "allows"? We don't usually mentio
nweiz
2016/06/23 21:01:21
Done.
| |
| 490 samePackage(id) && constraint.allows(id.version); | |
| 486 | 491 |
| 487 bool operator ==(other) { | 492 int get hashCode => super.hashCode ^ constraint.hashCode; |
| 488 // TODO(rnystrom): We're assuming here that we don't need to delve into the | 493 |
| 489 // description. | 494 bool operator ==(other) => |
| 490 return other is PackageDep && | 495 other is PackageDep && |
| 491 other.name == name && | 496 samePackage(other) && |
| 492 other.source == source && | 497 other.constraint == constraint; |
| 493 other.constraint == constraint; | |
| 494 } | |
| 495 } | 498 } |
| OLD | NEW |