Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cdk): generate command params #4026

Merged
merged 10 commits into from
Jun 15, 2024
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]

EstebanBorai marked this conversation as resolved.
Show resolved Hide resolved
[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>,

sehz marked this conversation as resolved.
Show resolved Hide resolved
/// 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
Loading