diff --git a/.dockerignore b/.dockerignore index 9fe342c..1f5346b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ ./target +Dockerfile diff --git a/Cargo.lock b/Cargo.lock index 315ea66..24df36e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aead" version = "0.2.0" @@ -120,6 +135,7 @@ dependencies = [ "eyre", "fern", "fork", + "human-panic", "indicatif", "itertools", "log 0.4.14", @@ -150,6 +166,20 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "backtrace" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.9.3" @@ -822,6 +852,12 @@ dependencies = [ "polyval", ] +[[package]] +name = "gimli" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" + [[package]] name = "glob" version = "0.3.0" @@ -937,6 +973,21 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +[[package]] +name = "human-panic" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f357a500abcbd7c5f967c1d45c8838585b36743823b9d43488f24850534e36" +dependencies = [ + "backtrace", + "os_type", + "serde 1.0.125", + "serde_derive", + "termcolor", + "toml 0.5.8", + "uuid", +] + [[package]] name = "hyper" version = "0.10.16" @@ -1261,6 +1312,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "mio" version = "0.6.23" @@ -1501,6 +1562,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" +[[package]] +name = "object" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" + [[package]] name = "once_cell" version = "1.5.2" @@ -1546,6 +1613,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_type" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edc011af0ae98b7f88cf7e4a83b70a54a75d2b8cb013d6efd02e5956207e9eb" +dependencies = [ + "regex", +] + [[package]] name = "parking_lot" version = "0.11.1" @@ -2142,6 +2218,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" +[[package]] +name = "rustc-demangle" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" + [[package]] name = "rustc-serialize" version = "0.3.24" diff --git a/Cargo.toml b/Cargo.toml index 9d33787..66955c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ fork = "0.1.18" parse_duration = "2.1.1" rand = "0.8.3" rust-crypto = "^0.2" +human-panic = "1.0.3" [dependencies.rusqlite] version = "0.25" diff --git a/Dockerfile b/Dockerfile index 4ef5f15..774468e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,34 @@ -# no point in tagging the rust version, currently using nightly -FROM rust:slim-buster +FROM rust as builder -RUN apt update && apt -y install libssl-dev libpq-dev pkg-config make RUN rustup default nightly + +RUN cargo new --bin atuin WORKDIR /atuin -COPY . /atuin +COPY ./Cargo.toml ./Cargo.toml +COPY ./Cargo.lock ./Cargo.lock RUN cargo build --release -ENTRYPOINT ["/atuin/target/release/atuin"] +RUN rm src/*.rs + +ADD . ./ + +RUN rm ./target/release/deps/atuin* +RUN cargo build --release + +FROM debian:buster-slim + +RUN apt-get update \ + && apt-get install -y ca-certificates tzdata libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +EXPOSE 8888 + +ENV TZ=Etc/UTC +ENV RUST_LOG=info +ENV ATUIN_CONFIG=/config/config.toml + +COPY --from=builder /atuin/target/release/atuin ./atuin + +ENTRYPOINT ["./atuin"] diff --git a/README.md b/README.md index 7874789..76289fa 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
Through the fathomless deeps of space swims the star turtle Great A’Tuin, bearing on its back the four giant elephants who carry on their shoulders the mass of the Discworld. @@ -12,11 +12,11 @@ -A'tuin manages and synchronizes your shell history! Instead of storing -everything in a text file (such as ~/.history), A'tuin uses a sqlite database. +A'Tuin manages and synchronizes your shell history! Instead of storing +everything in a text file (such as ~/.history), A'Tuin uses a sqlite database. While being a little more complex, this allows for more functionality. -As well as the expected command, A'tuin stores +As well as the expected command, A'Tuin stores - duration - exit code @@ -33,7 +33,7 @@ As well as the expected command, A'tuin stores ### AUR -A'tuin is available on the [AUR](https://aur.archlinux.org/packages/atuin/) +A'Tuin is available on the [AUR](https://aur.archlinux.org/packages/atuin/) ``` yay -S atuin # or your AUR helper of choice @@ -73,7 +73,7 @@ to your `.zshrc`/`.bashrc`/whatever your shell uses. ### History search -By default A'tuin will rebind ctrl-r and the up arrow to search your history. +By default A'Tuin will rebind ctrl-r and the up arrow to search your history. You can prevent this by putting @@ -119,7 +119,7 @@ atuin h l -s # similarly short ### Stats -A'tuin can calculate statistics for a single day, and accepts "natural language" style date input, as well as absolute dates: +A'Tuin can calculate statistics for a single day, and accepts "natural language" style date input, as well as absolute dates: ``` $ atuin stats day last friday @@ -155,7 +155,7 @@ $ atuin stats all ## Config -A'tuin is configurable via TOML. The file lives at ` ~/.config/atuin/config.toml`, +A'Tuin is configurable via TOML. The file lives at ` ~/.config/atuin/config.toml`, and looks like this: ``` @@ -169,5 +169,5 @@ path = "~/.local/share/atuin/history.db" # the local database for history ## ...what's with the name? -A'tuin is named after "The Great A'tuin", a giant turtle from Terry Pratchett's +A'Tuin is named after "The Great A'Tuin", a giant turtle from Terry Pratchett's Discworld series of books. diff --git a/src/command/server.rs b/src/command/server.rs index ba2a9a2..bf75794 100644 --- a/src/command/server.rs +++ b/src/command/server.rs @@ -29,9 +29,8 @@ impl Cmd { ); let port = port.map_or(settings.server.port, |p| p); - server::launch(settings, host, port); + server::launch(settings, host, port) } } - Ok(()) } } diff --git a/src/main.rs b/src/main.rs index ae45980..94c7366 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use eyre::{eyre, Result}; +use human_panic::setup_panic; use structopt::{clap::AppSettings, StructOpt}; #[macro_use] @@ -73,6 +74,7 @@ impl Atuin { } fn main() -> Result<()> { + setup_panic!(); let settings = Settings::new()?; fern::Dispatch::new() diff --git a/src/remote/database.rs b/src/remote/database.rs index ddcffda..03973ca 100644 --- a/src/remote/database.rs +++ b/src/remote/database.rs @@ -1,5 +1,6 @@ use diesel::pg::PgConnection; use diesel::prelude::*; +use eyre::{eyre, Result}; use crate::settings::Settings; @@ -7,8 +8,15 @@ use crate::settings::Settings; pub struct AtuinDbConn(diesel::PgConnection); // TODO: connection pooling -pub fn establish_connection(settings: &Settings) -> PgConnection { - let database_url = &settings.server.db_uri; - PgConnection::establish(database_url) - .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) +pub fn establish_connection(settings: &Settings) -> Result{ + if settings.server.db_uri == "default_uri" { + Err(eyre!( + "Please configure your database! Set db_uri in config.toml" + )) + } else { + let database_url = &settings.server.db_uri; + let conn = PgConnection::establish(database_url)?; + + Ok(conn) + } } diff --git a/src/remote/server.rs b/src/remote/server.rs index de58397..ee481ca 100644 --- a/src/remote/server.rs +++ b/src/remote/server.rs @@ -1,5 +1,3 @@ -use rocket::config::{Config, Environment, LoggingLevel, Value}; - use std::collections::HashMap; use crate::remote::database::establish_connection; @@ -7,6 +5,9 @@ use crate::settings::Settings; use super::database::AtuinDbConn; +use eyre::Result; +use rocket::config::{Config, Environment, LoggingLevel, Value}; + // a bunch of these imports are generated by macros, it's easier to wildcard #[allow(clippy::clippy::wildcard_imports)] use super::views::*; @@ -16,7 +17,7 @@ use super::auth::*; embed_migrations!("migrations"); -pub fn launch(settings: &Settings, host: String, port: u16) { +pub fn launch(settings: &Settings, host: String, port: u16) -> Result<()> { let settings: Settings = settings.clone(); // clone so rocket can manage it let mut database_config = HashMap::new(); @@ -25,7 +26,8 @@ pub fn launch(settings: &Settings, host: String, port: u16) { database_config.insert("url", Value::from(settings.server.db_uri.clone())); databases.insert("atuin", Value::from(database_config)); - let connection = establish_connection(&settings); + let connection = establish_connection(&settings)?; + embedded_migrations::run(&connection).expect("failed to run migrations"); let config = Config::build(Environment::Production) @@ -54,4 +56,6 @@ pub fn launch(settings: &Settings, host: String, port: u16) { .attach(AtuinDbConn::fairing()) .register(catchers![internal_error, bad_request]) .launch(); + + Ok(()) } diff --git a/src/settings.rs b/src/settings.rs index 5d19699..f3bc62e 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -133,7 +133,7 @@ impl Settings { s.set_default("server.host", "127.0.0.1")?; s.set_default("server.port", 8888)?; s.set_default("server.open_registration", false)?; - s.set_default("server.db_uri", "DEFAULT POSTGRES URI, PLEASE CHANGE")?; + s.set_default("server.db_uri", "default_uri")?; if config_file.exists() { s.merge(ConfigFile::with_name(config_file.to_str().unwrap()))?;