Skip to content

Commit

Permalink
Merge pull request #506 from paperclip-rs/draft-poc
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagolobocastro authored Oct 21, 2024
2 parents 3da20d8 + 0a32d58 commit 1c16b3f
Show file tree
Hide file tree
Showing 331 changed files with 32,735 additions and 38 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ jobs:
timeout-minutes: 10
with:
command: build
args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator"
args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator cli-ng"

- name: Build actix3 features
uses: actions-rs/cargo@v1
timeout-minutes: 10
with:
command: build
args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator"
args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator cli-ng"

# - name: Build actix2 features
# uses: actions-rs/cargo@v1
Expand All @@ -82,14 +82,14 @@ jobs:
timeout-minutes: 20
with:
command: test
args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator"
args: --all --features "actix4 cli chrono url uuid swagger-ui rapidoc v3 actix4-validator cli-ng"

- name: Run actix3 tests
uses: actions-rs/cargo@v1
timeout-minutes: 20
with:
command: test
args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator"
args: --all --features "actix3 cli chrono url uuid swagger-ui rapidoc v3 actix3-validator cli-ng"

# - name: Run actix2 tests
# uses: actions-rs/cargo@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: doc
args: --all --features "actix4 cli chrono url uuid swagger-ui v3" --no-deps
args: --all --features "actix4 cli chrono url uuid swagger-ui v3 cli-ng" --no-deps

- name: Setup GitBook
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all --features "actix4 cli chrono url uuid swagger-ui v3" -- -D clippy::all ${{ matrix.exclude }}
args: --all --features "actix4 cli chrono url uuid swagger-ui v3 cli-ng" -- -D clippy::all ${{ matrix.exclude }}

fmt:
name: rustfmt
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Publish Bins
on:
release:
types: [published]
jobs:
paperclip-bins:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
- os: ubuntu-latest
target: aarch64-unknown-linux-musl
- os: macos-14
target: x86_64-apple-darwin
- os: macos-13
target: aarch64-apple-darwin
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Build
uses: actions-rs/cargo@v1
with:
use-cross: true
command: build
args: --bins --verbose --release --features "cli" -p paperclip -p paperclip-ng --target ${{ matrix.target }}
- name: Archive
shell: bash
run: |
tar -czf paperclip-${{ matrix.target }}.tar.gz LICENSE-APACHE LICENSE-MIT -C ./target/${{ matrix.target }}/release/ paperclip paperclip-ng
- name: Publish
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release upload "${{ github.event.release.tag_name }}" --clobber *.tar.gz
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.9.3] - 2024-10-21
### Added
- Experimental openapiv3 cli codegen. [PR#506](https://github.com/paperclip-rs/paperclip/pull/506)

## [0.9.2] - 2024-10-13
### Fixed
- Switch to pro-macro-error2. [PR#545](https://github.com/paperclip-rs/paperclip/pull/545)
Expand Down
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "paperclip"
version = "0.9.2"
version = "0.9.3"
edition = "2018"
description = "OpenAPI tooling library for type-safe compile-time checked HTTP APIs"
documentation = "https://paperclip-rs.github.io/paperclip/paperclip"
Expand All @@ -20,9 +20,10 @@ required-features = ["cli"]
paperclip-actix = { path = "plugins/actix-web", version = "0.7.2", optional = true }
paperclip-core = { path = "core", version = "0.7.2" }
paperclip-macros = { path = "macros", version = "0.7.0", optional = true }
paperclip-ng = { path = "cli-ng", version = "0.1.0", optional = true }

env_logger = { version = "0.8", optional = true }
git2 = { version = "0.15", optional = true }
git2 = { version = "0.15", default-features = false, optional = true }
heck = { version = "0.4", optional = true }
http = { version = "0.2", optional = true }
itertools = "0.10"
Expand Down Expand Up @@ -83,7 +84,8 @@ codegen = ["heck", "http", "log", "regex", "tinytemplate", "paperclip-core/codeg
v2 = ["paperclip-macros/v2", "paperclip-core/v2"]
# OpenAPI v2 to v3 support
v3 = ["openapiv3-paper", "v2", "paperclip-core/v3", "paperclip-actix/v3"]

# Experimental V3 CodeGen
cli-ng = ["cli", "paperclip-ng", "openapiv3-paper"]

# Features for implementing traits for dependencies.
actix-multipart = ["paperclip-core/actix-multipart"]
Expand All @@ -107,6 +109,7 @@ members = [
"core",
"macros",
"plugins/actix-web",
"cli-ng"
]

[[test]]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ doc:
build:
cargo build
cargo build --features actix4
cargo build --features cli
cargo build --features "cli cli-ng"

test:
cargo test --all --features "actix4 cli chrono uuid swagger-ui rapidoc actix4-validator"
Expand Down
27 changes: 27 additions & 0 deletions cli-ng/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "paperclip-ng"
version = "0.1.0"
edition = "2018"
license = "MIT OR Apache-2.0"
keywords = [ "openapi", "openapiv3", "cli", "codegen" ]
description = "Experimental OpenAPI V3.0.3 Code Generator"
homepage = "https://github.com/paperclip-rs/paperclip"
repository = "https://github.com/paperclip-rs/paperclip"

[[bin]]
name = "paperclip-ng"
path = "src/bin/cli/main.rs"

[dependencies]
ramhorns = { version = "1.0", default-features = false, features = ["indexes"] }
ramhorns-derive = { version = "1.0" }
openapiv3-paper = { version = "2.0" }
heck = { version = "0.4" }
itertools = { version = "0.10" }

env_logger = "0.8"
log = { version = "0.4", features = ["kv_unstable"] }
structopt = { version = "0.3" }
serde_json = "1.0"
serde_yaml = "0.9"
thiserror = "1.0"
30 changes: 30 additions & 0 deletions cli-ng/src/bin/cli/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
macro_rules! impl_err_from {
($err:ident :: $type:ty > $variant:ident) => {
impl From<$type> for $err {
fn from(s: $type) -> Self {
$err::$variant(s)
}
}
};
}

/// Global error which encapsulates all related errors.
#[derive(Debug, thiserror::Error)]
pub(crate) enum Error {
/// The given directory cannot be used for generating code.
#[error("Cannot generate code in the given directory")]
InvalidCodegenDirectory,
/// I/O errors.
#[error("I/O error: {}", _0)]
Io(std::io::Error),
/// JSON coding errors.
#[error("JSON error: {}", _0)]
Json(serde_json::Error),
/// YAML coding errors.
#[error("YAML error: {}", _0)]
Yaml(serde_yaml::Error),
}

impl_err_from!(Error::std::io::Error > Io);
impl_err_from!(Error::serde_json::Error > Json);
impl_err_from!(Error::serde_yaml::Error > Yaml);
99 changes: 99 additions & 0 deletions cli-ng/src/bin/cli/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use heck::ToSnakeCase;
use std::{
fs::{self, File},
io::Read,
path::PathBuf,
};
use structopt::StructOpt;

mod error;
use error::Error;

/// Deserialize the schema from the given reader. Currently, this only supports
/// JSON and YAML formats.
fn from_reader_v3<R>(mut reader: R) -> Result<openapiv3::OpenAPI, Error>
where
R: Read,
{
let mut buf = [b' '];
while buf[0].is_ascii_whitespace() {
reader.read_exact(&mut buf)?;
}
let reader = buf.as_ref().chain(reader);

Ok(if buf[0] == b'{' {
serde_json::from_reader::<_, openapiv3::OpenAPI>(reader)?
} else {
serde_yaml::from_reader::<_, openapiv3::OpenAPI>(reader)?
})
}
fn parse_spec_v3(s: &str) -> Result<openapiv3::OpenAPI, Error> {
let fd = File::open(s)?;
from_reader_v3(fd)
}

#[derive(Debug, StructOpt)]
struct Opt {
/// Path to OpenAPI spec in JSON/YAML format (also supports publicly accessible URLs).
#[structopt(long)]
spec: std::path::PathBuf,
/// Output directory to write code (default: current working directory).
#[structopt(short = "o", long = "out", parse(from_os_str))]
output: Option<PathBuf>,
/// Don't Render models.
#[structopt(long)]
no_models: bool,
/// Don't Render operations.
#[structopt(long)]
no_ops: bool,
/// Name of the crate. If this is not specified, then the name of the
/// working directory is assumed to be crate name.
#[structopt(long = "name")]
pub name: Option<String>,
/// The Version of the crate.
#[structopt(long = "version", default_value = "0.1.0")]
pub version: String,
/// The Edition of the crate.
#[structopt(long = "edition", default_value = "2018")]
pub edition: String,
/// Use custom templates (mustache) files, rather than the builtin ones.
/// The root dir in this path must be the template name, example: default.
#[structopt(short = "t", long = "templates", parse(from_os_str))]
templates: Option<PathBuf>,
}

fn parse_args_and_run() -> Result<(), Error> {
let opt: Opt = Opt::from_args();

if let Some(o) = &opt.output {
fs::create_dir_all(o)?;
}

let spec = parse_spec_v3(opt.spec.to_string_lossy().as_ref())?;
let name = opt.name.map(Ok::<String, Error>).unwrap_or_else(|| {
Ok(fs::canonicalize(std::path::Path::new("."))?
.file_name()
.ok_or(Error::InvalidCodegenDirectory)?
.to_string_lossy()
.into_owned()
.to_snake_case())
})?;
let info = paperclip_ng::v3_03::PackageInfo {
libname: name.to_snake_case(),
name,
version: opt.version,
edition: opt.edition,
};

paperclip_ng::v3_03::OpenApiV3::new(spec, opt.templates, opt.output, info)?
.run(!opt.no_models, !opt.no_ops)?;
Ok(())
}

fn main() {
env_logger::init();
if let Err(e) = parse_args_and_run() {
eprintln!("{}", e);
std::process::exit(1);
}
}
5 changes: 5 additions & 0 deletions cli-ng/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod v3;

pub mod v3_03 {
pub use super::v3::{OpenApiV3, PackageInfo};
}
Loading

0 comments on commit 1c16b3f

Please sign in to comment.