Skip to content
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

refactor: Move diagnostic printing to Shell #13813

Merged
merged 1 commit into from
Apr 30, 2024

Conversation

Muscraft
Copy link
Member

@Muscraft Muscraft commented Apr 27, 2024

As I have been working on cargo's diagnostic system, I have disliked copying around the code for a new Renderer, and then emitting the diagnostic:

let renderer = Renderer::styled().term_width(
    gctx.shell()
        .err_width()
        .diagnostic_terminal_width()
        .unwrap_or(annotate_snippets::renderer::DEFAULT_TERM_WIDTH),
);
writeln!(gctx.shell().err(), "{}", renderer.render(message))?;

Moving to a method on Shell helps mitigate the risk of updating duplicate code and missing one. It should also make it nearly impossible to get into scenarios where gctx.shell() is borrowed twice, leading to panics. This problem was one I ran into early on as I tried to write messages to stderr like so:

writeln!(
    gctx.shell().err(),
    "{}",
    Renderer::styled()
        .term_width(
            gctx.shell()
                .err_width()
                .diagnostic_terminal_width()
                .unwrap_or(annotate_snippets::renderer::DEFAULT_TERM_WIDTH),
        )
        .render(message)
)?;

@rustbot
Copy link
Collaborator

rustbot commented Apr 27, 2024

r? @epage

rustbot has assigned @epage.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-configuration Area: cargo config files and env vars A-manifest Area: Cargo.toml issues S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 27, 2024
Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me, especially for the prevention of double borrowing RefCell!

However, I wonder if we need diagnostic with to be computed every time before Cargo prints messages. I guess the answer is no, we don't care people resize their terminal width during a build.

@epage
Copy link
Contributor

epage commented Apr 29, 2024

I'm a bit uncomfortable generating this in Context::new because it can be quite easy for us to add config for controlling this (honestly, I'm surprised it doesn't exist).

As for the terminal width changing, that is more likely to come up when it comes to cargo watch support (#9339).

So far, a Renderer is "cheap". We could instead make the renderer on every call.

@@ -412,6 +413,22 @@ impl GlobalContext {
self.shell.borrow_mut()
}

/// Prints the passed in [Message] to stderr
pub fn renderer_diagnostic(&self, message: Message<'_>) -> std::io::Result<()> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason that this method is on GlobalContext instead of Shell?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None that I can think of, I went ahead and moved it to Shell

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the problems with #12875 is that it put diagnostic tracking in Shell. For me, I see Shell as lower level than that. I feel like putting diagnotic rendering in Shell could encourage that kind of thinking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree diagnostic tracking should not be in Shell, but I am not as worried about encouraging that thinking with this change. This change moves to a function where things get rendered and then emitted, similar to:

pub fn print_json<T: serde::ser::Serialize>(&mut self, obj: &T) -> CargoResult<()> {
// Path may fail to serialize to JSON ...
let encoded = serde_json::to_string(&obj)?;
// ... but don't fail due to a closed pipe.
drop(writeln!(self.out(), "{}", encoded));
Ok(())
}

The JSON gets "rendered" by serde_json::to_string and then printed to stdout.

The fact Renderer gets created inside of emit_diagnostic is an implementation detail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epage do you consider it as a blocker? I am fine with either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree diagnostic tracking should not be in Shell, but I am not as worried about encouraging that thinking with this change.

By putting it here, it implicitly states diagnostics live here and it is the starting point for any thought process on how to evolve this code.

do you consider it as a blocker? I am fine with either way.

I'm mixed. In terms of "this is all internal and easily changed", its not a blocker. It just sets us down the wrong direction for future changes unless someone thinks beyond the code in front of them which we don't always do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could put some design principles in the module-level for shell, so at least this discussion won't just disappear in the air.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current naming is low level enough that I'm fine with moving this forward

@rustbot rustbot added the A-console-output Area: Terminal output, colors, progress bar, etc. label Apr 29, 2024
@Muscraft Muscraft changed the title Move to a global Renderer Move Renderer creation to Shell Apr 29, 2024
@Muscraft Muscraft changed the title Move Renderer creation to Shell refactor: Move diagnostic printing to Shell Apr 29, 2024
@@ -1,3 +1,4 @@
use annotate_snippets::{Message, Renderer};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we don't really have a style convention for imports, though I believe if this was added by auto-import via Rust Analyzer, it would be grouped together with anstream and `anstyle.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! Normally, things get added correctly; I'm not sure why it didn't in this case.

I wish group_imports and imports_granularity were stable so we could use them.

src/cargo/core/shell.rs Outdated Show resolved Hide resolved
@weihanglo
Copy link
Member

@bors r+

Thank you all :)

@bors
Copy link
Collaborator

bors commented Apr 30, 2024

📌 Commit 5415b04 has been approved by weihanglo

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 30, 2024
@bors
Copy link
Collaborator

bors commented Apr 30, 2024

⌛ Testing commit 5415b04 with merge a1f8e45...

@bors
Copy link
Collaborator

bors commented Apr 30, 2024

☀️ Test successful - checks-actions
Approved by: weihanglo
Pushing a1f8e45 to master...

@bors bors merged commit a1f8e45 into rust-lang:master Apr 30, 2024
21 checks passed
@Muscraft Muscraft deleted the add-global-renderer branch April 30, 2024 19:10
bors added a commit to rust-lang-ci/rust that referenced this pull request May 1, 2024
Update cargo

15 commits in b60a1555155111e962018007a6d0ef85207db463..6087566b3fa73bfda29702632493e938b12d19e5
2024-04-26 16:37:29 +0000 to 2024-04-30 20:45:20 +0000
- fix(cargo-fix): dont fix into standard library (rust-lang/cargo#13792)
- refactor: Move diagnostic printing to Shell (rust-lang/cargo#13813)
- Populate git information when building Cargo from Rust's source tarball (rust-lang/cargo#13832)
- docs: fix several typos found by `typos-cli` (rust-lang/cargo#13831)
- fix(alias): Aliases without subcommands should not panic (rust-lang/cargo#13819)
- fix(toml): Improve granularity of traces (rust-lang/cargo#13830)
- fix(toml): Warn, rather than fail publish, if a target is excluded (rust-lang/cargo#13713)
- test(cargo-lints): Add a test to ensure cap-lints works (rust-lang/cargo#13829)
- fix(toml)!: Remove support for inheriting badges (rust-lang/cargo#13788)
- chore(ci): Don't check `cargo` against beta channel (rust-lang/cargo#13827)
- Fix target entry in .gitignore (rust-lang/cargo#13817)
- Bump to 0.81.0; update changelog (rust-lang/cargo#13823)
- Add failing test: artifact_dep_target_specified (rust-lang/cargo#13816)
- fix(cargo-lints): Don't always inherit workspace lints (rust-lang/cargo#13812)
- Update SleepTraker returns_in_order unit test (rust-lang/cargo#13811)

r? ghost
@rustbot rustbot added this to the 1.80.0 milestone May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-configuration Area: cargo config files and env vars A-console-output Area: Terminal output, colors, progress bar, etc. A-manifest Area: Cargo.toml issues S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants