-
Notifications
You must be signed in to change notification settings - Fork 955
Replace term with termcolor #3351
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
Conversation
17305eb
to
0cd5415
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.
My suggestion:
Don't push Terminal into FileSource, instead keep the abstraction we had before - Writer and Write - and use StandardStream and StandardStreamLock as appropriate on top of that. Push isatty into FileSource (it probably should be anyway for testing support), but we shouldn't be constructing these a lot anyway - even with cross-thread concerns. In term.rs it could make sense to have a long lived reference to a StandardStream.
Note that the Inner is simple : https://docs.rs/termcolor/latest/src/termcolor/lib.rs.html#465 - and should be threadsafe itself if W is, so its not clear what was going on.
Do you have the git ref that shows the problem you encountered?
This comment was marked as outdated.
This comment was marked as outdated.
1afcaa6
to
30b259c
Compare
Ah I think I meant further back than that - you were asking about a thread compile error - missing Sync or some such thing somewhere. |
93b08e4
to
8af7e6a
Compare
Oh, I want to pass a |
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 will squash the commits and do some manual tests after your review.
ok, so coming back to the dyn question; because we implement an analog to std::io::stdout(), most code doesn't know the concrete type that will be returned. So we return a Box rather than being specialised by some T=std::io::StdOut. Doing that might be better, but it would require threading that type T throughout the code base - I did attempt that, and it was pretty awful - thousands and thousands of lines of churn, and a type parameter on nearly every struct in the codebase. Console IO probably isn't such a common call-path that removing the one dyn is critical (but perhaps in future). However, I see a more subtle problem with your patch.
This depends on term_color::StandardStream, which itself is defined as:
Thats problematic because our TestProcess has no room to hook into that that all. I presume thats why CurrentProcess was changed to return Terminal types, not Stdout / Stderr look-alikes. Thats a shame, but I guess natural. I'd like to suggest we put these crate updates aside and don't do them yet. Instead, lets refactor all our console IO to the following shape without changing dependencies, and then after that it should be really easy to drop new things in. The new shape is:
Theres a little hair in there related to getting into an async mode, but I think I've got that cracked - the otel code seems pretty reliable at this point, so expanding our async coverage bit by bit could be really nice. The main bit thats missing is adding in a shim to the tokio runtime for every new thread we create - which I think at this point is just the gnarly IO worker pools, which I think don't even actually do console IO themselves ... so we might be able to defer that for a while yet. The key benefit of this approach is that we can do a series of small patches and not have to end up with a big-change at any point. Even though I did that just recently with ToolchainNames its something to avoid wherever possible! Concrete steps would be:
|
Putting organisational style comments here, as discord isn't googleable :P. I think the approach I'm proposing only has one real question, which is "is tokio's platform support wide enough for rustup" ? Rust Tiers are basically trailing definitions - a platform with everything working and tested is Tier 1, a platform where folk can developer is Tier2+host tools, and one everything builds is Tier 2, and Tier 3 is best effort. So for Rustup to adopt something that we can't fix easily ourselves as a dependency, we want it to support Tier 1 and Tier2+Host Tools, otherwise we're reducing our coverage accidentally. Supporting more - like Android and iOS - is nice but not a must-have as far as I can tell. Tokio platform support doesn't vary by architecture, only OS, so it seems that they consider an issue on some arch that they cover the OS for to be a bug. Doesn't mean there won't be any, but at least it would be something they consider important? MIO platform support is the thing that really dominates tokio support. So comparing: | platform | Tier | Tokio | Mio | I think this is pretty safe, but we could do an advance test where we only introduce the runtime don't use it, and see who screams. |
259962b
to
febf4e8
Compare
dd3d310
to
05e05bd
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.
This is looking pretty good.
I have left a number of comments.
There is one place in particular that I would like to see different which is the move of stdout/stderr into the terminal responsibility. At least in my head the streams and the terminal abstraction over them are really quite different. Having the terminal in currentprocess is required because of the termcolor design, so this is looking much nicer from that perspective, but I'd still like to see it layered, so that we can have terminal-free stdout when needed.
let _ = t.attr(term2::Attr::Bold); | ||
let _ = writeln!(t, "{target} (installed)"); | ||
let _ = t.attr(terminalsource::Attr::Bold); | ||
let _ = writeln!(t.lock(), "{target} (installed)"); |
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.
A note for future investigation .... is the let _ =
needed still? I presume its discarding the fallible from the call, but we're in a function that returns Result, so ?
should be usable.
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 will take a look later.
src/currentprocess/terminalsource.rs
Outdated
self.stream.reset() | ||
} | ||
|
||
fn carriage_return(&mut self) -> io::Result<()> { |
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 we should drop this method. It existed because the other terminal abstraction we used provided it, but if termcolor just wants a \r in the stream, we can just make our code do that directly.
This can be done in a later PR to keep this one focused on the like-for-like exchange.
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 will change it in my next PR.
05e05bd
to
304f812
Compare
- moves terminal into currentprocess abstraction, because termcolor doesn't accept a file handle, rather it takes an enum indirectly referencing the global state of stdout/stderr. - provides write/fg/bg/locked etc as before - abstracts over TestWriter, or termcolor's own concrete types - still permits completely terminal-free operation where desired (e.g. future JSON RPC on stdin/stdout) Signed-off-by: hi-rustin <rustin.liu@gmail.com> Signed-off-by: Robert Collins <robertc@robertcollins.net>
304f812
to
f7579b7
Compare
Signed-off-by: 二手掉包工程师 <rustin.liu@gmail.com>
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.
Self check
@rbtcollins Thanks for your review and help! 💚 💙 💜 💛 ❤️ |
close #1818
Based on https://github.com/rust-lang/rustup/pull/2790/files. Big thanks for aloucks.
Probably close #2292.