Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions cot-cli/src/migration_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use cot::db::migrations::{DynMigration, MigrationEngine};
use cot_codegen::model::{Field, Model, ModelArgs, ModelOpts, ModelType};
use cot_codegen::symbol_resolver::SymbolResolver;
use darling::FromMeta;
use heck::ToSnakeCase;
use petgraph::graph::DiGraph;
use petgraph::visit::EdgeRef;
use proc_macro2::TokenStream;
Expand Down Expand Up @@ -280,8 +281,12 @@ impl MigrationGenerator {
symbol_resolver.resolve_struct(&mut item);

let args = Self::model_args_from_attr(&path, attr)?;
let model_in_source =
ModelInSource::from_item(item, &args, &symbol_resolver)?;
let model_in_source = ModelInSource::from_item(
self.crate_name.as_str(),
item,
&args,
&symbol_resolver,
)?;

match args.model_type {
ModelType::Application => {
Expand Down Expand Up @@ -892,14 +897,16 @@ pub struct ModelInSource {

impl ModelInSource {
fn from_item(
app_name: &str,
item: syn::ItemStruct,
args: &ModelArgs,
symbol_resolver: &SymbolResolver,
) -> anyhow::Result<Self> {
let input: syn::DeriveInput = item.clone().into();
let opts = ModelOpts::new_from_derive_input(&input)
.map_err(|e| anyhow::anyhow!("cannot parse model: {}", e))?;
let model = opts.as_model(args, symbol_resolver)?;
let mut model = opts.as_model(args, symbol_resolver)?;
model.table_name = format!("{}__{}", app_name.to_snake_case(), model.table_name);

Ok(Self {
model_item: item,
Expand Down
24 changes: 12 additions & 12 deletions cot-cli/tests/migration_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ fn create_model_state_test() {
assert!(migration.dependencies.is_empty());

let (table_name, fields) = unwrap_create_model(&migration.operations[0]);
assert_eq!(table_name, "parent");
assert_eq!(table_name, "cot__parent");
assert_eq!(fields.len(), 1);

let (table_name, fields) = unwrap_create_model(&migration.operations[1]);
assert_eq!(table_name, "my_model");
assert_eq!(table_name, "cot__my_model");
assert_eq!(fields.len(), 4);

let field = &fields[0];
Expand Down Expand Up @@ -76,11 +76,11 @@ fn create_models_foreign_key() {

// Parent must be created before Child
let (table_name, fields) = unwrap_create_model(&migration.operations[0]);
assert_eq!(table_name, "parent");
assert_eq!(table_name, "cot__parent");
assert_eq!(fields.len(), 1);

let (table_name, fields) = unwrap_create_model(&migration.operations[1]);
assert_eq!(table_name, "child");
assert_eq!(table_name, "cot__child");
assert_eq!(fields.len(), 2);

let field = &fields[0];
Expand Down Expand Up @@ -112,15 +112,15 @@ fn create_models_foreign_key_cycle() {

// Parent must be created before Child
let (table_name, fields) = unwrap_create_model(&migration.operations[0]);
assert_eq!(table_name, "parent");
assert_eq!(table_name, "cot__parent");
assert_eq!(fields.len(), 1);

let (table_name, fields) = unwrap_create_model(&migration.operations[1]);
assert_eq!(table_name, "child");
assert_eq!(table_name, "cot__child");
assert_eq!(fields.len(), 2);

let (table_name, field) = unwrap_add_field(&migration.operations[2]);
assert_eq!(table_name, "parent");
assert_eq!(table_name, "cot__parent");
assert_eq!(field.field_name, "child");
}

Expand All @@ -147,7 +147,7 @@ fn create_models_foreign_key_two_migrations() {

assert_eq!(migration.dependencies.len(), 2);
assert!(migration.dependencies.contains(&DynDependency::Migration {
app: "my_crate".to_string(),
app: "cot".to_string(),
migration: "m_0001_initial".to_string()
}));
assert!(migration.dependencies.contains(&DynDependency::Model {
Expand All @@ -157,7 +157,7 @@ fn create_models_foreign_key_two_migrations() {
assert_eq!(migration.operations.len(), 1);

let (table_name, _fields) = unwrap_create_model(&migration.operations[0]);
assert_eq!(table_name, "child");
assert_eq!(table_name, "cot__child");
}

/// Test that the migration generator can generate a "create model" migration
Expand Down Expand Up @@ -203,9 +203,9 @@ fn write_migrations_module() {

let generator = MigrationGenerator::new(
PathBuf::from("Cargo.toml"),
String::from("my_crate"),
String::from("cot"),
MigrationGeneratorOptions {
app_name: Some("my_crate".to_string()),
app_name: Some("cot".to_string()),
output_dir: Some(tempdir.path().to_path_buf()),
},
);
Expand Down Expand Up @@ -304,7 +304,7 @@ fn list_migrations_missing_migrations_dir() {
fn test_generator() -> MigrationGenerator {
MigrationGenerator::new(
PathBuf::from("Cargo.toml"),
String::from("my_crate"),
String::from("cot"),
MigrationGeneratorOptions::default(),
)
}
Expand Down
24 changes: 15 additions & 9 deletions cot-cli/tests/snapshot_testing/migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ const EXAMPLE_DATABASE_MODEL: &str = include_str!("../../resources/example_datab
#[expect(clippy::cast_possible_truncation)]
fn migration_list_empty() {
let temp_dir = tempfile::TempDir::with_prefix("cot-test-").unwrap();
test_utils::make_package(temp_dir.path()).unwrap();
let proj_path = temp_dir.path().join("cot-test");

test_utils::make_package(&proj_path).unwrap();

let mut cmd = cot_cli!("migration", "list");
cmd.current_dir(temp_dir.path());
cmd.current_dir(&proj_path);

for (idx, mut cli) in cot_clis_with_verbosity(&cmd).into_iter().enumerate() {
let filter = Verbosity::<OffLevel>::new(idx as u8, 0).filter();
Expand All @@ -31,14 +33,16 @@ fn migration_list_empty() {
#[expect(clippy::cast_possible_truncation)]
fn migration_list_existing() {
let temp_dir = tempfile::TempDir::with_prefix("cot-test-").unwrap();
test_utils::make_package(temp_dir.path()).unwrap();
let proj_path = temp_dir.path().join("cot-test");

test_utils::make_package(&proj_path).unwrap();
let mut main = std::fs::OpenOptions::new()
.append(true)
.open(temp_dir.path().join("src").join("main.rs"))
.open(proj_path.join("src").join("main.rs"))
.unwrap();
write!(main, "{EXAMPLE_DATABASE_MODEL}").unwrap();
migration_generator::make_migrations(
temp_dir.path(),
&proj_path,
MigrationGeneratorOptions {
app_name: None,
output_dir: None,
Expand All @@ -47,7 +51,7 @@ fn migration_list_existing() {
.unwrap();

let mut cmd = cot_cli!("migration", "list");
cmd.current_dir(temp_dir.path());
cmd.current_dir(&proj_path);

for (idx, mut cli) in cot_clis_with_verbosity(&cmd).into_iter().enumerate() {
let filter = Verbosity::<OffLevel>::new(idx as u8, 0).filter();
Expand Down Expand Up @@ -92,10 +96,12 @@ fn migration_make_existing_model() {
let filter = Verbosity::<OffLevel>::new(idx as u8, 0).filter();

let temp_dir = tempfile::TempDir::with_prefix("cot-test-").unwrap();
test_utils::make_package(temp_dir.path()).unwrap();
let proj_path = temp_dir.path().join("cot-test");

test_utils::make_package(&proj_path).unwrap();
let mut main = std::fs::OpenOptions::new()
.append(true)
.open(temp_dir.path().join("src").join("main.rs"))
.open(proj_path.join("src").join("main.rs"))
.unwrap();
write!(main, "{EXAMPLE_DATABASE_MODEL}").unwrap();

Expand All @@ -104,7 +110,7 @@ fn migration_make_existing_model() {
description => format!("Verbosity level: {filter}"),
filters => [GENERIC_FILTERS, TEMP_PATH_FILTERS, TEMP_PROJECT_FILTERS].concat()
},
{ assert_cmd_snapshot!(cli.current_dir(temp_dir.path())) }
{ assert_cmd_snapshot!(cli.current_dir(&proj_path)) }
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ info:
success: true
exit_code: 0
----- stdout -----
cot-test-PROJECT-NAME m_0001_initial
cot-test m_0001_initial

----- stderr -----
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ exit_code: 0
----- stdout -----

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ exit_code: 0
----- stdout -----

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ info:
success: true
exit_code: 0
----- stdout -----
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/src/main.rs"
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/cot-test/src/main.rs"

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ info:
success: true
exit_code: 0
----- stdout -----
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/src/main.rs"
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/cot-test/src/main.rs"
TIMESTAMP TRACE cot_cli::migration_generator: Processing file: "main.rs"
TIMESTAMP TRACE cot_cli::migration_generator: Found an Application model: Test

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ info:
success: true
exit_code: 0
----- stdout -----
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/src/main.rs"
TIMESTAMP DEBUG cot_cli::migration_generator: Parsing file: "/tmp/TEMP_PATH/cot-test/src/main.rs"
TIMESTAMP TRACE cot_cli::migration_generator: Processing file: "main.rs"
TIMESTAMP TRACE cot_cli::migration_generator: Found an Application model: Test

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ exit_code: 0
----- stdout -----

----- stderr -----
 Creating Model 'test'
 Created Model 'test'
 Creating Model 'cot_test__test'
 Created Model 'cot_test__test'
 Creating Migration 'm_0001_initial'
 Creating Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/src/migrations/m_0001_initial.rs'
 Creating Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration file '/tmp/TEMP_PATH/cot-test/src/migrations/m_0001_initial.rs'
 Created Migration 'm_0001_initial'
20 changes: 17 additions & 3 deletions cot-macros/src/model.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use cot_codegen::model::{Field, Model, ModelArgs, ModelOpts};
use cot_codegen::model::{Field, Model, ModelArgs, ModelOpts, ModelType};
use darling::FromMeta;
use darling::ast::NestedMeta;
use heck::ToSnakeCase;
use proc_macro2::{Ident, TokenStream};
use quote::{ToTokens, TokenStreamExt, format_ident, quote};
use syn::Token;
Expand Down Expand Up @@ -69,6 +70,7 @@ fn remove_helper_field_attributes(fields: &mut syn::Fields) -> &Punctuated<syn::

#[derive(Debug)]
struct ModelBuilder {
app_name: String,
name: Ident,
vis: syn::Visibility,
table_name: String,
Expand All @@ -91,10 +93,21 @@ impl ToTokens for ModelBuilder {
impl ModelBuilder {
fn from_model(model: Model) -> Self {
let field_count = model.field_count();
let app_name = std::env::var("CARGO_PKG_NAME")
.expect("cargo should set the `CARGO_PKG_NAME` environment variable");
let table_name = match model.model_type {
ModelType::Internal => model.table_name,
_ => format!(
"{}__{}",
app_name.to_snake_case(),
model.table_name.to_snake_case()
),
};
let mut model_builder = Self {
app_name,
name: model.name.clone(),
vis: model.vis,
table_name: model.table_name,
table_name,
pk_field: model.pk_field.clone(),
fields_struct_name: format_ident!("{}Fields", model.name),
fields_as_columns: Vec::with_capacity(field_count),
Expand Down Expand Up @@ -150,6 +163,7 @@ impl ModelBuilder {
let orm_ident = orm_ident();

let name = &self.name;
let app_name = &self.app_name;
let table_name = &self.table_name;
let fields_struct_name = &self.fields_struct_name;
let fields_as_columns = &self.fields_as_columns;
Expand All @@ -170,7 +184,7 @@ impl ModelBuilder {
const COLUMNS: &'static [#orm_ident::Column] = &[
#(#fields_as_columns,)*
];
const APP_NAME: &'static str = env!("CARGO_PKG_NAME");
const APP_NAME: &'static str = #app_name;
const TABLE_NAME: #orm_ident::Identifier = #orm_ident::Identifier::new(#table_name);
const PRIMARY_KEY_NAME: #orm_ident::Identifier = #orm_ident::Identifier::new(#pk_column_name);

Expand Down
Loading