From d6afaa45803b028b9ea8779aa51bb7ddd17ae26f Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 20 Nov 2019 20:59:50 +0900 Subject: [PATCH] Use own parser for removing dev-dependencies --- Cargo.lock | 118 ------------------- Cargo.toml | 1 - src/main.rs | 3 +- src/manifest.rs | 18 +-- src/remove_dev_deps.rs | 252 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 256 insertions(+), 136 deletions(-) create mode 100644 src/remove_dev_deps.rs diff --git a/Cargo.lock b/Cargo.lock index d8cc24bd..bcc7da69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,26 +5,11 @@ name = "anyhow" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ascii" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "cargo-hack" version = "0.3.1" @@ -37,7 +22,6 @@ dependencies = [ "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "toml_edit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -50,29 +34,6 @@ name = "cfg-if" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "chrono" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "ctrlc" version = "3.1.3" @@ -91,11 +52,6 @@ dependencies = [ "syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "either" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "itoa" version = "0.4.4" @@ -106,16 +62,6 @@ name = "libc" version = "0.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "linked-hash-map" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "nix" version = "0.14.1" @@ -128,23 +74,6 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-integer" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "proc-macro2" version = "1.0.6" @@ -161,11 +90,6 @@ dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "ryu" version = "1.0.2" @@ -214,16 +138,6 @@ dependencies = [ "wincolor 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "toml" version = "0.5.5" @@ -232,29 +146,11 @@ dependencies = [ "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "toml_edit" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", - "combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "unicode-xid" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "void" version = "1.0.2" @@ -298,38 +194,24 @@ dependencies = [ [metadata] "checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" -"checksum ascii 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" -"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" -"checksum combine 3.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" "checksum ctrlc 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c7dfd2d8b4c82121dfdff120f818e09fc4380b0b7e17a742081a89b94853e87f" "checksum easy-ext 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed79d40452cc72aa676b63ddde7f415865b412984738a1ba11096615ab0b262c" -"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" -"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" -"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6" "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" "checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" "checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" "checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" -"checksum toml_edit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87f53b1aca7d5fe2e17498a38cac0e1f5a33234d5b980fb36b9402bb93b98ae4" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/Cargo.toml b/Cargo.toml index b4c33c27..fc65d13c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,6 @@ serde_derive = "1.0.102" serde_json = "1.0.41" termcolor = "1.0.5" toml = "0.5.5" -toml_edit = "0.1.5" [dev-dependencies] easy-ext = "0.1.6" diff --git a/src/main.rs b/src/main.rs index c2d8abf4..78f27214 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod cli; mod manifest; mod metadata; mod process; +mod remove_dev_deps; mod restore; use std::{env, ffi::OsString, fs, path::Path}; @@ -132,7 +133,7 @@ fn no_dev_deps( restore: &Restore, ) -> Result<()> { if args.no_dev_deps || args.remove_dev_deps { - let new = manifest.remove_dev_deps()?; + let new = manifest.remove_dev_deps(); let mut handle = restore.set_manifest(&manifest); fs::write(&package.manifest_path, new).with_context(|| { diff --git a/src/manifest.rs b/src/manifest.rs index b75fc10a..d75dd24a 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -40,22 +40,8 @@ impl Manifest { self.package.as_ref().unwrap().publish == false } - pub(crate) fn remove_dev_deps(&self) -> Result { - let mut doc: toml_edit::Document = self.raw.parse()?; - remove_key_and_target_key(doc.as_table_mut(), "dev-dependencies"); - Ok(doc.to_string_in_original_order()) - } -} - -fn remove_key_and_target_key(table: &mut toml_edit::Table, key: &str) { - table.remove(key); - if let Some(table) = table.entry("target").as_table_mut() { - // `toml_edit::Table` does not have `.iter_mut()`, so collect keys. - for k in table.iter().map(|(key, _)| key.to_string()).collect::>() { - if let Some(table) = table.entry(&k).as_table_mut() { - table.remove(key); - } - } + pub(crate) fn remove_dev_deps(&self) -> String { + super::remove_dev_deps::remove_dev_deps(&self.raw) } } diff --git a/src/remove_dev_deps.rs b/src/remove_dev_deps.rs new file mode 100644 index 00000000..f47bc7a3 --- /dev/null +++ b/src/remove_dev_deps.rs @@ -0,0 +1,252 @@ +use std::cmp; + +pub(crate) fn remove_dev_deps(bytes: &str) -> String { + const DEV_DEPS: &str = "dev-dependencies"; + const TARGET: &str = "target."; + + let mut bytes = bytes.to_string(); + let mut prev = 0; + let mut next = bytes.find('['); + + 'outer: while let Some(mut pos) = next { + prev = bytes[prev..pos].rfind('\n').map_or(prev, |n| cmp::min(n + prev + 1, pos)); + + // skip '# [...' and 'foo = [...' + if bytes[prev..pos].trim().is_empty() { + let slice = bytes[pos + 1..].trim_start(); + if slice.starts_with(DEV_DEPS) { + let maybe_close = pos + DEV_DEPS.len(); + for (i, _) in bytes[maybe_close..].match_indices('[') { + let back = bytes[maybe_close..maybe_close + i] + .rfind('\n') + .map_or(0, |n| cmp::min(n + 1, i)); + + // skip '# [...' and 'foo = [...' + if bytes[maybe_close + back..maybe_close + i].trim().is_empty() { + bytes.drain(prev..maybe_close + back); + next = Some(prev + i - back); + continue 'outer; + } + } + + bytes.drain(prev..); + break; + } else if slice.starts_with(TARGET) { + let close = bytes[pos + TARGET.len()..].find(']').unwrap() + pos + TARGET.len(); + let mut split = bytes[pos..close].split('.'); + let _ = split.next(); // `target` + let _ = split.next(); // `'cfg(...)'` + if let Some(deps) = split.next() { + if deps.trim() == DEV_DEPS { + for (i, _) in bytes[close..].match_indices('[') { + let back = bytes[close..close + i] + .rfind('\n') + .map_or(0, |n| cmp::min(n + 1, i)); + + // skip '# [...' and 'foo = [...' + if bytes[close + back..close + i].trim().is_empty() { + bytes.drain(prev..close + back); + next = Some(prev + i - back); + continue 'outer; + } + } + + bytes.drain(prev..); + break; + } + } + + prev = pos; + next = bytes[close..].find('[').map(|n| close + n); + continue; + } + } + + prev = pos; + // pos + 0 = '[' + // pos + 1 = part of table name (or '[') + // pos + 2 = ']' (or part of table name) + // pos + 3 = '\n' or eof (or part of table name or ']') + // pos + 4 = start of next table or eof (or part of this table) + pos += 4; + next = bytes.get(pos..).and_then(|s| s.find('[')).map(|n| pos + n); + continue; + } + + bytes +} + +#[cfg(test)] +mod tests { + + macro_rules! test { + ($name:ident, $input:expr, $expected:expr) => { + #[test] + fn $name() { + let input = super::remove_dev_deps($input); + assert_eq!(&$expected[..], input); + } + }; + } + + test!( + a, + "\ +[package] +[dependencies] +[[example]] +[dev-dependencies.opencl] +[dev-dependencies]", + "\ +[package] +[dependencies] +[[example]] +" + ); + + test!( + b, + "\ +[package] +[dependencies] +[[example]] +[dev-dependencies.opencl] +[dev-dependencies] +", + "\ +[package] +[dependencies] +[[example]] +" + ); + + test!( + c, + "\ +[dev-dependencies] +foo = { features = [] } +bar = \"0.1\" +", + "\ + " + ); + + test!( + d, + "\ +[dev-dependencies.foo] +features = [] + +[dev-dependencies] +bar = { features = [], a = [] } + +[dependencies] +bar = { features = [], a = [] } +", + "\ +[dependencies] +bar = { features = [], a = [] } +" + ); + + test!( + many_lines, + "\ +[package]\n\n + +[dev-dependencies.opencl] + + +[dev-dependencies] +", + "\ +[package]\n\n + +" + ); + + test!( + target_deps1, + "\ +[package] + +[target.'cfg(unix)'.dev-dependencies] + +[dependencies] +", + "\ +[package] + +[dependencies] +" + ); + + test!( + target_deps2, + "\ +[package] + +[target.'cfg(unix)'.dev-dependencies] +foo = \"0.1\" + +[target.'cfg(unix)'.dev-dependencies.bar] + +[dev-dependencies] +foo = \"0.1\" + +[target.'cfg(unix)'.dependencies] +foo = \"0.1\" +", + "\ +[package] + +[target.'cfg(unix)'.dependencies] +foo = \"0.1\" +" + ); + + test!( + target_deps3, + "\ +[package] + +[target.'cfg(unix)'.dependencies] + +[dev-dependencies] +", + "\ +[package] + +[target.'cfg(unix)'.dependencies] + +" + ); + + test!( + not_table, + "\ +[package] +foo = [dev-dependencies] +# [dev-dependencies] + + [dev-dependencies] + + [dependencies] + + [target.'cfg(unix)'.dev-dependencies] + foo = \"0.1\" + + +\t[dev-dependencies] +\tfoo = \"0.1\" +", + "\ +[package] +foo = [dev-dependencies] +# [dev-dependencies] + + [dependencies] + +" + ); +}