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

Add run subcommand #118

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 16 additions & 47 deletions crates/cairo-coverage-args/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,23 @@
use anyhow::ensure;
use camino::Utf8PathBuf;
use clap::{Parser, ValueEnum};
use crate::run::RunArgs;
use clap::{Parser, Subcommand};

pub mod run;

#[derive(Parser, Debug)]
#[command(version, args_conflicts_with_subcommands = true)]
pub struct CairoCoverageArgs {
/// Paths to the .json files with trace data.
#[arg(value_parser = parse_trace_file, num_args = 1.., required = true)]
pub trace_files: Vec<Utf8PathBuf>,

/// Path to the output file.
#[arg(short, long, default_value = "coverage.lcov")]
pub output_path: Utf8PathBuf,

/// Include additional components in the coverage report.
#[arg(long, short, num_args = 1..)]
pub include: Vec<IncludedComponent>,

/// Path to the project directory. If not provided, the project directory is inferred from the trace.
#[arg(value_parser = parse_project_path, long)]
pub project_path: Option<Utf8PathBuf>,
}

/// Additional components that can be included in the coverage report.
#[derive(ValueEnum, Debug, Clone, Eq, PartialEq)]
pub enum IncludedComponent {
/// Run coverage on functions marked with `#[test]` attribute
TestFunctions,
/// Run coverage on macros and generated code by them. This includes inline macros, attribute macros, and derive macros.
Macros,
/// Arguments for the `run` subcommand so user can use
/// `cairo-coverage` without specifying the subcommand.
#[clap(flatten)]
pub run_args: RunArgs,
/// Subcommand and its arguments.
#[command(subcommand)]
pub command: Option<Command>,
}

fn parse_trace_file(path: &str) -> anyhow::Result<Utf8PathBuf> {
let trace_file = Utf8PathBuf::from(path);

ensure!(trace_file.exists(), "Trace file does not exist");
ensure!(trace_file.is_file(), "Trace file is not a file");
ensure!(
matches!(trace_file.extension(), Some("json")),
"Trace file must have a JSON extension"
);

Ok(trace_file)
}

fn parse_project_path(path: &str) -> anyhow::Result<Utf8PathBuf> {
let project_path = Utf8PathBuf::from(path);

ensure!(project_path.exists(), "Project path does not exist");
ensure!(project_path.is_dir(), "Project path is not a directory");

Ok(project_path)
/// Subcommand and its arguments.
#[derive(Subcommand, Debug)]
pub enum Command {
/// Run `cairo-coverage` tool.
Run(RunArgs),
}
54 changes: 54 additions & 0 deletions crates/cairo-coverage-args/src/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use anyhow::{ensure, Result};
use camino::Utf8PathBuf;
use clap::{Parser, ValueEnum};

/// Arguments accepted by the `run` subcommand.
#[derive(Parser, Debug)]
pub struct RunArgs {
/// Paths to the .json files with trace data.
#[arg(value_parser = parse_trace_file, num_args = 1.., required = true)]
pub trace_files: Vec<Utf8PathBuf>,

/// Path to the output file.
#[arg(short, long, default_value = "coverage.lcov")]
pub output_path: Utf8PathBuf,

/// Include additional components in the coverage report.
#[arg(long, short, num_args = 1..)]
pub include: Vec<IncludedComponent>,

/// Path to the project directory. If not provided, the project directory is inferred from the trace.
#[arg(value_parser = parse_project_path, long)]
pub project_path: Option<Utf8PathBuf>,
}

/// Additional components that can be included in the coverage report.
#[derive(ValueEnum, Debug, Clone, Eq, PartialEq)]
pub enum IncludedComponent {
/// Run coverage on functions marked with `#[test]` attribute
TestFunctions,
/// Run coverage on macros and generated code by them. This includes inline macros, attribute macros, and derive macros.
Macros,
}

fn parse_trace_file(path: &str) -> Result<Utf8PathBuf> {
let trace_file = Utf8PathBuf::from(path);

ensure!(trace_file.exists(), "Trace file does not exist");
ensure!(trace_file.is_file(), "Trace file is not a file");
ensure!(
matches!(trace_file.extension(), Some("json")),
"Trace file must have a JSON extension"
);

Ok(trace_file)
}

fn parse_project_path(path: &str) -> Result<Utf8PathBuf> {
let project_path = Utf8PathBuf::from(path);

ensure!(project_path.exists(), "Project path does not exist");
ensure!(project_path.is_dir(), "Project path is not a directory");

Ok(project_path)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::input::filter::ignore::CairoCoverageIgnoreMatcher;
use crate::input::sierra_to_cairo_map::{SimpleLibfuncName, StatementOrigin};
use cairo_annotations::annotations::coverage::SourceFileFullPath;
use cairo_annotations::annotations::profiler::FunctionName;
use cairo_coverage_args::IncludedComponent;
use cairo_coverage_args::run::IncludedComponent;
use camino::Utf8PathBuf;
use regex::Regex;
use std::collections::HashSet;
Expand Down
6 changes: 3 additions & 3 deletions crates/cairo-coverage-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::data_loader::LoadedDataMap;
use crate::input::{InputData, StatementCategoryFilter};
use crate::output::lcov::LcovFormat;
use anyhow::{bail, ensure, Context, Result};
use cairo_coverage_args::CairoCoverageArgs;
use cairo_coverage_args::run::RunArgs;
use camino::Utf8PathBuf;
use indoc::indoc;
use merge::MergeOwned;
Expand All @@ -25,12 +25,12 @@ const SNFORGE_SIERRA_DIR: &str = ".snfoundry_versioned_programs";
/// # Errors
/// Fails if it can't produce the coverage report with the error message explaining the reason.
pub fn run(
CairoCoverageArgs {
RunArgs {
trace_files,
include,
output_path,
project_path,
}: CairoCoverageArgs,
}: RunArgs,
) -> Result<()> {
let coverage_data = LoadedDataMap::load(&trace_files)?
.iter()
Expand Down
11 changes: 11 additions & 0 deletions crates/cairo-coverage/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod run;

use anyhow::Result;
use cairo_coverage_args::Command;

/// Run chosen [`Command`].
pub fn run(command: Command) -> Result<()> {
match command {
Command::Run(args) => run::run(args),
}
}
8 changes: 8 additions & 0 deletions crates/cairo-coverage/src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use anyhow::Result;
use cairo_coverage_args::run::RunArgs;

/// Run the `cairo-coverage run` command with [`RunArgs`].
/// This is done by calling the [`cairo_coverage_core`] crate.
pub fn run(args: RunArgs) -> Result<()> {
cairo_coverage_core::run(args)
}
14 changes: 12 additions & 2 deletions crates/cairo-coverage/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
use anyhow::Result;
use cairo_coverage_args::CairoCoverageArgs;
use cairo_coverage_args::{CairoCoverageArgs, Command};
use clap::Parser;

mod commands;

fn main() -> Result<()> {
let cairo_coverage_args = CairoCoverageArgs::parse();

cairo_coverage_core::run(cairo_coverage_args)
let command = match cairo_coverage_args.command {
Some(command) => command,
// TODO:
// * In 0.5.0 add deprecation warning
// * In 0.6.0 remove the default command
None => Command::Run(cairo_coverage_args.run_args),
};

commands::run(command)
}
Loading