summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Reeder <vpzomtrrfrt@gmail.com>2020-12-13 13:56:14 -0700
committerColin Reeder <vpzomtrrfrt@gmail.com>2020-12-13 13:56:14 -0700
commit38ef280da222eb7a7b08380127f1078c785128ec (patch)
tree5472a178e3d51b4a04464bcc83a729e4ad22c6d1
parenta07ab6ad7258d12ee1586ab51cdd159982278f95 (diff)
Embed migrations into build (#96)
-rw-r--r--Cargo.lock183
-rw-r--r--Cargo.toml1
-rw-r--r--build.rs34
-rw-r--r--src/main.rs15
-rw-r--r--src/migrate.rs96
5 files changed, 310 insertions, 19 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 9b32e2c..7199d93 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 74536d4..85b0b7f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"),
+ }
+ }
+}