initial commit

This commit is contained in:
2026-05-25 17:05:15 +02:00
commit 6ebe505a07
25 changed files with 5929 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "ebookm-cli"
version = "0.1.0"
edition = "2024"
[dependencies]
clap = { version = "4.5", features = ["derive"] }
ebookm-core = { path = "../ebookm-core" }
miette = { version = "7.2", features = ["fancy"] }
serde_json = "1.0"
+89
View File
@@ -0,0 +1,89 @@
use std::path::PathBuf;
use clap::{Parser, Subcommand};
use ebookm_core::{
build_epub, inspect_source, load_manifest, render_init_manifest, validate_manifest,
};
use miette::{Context, IntoDiagnostic};
#[derive(Debug, Parser)]
#[command(
name = "ebookm",
version,
about = "Compile Substack articles into a single EPUB"
)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Subcommand)]
enum Commands {
Build {
#[arg(short, long)]
manifest: PathBuf,
#[arg(short, long)]
output: Option<PathBuf>,
},
Validate {
#[arg(short, long)]
manifest: PathBuf,
},
Inspect {
source: String,
#[arg(long, default_value = "json")]
format: String,
},
Init,
}
fn main() -> miette::Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Build { manifest, output } => {
let mut loaded = load_manifest(&manifest).into_diagnostic()?;
if let Some(output) = output {
loaded.output.path = output.display().to_string();
}
let warnings = validate_manifest(&loaded).into_diagnostic()?;
for warning in warnings {
eprintln!("warning: {warning}");
}
build_epub(&loaded, &manifest).into_diagnostic()?;
println!("{}", loaded.output.path);
}
Commands::Validate { manifest } => {
let loaded = load_manifest(&manifest).into_diagnostic()?;
let warnings = validate_manifest(&loaded).into_diagnostic()?;
for warning in warnings {
println!("warning: {warning}");
}
println!("manifest is valid");
}
Commands::Inspect { source, format } => {
let result = inspect_source(&source).into_diagnostic()?;
if format == "json" {
println!(
"{}",
serde_json::to_string_pretty(&result)
.into_diagnostic()
.wrap_err("failed to encode JSON")?
);
} else {
println!("title: {}", result.title.unwrap_or_default());
println!("author: {}", result.author.unwrap_or_default());
println!("published: {}", result.published.unwrap_or_default());
println!(
"canonical_url: {}",
result.canonical_url.unwrap_or_default()
);
}
}
Commands::Init => {
print!("{}", render_init_manifest());
}
}
Ok(())
}