-
Notifications
You must be signed in to change notification settings - Fork 292
esp-config tui #3442
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
base: main
Are you sure you want to change the base?
esp-config tui #3442
Conversation
For me this part is the weakest link in this approach:
esp-config is now 3-in-1: a build script library, a set of library-facing macros, and a tui. esp-hal projects' Cargo.lock files will include all sorts of non-embedded nonsense and people will ask why. |
The three "things" even don't share much code |
} | ||
|
||
// This partially mirrors [esp_config::ConfigOption] | ||
// but not exactly - `&'static str` is not great for deserializing |
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.
Why not just make it String
in esp-config?
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.
It makes it more annoying to use as is - we could ofc create constructors to compensate for that - my thinking was just that I don't want to do those changes w/o at least discussing them before
} | ||
|
||
// This partially mirrors [esp_config::Stability] | ||
// but not exactly. |
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.
Why?
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.
also &'static str
|
||
// This partially mirrors [esp_config::Validator] | ||
// but not exactly. | ||
// We especially can't and don't want to handle the `Custom` validator. |
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.
Why can't we? What am I missing here :D?
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.
Box<dyn Fn(&Value) -> Result<(), Error>>
isn't good for serialization/deserialization - and for having it clone,copy,eq etc.
(Fun fact: we don't use that validator at all currently IIRC - and while it's a wildcard for "everything" it is not nice to use it.
I'd personally like to see it go away and instead add another validator whenever we see a need for it)
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.
Alternatively we could probably have a Custom
validator using either a Rhai expression as we use it in other places or use the evalexpr
crate which is a bit more lightweight
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.
If it's not used, let's not solve the problem we don't have
esp-config/src/bin/esp-config/tui.rs
Outdated
use ratatui::{prelude::*, style::palette::tailwind, widgets::*}; | ||
use tui_textarea::{CursorMove, TextArea}; | ||
|
||
const TODO_HEADER_BG: Color = tailwind::BLUE.c950; |
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.
Considering esp-rs/esp-generate#172 maybe we shouldn't hard-code colors and emojis here, either. Also, why is this called TODO_HEADER_BG
, I couldn't figure it out even in esp-generate :)
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.
oh yes - thanks for the reminder - I wanted to add a TODO there but finally forgot to add it 😄
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.
TODO_HEADER_BG
That's a good question 🤔
esp-config/src/generate/mod.rs
Outdated
/// An integer config option | ||
/// | ||
/// Unstable and active by default. | ||
pub fn integer(name: &str, description: &str, default_value: i128) -> Self { |
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 would like to see the ConfigOption changes in a separate PR. I'm also wondering if we could get rid of the different constructors and decide based on the type of the value instead (with Into<Value>
for example)
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.
Sure - can split it up if we agree it's a direction we want to go in general
I'm also wondering if we could get rid of the different constructors and decide based on the type of the value instead (with Into for example)
Sounds like a good idea
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 think turning the big structs into builders is, well, not that valuable but I'm also not against it and you clearly think it's a good change so I'll not argue against it (except to say that I like named fields and the string
constructor being 3 stirngs is slightly-but-not-really harder to understand). But this is a huge PR and that part is a bit of a logical unit, so if we can split it out to shrink this one, that is worth it to me.
|
let mut errors_to_show = None; | ||
|
||
loop { | ||
let repository = tui::Repository::new(configs.clone()); |
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 don't understand why this is in a loop
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.
the idea is that a user could change something which is checked in the build.rs (e.g. esp-wifi does it) and the build check below will fail - in that case we show the TUI again with the error message from the build - the user can fix the problem or revert all changes in that case
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 think if any such issue could occur, is an issue with the options and their validations.
The users' projects can fail to compile for a multitude of reasons, for example the build could require a feature flag to be set. The TUI will not know how to build the project properly, so a check like this can turn the tool completely unuseable.
fn check_build_after_changes(path: &PathBuf) -> Option<String> { | ||
println!("Check configuration..."); | ||
|
||
let status = std::process::Command::new("cargo") |
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 probably shouldn't build the project, or we should make it optional. It can be very slow, or have special needs.
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.
making it optional sounds good - then we should also make the ensure_fresh_build
optional - the reason we do it is to detect invalid settings which are only checked in build.rs (esp-config initially wasn't built with tooling in mind)
we could also allow the user to pass features needed for building (while a vanilla esp-generate generated project won't require that) - I guess with a lot of customizations sooner or later a user will get to the point that they need to manage the config manually - on the other hand I assume most users will be fine with what esp-generate can do for them
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.
t.b.h.I wouldn't be sad to remove the "build-my-project" steps from the tool :)
Currently it builds before launching the TUI since it's the easiest way to guarantee the config-json is up to date .... the original plan was to check the "freshness" of the config-json and bail if needed instead - I guess that would be fine, too
For the build after applying the changes (and the cursed loop): users can modify the config in a way that makes the project fail to build (e.g.
Lines 236 to 249 in 29060ae
// Validate the configuration at compile time | |
#[allow(clippy::assertions_on_constants)] | |
const _: () = { | |
// We explicitely use `core` assert here because this evaluation happens at | |
// compile time and won't bloat the binary | |
core::assert!( | |
CONFIG.rx_ba_win < CONFIG.dynamic_rx_buf_num, | |
"WiFi configuration check: rx_ba_win should not be larger than dynamic_rx_buf_num!" | |
); | |
core::assert!( | |
CONFIG.rx_ba_win < (CONFIG.static_rx_buf_num * 2), | |
"WiFi configuration check: rx_ba_win should not be larger than double of the static_rx_buf_num!" | |
); | |
}; |
Without the check users will need to manually fix/revert the config change because the UI won't launch (because the config-json is outdated - I guess in the example above this isn't much of a problem since build.rs will write out the config-json before we fail the build in esp-wifi's lib.rs ???).
Probably that is
- not too common
- we can expect someone who is able to write Rust code to get the project back to a buildable state
So, this might be acceptable.
We could also go the extra mile and make the" build-my-project" steps opt-out - most users will benefit from the additional convenience while those who really need to can avoid it
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.
But this tool doesn't know how to build my project 🤔
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.
But this tool doesn't know how to build my project
Not yours but the projects of most people just using a vanilla esp-generate generated one - so if you could pass --no-build
(subject to bikeshed) you could use it?
Back to draft, again - since we agreed we want an overhaul of esp-config to make tooling easier |
Thank you for your contribution!
We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:
Submission Checklist 📝
cargo xtask fmt-packages
command to ensure that all changed code is formatted correctly.CHANGELOG.md
in the proper section.Extra:
Pull Request Details 📖
Description
This supercedes esp-rs/esp-generate#149
TL;DR this adds a TUI to edit config options
I guess in this case
skip-changelog
is fineTesting
Testing:
esp-config = { git = "https://github.com/esp-rs/esp-hal/" }
etc.cargo install --features=tui --path .
esp-config