Skip to content

Commit

Permalink
new python bindings: SqliteReportBuilder.from_pyreport() (#36)
Browse files Browse the repository at this point in the history
* sqlite report/builder: rename 'new' to 'open'

* make parse_pyreport take a sqlite report builder instead of an out path

* python bindings for parse_pyreport and SqliteReportBuilder
  • Loading branch information
matt-codecov authored Sep 16, 2024
1 parent dc4903d commit 739da11
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 75 deletions.
16 changes: 16 additions & 0 deletions bindings/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pub use codecov_rs::error::CodecovError as RsCodecovError;
use pyo3::{exceptions::PyRuntimeError, prelude::*};

pub struct PyCodecovError(RsCodecovError);

impl From<PyCodecovError> for PyErr {
fn from(error: PyCodecovError) -> Self {
PyRuntimeError::new_err(error.0.to_string())
}
}

impl From<RsCodecovError> for PyCodecovError {
fn from(other: RsCodecovError) -> Self {
Self(other)
}
}
41 changes: 32 additions & 9 deletions bindings/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
use std::{fs::File, path::PathBuf};

use codecov_rs::{parsers, report};
use pyo3::prelude::*;

// See if non-pyo3-annotated Rust lines are still instrumented
fn raw_rust_add(a: usize, b: usize) -> usize {
println!("hello");
a + b
}
use crate::error::PyCodecovError;

mod error;

#[pyclass]
pub struct SqliteReportBuilder(report::SqliteReportBuilder);

#[pymethods]
impl SqliteReportBuilder {
pub fn filepath(&self) -> PyResult<&PathBuf> {
Ok(&self.0.filename)
}

#[staticmethod]
#[pyo3(signature = (report_json_filepath, chunks_filepath, out_path))]
pub fn from_pyreport(
report_json_filepath: &str,
chunks_filepath: &str,
out_path: &str,
) -> PyResult<SqliteReportBuilder> {
let mut report_builder =
report::SqliteReportBuilder::open(out_path.into()).map_err(PyCodecovError::from)?;

#[pyfunction]
fn dummy_add(a: usize, b: usize) -> PyResult<usize> {
Ok(raw_rust_add(a, b))
let report_json_file = File::open(report_json_filepath)?;
let chunks_file = File::open(chunks_filepath)?;
parsers::pyreport::parse_pyreport(&report_json_file, &chunks_file, &mut report_builder)
.map_err(PyCodecovError::from)?;
Ok(SqliteReportBuilder(report_builder))
}
}

#[pymodule]
fn _bindings(_py: Python, m: &Bound<PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(dummy_add, m)?)?;
m.add_class::<SqliteReportBuilder>()?;
Ok(())
}
5 changes: 3 additions & 2 deletions core/examples/parse_pyreport.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{env, fs::File, path::PathBuf};

use codecov_rs::{error::Result, parsers::pyreport::parse_pyreport};
use codecov_rs::{error::Result, parsers::pyreport::parse_pyreport, report::SqliteReportBuilder};

fn usage_error() -> ! {
println!("Usage:");
Expand All @@ -23,7 +23,8 @@ pub fn main() -> Result<()> {
let chunks_file = File::open(&args[2])?;
let out_path = PathBuf::from(&args[3]);

parse_pyreport(&report_json_file, &chunks_file, out_path)?;
let mut report_builder = SqliteReportBuilder::open(out_path)?;
parse_pyreport(&report_json_file, &chunks_file, &mut report_builder)?;

Ok(())
}
2 changes: 1 addition & 1 deletion core/examples/sql_to_pyreport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn main() -> Result<()> {
}

let sqlite_path = &args[1];
let report = SqliteReport::new(sqlite_path.into())?;
let report = SqliteReport::open(sqlite_path.into())?;

let mut report_json_file = File::create(&args[2])?;
let mut chunks_file = File::create(&args[3])?;
Expand Down
13 changes: 6 additions & 7 deletions core/src/parsers/pyreport/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::{fs::File, path::PathBuf};
use std::fs::File;

use memmap2::Mmap;
use winnow::Parser;

use crate::{
error::{CodecovError, Result},
report::{ReportBuilder, SqliteReport, SqliteReportBuilder, SqliteReportBuilderTx},
report::{SqliteReport, SqliteReportBuilder, SqliteReportBuilderTx},
};

pub mod report_json;
Expand Down Expand Up @@ -38,9 +38,8 @@ mod utils;
pub fn parse_pyreport(
report_json_file: &File,
chunks_file: &File,
out_path: PathBuf,
) -> Result<SqliteReport> {
let mut report_builder = SqliteReportBuilder::new(out_path)?;
report_builder: &mut SqliteReportBuilder,
) -> Result<()> {
// Encapsulate all of this in a block so that `report_builder_tx` gets torn down
// at the end. Otherwise, it'll hold onto a reference to `report_builder`
// and prevent us from consuming `report_builder` to actually build a
Expand Down Expand Up @@ -69,6 +68,6 @@ pub fn parse_pyreport(
.map_err(|e| e.into_inner().unwrap_or_default())
.map_err(CodecovError::ParserError)?;
}
// Build and return the `SqliteReport`
report_builder.build()

Ok(())
}
8 changes: 4 additions & 4 deletions core/src/report/pyreport/chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ mod tests {
fn test_build_datapoint_from_row() {
let ctx = setup();
let db_path = ctx.temp_dir.path().join("test.db");
let report = SqliteReport::new(db_path).unwrap();
let report = SqliteReport::open(db_path).unwrap();

let test_cases: &[(&[&dyn rusqlite::ToSql], Option<JsonVal>)] = &[
(
Expand Down Expand Up @@ -415,7 +415,7 @@ mod tests {
fn test_build_line_session_from_row() {
let ctx = setup();
let db_path = ctx.temp_dir.path().join("test.db");
let report = SqliteReport::new(db_path).unwrap();
let report = SqliteReport::open(db_path).unwrap();

let test_cases: &[(&[&dyn rusqlite::ToSql], JsonVal)] = &[
(
Expand Down Expand Up @@ -502,7 +502,7 @@ mod tests {
fn test_build_report_line_from_row() {
let ctx = setup();
let db_path = ctx.temp_dir.path().join("test.db");
let report = SqliteReport::new(db_path).unwrap();
let report = SqliteReport::open(db_path).unwrap();

let test_cases = &[
(
Expand Down Expand Up @@ -645,7 +645,7 @@ mod tests {
json!({"labels_index": {"1": "test-case", "2": "test-case 2"}})
);

let empty_report = SqliteReport::new(ctx.temp_dir.path().join("empty.db")).unwrap();
let empty_report = SqliteReport::open(ctx.temp_dir.path().join("empty.db")).unwrap();
assert_eq!(query_chunks_file_header(&empty_report).unwrap(), json!({}),);
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/report/pyreport/report_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ mod tests {

assert_eq!(report_json, expected);

let empty_report = SqliteReport::new(ctx.temp_dir.path().join("empty.db")).unwrap();
let empty_report = SqliteReport::open(ctx.temp_dir.path().join("empty.db")).unwrap();

let mut report_output = Vec::new();
sql_to_report_json(&empty_report, &mut report_output).unwrap();
Expand Down
12 changes: 6 additions & 6 deletions core/src/report/sqlite/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ mod tests {
fn setup() -> Ctx {
let temp_dir = TempDir::new().ok().unwrap();
let db_file = temp_dir.path().join("db.sqlite");
let report = SqliteReport::new(db_file).unwrap();
let report = SqliteReport::open(db_file).unwrap();

report
.conn
Expand Down Expand Up @@ -730,7 +730,7 @@ mod tests {
fn test_context_assoc_single_insert() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let raw_upload = report_builder
.insert_raw_upload(Default::default())
Expand Down Expand Up @@ -771,7 +771,7 @@ mod tests {
fn test_coverage_sample_single_insert() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let source_file = report_builder.insert_file("foo.rs").unwrap();
let raw_upload = report_builder
Expand Down Expand Up @@ -804,7 +804,7 @@ mod tests {
fn test_branches_data_single_insert() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let source_file = report_builder.insert_file("path").unwrap();
let raw_upload = report_builder
Expand Down Expand Up @@ -854,7 +854,7 @@ mod tests {
fn test_method_data_single_insert() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let source_file = report_builder.insert_file("foo.rs").unwrap();
let raw_upload = report_builder
Expand Down Expand Up @@ -901,7 +901,7 @@ mod tests {
fn test_span_data_single_insert() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let source_file = report_builder.insert_file("foo.rs").unwrap();
let raw_upload = report_builder
Expand Down
12 changes: 6 additions & 6 deletions core/src/report/sqlite/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl fmt::Debug for SqliteReport {
}

impl SqliteReport {
pub fn new(filename: PathBuf) -> Result<SqliteReport> {
pub fn open(filename: PathBuf) -> Result<SqliteReport> {
let conn = open_database(&filename)?;
Ok(SqliteReport { filename, conn })
}
Expand Down Expand Up @@ -196,12 +196,12 @@ mod tests {
}

#[test]
fn test_new_report_runs_migrations() {
fn test_open_report_runs_migrations() {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
assert!(!db_file.exists());

let report = SqliteReport::new(db_file).unwrap();
let report = SqliteReport::open(db_file).unwrap();
assert_eq!(
super::super::MIGRATIONS.current_version(&report.conn),
Ok(SchemaVersion::Inside(NonZeroUsize::new(1).unwrap()))
Expand All @@ -214,7 +214,7 @@ mod tests {
let db_file_left = ctx.temp_dir.path().join("left.sqlite");
let db_file_right = ctx.temp_dir.path().join("right.sqlite");

let mut left_report_builder = SqliteReportBuilder::new(db_file_left).unwrap();
let mut left_report_builder = SqliteReportBuilder::open(db_file_left).unwrap();
let file_1 = left_report_builder.insert_file("src/report.rs").unwrap();
let file_2 = left_report_builder
.insert_file("src/report/models.rs")
Expand Down Expand Up @@ -262,7 +262,7 @@ mod tests {
});
}

let mut right_report_builder = SqliteReportBuilder::new(db_file_right).unwrap();
let mut right_report_builder = SqliteReportBuilder::open(db_file_right).unwrap();
let file_2 = right_report_builder
.insert_file("src/report/models.rs")
.unwrap();
Expand Down Expand Up @@ -367,7 +367,7 @@ mod tests {
let ctx = setup();
let db_file = ctx.temp_dir.path().join("db.sqlite");
assert!(!db_file.exists());
let mut report_builder = SqliteReportBuilder::new(db_file).unwrap();
let mut report_builder = SqliteReportBuilder::open(db_file).unwrap();

let file_1 = report_builder.insert_file("src/report.rs").unwrap();
let file_2 = report_builder.insert_file("src/report/models.rs").unwrap();
Expand Down
Loading

0 comments on commit 739da11

Please sign in to comment.