Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: lib/src/package.dart

Issue 2079303003: Track Source objects in PackageNames. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698