diff --git a/bindings/src/error.rs b/bindings/src/error.rs new file mode 100644 index 0000000..2c9532f --- /dev/null +++ b/bindings/src/error.rs @@ -0,0 +1,16 @@ +pub use codecov_rs::error::CodecovError as RsCodecovError; +use pyo3::{exceptions::PyRuntimeError, prelude::*}; + +pub struct PyCodecovError(RsCodecovError); + +impl From for PyErr { + fn from(error: PyCodecovError) -> Self { + PyRuntimeError::new_err(error.0.to_string()) + } +} + +impl From for PyCodecovError { + fn from(other: RsCodecovError) -> Self { + Self(other) + } +} diff --git a/bindings/src/lib.rs b/bindings/src/lib.rs index 696a20b..6c8e4e4 100644 --- a/bindings/src/lib.rs +++ b/bindings/src/lib.rs @@ -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 { + let mut report_builder = + report::SqliteReportBuilder::open(out_path.into()).map_err(PyCodecovError::from)?; -#[pyfunction] -fn dummy_add(a: usize, b: usize) -> PyResult { - 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) -> PyResult<()> { - m.add_function(wrap_pyfunction!(dummy_add, m)?)?; + m.add_class::()?; Ok(()) } diff --git a/core/examples/parse_pyreport.rs b/core/examples/parse_pyreport.rs index 10b5d19..42faac0 100644 --- a/core/examples/parse_pyreport.rs +++ b/core/examples/parse_pyreport.rs @@ -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:"); @@ -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(()) } diff --git a/core/examples/sql_to_pyreport.rs b/core/examples/sql_to_pyreport.rs index 4f373e3..3f57c10 100644 --- a/core/examples/sql_to_pyreport.rs +++ b/core/examples/sql_to_pyreport.rs @@ -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])?; diff --git a/core/src/parsers/pyreport/mod.rs b/core/src/parsers/pyreport/mod.rs index ec03538..4a4b1f2 100644 --- a/core/src/parsers/pyreport/mod.rs +++ b/core/src/parsers/pyreport/mod.rs @@ -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; @@ -38,9 +38,8 @@ mod utils; pub fn parse_pyreport( report_json_file: &File, chunks_file: &File, - out_path: PathBuf, -) -> Result { - 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 @@ -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(()) } diff --git a/core/src/report/pyreport/chunks.rs b/core/src/report/pyreport/chunks.rs index 5c86708..1d45a1e 100644 --- a/core/src/report/pyreport/chunks.rs +++ b/core/src/report/pyreport/chunks.rs @@ -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)] = &[ ( @@ -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)] = &[ ( @@ -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 = &[ ( @@ -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!({}),); } diff --git a/core/src/report/pyreport/report_json.rs b/core/src/report/pyreport/report_json.rs index b6df657..6fd882c 100644 --- a/core/src/report/pyreport/report_json.rs +++ b/core/src/report/pyreport/report_json.rs @@ -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(); diff --git a/core/src/report/sqlite/models.rs b/core/src/report/sqlite/models.rs index c2e4492..70fa3b5 100644 --- a/core/src/report/sqlite/models.rs +++ b/core/src/report/sqlite/models.rs @@ -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 @@ -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()) @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/core/src/report/sqlite/report.rs b/core/src/report/sqlite/report.rs index 84e8f93..c39bd96 100644 --- a/core/src/report/sqlite/report.rs +++ b/core/src/report/sqlite/report.rs @@ -20,7 +20,7 @@ impl fmt::Debug for SqliteReport { } impl SqliteReport { - pub fn new(filename: PathBuf) -> Result { + pub fn open(filename: PathBuf) -> Result { let conn = open_database(&filename)?; Ok(SqliteReport { filename, conn }) } @@ -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())) @@ -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") @@ -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(); @@ -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(); diff --git a/core/src/report/sqlite/report_builder.rs b/core/src/report/sqlite/report_builder.rs index 29728b7..40eee4e 100644 --- a/core/src/report/sqlite/report_builder.rs +++ b/core/src/report/sqlite/report_builder.rs @@ -50,7 +50,7 @@ pub struct SqliteReportBuilder { } impl SqliteReportBuilder { - pub fn new(filename: PathBuf) -> Result { + pub fn open(filename: PathBuf) -> Result { let conn = open_database(&filename)?; Ok(SqliteReportBuilder { filename, @@ -155,7 +155,7 @@ impl ReportBuilder for SqliteReportBuilder { /// # let temp_dir = tempdir().unwrap(); /// # let db_file = temp_dir.path().join("test.db"); /// - /// let mut report_builder = SqliteReportBuilder::new(db_file).unwrap(); + /// let mut report_builder = SqliteReportBuilder::open(db_file).unwrap(); /// /// let mut tx = report_builder.transaction().unwrap(); /// let _ = tx.insert_file("foo.rs"); @@ -173,7 +173,7 @@ impl ReportBuilder for SqliteReportBuilder { /// # let temp_dir = tempdir().unwrap(); /// # let db_file = temp_dir.path().join("test.db"); /// - /// let mut report_builder = SqliteReportBuilder::new(db_file).unwrap(); + /// let mut report_builder = SqliteReportBuilder::open(db_file).unwrap(); /// /// // `tx` will go out of scope at the end of this block /// { @@ -194,7 +194,7 @@ impl ReportBuilder for SqliteReportBuilder { /// # let temp_dir = tempdir().unwrap(); /// # let db_file = temp_dir.path().join("test.db"); /// - /// let mut report_builder = SqliteReportBuilder::new(db_file).unwrap(); + /// let mut report_builder = SqliteReportBuilder::open(db_file).unwrap(); /// /// let mut tx = report_builder.transaction().unwrap(); /// let _ = tx.insert_file("foo.rs"); @@ -348,12 +348,12 @@ mod tests { } #[test] - fn test_new_report_builder_runs_migrations() { + fn test_open_report_builder_runs_migrations() { let ctx = setup(); let db_file = ctx.temp_dir.path().join("db.sqlite"); assert!(!db_file.exists()); - let report_builder = SqliteReportBuilder::new(db_file).unwrap(); + let report_builder = SqliteReportBuilder::open(db_file).unwrap(); assert_eq!( super::super::MIGRATIONS.current_version(&report_builder.conn), Ok(SchemaVersion::Inside(NonZeroUsize::new(1).unwrap())) @@ -364,7 +364,7 @@ mod tests { fn test_insert_file() { 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 expected_file = models::SourceFile::new("src/report.rs"); let actual_file = report_builder.insert_file(&expected_file.path).unwrap(); @@ -381,7 +381,7 @@ mod tests { fn test_insert_context() { 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 expected_context = models::Context::new("foo"); let actual_context = report_builder.insert_context("foo").unwrap(); @@ -398,7 +398,7 @@ mod tests { fn test_insert_coverage_sample() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -443,7 +443,7 @@ mod tests { fn test_multi_insert_coverage_sample() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -505,7 +505,7 @@ mod tests { fn test_insert_branches_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -561,7 +561,7 @@ mod tests { fn test_multi_insert_branches_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -636,7 +636,7 @@ mod tests { fn test_insert_method_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); @@ -696,7 +696,7 @@ mod tests { fn test_multi_insert_method_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -764,7 +764,7 @@ mod tests { fn test_insert_span_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -816,7 +816,7 @@ mod tests { fn test_multi_insert_span_data() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -891,7 +891,7 @@ mod tests { fn test_insert_context_assoc() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); @@ -954,7 +954,7 @@ mod tests { fn test_multi_associate_context() { 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 file = report_builder.insert_file("src/report.rs").unwrap(); let raw_upload = report_builder @@ -998,7 +998,7 @@ mod tests { fn test_insert_raw_upload() { 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 inserted_upload = models::RawUpload { timestamp: Some(123), @@ -1026,7 +1026,7 @@ mod tests { fn test_transaction_drop_behavior() { 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 tx = report_builder.transaction().unwrap(); assert_eq!(tx.conn.drop_behavior(), rusqlite::DropBehavior::Commit); @@ -1036,7 +1036,7 @@ mod tests { fn test_transaction_cannot_build() { 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 tx = report_builder.transaction().unwrap(); @@ -1050,7 +1050,7 @@ mod tests { fn test_transaction_rollback() { 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 mut tx = report_builder.transaction().unwrap(); tx.insert_file("foo.rs").unwrap(); diff --git a/core/src/test_utils/sqlite_report.rs b/core/src/test_utils/sqlite_report.rs index 63491ba..0040a53 100644 --- a/core/src/test_utils/sqlite_report.rs +++ b/core/src/test_utils/sqlite_report.rs @@ -8,7 +8,7 @@ use crate::{ }; pub fn build_sample_report(path: PathBuf) -> Result { - let mut builder = SqliteReportBuilder::new(path)?; + let mut builder = SqliteReportBuilder::open(path)?; let file_1 = builder.insert_file("src/report/report.rs")?; let file_2 = builder.insert_file("src/report/models.rs")?; diff --git a/core/tests/test_pyreport_shim.rs b/core/tests/test_pyreport_shim.rs index 364d690..5412b38 100644 --- a/core/tests/test_pyreport_shim.rs +++ b/core/tests/test_pyreport_shim.rs @@ -35,7 +35,7 @@ fn test_parse_report_json() { let input = read_fixture(Pyreport, Small, "codecov-rs-reports-json-d2a9ba1.txt").unwrap(); let test_ctx = setup(); - let mut report_builder = SqliteReportBuilder::new(test_ctx.db_file).unwrap(); + let mut report_builder = SqliteReportBuilder::open(test_ctx.db_file).unwrap(); let ParsedReportJson { files: file_id_map, @@ -95,7 +95,7 @@ fn test_parse_chunks_file() { let input = std::str::from_utf8(&input).unwrap(); let test_ctx = setup(); - let mut report_builder = SqliteReportBuilder::new(test_ctx.db_file).unwrap(); + let mut report_builder = SqliteReportBuilder::open(test_ctx.db_file).unwrap(); // Pretend `parse_report_json` has already run let mut report_json_files = HashMap::new(); @@ -208,8 +208,10 @@ fn test_parse_pyreport() { let chunks_file = open_fixture(Pyreport, Small, "codecov-rs-chunks-d2a9ba1.txt").unwrap(); let test_ctx = setup(); - let report = pyreport::parse_pyreport(&report_json_file, &chunks_file, test_ctx.db_file) + let mut report_builder = SqliteReportBuilder::open(test_ctx.db_file).unwrap(); + pyreport::parse_pyreport(&report_json_file, &chunks_file, &mut report_builder) .expect("Failed to parse pyreport"); + let report = report_builder.build().unwrap(); let expected_files = [ models::SourceFile::new("src/report.rs"), @@ -308,12 +310,14 @@ fn test_sql_to_pyreport_to_sql_totals_match() { let chunks_input_file = open_fixture(Pyreport, Small, "codecov-rs-chunks-d2a9ba1.txt").unwrap(); let test_ctx = setup(); - let report = pyreport::parse_pyreport( + let mut report_builder = SqliteReportBuilder::open(test_ctx.db_file).unwrap(); + pyreport::parse_pyreport( &report_json_input_file, &chunks_input_file, - test_ctx.db_file, + &mut report_builder, ) .expect("Failed to parse pyreport"); + let report = report_builder.build().unwrap(); let report_json_output_path = test_ctx.temp_dir.path().join("report_json.json"); let chunks_output_path = test_ctx.temp_dir.path().join("chunks.txt"); @@ -342,12 +346,14 @@ fn test_sql_to_pyreport_to_sql_totals_match() { chunks_output_file.rewind().unwrap(); let roundtrip_db_path = test_ctx.temp_dir.path().join("roundtrip.sqlite"); - let report = pyreport::parse_pyreport( + let mut report_builder = SqliteReportBuilder::open(roundtrip_db_path).unwrap(); + pyreport::parse_pyreport( &report_json_output_file, &chunks_output_file, - roundtrip_db_path, + &mut report_builder, ) .expect("Failed to parse roundtrip report"); + let report = report_builder.build().unwrap(); let roundtrip_totals = report.totals().unwrap(); assert_eq!(original_totals, roundtrip_totals); diff --git a/python/codecov_rs/dummy_add.py b/python/codecov_rs/dummy_add.py deleted file mode 100644 index 6801173..0000000 --- a/python/codecov_rs/dummy_add.py +++ /dev/null @@ -1,3 +0,0 @@ -from ._bindings import dummy_add - -dummy_add.__module__ = __name__ diff --git a/python/codecov_rs/dummy_add.pyi b/python/codecov_rs/dummy_add.pyi deleted file mode 100644 index 8d003c5..0000000 --- a/python/codecov_rs/dummy_add.pyi +++ /dev/null @@ -1,3 +0,0 @@ -from pydantic.types import NonNegativeInt - -def dummy_add(a: NonNegativeInt, b: NonNegativeInt) -> NonNegativeInt: ... diff --git a/python/codecov_rs/report.py b/python/codecov_rs/report.py new file mode 100644 index 0000000..35d9089 --- /dev/null +++ b/python/codecov_rs/report.py @@ -0,0 +1,3 @@ +from ._bindings import SqliteReportBuilder + +SqliteReportBuilder.__module__ = __name__ diff --git a/python/codecov_rs/report.pyi b/python/codecov_rs/report.pyi new file mode 100644 index 0000000..2c6aecf --- /dev/null +++ b/python/codecov_rs/report.pyi @@ -0,0 +1,6 @@ +class SqliteReportBuilder: + @staticmethod + def from_pyreport( + report_json_filepath: str, chunks_filepath: str, out_filepath: str + ) -> SqliteReportBuilder: ... + def filepath(self) -> str: ... diff --git a/python/tests/test_lib.py b/python/tests/test_lib.py index ec3a03f..4e53097 100644 --- a/python/tests/test_lib.py +++ b/python/tests/test_lib.py @@ -1,4 +1,26 @@ -def test_dummy_add(): - from codecov_rs.dummy_add import dummy_add +from pathlib import Path +from tempfile import NamedTemporaryFile - assert dummy_add(3, 4) == 7 +from codecov_rs.report import SqliteReportBuilder + +PROJECT_ROOT = Path(__file__).parent.parent.parent + + +def get_fixture_path(path_from_root: str) -> str: + return str(PROJECT_ROOT / path_from_root) + + +def test_from_pyreport(): + report_json_filepath = get_fixture_path( + "test_utils/fixtures/pyreport/codecov-rs-reports-json-d2a9ba1.txt" + ) + chunks_filepath = get_fixture_path( + "test_utils/fixtures/pyreport/codecov-rs-chunks-d2a9ba1.txt" + ) + + with NamedTemporaryFile() as out_file: + report_builder = SqliteReportBuilder.from_pyreport( + report_json_filepath, chunks_filepath, out_file.name + ) + print(report_builder.filepath()) + assert report_builder.filepath() is not None