Replace argh with clap
Mostly for the more concise Config parsing and error handling.
This commit is contained in:
parent
abd540d2ff
commit
7e06d23bba
145
Cargo.lock
generated
145
Cargo.lock
generated
@ -62,40 +62,61 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is-terminal",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.71"
|
version = "1.0.71"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e"
|
|
||||||
dependencies = [
|
|
||||||
"argh_derive",
|
|
||||||
"argh_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh_derive"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6"
|
|
||||||
dependencies = [
|
|
||||||
"argh_shared",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "argh_shared"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "article_scraper"
|
name = "article_scraper"
|
||||||
version = "2.0.0-alpha.0"
|
version = "2.0.0-alpha.0"
|
||||||
@ -314,6 +335,48 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9394150f5b4273a1763355bd1c2ec54cc5a2593f790587bcd6b2c947cfa9211"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a78fbdd3cc2914ddf37ba444114bc7765bbdcb55ec9cbe6fa054f0137400717"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"bitflags",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.15",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "codespan-reporting"
|
name = "codespan-reporting"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -330,6 +393,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
@ -361,11 +430,11 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi-to-html",
|
"ansi-to-html",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argh",
|
|
||||||
"article_scraper",
|
"article_scraper",
|
||||||
"axum",
|
"axum",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"clap",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"feed-rs",
|
"feed-rs",
|
||||||
"maud",
|
"maud",
|
||||||
@ -1218,6 +1287,18 @@ version = "2.7.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
|
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is-terminal"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi 0.3.1",
|
||||||
|
"io-lifetimes",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
@ -2766,6 +2847,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -3,6 +3,7 @@ name = "crawlnicle"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "crawlnicle"
|
default-run = "crawlnicle"
|
||||||
|
authors = ["Tyler Hallada <tyler@hallada.net>"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lib"
|
name = "lib"
|
||||||
@ -13,11 +14,11 @@ path = "src/lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ansi-to-html = "0.1"
|
ansi-to-html = "0.1"
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
argh = "0.1"
|
|
||||||
article_scraper = "2.0.0-alpha.0"
|
article_scraper = "2.0.0-alpha.0"
|
||||||
axum = "0.6"
|
axum = "0.6"
|
||||||
bytes = "1.4"
|
bytes = "1.4"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
clap = { version = "4.3", features = ["derive", "env"] }
|
||||||
dotenvy = "0.15"
|
dotenvy = "0.15"
|
||||||
feed-rs = "1.3"
|
feed-rs = "1.3"
|
||||||
maud = { version = "0.25", features = ["axum"] }
|
maud = { version = "0.25", features = ["axum"] }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use argh::FromArgs;
|
use clap::{Args, Parser, Subcommand};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
@ -12,82 +12,73 @@ use lib::models::feed::{create_feed, delete_feed, CreateFeed, FeedType};
|
|||||||
use lib::models::entry::{create_entry, delete_entry, CreateEntry};
|
use lib::models::entry::{create_entry, delete_entry, CreateEntry};
|
||||||
use lib::uuid::Base62Uuid;
|
use lib::uuid::Base62Uuid;
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
|
||||||
/// CLI for crawlnicle
|
/// CLI for crawlnicle
|
||||||
struct Args {
|
#[derive(Parser)]
|
||||||
#[argh(subcommand)]
|
#[command(author, version, about, long_about = None)]
|
||||||
|
#[command(propagate_version = true)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
commands: Commands,
|
commands: Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(Subcommand)]
|
||||||
#[argh(subcommand)]
|
|
||||||
enum Commands {
|
enum Commands {
|
||||||
|
/// Fetches new entries from all feeds in the database
|
||||||
|
Crawl,
|
||||||
AddFeed(AddFeed),
|
AddFeed(AddFeed),
|
||||||
DeleteFeed(DeleteFeed),
|
DeleteFeed(DeleteFeed),
|
||||||
AddEntry(AddEntry),
|
AddEntry(AddEntry),
|
||||||
DeleteEntry(DeleteEntry),
|
DeleteEntry(DeleteEntry),
|
||||||
Crawl(Crawl),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
|
||||||
/// Add a feed to the database
|
/// Add a feed to the database
|
||||||
#[argh(subcommand, name = "add-feed")]
|
#[derive(Args)]
|
||||||
struct AddFeed {
|
struct AddFeed {
|
||||||
#[argh(option)]
|
|
||||||
/// title of the feed (max 255 characters)
|
/// title of the feed (max 255 characters)
|
||||||
|
#[arg(short, long)]
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
#[argh(option)]
|
|
||||||
/// URL of the feed (max 2048 characters)
|
/// URL of the feed (max 2048 characters)
|
||||||
|
#[arg(short, long)]
|
||||||
url: String,
|
url: String,
|
||||||
#[argh(option, long = "type")]
|
|
||||||
/// type of the feed ('rss' or 'atom')
|
/// type of the feed ('rss' or 'atom')
|
||||||
|
#[arg(short, long)]
|
||||||
feed_type: FeedType,
|
feed_type: FeedType,
|
||||||
#[argh(option)]
|
|
||||||
/// description of the feed
|
/// description of the feed
|
||||||
|
#[arg(short, long)]
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(Args)]
|
||||||
/// Delete a feed from the database
|
/// Delete a feed from the database
|
||||||
#[argh(subcommand, name = "delete-feed")]
|
|
||||||
struct DeleteFeed {
|
struct DeleteFeed {
|
||||||
#[argh(positional)]
|
|
||||||
/// id of the feed to delete
|
/// id of the feed to delete
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(Args)]
|
||||||
/// Add an entry to the database
|
/// Add an entry to the database
|
||||||
#[argh(subcommand, name = "add-entry")]
|
|
||||||
struct AddEntry {
|
struct AddEntry {
|
||||||
#[argh(option)]
|
|
||||||
/// title of the entry (max 255 characters)
|
/// title of the entry (max 255 characters)
|
||||||
|
#[arg(short, long)]
|
||||||
title: Option<String>,
|
title: Option<String>,
|
||||||
#[argh(option)]
|
|
||||||
/// URL of the entry (max 2048 characters)
|
/// URL of the entry (max 2048 characters)
|
||||||
|
#[arg(short, long)]
|
||||||
url: String,
|
url: String,
|
||||||
#[argh(option)]
|
|
||||||
/// description of the entry
|
/// description of the entry
|
||||||
|
#[arg(short, long)]
|
||||||
description: Option<String>,
|
description: Option<String>,
|
||||||
#[argh(option)]
|
|
||||||
/// source feed for the entry
|
/// source feed for the entry
|
||||||
|
#[arg(short, long)]
|
||||||
feed_id: Uuid,
|
feed_id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(Args)]
|
||||||
/// Delete an entry from the database
|
/// Delete an entry from the database
|
||||||
#[argh(subcommand, name = "delete-entry")]
|
|
||||||
struct DeleteEntry {
|
struct DeleteEntry {
|
||||||
#[argh(positional)]
|
|
||||||
/// id of the entry to delete
|
/// id of the entry to delete
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
|
||||||
/// Delete an entry from the database
|
|
||||||
#[argh(subcommand, name = "crawl")]
|
|
||||||
struct Crawl {}
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn main() -> Result<()> {
|
pub async fn main() -> Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
@ -99,9 +90,9 @@ pub async fn main() -> Result<()> {
|
|||||||
.connect(&env::var("DATABASE_URL")?)
|
.connect(&env::var("DATABASE_URL")?)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let args: Args = argh::from_env();
|
let cli: Cli = Cli::parse();
|
||||||
|
|
||||||
match args.commands {
|
match cli.commands {
|
||||||
Commands::AddFeed(args) => {
|
Commands::AddFeed(args) => {
|
||||||
let feed = create_feed(
|
let feed = create_feed(
|
||||||
&pool,
|
&pool,
|
||||||
@ -138,7 +129,7 @@ pub async fn main() -> Result<()> {
|
|||||||
delete_entry(&pool, args.id).await?;
|
delete_entry(&pool, args.id).await?;
|
||||||
info!("Deleted entry with id {}", Base62Uuid::from(args.id));
|
info!("Deleted entry with id {}", Base62Uuid::from(args.id));
|
||||||
}
|
}
|
||||||
Commands::Crawl(_) => {
|
Commands::Crawl => {
|
||||||
info!("Crawling...");
|
info!("Crawling...");
|
||||||
crawl(&pool).await?;
|
crawl(&pool).await?;
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,17 @@
|
|||||||
use anyhow::{Context, Result};
|
use clap::Parser;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Parser, Clone, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
|
#[clap(long, env)]
|
||||||
pub database_url: String,
|
pub database_url: String,
|
||||||
|
#[clap(long, env)]
|
||||||
pub database_max_connections: u32,
|
pub database_max_connections: u32,
|
||||||
|
#[clap(long, env)]
|
||||||
pub host: String,
|
pub host: String,
|
||||||
|
#[clap(long, env)]
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
#[clap(long, env)]
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
#[clap(long, env)]
|
||||||
pub max_mem_log_size: usize,
|
pub max_mem_log_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
|
||||||
pub fn new() -> Result<Config> {
|
|
||||||
let database_url = std::env::var("DATABASE_URL").context("DATABASE_URL not set")?;
|
|
||||||
let database_max_connections = std::env::var("DATABASE_MAX_CONNECTIONS").context("DATABASE_MAX_CONNECTIONS not set")?.parse()?;
|
|
||||||
let host = std::env::var("HOST").context("HOST not set")?;
|
|
||||||
let port = std::env::var("PORT").context("PORT not set")?.parse()?;
|
|
||||||
let title = std::env::var("TITLE").context("TITLE not set")?;
|
|
||||||
let max_mem_log_size = std::env::var("MAX_MEM_LOG_SIZE").context("MAX_MEM_LOG_SIZE not set")?.parse()?;
|
|
||||||
|
|
||||||
Ok(Config {
|
|
||||||
database_url,
|
|
||||||
database_max_connections,
|
|
||||||
host,
|
|
||||||
port,
|
|
||||||
title,
|
|
||||||
max_mem_log_size,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@ use axum::{
|
|||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use clap::Parser;
|
||||||
use dotenvy::dotenv;
|
use dotenvy::dotenv;
|
||||||
use notify::Watcher;
|
use notify::Watcher;
|
||||||
use sqlx::postgres::PgPoolOptions;
|
use sqlx::postgres::PgPoolOptions;
|
||||||
@ -32,7 +33,7 @@ async fn serve(app: Router, addr: SocketAddr) -> Result<()> {
|
|||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
let config = Config::new()?;
|
let config = Config::parse();
|
||||||
|
|
||||||
let (log_sender, log_receiver) = channel::<Bytes>(Bytes::new());
|
let (log_sender, log_receiver) = channel::<Bytes>(Bytes::new());
|
||||||
let _guards = init_tracing(&config, log_sender)?;
|
let _guards = init_tracing(&config, log_sender)?;
|
||||||
|
@ -8,7 +8,7 @@ use validator::Validate;
|
|||||||
|
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, sqlx::Type)]
|
#[derive(Debug, Serialize, Deserialize, sqlx::Type, Clone)]
|
||||||
#[sqlx(type_name = "feed_type", rename_all = "lowercase")]
|
#[sqlx(type_name = "feed_type", rename_all = "lowercase")]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum FeedType {
|
pub enum FeedType {
|
||||||
|
Loading…
Reference in New Issue
Block a user