Skip to content

Commit

Permalink
Auto merge of #1995 - alexcrichton:less-recursion, r=alexcrichton
Browse files Browse the repository at this point in the history
A few final nits and such taken care of, attempting to land now!
  • Loading branch information
bors committed Sep 21, 2015
2 parents 4080ea8 + 6dfb84f commit ecafa40
Show file tree
Hide file tree
Showing 8 changed files with 326 additions and 229 deletions.
14 changes: 1 addition & 13 deletions src/bin/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use std::fs;
use std::io;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::thread::Builder;

use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
Expand Down Expand Up @@ -58,18 +57,7 @@ See 'cargo help <command>' for more information on a specific command.

fn main() {
env_logger::init().unwrap();

// Right now the algorithm in cargo::core::resolve is pretty recursive and
// runs the risk of blowing the stack. Platforms tend to have different
// stack limits by default (I just witnessed 512K on OSX and 2MB on Linux)
// so to get a consistent experience just spawn ourselves with a large stack
// size.
let stack_size = env::var("CARGO_STACK_SIZE").ok()
.and_then(|s| s.parse().ok())
.unwrap_or(8 * 1024 * 1024); // 8MB
Builder::new().stack_size(stack_size).spawn(|| {
execute_main_without_stdin(execute, true, USAGE)
}).unwrap().join().unwrap();
execute_main_without_stdin(execute, true, USAGE)
}

macro_rules! each_subcommand{ ($mac:ident) => ({
Expand Down
97 changes: 81 additions & 16 deletions src/cargo/core/dependency.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use semver::VersionReq;

use core::{SourceId, Summary, PackageId};
use std::rc::Rc;
use util::CargoResult;

/// Informations about a dependency requested by a Cargo manifest.
/// The data underlying a Dependency.
#[derive(PartialEq,Clone,Debug)]
pub struct Dependency {
pub struct DependencyInner {
name: String,
source_id: SourceId,
req: VersionReq,
Expand All @@ -22,33 +23,40 @@ pub struct Dependency {
only_for_platform: Option<String>,
}

/// Information about a dependency requested by a Cargo manifest.
/// Cheap to copy.
#[derive(PartialEq,Clone,Debug)]
pub struct Dependency {
inner: Rc<DependencyInner>,
}

#[derive(PartialEq, Clone, Debug, Copy)]
pub enum Kind {
Normal,
Development,
Build,
}

impl Dependency {
impl DependencyInner {
/// Attempt to create a `Dependency` from an entry in the manifest.
pub fn parse(name: &str,
version: Option<&str>,
source_id: &SourceId) -> CargoResult<Dependency> {
source_id: &SourceId) -> CargoResult<DependencyInner> {
let version_req = match version {
Some(v) => try!(VersionReq::parse(v)),
None => VersionReq::any()
};

Ok(Dependency {
Ok(DependencyInner {
only_match_name: false,
req: version_req,
specified_req: version.map(|s| s.to_string()),
.. Dependency::new_override(name, source_id)
.. DependencyInner::new_override(name, source_id)
})
}

pub fn new_override(name: &str, source_id: &SourceId) -> Dependency {
Dependency {
pub fn new_override(name: &str, source_id: &SourceId) -> DependencyInner {
DependencyInner {
name: name.to_string(),
source_id: source_id.clone(),
req: VersionReq::any(),
Expand Down Expand Up @@ -76,49 +84,49 @@ impl Dependency {
self.only_for_platform.as_ref().map(|s| &s[..])
}

pub fn set_kind(mut self, kind: Kind) -> Dependency {
pub fn set_kind(mut self, kind: Kind) -> DependencyInner {
self.kind = kind;
self
}

/// Sets the list of features requested for the package.
pub fn set_features(mut self, features: Vec<String>) -> Dependency {
pub fn set_features(mut self, features: Vec<String>) -> DependencyInner {
self.features = features;
self
}

/// Sets whether the dependency requests default features of the package.
pub fn set_default_features(mut self, default_features: bool) -> Dependency {
pub fn set_default_features(mut self, default_features: bool) -> DependencyInner {
self.default_features = default_features;
self
}

/// Sets whether the dependency is optional.
pub fn set_optional(mut self, optional: bool) -> Dependency {
pub fn set_optional(mut self, optional: bool) -> DependencyInner {
self.optional = optional;
self
}

/// Set the source id for this dependency
pub fn set_source_id(mut self, id: SourceId) -> Dependency {
pub fn set_source_id(mut self, id: SourceId) -> DependencyInner {
self.source_id = id;
self
}

/// Set the version requirement for this dependency
pub fn set_version_req(mut self, req: VersionReq) -> Dependency {
pub fn set_version_req(mut self, req: VersionReq) -> DependencyInner {
self.req = req;
self
}

pub fn set_only_for_platform(mut self, platform: Option<String>)
-> Dependency {
-> DependencyInner {
self.only_for_platform = platform;
self
}

/// Lock this dependency to depending on the specified package id
pub fn lock_to(self, id: &PackageId) -> Dependency {
pub fn lock_to(self, id: &PackageId) -> DependencyInner {
assert_eq!(self.source_id, *id.source_id());
assert!(self.req.matches(id.version()));
self.set_version_req(VersionReq::exact(id.version()))
Expand Down Expand Up @@ -152,6 +160,63 @@ impl Dependency {
(self.only_match_name || (self.req.matches(id.version()) &&
&self.source_id == id.source_id()))
}

pub fn into_dependency(self) -> Dependency {
Dependency {inner: Rc::new(self)}
}
}

impl Dependency {
/// Attempt to create a `Dependency` from an entry in the manifest.
pub fn parse(name: &str,
version: Option<&str>,
source_id: &SourceId) -> CargoResult<Dependency> {
DependencyInner::parse(name, version, source_id).map(|di| {
di.into_dependency()
})
}

pub fn new_override(name: &str, source_id: &SourceId) -> Dependency {
DependencyInner::new_override(name, source_id).into_dependency()
}

pub fn clone_inner(&self) -> DependencyInner { (*self.inner).clone() }

pub fn version_req(&self) -> &VersionReq { self.inner.version_req() }
pub fn name(&self) -> &str { self.inner.name() }
pub fn source_id(&self) -> &SourceId { self.inner.source_id() }
pub fn kind(&self) -> Kind { self.inner.kind() }
pub fn specified_req(&self) -> Option<&str> { self.inner.specified_req() }

/// If none, this dependencies must be built for all platforms.
/// If some, it must only be built for the specified platform.
pub fn only_for_platform(&self) -> Option<&str> {
self.inner.only_for_platform()
}

/// Lock this dependency to depending on the specified package id
pub fn lock_to(self, id: &PackageId) -> Dependency {
self.clone_inner().lock_to(id).into_dependency()
}

/// Returns false if the dependency is only used to build the local package.
pub fn is_transitive(&self) -> bool { self.inner.is_transitive() }
pub fn is_build(&self) -> bool { self.inner.is_build() }
pub fn is_optional(&self) -> bool { self.inner.is_optional() }
/// Returns true if the default features of the dependency are requested.
pub fn uses_default_features(&self) -> bool {
self.inner.uses_default_features()
}
/// Returns the list of features that are requested by the dependency.
pub fn features(&self) -> &[String] { self.inner.features() }

/// Returns true if the package (`sum`) can fulfill this dependency request.
pub fn matches(&self, sum: &Summary) -> bool { self.inner.matches(sum) }

/// Returns true if the package (`id`) can fulfill this dependency request.
pub fn matches_id(&self, id: &PackageId) -> bool {
self.inner.matches_id(id)
}
}

#[derive(PartialEq,Clone,RustcEncodable)]
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub use self::dependency::Dependency;
pub use self::dependency::{Dependency, DependencyInner};
pub use self::manifest::{Manifest, Target, TargetKind, Profile, LibKind, Profiles};
pub use self::package::{Package, PackageSet};
pub use self::package_id::{PackageId, Metadata};
Expand Down
Loading

0 comments on commit ecafa40

Please sign in to comment.