>_ DevTrendsit

Lingua

Home

Linguaggi

Sezioni

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Sicurezza
Rust

Perché le utility da console hanno bisogno di una loro alternativa a OpenAPI e come funziona il progetto Usage

Ogni volta che scrivo una piccola utility da console, la stessa storia si ripete. Prima schizzi gli argomenti e i flag nel codice. Poi decidi di aggiungere l'autocompletamento per bash e zsh, ti immergi nel ricordare la sintassi degli script shell o cercare generatori. Successivamente devi formattare la documentazione in Markdown, aggiornare le pagine man e ricordarti di supportare le variabili d'ambiente. Se il progetto viene riscritto in un altro linguaggio o ottiene wrapper Python o Bash, devi duplicare manualmente l'intera struttura degli argomenti.

Lo sviluppatore jdx, noto per il popolare version manager mise, ha affrontato questa routine in modo sistematico creando il progetto Usage.

Un contratto invece di workaround sparsi

L'idea centrale dietro Usage è semplice: il software da console ha bisogno di un equivalente OpenAPI o Swagger tutto suo. Invece di legare le descrizioni degli argomenti a una libreria specifica in un linguaggio specifico, Usage offre una singola specifica portatile in formato KDL.

KDL non è stato scelto a caso. Questo linguaggio di documentazione è più pulito e leggibile di JSON o YAML, rendendolo conveniente per descrivere comandi nidificati, flag, alias brevi e tipi di dati.

Descrivere l'interfaccia della tua utility in questo formato una volta risolve diversi problemi contemporaneamente:

  • Generazione di script di autocompletamento per tutte le shell di comandi più diffuse.
  • Assemblaggio automatico della documentazione in Markdown e pagine man.
  • Parsing degli argomenti da script in altri linguaggi.
  • Scaffolding del codice per diverse librerie CLI.

Come appare in Rust

Se scrivi in Rust, non devi scrivere affatto il manifest KDL a mano. Il progetto include una crate usage-rs che genera la specifica direttamente dalla tua struttura dati usando derive macro.

Ecco un esempio base:

[dependencies]
usage = { package = "usage-rs", version = "6" }
use usage::Cli;

#[derive(Cli)]
#[usage(bin = "example", version)]
struct App {
    /// Print more detail.
    #[usage(short = 'v', long, count)]
    verbose: u8,

    /// Files to process.
    files: Vec<String>,
}

fn main() {
    let app = App::parse();
    // app.verbose и app.files готовы к работе
}

Il parser runtime non trascina con sé dipendenze pesanti. Allo stesso tempo, puoi esportare una specifica KDL pronta all'uso dalla stessa struttura e usarla in infrastrutture di build esterne o pipeline CI/CD.

Differenze dal familiare clap

La maggior parte degli sviluppatori Rust è abituata a usare clap. L'autore di Usage riconosce apertamente l'influenza di questa libreria e ha preservato un formato di output simile per i messaggi di help e i report degli errori per rendere la transizione il meno dolorosa possibile.

La differenza sta nella filosofia. clap è strettamente orientato verso l'ecosistema Rust. usage sposta lo schema dell'interfaccia a un livello superiore, trasformandolo in un contratto universale. Puoi prendere la specifica e parsare gli argomenti in uno script Bash tramite l'utility CLI usage senza riscrivere la tua logica di validazione dei flag.

Aziende come 37signals sono già tra gli sponsor del progetto. Questo dimostra l'interesse dell'industria nella standardizzazione delle interfacce terminal.

A chi serve il progetto adesso

Usage difficilmente sarà necessario per uno script usa e getta di venti righe. Tuttavia, lo strumento si adatta perfettamente allo sviluppo di utility interne aziendali complesse, client CLI per API e strumenti di piattaforma usati da team diversi.

Se sei stanco di sincronizzare manualmente la documentazione con i flag e scrivere script di autocompletamento per ogni shell, il progetto vale sicuramente la pena di essere provato. La documentazione e le guide di migrazione sono disponibili sul sito ufficiale usage.jdx.dev.

Progetti correlati