37fd8f03fd
Get rid of special cases for names beginning with "rust-" or containing hyphens, and just store a Path in a package ID. The Rust-identifier for the crate is none of rustpkg's business.
128 lines
3.9 KiB
Rust
128 lines
3.9 KiB
Rust
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use version::{try_getting_version, try_getting_local_version,
|
|
Version, NoVersion, split_version};
|
|
use std::rt::io::Writer;
|
|
use std::hash::Streaming;
|
|
use std::hash;
|
|
|
|
/// Path-fragment identifier of a package such as
|
|
/// 'github.com/graydon/test'; path must be a relative
|
|
/// path with >=1 component.
|
|
#[deriving(Clone)]
|
|
pub struct PkgId {
|
|
/// This is a path, on the local filesystem, referring to where the
|
|
/// files for this package live. For example:
|
|
/// github.com/mozilla/quux-whatever (it's assumed that if we're
|
|
/// working with a package ID of this form, rustpkg has already cloned
|
|
/// the sources into a local directory in the RUST_PATH).
|
|
path: Path,
|
|
/// Short name. This is the path's filestem, but we store it
|
|
/// redundantly so as to not call get() everywhere (filestem() returns an
|
|
/// option)
|
|
/// The short name does not need to be a valid Rust identifier.
|
|
/// Users can write: `extern mod foo = "...";` to get around the issue
|
|
/// of package IDs whose short names aren't valid Rust identifiers.
|
|
short_name: ~str,
|
|
/// The requested package version.
|
|
version: Version
|
|
}
|
|
|
|
impl Eq for PkgId {
|
|
fn eq(&self, p: &PkgId) -> bool {
|
|
p.path == self.path && p.version == self.version
|
|
}
|
|
fn ne(&self, p: &PkgId) -> bool {
|
|
!(self.eq(p))
|
|
}
|
|
}
|
|
|
|
impl PkgId {
|
|
pub fn new(s: &str) -> PkgId {
|
|
use conditions::bad_pkg_id::cond;
|
|
|
|
let mut given_version = None;
|
|
|
|
// Did the user request a specific version?
|
|
let s = match split_version(s) {
|
|
Some((path, v)) => {
|
|
debug!("s = %s, path = %s, v = %s", s, path, v.to_str());
|
|
given_version = Some(v);
|
|
path
|
|
}
|
|
None => {
|
|
debug!("%s has no explicit version", s);
|
|
s
|
|
}
|
|
};
|
|
|
|
let path = Path(s);
|
|
if path.is_absolute {
|
|
return cond.raise((path, ~"absolute pkgid"));
|
|
}
|
|
if path.components.len() < 1 {
|
|
return cond.raise((path, ~"0-length pkgid"));
|
|
}
|
|
let short_name = path.clone().filestem().expect(fmt!("Strange path! %s", s));
|
|
|
|
let version = match given_version {
|
|
Some(v) => v,
|
|
None => match try_getting_local_version(&path) {
|
|
Some(v) => v,
|
|
None => match try_getting_version(&path) {
|
|
Some(v) => v,
|
|
None => NoVersion
|
|
}
|
|
}
|
|
};
|
|
|
|
debug!("path = %s", path.to_str());
|
|
PkgId {
|
|
path: path,
|
|
short_name: short_name,
|
|
version: version
|
|
}
|
|
}
|
|
|
|
pub fn hash(&self) -> ~str {
|
|
fmt!("%s-%s-%s", self.path.to_str(),
|
|
hash(self.path.to_str() + self.version.to_str()),
|
|
self.version.to_str())
|
|
}
|
|
|
|
pub fn short_name_with_version(&self) -> ~str {
|
|
fmt!("%s%s", self.short_name, self.version.to_str())
|
|
}
|
|
|
|
/// True if the ID has multiple components
|
|
pub fn is_complex(&self) -> bool {
|
|
self.short_name != self.path.to_str()
|
|
}
|
|
}
|
|
|
|
impl ToStr for PkgId {
|
|
fn to_str(&self) -> ~str {
|
|
// should probably use the filestem and not the whole path
|
|
fmt!("%s-%s", self.path.to_str(), self.version.to_str())
|
|
}
|
|
}
|
|
|
|
|
|
pub fn write<W: Writer>(writer: &mut W, string: &str) {
|
|
writer.write(string.as_bytes());
|
|
}
|
|
|
|
pub fn hash(data: ~str) -> ~str {
|
|
let hasher = &mut hash::default_state();
|
|
write(hasher, data);
|
|
hasher.result_str()
|
|
}
|