mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 15:13:47 +00:00
cli: Add --config arg to report generate
This commit is contained in:
parent
6c7160ab7e
commit
39b1b49985
@ -1,7 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
io::stdout,
|
io::stdout,
|
||||||
mem,
|
mem,
|
||||||
str::FromStr,
|
|
||||||
sync::{
|
sync::{
|
||||||
Arc,
|
Arc,
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
@ -29,10 +28,7 @@ use objdiff_core::{
|
|||||||
ProjectConfig, ProjectObject, ProjectObjectMetadata, build_globset,
|
ProjectConfig, ProjectObject, ProjectObjectMetadata, build_globset,
|
||||||
path::{check_path_buf, platform_path, platform_path_serde_option},
|
path::{check_path_buf, platform_path, platform_path_serde_option},
|
||||||
},
|
},
|
||||||
diff::{
|
diff::{self, DiffObjConfig, MappingConfig, ObjectDiff},
|
||||||
self, ConfigEnum, ConfigPropertyId, ConfigPropertyKind, DiffObjConfig, MappingConfig,
|
|
||||||
ObjectDiff,
|
|
||||||
},
|
|
||||||
jobs::{
|
jobs::{
|
||||||
Job, JobQueue, JobResult,
|
Job, JobQueue, JobResult,
|
||||||
objdiff::{ObjDiffConfig, start_build},
|
objdiff::{ObjDiffConfig, start_build},
|
||||||
@ -43,6 +39,7 @@ use ratatui::prelude::*;
|
|||||||
use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
|
use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
cmd::apply_config_args,
|
||||||
util::{
|
util::{
|
||||||
output::{OutputFormat, write_output},
|
output::{OutputFormat, write_output},
|
||||||
term::crossterm_panic_handler,
|
term::crossterm_panic_handler,
|
||||||
@ -183,28 +180,7 @@ pub fn run(args: Args) -> Result<()> {
|
|||||||
|
|
||||||
fn build_config_from_args(args: &Args) -> Result<(DiffObjConfig, MappingConfig)> {
|
fn build_config_from_args(args: &Args) -> Result<(DiffObjConfig, MappingConfig)> {
|
||||||
let mut diff_config = DiffObjConfig::default();
|
let mut diff_config = DiffObjConfig::default();
|
||||||
for config in &args.config {
|
apply_config_args(&mut diff_config, &args.config)?;
|
||||||
let (key, value) = config.split_once('=').context("--config expects \"key=value\"")?;
|
|
||||||
let property_id = ConfigPropertyId::from_str(key)
|
|
||||||
.map_err(|()| anyhow!("Invalid configuration property: {}", key))?;
|
|
||||||
diff_config.set_property_value_str(property_id, value).map_err(|()| {
|
|
||||||
let mut options = String::new();
|
|
||||||
match property_id.kind() {
|
|
||||||
ConfigPropertyKind::Boolean => {
|
|
||||||
options = "true, false".to_string();
|
|
||||||
}
|
|
||||||
ConfigPropertyKind::Choice(variants) => {
|
|
||||||
for (i, variant) in variants.iter().enumerate() {
|
|
||||||
if i > 0 {
|
|
||||||
options.push_str(", ");
|
|
||||||
}
|
|
||||||
options.push_str(variant.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
anyhow!("Invalid value for {}. Expected one of: {}", property_id.name(), options)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
let mut mapping_config = MappingConfig {
|
let mut mapping_config = MappingConfig {
|
||||||
mappings: Default::default(),
|
mappings: Default::default(),
|
||||||
selecting_left: args.selecting_left.clone(),
|
selecting_left: args.selecting_left.clone(),
|
||||||
|
@ -1,2 +1,33 @@
|
|||||||
pub mod diff;
|
pub mod diff;
|
||||||
pub mod report;
|
pub mod report;
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use anyhow::{Context, Result, anyhow};
|
||||||
|
use objdiff_core::diff::{ConfigEnum, ConfigPropertyId, ConfigPropertyKind, DiffObjConfig};
|
||||||
|
|
||||||
|
pub fn apply_config_args(diff_config: &mut DiffObjConfig, args: &[String]) -> Result<()> {
|
||||||
|
for config in args {
|
||||||
|
let (key, value) = config.split_once('=').context("--config expects \"key=value\"")?;
|
||||||
|
let property_id = ConfigPropertyId::from_str(key)
|
||||||
|
.map_err(|()| anyhow!("Invalid configuration property: {}", key))?;
|
||||||
|
diff_config.set_property_value_str(property_id, value).map_err(|()| {
|
||||||
|
let mut options = String::new();
|
||||||
|
match property_id.kind() {
|
||||||
|
ConfigPropertyKind::Boolean => {
|
||||||
|
options = "true, false".to_string();
|
||||||
|
}
|
||||||
|
ConfigPropertyKind::Choice(variants) => {
|
||||||
|
for (i, variant) in variants.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
options.push_str(", ");
|
||||||
|
}
|
||||||
|
options.push_str(variant.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anyhow!("Invalid value for {}. Expected one of: {}", property_id.name(), options)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@ -17,7 +17,7 @@ use tracing::{info, warn};
|
|||||||
use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
|
use typed_path::{Utf8PlatformPath, Utf8PlatformPathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cmd::diff::ObjectConfig,
|
cmd::{apply_config_args, diff::ObjectConfig},
|
||||||
util::output::{OutputFormat, write_output},
|
util::output::{OutputFormat, write_output},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,6 +52,9 @@ pub struct GenerateArgs {
|
|||||||
#[argp(option, short = 'f')]
|
#[argp(option, short = 'f')]
|
||||||
/// Output format (json, json-pretty, proto) (default: json)
|
/// Output format (json, json-pretty, proto) (default: json)
|
||||||
format: Option<String>,
|
format: Option<String>,
|
||||||
|
#[argp(option, short = 'c')]
|
||||||
|
/// Configuration property (key=value)
|
||||||
|
config: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
@ -80,6 +83,12 @@ pub fn run(args: Args) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate(args: GenerateArgs) -> Result<()> {
|
fn generate(args: GenerateArgs) -> Result<()> {
|
||||||
|
let mut diff_config = diff::DiffObjConfig {
|
||||||
|
function_reloc_diffs: diff::FunctionRelocDiffs::None,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
apply_config_args(&mut diff_config, &args.config)?;
|
||||||
|
|
||||||
let output_format = OutputFormat::from_option(args.format.as_deref())?;
|
let output_format = OutputFormat::from_option(args.format.as_deref())?;
|
||||||
let project_dir = args.project.as_deref().unwrap_or_else(|| Utf8PlatformPath::new("."));
|
let project_dir = args.project.as_deref().unwrap_or_else(|| Utf8PlatformPath::new("."));
|
||||||
info!("Loading project {}", project_dir);
|
info!("Loading project {}", project_dir);
|
||||||
@ -114,14 +123,15 @@ fn generate(args: GenerateArgs) -> Result<()> {
|
|||||||
if args.deduplicate {
|
if args.deduplicate {
|
||||||
// If deduplicating, we need to run single-threaded
|
// If deduplicating, we need to run single-threaded
|
||||||
for object in &objects {
|
for object in &objects {
|
||||||
if let Some(unit) = report_object(object, Some(&mut existing_functions))? {
|
if let Some(unit) = report_object(object, &diff_config, Some(&mut existing_functions))?
|
||||||
|
{
|
||||||
units.push(unit);
|
units.push(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let vec = objects
|
let vec = objects
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|object| report_object(object, None))
|
.map(|object| report_object(object, &diff_config, None))
|
||||||
.collect::<Result<Vec<Option<ReportUnit>>>>()?;
|
.collect::<Result<Vec<Option<ReportUnit>>>>()?;
|
||||||
units = vec.into_iter().flatten().collect();
|
units = vec.into_iter().flatten().collect();
|
||||||
}
|
}
|
||||||
@ -145,6 +155,7 @@ fn generate(args: GenerateArgs) -> Result<()> {
|
|||||||
|
|
||||||
fn report_object(
|
fn report_object(
|
||||||
object: &ObjectConfig,
|
object: &ObjectConfig,
|
||||||
|
diff_config: &diff::DiffObjConfig,
|
||||||
mut existing_functions: Option<&mut HashSet<String>>,
|
mut existing_functions: Option<&mut HashSet<String>>,
|
||||||
) -> Result<Option<ReportUnit>> {
|
) -> Result<Option<ReportUnit>> {
|
||||||
match (&object.target_path, &object.base_path) {
|
match (&object.target_path, &object.base_path) {
|
||||||
@ -158,16 +169,12 @@ fn report_object(
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let diff_config = diff::DiffObjConfig {
|
|
||||||
function_reloc_diffs: diff::FunctionRelocDiffs::None,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
let mapping_config = diff::MappingConfig::default();
|
let mapping_config = diff::MappingConfig::default();
|
||||||
let target = object
|
let target = object
|
||||||
.target_path
|
.target_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
obj::read::read(p.as_ref(), &diff_config)
|
obj::read::read(p.as_ref(), diff_config)
|
||||||
.with_context(|| format!("Failed to open {}", p))
|
.with_context(|| format!("Failed to open {}", p))
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
@ -175,12 +182,12 @@ fn report_object(
|
|||||||
.base_path
|
.base_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
obj::read::read(p.as_ref(), &diff_config)
|
obj::read::read(p.as_ref(), diff_config)
|
||||||
.with_context(|| format!("Failed to open {}", p))
|
.with_context(|| format!("Failed to open {}", p))
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let result =
|
let result =
|
||||||
diff::diff_objs(target.as_ref(), base.as_ref(), None, &diff_config, &mapping_config)?;
|
diff::diff_objs(target.as_ref(), base.as_ref(), None, diff_config, &mapping_config)?;
|
||||||
|
|
||||||
let metadata = ReportUnitMetadata {
|
let metadata = ReportUnitMetadata {
|
||||||
complete: object.metadata.complete,
|
complete: object.metadata.complete,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user