From 1ea1d694a0375eb4b17b3738e4fdef50a97ecde3 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Mon, 27 Jul 2020 21:40:29 -0700 Subject: [PATCH 01/11] fixes + add rfc3339Nano --- date-formats-workflow/src/main.rs | 41 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index c624ad8..b088490 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -1,7 +1,7 @@ use alfred::{json, Item}; use chrono::prelude::*; +use chrono::{Local, Utc}; use chrono_tz::Tz; -use chrono::{Datelike, Timelike, Utc, Local}; use clap::{ app_from_crate, crate_authors, crate_description, crate_name, crate_version, AppSettings, Arg, SubCommand, @@ -11,7 +11,6 @@ use failure::{format_err, Error}; use std::io; use std::io::Write; use std::str::FromStr; -use std::time::{SystemTime, UNIX_EPOCH}; const SUBCOMMAND_NOW: &str = "now"; const SUBCOMMAND_PRINT: &str = "print"; @@ -74,7 +73,7 @@ fn main() -> Result<(), Error> { match arg.as_str() { // some funny business to parse the tz because of accepting // arbitrary text before it - "-t" | "-tz" => { + "-t" | "--tz" => { break 'outer; } _ => time_args.push(arg), @@ -109,9 +108,9 @@ const NAIVE_DATE_PARSE_FORMATS: &[&str] = &["%Y-%m-%d"]; #[inline] fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result, Error> { // there isn't a real timezone PST etc.. so doing a common mapping for ease of use. - let tz = match tz { - "PST" => "America/Vancouver", - "CST" => "America/Winnipeg", + let tz = match tz.to_lowercase().as_str() { + "pst" => "America/Vancouver", + "cst" => "America/Winnipeg", _ => tz, }; match Tz::from_str(tz) { @@ -226,8 +225,8 @@ fn parse_datetime(dt: &str) -> Result { #[inline] fn write_items(writer: W, items: &[Item]) -> Result<(), Error> - where - W: Write, +where + W: Write, { json::write_items(writer, &items[..]) .map_err(|e| format_err!("failed to write alfred items->json: {}", e)) @@ -248,6 +247,10 @@ fn write_variations(dt: &DateTime) -> Result<(), Error> { dt.to_rfc3339_opts(SecondsFormat::Secs, false), "rfc_3339 - iso8601 compatible", ); + let rfc_3339_nano = build_item( + dt.to_rfc3339_opts(SecondsFormat::Nanos, true), + "rfc_3339_nano - iso8601 compatible", + ); let rfc_2822 = build_item(dt.to_rfc2822(), "rfc_2822"); let alt = build_item(dt.format("%e %b %Y %H:%M:%S").to_string(), ""); @@ -270,20 +273,28 @@ fn write_variations(dt: &DateTime) -> Result<(), Error> { diff.num_seconds().abs() % 60, attr ); - let time_since = build_item( - diff_str, - decor, - ); + let time_since = build_item(diff_str, decor); let time_current_tz = build_item( - dt.with_timezone(&Local).format("%e %b %Y %H:%M:%S").to_string(), + dt.with_timezone(&Local) + .format("%e %b %Y %H:%M:%S") + .to_string(), "Time in local timezone", ); - write_items( io::stdout(), - &[unix_sec, unix_milli, unix_nano, alt, time_current_tz, rfc_2822, rfc_3339, time_since], + &[ + unix_sec, + unix_milli, + unix_nano, + alt, + time_current_tz, + rfc_2822, + rfc_3339, + rfc_3339_nano, + time_since, + ], ) } From 57e323f2c27abb8e352c2b9a2613207462bc31c4 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 28 Jul 2020 22:24:29 -0700 Subject: [PATCH 02/11] tmp commit --- date-formats-workflow/Cargo.toml | 9 ++--- date-formats-workflow/src/errors.rs | 21 +++++++++++ date-formats-workflow/src/main.rs | 49 +++++++++++--------------- github-workflow/Cargo.toml | 13 +++---- github-workflow/src/bin/main.rs | 8 ++--- github-workflow/src/database/errors.rs | 7 ++++ github-workflow/src/database/mod.rs | 13 +++---- github-workflow/src/errors.rs | 10 ++++++ github-workflow/src/github.rs | 4 +-- github-workflow/src/lib.rs | 1 + github-workflow/src/workflow.rs | 2 +- 11 files changed, 84 insertions(+), 53 deletions(-) create mode 100644 date-formats-workflow/src/errors.rs create mode 100644 github-workflow/src/database/errors.rs create mode 100644 github-workflow/src/errors.rs diff --git a/date-formats-workflow/Cargo.toml b/date-formats-workflow/Cargo.toml index 20a7bfc..b619725 100644 --- a/date-formats-workflow/Cargo.toml +++ b/date-formats-workflow/Cargo.toml @@ -21,7 +21,8 @@ version = "1.2.0" [dependencies] alfred = "4.0.2" -chrono = "0.4.9" -chrono-tz = "0.5.1" -clap = "2.33.0" -failure = "0.1.6" +chrono = "0.4.13" +chrono-tz = "0.5.2" +clap = "2.33.1" +thiserror = "1.0.20" +anyhow = "1.0.32" diff --git a/date-formats-workflow/src/errors.rs b/date-formats-workflow/src/errors.rs new file mode 100644 index 0000000..8b3247a --- /dev/null +++ b/date-formats-workflow/src/errors.rs @@ -0,0 +1,21 @@ +use std::io; +use std::num::ParseIntError; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("{}", _0)] + Text(String), + + #[error("failed to parse integer {}", _0)] + ParseInt(#[from] ParseIntError), + + #[error("failed to write alfred items->json {}", _0)] + WriteItems(#[from] io::Error), + + #[error("failed to parse DateTime from unix timestamp")] + UnixTimestamp, + + #[error("failed to parse DateTime")] + ParseDateTime, +} diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index b088490..fc65fea 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -1,4 +1,7 @@ +mod errors; + use alfred::{json, Item}; +use anyhow::Error as AnyError; use chrono::prelude::*; use chrono::{Local, Utc}; use chrono_tz::Tz; @@ -6,8 +9,7 @@ use clap::{ app_from_crate, crate_authors, crate_description, crate_name, crate_version, AppSettings, Arg, SubCommand, }; -use failure::_core::num::ParseIntError; -use failure::{format_err, Error}; +use errors::Error; use std::io; use std::io::Write; use std::str::FromStr; @@ -17,7 +19,7 @@ const SUBCOMMAND_PRINT: &str = "print"; const ARG_TIMEZONE: &str = "tz"; const ARG_VALUE: &str = "value"; -fn main() -> Result<(), Error> { +fn main() -> Result<(), AnyError> { let matches = app_from_crate!("\n") .setting(AppSettings::AllowExternalSubcommands) .arg( @@ -96,7 +98,7 @@ fn main() -> Result<(), Error> { .autocomplete(format!(" {} ", SUBCOMMAND_NOW)) .arg(format!("{} --{} UTC", SUBCOMMAND_NOW, ARG_TIMEZONE)) .into_item(); - write_items(io::stdout(), &[now]) + Ok(write_items(io::stdout(), &[now])?) } } } @@ -113,10 +115,9 @@ fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result "cst" => "America/Winnipeg", _ => tz, }; - match Tz::from_str(tz) { - Ok(tz) => Ok(tz.from_utc_datetime(ndt)), - Err(e) => Err(format_err!("{}", e)), - } + Tz::from_str(tz) + .map_err(|e| Error::Text(e)) + .map(|tz| tz.from_utc_datetime(ndt)) } struct UnixExtract { @@ -125,7 +126,7 @@ struct UnixExtract { } #[inline] -fn parse_seconds_ns(dt: &str) -> Result { +fn parse_seconds_ns(dt: &str) -> Result { let num = dt.parse::()?; let ns = num % 1_000_000_000; Ok(UnixExtract { @@ -139,26 +140,19 @@ fn parse_datetime(dt: &str) -> Result { let time = match dt.len() { 10 => { // unix timestamp - seconds - match dt.parse() { - Ok(num) => Ok(NaiveDateTime::from_timestamp(num, 0)), - Err(e) => Err(format_err!("{}", e)), - } + Ok(NaiveDateTime::from_timestamp(dt.parse::()?, 0)) } 13 => { // unix timestamp - milliseconds - match parse_seconds_ns(dt) { - Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), - Err(e) => Err(format_err!("{}", e)), - } + let u = parse_seconds_ns(dt)?; + Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)) } 19 => { // unix timestamp - nanoseconds - match parse_seconds_ns(dt) { - Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), - Err(e) => Err(format_err!("{}", e)), - } + let u = parse_seconds_ns(dt)?; + Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)) } - _ => Err(format_err!("failed to parse DateTime from unix timestamp")), + _ => Err(Error::UnixTimestamp), }; // try to unwrap the common date & times @@ -170,7 +164,7 @@ fn parse_datetime(dt: &str) -> Result { Ok(v) => Ok(v.naive_utc()), Err(_) => match DateTime::parse_from_rfc2822(&dt) { Ok(v) => Ok(v.naive_utc()), - Err(e) => Err(e), + Err(_) => Err(Error::ParseDateTime), }, }, }, @@ -185,7 +179,7 @@ fn parse_datetime(dt: &str) -> Result { .find_map(Result::ok); match result { Some(v) => Ok(v.naive_utc()), - None => Err(format_err!("failed to parse DateTime")), + None => Err(Error::ParseDateTime), } } }; @@ -199,7 +193,7 @@ fn parse_datetime(dt: &str) -> Result { .find_map(Result::ok); match result { Some(v) => Ok(v.naive_utc()), - None => Err(format_err!("failed to parse DateTime")), + None => Err(Error::ParseDateTime), } } }; @@ -216,7 +210,7 @@ fn parse_datetime(dt: &str) -> Result { v, NaiveTime::from_num_seconds_from_midnight(0, 0), )), - None => Err(format_err!("failed to parse DateTime")), + None => Err(Error::ParseDateTime), } } }?; @@ -228,8 +222,7 @@ fn write_items(writer: W, items: &[Item]) -> Result<(), Error> where W: Write, { - json::write_items(writer, &items[..]) - .map_err(|e| format_err!("failed to write alfred items->json: {}", e)) + Ok(json::write_items(writer, &items[..])?) } #[inline] diff --git a/github-workflow/Cargo.toml b/github-workflow/Cargo.toml index 364c53c..c97802d 100644 --- a/github-workflow/Cargo.toml +++ b/github-workflow/Cargo.toml @@ -20,14 +20,15 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -clap = "2.33.0" -dirs = "2.0.2" -failure = "0.1.6" -serde_json = "1.0.41" +clap = "2.33.1" +dirs = "3.0.1" +serde_json = "1.0.57" +thiserror = "1.0.20" +anyhow = "1.0.32" [dependencies.chrono] features = ["serde"] -version = "0.4.9" +version = "0.4.13" [dependencies.reqwest] features = ["rustls-tls"] @@ -42,7 +43,7 @@ version = "0.20.0" [dependencies.serde] features = ["derive"] -version = "1.0.102" +version = "1.0.114" [lib] name = "github_workflow_lib" diff --git a/github-workflow/src/bin/main.rs b/github-workflow/src/bin/main.rs index d752c46..5d38676 100644 --- a/github-workflow/src/bin/main.rs +++ b/github-workflow/src/bin/main.rs @@ -1,9 +1,9 @@ use alfred::{json, Item}; +use anyhow::{anyhow, Error}; use clap::{ app_from_crate, crate_authors, crate_description, crate_name, crate_version, AppSettings, Arg, SubCommand, }; -use failure::{format_err, Error}; use github_workflow_lib::workflow::GithubWorkflow; use std::borrow::Cow; use std::io::Write; @@ -47,7 +47,7 @@ fn main() -> Result<(), Error> { println!("Successfully Refreshed GitHub cache"); Ok(()) } - _ => Err(format_err!("No suitable SubCommand found")), + _ => Err(anyhow!("No suitable SubCommand found")), }, (SUBCOMMAND_OPEN, Some(m)) => { let input = m.value_of(ARG_INPUT).unwrap_or_default(); @@ -55,7 +55,7 @@ fn main() -> Result<(), Error> { Command::new("open") .arg(input) .output() - .map_err(|e| format_err!("failed to execute process: {}", e))?; + .map_err(|e| anyhow!("failed to execute process: {}", e))?; } Ok(()) } @@ -88,5 +88,5 @@ where W: Write, { json::write_items(writer, &items[..]) - .map_err(|e| format_err!("failed to write alfred items->json: {}", e)) + .map_err(|e| anyhow!("failed to write alfred items->json: {}", e)) } diff --git a/github-workflow/src/database/errors.rs b/github-workflow/src/database/errors.rs new file mode 100644 index 0000000..44bf0da --- /dev/null +++ b/github-workflow/src/database/errors.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + SQLite(#[from] rusqlite::Error), +} diff --git a/github-workflow/src/database/mod.rs b/github-workflow/src/database/mod.rs index e998351..a3c38ac 100644 --- a/github-workflow/src/database/mod.rs +++ b/github-workflow/src/database/mod.rs @@ -1,7 +1,8 @@ +pub mod errors; pub mod models; use crate::database::models::Repository; -use failure::{format_err, Error}; +use errors::Error; use rusqlite::{Connection, ToSql, NO_PARAMS}; pub struct DbContext { @@ -49,7 +50,7 @@ impl DbContext { .join("%") ); - let results = self.conn.prepare( + self.conn.prepare( "SELECT name_with_owner, name, url, pushed_at FROM repositories WHERE name LIKE ? ORDER BY pushed_at DESC LIMIT ?", )?.query_map(&[&query as &dyn ToSql,&limit], |row| { Ok(Repository{ @@ -59,12 +60,8 @@ impl DbContext { pushed_at:row.get(3)?, }) })?.map(|r|{ - match r{ - Ok(v) => Ok(v), - Err(e)=> Err(format_err!("Query + Transform into Repository failed: {}",e)), - } - }).collect::, _>>(); - results + Ok(r?) + }).collect::, _>>() } #[inline] diff --git a/github-workflow/src/errors.rs b/github-workflow/src/errors.rs new file mode 100644 index 0000000..d1740b2 --- /dev/null +++ b/github-workflow/src/errors.rs @@ -0,0 +1,10 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + Request(#[from] reqwest::Error), + + #[error(transparent)] + SQLite(#[from] crate::database::errors::Error), +} diff --git a/github-workflow/src/github.rs b/github-workflow/src/github.rs index 819d31e..b692f32 100644 --- a/github-workflow/src/github.rs +++ b/github-workflow/src/github.rs @@ -1,6 +1,6 @@ use crate::database::models::Repository; +use crate::errors::Error; use chrono::{DateTime, Utc}; -use failure::Error; use reqwest::header::CONTENT_TYPE; #[derive(Debug)] @@ -47,7 +47,7 @@ impl<'a> GitHubAPI<'a> { ); // TODO: clean this up with a proper type that will escape automatically when serialized to JSON - let mut escaped = query.to_string(); + let mut escaped = query; escaped = escaped.replace("\n", "\\n"); escaped = escaped.replace("\"", "\\\""); diff --git a/github-workflow/src/lib.rs b/github-workflow/src/lib.rs index 644fa68..55ecc64 100644 --- a/github-workflow/src/lib.rs +++ b/github-workflow/src/lib.rs @@ -2,5 +2,6 @@ extern crate serde; pub(crate) mod database; +pub mod errors; pub(crate) mod github; pub mod workflow; diff --git a/github-workflow/src/workflow.rs b/github-workflow/src/workflow.rs index e750e86..a60cee5 100644 --- a/github-workflow/src/workflow.rs +++ b/github-workflow/src/workflow.rs @@ -1,7 +1,7 @@ use crate::database::DbContext; +use crate::errors::Error; use crate::github::GitHubAPI; use alfred::Item; -use failure::Error; pub struct GithubWorkflow<'a> { api_key: &'a str, From 94296358c23e89b59cdc447c6c7c34897d40ae23 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 28 Jul 2020 22:30:27 -0700 Subject: [PATCH 03/11] tmp commit reqwest upgrade --- github-workflow/Cargo.toml | 4 ++-- github-workflow/src/github.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/github-workflow/Cargo.toml b/github-workflow/Cargo.toml index c97802d..ce4d724 100644 --- a/github-workflow/Cargo.toml +++ b/github-workflow/Cargo.toml @@ -31,8 +31,8 @@ features = ["serde"] version = "0.4.13" [dependencies.reqwest] -features = ["rustls-tls"] -version = "0.9.22" +features = ["rustls-tls","blocking", "json"] +version = "0.10.7" [dependencies.rusqlite] features = [ diff --git a/github-workflow/src/github.rs b/github-workflow/src/github.rs index b692f32..666c9c7 100644 --- a/github-workflow/src/github.rs +++ b/github-workflow/src/github.rs @@ -55,7 +55,7 @@ impl<'a> GitHubAPI<'a> { q.push_str(&escaped); q.push_str("\" }"); - let results: Results = reqwest::Client::new() + let results: Results = reqwest::blocking::Client::new() .post("https://api.github.com/graphql") .bearer_auth(self.token) .header(CONTENT_TYPE, "application/json") From 13e571fe4e89f901c0eb280fa8dea0ca94bda34c Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 28 Jul 2020 22:37:32 -0700 Subject: [PATCH 04/11] upgrade rusqlite --- alfred-workflow/Cargo.toml | 7 ++++++- buildkite-workflow/Cargo.toml | 5 ++--- datadog-workflow/Cargo.toml | 5 ++--- github-workflow/Cargo.toml | 5 ++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/alfred-workflow/Cargo.toml b/alfred-workflow/Cargo.toml index 0bd3a66..744971e 100644 --- a/alfred-workflow/Cargo.toml +++ b/alfred-workflow/Cargo.toml @@ -14,4 +14,9 @@ categories = ["development-tools"] alfred = "4.0.1" dirs = "2.0.2" failure = "0.1.5" -rusqlite = {version = "0.20.0",features = ["chrono", "bundled"]} + +[dependencies.rusqlite] +features = [ + "bundled-full", +] +version = "0.23.1" diff --git a/buildkite-workflow/Cargo.toml b/buildkite-workflow/Cargo.toml index 9a7b178..64f9420 100644 --- a/buildkite-workflow/Cargo.toml +++ b/buildkite-workflow/Cargo.toml @@ -36,10 +36,9 @@ version = "0.9.22" [dependencies.rusqlite] features = [ - "chrono", - "bundled", + "bundled-full", ] -version = "0.20.0" +version = "0.23.1" [dependencies.serde] features = ["derive"] diff --git a/datadog-workflow/Cargo.toml b/datadog-workflow/Cargo.toml index 754a649..252be9e 100644 --- a/datadog-workflow/Cargo.toml +++ b/datadog-workflow/Cargo.toml @@ -30,10 +30,9 @@ version = "0.4.9" [dependencies.rusqlite] features = [ - "chrono", - "bundled", + "bundled-full", ] -version = "0.20.0" +version = "0.23.1" [dependencies.serde] features = ["derive"] diff --git a/github-workflow/Cargo.toml b/github-workflow/Cargo.toml index ce4d724..46ccad3 100644 --- a/github-workflow/Cargo.toml +++ b/github-workflow/Cargo.toml @@ -36,10 +36,9 @@ version = "0.10.7" [dependencies.rusqlite] features = [ - "chrono", - "bundled", + "bundled-full", ] -version = "0.20.0" +version = "0.23.1" [dependencies.serde] features = ["derive"] From c22eac6625ac2673a4110bae3eb44f9634ba78f8 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 28 Jul 2020 22:40:05 -0700 Subject: [PATCH 05/11] update base workflow packages --- alfred-workflow/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/alfred-workflow/Cargo.toml b/alfred-workflow/Cargo.toml index 744971e..ddf15b9 100644 --- a/alfred-workflow/Cargo.toml +++ b/alfred-workflow/Cargo.toml @@ -11,9 +11,9 @@ keywords = ["alfred", "workflow"] categories = ["development-tools"] [dependencies] -alfred = "4.0.1" -dirs = "2.0.2" -failure = "0.1.5" +alfred = "4.0.2" +dirs = "3.0.1" +failure = "0.1.8" [dependencies.rusqlite] features = [ From 19a7ce8dab12fc5b06721228a4571e9b52d11fe0 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 19 Jan 2021 21:05:13 -0800 Subject: [PATCH 06/11] upgrades --- .DS_Store | Bin 0 -> 6148 bytes alfred-workflow/Cargo.toml | 4 +-- alfred-workflow/src/lib.rs | 10 +++--- buildkite-workflow/Cargo.toml | 21 +++++------ buildkite-workflow/src/bin/main.rs | 6 ++-- .../src/buildkite_api/errors.rs | 18 ++++------ buildkite-workflow/src/buildkite_api/mod.rs | 18 ++++------ buildkite-workflow/src/database/errors.rs | 16 +++------ buildkite-workflow/src/database/mod.rs | 3 +- buildkite-workflow/src/errors.rs | 14 ++++++++ buildkite-workflow/src/lib.rs | 1 + buildkite-workflow/src/workflow.rs | 10 +++--- datadog-workflow/Cargo.toml | 16 +++++---- datadog-workflow/src/bin/main.rs | 8 ++--- datadog-workflow/src/database/errors.rs | 7 ++++ datadog-workflow/src/database/mod.rs | 8 ++--- datadog-workflow/src/database/monitors.rs | 34 +++++------------- datadog-workflow/src/database/screenboards.rs | 17 +++------ datadog-workflow/src/database/timeboards.rs | 22 ++++-------- datadog-workflow/src/datadog.rs | 6 ++-- datadog-workflow/src/errors.rs | 10 ++++++ datadog-workflow/src/lib.rs | 1 + datadog-workflow/src/workflow.rs | 4 +-- date-formats-workflow/Cargo.toml | 2 +- date-formats-workflow/src/main.rs | 4 +-- github-workflow/Cargo.toml | 2 +- github-workflow/src/database/mod.rs | 3 +- github-workflow/src/github.rs | 3 +- 28 files changed, 125 insertions(+), 143 deletions(-) create mode 100644 .DS_Store create mode 100644 buildkite-workflow/src/errors.rs create mode 100644 datadog-workflow/src/database/errors.rs create mode 100644 datadog-workflow/src/errors.rs diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9fcdb8e8dff2928d8a4832ff5de192f464bec2ae GIT binary patch literal 6148 zcmeHK%}OId5bloAoiQLI>_Ndpg9k4;BpA$fh`J|1ab!LClguzfGBC`@q+<>tFzf^D z1FTnn-a~x|U&Q-Xb$5giJt~`}3aY=F>ZCI*Os&tm}B2LX!c8Z0!br2`r~K4O0v5e00# zOCSn^uE9bh^nh@k3aC@Lxngjg4t`|4%2;6EQ#x{8tR{@}9TXf=@Dg>&(aDUMoO5pePtuXnacnLv6(n fi(By;s1ooCGyq+Lg+}mz&_O`aKn*eQr40N9!g*qW literal 0 HcmV?d00001 diff --git a/alfred-workflow/Cargo.toml b/alfred-workflow/Cargo.toml index ddf15b9..e37d940 100644 --- a/alfred-workflow/Cargo.toml +++ b/alfred-workflow/Cargo.toml @@ -3,7 +3,7 @@ name = "alfred-workflow" description = "This contains common and reusable abstractions for creating workflows." repository = "https://github.com/rust-playground/alfred-workflows-rs/tree/master/alfred-workflow" license = " MIT" -version = "1.1.0" +version = "1.2.0" authors = ["Dean Karn "] edition = "2018" readme = "README.md" @@ -13,7 +13,7 @@ categories = ["development-tools"] [dependencies] alfred = "4.0.2" dirs = "3.0.1" -failure = "0.1.8" +anyhow = "1.0.32" [dependencies.rusqlite] features = [ diff --git a/alfred-workflow/src/lib.rs b/alfred-workflow/src/lib.rs index 2fe523b..4b536b7 100644 --- a/alfred-workflow/src/lib.rs +++ b/alfred-workflow/src/lib.rs @@ -1,7 +1,7 @@ //! This contains common abstractions for reuse in multiple workflows //! use alfred::{json, Item}; -use failure::{format_err, Error}; +use anyhow::{anyhow, Error}; use rusqlite::Connection; use std::{fs, io::Write}; @@ -17,7 +17,7 @@ use std::{fs, io::Write}; /// # Examples /// /// ``` -/// use failure::Error; +/// use anyhow::Error; /// use rusqlite::Connection; /// use rusqlite::NO_PARAMS; /// @@ -43,7 +43,7 @@ where { let conn: Connection; let path = dirs::home_dir() - .ok_or_else(|| format_err!("Impossible to get your home dir!"))? + .ok_or_else(|| anyhow!("Impossible to get your home dir!"))? .join(".alfred") .join("workflows") .join(name); @@ -69,7 +69,7 @@ where /// ``` /// use alfred::{json, Item}; /// use std::{io, io::Write}; -/// use failure::Error; +/// use anyhow::Error; /// /// fn main() -> Result<(), Error> { /// let item = alfred::ItemBuilder::new("settings") @@ -83,5 +83,5 @@ where W: Write, { json::write_items(writer, &items[..]) - .map_err(|e| format_err!("failed to write alfred items->json: {}", e)) + .map_err(|e| anyhow!("failed to write alfred items->json: {}", e)) } diff --git a/buildkite-workflow/Cargo.toml b/buildkite-workflow/Cargo.toml index 64f9420..1caf824 100644 --- a/buildkite-workflow/Cargo.toml +++ b/buildkite-workflow/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT" name = "buildkite-workflow" readme = "README.md" repository = "https://github.com/rust-playground/alfred-workflows-rs/tree/master/buildkite-workflow" -version = "1.0.0" +version = "1.1.0" [[bin]] name = "buildkite-workflow" @@ -20,19 +20,20 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -dirs = "2.0.2" -regex = "1.3.1" -serde_json = "1.0.41" -snafu = "0.6.0" -structopt = "0.3.4" +dirs = "3.0.1" +regex = "1.3.9" +serde_json = "1.0.57" +structopt = "0.3.15" +anyhow = "1.0.32" +thiserror = "1.0.20" [dependencies.chrono] features = ["serde"] -version = "0.4.9" +version = "0.4.13" [dependencies.reqwest] -features = ["rustls-tls"] -version = "0.9.22" +features = ["rustls-tls","blocking", "json"] +version = "0.10.7" [dependencies.rusqlite] features = [ @@ -42,7 +43,7 @@ version = "0.23.1" [dependencies.serde] features = ["derive"] -version = "1.0.102" +version = "1.0.114" [lib] name = "buildkite_workflow_lib" diff --git a/buildkite-workflow/src/bin/main.rs b/buildkite-workflow/src/bin/main.rs index ff5c8fd..3ee973b 100644 --- a/buildkite-workflow/src/bin/main.rs +++ b/buildkite-workflow/src/bin/main.rs @@ -1,6 +1,6 @@ use alfred::{json, Item}; +use anyhow::Error; use buildkite_workflow_lib::workflow::BuildkiteWorkflow; -use std::error::Error; use std::io::Write; use std::process::Command; use std::{env, io}; @@ -14,7 +14,7 @@ struct Opt { args: Vec, } -fn main() -> Result<(), Box> { +fn main() -> Result<(), Error> { let opt = Opt::from_args(); let api_key = env::var("API_KEY")?; @@ -64,7 +64,7 @@ fn main() -> Result<(), Box> { Ok(()) } -fn write_items(writer: W, items: &[Item]) -> Result<(), Box> +fn write_items(writer: W, items: &[Item]) -> Result<(), Error> where W: Write, { diff --git a/buildkite-workflow/src/buildkite_api/errors.rs b/buildkite-workflow/src/buildkite_api/errors.rs index b2bc075..8f6a985 100644 --- a/buildkite-workflow/src/buildkite_api/errors.rs +++ b/buildkite-workflow/src/buildkite_api/errors.rs @@ -1,18 +1,12 @@ -use snafu::Snafu; +use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Snafu)] +#[derive(Debug, Error)] pub enum Error { - #[snafu(display("Database error: {}", err))] - HTTP { err: String }, + #[error("HTTP error: {}", _0)] + HTTP(String), - #[snafu(display("Reqwest error: {}", err))] - ReqwestError { err: reqwest::Error }, -} - -impl From for Error { - fn from(err: reqwest::Error) -> Self { - Error::ReqwestError { err: err } - } + #[error(transparent)] + ReqwestError(#[from] reqwest::Error), } diff --git a/buildkite-workflow/src/buildkite_api/mod.rs b/buildkite-workflow/src/buildkite_api/mod.rs index 231ae19..c1bd2b8 100644 --- a/buildkite-workflow/src/buildkite_api/mod.rs +++ b/buildkite-workflow/src/buildkite_api/mod.rs @@ -40,43 +40,37 @@ impl<'a> BuildkiteAPI<'a> { #[inline] fn fetch_organizations(&self, url: &str) -> Result { - let mut response = reqwest::Client::new() + let response = reqwest::blocking::Client::new() .get(url) .bearer_auth(self.token) .header(CONTENT_TYPE, "application/json") .send()?; if !response.status().is_success() { - return Err(Error::HTTP { - err: response.text()?, - }); + return Err(Error::HTTP(response.text()?)); } - let results: Vec = response.json()?; let link = response.headers().get(LINK); let next = self.extract_next(link); - + let results: Vec = response.json()?; Ok(OrganizationResponse { next, results }) } #[inline] fn fetch_pipelines(&self, url: &str) -> Result { - let mut response = reqwest::Client::new() + let response = reqwest::blocking::Client::new() .get(url) .bearer_auth(self.token) .header(CONTENT_TYPE, "application/json") .send()?; if !response.status().is_success() { - return Err(Error::HTTP { - err: response.text()?, - }); + return Err(Error::HTTP(response.text()?)); } - let results: Vec = response.json()?; let link = response.headers().get(LINK); let next = self.extract_next(link); - + let results: Vec = response.json()?; Ok(PipelineResponse { next, results }) } diff --git a/buildkite-workflow/src/database/errors.rs b/buildkite-workflow/src/database/errors.rs index 7da7441..a835b4c 100644 --- a/buildkite-workflow/src/database/errors.rs +++ b/buildkite-workflow/src/database/errors.rs @@ -1,17 +1,9 @@ -use snafu::Snafu; +use thiserror::Error; pub type Result = std::result::Result; -#[derive(Debug, Snafu)] +#[derive(Debug, Error)] pub enum Error { - #[snafu(display("Database error: {}", err))] - Sqlite { err: String }, -} - -impl From for Error { - fn from(err: rusqlite::Error) -> Self { - Error::Sqlite { - err: err.to_string(), - } - } + #[error(transparent)] + Sqlite(#[from] rusqlite::Error), } diff --git a/buildkite-workflow/src/database/mod.rs b/buildkite-workflow/src/database/mod.rs index 5e67fb7..fd285a5 100644 --- a/buildkite-workflow/src/database/mod.rs +++ b/buildkite-workflow/src/database/mod.rs @@ -18,13 +18,12 @@ impl DbContext { #[inline] pub fn run_migrations(&self) -> Result<()> { - self.conn.execute( + self.conn.execute_batch( "CREATE TABLE IF NOT EXISTS pipelines ( unique_name TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL, url TEXT NOT NULL );", - NO_PARAMS, )?; Ok(()) } diff --git a/buildkite-workflow/src/errors.rs b/buildkite-workflow/src/errors.rs new file mode 100644 index 0000000..334b420 --- /dev/null +++ b/buildkite-workflow/src/errors.rs @@ -0,0 +1,14 @@ +use std::io; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + API(#[from] crate::buildkite_api::errors::Error), + + #[error(transparent)] + SQLite(#[from] crate::database::errors::Error), + + #[error("failed to write alfred items->json {}", _0)] + WriteItems(#[from] io::Error), +} diff --git a/buildkite-workflow/src/lib.rs b/buildkite-workflow/src/lib.rs index 9a6eaff..cb87c94 100644 --- a/buildkite-workflow/src/lib.rs +++ b/buildkite-workflow/src/lib.rs @@ -3,4 +3,5 @@ extern crate serde; pub(crate) mod buildkite_api; pub(crate) mod database; +pub mod errors; pub mod workflow; diff --git a/buildkite-workflow/src/workflow.rs b/buildkite-workflow/src/workflow.rs index 4695bf1..83ab4b2 100644 --- a/buildkite-workflow/src/workflow.rs +++ b/buildkite-workflow/src/workflow.rs @@ -1,8 +1,8 @@ use crate::buildkite_api::BuildkiteAPI; use crate::database::models::Pipeline; use crate::database::DbContext; +use crate::errors::Error; use alfred::Item; -use std::error::Error; pub struct BuildkiteWorkflow<'a> { api_key: &'a str, @@ -11,18 +11,16 @@ pub struct BuildkiteWorkflow<'a> { impl<'a> BuildkiteWorkflow<'a> { #[inline] - pub fn new(api_key: &'a str, database_url: &str) -> Result> { + pub fn new(api_key: &'a str, database_url: &str) -> Result { let db = DbContext::new(database_url)?; Ok(BuildkiteWorkflow { api_key, db }) } #[inline] - pub fn refresh_cache(&mut self) -> Result<(), Box> { + pub fn refresh_cache(&mut self) -> Result<(), Error> { self.db.run_migrations()?; let api = BuildkiteAPI::new(self.api_key); - self.db.delete_pipelines()?; - for organizations in api.get_organizations_paginated() { for org in organizations? { for pipelines in api.get_pipelines_paginated(&org.slug) { @@ -44,7 +42,7 @@ impl<'a> BuildkiteWorkflow<'a> { } #[inline] - pub fn query<'items>(&self, repo_name: &[String]) -> Result>, Box> { + pub fn query<'items>(&self, repo_name: &[String]) -> Result>, Error> { self.db .find_pipelines(repo_name, 10)? .into_iter() diff --git a/datadog-workflow/Cargo.toml b/datadog-workflow/Cargo.toml index 252be9e..825d551 100644 --- a/datadog-workflow/Cargo.toml +++ b/datadog-workflow/Cargo.toml @@ -12,7 +12,7 @@ license = " MIT" name = "datadog-workflow" readme = "README.md" repository = "https://github.com/rust-playground/alfred-workflows-rs/tree/master/datadog-workflow" -version = "2.0.1" +version = "2.1.0" [[bin]] name = "datadog-workflow" @@ -20,13 +20,17 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -clap = "2.33.0" -failure = "0.1.6" -reqwest = "0.9.22" +clap = "2.33.1" +anyhow = "1.0.32" +thiserror = "1.0.20" [dependencies.chrono] features = ["serde"] -version = "0.4.9" +version = "0.4.13" + +[dependencies.reqwest] +features = ["rustls-tls","blocking", "json"] +version = "0.10.7" [dependencies.rusqlite] features = [ @@ -36,7 +40,7 @@ version = "0.23.1" [dependencies.serde] features = ["derive"] -version = "1.0.102" +version = "1.0.114" [lib] name = "datadog_workflow_lib" diff --git a/datadog-workflow/src/bin/main.rs b/datadog-workflow/src/bin/main.rs index 44c7914..ecaf7f8 100644 --- a/datadog-workflow/src/bin/main.rs +++ b/datadog-workflow/src/bin/main.rs @@ -1,9 +1,9 @@ use alfred::{json, Item}; +use anyhow::{anyhow, Error}; use clap::{ app_from_crate, crate_authors, crate_description, crate_name, crate_version, Arg, SubCommand, }; use datadog_workflow_lib::workflow::DatadogWorkflow; -use failure::{format_err, Error}; use std::io::Write; use std::{env, io, process::Command}; @@ -146,7 +146,7 @@ fn main() -> Result<(), Error> { println!("Successfully Refreshed Datadog cache"); Ok(()) } - _ => Err(format_err!("No suitable SubCommand found")), + _ => Err(anyhow!("No suitable SubCommand found")), }, (SUBCOMMAND_OPEN, Some(m)) => { let input = m.value_of(ARG_INPUT).unwrap_or_default(); @@ -154,7 +154,7 @@ fn main() -> Result<(), Error> { Command::new("open") .arg(input) .output() - .map_err(|e| format_err!("failed to execute process: {}", e))?; + .map_err(|e| anyhow!("failed to execute process: {}", e))?; } Ok(()) } @@ -173,5 +173,5 @@ where W: Write, { json::write_items(writer, &items[..]) - .map_err(|e| format_err!("failed to write alfred items->json: {}", e)) + .map_err(|e| anyhow!("failed to write alfred items->json: {}", e)) } diff --git a/datadog-workflow/src/database/errors.rs b/datadog-workflow/src/database/errors.rs new file mode 100644 index 0000000..44bf0da --- /dev/null +++ b/datadog-workflow/src/database/errors.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + SQLite(#[from] rusqlite::Error), +} diff --git a/datadog-workflow/src/database/mod.rs b/datadog-workflow/src/database/mod.rs index 262bed7..7deec42 100644 --- a/datadog-workflow/src/database/mod.rs +++ b/datadog-workflow/src/database/mod.rs @@ -1,13 +1,14 @@ +pub mod errors; pub mod models; pub mod monitors; pub mod screenboards; pub mod timeboards; +use crate::database::errors::Error; use crate::database::models::Dashboard; use crate::database::monitors::Monitors; use crate::database::screenboards::Screenboards; use crate::database::timeboards::Timeboards; -use failure::{format_err, Error}; use rusqlite::{Connection, ToSql, NO_PARAMS}; #[derive(Debug)] @@ -67,10 +68,7 @@ impl DbContext { url: row.get(2)?, }) })?.map(|r|{ - match r{ - Ok(v) => Ok(v), - Err(e)=> Err(format_err!("Query + Transform into ScreenBoard failed: {}",e)), - } + Ok(r?) }).collect::, _>>() } diff --git a/datadog-workflow/src/database/monitors.rs b/datadog-workflow/src/database/monitors.rs index e3aa996..8ccb8ca 100644 --- a/datadog-workflow/src/database/monitors.rs +++ b/datadog-workflow/src/database/monitors.rs @@ -1,6 +1,6 @@ +use crate::database::errors::Error; use crate::database::models::{InsertMonitor, Monitor}; use crate::database::DbContext; -use failure::{format_err, Error}; use rusqlite::{ToSql, NO_PARAMS}; pub struct Monitors<'a> { @@ -15,37 +15,24 @@ impl<'a> Monitors<'a> { #[inline] pub fn run_migrations(&self) -> Result<(), Error> { - self.db.conn.execute( + self.db.conn.execute_batch( "CREATE TABLE IF NOT EXISTS monitors ( id INTEGER NOT NULL PRIMARY KEY, name TEXT NOT NULL, url TEXT NOT NULL, modified DATETIME NOT NULL - );", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE INDEX IF NOT EXISTS idx_monitors_name_modified ON monitors (name, modified);", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE TABLE IF NOT EXISTS monitor_tags ( + ); + CREATE INDEX IF NOT EXISTS idx_monitors_name_modified ON monitors (name, modified); + CREATE TABLE IF NOT EXISTS monitor_tags ( id INTEGER NOT NULL, name TEXT NOT NULL, CONSTRAINT fk_monitors FOREIGN KEY (id) REFERENCES monitors(id) ON DELETE CASCADE - );", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE INDEX IF NOT EXISTS idx_monitor_tags_id ON monitor_tags (id);", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE INDEX IF NOT EXISTS idx_monitor_tags_name ON monitor_tags (name);", - NO_PARAMS, + ); + CREATE INDEX IF NOT EXISTS idx_monitor_tags_id ON monitor_tags (id); + CREATE INDEX IF NOT EXISTS idx_monitor_tags_name ON monitor_tags (name);", )?; Ok(()) } @@ -130,10 +117,7 @@ impl<'a> Monitors<'a> { modified: row.get(3)?, }) })? - .map(|r| match r { - Ok(v) => Ok(v), - Err(e) => Err(format_err!("Query + Transform into Monitor failed: {}", e)), - }) + .map(|r| Ok(r?)) .collect::, _>>() } } diff --git a/datadog-workflow/src/database/screenboards.rs b/datadog-workflow/src/database/screenboards.rs index 82972fc..b7aa829 100644 --- a/datadog-workflow/src/database/screenboards.rs +++ b/datadog-workflow/src/database/screenboards.rs @@ -1,6 +1,6 @@ +use crate::database::errors::Error; use crate::database::models::{InsertScreenBoard, ScreenBoard}; use crate::database::DbContext; -use failure::{format_err, Error}; use rusqlite::{ToSql, NO_PARAMS}; pub struct Screenboards<'a> { @@ -15,19 +15,15 @@ impl<'a> Screenboards<'a> { #[inline] pub fn run_migrations(&self) -> Result<(), Error> { - self.db.conn.execute( + self.db.conn.execute_batch( "CREATE TABLE IF NOT EXISTS screenboards ( id INTEGER NOT NULL PRIMARY KEY, title TEXT NOT NULL, description TEXT NOT NULL, url TEXT NOT NULL, modified DATETIME NOT NULL - );", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE INDEX IF NOT EXISTS idx_screenboards_title_modified ON screenboards (title, modified);", - NO_PARAMS, + ); + CREATE INDEX IF NOT EXISTS idx_screenboards_title_modified ON screenboards (title, modified);", )?; Ok(()) } @@ -89,10 +85,7 @@ impl<'a> Screenboards<'a> { modified:row.get(4)?, }) })?.map(|r|{ - match r{ - Ok(v) => Ok(v), - Err(e)=> Err(format_err!("Query + Transform into ScreenBoard failed: {}",e)), - } + Ok(r?) }).collect::, _>>() } } diff --git a/datadog-workflow/src/database/timeboards.rs b/datadog-workflow/src/database/timeboards.rs index 258ad4b..21d83f7 100644 --- a/datadog-workflow/src/database/timeboards.rs +++ b/datadog-workflow/src/database/timeboards.rs @@ -1,6 +1,6 @@ +use crate::database::errors::Error; use crate::database::models::{InsertTimeBoard, TimeBoard}; use crate::database::DbContext; -use failure::{format_err, Error}; use rusqlite::{ToSql, NO_PARAMS}; pub struct Timeboards<'a> { @@ -15,19 +15,15 @@ impl<'a> Timeboards<'a> { #[inline] pub fn run_migrations(&self) -> Result<(), Error> { - self.db.conn.execute( + self.db.conn.execute_batch( "CREATE TABLE IF NOT EXISTS timeboards ( id TEXT NOT NULL PRIMARY KEY, title TEXT NOT NULL, description TEXT NOT NULL, url TEXT NOT NULL, modified DATETIME NOT NULL - );", - NO_PARAMS, - )?; - self.db.conn.execute( - "CREATE INDEX IF NOT EXISTS idx_timeboards_title_modified ON timeboards (title, modified);", - NO_PARAMS, + ); + CREATE INDEX IF NOT EXISTS idx_timeboards_title_modified ON timeboards (title, modified);", )?; Ok(()) } @@ -76,7 +72,7 @@ impl<'a> Timeboards<'a> { .join("%") ); - let results = self.db.conn.prepare( + self.db.conn.prepare( "SELECT id, title, description, url, modified FROM timeboards WHERE title LIKE ? ORDER BY modified DESC LIMIT ?", )?.query_map(&[&query as &dyn ToSql,&limit], |row| { Ok(TimeBoard { @@ -87,11 +83,7 @@ impl<'a> Timeboards<'a> { modified:row.get(4)?, }) })?.map(|r|{ - match r{ - Ok(v) => Ok(v), - Err(e)=> Err(format_err!("Query + Transform into Repository failed: {}",e)), - } - }).collect::, _>>(); - results + Ok(r?) + }).collect::, _>>() } } diff --git a/datadog-workflow/src/datadog.rs b/datadog-workflow/src/datadog.rs index 4d41146..efe50a9 100644 --- a/datadog-workflow/src/datadog.rs +++ b/datadog-workflow/src/datadog.rs @@ -1,6 +1,6 @@ use crate::database::models::{InsertMonitor, InsertScreenBoard, InsertTimeBoard}; -use failure::Error; -use reqwest::Client; +use crate::errors::Error; +use reqwest::blocking::Client; const APPLICATION_KEY: &str = "application_key"; const API_KEY: &str = "api_key"; @@ -27,7 +27,7 @@ impl<'a> DatadogAPI<'a> { application_key, api_url, subdomain, - client: reqwest::Client::new(), + client: reqwest::blocking::Client::new(), } } diff --git a/datadog-workflow/src/errors.rs b/datadog-workflow/src/errors.rs new file mode 100644 index 0000000..d1740b2 --- /dev/null +++ b/datadog-workflow/src/errors.rs @@ -0,0 +1,10 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + Request(#[from] reqwest::Error), + + #[error(transparent)] + SQLite(#[from] crate::database::errors::Error), +} diff --git a/datadog-workflow/src/lib.rs b/datadog-workflow/src/lib.rs index b6b4b7b..022d10d 100644 --- a/datadog-workflow/src/lib.rs +++ b/datadog-workflow/src/lib.rs @@ -3,4 +3,5 @@ extern crate serde; pub(crate) mod database; pub(crate) mod datadog; +pub mod errors; pub mod workflow; diff --git a/datadog-workflow/src/workflow.rs b/datadog-workflow/src/workflow.rs index 6b64308..acbe437 100644 --- a/datadog-workflow/src/workflow.rs +++ b/datadog-workflow/src/workflow.rs @@ -1,7 +1,7 @@ use crate::database::DbContext; use crate::datadog::DatadogAPI; +use crate::errors::Error; use alfred::Item; -use failure::Error; use std::str; pub struct DatadogWorkflow<'a> { @@ -44,7 +44,7 @@ impl<'a> DatadogWorkflow<'a> { self.refresh_monitors(&datadog_api)?; // and DB cleanup work - self.db.optimize() + Ok(self.db.optimize()?) } fn refresh_timeboards(&mut self, datadog_api: &DatadogAPI) -> Result<(), Error> { diff --git a/date-formats-workflow/Cargo.toml b/date-formats-workflow/Cargo.toml index b619725..db1ee13 100644 --- a/date-formats-workflow/Cargo.toml +++ b/date-formats-workflow/Cargo.toml @@ -17,7 +17,7 @@ license = "MIT" name = "date-formats-workflow" readme = "README.md" repository = "https://github.com/rust-playground/alfred-workflows-rs/tree/master/date-formats-workflow" -version = "1.2.0" +version = "1.3.0" [dependencies] alfred = "4.0.2" diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index fc65fea..f21d8a1 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -116,7 +116,7 @@ fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result _ => tz, }; Tz::from_str(tz) - .map_err(|e| Error::Text(e)) + .map_err(Error::Text) .map(|tz| tz.from_utc_datetime(ndt)) } @@ -237,7 +237,7 @@ fn write_variations(dt: &DateTime) -> Result<(), Error> { "UNIX timestamp - nanoseconds", ); let rfc_3339 = build_item( - dt.to_rfc3339_opts(SecondsFormat::Secs, false), + dt.to_rfc3339_opts(SecondsFormat::Secs, true), "rfc_3339 - iso8601 compatible", ); let rfc_3339_nano = build_item( diff --git a/github-workflow/Cargo.toml b/github-workflow/Cargo.toml index 46ccad3..60149f8 100644 --- a/github-workflow/Cargo.toml +++ b/github-workflow/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT" name = "github-workflow" readme = "README.md" repository = "https://github.com/rust-playground/alfred-workflows-rs/tree/master/github-workflow" -version = "2.1.0" +version = "2.2.0" [[bin]] name = "github-workflow" diff --git a/github-workflow/src/database/mod.rs b/github-workflow/src/database/mod.rs index a3c38ac..9f29bd2 100644 --- a/github-workflow/src/database/mod.rs +++ b/github-workflow/src/database/mod.rs @@ -18,14 +18,13 @@ impl DbContext { #[inline] pub fn run_migrations(&self) -> Result<(), Error> { - self.conn.execute( + self.conn.execute_batch( "CREATE TABLE IF NOT EXISTS repositories ( name_with_owner TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL, url TEXT NOT NULL, pushed_at DATETIME NOT NULL );", - NO_PARAMS, )?; Ok(()) } diff --git a/github-workflow/src/github.rs b/github-workflow/src/github.rs index 666c9c7..c6c07c8 100644 --- a/github-workflow/src/github.rs +++ b/github-workflow/src/github.rs @@ -1,7 +1,7 @@ use crate::database::models::Repository; use crate::errors::Error; use chrono::{DateTime, Utc}; -use reqwest::header::CONTENT_TYPE; +use reqwest::header::{CONTENT_TYPE, USER_AGENT}; #[derive(Debug)] pub struct GitHubAPI<'a> { @@ -59,6 +59,7 @@ impl<'a> GitHubAPI<'a> { .post("https://api.github.com/graphql") .bearer_auth(self.token) .header(CONTENT_TYPE, "application/json") + .header(USER_AGENT, "Alfred Github Workflow") .body(q) .send()? .json()?; From d01df6e2e78e22dbba46f1f1318452cc62ad1fdc Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Tue, 19 Jan 2021 21:36:46 -0800 Subject: [PATCH 07/11] fix parsing when len equals number parsing lengths --- date-formats-workflow/src/main.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index f21d8a1..244b70c 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -104,7 +104,11 @@ fn main() -> Result<(), AnyError> { } const DATE_TIME_PARSE_FORMATS: &[&str] = &["%Y-%m-%d %H:%M:%S %z"]; -const UTC_DATE_TIME_PARSE_FORMATS: &[&str] = &["%Y-%m-%d %H:%M:%S", "%a %b %e %T %Y"]; +const UTC_DATE_TIME_PARSE_FORMATS: &[&str] = &[ + "%Y-%m-%d %H:%M:%S%.f", + "%Y-%m-%d %H:%M:%S", + "%a %b %e %T %Y", +]; const NAIVE_DATE_PARSE_FORMATS: &[&str] = &["%Y-%m-%d"]; #[inline] @@ -136,23 +140,32 @@ fn parse_seconds_ns(dt: &str) -> Result { } fn parse_datetime(dt: &str) -> Result { + // panic!(dt.to_owned()); + // check lengths and try to parse unix timestamps first - let time = match dt.len() { + let time: Result> = match dt.len() { 10 => { // unix timestamp - seconds - Ok(NaiveDateTime::from_timestamp(dt.parse::()?, 0)) + match dt.parse::() { + Ok(u) => Ok(NaiveDateTime::from_timestamp(u, 0)), + Err(e) => Err(Box::new(e)), + } } 13 => { // unix timestamp - milliseconds - let u = parse_seconds_ns(dt)?; - Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)) + match parse_seconds_ns(dt) { + Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), + Err(e) => Err(Box::new(e)), + } } 19 => { // unix timestamp - nanoseconds - let u = parse_seconds_ns(dt)?; - Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)) + match parse_seconds_ns(dt) { + Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), + Err(e) => Err(Box::new(e)), + } } - _ => Err(Error::UnixTimestamp), + _ => Err(Box::new(Error::UnixTimestamp)), }; // try to unwrap the common date & times From 95d2122ce8dfa851ce0f8ea9b437112aa8c872a1 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Sun, 11 Jul 2021 21:42:02 -0700 Subject: [PATCH 08/11] fix parsing or unix times --- date-formats-workflow/src/main.rs | 37 +++++++++---------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index 244b70c..cee86f8 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -124,48 +124,31 @@ fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result .map(|tz| tz.from_utc_datetime(ndt)) } -struct UnixExtract { - seconds: i64, - ns: u32, -} - -#[inline] -fn parse_seconds_ns(dt: &str) -> Result { - let num = dt.parse::()?; - let ns = num % 1_000_000_000; - Ok(UnixExtract { - seconds: (num - ns) / 1_000_000_000, - ns: ns as u32, - }) -} - fn parse_datetime(dt: &str) -> Result { - // panic!(dt.to_owned()); - - // check lengths and try to parse unix timestamps first - let time: Result> = match dt.len() { + // check lengths and try to parse unix timestamps first as a potential fast path + let time: Result = match dt.len() { 10 => { // unix timestamp - seconds match dt.parse::() { Ok(u) => Ok(NaiveDateTime::from_timestamp(u, 0)), - Err(e) => Err(Box::new(e)), + Err(e) => Err(e.into()), } } 13 => { // unix timestamp - milliseconds - match parse_seconds_ns(dt) { - Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), - Err(e) => Err(Box::new(e)), + match dt.parse::() { + Ok(u) => Ok(Utc.timestamp_nanos(u * 1_000_000).naive_utc()), + Err(e) => Err(e.into()), } } 19 => { // unix timestamp - nanoseconds - match parse_seconds_ns(dt) { - Ok(u) => Ok(NaiveDateTime::from_timestamp(u.seconds, u.ns)), - Err(e) => Err(Box::new(e)), + match dt.parse::() { + Ok(u) => Ok(Utc.timestamp_nanos(u).naive_utc()), + Err(e) => Err(e.into()), } } - _ => Err(Box::new(Error::UnixTimestamp)), + _ => Err(Error::UnixTimestamp), }; // try to unwrap the common date & times From 2d40d71de56fbca4337a6f59928589da82928be7 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 4 Nov 2021 21:12:41 -0700 Subject: [PATCH 09/11] upgrades --- alfred-workflow/Cargo.toml | 6 +- alfred-workflow/src/lib.rs | 3 +- buildkite-workflow/Cargo.toml | 20 +-- buildkite-workflow/src/bin/main.rs | 2 +- .../src/buildkite_api/errors.rs | 3 +- buildkite-workflow/src/buildkite_api/mod.rs | 16 +-- buildkite-workflow/src/database/mod.rs | 6 +- datadog-workflow/Cargo.toml | 14 +-- datadog-workflow/src/database/mod.rs | 4 +- datadog-workflow/src/database/monitors.rs | 6 +- datadog-workflow/src/database/screenboards.rs | 6 +- datadog-workflow/src/database/timeboards.rs | 4 +- date-formats-workflow/Cargo.toml | 11 +- date-formats-workflow/src/errors.rs | 11 +- date-formats-workflow/src/main.rs | 115 ++---------------- github-workflow/Cargo.toml | 18 +-- github-workflow/src/database/mod.rs | 23 +++- 17 files changed, 85 insertions(+), 183 deletions(-) diff --git a/alfred-workflow/Cargo.toml b/alfred-workflow/Cargo.toml index e37d940..f780773 100644 --- a/alfred-workflow/Cargo.toml +++ b/alfred-workflow/Cargo.toml @@ -12,11 +12,11 @@ categories = ["development-tools"] [dependencies] alfred = "4.0.2" -dirs = "3.0.1" -anyhow = "1.0.32" +dirs = "4.0.0" +anyhow = "1.0.44" [dependencies.rusqlite] features = [ "bundled-full", ] -version = "0.23.1" +version = "0.26.1" diff --git a/alfred-workflow/src/lib.rs b/alfred-workflow/src/lib.rs index 4b536b7..20e0efe 100644 --- a/alfred-workflow/src/lib.rs +++ b/alfred-workflow/src/lib.rs @@ -19,7 +19,6 @@ use std::{fs, io::Write}; /// ``` /// use anyhow::Error; /// use rusqlite::Connection; -/// use rusqlite::NO_PARAMS; /// /// fn main() -> Result<(), Error> { /// let conn = alfred_workflow::open_database_or_else("myworkflow", create_tables)?; @@ -32,7 +31,7 @@ use std::{fs, io::Write}; /// key TEXT NOT NULL PRIMARY KEY, /// value TEXT NOT NULL /// );", -/// NO_PARAMS, +/// [], /// )?; /// Ok(()) /// } diff --git a/buildkite-workflow/Cargo.toml b/buildkite-workflow/Cargo.toml index 1caf824..55d6411 100644 --- a/buildkite-workflow/Cargo.toml +++ b/buildkite-workflow/Cargo.toml @@ -20,30 +20,30 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -dirs = "3.0.1" -regex = "1.3.9" -serde_json = "1.0.57" -structopt = "0.3.15" -anyhow = "1.0.32" -thiserror = "1.0.20" +dirs = "4.0.0" +regex = "1.5.4" +serde_json = "1.0.68" +structopt = "0.3.25" +anyhow = "1.0.44" +thiserror = "1.0.30" [dependencies.chrono] features = ["serde"] -version = "0.4.13" +version = "0.4.19" [dependencies.reqwest] features = ["rustls-tls","blocking", "json"] -version = "0.10.7" +version = "0.11.6" [dependencies.rusqlite] features = [ "bundled-full", ] -version = "0.23.1" +version = "0.26.1" [dependencies.serde] features = ["derive"] -version = "1.0.114" +version = "1.0.130" [lib] name = "buildkite_workflow_lib" diff --git a/buildkite-workflow/src/bin/main.rs b/buildkite-workflow/src/bin/main.rs index 3ee973b..b93cb26 100644 --- a/buildkite-workflow/src/bin/main.rs +++ b/buildkite-workflow/src/bin/main.rs @@ -68,6 +68,6 @@ fn write_items(writer: W, items: &[Item]) -> Result<(), Error> where W: Write, { - json::write_items(writer, &items[..])?; + json::write_items(writer, items)?; Ok(()) } diff --git a/buildkite-workflow/src/buildkite_api/errors.rs b/buildkite-workflow/src/buildkite_api/errors.rs index 8f6a985..6895e53 100644 --- a/buildkite-workflow/src/buildkite_api/errors.rs +++ b/buildkite-workflow/src/buildkite_api/errors.rs @@ -1,11 +1,10 @@ - use thiserror::Error; pub type Result = std::result::Result; #[derive(Debug, Error)] pub enum Error { #[error("HTTP error: {}", _0)] - HTTP(String), + Http(String), #[error(transparent)] ReqwestError(#[from] reqwest::Error), diff --git a/buildkite-workflow/src/buildkite_api/mod.rs b/buildkite-workflow/src/buildkite_api/mod.rs index c1bd2b8..bcd29d1 100644 --- a/buildkite-workflow/src/buildkite_api/mod.rs +++ b/buildkite-workflow/src/buildkite_api/mod.rs @@ -47,7 +47,7 @@ impl<'a> BuildkiteAPI<'a> { .send()?; if !response.status().is_success() { - return Err(Error::HTTP(response.text()?)); + return Err(Error::Http(response.text()?)); } let link = response.headers().get(LINK); @@ -65,7 +65,7 @@ impl<'a> BuildkiteAPI<'a> { .send()?; if !response.status().is_success() { - return Err(Error::HTTP(response.text()?)); + return Err(Error::Http(response.text()?)); } let link = response.headers().get(LINK); @@ -96,11 +96,7 @@ impl<'a> Iterator for OrganizationsIter<'a> { type Item = Result>; fn next(&mut self) -> Option { - if self.next.is_none() { - return None; - } - - let response = self.api.fetch_organizations(&self.next.as_ref().unwrap()); + let response = self.api.fetch_organizations(self.next.as_ref()?); if response.is_err() { return Some(Err(response.err().unwrap())); } @@ -124,11 +120,7 @@ impl<'a> Iterator for PipelinesIter<'a> { type Item = Result>; fn next(&mut self) -> Option { - if self.next.is_none() { - return None; - } - - let response = self.api.fetch_pipelines(&self.next.as_ref().unwrap()); + let response = self.api.fetch_pipelines(self.next.as_ref()?); if response.is_err() { return Some(Err(response.err().unwrap())); } diff --git a/buildkite-workflow/src/database/mod.rs b/buildkite-workflow/src/database/mod.rs index fd285a5..cad7434 100644 --- a/buildkite-workflow/src/database/mod.rs +++ b/buildkite-workflow/src/database/mod.rs @@ -3,7 +3,7 @@ pub mod models; use crate::database::models::Pipeline; use errors::Result; -use rusqlite::{Connection, ToSql, NO_PARAMS}; +use rusqlite::{Connection, ToSql}; pub struct DbContext { conn: Connection, @@ -30,7 +30,7 @@ impl DbContext { #[inline] pub fn delete_pipelines(&self) -> Result<()> { - self.conn.execute("DELETE FROM pipelines;", NO_PARAMS)?; + self.conn.execute("DELETE FROM pipelines;", [])?; Ok(()) } @@ -84,7 +84,7 @@ impl DbContext { #[inline] pub fn optimize(&self) -> Result<()> { // since this workflow is READ heavy, let's optimize the SQLite indexes and DB - self.conn.execute("VACUUM;", NO_PARAMS)?; + self.conn.execute("VACUUM;", [])?; Ok(()) } } diff --git a/datadog-workflow/Cargo.toml b/datadog-workflow/Cargo.toml index 825d551..252b5ee 100644 --- a/datadog-workflow/Cargo.toml +++ b/datadog-workflow/Cargo.toml @@ -20,27 +20,27 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -clap = "2.33.1" -anyhow = "1.0.32" -thiserror = "1.0.20" +clap = "2.33.3" +anyhow = "1.0.44" +thiserror = "1.0.30" [dependencies.chrono] features = ["serde"] -version = "0.4.13" +version = "0.4.19" [dependencies.reqwest] features = ["rustls-tls","blocking", "json"] -version = "0.10.7" +version = "0.11.6" [dependencies.rusqlite] features = [ "bundled-full", ] -version = "0.23.1" +version = "0.26.1" [dependencies.serde] features = ["derive"] -version = "1.0.114" +version = "1.0.130" [lib] name = "datadog_workflow_lib" diff --git a/datadog-workflow/src/database/mod.rs b/datadog-workflow/src/database/mod.rs index 7deec42..5687619 100644 --- a/datadog-workflow/src/database/mod.rs +++ b/datadog-workflow/src/database/mod.rs @@ -9,7 +9,7 @@ use crate::database::models::Dashboard; use crate::database::monitors::Monitors; use crate::database::screenboards::Screenboards; use crate::database::timeboards::Timeboards; -use rusqlite::{Connection, ToSql, NO_PARAMS}; +use rusqlite::{Connection, ToSql}; #[derive(Debug)] pub struct DbContext { @@ -83,7 +83,7 @@ impl DbContext { #[inline] pub fn optimize(&self) -> Result<(), Error> { // since this workflow is READ heavy, let's optimize the SQLite indexes and DB - self.conn.execute("VACUUM;", NO_PARAMS)?; + self.conn.execute("VACUUM;", [])?; Ok(()) } } diff --git a/datadog-workflow/src/database/monitors.rs b/datadog-workflow/src/database/monitors.rs index 8ccb8ca..d5888d8 100644 --- a/datadog-workflow/src/database/monitors.rs +++ b/datadog-workflow/src/database/monitors.rs @@ -1,7 +1,7 @@ use crate::database::errors::Error; use crate::database::models::{InsertMonitor, Monitor}; use crate::database::DbContext; -use rusqlite::{ToSql, NO_PARAMS}; +use rusqlite::ToSql; pub struct Monitors<'a> { db: &'a mut DbContext, @@ -39,7 +39,7 @@ impl<'a> Monitors<'a> { #[inline] pub fn delete_all(&self) -> Result<(), Error> { - self.db.conn.execute("DELETE FROM monitors;", NO_PARAMS)?; + self.db.conn.execute("DELETE FROM monitors;", [])?; Ok(()) } @@ -109,7 +109,7 @@ impl<'a> Monitors<'a> { self.db .conn .prepare(&select)? - .query_map(¶ms, |row| { + .query_map(&*params, |row| { Ok(Monitor { id: row.get(0)?, name: row.get(1)?, diff --git a/datadog-workflow/src/database/screenboards.rs b/datadog-workflow/src/database/screenboards.rs index b7aa829..90f7652 100644 --- a/datadog-workflow/src/database/screenboards.rs +++ b/datadog-workflow/src/database/screenboards.rs @@ -1,7 +1,7 @@ use crate::database::errors::Error; use crate::database::models::{InsertScreenBoard, ScreenBoard}; use crate::database::DbContext; -use rusqlite::{ToSql, NO_PARAMS}; +use rusqlite::ToSql; pub struct Screenboards<'a> { db: &'a mut DbContext, @@ -30,9 +30,7 @@ impl<'a> Screenboards<'a> { #[inline] pub fn delete_all(&self) -> Result<(), Error> { - self.db - .conn - .execute("DELETE FROM screenboards;", NO_PARAMS)?; + self.db.conn.execute("DELETE FROM screenboards;", [])?; Ok(()) } diff --git a/datadog-workflow/src/database/timeboards.rs b/datadog-workflow/src/database/timeboards.rs index 21d83f7..ac6354f 100644 --- a/datadog-workflow/src/database/timeboards.rs +++ b/datadog-workflow/src/database/timeboards.rs @@ -1,7 +1,7 @@ use crate::database::errors::Error; use crate::database::models::{InsertTimeBoard, TimeBoard}; use crate::database::DbContext; -use rusqlite::{ToSql, NO_PARAMS}; +use rusqlite::ToSql; pub struct Timeboards<'a> { db: &'a mut DbContext, @@ -30,7 +30,7 @@ impl<'a> Timeboards<'a> { #[inline] pub fn delete_all(&self) -> Result<(), Error> { - self.db.conn.execute("DELETE FROM timeboards;", NO_PARAMS)?; + self.db.conn.execute("DELETE FROM timeboards;", [])?; Ok(()) } diff --git a/date-formats-workflow/Cargo.toml b/date-formats-workflow/Cargo.toml index db1ee13..1fe37d4 100644 --- a/date-formats-workflow/Cargo.toml +++ b/date-formats-workflow/Cargo.toml @@ -21,8 +21,9 @@ version = "1.3.0" [dependencies] alfred = "4.0.2" -chrono = "0.4.13" -chrono-tz = "0.5.2" -clap = "2.33.1" -thiserror = "1.0.20" -anyhow = "1.0.32" +chrono = "0.4.19" +chrono-tz = "0.6.0" +clap = "2.33.3" +thiserror = "1.0.30" +anyhow = "1.0.44" +dateparser = "0.1.6" diff --git a/date-formats-workflow/src/errors.rs b/date-formats-workflow/src/errors.rs index 8b3247a..14fb6b4 100644 --- a/date-formats-workflow/src/errors.rs +++ b/date-formats-workflow/src/errors.rs @@ -1,5 +1,4 @@ use std::io; -use std::num::ParseIntError; use thiserror::Error; #[derive(Error, Debug)] @@ -7,15 +6,9 @@ pub enum Error { #[error("{}", _0)] Text(String), - #[error("failed to parse integer {}", _0)] - ParseInt(#[from] ParseIntError), - #[error("failed to write alfred items->json {}", _0)] WriteItems(#[from] io::Error), - #[error("failed to parse DateTime from unix timestamp")] - UnixTimestamp, - - #[error("failed to parse DateTime")] - ParseDateTime, + #[error(transparent)] + Parse(#[from] anyhow::Error), } diff --git a/date-formats-workflow/src/main.rs b/date-formats-workflow/src/main.rs index cee86f8..c0a91dc 100644 --- a/date-formats-workflow/src/main.rs +++ b/date-formats-workflow/src/main.rs @@ -9,6 +9,7 @@ use clap::{ app_from_crate, crate_authors, crate_description, crate_name, crate_version, AppSettings, Arg, SubCommand, }; +use dateparser::parse; use errors::Error; use std::io; use std::io::Write; @@ -50,8 +51,8 @@ fn main() -> Result<(), AnyError> { match matches.subcommand() { (SUBCOMMAND_NOW, Some(m)) => { let tz = m.value_of(ARG_TIMEZONE).unwrap(); // safe because there is a default value - let now = Utc::now().naive_utc(); - let dt = parse_timezone_and_date(&now, &tz)?; + let now = Utc::now(); + let dt = parse_timezone_and_date(&now, tz)?; write_variations(&dt)?; Ok(()) } @@ -71,13 +72,11 @@ fn main() -> Result<(), AnyError> { Some(args) => { let mut time_args = Vec::new(); let mut iter = args.vals.iter().map(|s| s.to_string_lossy().into_owned()); - 'outer: while let Some(arg) = iter.next() { + for arg in &mut iter { match arg.as_str() { // some funny business to parse the tz because of accepting // arbitrary text before it - "-t" | "--tz" => { - break 'outer; - } + "-t" | "--tz" => break, _ => time_args.push(arg), } } @@ -87,7 +86,8 @@ fn main() -> Result<(), AnyError> { None => String::from(""), }; let dt = date.to_owned() + " " + &time; - let parsed = parse_datetime(&dt.trim())?; + + let parsed = parse(dt.trim())?; let dt = parse_timezone_and_date(&parsed, &tz)?; write_variations(&dt)?; Ok(()) @@ -103,16 +103,8 @@ fn main() -> Result<(), AnyError> { } } -const DATE_TIME_PARSE_FORMATS: &[&str] = &["%Y-%m-%d %H:%M:%S %z"]; -const UTC_DATE_TIME_PARSE_FORMATS: &[&str] = &[ - "%Y-%m-%d %H:%M:%S%.f", - "%Y-%m-%d %H:%M:%S", - "%a %b %e %T %Y", -]; -const NAIVE_DATE_PARSE_FORMATS: &[&str] = &["%Y-%m-%d"]; - #[inline] -fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result, Error> { +fn parse_timezone_and_date(ndt: &DateTime, tz: &str) -> Result, Error> { // there isn't a real timezone PST etc.. so doing a common mapping for ease of use. let tz = match tz.to_lowercase().as_str() { "pst" => "America/Vancouver", @@ -121,96 +113,7 @@ fn parse_timezone_and_date(ndt: &NaiveDateTime, tz: &str) -> Result }; Tz::from_str(tz) .map_err(Error::Text) - .map(|tz| tz.from_utc_datetime(ndt)) -} - -fn parse_datetime(dt: &str) -> Result { - // check lengths and try to parse unix timestamps first as a potential fast path - let time: Result = match dt.len() { - 10 => { - // unix timestamp - seconds - match dt.parse::() { - Ok(u) => Ok(NaiveDateTime::from_timestamp(u, 0)), - Err(e) => Err(e.into()), - } - } - 13 => { - // unix timestamp - milliseconds - match dt.parse::() { - Ok(u) => Ok(Utc.timestamp_nanos(u * 1_000_000).naive_utc()), - Err(e) => Err(e.into()), - } - } - 19 => { - // unix timestamp - nanoseconds - match dt.parse::() { - Ok(u) => Ok(Utc.timestamp_nanos(u).naive_utc()), - Err(e) => Err(e.into()), - } - } - _ => Err(Error::UnixTimestamp), - }; - - // try to unwrap the common date & times - let time = match time { - Ok(ndt) => Ok(ndt), - Err(_) => match dt.parse::>() { - Ok(v) => Ok(v.naive_utc()), - Err(_) => match DateTime::parse_from_rfc3339(&dt) { - Ok(v) => Ok(v.naive_utc()), - Err(_) => match DateTime::parse_from_rfc2822(&dt) { - Ok(v) => Ok(v.naive_utc()), - Err(_) => Err(Error::ParseDateTime), - }, - }, - }, - }; - - let time = match time { - Ok(ndt) => Ok(ndt), - Err(_) => { - let result = DATE_TIME_PARSE_FORMATS - .iter() - .map(|fmt| DateTime::parse_from_str(&dt, fmt)) - .find_map(Result::ok); - match result { - Some(v) => Ok(v.naive_utc()), - None => Err(Error::ParseDateTime), - } - } - }; - - let time = match time { - Ok(ndt) => Ok(ndt), - Err(_) => { - let result = UTC_DATE_TIME_PARSE_FORMATS - .iter() - .map(|fmt| Utc.datetime_from_str(&dt, fmt)) - .find_map(Result::ok); - match result { - Some(v) => Ok(v.naive_utc()), - None => Err(Error::ParseDateTime), - } - } - }; - - let time = match time { - Ok(ndt) => Ok(ndt), - Err(_) => { - let result = NAIVE_DATE_PARSE_FORMATS - .iter() - .map(|fmt| NaiveDate::parse_from_str(&dt, fmt)) - .find_map(Result::ok); - match result { - Some(v) => Ok(NaiveDateTime::new( - v, - NaiveTime::from_num_seconds_from_midnight(0, 0), - )), - None => Err(Error::ParseDateTime), - } - } - }?; - Ok(time) + .map(|tz| ndt.with_timezone(&tz)) } #[inline] diff --git a/github-workflow/Cargo.toml b/github-workflow/Cargo.toml index 60149f8..fdc6005 100644 --- a/github-workflow/Cargo.toml +++ b/github-workflow/Cargo.toml @@ -20,29 +20,29 @@ path = "src/bin/main.rs" [dependencies] alfred = "4.0.2" -clap = "2.33.1" -dirs = "3.0.1" -serde_json = "1.0.57" -thiserror = "1.0.20" -anyhow = "1.0.32" +clap = "2.33.3" +dirs = "4.0.0" +serde_json = "1.0.68" +thiserror = "1.0.30" +anyhow = "1.0.44" [dependencies.chrono] features = ["serde"] -version = "0.4.13" +version = "0.4.19" [dependencies.reqwest] features = ["rustls-tls","blocking", "json"] -version = "0.10.7" +version = "0.11.6" [dependencies.rusqlite] features = [ "bundled-full", ] -version = "0.23.1" +version = "0.26.1" [dependencies.serde] features = ["derive"] -version = "1.0.114" +version = "1.0.130" [lib] name = "github_workflow_lib" diff --git a/github-workflow/src/database/mod.rs b/github-workflow/src/database/mod.rs index 9f29bd2..a95a850 100644 --- a/github-workflow/src/database/mod.rs +++ b/github-workflow/src/database/mod.rs @@ -3,7 +3,7 @@ pub mod models; use crate::database::models::Repository; use errors::Error; -use rusqlite::{Connection, ToSql, NO_PARAMS}; +use rusqlite::{Connection, ToSql}; pub struct DbContext { conn: Connection, @@ -26,12 +26,16 @@ impl DbContext { pushed_at DATETIME NOT NULL );", )?; + // CREATE VIRTUAL TABLE IF NOT EXISTS repositories_fts4 using fts4(content) Ok(()) } #[inline] pub fn delete_repositories(&self) -> Result<(), Error> { - self.conn.execute("DELETE FROM repositories;", NO_PARAMS)?; + self.conn.execute_batch( + "DELETE FROM repositories; + ", + )?; Ok(()) } @@ -49,6 +53,8 @@ impl DbContext { .join("%") ); + // "SELECT name_with_owner, name, url, pushed_at FROM repositories LEFT JOIN(SELECT content FROM repositories_fts4 WHERE content MATCH ?) ON content = name_with_owner ORDER BY pushed_at DESC LIMIT ?", + self.conn.prepare( "SELECT name_with_owner, name, url, pushed_at FROM repositories WHERE name LIKE ? ORDER BY pushed_at DESC LIMIT ?", )?.query_map(&[&query as &dyn ToSql,&limit], |row| { @@ -79,13 +85,24 @@ impl DbContext { stmt.finalize()?; tx.commit()?; + + // let tx = self.conn.transaction()?; + // let mut stmt2 = tx.prepare("INSERT INTO repositories_fts4 (content) VALUES (?1)")?; + + // for repo in repositories { + // stmt2.execute(&[&repo.name_with_owner as &dyn ToSql])?; + // } + + // stmt2.finalize()?; + // tx.commit()?; + Ok(()) } #[inline] pub fn optimize(&self) -> Result<(), Error> { // since this workflow is READ heavy, let's optimize the SQLite indexes and DB - self.conn.execute("VACUUM;", NO_PARAMS)?; + self.conn.execute("VACUUM;", [])?; Ok(()) } } From f0f29d8c1c8411448334e2501157cc3c99632850 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 4 Nov 2021 21:14:30 -0700 Subject: [PATCH 10/11] change ci to GitHub Actions --- .github/workflows/rust.yml | 50 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 19 --------------- 2 files changed, 50 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/rust.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..cf92557 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,50 @@ +name: Lint & Test +on: + pull_request: + types: [opened, edited, reopened, synchronize] +jobs: + test: + strategy: + matrix: + platform: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.platform }} + steps: + - name: Install Rust Stable + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Install Cargo + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: clippy + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Cache cargo registry + uses: actions/cache@v1 + with: + path: ~/.cargo/registry + key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo index + uses: actions/cache@v1 + with: + path: ~/.cargo/git + key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo build + uses: actions/cache@v1 + with: + path: target + key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} + + - name: Lint + uses: actions-rs/clippy@master + with: + args: --all-features --all-targets + + - name: Test + run: cargo test --all-features \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 818e42b..0000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: rust -cache: cargo -rust: - - stable - - nightly -matrix: - allow_failures: - - rust: nightly - fast_finish: true - -notifications: - email: - recipients: dean.karn@gmail.com - on_success: change - on_failure: always - -script: - - cargo build --verbose --all - - cargo test --verbose --all From 6a81838a71bdd510462e04f142b56bc76c0b0286 Mon Sep 17 00:00:00 2001 From: Dean Karn Date: Thu, 4 Nov 2021 21:16:37 -0700 Subject: [PATCH 11/11] only need to test on macos --- .github/workflows/rust.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index cf92557..1518c42 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -6,7 +6,7 @@ jobs: test: strategy: matrix: - platform: [ubuntu-latest, macos-latest, windows-latest] + platform: [macos-latest] runs-on: ${{ matrix.platform }} steps: - name: Install Rust Stable