>_ DevTrendspl

Język

Strona główna

Języki

Sekcje

Frontend Backend Mobilne DevOps AI / ML GameDev Blockchain Systemy wbudowane Bezpieczeństwo
Rust

Dlaczego narzędzia konsolowe potrzebują własnej alternatywy dla OpenAPI i jak działa projekt Usage

Za każdym razem, gdy piszę małe narzędzie konsolowe, ta sama historia się powtarza. Najpierw szkicujesz argumenty i flagi w kodzie. Potem decydujesz się dodać autouzupełnianie dla Basza i zsh, grzebać w zapamiętywaniu składni skryptów powłoki lub szukać generatorów. Następnie musisz sformatować dokumentację w Markdown, zaktualizować strony man i pamiętać o obsłudze zmiennych środowiskowych. Jeśli projekt zostanie przepisany w innym języku lub zyska wrappery Pythona lub Basza, musisz ręcznie zduplikować całą strukturę argumentów.

Deweloper jdx, znany z popularnego menedżera wersji mise, podszedł do tej rutyny systematycznie i stworzył projekt Usage.

Kontrakt zamiast rozrzuconych obejść

Główna idea Usage jest prosta: oprogramowanie konsolowe potrzebuje własnego odpowiednika OpenAPI lub Swaggera. Zamiast wiązać opisy argumentów z konkretną biblioteką w konkretnym języku, Usage oferuje jedną przenośną specyfikację w formacie KDL.

KDL nie został wybrany przypadkowo. Ten język dokumentów jest czystszy i bardziej czytelny niż JSON czy YAML, co czyni go wygodnym do opisywania zagnieżdżonych poleceń, flag, krótkich aliasów i typów danych.

Jednokrotne opisanie interfejsu narzędzia w tym formacie rozwiązuje od razu kilka problemów:

  • Generowanie skryptów autouzupełniania dla wszystkich popularnych powłok poleceń.
  • Automatyczne tworzenie dokumentacji w Markdown i stron man.
  • Parsowanie argumentów ze skryptów w innych językach.
  • Szkielet kodu dla różnych bibliotek CLI.

Jak to wygląda w Rust

Jeśli piszesz w Rust, nie musisz w ogóle pisać manifestu KDL ręcznie. Projekt zawiera crate usage-rs, który generuje specyfikację bezpośrednio ze struktury danych za pomocą makr derive.

Oto podstawowy przykład:

[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 готовы к работе
}

Parser runtime nie ciągnie za sobą ciężkich zależności. Jednocześnie możesz wyeksportować gotową specyfikację KDL z tej samej struktury i użyć jej w zewnętrznej infrastrukturze budowania lub pipeline'ach CI/CD.

Różnice w porównaniu z znanym clap

Większość deweloperów Rust jest przyzwyczajona do używania clap. Autor Usage otwarcie przyznaje wpływ tej biblioteki i zachował podobny format wyjściowy dla wiadomości pomocy i raportów błędów, aby przejście było jak najbardziej bezbolesne.

Różnica tkwi w filozofii. clap jest ściśle zorientowany na ekosystem Rust. usage przenosi schemat interfejsu na wyższy poziom, przekształcając go w uniwersalny kontrakt. Możesz wziąć specyfikację i parsować argumenty w skrypcie Basza za pomocą narzędzia CLI usage bez przepisywania logiki walidacji flag.

Firmy takie jak 37signals są już wśród sponsorów projektu. Świadczy to o zainteresowaniu branży standaryzacją interfejsów terminalowych.

Komu projekt jest teraz przydatny

Usage prawdopodobnie nie będzie potrzebny do jednorazowego skryptu z dwudziestoma liniami. Jednak narzędzie idealnie sprawdza się przy tworzeniu złożonych wewnętrznych narzędzi firmowych, klientów CLI API i narzędzi platformowych używanych przez różne zespoły.

Jeśli masz dość ręcznego synchronizowania dokumentacji z flagami i pisania skryptów autouzupełniania dla każdej powłoki, projekt zdecydowanie warto sprawdzić. Dokumentacja i przewodniki migracji są dostępne na oficjalnej stronie usage.jdx.dev.

Powiązane projekty