Skip to content

Commit 7e80c68

Browse files
committed
Fix for #3722
When using init, add [[bin]] and [lib] section where appropriate.
1 parent 163de44 commit 7e80c68

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed

src/cargo/ops/cargo_new.rs

+45-14
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(|| {
@@ -659,40 +692,38 @@ fn walk_template_dir(dir: &Path, cb: &mut FnMut(DirEntry) -> CargoResult<()>) ->
659692
/// Create a generic template
660693
///
661694
/// This consists of a Cargo.toml, and a src directory.
662-
fn create_generic_template() -> Vec<Box<TemplateFile>> {
663-
let template_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("Cargo.toml"),
664-
String::from(r#"[package]
695+
fn create_generic_template(extra_cargo_info: &str) -> Vec<Box<TemplateFile>> {
696+
let mut cargo_toml_contents = String::from(r#"[package]
665697
name = "{{name}}"
666698
version = "0.1.0"
667699
authors = [{{toml-escape author}}]
668700
669701
[dependencies]
670-
"#)));
702+
"#);
703+
cargo_toml_contents.push_str(extra_cargo_info);
704+
let template_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("Cargo.toml"),
705+
cargo_toml_contents));
671706
vec![template_file]
672707
}
673708

674709
/// Create a new "lib" project
675710
fn create_lib_template() -> Vec<Box<TemplateFile>> {
676-
let mut template_files = create_generic_template();
677711
let lib_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("src/lib.rs"),
678712
String::from(r#"#[test]
679713
fn it_works() {
680714
}
681715
"#)));
682-
template_files.push(lib_file);
683-
template_files
716+
vec![lib_file]
684717
}
685718

686719
/// Create a new "bin" project
687720
fn create_bin_template() -> Vec<Box<TemplateFile>> {
688-
let mut template_files = create_generic_template();
689721
let main_file = Box::new(InMemoryTemplateFile::new(PathBuf::from("src/main.rs"),
690722
String::from("fn main() {
691723
println!(\"Hello, world!\");
692724
}
693725
")));
694-
template_files.push(main_file);
695-
template_files
726+
vec![main_file]
696727
}
697728

698729
#[cfg(test)]

tests/init.rs

+43-10
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,47 @@ 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().read_to_string(&mut cargo_content).unwrap();
100+
// Check that Cargo.toml has a bin section pointing to the correct location (if needed)
101+
if needs_bin_section {
102+
assert!(cargo_content.contains(r#"[[bin]]"#));
103+
assert_that(&paths::root().join("foo/src/main.rs"), is_not(existing_file()));
104+
} else {
105+
assert!(!cargo_content.contains(r#"[[bin]]"#));
106+
assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
107+
}
97108
}
98109

99110
#[test]
100111
fn bin_already_exists_explicit() {
101-
bin_already_exists(true, "src/main.rs")
112+
bin_already_exists(true, "src/main.rs", false)
102113
}
103114

104115
#[test]
105116
fn bin_already_exists_implicit() {
106-
bin_already_exists(false, "src/main.rs")
117+
bin_already_exists(false, "src/main.rs", false)
107118
}
108119

109120
#[test]
110121
fn bin_already_exists_explicit_nosrc() {
111-
bin_already_exists(true, "main.rs")
122+
bin_already_exists(true, "main.rs", true)
112123
}
113124

114125
#[test]
115126
fn bin_already_exists_implicit_nosrc() {
116-
bin_already_exists(false, "main.rs")
127+
bin_already_exists(false, "main.rs", true)
117128
}
118129

119130
#[test]
120131
fn bin_already_exists_implicit_namenosrc() {
121-
bin_already_exists(false, "foo.rs")
132+
bin_already_exists(false, "foo.rs", true)
122133
}
123134

124135
#[test]
125136
fn bin_already_exists_implicit_namesrc() {
126-
bin_already_exists(false, "src/foo.rs")
137+
bin_already_exists(false, "src/foo.rs", true)
127138
}
128139

129140
#[test]
@@ -190,7 +201,7 @@ cannot automatically generate Cargo.toml as the main target would be ambiguous
190201
assert_that(&paths::root().join("foo/Cargo.toml"), is_not(existing_file()));
191202
}
192203

193-
fn lib_already_exists(rellocation: &str) {
204+
fn lib_already_exists(rellocation: &str, needs_lib_section: bool) {
194205
let path = paths::root().join("foo");
195206
fs::create_dir_all(&path.join("src")).unwrap();
196207

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

218241
#[test]
219242
fn lib_already_exists_src() {
220-
lib_already_exists("src/lib.rs")
243+
lib_already_exists("src/lib.rs", false)
221244
}
222245

223246
#[test]
224247
fn lib_already_exists_nosrc() {
225-
lib_already_exists("lib.rs")
248+
lib_already_exists("lib.rs", true)
249+
}
250+
251+
#[test]
252+
fn no_lib_already_exists_src_add_lib_section() {
253+
lib_already_exists("src/foo.rs", true)
254+
}
255+
256+
#[test]
257+
fn no_lib_already_exists_nosrc_add_lib_section() {
258+
lib_already_exists("foo.rs", true)
226259
}
227260

228261
#[test]

0 commit comments

Comments
 (0)