diff --git a/Cargo.lock b/Cargo.lock index 7ed935d1b04..b82576568df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,7 +28,7 @@ dependencies = [ "tar 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -434,7 +434,7 @@ dependencies = [ [[package]] name = "toml" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 43dca3be7db..996bc04e143 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ semver = "0.2.2" tar = "0.4" tempdir = "0.3" term = "0.4.4" -toml = "0.1" +toml = "0.1.29" url = "1.1" winapi = "0.2" diff --git a/src/cargo/ops/lockfile.rs b/src/cargo/ops/lockfile.rs index 41b6ac4b8d6..f24fe5bd571 100644 --- a/src/cargo/ops/lockfile.rs +++ b/src/cargo/ops/lockfile.rs @@ -22,7 +22,7 @@ pub fn load_pkg_lockfile(pkg: &Package, config: &Config) })); (|| { - let table = toml::Value::Table(try!(cargo_toml::parse(&s, f.path()))); + let table = toml::Value::Table(try!(cargo_toml::parse(&s, f.path(), config))); let mut d = toml::Decoder::new(table); let v: resolver::EncodableResolve = try!(Decodable::decode(&mut d)); Ok(Some(try!(v.to_resolve(pkg, config)))) diff --git a/src/cargo/util/config.rs b/src/cargo/util/config.rs index b03b6837902..53ad520e609 100644 --- a/src/cargo/util/config.rs +++ b/src/cargo/util/config.rs @@ -330,7 +330,9 @@ impl Config { try!(walk_tree(&self.cwd, |mut file, path| { let mut contents = String::new(); try!(file.read_to_string(&mut contents)); - let table = try!(cargo_toml::parse(&contents, &path).chain_error(|| { + let table = try!(cargo_toml::parse(&contents, + &path, + self).chain_error(|| { human(format!("could not parse TOML configuration in `{}`", path.display())) })); @@ -717,7 +719,7 @@ pub fn set_config(cfg: &Config, }; let mut contents = String::new(); let _ = file.read_to_string(&mut contents); - let mut toml = try!(cargo_toml::parse(&contents, file.path())); + let mut toml = try!(cargo_toml::parse(&contents, file.path(), cfg)); toml.insert(key.to_string(), value.into_toml()); let contents = toml::Value::Table(toml).to_string(); diff --git a/src/cargo/util/toml.rs b/src/cargo/util/toml.rs index 207e22b7db2..4d19b9d70fb 100644 --- a/src/cargo/util/toml.rs +++ b/src/cargo/util/toml.rs @@ -114,7 +114,7 @@ pub fn to_manifest(contents: &[u8], let contents = try!(str::from_utf8(contents).map_err(|_| { human(format!("{} is not valid UTF-8", manifest.display())) })); - let root = try!(parse(contents, &manifest)); + let root = try!(parse(contents, &manifest, config)); let mut d = toml::Decoder::new(toml::Value::Table(root)); let manifest: TomlManifest = try!(Decodable::decode(&mut d).map_err(|e| { human(e.to_string()) @@ -157,15 +157,33 @@ pub fn to_manifest(contents: &[u8], } } -pub fn parse(toml: &str, file: &Path) -> CargoResult { - let mut parser = toml::Parser::new(&toml); - if let Some(toml) = parser.parse() { +pub fn parse(toml: &str, + file: &Path, + config: &Config) -> CargoResult { + let mut first_parser = toml::Parser::new(&toml); + if let Some(toml) = first_parser.parse() { return Ok(toml); } + + let mut second_parser = toml::Parser::new(toml); + second_parser.set_require_newline_after_table(false); + if let Some(toml) = second_parser.parse() { + let msg = format!("\ +TOML file found which contains invalid syntax and will soon not parse +at `{}`. + +The TOML spec requires newlines after table definitions (e.g. `[a] b = 1` is +invalid), but this file has a table header which does not have a newline after +it. A newline needs to be added and this warning will soon become a hard error +in the future.", file.display()); + try!(config.shell().warn(&msg)); + return Ok(toml) + } + let mut error_str = format!("could not parse input as TOML\n"); - for error in parser.errors.iter() { - let (loline, locol) = parser.to_linecol(error.lo); - let (hiline, hicol) = parser.to_linecol(error.hi); + for error in first_parser.errors.iter() { + let (loline, locol) = first_parser.to_linecol(error.lo); + let (hiline, hicol) = first_parser.to_linecol(error.hi); error_str.push_str(&format!("{}:{}:{}{} {}\n", file.display(), loline + 1, locol + 1, diff --git a/tests/bad-config.rs b/tests/bad-config.rs index b88ea2f6bfe..63abb529f73 100644 --- a/tests/bad-config.rs +++ b/tests/bad-config.rs @@ -479,3 +479,30 @@ warning: dependency (foo) specified without providing a local path, Git reposito to use. This will be considered an error in future versions ")); } + +#[test] +fn invalid_toml_historically_allowed_is_warned() { + let p = project("empty_deps") + .file("Cargo.toml", r#" + [package] + name = "empty_deps" + version = "0.0.0" + authors = [] + "#) + .file(".cargo/config", r#" + [foo] bar = 2 + "#) + .file("src/main.rs", "fn main() {}"); + + assert_that(p.cargo_process("build"), + execs().with_status(0).with_stderr("\ +warning: TOML file found which contains invalid syntax and will soon not parse +at `[..]config`. + +The TOML spec requires newlines after table definitions (e.g. `[a] b = 1` is +invalid), but this file has a table header which does not have a newline after +it. A newline needs to be added and this warning will soon become a hard error +in the future. +[COMPILING] empty_deps v0.0.0 ([..]) +")); +} diff --git a/tests/path.rs b/tests/path.rs index 97cc213225a..574851e9387 100644 --- a/tests/path.rs +++ b/tests/path.rs @@ -256,8 +256,10 @@ fn no_rebuild_dependency() { version = "0.5.0" authors = ["wycats@example.com"] - [[bin]] name = "foo" - [dependencies.bar] path = "bar" + [[bin]] + name = "foo" + [dependencies.bar] + path = "bar" "#) .file("src/foo.rs", r#" extern crate bar; @@ -270,7 +272,8 @@ fn no_rebuild_dependency() { version = "0.5.0" authors = ["wycats@example.com"] - [lib] name = "bar" + [lib] + name = "bar" "#) .file("bar/src/bar.rs", r#" pub fn bar() {}