diff options
author | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-12-13 13:56:14 -0700 |
---|---|---|
committer | Colin Reeder <vpzomtrrfrt@gmail.com> | 2020-12-13 13:56:14 -0700 |
commit | 38ef280da222eb7a7b08380127f1078c785128ec (patch) | |
tree | 5472a178e3d51b4a04464bcc83a729e4ad22c6d1 | |
parent | a07ab6ad7258d12ee1586ab51cdd159982278f95 (diff) |
Embed migrations into build (#96)
-rw-r--r-- | Cargo.lock | 183 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | build.rs | 34 | ||||
-rw-r--r-- | src/main.rs | 15 | ||||
-rw-r--r-- | src/migrate.rs | 96 |
5 files changed, 310 insertions, 19 deletions
@@ -26,6 +26,21 @@ dependencies = [ ] [[package]] +name = "addr2line" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] name = "ahash" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -94,6 +109,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" [[package]] +name = "backtrace" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] name = "base64" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -219,6 +248,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] name = "chrono" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -297,7 +332,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "crossbeam-utils", "maybe-uninit", ] @@ -309,7 +344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -330,7 +365,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f260e2fc850179ef410018660006951c1b55b79e8087e87111a2c388994b9b5" dependencies = [ "ahash", - "cfg-if", + "cfg-if 0.1.10", "num_cpus", ] @@ -400,7 +435,17 @@ version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "backtrace", + "version_check", ] [[package]] @@ -662,7 +707,7 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi", ] @@ -673,12 +718,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee8025cf36f917e6a52cce185b7c7177689b838b7ec138364e50cc2277a56cf4" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "wasi", ] [[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + +[[package]] name = "h2" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1003,7 +1054,7 @@ checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616" dependencies = [ "arrayvec", "bitflags", - "cfg-if", + "cfg-if 0.1.10", "ryu", "static_assertions", ] @@ -1029,7 +1080,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -1038,7 +1089,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "generator", "scoped-tls", ] @@ -1071,6 +1122,7 @@ dependencies = [ "hyper-tls", "lazy_static", "lettre", + "migrant_lib", "mime", "openssl", "pdcm-linkify", @@ -1166,6 +1218,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" [[package]] +name = "migrant_lib" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd763657dd793f0cfb3f5e5e1eb754bf56c38b5bc964696ebc4573cdfd0c240" +dependencies = [ + "chrono", + "error-chain", + "lazy_static", + "log", + "percent-encoding", + "postgres", + "regex", + "serde", + "serde_derive", + "serde_json", + "toml", + "url", + "walkdir", +] + +[[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1182,12 +1255,22 @@ dependencies = [ ] [[package]] +name = "miniz_oxide" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] name = "mio" version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "fuchsia-zircon", "fuchsia-zircon-sys", "iovec", @@ -1269,7 +1352,7 @@ version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "winapi 0.3.9", ] @@ -1321,6 +1404,12 @@ dependencies = [ ] [[package]] +name = "object" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" + +[[package]] name = "once_cell" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1345,7 +1434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" dependencies = [ "bitflags", - "cfg-if", + "cfg-if 0.1.10", "foreign-types", "lazy_static", "libc", @@ -1388,7 +1477,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "cloudabi", "instant", "libc", @@ -1489,6 +1578,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" [[package]] +name = "postgres" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14d864cf6c2eabf1323afe4145ff273aad1898e4f2a3bcb30347715df8624a07" +dependencies = [ + "bytes", + "fallible-iterator", + "futures", + "log", + "tokio", + "tokio-postgres", +] + +[[package]] name = "postgres-protocol" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1734,6 +1837,12 @@ dependencies = [ ] [[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + +[[package]] name = "rustc_version" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1749,6 +1858,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] name = "schannel" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1879,7 +1997,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2933378ddfeda7ea26f48c555bdad8bb446bf8a3d17832dc83e380d444cfb8c1" dependencies = [ "block-buffer 0.9.0", - "cfg-if", + "cfg-if 0.1.10", "cpuid-bool", "digest 0.9.0", "opaque-debug 0.3.0", @@ -1919,7 +2037,7 @@ version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_syscall", "winapi 0.3.9", @@ -1995,7 +2113,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "rand", "redox_syscall", @@ -2157,6 +2275,15 @@ dependencies = [ ] [[package]] +name = "toml" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cf45bb0bef80604d001caaec0d09da99611b3c0fd39d3080468875cdb65645" +dependencies = [ + "serde", +] + +[[package]] name = "tower-service" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2321,6 +2448,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] +name = "walkdir" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + +[[package]] name = "want" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2342,7 +2480,7 @@ version = "0.2.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "serde", "serde_json", "wasm-bindgen-macro", @@ -2369,7 +2507,7 @@ version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "js-sys", "wasm-bindgen", "web-sys", @@ -2443,6 +2581,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -51,6 +51,7 @@ ammonia = "3.1.0" base64 = "0.13.0" pdcm-linkify = { git = "https://git.sr.ht/~vpzom/pdcm-linkify", rev = "18c43df5" } pulldown-cmark = "0.8.0" +migrant_lib = { version = "0.30.0", features = ["d-postgres"] } [dev-dependencies] rand = "0.7.3" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..8382002 --- /dev/null +++ b/build.rs @@ -0,0 +1,34 @@ +use std::io::Write; + +const MIGRATIONS_DIR: &str = "migrations"; + +fn main() -> Result<(), Box<dyn std::error::Error>> { + println!("cargo:rerun-if-changed={}", MIGRATIONS_DIR); + + let out_dir = std::env::var("OUT_DIR")?; + let mut out_file = std::fs::File::create(std::path::Path::new(&out_dir).join("migrations.rs"))?; + writeln!(out_file, "&[")?; + + let paths: Result<Vec<_>, _> = std::fs::read_dir(MIGRATIONS_DIR)?.collect(); + let mut paths = paths?; + + paths.sort_by_cached_key(|entry| entry.file_name()); + + for entry in paths { + let filename = entry.file_name(); + let tag = filename.to_str().unwrap(); + + let path = entry.path().canonicalize()?; + let path = path.to_str().unwrap(); + + writeln!( + out_file, + r##"StaticMigration {{ tag: r#"{}"#, up: include_str!(r#"{1}/up.sql"#), down: include_str!(r#"{1}/down.sql"#) }},"##, + tag, path + )?; + } + + write!(out_file, "]")?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index c0dff37..592bd36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use trout::hyper::RoutingFailureExtHyper; mod apub_util; +mod migrate; mod routes; mod tasks; mod worker; @@ -906,8 +907,20 @@ pub fn on_post_add_comment(comment: CommentInfo<'static>, ctx: Arc<crate::RouteC }); } +fn main() -> Result<(), Box<dyn std::error::Error>> { + let mut args = std::env::args(); + args.next(); // discard first element + match args.next().as_deref() { + Some("migrate") => Ok(crate::migrate::run(args)), + None => run(), + _ => { + panic!("Unexpected argument"); + } + } +} + #[tokio::main] -async fn main() -> Result<(), Box<dyn std::error::Error>> { +async fn run() -> Result<(), Box<dyn std::error::Error>> { let host_url_apub = std::env::var("HOST_URL_ACTIVITYPUB").expect("Missing HOST_URL_ACTIVITYPUB"); diff --git a/src/migrate.rs b/src/migrate.rs new file mode 100644 index 0000000..1d2ccd0 --- /dev/null +++ b/src/migrate.rs @@ -0,0 +1,96 @@ +pub const MIGRATIONS: &[StaticMigration] = include!(concat!(env!("OUT_DIR"), "/migrations.rs")); + +pub struct StaticMigration { + tag: &'static str, + up: &'static str, + down: &'static str, +} + +pub fn run(mut args: std::env::Args) { + let action = args.next(); + let action = action.as_deref().unwrap_or("up"); + + let database_url = std::env::var("DATABASE_URL").expect("Missing DATABASE_URL"); + let db_cfg: tokio_postgres::Config = + database_url.parse().expect("Failed to parse DATABASE_URL"); + + let mut settings = migrant_lib::Settings::configure_postgres(); + settings + .database_name(db_cfg.get_dbname().expect("Missing dbname")) + .database_user(db_cfg.get_user().expect("Missing user")) + .database_password( + std::str::from_utf8(db_cfg.get_password().expect("Missing password")).unwrap(), + ); + + let hosts = db_cfg.get_hosts(); + if !hosts.is_empty() { + let host = hosts + .iter() + .filter_map(|host| match host { + tokio_postgres::config::Host::Tcp(hostname) => Some(hostname), + _ => None, + }) + .next(); + + match host { + None => panic!("Unsupported host type"), + Some(hostname) => { + settings.database_host(hostname); + } + } + } + + let ports = db_cfg.get_ports(); + if !ports.is_empty() { + if ports.len() == 1 { + settings.database_port(ports[0]); + } else { + panic!("Multiple ports are not supported"); + } + } + + let settings = settings.build().unwrap(); + + let mut config = migrant_lib::Config::with_settings(&settings); + config.use_cli_compatible_tags(true); + + if action == "setup" { + config.setup().expect("Failed to setup database"); + } else { + let migrations: Vec<_> = MIGRATIONS + .iter() + .map(|item| { + migrant_lib::EmbeddedMigration::with_tag(item.tag) + .up(item.up) + .down(item.down) + .boxed() + }) + .collect(); + config + .use_migrations(&migrations) + .expect("Failed to initialize migrations"); + + let config = config.reload().expect("Failed to check status"); + + match action { + "up" => { + println!("Applying migrations..."); + migrant_lib::Migrator::with_config(&config) + .all(true) + .swallow_completion(true) + .apply() + .expect("Failed to apply migrations"); + } + "down" => { + println!("Unapplying migration..."); + migrant_lib::Migrator::with_config(&config) + .direction(migrant_lib::Direction::Down) + .all(false) + .swallow_completion(true) + .apply() + .expect("Failed to undo migration"); + } + _ => panic!("Unknown migrate action"), + } + } +} |