From 97f61ec2a85afa184a8becd7d3e85292bdb35562 Mon Sep 17 00:00:00 2001 From: Will Stott Date: Sun, 8 Sep 2019 13:07:45 +0100 Subject: [PATCH] Protobuf 2.4.0, generate all proto files every time, but only write when changed, supporting poor souls with crlf line ending conversion. Drop Regex dependency, just parse using simple string methods. Protobuf 2.4.0, generate all proto files every time, but only write when changed, supporting poor souls with crlf line ending conversion. --- Cargo.lock | 1 + protocol/Cargo.toml | 1 + protocol/build.rs | 131 ++++++++++++++++---------------------------- protocol/files.rs | 10 ---- protocol/src/lib.rs | 4 +- 5 files changed, 50 insertions(+), 97 deletions(-) delete mode 100644 protocol/files.rs diff --git a/Cargo.lock b/Cargo.lock index d50a0ac41..9b3a96a37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -956,6 +956,7 @@ name = "librespot-protocol" version = "0.1.0" dependencies = [ "protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "protobuf-codegen 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "protobuf-codegen-pure 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index 18bba8fbd..a0d30ad05 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -9,3 +9,4 @@ protobuf = "2.8.*" [build-dependencies] protobuf-codegen-pure = "2.8.*" +protobuf-codegen = "*" diff --git a/protocol/build.rs b/protocol/build.rs index a1c5c662d..ec6fff848 100644 --- a/protocol/build.rs +++ b/protocol/build.rs @@ -1,93 +1,54 @@ -extern crate protobuf_codegen_pure; -use protobuf_codegen_pure::Customize; -use std::fs::File; -use std::io::prelude::*; - -mod files; +extern crate protobuf_codegen; // Does the business +extern crate protobuf_codegen_pure; // Helper function -fn main() { - let mut changed = false; - let mut file = File::open("files.rs").unwrap(); - let mut f_str = String::new(); - file.read_to_string(&mut f_str).unwrap(); - drop(file); - for &(path, expected_checksum) in files::FILES { - let actual = cksum_file(path).unwrap(); - if expected_checksum != actual { - protobuf_codegen_pure::run(protobuf_codegen_pure::Args { - out_dir: "src", - input: &[path], - includes: &["proto"], - customize: Customize { ..Default::default() }, - }).expect("protoc"); - let new_checksum = cksum_file(path).unwrap(); - f_str = f_str.replace(&expected_checksum.to_string(), &new_checksum.to_string()); - changed = true; - } - } - if changed { - // Write new checksums to file - let mut file = File::create("files.rs").unwrap(); - file.write_all(f_str.as_bytes()).unwrap(); - } -} +use std::path::Path; +use std::fs::{read_to_string, write}; -fn cksum_file>(path: T) -> std::io::Result { - let mut file = File::open(path)?; - let mut contents = Vec::new(); - file.read_to_end(&mut contents)?; +use protobuf_codegen_pure::Customize; +use protobuf_codegen_pure::parse_and_typecheck; - Ok(cksum(&contents)) -} +fn main() { + let customizations = Customize { ..Default::default() }; -fn cksum>(data: T) -> u32 { - let data = data.as_ref(); + let lib_str = read_to_string("src/lib.rs").unwrap(); - let mut value = 0u32; - for x in data { - value = (value << 8) ^ CRC_LOOKUP_ARRAY[(*x as u32 ^ (value >> 24)) as usize]; - } + // Iterate over the desired module names. + for line in lib_str.lines() { + if !line.starts_with("pub mod ") { + continue; + } + let len = line.len(); + let name = &line[8..len-1]; // Remove keywords and semi-colon + + // Build the paths to relevant files. + let src = &format!("proto/{}.proto", name); + let dest = &format!("src/{}.rs", name); + + // Get the contents of the existing generated file. + let mut existing = "".to_string(); + if Path::new(dest).exists() { + // Removing CRLF line endings if present. + existing = read_to_string(dest).unwrap().replace("\r\n", "\n"); + } - let mut n = data.len(); - while n != 0 { - value = (value << 8) ^ CRC_LOOKUP_ARRAY[((n & 0xFF) as u32 ^ (value >> 24)) as usize]; - n >>= 8; + println!("Regenerating {} from {}", dest, src); + + // Parse the proto files as the protobuf-codegen-pure crate does. + let p = parse_and_typecheck(&["proto"], &[src]).expect("protoc"); + // But generate them with the protobuf-codegen crate directly. + // Then we can keep the result in-memory. + let result = protobuf_codegen::gen( + &p.file_descriptors, + &p.relative_paths, + &customizations, + ); + // Protoc result as a byte array. + let new = &result.first().unwrap().content; + // Convert to utf8 to compare with existing. + let new = std::str::from_utf8(&new).unwrap(); + // Save newly generated file if changed. + if new != existing { + write(dest, &new).unwrap(); + } } - - !value } - -static CRC_LOOKUP_ARRAY: &'static [u32] = &[ - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, - 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, - 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, - 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, - 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, - 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, - 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, - 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, - 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, - 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, - 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, - 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, - 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, - 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, - 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, - 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, - 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, - 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4, -]; diff --git a/protocol/files.rs b/protocol/files.rs deleted file mode 100644 index 25529ce8e..000000000 --- a/protocol/files.rs +++ /dev/null @@ -1,10 +0,0 @@ -// Autogenerated by build.rs - -pub const FILES: &'static [(&'static str, u32)] = &[ - ("proto/authentication.proto", 2098196376), - ("proto/keyexchange.proto", 451735664), - ("proto/mercury.proto", 709993906), - ("proto/metadata.proto", 2474472423), - ("proto/pubsub.proto", 2686584829), - ("proto/spirc.proto", 1587493382), -]; diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index ad9d9a329..30233384a 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,6 +1,6 @@ -// Autogenerated by build.sh - extern crate protobuf; +// This file is parsed by build.rs +// Each included module will be compiled from the matching .proto definition. pub mod authentication; pub mod keyexchange; pub mod mercury;