Refactor buster-cli: Simplify Deploy command by removing parameters, update deploy function signature, and enhance model file handling with new data structures for YAML parsing. Cleaned up init function and removed unnecessary comments.

This commit is contained in:
Dallin Bentley 2024-11-26 10:47:43 -07:00
parent d616f98c90
commit 1f6e6c68c6
4 changed files with 88 additions and 59 deletions

View File

@ -1,5 +1,6 @@
use anyhow::Result;
pub async fn deploy(dbt_only: bool, buster_only: bool) -> Result<()> {
pub async fn deploy() -> Result<()> {
Ok(())
}

View File

@ -1,5 +1,5 @@
use anyhow::Result;
use inquire::{MultiSelect, Select};
use inquire::MultiSelect;
use ratatui::style::Stylize;
use tokio::task::JoinSet;
@ -16,14 +16,6 @@ fn print_error(msg: &str) {
println!("{}", msg.red().bold());
}
/// Check to make sure that the appropriate credentials are in.
/// Check to see if an existing dbt project exists.
/// - If it does, ask if they want to use it for Buster
/// - If yes:
/// -
/// - If no, as if no dbt exists
/// - If not, create a new example project
pub async fn init() -> Result<()> {
if let Err(e) = check_dbt_installation().await {
print_error("Error: Failed to check dbt installation");

View File

@ -15,12 +15,7 @@ pub enum Commands {
Auth,
Generate,
Import,
Deploy {
#[arg(long, default_value = "false")]
dbt_only: bool,
#[arg(long, default_value = "false")]
buster_only: bool,
},
Deploy,
}
#[derive(Parser)]
@ -39,10 +34,7 @@ async fn main() {
Commands::Auth => auth().await,
Commands::Generate => generate().await,
Commands::Import => import().await,
Commands::Deploy {
dbt_only,
buster_only,
} => deploy(dbt_only, buster_only).await,
Commands::Deploy => deploy().await,
};
if let Err(e) = result {

View File

@ -1,49 +1,93 @@
use anyhow::Result;
use serde_yaml::{Mapping, Value};
pub fn convert_buster_to_dbt_model(buster_yaml: &str) -> Result<String, anyhow::Error> {
let mut yaml_value: Value = serde_yaml::from_str(buster_yaml)?;
if let Value::Mapping(ref mut map) = yaml_value {
if let Some(Value::Sequence(semantic_models)) = map.get_mut("semantic_models") {
for model in semantic_models.iter_mut() {
if let Value::Mapping(model_map) = model {
// Remove Buster-specific fields
model_map.remove("aliases");
// Clean up entities
if let Some(Value::Sequence(entities)) = model_map.get_mut("entities") {
for entity in entities.iter_mut() {
if let Value::Mapping(entity_map) = entity {
entity_map.remove("join_type");
entity_map.remove("relationship_type");
}
}
}
use serde::{Deserialize, Serialize};
use tokio::fs;
// Clean up dimensions
if let Some(Value::Sequence(dimensions)) = model_map.get_mut("dimensions") {
for dim in dimensions.iter_mut() {
if let Value::Mapping(dim_map) = dim {
dim_map.remove("searchable");
dim_map.remove("alias");
dim_map.remove("timezone");
dim_map.remove("sql");
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BusterModelObject {
pub sql_definition: String,
pub model_file: BusterModel,
}
// Clean up measures
if let Some(Value::Sequence(measures)) = model_map.get_mut("measures") {
for measure in measures.iter_mut() {
if let Value::Mapping(measure_map) = measure {
measure_map.remove("alias");
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BusterModel {
pub version: i32,
pub semantic_models: Vec<SemanticModel>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SemanticModel {
pub name: String,
pub defaults: ModelDefaults,
pub description: String,
pub model: String,
pub entities: Vec<Entity>,
pub dimensions: Vec<Dimension>,
pub measures: Vec<Measure>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ModelDefaults {
pub agg_time_dimension: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Entity {
pub name: String,
pub expr: String,
#[serde(rename = "type")]
pub entity_type: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Dimension {
pub name: String,
pub expr: String,
#[serde(rename = "type")]
pub dimension_type: String,
pub description: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Measure {
pub name: String,
pub expr: String,
pub agg: String,
pub description: String,
}
pub async fn get_model_files() -> Result<Vec<BusterModelObject>> {
let mut model_objects = Vec::new();
// Walk through models directory recursively
let models_dir = std::path::Path::new("models");
let mut dir = tokio::fs::read_dir(models_dir).await?;
while let Some(entry) = dir.next_entry().await? {
let path = entry.path();
// Check if this is a .yml file
if let Some(ext) = path.extension() {
if ext == "yml" {
// Get corresponding .sql file path
let sql_path = path.with_extension("sql");
if sql_path.exists() {
// Read SQL definition
let sql_definition = tokio::fs::read_to_string(&sql_path).await?;
// Parse YAML into BusterModel
let yaml_content = fs::read_to_string(path).await?;
let model: BusterModel = serde_yaml::from_str(&yaml_content)?;
model_objects.push(BusterModelObject {
sql_definition,
model_file: model,
});
}
}
}
}
Ok(serde_yaml::to_string(&yaml_value)?)
Ok(model_objects)
}