From 8836d773980aa5abf3f3dafaabe7c90574a7f8af Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Tue, 17 Jan 2023 11:21:36 +0800 Subject: [PATCH] generate Cargo.toml using built dependency versions (#298) --- Cargo.lock | 40 ++++++++++++++++++++++- progenitor-impl/src/lib.rs | 42 +++++------------------- progenitor/Cargo.toml | 5 +++ progenitor/build.rs | 10 ++++++ progenitor/src/main.rs | 66 +++++++++++++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 36 deletions(-) create mode 100644 progenitor/build.rs diff --git a/Cargo.lock b/Cargo.lock index febab07..5cb76b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,6 +102,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "built" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9c056b9ed43aee5e064b683aa1ec783e19c6acec7559e3ae931b7490472fbe" +dependencies = [ + "cargo-lock", +] + [[package]] name = "bumpalo" version = "3.9.1" @@ -114,6 +123,18 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +[[package]] +name = "cargo-lock" +version = "8.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031718ddb8f78aa5def78a09e90defe30151d1f6c672f937af4dd916429ed996" +dependencies = [ + "semver 1.0.16", + "serde", + "toml", + "url", +] + [[package]] name = "cc" version = "1.0.72" @@ -1096,6 +1117,7 @@ version = "0.2.1-dev" dependencies = [ "anyhow", "base64 0.21.0", + "built", "chrono", "clap", "futures", @@ -1104,6 +1126,7 @@ dependencies = [ "progenitor-client", "progenitor-impl", "progenitor-macro", + "project-root", "rand", "regress", "reqwest", @@ -1169,6 +1192,12 @@ dependencies = [ "syn", ] +[[package]] +name = "project-root" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bccbff07d5ed689c4087d20d7307a52ab6141edeedf487c3876a55b86cf63df" + [[package]] name = "quote" version = "1.0.23" @@ -1468,6 +1497,15 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +dependencies = [ + "serde", +] + [[package]] name = "semver-parser" version = "0.10.2" @@ -1891,7 +1929,7 @@ dependencies = [ "home", "lazy_static", "regex", - "semver", + "semver 0.11.0", "walkdir", ] diff --git a/progenitor-impl/src/lib.rs b/progenitor-impl/src/lib.rs index db47ca0..f838a97 100644 --- a/progenitor-impl/src/lib.rs +++ b/progenitor-impl/src/lib.rs @@ -505,44 +505,18 @@ impl Generator { }) } - pub fn dependencies(&self) -> Vec { - let mut deps = vec![ - "bytes = \"1.3.0\"", - "futures-core = \"0.3\"", - "percent-encoding = \"2.2\"", - "reqwest = { version = \"0.11.13\", default-features=false, features = [\"json\", \"stream\"] }", - "serde = { version = \"1.0\", features = [\"derive\"] }", - "serde_urlencoded = \"0.7.1\"", - ]; - if self.type_space.uses_regress() { - deps.push("regress = \"0.4.1\"") - } - if self.type_space.uses_uuid() { - deps.push( - "uuid = { version = \">=0.8.0, <2.0.0\", features = [\"serde\", \"v4\"] }", - ) - } - if self.type_space.uses_chrono() { - deps.push("chrono = { version = \"0.4\", default-features=false, features = [\"serde\"] }") - } - if self.uses_futures { - deps.push("futures = \"0.3\"") - } - if self.uses_websockets { - deps.push("base64 = \"0.21\""); - deps.push("rand = \"0.8\""); - } - if self.type_space.uses_serde_json() { - deps.push("serde_json = \"1.0\"") - } - deps.sort_unstable(); - deps.iter().map(ToString::to_string).collect() - } - // TODO deprecate? pub fn get_type_space(&self) -> &TypeSpace { &self.type_space } + + pub fn uses_futures(&self) -> bool { + self.uses_futures + } + + pub fn uses_websockets(&self) -> bool { + self.uses_websockets + } } fn validate_openapi(spec: &OpenAPI) -> Result<()> { diff --git a/progenitor/Cargo.toml b/progenitor/Cargo.toml index 1277587..56ebb78 100644 --- a/progenitor/Cargo.toml +++ b/progenitor/Cargo.toml @@ -8,6 +8,7 @@ repository = "https://github.com/oxidecomputer/progenitor.git" readme = "../README.md" keywords = ["openapi", "openapiv3", "sdk", "generator", "proc_macro"] categories = ["api-bindings", "compilers"] +build = "build.rs" [dependencies] progenitor-client = { version = "0.2.1-dev", path = "../progenitor-client" } @@ -20,6 +21,10 @@ serde_json = "1.0" serde_yaml = "0.9" clap = { version = "4.1.1", features = ["derive"] } +[build-dependencies] +built = { version = "0.5" } +project-root = "*" + [dev-dependencies] base64 = "0.21" chrono = { version = "0.4", features = ["serde"] } diff --git a/progenitor/build.rs b/progenitor/build.rs new file mode 100644 index 0000000..b80b0ba --- /dev/null +++ b/progenitor/build.rs @@ -0,0 +1,10 @@ +fn main() { + let mut opts = built::Options::default(); + opts.set_dependencies(true); + + let src = project_root::get_project_root().unwrap(); + let dst = std::path::Path::new(&std::env::var("OUT_DIR").unwrap()) + .join("built.rs"); + built::write_built_file_with_opts(&opts, src.as_ref(), &dst) + .expect("Failed to acquire build-time information"); +} diff --git a/progenitor/src/main.rs b/progenitor/src/main.rs index 1818d02..e2b91c3 100644 --- a/progenitor/src/main.rs +++ b/progenitor/src/main.rs @@ -1,6 +1,7 @@ // Copyright 2022 Oxide Computer Company use std::{ + collections::HashMap, fs::{File, OpenOptions}, io::Write, path::{Path, PathBuf}, @@ -11,6 +12,11 @@ use clap::{Parser, ValueEnum}; use openapiv3::OpenAPI; use progenitor::{GenerationSettings, Generator, InterfaceStyle, TagStyle}; +pub mod built_info { + // The file has been placed there by the build script. + include!(concat!(env!("OUT_DIR"), "/built.rs")); +} + #[derive(Parser)] struct Args { /// OpenAPI definition document (JSON or YAML) @@ -129,7 +135,7 @@ fn main() -> Result<()> { \n", name, version, - builder.dependencies().join("\n"), + dependencies(builder).join("\n"), ); save(&toml, tomlout.as_str())?; @@ -167,6 +173,64 @@ fn main() -> Result<()> { Ok(()) } +pub fn dependencies(builder: Generator) -> Vec { + let dependency_versions: HashMap = built_info::DEPENDENCIES + .iter() + .map(|(name, version)| (name.to_string(), version.to_string())) + .collect(); + + let mut deps = vec![ + format!("bytes = \"{}\"", dependency_versions.get("bytes").unwrap()), + format!("futures-core = \"{}\"", dependency_versions.get("futures-core").unwrap()), + format!("percent-encoding = \"{}\"", dependency_versions.get("percent-encoding").unwrap()), + format!("reqwest = {{ version = \"{}\", default-features=false, features = [\"json\", \"stream\"] }}", dependency_versions.get("reqwest").unwrap()), + format!("serde = {{ version = \"{}\", features = [\"derive\"] }}", dependency_versions.get("serde").unwrap()), + format!("serde_urlencoded = \"{}\"", dependency_versions.get("serde_urlencoded").unwrap()), + ]; + + let type_space = builder.get_type_space(); + + if type_space.uses_regress() { + deps.push(format!( + "regress = \"{}\"", + dependency_versions.get("regress").unwrap() + )); + } + if type_space.uses_uuid() { + deps.push(format!( + "uuid = {{ version = \"{}\", features = [\"serde\", \"v4\"] }}", + dependency_versions.get("uuid").unwrap() + )); + } + if type_space.uses_chrono() { + deps.push(format!("chrono = {{ version = \"{}\", default-features=false, features = [\"serde\"] }}", dependency_versions.get("chrono").unwrap())) + } + if builder.uses_futures() { + deps.push(format!( + "futures = \"{}\"", + dependency_versions.get("futures").unwrap() + )); + } + if builder.uses_websockets() { + deps.push(format!( + "base64 = \"{}\"", + dependency_versions.get("base64").unwrap() + )); + deps.push(format!( + "rand = \"{}\"", + dependency_versions.get("rand").unwrap() + )); + } + if type_space.uses_serde_json() { + deps.push(format!( + "serde_json = \"{}\"", + dependency_versions.get("serde_json").unwrap() + )); + } + deps.sort_unstable(); + deps +} + fn load_api

(p: P) -> Result where P: AsRef + std::clone::Clone + std::fmt::Debug,