cargo/ops/cargo_report/
sessions.rs

1//! The `cargo report sessions` command.
2
3use annotate_snippets::Level;
4
5use crate::CargoResult;
6use crate::GlobalContext;
7use crate::core::Workspace;
8use crate::ops::cargo_report::util::list_log_files;
9use crate::util::BuildLogger;
10
11pub struct ReportSessionsOptions {
12    pub limit: usize,
13}
14
15pub fn report_sessions(
16    gctx: &GlobalContext,
17    ws: Option<&Workspace<'_>>,
18    opts: ReportSessionsOptions,
19) -> CargoResult<()> {
20    let ws_run_id = ws.map(BuildLogger::generate_run_id);
21
22    // Take limit + 1 to detect if there are more sessions
23    let sessions: Vec<_> = list_log_files(gctx, None)?
24        .filter(|(_, id)| {
25            ws_run_id
26                .as_ref()
27                .map(|ws_run_id| ws_run_id.same_workspace(id))
28                .unwrap_or(true)
29        })
30        .take(opts.limit + 1)
31        .collect();
32
33    if sessions.is_empty() {
34        let context = if let Some(ws) = ws {
35            format!(" for workspace at `{}`", ws.root().display())
36        } else {
37            String::new()
38        };
39        let title = format!("no sessions found{context}");
40        let note = "run build commands with `-Z build-analysis` to generate log files";
41
42        let report = [Level::ERROR
43            .primary_title(title)
44            .element(Level::NOTE.message(note))];
45        gctx.shell().print_report(&report, false)?;
46        return Err(crate::AlreadyPrintedError::new(anyhow::anyhow!("")).into());
47    }
48
49    let truncated = sessions.len() > opts.limit;
50    let display_count = opts.limit.min(sessions.len());
51
52    let mut shell = gctx.shell();
53    let stderr = shell.err();
54
55    if let Some(ws) = ws {
56        writeln!(
57            stderr,
58            "Session IDs for `{}` (most recent first):",
59            ws.root().display(),
60        )?;
61    } else {
62        writeln!(stderr, "Session IDs (most recent first):",)?
63    };
64    writeln!(stderr)?;
65
66    for (_path, run_id) in sessions.iter().take(display_count) {
67        writeln!(stderr, " - {run_id}")?;
68    }
69
70    if truncated {
71        writeln!(stderr)?;
72        writeln!(stderr, "... and more (use --limit N to see more)")?;
73    }
74
75    Ok(())
76}