Skip to content
Open
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
14 changes: 14 additions & 0 deletions examples/simple-analyze/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "simple-analyze"
version = "0.1.0"
edition = "2021"
publish = false

[[bin]]
name = "simple-analyze"
path = "main.rs"

[dependencies]
dx-scope = { path = "../.." }
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"
53 changes: 53 additions & 0 deletions examples/simple-analyze/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Simple Analyze Example

This example demonstrates how to use dx-scope's analyze functionality programmatically.

## Running

```bash
cd examples/simple-analyze
cargo run
```

## Features Demonstrated

- Loading scope configuration with known errors
- Analyzing text strings directly
- Analyzing lines from a vector
- Analyzing files
- Using different interaction modes (AutoApprove, DenyAll)

## Key Concepts

### AnalyzeInput

Specify where input comes from:

- `AnalyzeInput::from_lines(vec)` - Analyze in-memory lines
- `AnalyzeInput::from_file(path)` - Analyze a file
- `AnalyzeInput::Stdin` - Analyze from stdin

### AnalyzeOptions

Configure the analysis:

- `known_errors`: Map of known error patterns to detect
- `working_dir`: Directory to run fix commands in

### UserInteraction

Control how fixes are handled:

- `AutoApprove` - Automatically apply all fixes (good for CI)
- `DenyAll` - Never apply fixes (good for dry-run)
- `InquireInteraction` - Interactive prompts (CLI only)

### AnalyzeStatus

The result indicates what happened:

- `NoKnownErrorsFound` - Clean scan
- `KnownErrorFoundNoFixFound` - Error detected but no automatic fix
- `KnownErrorFoundUserDenied` - User declined the fix
- `KnownErrorFoundFixFailed` - Fix was attempted but failed
- `KnownErrorFoundFixSucceeded` - Error detected and fix applied successfully
86 changes: 86 additions & 0 deletions examples/simple-analyze/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//! Simple example of using dx-scope's analyze functionality as a library.
//!
//! This example demonstrates how to programmatically analyze text for
//! known errors without using the CLI.

use dx_scope::analyze;
use dx_scope::{AnalyzeInput, AnalyzeOptions, AnalyzeStatus, AutoApprove, DenyAll};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
// For this example, we'll use an empty config
// In a real application, you'd load config from your project
let working_dir = std::env::current_dir()?;
let config = dx_scope::FoundConfig::empty(working_dir);

println!("Found {} known errors", config.known_error.len());
println!();

// Create options for analysis
let options = AnalyzeOptions::new(config.known_error.clone(), config.working_dir.clone());

// Example 1: Analyze a string directly
println!("=== Example 1: Analyzing text with known error ===");
let log_text = r#"
Building project...
Compiling dependencies...
error: disk is full
Build failed!
"#;

let status = analyze::process_text(&options, log_text, &AutoApprove).await?;
print_status("Direct text analysis", status);
println!();

// Example 2: Analyze lines from a vector (auto-approve fixes)
println!("=== Example 2: Analyzing lines with auto-approve ===");
let lines = vec![
"Starting deployment...".to_string(),
"Connecting to server...".to_string(),
"error: connection timeout".to_string(),
"Deployment failed".to_string(),
];

let input = AnalyzeInput::from_lines(lines);
let status = analyze::process_input(&options, input, &AutoApprove).await?;
print_status("Lines with auto-approve", status);
println!();

// Example 3: Analyze with DenyAll (dry-run mode)
println!("=== Example 3: Analyzing with DenyAll (no fixes) ===");
let input = AnalyzeInput::from_lines(vec!["error: disk is full".to_string()]);

let status = analyze::process_input(&options, input, &DenyAll).await?;
print_status("With DenyAll", status);
println!();

// Example 4: Analyze a file
println!("=== Example 4: Analyzing a file ===");
// Create a temporary log file
let log_content = "Building...\nerror: something went wrong\nDone.\n";
tokio::fs::write("/tmp/test.log", log_content).await?;

let input = AnalyzeInput::from_file("/tmp/test.log");
let status = analyze::process_input(&options, input, &DenyAll).await?;
print_status("File analysis", status);

// Clean up
tokio::fs::remove_file("/tmp/test.log").await?;

Ok(())
}

fn print_status(label: &str, status: AnalyzeStatus) {
println!("{}: {:?}", label, status);
println!(" Exit code: {}", status.to_exit_code());

let message = match status {
AnalyzeStatus::NoKnownErrorsFound => "✓ No known errors detected",
AnalyzeStatus::KnownErrorFoundNoFixFound => "⚠ Error found, but no fix available",
AnalyzeStatus::KnownErrorFoundUserDenied => "⊘ Fix available but user declined",
AnalyzeStatus::KnownErrorFoundFixFailed => "✗ Fix attempted but failed",
AnalyzeStatus::KnownErrorFoundFixSucceeded => "✓ Error found and fixed!",
};

println!(" {}", message);
}
14 changes: 14 additions & 0 deletions examples/simple-doctor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "simple-doctor"
version = "0.1.0"
edition = "2021"
publish = false

[[bin]]
name = "simple-doctor"
path = "main.rs"

[dependencies]
dx-scope = { path = "../.." }
tokio = { version = "1", features = ["full"] }
anyhow = "1.0"
37 changes: 37 additions & 0 deletions examples/simple-doctor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Simple Doctor Example

This example demonstrates how to use dx-scope's doctor functionality programmatically.

## Running

```bash
cd examples/simple-doctor
cargo run
```

## Features Demonstrated

- Loading scope configuration
- Running health checks in CI mode (without fixes)
- Running specific groups with auto-fix enabled
- Listing available checks

## Key Concepts

### DoctorRunOptions

Configure how doctor checks run:

- `DoctorRunOptions::ci_mode()` - Run checks without applying fixes
- `DoctorRunOptions::with_fixes()` - Run checks and auto-apply fixes
- `DoctorRunOptions::for_groups(vec)` - Run only specific groups

### PathRunResult

The result contains:

- `did_succeed`: Overall success/failure
- `succeeded_groups`: Set of group names that passed
- `failed_group`: Set of group names that failed
- `skipped_group`: Set of group names that were skipped
- `group_reports`: Detailed reports for each group
59 changes: 59 additions & 0 deletions examples/simple-doctor/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! Simple example of using dx-scope's doctor functionality as a library.
//!
//! This example demonstrates how to programmatically run health checks
//! without using the CLI.

use dx_scope::DoctorRunOptions;
use dx_scope::doctor;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Load configuration from the current directory
println!("Loading scope configuration...");

// Note: For library usage, you can either:
// 1. Create an empty config and populate it programmatically
// 2. Load from disk using your own config loading logic
let working_dir = std::env::current_dir()?;
let config = dx_scope::FoundConfig::empty(working_dir);

println!("Found {} doctor groups", config.doctor_group.len());
println!();

// Option 1: Run all checks without fixes (CI mode)
println!("=== Running checks in CI mode (no fixes) ===");
let ci_options = DoctorRunOptions::ci_mode();
let result = doctor::run(&config, ci_options).await?;

println!("✓ Succeeded: {}", result.succeeded_groups.len());
println!("✗ Failed: {}", result.failed_group.len());
println!("⊘ Skipped: {}", result.skipped_group.len());
println!("Overall success: {}", result.did_succeed);
println!();

// Option 2: Run specific groups with auto-fix enabled
println!("=== Running specific groups with auto-fix ===");
let targeted_options = DoctorRunOptions::for_groups(vec!["example-group".to_string()]);

match doctor::run(&config, targeted_options).await {
Ok(result) => {
println!("Targeted run completed:");
println!(" Succeeded: {:?}", result.succeeded_groups);
println!(" Failed: {:?}", result.failed_group);
}
Err(e) => {
println!("Run failed: {}", e);
}
}

println!();
println!("=== Listing available checks ===");
let groups = doctor::list(&config).await?;
for group in groups {
println!("Group: {}", group.metadata.name());
println!(" Description: {}", group.metadata.description());
println!(" Actions: {}", group.actions.len());
}

Ok(())
}