feat: teach macros about migrate.table-name, migrations-dir

This commit is contained in:
Austin Bonander 2024-09-23 02:06:46 -07:00
parent 65ef27f70c
commit 9d1bc64ced
4 changed files with 39 additions and 18 deletions

View File

@ -3,12 +3,15 @@ extern crate proc_macro;
use std::path::{Path, PathBuf};
use proc_macro2::TokenStream;
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::LitStr;
use syn::spanned::Spanned;
use sqlx_core::config::Config;
use sqlx_core::migrate::{Migration, MigrationType};
pub const DEFAULT_PATH: &str = "./migrations";
pub struct QuoteMigrationType(MigrationType);
impl ToTokens for QuoteMigrationType {
@ -81,20 +84,26 @@ impl ToTokens for QuoteMigration {
}
}
pub fn expand_migrator_from_lit_dir(dir: LitStr) -> crate::Result<TokenStream> {
expand_migrator_from_dir(&dir.value(), dir.span())
pub fn default_path(config: &Config) -> &str {
config.migrate.migrations_dir
.as_deref()
.unwrap_or(DEFAULT_PATH)
}
pub(crate) fn expand_migrator_from_dir(
dir: &str,
err_span: proc_macro2::Span,
) -> crate::Result<TokenStream> {
let path = crate::common::resolve_path(dir, err_span)?;
pub fn expand(path_arg: Option<LitStr>) -> crate::Result<TokenStream> {
let config = Config::from_crate();
expand_migrator(&path)
let path = match path_arg {
Some(path_arg) => crate::common::resolve_path(path_arg.value(), path_arg.span())?,
None => {
crate::common::resolve_path(default_path(config), Span::call_site())
}?
};
expand_with_path(config, &path)
}
pub(crate) fn expand_migrator(path: &Path) -> crate::Result<TokenStream> {
pub fn expand_with_path(config: &Config, path: &Path) -> crate::Result<TokenStream> {
let path = path.canonicalize().map_err(|e| {
format!(
"error canonicalizing migration directory {}: {e}",
@ -119,11 +128,19 @@ pub(crate) fn expand_migrator(path: &Path) -> crate::Result<TokenStream> {
proc_macro::tracked_path::path(path);
}
let table_name = config.migrate.table_name
.as_deref()
.map_or_else(
|| quote! {},
|name| quote! { table_name: Some(::std::borrow::Cow::Borrowed(#name)), }
);
Ok(quote! {
::sqlx::migrate::Migrator {
migrations: ::std::borrow::Cow::Borrowed(&[
#(#migrations),*
]),
#table_name
..::sqlx::migrate::Migrator::DEFAULT
}
})

View File

@ -77,6 +77,8 @@ fn expand_simple(input: syn::ItemFn) -> TokenStream {
#[cfg(feature = "migrate")]
fn expand_advanced(args: AttributeArgs, input: syn::ItemFn) -> crate::Result<TokenStream> {
let config = sqlx_core::config::Config::from_crate();
let ret = &input.sig.output;
let name = &input.sig.ident;
let inputs = &input.sig.inputs;
@ -143,15 +145,17 @@ fn expand_advanced(args: AttributeArgs, input: syn::ItemFn) -> crate::Result<Tok
let migrations = match args.migrations {
MigrationsOpt::ExplicitPath(path) => {
let migrator = crate::migrate::expand_migrator_from_lit_dir(path)?;
let migrator = crate::migrate::expand(Some(path))?;
quote! { args.migrator(&#migrator); }
}
MigrationsOpt::InferredPath if !inputs.is_empty() => {
let migrations_path =
crate::common::resolve_path("./migrations", proc_macro2::Span::call_site())?;
let path = crate::migrate::default_path(config);
if migrations_path.is_dir() {
let migrator = crate::migrate::expand_migrator(&migrations_path)?;
let resolved_path =
crate::common::resolve_path(path, proc_macro2::Span::call_site())?;
if resolved_path.is_dir() {
let migrator = crate::migrate::expand_with_path(config, &resolved_path)?;
quote! { args.migrator(&#migrator); }
} else {
quote! {}

View File

@ -69,7 +69,7 @@ pub fn migrate(input: TokenStream) -> TokenStream {
use syn::LitStr;
let input = syn::parse_macro_input!(input as LitStr);
match migrate::expand_migrator_from_lit_dir(input) {
match migrate::expand(input) {
Ok(ts) => ts.into(),
Err(e) => {
if let Some(parse_err) = e.downcast_ref::<syn::Error>() {

View File

@ -814,6 +814,6 @@ macro_rules! migrate {
}};
() => {{
$crate::sqlx_macros::migrate!("./migrations")
$crate::sqlx_macros::migrate!()
}};
}