Skip to content

Commit bdce1f5

Browse files
committed
Auto merge of #3767 - ehiggs:fix-init-bin-lib-section, r=alexcrichton
Fix for #3722 When using init, add [[bin]] and [lib] section where appropriate.
2 parents ef8fa8f + 8e4b8b2 commit bdce1f5

File tree

2 files changed

+90
-24
lines changed

2 files changed

+90
-24
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use term::color::BLACK;
1010

1111
use handlebars::{Handlebars, no_escape};
1212
use tempdir::TempDir;
13+
use toml;
1314

1415
use core::Workspace;
1516
use sources::git::clone;
@@ -44,6 +45,7 @@ struct MkOptions<'a> {
4445
path: &'a Path,
4546
name: &'a str,
4647
bin: bool,
48+
source_files: Vec<SourceFileInformation>,
4749
}
4850

4951
impl Decodable for VersionControl {
@@ -127,11 +129,40 @@ fn get_input_template(config: &Config, opts: &MkOptions) -> CargoResult<Template
127129
// no template given, use either "lib" or "bin" templates depending on the
128130
// presence of the --bin flag.
129131
TemplateType::Builtin => {
130-
let template_files = if opts.bin {
131-
create_bin_template()
132-
} else {
133-
create_lib_template()
132+
133+
134+
let mut cargotoml_path_specifier = String::new();
135+
// If the main function is in a weird location, let Cargo.toml know.
136+
// Otherwise, if the library files are somewhere else, let Cargo.toml know.
137+
for i in &opts.source_files {
138+
if i.bin {
139+
if i.relative_path != "src/main.rs" {
140+
cargotoml_path_specifier.push_str(&format!(r#"
141+
[[bin]]
142+
name = "{}"
143+
path = {}
144+
"#, i.target_name, toml::Value::String(i.relative_path.clone())));
145+
}
146+
} else {
147+
if i.relative_path != "src/lib.rs" {
148+
cargotoml_path_specifier.push_str(&format!(r#"
149+
[lib]
150+
name = "{}"
151+
path = {}
152+
"#, i.target_name, toml::Value::String(i.relative_path.clone())));
153+
}
154+
}
155+
}
156+
157+
let mut template_files = create_generic_template(&cargotoml_path_specifier);
158+
let mut source_files = match (opts.bin, cargotoml_path_specifier.len()) {
159+
(true, 0) => create_bin_template(),
160+
(true, _) => vec![],
161+
(false, 0) => create_lib_template(),
162+
(false, _) => vec![],
134163
};
164+
template_files.extend(source_files.drain(..));
165+
135166
TemplateSet {
136167
template_dir: None,
137168
template_files: template_files
@@ -338,6 +369,7 @@ pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> {
338369
path: &path,
339370
name: name,
340371
bin: opts.bin,
372+
source_files: vec![],
341373
};
342374

343375
mk(config, &mkopts).chain_error(|| {
@@ -405,6 +437,7 @@ pub fn init(opts: NewOptions, config: &Config) -> CargoResult<()> {
405437
path: &path,
406438
name: name,
407439
bin: src_paths_types.iter().any(|x|x.bin),
440+
source_files: src_paths_types,
408441
};
409442

410443
mk(config, &mkopts).chain_error(|| {
@@ -657,40 +690,38 @@ fn walk_template_dir(dir: &Path, cb: &mut FnMut(DirEntry) -> CargoResult<()>) ->
657690
/// Create a generic template
658691
///
659692
/// This consists of a Cargo.toml, and a src directory.
660-
fn create_generic_template() -> Vec<Box<TemplateFile>> {
661-
let template_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("Cargo.toml"),
662-
String::from(r#"[package]
693+
fn create_generic_template(extra_cargo_info: &str) -> Vec<Box<TemplateFile>> {
694+
let mut cargo_toml_contents = String::from(r#"[package]
663695
name = "{{name}}"
664696
version = "0.1.0"
665697
authors = [{{toml-escape author}}]
666698
667699
[dependencies]
668-
"#)));
700+
"#);
701+
cargo_toml_contents.push_str(extra_cargo_info);
702+
let template_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("Cargo.toml"),
703+
cargo_toml_contents));
669704
vec![template_file]
670705
}
671706

672707
/// Create a new "lib" project
673708
fn create_lib_template() -> Vec<Box<TemplateFile>> {
674-
let mut template_files = create_generic_template();
675709
let lib_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("src/lib.rs"),
676710
String::from(r#"#[test]
677711
fn it_works() {
678712
}
679713
"#)));
680-
template_files.push(lib_file);
681-
template_files
714+
vec![lib_file]
682715
}
683716

684717
/// Create a new "bin" project
685718
fn create_bin_template() -> Vec<Box<TemplateFile>> {
686-
let mut template_files = create_generic_template();
687719
let main_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("src/main.rs"),
688720
String::from("fn main() {
689721
println!(\"Hello, world!\");
690722
}
691723
")));
692-
template_files.push(main_file);
693-
template_files
724+
vec![main_file]
694725
}
695726

696727
#[cfg(test)]

tests/init.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fn both_lib_and_bin() {
6363
"[ERROR] can't specify both lib and binary outputs"));
6464
}
6565

66-
fn bin_already_exists(explicit: bool, rellocation: &str) {
66+
fn bin_already_exists(explicit: bool, rellocation: &str, needs_bin_section: bool) {
6767
let path = paths::root().join("foo");
6868
fs::create_dir_all(&path.join("src")).unwrap();
6969

@@ -94,36 +94,48 @@ fn bin_already_exists(explicit: bool, rellocation: &str) {
9494
let mut new_content = Vec::new();
9595
File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
9696
assert_eq!(Vec::from(content as &[u8]), new_content);
97+
98+
let mut cargo_content = String::new();
99+
File::open(&paths::root().join("foo/Cargo.toml")).unwrap()
100+
.read_to_string(&mut cargo_content).unwrap();
101+
// Check that Cargo.toml has a bin section pointing to the correct location (if needed)
102+
if needs_bin_section {
103+
assert!(cargo_content.contains(r#"[[bin]]"#));
104+
assert_that(&paths::root().join("foo/src/main.rs"), is_not(existing_file()));
105+
} else {
106+
assert!(!cargo_content.contains(r#"[[bin]]"#));
107+
assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
108+
}
97109
}
98110

99111
#[test]
100112
fn bin_already_exists_explicit() {
101-
bin_already_exists(true, "src/main.rs")
113+
bin_already_exists(true, "src/main.rs", false)
102114
}
103115

104116
#[test]
105117
fn bin_already_exists_implicit() {
106-
bin_already_exists(false, "src/main.rs")
118+
bin_already_exists(false, "src/main.rs", false)
107119
}
108120

109121
#[test]
110122
fn bin_already_exists_explicit_nosrc() {
111-
bin_already_exists(true, "main.rs")
123+
bin_already_exists(true, "main.rs", true)
112124
}
113125

114126
#[test]
115127
fn bin_already_exists_implicit_nosrc() {
116-
bin_already_exists(false, "main.rs")
128+
bin_already_exists(false, "main.rs", true)
117129
}
118130

119131
#[test]
120132
fn bin_already_exists_implicit_namenosrc() {
121-
bin_already_exists(false, "foo.rs")
133+
bin_already_exists(false, "foo.rs", true)
122134
}
123135

124136
#[test]
125137
fn bin_already_exists_implicit_namesrc() {
126-
bin_already_exists(false, "src/foo.rs")
138+
bin_already_exists(false, "src/foo.rs", true)
127139
}
128140

129141
#[test]
@@ -190,7 +202,7 @@ cannot automatically generate Cargo.toml as the main target would be ambiguous
190202
assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
191203
}
192204

193-
fn lib_already_exists(rellocation: &str) {
205+
fn lib_already_exists(rellocation: &str, needs_lib_section: bool) {
194206
let path = paths::root().join("foo");
195207
fs::create_dir_all(&path.join("src")).unwrap();
196208

@@ -213,16 +225,39 @@ fn lib_already_exists(rellocation: &str) {
213225
let mut new_content = Vec::new();
214226
File::open(&sourcefile_path).unwrap().read_to_end(&mut new_content).unwrap();
215227
assert_eq!(Vec::from(content as &[u8]), new_content);
228+
229+
let mut cargo_content = String::new();
230+
File::open(&paths::root().join("foo/Cargo.toml")).unwrap()
231+
.read_to_string(&mut cargo_content).unwrap();
232+
// Check that Cargo.toml has a lib section pointing to the correct location (if needed)
233+
if needs_lib_section {
234+
assert!(cargo_content.contains(r#"[lib]"#));
235+
assert_that(&paths::root().join("foo/src/lib.rs"), is_not(existing_file()));
236+
} else {
237+
assert!(!cargo_content.contains(r#"[lib]"#));
238+
assert_that(&paths::root().join("foo/src/lib.rs"), existing_file());
239+
}
240+
216241
}
217242

218243
#[test]
219244
fn lib_already_exists_src() {
220-
lib_already_exists("src/lib.rs")
245+
lib_already_exists("src/lib.rs", false)
221246
}
222247

223248
#[test]
224249
fn lib_already_exists_nosrc() {
225-
lib_already_exists("lib.rs")
250+
lib_already_exists("lib.rs", true)
251+
}
252+
253+
#[test]
254+
fn no_lib_already_exists_src_add_lib_section() {
255+
lib_already_exists("src/foo.rs", true)
256+
}
257+
258+
#[test]
259+
fn no_lib_already_exists_nosrc_add_lib_section() {
260+
lib_already_exists("foo.rs", true)
226261
}
227262

228263
#[test]

0 commit comments

Comments
 (0)