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",
|
||||
]
|
||||
|
||||
[[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]]
|
||||
name = "anyhow"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "article_scraper"
|
||||
version = "2.0.0-alpha.0"
|
||||
@ -314,6 +335,48 @@ dependencies = [
|
||||
"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]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
@ -330,6 +393,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
@ -361,11 +430,11 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi-to-html",
|
||||
"anyhow",
|
||||
"argh",
|
||||
"article_scraper",
|
||||
"axum",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap",
|
||||
"dotenvy",
|
||||
"feed-rs",
|
||||
"maud",
|
||||
@ -1218,6 +1287,18 @@ version = "2.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
@ -2766,6 +2847,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.2"
|
||||
|
@ -3,6 +3,7 @@ name = "crawlnicle"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "crawlnicle"
|
||||
authors = ["Tyler Hallada <tyler@hallada.net>"]
|
||||
|
||||
[lib]
|
||||
name = "lib"
|
||||
@ -13,11 +14,11 @@ path = "src/lib.rs"
|
||||
[dependencies]
|
||||
ansi-to-html = "0.1"
|
||||
anyhow = "1"
|
||||
argh = "0.1"
|
||||
article_scraper = "2.0.0-alpha.0"
|
||||
axum = "0.6"
|
||||
bytes = "1.4"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
clap = { version = "4.3", features = ["derive", "env"] }
|
||||
dotenvy = "0.15"
|
||||
feed-rs = "1.3"
|
||||
maud = { version = "0.25", features = ["axum"] }
|
||||
|
@ -1,5 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use argh::FromArgs;
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use chrono::Utc;
|
||||
use dotenvy::dotenv;
|
||||
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::uuid::Base62Uuid;
|
||||
|
||||
#[derive(FromArgs)]
|
||||
/// CLI for crawlnicle
|
||||
struct Args {
|
||||
#[argh(subcommand)]
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[command(propagate_version = true)]
|
||||
struct Cli {
|
||||
#[command(subcommand)]
|
||||
commands: Commands,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[argh(subcommand)]
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
/// Fetches new entries from all feeds in the database
|
||||
Crawl,
|
||||
AddFeed(AddFeed),
|
||||
DeleteFeed(DeleteFeed),
|
||||
AddEntry(AddEntry),
|
||||
DeleteEntry(DeleteEntry),
|
||||
Crawl(Crawl),
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
/// Add a feed to the database
|
||||
#[argh(subcommand, name = "add-feed")]
|
||||
#[derive(Args)]
|
||||
struct AddFeed {
|
||||
#[argh(option)]
|
||||
/// title of the feed (max 255 characters)
|
||||
#[arg(short, long)]
|
||||
title: Option<String>,
|
||||
#[argh(option)]
|
||||
/// URL of the feed (max 2048 characters)
|
||||
#[arg(short, long)]
|
||||
url: String,
|
||||
#[argh(option, long = "type")]
|
||||
/// type of the feed ('rss' or 'atom')
|
||||
#[arg(short, long)]
|
||||
feed_type: FeedType,
|
||||
#[argh(option)]
|
||||
/// description of the feed
|
||||
#[arg(short, long)]
|
||||
description: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[derive(Args)]
|
||||
/// Delete a feed from the database
|
||||
#[argh(subcommand, name = "delete-feed")]
|
||||
struct DeleteFeed {
|
||||
#[argh(positional)]
|
||||
/// id of the feed to delete
|
||||
id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[derive(Args)]
|
||||
/// Add an entry to the database
|
||||
#[argh(subcommand, name = "add-entry")]
|
||||
struct AddEntry {
|
||||
#[argh(option)]
|
||||
/// title of the entry (max 255 characters)
|
||||
#[arg(short, long)]
|
||||
title: Option<String>,
|
||||
#[argh(option)]
|
||||
/// URL of the entry (max 2048 characters)
|
||||
#[arg(short, long)]
|
||||
url: String,
|
||||
#[argh(option)]
|
||||
/// description of the entry
|
||||
#[arg(short, long)]
|
||||
description: Option<String>,
|
||||
#[argh(option)]
|
||||
/// source feed for the entry
|
||||
#[arg(short, long)]
|
||||
feed_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[derive(Args)]
|
||||
/// Delete an entry from the database
|
||||
#[argh(subcommand, name = "delete-entry")]
|
||||
struct DeleteEntry {
|
||||
#[argh(positional)]
|
||||
/// id of the entry to delete
|
||||
id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
/// Delete an entry from the database
|
||||
#[argh(subcommand, name = "crawl")]
|
||||
struct Crawl {}
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() -> Result<()> {
|
||||
dotenv().ok();
|
||||
@ -99,9 +90,9 @@ pub async fn main() -> Result<()> {
|
||||
.connect(&env::var("DATABASE_URL")?)
|
||||
.await?;
|
||||
|
||||
let args: Args = argh::from_env();
|
||||
let cli: Cli = Cli::parse();
|
||||
|
||||
match args.commands {
|
||||
match cli.commands {
|
||||
Commands::AddFeed(args) => {
|
||||
let feed = create_feed(
|
||||
&pool,
|
||||
@ -138,7 +129,7 @@ pub async fn main() -> Result<()> {
|
||||
delete_entry(&pool, args.id).await?;
|
||||
info!("Deleted entry with id {}", Base62Uuid::from(args.id));
|
||||
}
|
||||
Commands::Crawl(_) => {
|
||||
Commands::Crawl => {
|
||||
info!("Crawling...");
|
||||
crawl(&pool).await?;
|
||||
}
|
||||
|
@ -1,31 +1,17 @@
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Parser, Clone, Debug)]
|
||||
pub struct Config {
|
||||
#[clap(long, env)]
|
||||
pub database_url: String,
|
||||
#[clap(long, env)]
|
||||
pub database_max_connections: u32,
|
||||
#[clap(long, env)]
|
||||
pub host: String,
|
||||
#[clap(long, env)]
|
||||
pub port: u16,
|
||||
#[clap(long, env)]
|
||||
pub title: String,
|
||||
#[clap(long, env)]
|
||||
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,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use clap::Parser;
|
||||
use dotenvy::dotenv;
|
||||
use notify::Watcher;
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
@ -32,7 +33,7 @@ async fn serve(app: Router, addr: SocketAddr) -> Result<()> {
|
||||
async fn main() -> Result<()> {
|
||||
dotenv().ok();
|
||||
|
||||
let config = Config::new()?;
|
||||
let config = Config::parse();
|
||||
|
||||
let (log_sender, log_receiver) = channel::<Bytes>(Bytes::new());
|
||||
let _guards = init_tracing(&config, log_sender)?;
|
||||
|
@ -8,7 +8,7 @@ use validator::Validate;
|
||||
|
||||
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")]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum FeedType {
|
||||
|
Loading…
Reference in New Issue
Block a user