From ea126b0745b0ce517bd9bf58b84500df657dd49d Mon Sep 17 00:00:00 2001 From: Augustus Mayo Date: Fri, 2 May 2025 15:45:45 -0500 Subject: [PATCH 1/3] Extracted compilation test --- Cargo.lock | 26 ++++++++++ Cargo.toml | 1 + progenitor-impl/Cargo.toml | 9 ++++ progenitor-impl/tests/test_compilation.rs | 46 +++++++++++++++++ test-progenitor-compilation/Cargo.toml | 24 +++++++++ test-progenitor-compilation/src/lib.rs | 62 +++++++++++++++++++++++ 6 files changed, 168 insertions(+) create mode 100644 progenitor-impl/tests/test_compilation.rs create mode 100644 test-progenitor-compilation/Cargo.toml create mode 100644 test-progenitor-compilation/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a3c101a7..2ed0df2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1611,6 +1611,10 @@ dependencies = [ name = "progenitor-impl" version = "0.10.0" dependencies = [ + "anyhow", + "base64", + "chrono", + "clap", "dropshot", "expectorate", "futures", @@ -1622,7 +1626,9 @@ dependencies = [ "proc-macro2", "progenitor-client", "quote", + "rand", "regex", + "regress", "reqwest", "rustfmt-wrapper", "schemars", @@ -1631,10 +1637,12 @@ dependencies = [ "serde_json", "serde_yaml", "syn", + "test-progenitor-compilation", "thiserror 2.0.12", "tokio", "typify", "unicode-ident", + "uuid", ] [[package]] @@ -2311,6 +2319,24 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "test-progenitor-compilation" +version = "0.1.0" +dependencies = [ + "dropshot", + "expectorate", + "http", + "hyper", + "openapiv3", + "proc-macro2", + "progenitor-impl", + "quote", + "schemars", + "serde_json", + "serde_yaml", + "syn", +] + [[package]] name = "thiserror" version = "1.0.69" diff --git a/Cargo.toml b/Cargo.toml index f90a1922..3092c6c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "progenitor-client", "progenitor-impl", "progenitor-macro", + "test-progenitor-compilation" ] resolver = "2" diff --git a/progenitor-impl/Cargo.toml b/progenitor-impl/Cargo.toml index f4a3a9af..f0b5ad74 100644 --- a/progenitor-impl/Cargo.toml +++ b/progenitor-impl/Cargo.toml @@ -24,14 +24,23 @@ typify = { workspace = true } unicode-ident = { workspace = true } [dev-dependencies] +anyhow = { workspace = true } +base64 = { workspace = true } +clap = { workspace = true } +chrono = { workspace = true } dropshot = { workspace = true } expectorate = { workspace = true } futures = { workspace = true } http = { workspace = true } hyper = { workspace = true } progenitor-client = { workspace = true } +rand = { workspace = true } +regress = { workspace = true } reqwest = { workspace = true } rustfmt-wrapper = { workspace = true } +schemars = { workspace = true } semver = { workspace = true } serde_yaml = { workspace = true } +test-progenitor-compilation = { path = "../test-progenitor-compilation" } tokio = { workspace = true } +uuid = { workspace = true } diff --git a/progenitor-impl/tests/test_compilation.rs b/progenitor-impl/tests/test_compilation.rs new file mode 100644 index 00000000..e2324ca2 --- /dev/null +++ b/progenitor-impl/tests/test_compilation.rs @@ -0,0 +1,46 @@ +// Copyright 2022 Oxide Computer Company + +use test_progenitor_compilation::cli_tokens; + +#[test] +fn test_keeper_compilation() { + cli_tokens!("keeper.json"); +} + +#[test] +fn test_buildomat_compilation() { + cli_tokens!("buildomat.json"); +} + +#[test] +fn test_nexus_compilation() { + cli_tokens!("nexus.json"); +} + +#[test] +fn test_propolis_server_compilation() { + cli_tokens!("propolis-server.json"); +} + +#[test] +fn test_param_override_compilation() { + cli_tokens!("param-overrides.json"); +} + +#[test] +fn test_yaml_compilation() { + cli_tokens!("param-overrides.yaml"); +} + +#[test] +fn test_param_collision_compilation() { + cli_tokens!("param-collision.json"); +} + +// TODO this file is full of inconsistencies and incorrectly specified types. +// It's an interesting test to consider whether we try to do our best to +// interpret the intent or just fail. +// #[test] +// fn test_github() { +// cli_tokens!("api.github.com.json"); +// } diff --git a/test-progenitor-compilation/Cargo.toml b/test-progenitor-compilation/Cargo.toml new file mode 100644 index 00000000..9fc6fa9b --- /dev/null +++ b/test-progenitor-compilation/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "test-progenitor-compilation" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" +description = "An OpenAPI client generator - compilation test macro" +repository = "https://github.com/oxidecomputer/progenitor.git" + +[lib] +proc-macro = true + +[dependencies] +dropshot = { workspace = true } +expectorate = { workspace = true } +http = { workspace = true } +hyper = { workspace = true } +openapiv3 = { workspace = true } +proc-macro2 = { workspace = true } +progenitor-impl = { workspace = true } +quote = { workspace = true } +schemars = { workspace = true } +serde_yaml = { workspace = true } +serde_json = { workspace = true } +syn = { workspace = true } diff --git a/test-progenitor-compilation/src/lib.rs b/test-progenitor-compilation/src/lib.rs new file mode 100644 index 00000000..1ae5020a --- /dev/null +++ b/test-progenitor-compilation/src/lib.rs @@ -0,0 +1,62 @@ +// Copyright 2022 Oxide Computer Company + +extern crate proc_macro; + +use openapiv3::OpenAPI; +use proc_macro::TokenStream; +use progenitor_impl::{GenerationSettings, Generator, InterfaceStyle, TagStyle}; +use quote::quote; +use std::{ + fs::File, + path::{Path, PathBuf}, +}; + +#[proc_macro] +pub fn cli_tokens(item: TokenStream) -> TokenStream { + let arg = item.to_string().replace("\"", ""); + let mut in_path = PathBuf::from("sample_openapi"); + in_path.push(arg); + + let spec = load_api(in_path); + + let mut generator = Generator::new( + GenerationSettings::default() + .with_interface(InterfaceStyle::Builder) + .with_tag(TagStyle::Merged) + .with_derive("schemars::JsonSchema"), + ); + + // Builder generation with tags. + let sdk = generator.generate_tokens(&spec).unwrap(); + + // CLI generation. + let cli = generator.cli(&spec, "sdk").unwrap(); + + // println!("{}", cli); + + // panic!("exit"); + + quote! { + pub mod sdk { + #sdk + } + use sdk::*; + + #cli + } + .into() +} + +fn load_api

(p: P) -> OpenAPI +where + P: AsRef + std::clone::Clone + std::fmt::Debug, +{ + let mut f = File::open(p.clone()).unwrap(); + match serde_json::from_reader(f) { + Ok(json_value) => json_value, + _ => { + f = File::open(p).unwrap(); + serde_yaml::from_reader(f).unwrap() + } + } +} From c76c2555975af37caafee1de99441b791e7390e4 Mon Sep 17 00:00:00 2001 From: Augustus Mayo Date: Fri, 2 May 2025 15:50:58 -0500 Subject: [PATCH 2/3] Cleanup and fmt --- test-progenitor-compilation/src/lib.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test-progenitor-compilation/src/lib.rs b/test-progenitor-compilation/src/lib.rs index 1ae5020a..36ee7e77 100644 --- a/test-progenitor-compilation/src/lib.rs +++ b/test-progenitor-compilation/src/lib.rs @@ -31,10 +31,6 @@ pub fn cli_tokens(item: TokenStream) -> TokenStream { // CLI generation. let cli = generator.cli(&spec, "sdk").unwrap(); - - // println!("{}", cli); - - // panic!("exit"); quote! { pub mod sdk { From 9ac507d5d2007b3d5d6ed38881cab3a4933fc31b Mon Sep 17 00:00:00 2001 From: Augustus Mayo Date: Fri, 2 May 2025 16:29:24 -0500 Subject: [PATCH 3/3] Update test to use string flag --- progenitor-impl/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/progenitor-impl/Cargo.toml b/progenitor-impl/Cargo.toml index f0b5ad74..d19a5392 100644 --- a/progenitor-impl/Cargo.toml +++ b/progenitor-impl/Cargo.toml @@ -26,7 +26,7 @@ unicode-ident = { workspace = true } [dev-dependencies] anyhow = { workspace = true } base64 = { workspace = true } -clap = { workspace = true } +clap = { workspace = true, features = ["string"] } chrono = { workspace = true } dropshot = { workspace = true } expectorate = { workspace = true }