-
-
Notifications
You must be signed in to change notification settings - Fork 29
feat: make kopium usable as a library #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: make kopium usable as a library #347
Conversation
9ddea53
to
24a5319
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey, thanks for the showcase for this. it's a decent start.
i'm not keen on just exposing most of main
as a library interface though. arg parsing / stdin reading / auto complete / crd detection etc is not really a lib concern.
i am open to refactors that lifts stuff from main into the output module (or some similar formatter moduler) because then the already published library (e.g. the one with docs here) would be more useful.
also, file renames and large shifting around like this is also not great because this means i have a very hard github diff to review. kind of github problem and not yours, but i work with what's here 😢
@clux Would it be uhh.. keener to extract everything that isn't parsing / stdin reading / auto complete / crd detection to the lib level then? Happy to take a second pass at it. |
Signed-off-by: Mark S <[email protected]>
c35e0d3
to
cfac1bd
Compare
@clux took that second pass and separated all the "clearly CLI" from "probably library" code. Hopefully it's closer to spec? |
Signed-off-by: Mark S <[email protected]>
cfac1bd
to
6de78b3
Compare
Also used kopium to avoid manual adjustments to get rust types from xrd's. Atm has a compile-time dependency on the kopium-cli, but maybe we won't need this long time. (see kube-rs/kopium#347) Open Bugs: - metadata.generation seems to be passed as float and we won't accept it as it should be formally i64
hey, sorry slow response. not had a time to have a proper think about this, and the large diff makes it hard to sit down in small periods of time. but i've had your idea of the big typed builder emulating the cli bouncing around in my head for a while, and i wasn't sure about it last week, but think i am coming around to it. 😄 are you able to run |
Absolutely no worries, I know how it is.
Yeah, it's kinda nice. I actually put in a PR to the
Done, and merge conflicts resolved 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have had one go over, lmk what you think 😄
need to look more later, haven't dug in detail into the main
replacement (generate_rust_types_for
) yet
self.derive_traits.push(json) | ||
} | ||
} | ||
_ => {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can probably have an enum exposed for this for library case here to avoid string typing.
we can reference the kube-derive upstream derive modes it is based on
/// Enable all automation features | ||
/// | ||
/// This is functionally the same as supplying `--auto` to the `kopium` command | ||
pub fn auto(&mut self, value: bool) { | ||
self.emit_docs = value; | ||
if value { | ||
self.schema_mode = "derived".into(); | ||
} else { | ||
self.schema_mode = "disabled".into(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm a little unsure of whether this "fuzzy helper alias" should be part of the library api, but it is at least consistent with the cli 🤔
/// Add the supplied [`Derive`] directive to the list of traits to be derived on | ||
/// generated types | ||
pub fn derive(&mut self, value: Derive) { | ||
self.derive_traits.push(value); | ||
} | ||
/// Attempt to parse the supplied value as a [`Derive`] directive and add it to | ||
/// the list of traits to be derived on generated types | ||
pub fn try_derive(&mut self, value: impl AsRef<str>) { | ||
let derive = value.as_ref().parse::<Derive>().expect("unparsable value"); | ||
self.derive_traits.push(derive); | ||
} | ||
/// Add all the supplied [`Derive`] directives to the list of traits to be derived | ||
/// on generated types | ||
pub fn derive_all(&mut self, values: impl IntoIterator<Item = Derive>) { | ||
self.derive_traits.extend(values); | ||
} | ||
/// Attempt to parse each of the supplied values as a [`Derive`] directive and add | ||
/// them to the list of traits to be derived on generated types | ||
pub fn try_derive_all(&mut self, values: impl IntoIterator<Item = impl AsRef<str>>) { | ||
let values = values.into_iter().map(|value| { | ||
value.as_ref().parse::<Derive>().expect("unparsable value") | ||
}); | ||
self.derive_traits.extend(values); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am not a fan of relying on the FromStr
impl for Derive
which takes the same fuzzy input. Maybe we can make Target
and Derive
public and let people implement them for precise library input?
impl<T: AsRef<str>> From<T> for MapType { | ||
fn from(value: T) -> Self { | ||
let value = value.as_ref(); | ||
|
||
if value.eq_ignore_ascii_case("HashMap") { | ||
Self::HashMap | ||
} else { | ||
if !value.eq_ignore_ascii_case("BTreeMap") { | ||
log::warn!("unknown map type '{}', defaulting to BTreeMap", value); | ||
} | ||
|
||
Self::BTreeMap | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i see this is to get around clap arg parse, and we have kept it fuzzy. in this case, maybe it's better to do something like what prost_build is doing https://docs.rs/prost-build/latest/prost_build/struct.Config.html#method.btree_map
(with a .hash_map setter instead)
#[builder( | ||
default_code = r#"String::from("disabled")"#, | ||
via_mutators(init = String::from("disabled")), | ||
)] | ||
schema_mode: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the builder code like this flexible? the suggestion i made may be not super compatible with an inflexible builder setup?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my fiddling so far, it has been, yeah. It's really only there to try and maintain parity with the CLI behavior though, which may or may not be sensible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i do have a stronger sense of guarantees for library behavior baked into my head personally, because you can do a lot more of the common rust mantra (make invalid states unrepresentable) with the code as opposed to various cli flags that ultimately takes strings.
we don't have to go too far with it, in an initial pr like this, but ideally we can make the library interface follow standard library conventions a little more. as in, i don't think we need to maintain parity with the ad-hoc way i set up most of the kopium cli flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, when you put it like that, I think it makes a lot of sense. Seems like we could go the other way with it actually, and start (in a follow-up) by bringing the library interface up to snuff with standard rust library conventions and then bringing the CLI into line so to speak.
(Side note, please take all of ^ these type comments from me as a tacit offer to do the work in question, as opposed to "wouldn't it be great if someone..." 😅)
@clux Do you think it'd be possible to schedule a working session to get this into shape for merging? I'm sure your schedule is probably as unhelpful as mine, but I'd love to carve out some time to get it over the line if we can 😅 |
Yeah, that's probably a good idea. Do you mean like a video call or something? Can probably set something up or we can piggy-back on the kube sync. I'm UK, and if you're east coast, can do something in US morning a day you have time. Monday/Thu/Fri are good for me. |
Yes.
Awesome. If you're on the CNCF Slack, wanna coordinate there? (I sent you a DM there already, just in case) |
Per our conversation today, the recent changes are a bit much to be able to rebase / resolve the merge conflicts with any degree of certainty, so I'm I'm gonna close this PR in favor of simply redoing the work against the updated |
PR makes
kopium
usable as a library in addition to its current standalone tool status.Addresses #335