Skip to content

Commit

Permalink
feat(cdk): generate command params (#4026)
Browse files Browse the repository at this point in the history
* feat(cdk): generate command params

* fix: tests for gen/build

* chore: tests

* feat: support to build on workspace envs

* fix: also test source

* Update connector/cargo_template/Cargo.toml.liquid

* Update Cargo.toml.liquid
  • Loading branch information
EstebanBorai committed Jun 15, 2024
1 parent ce2bcb5 commit 95b43dc
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 11 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ dialoguer = "0.11.0"
directories = "5.0.0"
dirs = "5.0.0"
duct = { version = "0.13", default-features = false }
enum-display = "0.1.3"
event-listener = "3.1.0"
eyre = { version = "0.6", default-features = false }
flate2 = { version = "1.0.25" }
Expand Down
2 changes: 2 additions & 0 deletions connector/cargo_template/Cargo.toml.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ version = "0.1.0"
authors = ["{{authors}}"]
edition = "2021"

[workspace]

[dependencies]
{% if connector-type == "sink" %}futures = { version = "0.3", default-features = false }{% endif %}
serde = { version = "1.0", default-features = false, features = ["derive"]}
Expand Down
1 change: 1 addition & 0 deletions crates/cdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ cargo-generate = { workspace = true }
clap = { workspace = true, features = ["std", "derive", "help", "usage", "error-context", "env", "wrap_help", "suggestions"], default-features = false }
comfy-table = { workspace = true }
current_platform = { workspace = true }
enum-display = { workspace = true }
include_dir = { workspace = true }
serde = { workspace = true, features = ["derive"] }
sysinfo = { workspace = true, default-features = false }
Expand Down
146 changes: 140 additions & 6 deletions crates/cdk/src/generate.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use std::{fmt::Debug, path::PathBuf};
use std::fmt::Debug;
use std::fmt::Display;
use std::path::PathBuf;

use anyhow::{Result, Error};

use clap::Parser;
use clap::{Parser, ValueEnum};
use cargo_generate::{GenerateArgs, TemplatePath, generate};
use include_dir::{Dir, include_dir};
use tempfile::TempDir;
use enum_display::EnumDisplay;

// Note: Cargo.toml.liquid files are changed by cargo-generate to Cargo.toml
// this avoids the problem of cargo trying to parse Cargo.toml template files
Expand All @@ -17,9 +20,17 @@ static CONNECTOR_TEMPLATE: Dir<'static> =
/// Generate new SmartConnector project
#[derive(Debug, Parser)]
pub struct GenerateCmd {
/// SmartConnector Project Name
/// Connector Name
name: Option<String>,

#[arg(long, value_name = "GROUP")]
/// Connector developer group
group: Option<String>,

/// Connector description used as part of the project metadata
#[arg(long, value_name = "DESCRIPTION")]
conn_description: Option<String>,

/// Local path to generate the SmartConnector project.
/// Default to directory with project name, created in current directory
#[arg(long, env = "CDK_DESTINATION", value_name = "PATH")]
Expand All @@ -28,6 +39,16 @@ pub struct GenerateCmd {
/// Disable interactive prompt. Take all values from CLI flags. Fail if a value is missing.
#[arg(long, hide_short_help = true)]
silent: bool,

/// Type of Connector project to generate.
/// Skip prompt if value given.
#[arg(long, value_enum, value_name = "TYPE", env = "CDK_CONN_TYPE")]
conn_type: Option<ConnectorType>,

/// Visibility of Connector project to generate.
/// Skip prompt if value given.
#[arg(long, value_enum, value_name = "PUBLIC", env = "CDK_CONN_PUBLIC")]
conn_public: Option<bool>,
}

impl GenerateCmd {
Expand All @@ -46,16 +67,22 @@ impl GenerateCmd {
..Default::default()
};

let fluvio_dependency_version_hash =
format!("fluvio-cargo-dependency-hash={}", env!("GIT_HASH"));
let mut maybe_user_input = CdkTemplateUserValues::new();

maybe_user_input
.with_name(self.name.clone())
.with_group(self.group)
.with_description(self.conn_description)
.with_conn_type(self.conn_type)
.with_conn_public(self.conn_public);

let args = GenerateArgs {
name: self.name,
template_path,
verbose: !self.silent,
silent: self.silent,
destination: self.destination,
define: vec![fluvio_dependency_version_hash],
define: maybe_user_input.to_cargo_generate(),
..Default::default()
};

Expand All @@ -64,3 +91,110 @@ impl GenerateCmd {
Ok(())
}
}

#[derive(ValueEnum, Clone, Debug, Parser, PartialEq, Eq, EnumDisplay)]
#[clap(rename_all = "kebab-case")]
#[enum_display(case = "Kebab")]
enum ConnectorType {
Sink,
Source,
}

#[derive(Clone, Debug)]
enum CdkTemplateValue {
Name(String),
Group(String),
Description(String),
ConnFluvioDependencyHash(String),
ConnType(ConnectorType),
ConnPublic(bool),
}

impl Display for CdkTemplateValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CdkTemplateValue::Name(name) => write!(f, "project-name={}", name),
CdkTemplateValue::Group(group) => write!(f, "project-group={}", group),
CdkTemplateValue::Description(description) => {
write!(f, "project-description={}", description)
}
CdkTemplateValue::ConnFluvioDependencyHash(hash) => {
write!(f, "fluvio-cargo-dependency-hash={}", hash)
}
CdkTemplateValue::ConnType(conn_type) => write!(f, "connector-type={conn_type}"),
CdkTemplateValue::ConnPublic(conn_public) => {
write!(f, "connector-public={conn_public}")
}
}
}
}

#[derive(Debug, Default, Clone)]
struct CdkTemplateUserValues {
values: Vec<CdkTemplateValue>,
}

impl CdkTemplateUserValues {
fn new() -> Self {
// By default the fluvio dependency hash is the current git hash
// and its always passed as option to cargo generate
let values = vec![CdkTemplateValue::ConnFluvioDependencyHash(
env!("GIT_HASH").to_string(),
)];

Self { values }
}

fn to_vec(&self) -> Vec<CdkTemplateValue> {
self.values.clone()
}

fn to_cargo_generate(&self) -> Vec<String> {
self.to_vec().iter().map(|v| v.to_string()).collect()
}

fn with_name(&mut self, value: Option<String>) -> &mut Self {
if let Some(v) = value {
tracing::debug!("CDK Argument - project-name={}", v);
self.values.push(CdkTemplateValue::Name(v));
}

self
}

fn with_group(&mut self, value: Option<String>) -> &mut Self {
if let Some(v) = value {
tracing::debug!("CDK Argument - project-group={}", v);
self.values.push(CdkTemplateValue::Group(v));
}

self
}

fn with_description(&mut self, value: Option<String>) -> &mut Self {
if let Some(v) = value {
tracing::debug!("CDK Argument - project-description={}", v);
self.values.push(CdkTemplateValue::Description(v));
}

self
}

fn with_conn_type(&mut self, value: Option<ConnectorType>) -> &mut Self {
if let Some(v) = value {
tracing::debug!("CDK Argument - connector-type={}", v);
self.values.push(CdkTemplateValue::ConnType(v));
}

self
}

fn with_conn_public(&mut self, value: Option<bool>) -> &mut Self {
if let Some(v) = value {
tracing::debug!("CDK Argument - connector-public={}", v);
self.values.push(CdkTemplateValue::ConnPublic(v));
}

self
}
}
2 changes: 1 addition & 1 deletion crates/smartmodule-development-kit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ anyhow = { workspace = true }
clap = { workspace = true, features = ["std", "derive", "help", "usage", "error-context", "env", "wrap_help", "suggestions"], default-features = false }
current_platform = { workspace = true }
dirs = { workspace = true }
enum-display = { workspace = true }
toml = { workspace = true }
tokio = { workspace = true }
cargo-generate = { workspace = true }
include_dir = { workspace = true }
tempfile = { workspace = true }
enum-display = "0.1.3"
lib-cargo-crate = "0.2.1"


Expand Down
59 changes: 59 additions & 0 deletions tests/cli/cdk_smoke_tests/cdk-basic.bats
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,65 @@ setup_file() {
assert_success
}

@test "Generate and Builds a Sink Connector Package" {
export SINK_CONN_NAME="$PROJECT_NAME_PREFIX-my-sink-conn"

# move into test dir
cd $TEST_DIR

# generate a sink connector
run $CDK_BIN generate $SINK_CONN_NAME \
--group "$PROJECT_NAME_PREFIX" \
--conn-description "My Sink Connector" \
--conn-type sink \
--conn-public true
assert_success

# cd into the sink connector directory
cd $SINK_CONN_NAME

# build connector
run $CDK_BIN build --target x86_64-unknown-linux-gnu
assert_success
}

@test "Generate and Builds a Source Connector Package" {
export SOURCE_CONN_NAME="$PROJECT_NAME_PREFIX-my-source-conn"

# move into test dir
cd $TEST_DIR

# generate a source connector
run $CDK_BIN generate $SOURCE_CONN_NAME \
--group "$PROJECT_NAME_PREFIX" \
--conn-description "My Source Connector" \
--conn-type source \
--conn-public true
assert_success

# cd into the source connector directory
cd $SOURCE_CONN_NAME

# build connector
run $CDK_BIN build --target x86_64-unknown-linux-gnu
assert_success
}

@test "Fails on unsupported/invalid connector type" {
export BAD_TYPE_CONN_NAME="$PROJECT_NAME_PREFIX-my-bad-type-conn"

# move into test dir
cd $TEST_DIR

# generate a sink connector
run $CDK_BIN generate $BAD_TYPE_CONN_NAME \
--group "$PROJECT_NAME_PREFIX" \
--conn-description "My Source Connector" \
--conn-type bad-type \
--conn-public true
assert_failure
}

# fix CI authentication to hub service first:
# https://github.com/infinyon/fluvio/issues/3634
# @test "List connectors from hub" {
Expand Down

0 comments on commit 95b43dc

Please sign in to comment.