Remove dependence on various plugins

It's looking more likely like plugins will not make it into the stable channel
of Rust, so this commits removes Cargo's personal dependence on the two
plugin-based pieces of functionality it was using:

1. Uses of the `regex!` macro now go through `Regex::new`.
2. Uses of the `docopt!` macro now go through `deriving(Decodable)` instead.
This commit is contained in:
Alex Crichton 2014-10-17 15:04:13 -07:00
parent c3fd7d034a
commit 3512d99749
28 changed files with 262 additions and 146 deletions

13
Cargo.lock generated
View File

@ -3,8 +3,7 @@ name = "cargo"
version = "0.0.1-pre"
dependencies = [
"curl 0.0.1 (git+https://github.com/alexcrichton/curl-rust?ref=bundle#1d43e08f629dc22ffbc99d7ea8e97dfc7ab0b91a)",
"docopt 0.6.4 (git+https://github.com/docopt/docopt.rs#db3abbb1d55aec986daefcf4b6131a61ff78513c)",
"docopt_macros 0.6.4 (git+https://github.com/docopt/docopt.rs#db3abbb1d55aec986daefcf4b6131a61ff78513c)",
"docopt 0.6.4 (git+https://github.com/docopt/docopt.rs#4544a9f422b115c2ffef4ee9baf27ceb07c34602)",
"flate2 0.0.1 (git+https://github.com/alexcrichton/flate2-rs#68971ae77a523c7ec3f19b4bcd195f76291ea390)",
"git2 0.0.1 (git+https://github.com/alexcrichton/git2-rs#c01b0b279470552c48cf7f902ae5baf132df0a6d)",
"glob 0.0.1 (git+https://github.com/rust-lang/glob#27338cbd4736d3c8146294fc090c6f8f06c32d72)",
@ -33,15 +32,7 @@ source = "git+https://github.com/alexcrichton/curl-rust?ref=bundle#1d43e08f629dc
[[package]]
name = "docopt"
version = "0.6.4"
source = "git+https://github.com/docopt/docopt.rs#db3abbb1d55aec986daefcf4b6131a61ff78513c"
[[package]]
name = "docopt_macros"
version = "0.6.4"
source = "git+https://github.com/docopt/docopt.rs#db3abbb1d55aec986daefcf4b6131a61ff78513c"
dependencies = [
"docopt 0.6.4 (git+https://github.com/docopt/docopt.rs#db3abbb1d55aec986daefcf4b6131a61ff78513c)",
]
source = "git+https://github.com/docopt/docopt.rs#4544a9f422b115c2ffef4ee9baf27ceb07c34602"
[[package]]
name = "encoding"

View File

@ -11,9 +11,6 @@ path = "src/cargo/lib.rs"
[dependencies.docopt]
git = "https://github.com/docopt/docopt.rs"
[dependencies.docopt_macros]
git = "https://github.com/docopt/docopt.rs"
[dependencies.toml]
git = "https://github.com/alexcrichton/toml-rs"

View File

@ -4,9 +4,21 @@ use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError, CargoError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
use docopt;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_no_run: bool,
flag_package: Option<String>,
flag_jobs: Option<uint>,
flag_features: Vec<String>,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
arg_args: Vec<String>,
}
pub const USAGE: &'static str = "
Execute all benchmarks of a local package
Usage:
@ -31,9 +43,7 @@ If the --package argument is given, then SPEC is a package id specification
which indicates which package should be benchmarked. If it is not given, then
the current package is benchmarked. For more information on SPEC and its format,
see the `cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
flag_manifest_path: Option<String>, flag_features: Vec<String>,
flag_package: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));

View File

@ -5,9 +5,20 @@ use cargo::ops::CompileOptions;
use cargo::ops;
use cargo::util::important_paths::{find_root_manifest_for_cwd};
use cargo::util::{CliResult, CliError};
use docopt;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_package: Option<String>,
flag_jobs: Option<uint>,
flag_features: Vec<String>,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
flag_release: bool,
}
pub const USAGE: &'static str = "
Compile a local package and all of its dependencies
Usage:
@ -28,9 +39,7 @@ If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
current package is built. For more information on SPEC and its format, see the
`cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
flag_manifest_path: Option<String>, flag_features: Vec<String>,
flag_package: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-build; args={}", os::args());

View File

@ -1,28 +1,30 @@
#![feature(phase, macro_rules)]
#![deny(unused)]
extern crate serialize;
#[phase(plugin, link)] extern crate log;
extern crate cargo;
extern crate docopt;
#[phase(plugin)] extern crate docopt_macros;
use std::collections::TreeSet;
use std::os;
use std::io;
use std::io::fs::{mod, PathExtensions};
use std::io::process::{Command,InheritFd,ExitStatus,ExitSignal};
use docopt::FlagParser;
use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
use cargo::util::{CliError, CliResult};
fn main() {
execute_main_without_stdin(execute, true)
#[deriving(Decodable)]
struct Flags {
flag_list: bool,
flag_verbose: bool,
arg_command: String,
arg_args: Vec<String>,
}
docopt!(Flags, "
const USAGE: &'static str = "
Rust's package manager
Usage:
@ -46,7 +48,11 @@ Some common cargo commands are:
update Update dependencies listed in Cargo.lock
See 'cargo help <command>' for more information on a specific command.
")
";
fn main() {
execute_main_without_stdin(execute, true, USAGE)
}
macro_rules! each_subcommand( ($macro:ident) => ({
$macro!(bench)
@ -93,7 +99,7 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
let (mut args, command) = match flags.arg_command.as_slice() {
"" | "help" if flags.arg_args.len() == 0 => {
shell.set_verbose(true);
let r = cargo::call_main_without_stdin(execute, shell,
let r = cargo::call_main_without_stdin(execute, shell, USAGE,
["-h".to_string()], false);
cargo::process_executed(r, shell);
return Ok(None)
@ -108,6 +114,7 @@ fn execute(flags: Flags, shell: &mut MultiShell) -> CliResult<Option<()>> {
mod $name;
shell.set_verbose(true);
let r = cargo::call_main_without_stdin($name::execute, shell,
$name::USAGE,
args.as_slice(),
false);
cargo::process_executed(r, shell);

View File

@ -1,12 +1,19 @@
use std::os;
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_package: Option<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Remove artifacts that cargo has generated in the past
Usage:
@ -23,8 +30,7 @@ If the --package argument is given, then SPEC is a package id specification
which indicates which package's artifacts should be cleaned out. If it is not
given, then all packages' artifacts are removed. For more information on SPEC
and its format, see the `cargo help pkgid` command.
", flag_manifest_path: Option<String>, flag_package: Option<String>,
flag_target: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,23 +1,28 @@
use std::os;
use std::collections::HashMap;
use docopt;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError, config};
#[deriving(Decodable)]
struct ConfigForKeyFlags {
flag_human: bool,
flag_key: String,
}
#[deriving(Encodable)]
struct ConfigOut {
values: HashMap<String, config::ConfigValue>
}
docopt!(ConfigForKeyFlags, "
pub const USAGE: &'static str = "
Usage:
cargo config-for-key --human --key=<key>
cargo config-for-key -h | --help
Options:
-h, --help Print this message
")
";
pub fn execute(args: ConfigForKeyFlags,
_: &mut MultiShell) -> CliResult<Option<ConfigOut>> {

View File

@ -1,23 +1,27 @@
use std::os;
use std::collections::HashMap;
use docopt;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError, config};
#[deriving(Decodable)]
struct ConfigListFlags {
flag_human: bool,
}
#[deriving(Encodable)]
struct ConfigOut {
values: HashMap<String, config::ConfigValue>
}
docopt!(ConfigListFlags, "
pub const USAGE: &'static str = "
Usage:
cargo config-list --human
cargo config-list -h | --help
Options:
-h, --help Print this message
")
";
pub fn execute(args: ConfigListFlags,
_: &mut MultiShell) -> CliResult<Option<ConfigOut>> {

View File

@ -1,11 +1,20 @@
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_features: Vec<String>,
flag_jobs: Option<uint>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_no_deps: bool,
flag_open: bool,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Build a package's documentation
Usage:
@ -23,9 +32,7 @@ Options:
By default the documentation for the local package and all dependencies is
built. The output is all placed in `target/doc` in rustdoc's usual format.
", flag_jobs: Option<uint>,
flag_manifest_path: Option<String>,
flag_features: Vec<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,11 +1,15 @@
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::find_root_manifest_for_cwd;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_manifest_path: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Fetch dependencies of a package from the network.
Usage:
@ -24,7 +28,7 @@ the lockfile changes.
If the lockfile is not available, then this is the equivalent of
`cargo generate-lockfile`. A lockfile is generated and dependencies are also
all updated.
", flag_manifest_path: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,12 +1,17 @@
use std::os;
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::find_root_manifest_for_cwd;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_manifest_path: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Generate the lockfile for a project
Usage:
@ -16,7 +21,7 @@ Options:
-h, --help Print this message
--manifest-path PATH Path to the manifest to generate a lockfile for
-v, --verbose Use verbose output
", flag_manifest_path: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-generate-lockfile; args={}", os::args());

View File

@ -1,11 +1,16 @@
use docopt;
use cargo::core::MultiShell;
use cargo::core::source::{Source, SourceId};
use cargo::sources::git::{GitSource};
use cargo::util::{Config, CliResult, CliError, human, ToUrl};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_url: String,
flag_reference: String,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Usage:
cargo git-checkout [options] --url=URL --reference=REF
cargo git-checkout -h | --help
@ -13,9 +18,10 @@ Usage:
Options:
-h, --help Print this message
-v, --verbose Use verbose output
")
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);
let Options { flag_url: url, flag_reference: reference, .. } = options;
let url = try!(url.as_slice().to_url().map_err(|e| {

View File

@ -1,9 +1,10 @@
use docopt;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
docopt!(Options, "
#[deriving(Decodable)]
struct Options;
pub const USAGE: &'static str = "
Get some help with a cargo command.
Usage:
@ -12,7 +13,7 @@ Usage:
Options:
-h, --help Print this message
")
";
pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
// This is a dummy command just so that `cargo help help` works.

View File

@ -1,17 +1,20 @@
use docopt;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError, human, Require};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(LocateProjectFlags, "
#[deriving(Decodable)]
struct LocateProjectFlags {
flag_manifest_path: Option<String>,
}
pub const USAGE: &'static str = "
Usage:
cargo locate-project [options]
Options:
--manifest-path PATH Path to the manifest to build benchmarks for
-h, --help Print this message
", flag_manifest_path: Option<String>)
";
#[deriving(Encodable)]
struct ProjectLocation {

View File

@ -1,12 +1,18 @@
use std::io;
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::sources::RegistrySource;
use cargo::util::{CliResult, CliError};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_host: Option<String>,
arg_token: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Save an api token from the registry locally
Usage:
@ -17,7 +23,7 @@ Options:
--host HOST Host to set the token for
-v, --verbose Use verbose output
", arg_token: Option<String>, flag_host: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,11 +1,21 @@
use std::os;
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_verbose: bool,
flag_bin: bool,
flag_travis: bool,
flag_hg: bool,
flag_git: bool,
flag_no_git: bool,
arg_path: String,
}
pub const USAGE: &'static str = "
Create a new cargo package at <path>
Usage:
@ -21,7 +31,7 @@ Options:
--travis Create a .travis.yml file
--bin Use a binary instead of a library template
-v, --verbose Use verbose output
")
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-new; args={}", os::args());

View File

@ -1,10 +1,15 @@
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::find_root_manifest_for_cwd;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_verbose: bool,
flag_manifest_path: Option<String>,
}
pub const USAGE: &'static str = "
Assemble a the local package into a distributable tarball
Usage:
@ -15,7 +20,7 @@ Options:
--manifest-path PATH Path to the manifest to compile
-v, --verbose Use verbose output
", flag_manifest_path: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,11 +1,16 @@
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_verbose: bool,
flag_manifest_path: Option<String>,
arg_spec: Option<String>,
}
pub const USAGE: &'static str = "
Print a fully qualified package specification
Usage:
@ -35,7 +40,7 @@ Example Package IDs
crates.io/bar#foo:1.2.3 | foo | 1.2.3 | *://crates.io/bar
http://crates.io/foo#1.2.3 | foo | 1.2.3 | http://crates.io/foo
", flag_manifest_path: Option<String>, arg_spec: Option<String>)
";
pub fn execute(options: Options,
shell: &mut MultiShell) -> CliResult<Option<()>> {

View File

@ -1,10 +1,13 @@
use docopt;
use cargo::core::{MultiShell, Package, Source};
use cargo::util::{CliResult, CliError};
use cargo::sources::{PathSource};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_manifest_path: String,
}
pub const USAGE: &'static str = "
Usage:
cargo read-manifest [options] --manifest-path=PATH
cargo read-manifest -h | --help
@ -12,7 +15,7 @@ Usage:
Options:
-h, --help Print this message
-v, --verbose Use verbose output
")
";
pub fn execute(options: Options, _: &mut MultiShell) -> CliResult<Option<Package>> {
let path = Path::new(options.flag_manifest_path.as_slice());

View File

@ -1,12 +1,23 @@
use std::io::process::ExitStatus;
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_jobs: Option<uint>,
flag_features: Vec<String>,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
flag_release: bool,
arg_args: Vec<String>,
}
pub const USAGE: &'static str = "
Run the main binary of the local package (src/main.rs)
Usage:
@ -23,8 +34,7 @@ Options:
-v, --verbose Use verbose output
All of the trailing arguments are passed as to the binary to run.
", flag_jobs: Option<uint>, flag_target: Option<String>,
flag_manifest_path: Option<String>, flag_features: Vec<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -1,12 +1,24 @@
use std::io::process::ExitStatus;
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError, CargoError};
use cargo::util::important_paths::{find_root_manifest_for_cwd};
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
arg_args: Vec<String>,
flag_features: Vec<String>,
flag_jobs: Option<uint>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_no_run: bool,
flag_package: Option<String>,
flag_target: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Execute all unit and integration tests of a local package
Usage:
@ -30,9 +42,7 @@ If the --package argument is given, then SPEC is a package id specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
flag_manifest_path: Option<String>, flag_features: Vec<String>,
flag_package: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));

View File

@ -1,12 +1,21 @@
use std::os;
use docopt;
use cargo::ops;
use cargo::core::MultiShell;
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::find_root_manifest_for_cwd;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
arg_spec: Option<String>,
flag_package: Option<String>,
flag_aggressive: bool,
flag_precise: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Update dependencies as recorded in the local lock file.
Usage:
@ -40,8 +49,7 @@ If SPEC is not given, then all dependencies will be re-resolved and
updated.
For more information about package id specifications, see `cargo help pkgid`.
", flag_manifest_path: Option<String>, arg_spec: Option<String>,
flag_precise: Option<String>, flag_package: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-update; args={}", os::args());

View File

@ -1,11 +1,17 @@
use docopt;
use cargo::ops;
use cargo::core::{MultiShell};
use cargo::util::{CliResult, CliError};
use cargo::util::important_paths::find_root_manifest_for_cwd;
docopt!(Options, "
#[deriving(Decodable)]
struct Options {
flag_host: Option<String>,
flag_token: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Upload a package to the registry
Usage:
@ -18,8 +24,7 @@ Options:
--manifest-path PATH Path to the manifest to compile
-v, --verbose Use verbose output
", flag_host: Option<String>, flag_token: Option<String>,
flag_manifest_path: Option<String>)
";
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
shell.set_verbose(options.flag_verbose);

View File

@ -3,14 +3,19 @@ extern crate toml;
use std::collections::HashMap;
use std::io::File;
use std::os;
use docopt;
use cargo::core::MultiShell;
use cargo::util::CliResult;
pub type Error = HashMap<String, String>;
docopt!(Flags, "
#[deriving(Decodable)]
struct Flags {
flag_manifest_path: String,
flag_verbose: bool,
}
pub const USAGE: &'static str = "
Usage:
cargo verify-project [options] --manifest-path PATH
cargo verify-project -h | --help
@ -19,7 +24,7 @@ Options:
-h, --help Print this message
--manifest-path PATH Path to the manifest to verify
-v, --verbose Use verbose output
")
";
pub fn execute(args: Flags,
shell: &mut MultiShell) -> CliResult<Option<Error>> {

View File

@ -1,18 +1,20 @@
use std::os;
use docopt;
use cargo;
use cargo::core::MultiShell;
use cargo::util::CliResult;
docopt!(Options, "
#[deriving(Decodable)]
struct Options;
pub const USAGE: &'static str = "
Usage:
cargo version [options]
Options:
-h, --help Print this message
-v, --verbose Use verbose output
")
";
pub fn execute(_: Options, _: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-version; args={}", os::args());

View File

@ -4,6 +4,8 @@ use std::fmt::{mod, Show, Formatter};
use std::hash;
use serialize::{Encodable, Encoder, Decodable, Decoder};
use regex::Regex;
use util::{CargoResult, CargoError, short_hash, ToSemver};
use core::source::SourceId;
@ -25,7 +27,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for PackageId {
impl<E, D: Decoder<E>> Decodable<D, E> for PackageId {
fn decode(d: &mut D) -> Result<PackageId, E> {
let string: String = raw_try!(Decodable::decode(d));
let regex = regex!(r"^([^ ]+) ([^ ]+) \(([^\)]+)\)$");
let regex = Regex::new(r"^([^ ]+) ([^ ]+) \(([^\)]+)\)$").unwrap();
let captures = regex.captures(string.as_slice()).expect("invalid serialized PackageId");
let name = captures.at(1);

View File

@ -1,7 +1,8 @@
use std::collections::hashmap::{HashMap, HashSet, Occupied, Vacant};
use std::fmt;
use semver;
use regex::Regex;
use semver;
use serialize::{Encodable, Encoder, Decodable, Decoder};
use core::{PackageId, Registry, SourceId, Summary, Dependency};
@ -107,7 +108,7 @@ impl<E, S: Encoder<E>> Encodable<S, E> for EncodablePackageId {
impl<E, D: Decoder<E>> Decodable<D, E> for EncodablePackageId {
fn decode(d: &mut D) -> Result<EncodablePackageId, E> {
let string: String = raw_try!(Decodable::decode(d));
let regex = regex!(r"^([^ ]+) ([^ ]+)(?: \(([^\)]+)\))?$");
let regex = Regex::new(r"^([^ ]+) ([^ ]+)(?: \(([^\)]+)\))?$").unwrap();
let captures = regex.captures(string.as_slice())
.expect("invalid serialized PackageId");

View File

@ -11,7 +11,6 @@ extern crate regex;
extern crate serialize;
extern crate term;
extern crate time;
#[phase(plugin)] extern crate regex_macros;
#[phase(plugin, link)] extern crate log;
extern crate curl;
@ -29,7 +28,6 @@ use std::os;
use std::io::stdio::{stdout_raw, stderr_raw};
use std::io::{mod, stdout, stderr};
use serialize::{Decoder, Encoder, Decodable, Encodable, json};
use docopt::FlagParser;
use core::{Shell, MultiShell, ShellConfig};
use term::color::{BLACK};
@ -82,51 +80,49 @@ pub trait RepresentsJSON : Decodable<json::Decoder, json::DecoderError> {}
impl<T: Decodable<json::Decoder, json::DecoderError>> RepresentsJSON for T {}
pub fn execute_main<'a,
T: FlagParser,
T: Decodable<docopt::Decoder, docopt::Error>,
U: RepresentsJSON,
V: Encodable<json::Encoder<'a>, io::IoError>>(
exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
options_first: bool) {
// see comments below
off_the_main_thread(proc() {
process::<V>(|rest, shell| call_main(exec, shell, rest, options_first));
});
options_first: bool,
usage: &str) {
process::<V>(|rest, shell| call_main(exec, shell, usage, rest, options_first));
}
pub fn call_main<'a,
T: FlagParser,
T: Decodable<docopt::Decoder, docopt::Error>,
U: RepresentsJSON,
V: Encodable<json::Encoder<'a>, io::IoError>>(
exec: fn(T, U, &mut MultiShell) -> CliResult<Option<V>>,
shell: &mut MultiShell,
usage: &str,
args: &[String],
options_first: bool) -> CliResult<Option<V>> {
let flags = try!(flags_from_args::<T>(args, options_first));
let flags = try!(flags_from_args::<T>(usage, args, options_first));
let json = try!(json_from_stdin::<U>());
exec(flags, json, shell)
}
pub fn execute_main_without_stdin<'a,
T: FlagParser,
T: Decodable<docopt::Decoder, docopt::Error>,
V: Encodable<json::Encoder<'a>, io::IoError>>(
exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
options_first: bool) {
// see comments below
off_the_main_thread(proc() {
process::<V>(|rest, shell| call_main_without_stdin(exec, shell, rest,
options_first));
});
options_first: bool,
usage: &str) {
process::<V>(|rest, shell| call_main_without_stdin(exec, shell, usage, rest,
options_first));
}
pub fn call_main_without_stdin<'a,
T: FlagParser,
T: Decodable<docopt::Decoder, docopt::Error>,
V: Encodable<json::Encoder<'a>, io::IoError>>(
exec: fn(T, &mut MultiShell) -> CliResult<Option<V>>,
shell: &mut MultiShell,
usage: &str,
args: &[String],
options_first: bool) -> CliResult<Option<V>> {
let flags = try!(flags_from_args::<T>(args, options_first));
let flags = try!(flags_from_args::<T>(usage, args, options_first));
exec(flags, shell)
}
@ -221,15 +217,21 @@ pub fn version() -> String {
})
}
fn flags_from_args<T: FlagParser>(args: &[String],
options_first: bool) -> CliResult<T> {
fn flags_from_args<'a, T>(usage: &str, args: &[String],
options_first: bool) -> CliResult<T>
where T: Decodable<docopt::Decoder, docopt::Error> {
let args = args.iter().map(|a| a.as_slice()).collect::<Vec<&str>>();
let config = docopt::Config {
options_first: options_first,
help: true,
version: Some(version()),
};
FlagParser::parse_args(config, args.as_slice()).map_err(|e| {
let value_map = try!(docopt::docopt_args(config, args.as_slice(),
usage).map_err(|e| {
let code = if e.fatal() {1} else {0};
CliError::from_error(e, code)
}));
value_map.decode().map_err(|e| {
let code = if e.fatal() {1} else {0};
CliError::from_error(e, code)
})
@ -250,16 +252,3 @@ fn json_from_stdin<T: RepresentsJSON>() -> CliResult<T> {
CliError::new("Could not process standard in as input", 1)
})
}
// Seems curious to run cargo off the main thread, right? Well do I have a story
// for you. Turns out rustdoc does a similar thing, and already has a good
// explanation [1] though, so I'll just point you over there.
//
// [1]: https://github.com/rust-lang/rust/blob/85fd37f/src/librustdoc/lib.rs#L92-L122
fn off_the_main_thread(p: proc():Send) {
let (tx, rx) = channel();
spawn(proc() { p(); tx.send(()); });
if rx.recv_opt().is_err() {
std::os::set_exit_status(std::rt::DEFAULT_ERROR_CODE);
}
}