Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Requirements Discussion: what is quicli? #19
This is a discussion on what the use case and requirements of these two libraries are.
Also related: require that all versions in quicli are of the form
What is quicli?
Qui CLI seems to have similar but not completely overlapping goals. I would prefer we merge forces rather than create competing libraries.
I think it should be possible through liberal use of feature flags to accomplish any usecase a user might want. I.e.
Wow, this turned out way longer than I anticipated. Sorry about that – but thank you very much for making me think about all of this! :)
That would be my preference as well! I do want to keep this crate small, though. And I fear we might want to go in different directions because of that. Or rather, you'll want to go much further than me. So, I hope we can share the first part of the way at least :)
As written on Reddit, my goal is to provide an opinionated set of convenience functions to quickly build CLI apps – And I want to stop there!
This crate already re-exports a bunch of stuff, and I agree that these re-exports make the experience of writing CLIs quickly much more smooth. There are some traits that are very useful, and deserve to re-exported! I want to be very deliberate in what I re-export, though. Let me give some reasoning for this.
First, a disclaimer: I'm not sure what crates/functions/types/traits "typical Rust CLI apps" actually use (I'd love to hear what people are actually using!).
E.g., having Read and Write in the prelude seems like a good idea, but AtomicBool? I've never used that one the last 4 years I've written Rust code. The attitude I wrote this crate with is even more radical, though: I'm pretty sure even Read and Write are only used in a few specific use cases. So, we should try to identify these use cases, and provide convenience functions for those! (I originally wrote that in #18 but moved it here for context.)
Just like I didn't want to re-export env_logger and instead changed the
So, instead of offering the user "everything", I want to introduce some abstractions that are simple to use, and have simple but useful examples. In addition to that, the documentation should point to where to look when you want to use some of these parts more directly/seriously.
This is an honorable goal! Rust is not Python, though, and I'm note sure how much I would try to stretch the language to make it feel like it is. I want people to know they are writing Rust, and if that means they get compiler errors telling the to
Oh god no. I'm not ready for this library to get so complex after two days in existence!
If you need a "
Yes. This is my conclusion as well.
I'd love to collaborate with you on this. But I don't think we should merge stdcli into quicli. Maybe the other way around? It seems like I am way more conservative in what I want this crate to contains. That may be a good foundation for stdcli to use as a starting point from which you include more crates and features.
I really like your response! I think it is on the right track.
Here's what I'm thinking... the ecosystem is probably not quite ready for a crate like stdcli. Instead, we should have different crates that clean up the ergonomics of different aspects of developing CLI crates and stdcli could unify them (the non-CLI ecosystem might be able to do this as well, but let's focus on CLI).
Take this crate (quicli) for example, I am (currently spitballing) its core requirements as make the
Fulfilling these requirements in an ergonomic fashion is absolutely something that we need! It's not every major requirement of a CLI, so we should probably make other "combining forces" crates. Some examples:
I think this crate doing the "generally needed stuff" would be really good, but otherwise it shouldn't touch the other domains. Instead we should create similar crates that combine the above, document them, have integration tests, etc.
At the end of the day we have simple components that add up to a complete and batteries included experience. Even better, library authors can continue to solve "one little problem" and then have their crate added to one of the conglomerating crates. This is better for both parties -- keeping crates small is really good for the ecosystem, but also being able to have an "off the shelf solution" for general problems is necessary for the ecosystem's continued growth.
I think the idea of creating "pieces of an ecosystem" is the right one. If we could design the ecoysystem from a high level we can (hopefully) start to see where the missing peices are and the role of each (conglomerating) crate individually.
That sounds awesome! Very well put.
That sounds about right!
It'd say it does go a small step beyond that, and I don't really want to stop doing that: I also want to add/export the most common functions you need in a CLI (whatever those may be).
So, in my mind, quicli gives a user the first basic layer of functionally: Add quicli and writing simple CLIs (quickly). It has a read_file helper, but to do more fancy stuff, you need to use std::fs or an external crate. It has logging, but if you want to log structured output to journald, you have do it yourself.
This is where the second layer of crates comes in: It gives you a good selection of fancy tools for specific areas. (I also think that there are some crates out there that are already perfectly usable as "second layer" crates, e.g. serde_json, reqwest, or duct.)
Wait, do you mean quicli with "this crate"? 'Cause I'm not sure I agree that maplit is generally needed (I've never needed it even though I think it's cool) and I don't see quicli re-exporting lazy-static – except indirectly in a regex function.
This is one of the hardest jobs in any ecosystem that promotes small libraries – picking and choosing and integrating a bunch of small building blocks to construct something that is useful and not chaotic.
Do you want to start writing all these crates right now or do you want to gather some feedback of what people ask for and where they find annoyances first? I'd probably go with the latter one but I'm not sure how much experience you've already gathered! :) And I have to admit, I think this is gonna be lot of work.
You right, it is probably too early for a "stable" stdcli – most of the crates you listed are not 1.0 yet and still evolving their APIs. It's hard to say which crates we'll be using next year.
In which way do you want to organize this effort? Also, I'm sure having some kind of "brand" would go a long way to connect the crates together.
This is a deep dark hole from which there is no escape
Seriously, once you start going beyond a basic requirement it become impossible (in my experience) to figure out what belongs and what doesn't.
I think some of them could be written immediately -- especially the config one (serde is pretty standard now) and probably the
I think the filesystem needs some work (like the error type you mentioned) but in my opinion it is really close.
The least stable is definitely the "terminal output" one. I don't think there is any stability there, and I've found most solutions to be unergonomic, especially when testing (and haven't yet started using the one I wrote, termstyle, yet -- which is attempting to solve some of the issues).
On maplit specifically
I've found maplit to be a lifesaver when writing tests or the rare time I want to create serialized output by hand. Mostly, as a python user, it's just a huge annoyance to not have a
Just FYI, I'm finally trying to finish up the work to merge structopt into clap proper (assuming my paid work doesn't keep interrupting
I just started the ergo crate and project: making rust's ecosystem more ergonomic, therefore more fun.
I will be creating sub-crates as defined above in the coming weeks. If anyone wants to help out feel free to dig in your heels!
Let's discuss configure in #21.
@vitiral I'm excited for ergo! Ping me if you want me to join :) I can't promise I'll have lots of time to help out, hence I'm probably not of much help on the implementation side, but I know a lot of synonyms for 'ergo' and am thus able to suggest weird module names.
FYI, after seeing how much text I wrote in this issue here, I stared rewriting it as a blog post. You can find a draft of it here if you're interested :)