Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions cli/assets/fig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,55 @@ const completionSpec: Fig.Spec = {
},
],
},
{
name: "sdk",
description: "Generate a type-safe SDK from a usage spec",
options: [
{
name: ["-f", "--file"],
description: "A usage spec taken in as a file",
isRepeatable: false,
args: {
name: "file",
template: "filepaths",
},
},
{
name: ["-l", "--language"],
description: "Target language for the SDK",
isRepeatable: false,
args: {
name: "language",
suggestions: ["typescript", "python"],
},
},
{
name: ["-o", "--output"],
description: "Output directory for generated SDK files",
isRepeatable: false,
args: {
name: "output",
},
},
{
name: ["-p", "--package-name"],
description:
"Override the package/module name (defaults to spec bin name)",
isRepeatable: false,
args: {
name: "package_name",
},
},
{
name: "--spec",
description: "Raw string spec input",
isRepeatable: false,
args: {
name: "spec",
},
},
],
},
],
},
{
Expand Down
25 changes: 25 additions & 0 deletions cli/assets/usage.1
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ Generate markdown documentation from usage specs
\fIAliases: \fRmd
.RE
.TP
\fBgenerate sdk\fR
Generate a type\-safe SDK from a usage spec
.TP
\fBlint\fR
Lint a usage spec file for common issues
.TP
Expand Down Expand Up @@ -310,6 +313,28 @@ Replace `<pre>` tags with markdown code fences
.TP
\fB\-\-url\-prefix\fR \fI<URL_PREFIX>\fR
Prefix to add to all URLs
.SH "USAGE GENERATE SDK"
Generate a type\-safe SDK from a usage spec
.PP
\fBUsage:\fR usage generate sdk [OPTIONS]
.PP
\fBOptions:\fR
.PP
.TP
\fB\-f, \-\-file\fR \fI<FILE>\fR
A usage spec taken in as a file
.TP
\fB\-l, \-\-language\fR \fI<LANGUAGE>\fR
Target language for the SDK
.TP
\fB\-o, \-\-output\fR \fI<OUTPUT>\fR
Output directory for generated SDK files
.TP
\fB\-p, \-\-package\-name\fR \fI<PACKAGE_NAME>\fR
Override the package/module name (defaults to spec bin name)
.TP
\fB\-\-spec\fR \fI<SPEC>\fR
Raw string spec input
.SH "USAGE LINT"
Lint a usage spec file for common issues
.PP
Expand Down
3 changes: 3 additions & 0 deletions cli/src/cli/generate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod fig;
mod json;
mod manpage;
mod markdown;
mod sdk;

/// Generate completions, documentation, and other artifacts from usage specs
#[derive(clap::Args)]
Expand All @@ -27,6 +28,7 @@ pub enum Command {
Json(json::Json),
Manpage(manpage::Manpage),
Markdown(markdown::Markdown),
Sdk(sdk::Sdk),
}

impl Generate {
Expand All @@ -38,6 +40,7 @@ impl Generate {
Command::Json(cmd) => cmd.run(),
Command::Manpage(cmd) => cmd.run(),
Command::Markdown(cmd) => cmd.run(),
Command::Sdk(cmd) => cmd.run(),
}
}
}
Expand Down
66 changes: 66 additions & 0 deletions cli/src/cli/generate/sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::path::PathBuf;

use clap::Args;

use crate::cli::generate;

use usage::sdk::{SdkLanguage, SdkOptions};

#[derive(Args)]
#[clap(about = "Generate a type-safe SDK from a usage spec")]
pub struct Sdk {
/// A usage spec taken in as a file
#[clap(short, long)]
file: Option<PathBuf>,

/// Target language for the SDK
#[clap(short, long, value_parser = ["typescript", "python"])]
language: String,

/// Output directory for generated SDK files
#[clap(short, long)]
output: PathBuf,

/// Override the package/module name (defaults to spec bin name)
#[clap(short, long)]
package_name: Option<String>,

/// Raw string spec input
#[clap(long, required_unless_present = "file", overrides_with = "file")]
spec: Option<String>,
}

impl Sdk {
pub fn run(&self) -> miette::Result<()> {
let spec = generate::file_or_spec(&self.file, &self.spec)?;

let language = match self.language.as_str() {
"typescript" => SdkLanguage::TypeScript,
"python" => SdkLanguage::Python,
other => {
return Err(miette::miette!("unsupported language: {other}"));
}
};

let source_file = self.file.as_ref().map(|p| p.display().to_string());

let opts = SdkOptions {
language,
package_name: self.package_name.clone(),
source_file,
};

let output = usage::sdk::generate(&spec, &opts);

std::fs::create_dir_all(&self.output)
.map_err(|e| miette::miette!("failed to create output directory: {e}"))?;

for file in &output.files {
let path = self.output.join(&file.path);
println!("writing to {}", path.display());
xx::file::write(&path, &file.content)?;
}

Ok(())
}
}
19 changes: 19 additions & 0 deletions cli/usage.usage.kdl
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,25 @@ cmd generate subcommand_required=#true help="Generate completions, documentation
arg <URL_PREFIX>
}
}
cmd sdk help="Generate a type-safe SDK from a usage spec" {
flag "-f --file" help="A usage spec taken in as a file" {
arg <FILE>
}
flag "-l --language" help="Target language for the SDK" required=#true {
arg <LANGUAGE> {
choices typescript python
}
}
flag "-o --output" help="Output directory for generated SDK files" required=#true {
arg <OUTPUT>
}
flag "-p --package-name" help="Override the package/module name (defaults to spec bin name)" {
arg <PACKAGE_NAME>
}
flag --spec help="Raw string spec input" {
arg <SPEC>
}
}
}
cmd lint help="Lint a usage spec file for common issues" {
flag "-f --format" help="Output format" default=text {
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default defineConfig({
{ text: "Completions", link: "/cli/completions" },
{ text: "Manpages", link: "/cli/manpages" },
{ text: "Markdown", link: "/cli/markdown" },
{ text: "SDK Generation", link: "/cli/sdk" },
{ text: "Scripts", link: "/cli/scripts" },
{
text: "CLI Reference", link: "/cli/reference/", items:
Expand Down
105 changes: 105 additions & 0 deletions docs/cli/reference/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,111 @@
"aliases": ["md"],
"hidden_aliases": [],
"examples": []
},
"sdk": {
"full_cmd": ["generate", "sdk"],
"usage": "generate sdk <FLAGS>",
"subcommands": {},
"args": [],
"flags": [
{
"name": "file",
"usage": "-f --file <FILE>",
"help": "A usage spec taken in as a file",
"help_first_line": "A usage spec taken in as a file",
"short": ["f"],
"long": ["file"],
"hide": false,
"global": false,
"arg": {
"name": "FILE",
"usage": "<FILE>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
{
"name": "language",
"usage": "-l --language <LANGUAGE>",
"help": "Target language for the SDK",
"help_first_line": "Target language for the SDK",
"short": ["l"],
"long": ["language"],
"required": true,
"hide": false,
"global": false,
"arg": {
"name": "LANGUAGE",
"usage": "<LANGUAGE>",
"required": true,
"double_dash": "Optional",
"hide": false,
"choices": {
"choices": ["typescript", "python"]
}
}
},
{
"name": "output",
"usage": "-o --output <OUTPUT>",
"help": "Output directory for generated SDK files",
"help_first_line": "Output directory for generated SDK files",
"short": ["o"],
"long": ["output"],
"required": true,
"hide": false,
"global": false,
"arg": {
"name": "OUTPUT",
"usage": "<OUTPUT>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
{
"name": "package-name",
"usage": "-p --package-name <PACKAGE_NAME>",
"help": "Override the package/module name (defaults to spec bin name)",
"help_first_line": "Override the package/module name (defaults to spec bin name)",
"short": ["p"],
"long": ["package-name"],
"hide": false,
"global": false,
"arg": {
"name": "PACKAGE_NAME",
"usage": "<PACKAGE_NAME>",
"required": true,
"double_dash": "Optional",
"hide": false
}
},
{
"name": "spec",
"usage": "--spec <SPEC>",
"help": "Raw string spec input",
"help_first_line": "Raw string spec input",
"short": [],
"long": ["spec"],
"hide": false,
"global": false,
"arg": {
"name": "SPEC",
"usage": "<SPEC>",
"required": true,
"double_dash": "Optional",
"hide": false
}
}
],
"mounts": [],
"hide": false,
"help": "Generate a type-safe SDK from a usage spec",
"name": "sdk",
"aliases": [],
"hidden_aliases": [],
"examples": []
}
},
"args": [],
Expand Down
1 change: 1 addition & 0 deletions docs/cli/reference/generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Generate completions, documentation, and other artifacts from usage specs
- [`usage generate json [-f --file <FILE>] [--spec <SPEC>]`](/cli/reference/generate/json.md)
- [`usage generate manpage <FLAGS>`](/cli/reference/generate/manpage.md)
- [`usage generate markdown <FLAGS>`](/cli/reference/generate/markdown.md)
- [`usage generate sdk <FLAGS>`](/cli/reference/generate/sdk.md)
35 changes: 35 additions & 0 deletions docs/cli/reference/generate/sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!-- @generated by usage-cli from usage spec -->

# `usage generate sdk`

- **Usage**: `usage generate sdk <FLAGS>`
- **Source code**: [`cli/src/cli/generate/sdk.rs`](https://github.com/jdx/usage/blob/main/cli/src/cli/generate/sdk.rs)

Generate a type-safe SDK from a usage spec

## Flags

### `-f --file <FILE>`

A usage spec taken in as a file

### `-l --language <LANGUAGE>`

Target language for the SDK

**Choices:**

- `typescript`
- `python`

### `-o --output <OUTPUT>`

Output directory for generated SDK files

### `-p --package-name <PACKAGE_NAME>`

Override the package/module name (defaults to spec bin name)

### `--spec <SPEC>`

Raw string spec input
1 change: 1 addition & 0 deletions docs/cli/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Outputs a `usage.kdl` spec for this CLI itself
- [`usage generate json [-f --file <FILE>] [--spec <SPEC>]`](/cli/reference/generate/json.md)
- [`usage generate manpage <FLAGS>`](/cli/reference/generate/manpage.md)
- [`usage generate markdown <FLAGS>`](/cli/reference/generate/markdown.md)
- [`usage generate sdk <FLAGS>`](/cli/reference/generate/sdk.md)
- [`usage lint [-f --format <FORMAT>] [-W --warnings-as-errors] <FILE>`](/cli/reference/lint.md)
- [`usage powershell [-h] [--help] <SCRIPT> [ARGS]…`](/cli/reference/powershell.md)
- [`usage zsh [-h] [--help] <SCRIPT> [ARGS]…`](/cli/reference/zsh.md)
Loading