sqlx_migrate/gen/
build_rs.rs

1use crate::DatabaseType;
2use proc_macro2::{Ident, Span};
3use std::{fs, path::Path};
4use syn::parse_quote;
5use walkdir::WalkDir;
6
7/// Generate Rust code from a migrations directory.
8/// It is meant to be used in `build.rs`.
9///
10/// # Panics
11///
12/// This function is meant to be used in `build.rs` and will panic on errors.
13pub fn generate(
14    migrations_dir: impl AsRef<Path>,
15    module_path: impl AsRef<Path>,
16    db_type: DatabaseType,
17) {
18    cargo_rerun(migrations_dir.as_ref());
19
20    let modules = super::migration_modules(migrations_dir.as_ref());
21    let migrations = super::migrations(db_type, migrations_dir.as_ref());
22
23    if let Some(p) = module_path.as_ref().parent() {
24        fs::create_dir_all(p).unwrap();
25    }
26
27    let db_ident = Ident::new(db_type.sqlx_type(), Span::call_site());
28
29    fs::write(
30        module_path,
31        prettyplease::unparse(&parse_quote! {
32            pub use sqlx_migrate::prelude::*;
33
34            #modules
35
36            /// All the migrations.
37            pub fn migrations() -> impl IntoIterator<Item = Migration<sqlx::#db_ident>> {
38                #migrations
39            }
40
41        }),
42    )
43    .unwrap();
44}
45
46fn cargo_rerun(dir: &Path) {
47    for entry in WalkDir::new(dir) {
48        let Ok(entry) = entry else { continue };
49        println!("cargo:rerun-if-changed={}", entry.path().to_string_lossy());
50    }
51}