aboutsummaryrefslogtreecommitdiff
path: root/primrose/crates/candelabra-cli/src/main.rs
blob: 00c85cc883aa14dbef72adb116bc52339f489cca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use std::collections::HashSet;

use anyhow::{anyhow, Context, Result};
use argh::FromArgs;
use log::info;
use project::Project;

use crate::{candidates::CandidatesStore, cost::ResultsStore, paths::Paths};

mod cache;
mod candidates;
mod cost;
mod paths;
mod project;

#[derive(FromArgs)]
/// Find the best performing container type using primrose
struct Args {
    /// path to Cargo.toml
    #[argh(option)]
    manifest_path: Option<String>,

    /// project to run on, if in a workspace
    #[argh(option, short = 'p')]
    project: Option<String>,
}

fn main() -> Result<()> {
    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();

    let args: Args = argh::from_env();

    let paths = Paths::default();
    info!("Using source dir: {:?}", &paths.base);

    let projects = get_projects(&args).context("failed to find project paths")?;

    let candidates = CandidatesStore::new(&paths)?;
    let benchmarks = ResultsStore::new(&paths)?;

    let mut seen_types = HashSet::new();
    for project in projects {
        info!("Processing {}", &project.name);

        let all_candidates = project.get_all_candidates(&candidates)?;
        info!("Found candidates: {:?}", all_candidates);
        for (_, candidates) in all_candidates.iter() {
            for candidate in candidates {
                seen_types.insert(candidate.clone());
            }
        }
    }

    info!("Found all candidate types. Running benchmarks");
    for typ in seen_types.into_iter() {
        dbg!(benchmarks.get(&typ).context("Error running benchmark")?);
    }

    Ok(())
}

fn get_projects(args: &Args) -> Result<Vec<Project>> {
    let mut cmd = cargo_metadata::MetadataCommand::new();
    if let Some(p) = &args.manifest_path {
        cmd.manifest_path(p);
    }

    let metadata = cmd.exec().context("failed to get manifest metadata")?;

    if let Some(p) = &args.project {
        // Select a specific project
        Ok(vec![metadata
            .packages
            .iter()
            .find(|pkg| pkg.name == *p)
            .map(|pkg| Project::new(pkg.clone()))
            .ok_or_else(|| {
                anyhow!("specified project does not exist")
            })?])
    } else {
        // Default to all workspace members
        Ok(metadata
            .workspace_members
            .iter()
            .flat_map(|member| metadata.packages.iter().find(|pkg| pkg.id == *member))
            .map(|pkg| Project::new(pkg.clone()))
            .collect())
    }
}