#![allow(unused_assignments)]
#![allow(clippy::expect_used)]
mod builder;
pub mod cli;
pub mod commands;
pub mod completions;
pub mod coordinator;
pub mod events;
pub mod performance;
pub mod provider;
pub mod providers;
pub mod registry;
pub mod tracing;
pub mod tui;
pub use builder::CuenvBuilder;
pub use cuenv_core::Result;
pub use provider::{Provider, RuntimeCapability, SecretCapability, SyncCapability};
pub use registry::ProviderRegistry;
use crate::cli::EXIT_OK;
pub struct Cuenv {
pub registry: ProviderRegistry,
}
impl Cuenv {
#[must_use]
pub fn builder() -> CuenvBuilder {
CuenvBuilder::new()
}
#[must_use]
pub fn with_defaults() -> Self {
Self::builder().with_defaults().build()
}
#[must_use]
pub fn build_sync_command(&self) -> clap::Command {
use clap::{Arg, Command};
let mut sync_cmd = Command::new("sync")
.about("Sync generated files from CUE configuration")
.arg(
Arg::new("path")
.long("path")
.short('p')
.help("Path to directory containing CUE files")
.default_value("."),
)
.arg(
Arg::new("package")
.long("package")
.help("Name of the CUE package to evaluate")
.default_value("cuenv"),
)
.arg(
Arg::new("dry-run")
.long("dry-run")
.help("Show what would be generated without writing files")
.action(clap::ArgAction::SetTrue)
.global(true),
)
.arg(
Arg::new("check")
.long("check")
.help("Check if files are in sync without making changes")
.action(clap::ArgAction::SetTrue)
.global(true),
)
.arg(
Arg::new("all")
.long("all")
.short('A')
.help("Sync all projects in the workspace")
.action(clap::ArgAction::SetTrue)
.global(true),
);
for provider in self.registry.sync_providers() {
sync_cmd = sync_cmd.subcommand(provider.build_sync_command());
}
sync_cmd
}
#[doc(hidden)]
pub fn run(self) -> Result<()> {
let exit_code = run_cli_with_registry(self);
if exit_code == EXIT_OK {
Ok(())
} else {
Err(cuenv_core::Error::configuration(format!(
"Command failed with exit code {exit_code}"
)))
}
}
}
fn run_cli_with_registry(_cuenv: Cuenv) -> i32 {
EXIT_OK
}
pub const EXIT_SIGINT: i32 = 130;
pub const LLMS_CONTENT: &str = include_str!(concat!(env!("OUT_DIR"), "/llms-full.txt"));
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cuenv_builder() {
let cuenv = Cuenv::builder().build();
assert!(cuenv.registry.is_empty());
}
#[test]
fn test_cuenv_with_defaults() {
let cuenv = Cuenv::with_defaults();
assert_eq!(cuenv.registry.sync_provider_count(), 3);
}
#[test]
fn test_dynamic_sync_command() {
let cuenv = Cuenv::with_defaults();
let sync_cmd = cuenv.build_sync_command();
let subcommands: Vec<_> = sync_cmd.get_subcommands().map(|c| c.get_name()).collect();
assert!(subcommands.contains(&"ci"), "Missing 'ci' subcommand");
assert!(
subcommands.contains(&"codegen"),
"Missing 'codegen' subcommand"
);
assert!(subcommands.contains(&"rules"), "Missing 'rules' subcommand");
}
#[test]
fn test_dynamic_sync_command_empty_registry() {
let cuenv = Cuenv::builder().build();
let sync_cmd = cuenv.build_sync_command();
let subcommand_count = sync_cmd.get_subcommands().count();
assert_eq!(subcommand_count, 0);
}
#[test]
fn test_run_with_empty_registry() {
let cuenv = Cuenv::builder().build();
let result = cuenv.run();
assert!(result.is_ok());
}
#[test]
fn test_run_with_defaults() {
let cuenv = Cuenv::with_defaults();
let result = cuenv.run();
assert!(result.is_ok());
}
#[test]
fn test_exit_sigint_constant() {
assert_eq!(EXIT_SIGINT, 130);
}
#[test]
#[allow(clippy::const_is_empty)]
fn test_llms_content_not_empty() {
assert!(!LLMS_CONTENT.is_empty());
}
#[test]
fn test_sync_command_has_path_arg() {
let cuenv = Cuenv::with_defaults();
let sync_cmd = cuenv.build_sync_command();
let args: Vec<_> = sync_cmd
.get_arguments()
.map(|a| a.get_id().as_str())
.collect();
assert!(args.contains(&"path"));
assert!(args.contains(&"package"));
assert!(args.contains(&"dry-run"));
assert!(args.contains(&"check"));
assert!(args.contains(&"all"));
}
#[test]
fn test_run_cli_with_registry_returns_ok() {
let exit_code = run_cli_with_registry(Cuenv::builder().build());
assert_eq!(exit_code, EXIT_OK);
}
}