Auto merge of #4559 - derekdreery:add_docs, r=alexcrichton

Add some more docs

Add some more docs for various parts of cargo, and add/improve a few debug implementations.
This commit is contained in:
bors 2017-10-03 09:18:58 +00:00
commit 873a081019
8 changed files with 242 additions and 13 deletions

View file

@ -20,12 +20,13 @@ use util::errors::{CargoResult, CargoResultExt};
// TODO: Is manifest_path a relic?
#[derive(Clone, Debug)]
pub struct Package {
// The package's manifest
/// The package's manifest
manifest: Manifest,
// The root of the package
/// The root of the package
manifest_path: PathBuf,
}
/// A Package in a form where `Serialize` can be derived.
#[derive(Serialize)]
struct SerializedPackage<'a> {
name: &'a str,
@ -69,6 +70,7 @@ impl ser::Serialize for Package {
}
impl Package {
/// Create a package from a manifest and its location
pub fn new(manifest: Manifest,
manifest_path: &Path) -> Package {
Package {
@ -77,6 +79,7 @@ impl Package {
}
}
/// Calculate the Package from the manifest path (and cargo configuration).
pub fn for_path(manifest_path: &Path, config: &Config) -> CargoResult<Package> {
let path = manifest_path.parent().unwrap();
let source_id = SourceId::for_path(path)?;
@ -84,18 +87,30 @@ impl Package {
Ok(pkg)
}
/// Get the manifest dependencies
pub fn dependencies(&self) -> &[Dependency] { self.manifest.dependencies() }
/// Get the manifest
pub fn manifest(&self) -> &Manifest { &self.manifest }
/// Get the path to the manifest
pub fn manifest_path(&self) -> &Path { &self.manifest_path }
/// Get the name of the package
pub fn name(&self) -> &str { self.package_id().name() }
/// Get the PackageId object for the package (fully defines a packge)
pub fn package_id(&self) -> &PackageId { self.manifest.package_id() }
/// Get the root folder of the package
pub fn root(&self) -> &Path { self.manifest_path.parent().unwrap() }
/// Get the summary for the package
pub fn summary(&self) -> &Summary { self.manifest.summary() }
/// Get the targets specified in the manifest
pub fn targets(&self) -> &[Target] { self.manifest.targets() }
/// Get the current package version
pub fn version(&self) -> &Version { self.package_id().version() }
/// Get the package authors
pub fn authors(&self) -> &Vec<String> { &self.manifest.metadata().authors }
/// Whether the package is set to publish
pub fn publish(&self) -> bool { self.manifest.publish() }
/// Whether the package uses a custom build script for any target
pub fn has_custom_build(&self) -> bool {
self.targets().iter().any(|t| t.is_custom_build())
}

View file

@ -7,37 +7,60 @@ use termcolor::{self, StandardStream, Color, ColorSpec, WriteColor};
use util::errors::CargoResult;
#[derive(Clone, Copy, PartialEq)]
/// The requested verbosity of output
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Verbosity {
Verbose,
Normal,
Quiet
}
/// An abstraction around a `Write`able object that remembers preferences for output verbosity and
/// color.
pub struct Shell {
/// the `Write`able object, either with or without color support (represented by different enum
/// variants)
err: ShellOut,
/// How verbose messages should be
verbosity: Verbosity,
}
impl fmt::Debug for Shell {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Shell")
match &self.err {
&ShellOut::Write(_) => f.debug_struct("Shell")
.field("verbosity", &self.verbosity)
.finish(),
&ShellOut::Stream(_, color_choice) => f.debug_struct("Shell")
.field("verbosity", &self.verbosity)
.field("color_choice", &color_choice)
.finish()
}
}
}
/// A `Write`able object, either with or without color support
enum ShellOut {
/// A plain write object without color support
Write(Box<Write>),
/// Color-enabled stdio, with information on whether color should be used
Stream(StandardStream, ColorChoice),
}
#[derive(PartialEq, Clone, Copy)]
/// Whether messages should use color output
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum ColorChoice {
/// Force color output
Always,
/// Force disable color output
Never,
/// Intelligently guess whether to use color output
CargoAuto,
}
impl Shell {
/// Create a new shell (color choice and verbosity), defaulting to 'auto' color and verbose
/// output.
pub fn new() -> Shell {
Shell {
err: ShellOut::Stream(
@ -48,6 +71,7 @@ impl Shell {
}
}
/// Create a shell from a plain writable object, with no color, and max verbosity.
pub fn from_write(out: Box<Write>) -> Shell {
Shell {
err: ShellOut::Write(out),
@ -55,6 +79,8 @@ impl Shell {
}
}
/// Print a message, where the status will have `color` color, and can be justified. The
/// messages follows without color.
fn print(&mut self,
status: &fmt::Display,
message: &fmt::Display,
@ -68,16 +94,19 @@ impl Shell {
}
}
/// Get a reference to the underlying writer
pub fn err(&mut self) -> &mut Write {
self.err.as_write()
}
/// Shortcut to right-align and color green a status message.
pub fn status<T, U>(&mut self, status: T, message: U) -> CargoResult<()>
where T: fmt::Display, U: fmt::Display
{
self.print(&status, &message, Green, true)
}
/// Shortcut to right-align a status message.
pub fn status_with_color<T, U>(&mut self,
status: T,
message: U,
@ -87,6 +116,7 @@ impl Shell {
self.print(&status, &message, color, true)
}
/// Run the callback only if we are in verbose mode
pub fn verbose<F>(&mut self, mut callback: F) -> CargoResult<()>
where F: FnMut(&mut Shell) -> CargoResult<()>
{
@ -96,6 +126,7 @@ impl Shell {
}
}
/// Run the callback if we are not in verbose mode.
pub fn concise<F>(&mut self, mut callback: F) -> CargoResult<()>
where F: FnMut(&mut Shell) -> CargoResult<()>
{
@ -105,10 +136,12 @@ impl Shell {
}
}
/// Print a red 'error' message
pub fn error<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
self.print(&"error:", &message, Red, false)
}
/// Print an amber 'warning' message
pub fn warn<T: fmt::Display>(&mut self, message: T) -> CargoResult<()> {
match self.verbosity {
Verbosity::Quiet => Ok(()),
@ -116,14 +149,17 @@ impl Shell {
}
}
/// Update the verbosity of the shell
pub fn set_verbosity(&mut self, verbosity: Verbosity) {
self.verbosity = verbosity;
}
/// Get the verbosity of the shell
pub fn verbosity(&self) -> Verbosity {
self.verbosity
}
/// Update the color choice (always, never, or auto) from a string.
pub fn set_color_choice(&mut self, color: Option<&str>) -> CargoResult<()> {
if let ShellOut::Stream(ref mut err, ref mut cc) = self.err {
let cfg = match color {
@ -142,6 +178,10 @@ impl Shell {
Ok(())
}
/// Get the current color choice
///
/// If we are not using a color stream, this will always return Never, even if the color choice
/// has been set to something else.
pub fn color_choice(&self) -> ColorChoice {
match self.err {
ShellOut::Stream(_, cc) => cc,
@ -151,6 +191,8 @@ impl Shell {
}
impl ShellOut {
/// Print out a message with a status. The status comes first and is bold + the given color.
/// The status can be justified, in which case the max width that will right align is 12 chars.
fn print(&mut self,
status: &fmt::Display,
message: &fmt::Display,
@ -182,6 +224,7 @@ impl ShellOut {
Ok(())
}
/// Get this object as a `io::Write`.
fn as_write(&mut self) -> &mut Write {
match *self {
ShellOut::Stream(ref mut err, _) => err,
@ -191,6 +234,7 @@ impl ShellOut {
}
impl ColorChoice {
/// Convert our color choice to termcolor's version
fn to_termcolor_color_choice(&self) -> termcolor::ColorChoice {
match *self {
ColorChoice::Always => termcolor::ColorChoice::Always,

View file

@ -21,6 +21,7 @@ use util::{Config, CargoResult, ToUrl};
/// A Source finds and downloads remote packages based on names and
/// versions.
pub trait Source: Registry {
/// Returns the `SourceId` corresponding to this source
fn source_id(&self) -> &SourceId;
/// The update method performs any network operations required to
@ -56,27 +57,34 @@ pub trait Source: Registry {
}
impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
/// Forwards to `Source::source_id`
fn source_id(&self) -> &SourceId {
(**self).source_id()
}
/// Forwards to `Source::update`
fn update(&mut self) -> CargoResult<()> {
(**self).update()
}
/// Forwards to `Source::download`
fn download(&mut self, id: &PackageId) -> CargoResult<Package> {
(**self).download(id)
}
/// Forwards to `Source::fingerprint`
fn fingerprint(&self, pkg: &Package) -> CargoResult<String> {
(**self).fingerprint(pkg)
}
/// Forwards to `Source::verify`
fn verify(&self, pkg: &PackageId) -> CargoResult<()> {
(**self).verify(pkg)
}
}
/// The possible kinds of code source. Along with a URL, this fully defines the
/// source
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum Kind {
/// Kind::Git(<git reference>) represents a git repository
@ -91,10 +99,14 @@ enum Kind {
Directory,
}
/// Information to find a specific commit in a git repository
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum GitReference {
/// from a tag
Tag(String),
/// from the HEAD of a branch
Branch(String),
/// from a specific revision
Rev(String),
}
@ -104,16 +116,23 @@ pub struct SourceId {
inner: Arc<SourceIdInner>,
}
/// Unique identifier for a source of packages.
#[derive(Eq, Clone, Debug)]
struct SourceIdInner {
/// The source URL
url: Url,
/// `git::canonicalize_url(url)` for the url field
canonical_url: Url,
/// The source kind
kind: Kind,
// e.g. the exact git revision of the specified branch for a Git Source
precise: Option<String>,
}
impl SourceId {
/// Create a SourceId object from the kind and url.
///
/// The canonical url will be calculated, but the precise field will not
fn new(kind: Kind, url: Url) -> CargoResult<SourceId> {
let source_id = SourceId {
inner: Arc::new(SourceIdInner {
@ -174,29 +193,36 @@ impl SourceId {
}
}
/// A view of the `SourceId` that can be `Display`ed as a URL
pub fn to_url(&self) -> SourceIdToUrl {
SourceIdToUrl { inner: &*self.inner }
}
// Pass absolute path
/// Create a SourceId from a filesystem path.
///
/// Pass absolute path
pub fn for_path(path: &Path) -> CargoResult<SourceId> {
let url = path.to_url()?;
SourceId::new(Kind::Path, url)
}
/// Crate a SourceId from a git reference
pub fn for_git(url: &Url, reference: GitReference) -> CargoResult<SourceId> {
SourceId::new(Kind::Git(reference), url.clone())
}
/// Create a SourceId from a registry url
pub fn for_registry(url: &Url) -> CargoResult<SourceId> {
SourceId::new(Kind::Registry, url.clone())
}
/// Create a SourceId from a local registry path
pub fn for_local_registry(path: &Path) -> CargoResult<SourceId> {
let url = path.to_url()?;
SourceId::new(Kind::LocalRegistry, url)
}
/// Create a SourceId from a directory path
pub fn for_directory(path: &Path) -> CargoResult<SourceId> {
let url = path.to_url()?;
SourceId::new(Kind::Directory, url)
@ -212,9 +238,9 @@ impl SourceId {
static WARNED: AtomicBool = ATOMIC_BOOL_INIT;
if !WARNED.swap(true, SeqCst) {
config.shell().warn("custom registry support via \
the `registry.index` configuration is \
being removed, this functionality \
will not work in the future")?;
the `registry.index` configuration is \
being removed, this functionality \
will not work in the future")?;
}
&index[..]
} else {
@ -224,16 +250,22 @@ impl SourceId {
SourceId::for_registry(&url)
}
/// Get this source URL
pub fn url(&self) -> &Url {
&self.inner.url
}
/// Is this source from a filesystem path
pub fn is_path(&self) -> bool {
self.inner.kind == Kind::Path
}
/// Is this source from a registry (either local or not)
pub fn is_registry(&self) -> bool {
self.inner.kind == Kind::Registry || self.inner.kind == Kind::LocalRegistry
}
/// Is this source from a git repository
pub fn is_git(&self) -> bool {
match self.inner.kind {
Kind::Git(_) => true,
@ -271,10 +303,12 @@ impl SourceId {
}
}
/// Get the value of the precise field
pub fn precise(&self) -> Option<&str> {
self.inner.precise.as_ref().map(|s| &s[..])
}
/// Get the git reference if this is a git source, otherwise None.
pub fn git_reference(&self) -> Option<&GitReference> {
match self.inner.kind {
Kind::Git(ref s) => Some(s),
@ -282,6 +316,7 @@ impl SourceId {
}
}
/// Create a new SourceId from this source with the given `precise`
pub fn with_precise(&self, v: Option<String>) -> SourceId {
SourceId {
inner: Arc::new(SourceIdInner {
@ -291,6 +326,7 @@ impl SourceId {
}
}
/// Whether the remote registry is the standard https://crates.io
pub fn is_default_registry(&self) -> bool {
match self.inner.kind {
Kind::Registry => {}
@ -299,6 +335,10 @@ impl SourceId {
self.inner.url.to_string() == CRATES_IO
}
/// Hash `self`
///
/// For paths, remove the workspace prefix so the same source will give the
/// same hash in different locations.
pub fn stable_hash<S: hash::Hasher>(&self, workspace: &Path, into: &mut S) {
if self.is_path() {
if let Ok(p) = self.inner.url.to_file_path().unwrap().strip_prefix(workspace) {
@ -383,6 +423,9 @@ impl fmt::Display for SourceId {
// This custom implementation handles situations such as when two git sources
// point at *almost* the same URL, but not quite, even when they actually point
// to the same repository.
/// This method tests for self and other values to be equal, and is used by ==.
///
/// For git repositories, the canonical url is checked.
impl PartialEq for SourceIdInner {
fn eq(&self, other: &SourceIdInner) -> bool {
if self.kind != other.kind {
@ -441,6 +484,7 @@ impl Hash for SourceId {
}
}
/// A `Display`able view into a SourceId that will write it as a url
pub struct SourceIdToUrl<'a> {
inner: &'a SourceIdInner,
}
@ -477,6 +521,8 @@ impl<'a> fmt::Display for SourceIdToUrl<'a> {
}
impl GitReference {
/// Returns a `Display`able view of this git reference, or None if using
/// the head of the "master" branch
pub fn pretty_ref(&self) -> Option<PrettyRef> {
match *self {
GitReference::Branch(ref s) if *s == "master" => None,
@ -485,6 +531,7 @@ impl GitReference {
}
}
/// A git reference that can be `Display`ed
pub struct PrettyRef<'a> {
inner: &'a GitReference,
}
@ -499,26 +546,32 @@ impl<'a> fmt::Display for PrettyRef<'a> {
}
}
/// A `HashMap` of `SourceId` -> `Box<Source>`
#[derive(Default)]
pub struct SourceMap<'src> {
map: HashMap<SourceId, Box<Source + 'src>>,
}
/// A `std::collection::hash_map::Values` for `SourceMap`
pub type Sources<'a, 'src> = Values<'a, SourceId, Box<Source + 'src>>;
/// A `std::collection::hash_map::IterMut` for `SourceMap`
pub struct SourcesMut<'a, 'src: 'a> {
inner: IterMut<'a, SourceId, Box<Source + 'src>>,
}
impl<'src> SourceMap<'src> {
/// Create an empty map
pub fn new() -> SourceMap<'src> {
SourceMap { map: HashMap::new() }
}
/// Like `HashMap::contains_key`
pub fn contains(&self, id: &SourceId) -> bool {
self.map.contains_key(id)
}
/// Like `HashMap::get`
pub fn get(&self, id: &SourceId) -> Option<&(Source + 'src)> {
let source = self.map.get(id);
@ -528,6 +581,7 @@ impl<'src> SourceMap<'src> {
})
}
/// Like `HashMap::get_mut`
pub fn get_mut(&mut self, id: &SourceId) -> Option<&mut (Source + 'src)> {
self.map.get_mut(id).map(|s| {
let s: &mut (Source + 'src) = &mut **s;
@ -535,27 +589,34 @@ impl<'src> SourceMap<'src> {
})
}
/// Like `HashMap::get`, but first calculates the `SourceId` from a
/// `PackageId`
pub fn get_by_package_id(&self, pkg_id: &PackageId) -> Option<&(Source + 'src)> {
self.get(pkg_id.source_id())
}
/// Like `HashMap::insert`, but derives the SourceId key from the Source
pub fn insert(&mut self, source: Box<Source + 'src>) {
let id = source.source_id().clone();
self.map.insert(id, source);
}
/// Like `HashMap::is_empty`
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
/// Like `HashMap::len`
pub fn len(&self) -> usize {
self.map.len()
}
/// Like `HashMap::values`
pub fn sources<'a>(&'a self) -> Sources<'a, 'src> {
self.map.values()
}
/// Like `HashMap::iter_mut`
pub fn sources_mut<'a>(&'a mut self) -> SourcesMut<'a, 'src> {
SourcesMut { inner: self.map.iter_mut() }
}

View file

@ -25,18 +25,50 @@ use super::layout::Layout;
use super::links::Links;
use super::{Kind, Compilation, BuildConfig};
/// All information needed to define a Unit.
///
/// A unit is an object that has enough information so that cargo knows how to build it.
/// For example, if your project has dependencies, then every dependency will be built as a library
/// unit. If your project is a library, then it will be built as a library unit as well, or if it
/// is a binary with `main.rs`, then a binary will be output. There are also separate unit types
/// for `test`ing and `check`ing, amongst others.
///
/// The unit also holds information about all possible metadata about the package in `pkg`.
///
/// A unit needs to know extra information in addition to the type and root source file. For
/// example, it needs to know the target architecture (OS, chip arch etc.) and it needs to know
/// whether you want a debug or release build. There is enough information in this struct to figure
/// all that out.
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Unit<'a> {
/// Information about avaiable targets, which files to include/exclude, etc. Basically stuff in
/// `Cargo.toml`.
pub pkg: &'a Package,
/// Information about the specific target to build, out of the possible targets in `pkg`. Not
/// to be confused with *target-triple* (or *target architecture* ...), the target arch for a
/// build.
pub target: &'a Target,
/// The profile contains information about *how* the build should be run, including debug
/// level, extra args to pass to rustc, etc.
pub profile: &'a Profile,
/// Whether this compilation unit is for the host or target architecture.
///
/// For example, when
/// cross compiling and using a custom build script, the build script needs to be compiled for
/// the host architecture so the host rustc can use it (when compiling to the target
/// architecture).
pub kind: Kind,
}
/// The build context, containing all information about a build task
pub struct Context<'a, 'cfg: 'a> {
/// The workspace the build is for
pub ws: &'a Workspace<'cfg>,
/// The cargo configuration
pub config: &'cfg Config,
/// The dependency graph for our build
pub resolve: &'a Resolve,
/// Information on the compilation output
pub compilation: Compilation<'cfg>,
pub packages: &'a PackageSet<'cfg>,
pub build_state: Arc<BuildState>,
@ -50,13 +82,21 @@ pub struct Context<'a, 'cfg: 'a> {
pub used_in_plugin: HashSet<Unit<'a>>,
pub jobserver: Client,
/// The target directory layout for the host (and target if it is the same as host)
host: Layout,
/// The target directory layout for the target (if different from then host)
target: Option<Layout>,
target_info: TargetInfo,
host_info: TargetInfo,
profiles: &'a Profiles,
incremental_enabled: bool,
/// For each Unit, a list all files produced as a triple of
///
/// - File name that will be produced by the build process (in `deps`)
/// - If it should be linked into `target`, and what it should be called (e.g. without
/// metadata).
/// - Whether it is something you can link against (e.g. a library)
target_filenames: HashMap<Unit<'a>, Arc<Vec<(PathBuf, Option<PathBuf>, bool)>>>,
target_metadatas: HashMap<Unit<'a>, Option<Metadata>>,
}
@ -210,6 +250,10 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
Ok(())
}
/// A recursive function that checks all crate types (`rlib`, ...) are in `crate_types`
/// for this unit and its dependencies.
///
/// Tracks visited units to avoid unnecessary work.
fn visit_crate_type(&self,
unit: &Unit<'a>,
crate_types: &mut BTreeSet<String>,
@ -660,7 +704,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}
}
};
//info!("{:?}", unit);
match *unit.target.kind() {
TargetKind::Bin |
TargetKind::CustomBuild |
@ -1038,8 +1082,23 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}
}
// Acquire extra flags to pass to the compiler from the
// RUSTFLAGS environment variable and similar config values
/// Acquire extra flags to pass to the compiler from various locations.
///
/// The locations are:
///
/// - the `RUSTFLAGS` environment variable
///
/// then if this was not found
///
/// - `target.*.rustflags` from the manifest (Cargo.toml)
/// - `target.cfg(..).rustflags` from the manifest
///
/// then if neither of these were found
///
/// - `build.rustflags` from the manifest
///
/// Note that if a `target` is specified, no args will be passed to host code (plugins, build
/// scripts, ...), even if it is the same as the target.
fn env_args(config: &Config,
build_config: &BuildConfig,
target_info: &TargetInfo,
@ -1136,6 +1195,14 @@ impl fmt::Display for Metadata {
}
}
/// Takes rustc output (using specialized command line args), and calculates the file prefix and
/// suffix for the given crate type, or returns None if the type is not supported. (e.g. for a
/// rust library like libcargo.rlib, prefix = "lib", suffix = "rlib").
///
/// The caller needs to ensure that the lines object is at the correct line for the given crate
/// type: this is not checked.
// This function can not handle more than 1 file per type (with wasm32-unknown-emscripten, there
// are 2 files for bin (.wasm and .js))
fn parse_crate_type(
crate_type: &str,
error: &str,

View file

@ -56,6 +56,9 @@ use std::path::{PathBuf, Path};
use core::Workspace;
use util::{Config, FileLock, CargoResult, Filesystem};
/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
root: PathBuf,
deps: PathBuf,
@ -64,6 +67,7 @@ pub struct Layout {
incremental: PathBuf,
fingerprint: PathBuf,
examples: PathBuf,
/// The lockfile for a build, will be unlocked when this struct is `drop`ped.
_lock: FileLock,
}
@ -74,6 +78,12 @@ pub fn is_bad_artifact_name(name: &str) -> bool {
}
impl Layout {
/// Calcuate the paths for build output, lock the build directory, and return as a Layout.
///
/// This function will block if the directory is already locked.
///
/// Differs from `at` in that it calculates the root path from the workspace target directory,
/// adding the target triple and the profile (debug, release, ...).
pub fn new(ws: &Workspace,
triple: Option<&str>,
dest: &str) -> CargoResult<Layout> {
@ -88,6 +98,9 @@ impl Layout {
Layout::at(ws.config(), path)
}
/// Calcuate the paths for build output, lock the build directory, and return as a Layout.
///
/// This function will block if the directory is already locked.
pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
// For now we don't do any more finer-grained locking on the artifact
// directory, so just lock the entire thing for the duration of this
@ -136,6 +149,7 @@ impl Layout {
}
}
/// Make sure all directories stored in the Layout exist on the filesystem.
pub fn prepare(&mut self) -> io::Result<()> {
if fs::metadata(&self.root).is_err() {
fs::create_dir_all(&self.root)?;
@ -160,11 +174,18 @@ impl Layout {
}
}
/// Fetch the root path.
pub fn dest(&self) -> &Path { &self.root }
/// Fetch the deps path.
pub fn deps(&self) -> &Path { &self.deps }
/// Fetch the examples path.
pub fn examples(&self) -> &Path { &self.examples }
/// Fetch the root path.
pub fn root(&self) -> &Path { &self.root }
/// Fetch the incremental path.
pub fn incremental(&self) -> &Path { &self.incremental }
/// Fetch the fingerprint path.
pub fn fingerprint(&self) -> &Path { &self.fingerprint }
/// Fetch the build path.
pub fn build(&self) -> &Path { &self.build }
}

View file

@ -28,15 +28,27 @@ use util::{Filesystem, LazyCell};
use self::ConfigValue as CV;
/// Configuration information for cargo. This is not specific to a build, it is information
/// relating to cargo itself.
///
/// This struct implements `Default`: all fields can be inferred.
#[derive(Debug)]
pub struct Config {
/// The location of the users's 'home' directory. OS-dependent.
home_path: Filesystem,
/// Information about how to write messages to the shell
shell: RefCell<Shell>,
/// Information on how to invoke the compiler (rustc)
rustc: LazyCell<Rustc>,
/// A collection of configuration options
values: LazyCell<HashMap<String, ConfigValue>>,
/// The current working directory of cargo
cwd: PathBuf,
/// The location of the cargo executable (path to current process)
cargo_exe: LazyCell<PathBuf>,
/// The location of the rustdoc executable
rustdoc: LazyCell<PathBuf>,
/// Whether we are printing extra verbose messages
extra_verbose: Cell<bool>,
frozen: Cell<bool>,
locked: Cell<bool>,

View file

@ -2,17 +2,23 @@ use std::path::PathBuf;
use util::{self, CargoResult, internal, ProcessBuilder};
/// Information on the `rustc` executable
#[derive(Debug)]
pub struct Rustc {
/// The location of the exe
pub path: PathBuf,
/// An optional program that will be passed the path of the rust exe as its first argument, and
/// rustc args following this.
pub wrapper: Option<PathBuf>,
/// Verbose version information (the output of `rustc -vV`)
pub verbose_version: String,
/// The host triple (arch-platform-OS), this comes from verbose_version.
pub host: String,
}
impl Rustc {
/// Run the compiler at `path` to learn various pieces of information about
/// it.
/// it, with an optional wrapper.
///
/// If successful this function returns a description of the compiler along
/// with a list of its capabilities.
@ -41,6 +47,7 @@ impl Rustc {
})
}
/// Get a process builder set up to use the found rustc version, with a wrapper if Some
pub fn process(&self) -> ProcessBuilder {
if let Some(ref wrapper) = self.wrapper {
let mut cmd = util::process(wrapper);

View file

@ -4,7 +4,9 @@ use url::Url;
use util::CargoResult;
/// A type that can be converted to a Url
pub trait ToUrl {
/// Performs the conversion
fn to_url(self) -> CargoResult<Url>;
}