Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions cargo-progenitor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
use anyhow::{bail, Result};
use clap::{Parser, ValueEnum};
use openapiv3::OpenAPI;
use progenitor::{GenerationSettings, Generator, InterfaceStyle, TagStyle};
use progenitor::{GenerationSettings, Generator, InterfaceStyle, OperationIdStrategy, TagStyle};
use progenitor_impl::space_out_items;

fn is_non_release() -> bool {
Expand Down Expand Up @@ -51,6 +51,9 @@ struct Args {
/// SDK tag style
#[clap(value_enum, long, default_value_t = TagArg::Merged)]
tags: TagArg,
/// SDK operation id style
#[clap(value_enum, long, default_value_t = OperationIdStrategyArg::RejectMissing)]
operation_id_strategy: OperationIdStrategyArg,
/// Include client code rather than depending on progenitor-client
#[clap(default_value = match is_non_release() { true => "true", false => "false" }, long, action = clap::ArgAction::Set)]
include_client: bool,
Expand Down Expand Up @@ -86,6 +89,23 @@ impl From<TagArg> for TagStyle {
}
}

#[derive(Copy, Clone, ValueEnum)]
enum OperationIdStrategyArg {
RejectMissing,
OmitMissing,
GenerateMissing,
}

impl From<OperationIdStrategyArg> for OperationIdStrategy {
fn from(arg: OperationIdStrategyArg) -> Self {
match arg {
OperationIdStrategyArg::RejectMissing => OperationIdStrategy::RejectMissing,
OperationIdStrategyArg::OmitMissing => OperationIdStrategy::OmitMissing,
OperationIdStrategyArg::GenerateMissing => OperationIdStrategy::GenerateMissing,
}
}
}

fn reformat_code(input: String) -> String {
let config = rustfmt_wrapper::config::Config {
normalize_doc_attributes: Some(true),
Expand Down Expand Up @@ -119,7 +139,8 @@ fn main() -> Result<()> {
let mut builder = Generator::new(
GenerationSettings::default()
.with_interface(args.interface.into())
.with_tag(args.tags.into()),
.with_tag(args.tags.into())
.with_operation_id_strategy(args.operation_id_strategy.into()),
);

match builder.generate_tokens(&api) {
Expand Down
5 changes: 2 additions & 3 deletions cargo-progenitor/tests/test_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// Copyright 2025 Oxide Computer Company

use assert_cmd::Command;
use assert_cmd::cargo::cargo_bin_cmd;

#[test]
fn test_help() {
Command::cargo_bin("cargo-progenitor")
.unwrap()
cargo_bin_cmd!("cargo-progenitor")
.arg("progenitor")
.arg("--help")
.assert()
Expand Down
14 changes: 11 additions & 3 deletions progenitor-impl/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct CliOperation {
impl Generator {
/// Generate a `clap`-based CLI.
pub fn cli(&mut self, spec: &OpenAPI, crate_name: &str) -> Result<TokenStream> {
validate_openapi(spec)?;
validate_openapi(spec, self.settings.operation_id_strategy)?;

// Convert our components dictionary to schemars
let schemas = spec.components.iter().flat_map(|components| {
Expand All @@ -46,8 +46,16 @@ impl Generator {
(path.as_str(), method, operation, &item.parameters)
})
})
.map(|(path, method, operation, path_parameters)| {
self.process_operation(operation, &spec.components, path, method, path_parameters)
.filter_map(|(path, method, operation, path_parameters)| {
self.process_operation(
operation,
&spec.components,
path,
method,
path_parameters,
self.settings.operation_id_strategy,
)
.transpose()
})
.collect::<Result<Vec<_>>>()?;

Expand Down
14 changes: 11 additions & 3 deletions progenitor-impl/src/httpmock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Generator {
/// the SDK. This can include `::` and instances of `-` in the crate name
/// should be converted to `_`.
pub fn httpmock(&mut self, spec: &OpenAPI, crate_path: &str) -> Result<TokenStream> {
validate_openapi(spec)?;
validate_openapi(spec, self.settings.operation_id_strategy)?;

// Convert our components dictionary to schemars
let schemas = spec.components.iter().flat_map(|components| {
Expand All @@ -52,8 +52,16 @@ impl Generator {
(path.as_str(), method, operation, &item.parameters)
})
})
.map(|(path, method, operation, path_parameters)| {
self.process_operation(operation, &spec.components, path, method, path_parameters)
.filter_map(|(path, method, operation, path_parameters)| {
self.process_operation(
operation,
&spec.components,
path,
method,
path_parameters,
self.settings.operation_id_strategy,
)
.transpose()
})
.collect::<Result<Vec<_>>>()?;

Expand Down
Loading