diff --git a/Cargo.lock b/Cargo.lock index f2c51fb..06d6877 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1796,9 +1796,9 @@ dependencies = [ [[package]] name = "oxide-api" -version = "0.1.0-rc.40" +version = "0.1.0-rc.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70dd62a963e00455ed648d011f3bb55a8b2c534e33383902bf4d53ea01dbf1c" +checksum = "dce0e8416b4283f082058e1d1434d42a5db7d5470761c67234701f461e67c049" dependencies = [ "anyhow", "bytes", diff --git a/Cargo.toml b/Cargo.toml index c0effa2..1198121 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ regex = "1" num-traits = "^0.2.14" oauth2 = "4.1" open = "^2.1.1" -oxide-api = "0.1.0-rc.40" +oxide-api = "0.1.0-rc.41" #oxide-api = { path= "../oxide.rs/oxide" } parse-display = "^0.5.5" pulldown-cmark = "^0.9.1" diff --git a/cli-macro-impl/src/lib.rs b/cli-macro-impl/src/lib.rs index 95b68fa..ffb10be 100644 --- a/cli-macro-impl/src/lib.rs +++ b/cli-macro-impl/src/lib.rs @@ -583,6 +583,7 @@ struct Property { schema: openapiv3::ReferenceOr, required: bool, description: Option, + default: Option, } struct Parameter { @@ -745,6 +746,7 @@ impl Operation { required: obj.required.contains(&key) || obj.required.contains(&key.trim_start_matches("new_").to_string()), description: s.schema_data.description, + default: s.schema_data.default, }, ); } @@ -938,6 +940,7 @@ impl Operation { schema: openapiv3::ReferenceOr, description: Option, required: bool, + default: Option, ) -> Result { if skip_defaults(name, tag) || name == format!("{}_name", singular(tag)) @@ -1022,9 +1025,33 @@ impl Operation { quote! { #[clap(#long_flag, #short_flag multiple_values = true)] } + } else if rendered == "bool" { + // Clap treats bools as flags, so any value passed is ignored + // just whether the argument is present or not is used. + // So if a default value of true is passed, there's no way to + // set the flag to false. We use `parse(try_from_str)` to + // allow passing true or false as the value. + // To also allow passing the flag without a value, we use + // `default_missing_value`. + // Perhaps we could be smart and generate --foo / --no-foo? + let default = default + .map(|d| d.to_string()) + .map(|d| quote! { + parse(try_from_str), default_value = #d, default_missing_value = #d + }) + .unwrap_or_else(|| quote! { }); + + quote! { + #[clap(#long_flag, #short_flag #default)] + } } else { + let default = default + .map(|d| d.to_string()) + .map(|d| quote! { default_value = #d }) + .unwrap_or_else(|| quote! { default_value_t }); + quote! { - #[clap(#long_flag, #short_flag default_value_t)] + #[clap(#long_flag, #short_flag #default)] } } } else { @@ -1054,11 +1081,11 @@ impl Operation { // Let's get the type. let schema = data.format.schema()?; - params.push(self.render_struct_param(¶m, tag, schema, data.description, p.required)?); + params.push(self.render_struct_param(¶m, tag, schema, data.description, p.required, None)?); } for (param, p) in self.get_request_body_properties()? { - params.push(self.render_struct_param(¶m, tag, p.schema, p.description, p.required)?); + params.push(self.render_struct_param(¶m, tag, p.schema, p.description, p.required, p.default)?); } Ok(params) diff --git a/cli-macro-impl/tests/gen/instances.rs.gen b/cli-macro-impl/tests/gen/instances.rs.gen index bc5b456..51ffeb8 100644 --- a/cli-macro-impl/tests/gen/instances.rs.gen +++ b/cli-macro-impl/tests/gen/instances.rs.gen @@ -97,8 +97,17 @@ pub struct CmdInstanceCreate { #[doc = "The network interfaces to be created for this instance."] #[clap(long = "network-interfaces", short = 'n')] pub network_interfaces: Option, + #[doc = "Should this instance be started upon creation; true by default."] + #[clap( + long = "start", + short = 's', + parse(try_from_str), + default_value = "true", + default_missing_value = "true" + )] + pub start: bool, #[doc = "User data for instance initialization systems (such as cloud-init). Must be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and / characters with padding). Maximum 32 KiB unencoded data."] - #[clap(long = "user-data", short = 'u', default_value_t)] + #[clap(long = "user-data", short = 'u', default_value = "\"\"")] pub user_data: String, } @@ -273,6 +282,7 @@ impl crate::cmd::Command for CmdInstanceCreate { name: instance.clone(), ncpus: ncpus.clone(), network_interfaces: self.network_interfaces.clone(), + start: self.start.clone(), user_data: self.user_data.clone(), }, ) diff --git a/docs/oxide.json b/docs/oxide.json index 87f6923..d842932 100644 --- a/docs/oxide.json +++ b/docs/oxide.json @@ -1403,6 +1403,11 @@ "long": "network-interfaces", "help": "The network interfaces to be created for this instance" }, + { + "short": "s", + "long": "start", + "help": "Should this instance be started upon creation; true by default" + }, { "short": "u", "long": "user-data", diff --git a/spec.json b/spec.json index eff43d3..a65971c 100644 --- a/spec.json +++ b/spec.json @@ -8782,6 +8782,11 @@ } ] }, + "start": { + "description": "Should this instance be started upon creation; true by default.", + "default": true, + "type": "boolean" + }, "user_data": { "description": "User data for instance initialization systems (such as cloud-init). Must be a Base64-encoded string, as specified in RFC 4648 § 4 (+ and / characters with padding). Maximum 32 KiB unencoded data.", "default": "", @@ -12142,4 +12147,4 @@ } } ] -} \ No newline at end of file +} diff --git a/src/cmd_instance.rs b/src/cmd_instance.rs index 8cf61ee..f85154e 100644 --- a/src/cmd_instance.rs +++ b/src/cmd_instance.rs @@ -558,6 +558,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(), @@ -578,6 +579,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(), @@ -598,6 +600,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(), @@ -618,6 +621,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(), @@ -638,6 +642,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(), @@ -658,6 +663,7 @@ mod test { disks: Default::default(), user_data: "some data".to_string(), external_ips: Vec::from(["mypool".to_string()]), + start: true, }), stdin: "".to_string(),