Auto merge of #5029 - matklad:new-defaults-to-bin, r=withoutboats

New defaults to bin

So this switches `cargo new` default from `--lib` to `--bin`, as discussed on IRC.

The first two commits are just refactorings, and the last one actually flips the switch. Surprisingly enough, no tests need to be modified it seems!

r? @withoutboats
This commit is contained in:
bors 2018-02-13 11:03:57 +00:00
commit 5891aecf37
5 changed files with 55 additions and 56 deletions

View File

@ -32,8 +32,8 @@ Options:
control system (git, hg, pijul, or fossil) or do not control system (git, hg, pijul, or fossil) or do not
initialize any version control at all (none), overriding initialize any version control at all (none), overriding
a global configuration. a global configuration.
--bin Use a binary (application) template --bin Use a binary (application) template [default]
--lib Use a library template [default] --lib Use a library template
--name NAME Set the resulting package name --name NAME Set the resulting package name
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output) -v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout -q, --quiet No output printed to stdout
@ -59,14 +59,11 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
flag_bin, flag_bin,
flag_lib, flag_lib,
path, path,
flag_name.as_ref().map(|s| s.as_ref())); flag_name.as_ref().map(|s| s.as_ref()))?;
let opts_lib = opts.lib;
ops::init(&opts, config)?; ops::init(&opts, config)?;
config.shell().status("Created", format!("{} project", config.shell().status("Created", format!("{} project", opts.kind))?;
if opts_lib { "library" }
else {"binary (application)"}))?;
Ok(()) Ok(())
} }

View File

@ -32,8 +32,8 @@ Options:
control system (git, hg, pijul, or fossil) or do not control system (git, hg, pijul, or fossil) or do not
initialize any version control at all (none), overriding initialize any version control at all (none), overriding
a global configuration. a global configuration.
--bin Use a binary (application) template --bin Use a binary (application) template [default]
--lib Use a library template [default] --lib Use a library template
--name NAME Set the resulting package name, defaults to the value of <path> --name NAME Set the resulting package name, defaults to the value of <path>
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output) -v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout -q, --quiet No output printed to stdout
@ -58,15 +58,11 @@ pub fn execute(options: Options, config: &mut Config) -> CliResult {
flag_bin, flag_bin,
flag_lib, flag_lib,
&arg_path, &arg_path,
flag_name.as_ref().map(|s| s.as_ref())); flag_name.as_ref().map(|s| s.as_ref()))?;
let opts_lib = opts.lib;
ops::new(&opts, config)?; ops::new(&opts, config)?;
config.shell().status("Created", format!("{} `{}` project", config.shell().status("Created", format!("{} `{}` project", opts.kind, arg_path))?;
if opts_lib { "library" }
else {"binary (application)"},
arg_path))?;
Ok(()) Ok(())
} }

View File

@ -1,6 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::env; use std::env;
use std::fs; use std::fs;
use std::fmt;
use std::path::Path; use std::path::Path;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
@ -23,12 +24,32 @@ pub enum VersionControl { Git, Hg, Pijul, Fossil, NoVcs }
#[derive(Debug)] #[derive(Debug)]
pub struct NewOptions<'a> { pub struct NewOptions<'a> {
pub version_control: Option<VersionControl>, pub version_control: Option<VersionControl>,
pub bin: bool, pub kind: NewProjectKind,
pub lib: bool,
pub path: &'a str, pub path: &'a str,
pub name: Option<&'a str>, pub name: Option<&'a str>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum NewProjectKind {
Bin,
Lib,
}
impl NewProjectKind {
fn is_bin(&self) -> bool {
*self == NewProjectKind::Bin
}
}
impl fmt::Display for NewProjectKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
NewProjectKind::Bin => "binary (application)",
NewProjectKind::Lib => "library",
}.fmt(f)
}
}
struct SourceFileInformation { struct SourceFileInformation {
relative_path: String, relative_path: String,
target_name: String, target_name: String,
@ -65,23 +86,18 @@ impl<'a> NewOptions<'a> {
bin: bool, bin: bool,
lib: bool, lib: bool,
path: &'a str, path: &'a str,
name: Option<&'a str>) -> NewOptions<'a> { name: Option<&'a str>) -> CargoResult<NewOptions<'a>> {
// default to lib let kind = match (bin, lib) {
let is_lib = if !bin { (true, true) => bail!("can't specify both lib and binary outputs"),
true (true, false) => NewProjectKind::Bin,
} (false, true) => NewProjectKind::Lib,
else { // default to bin
lib (false, false) => NewProjectKind::Bin,
}; };
NewOptions { let opts = NewOptions { version_control, kind, path, name };
version_control: version_control, Ok(opts)
bin: bin,
lib: is_lib,
path: path,
name: name,
}
} }
} }
@ -127,7 +143,7 @@ fn check_name(name: &str, opts: &NewOptions) -> CargoResult<()> {
"super", "test", "trait", "true", "type", "typeof", "super", "test", "trait", "true", "type", "typeof",
"unsafe", "unsized", "use", "virtual", "where", "unsafe", "unsized", "use", "virtual", "where",
"while", "yield"]; "while", "yield"];
if blacklist.contains(&name) || (opts.bin && is_bad_artifact_name(name)) { if blacklist.contains(&name) || (opts.kind.is_bin() && is_bad_artifact_name(name)) {
bail!("The name `{}` cannot be used as a crate name{}", bail!("The name `{}` cannot be used as a crate name{}",
name, name,
name_help) name_help)
@ -269,10 +285,6 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
) )
} }
if opts.lib && opts.bin {
bail!("can't specify both lib and binary outputs")
}
let name = get_name(&path, opts)?; let name = get_name(&path, opts)?;
check_name(name, opts)?; check_name(name, opts)?;
@ -280,8 +292,8 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
version_control: opts.version_control, version_control: opts.version_control,
path: &path, path: &path,
name: name, name: name,
source_files: vec![plan_new_source_file(opts.bin, name.to_string())], source_files: vec![plan_new_source_file(opts.kind.is_bin(), name.to_string())],
bin: opts.bin, bin: opts.kind.is_bin(),
}; };
mk(config, &mkopts).chain_err(|| { mk(config, &mkopts).chain_err(|| {
@ -299,10 +311,6 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
bail!("`cargo init` cannot be run on existing Cargo projects") bail!("`cargo init` cannot be run on existing Cargo projects")
} }
if opts.lib && opts.bin {
bail!("can't specify both lib and binary outputs");
}
let name = get_name(&path, opts)?; let name = get_name(&path, opts)?;
check_name(name, opts)?; check_name(name, opts)?;
@ -311,7 +319,7 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
detect_source_paths_and_types(&path, name, &mut src_paths_types)?; detect_source_paths_and_types(&path, name, &mut src_paths_types)?;
if src_paths_types.is_empty() { if src_paths_types.is_empty() {
src_paths_types.push(plan_new_source_file(opts.bin, name.to_string())); src_paths_types.push(plan_new_source_file(opts.kind.is_bin(), name.to_string()));
} else { } else {
// --bin option may be ignored if lib.rs or src/lib.rs present // --bin option may be ignored if lib.rs or src/lib.rs present
// Maybe when doing `cargo init --bin` inside a library project stub, // Maybe when doing `cargo init --bin` inside a library project stub,
@ -353,9 +361,9 @@ pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
} }
let mkopts = MkOptions { let mkopts = MkOptions {
version_control: version_control, version_control,
path: &path, path: &path,
name: name, name,
bin: src_paths_types.iter().any(|x|x.bin), bin: src_paths_types.iter().any(|x|x.bin),
source_files: src_paths_types, source_files: src_paths_types,
}; };

View File

@ -7,7 +7,7 @@ $ cargo new hello_world --bin
``` ```
Were passing `--bin` because were making a binary program: if we Were passing `--bin` because were making a binary program: if we
were making a library, wed leave it off. were making a library, wed pass `--lib`.
Lets check out what Cargo has generated for us: Lets check out what Cargo has generated for us:

View File

@ -7,7 +7,7 @@ $ cargo new hello_world --bin
``` ```
Were passing `--bin` because were making a binary program: if we Were passing `--bin` because were making a binary program: if we
were making a library, wed leave it off. This also initializes a new `git` were making a library, wed pass `--lib`. This also initializes a new `git`
repository by default. If you don't want it to do that, pass `--vcs none`. repository by default. If you don't want it to do that, pass `--vcs none`.
Lets check out what Cargo has generated for us: Lets check out what Cargo has generated for us:
@ -23,9 +23,7 @@ $ tree .
1 directory, 2 files 1 directory, 2 files
``` ```
If we had just used `cargo new hello_world` without the `--bin` flag, then Lets take a closer look at `Cargo.toml`:
we would have a `lib.rs` instead of a `main.rs`. For now, however, this is all
we need to get started. First, lets check out `Cargo.toml`:
```toml ```toml
[package] [package]