// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library pub.source_registry; import 'dart:collection'; import 'package.dart'; import 'source.dart'; import 'source/unknown.dart'; /// A class that keeps track of [Source]s used for getting packages. class SourceRegistry extends IterableBase<Source> { final _sources = new Map<String, Source>(); Source _default; /// Returns the default source, which is used when no source is specified. Source get defaultSource => _default; /// Iterates over the registered sources in name order. Iterator<Source> get iterator { var sources = _sources.values.toList(); sources.sort((a, b) => a.name.compareTo(b.name)); return sources.iterator; } /// Returns whether [id1] and [id2] refer to the same package, including /// validating that their descriptions are equivalent. bool idsEqual(PackageId id1, PackageId id2) { if (id1 != id2) return false; if (id1 == null && id2 == null) return true; return idDescriptionsEqual(id1, id2); } /// Returns whether [id1] and [id2] have the same source and description. /// /// This doesn't check whether the name or versions are equal. bool idDescriptionsEqual(PackageId id1, PackageId id2) { if (id1.source != id2.source) return false; return this[id1.source].descriptionsEqual(id1.description, id2.description); } /// Sets the default source. /// /// This takes a string, which must be the name of a registered source. void setDefault(String name) { if (!_sources.containsKey(name)) { throw new StateError('Default source $name is not in the registry'); } _default = _sources[name]; } /// Registers a new source. /// /// This source may not have the same name as a source that's already been /// registered. void register(Source source) { if (_sources.containsKey(source.name)) { throw new StateError('Source registry already has a source named ' '${source.name}'); } _sources[source.name] = source; } /// Loads the package identified by [id]. /// /// Throws an [ArgumentError] if [id] has an invalid source. Package load(PackageId id) { var source = this[id.source]; if (source == null) throw new ArgumentError("Unknown source ${id.source}."); var dir = source.getDirectory(id); return new Package.load(id.name, dir, this); } /// Returns the source named [name]. /// /// Returns an [UnknownSource] if no source with that name has been /// registered. If [name] is null, returns the default source. Source operator[](String name) { if (name == null) { if (defaultSource != null) return defaultSource; throw new StateError('No default source has been registered'); } if (_sources.containsKey(name)) return _sources[name]; return new UnknownSource(name); } }