From 8d2fccb9e9fadc819febebef180e4a6e6dfdda79 Mon Sep 17 00:00:00 2001 From: Lukas Pustina Date: Wed, 11 Mar 2020 09:30:02 +0100 Subject: [PATCH] Move Pivotal API to separate Crate --- Cargo.lock | 18 +++++++++++++ Cargo.toml | 6 +++++ crates/pivotal_api/Cargo.toml | 23 ++++++++++++++++ .../pivotal_api/src/lib.rs | 27 ++++++++++++++++--- src/lib.rs | 3 +-- src/modules/stories/export.rs | 8 +++--- src/modules/stories/mod.rs | 4 --- src/modules/stories/prepare.rs | 10 ++++--- src/modules/stories/start.rs | 4 ++- src/output/stories/markdown_output.rs | 2 +- src/output/stories/mod.rs | 2 +- 11 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 crates/pivotal_api/Cargo.toml rename src/modules/stories/pivotal_api.rs => crates/pivotal_api/src/lib.rs (94%) diff --git a/Cargo.lock b/Cargo.lock index 8f648a6..978565c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -277,6 +277,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "pivotal_api 0.0.1", "prettytable-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1876,6 +1877,23 @@ name = "pin-utils" version = "0.1.0-alpha.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pivotal_api" +version = "0.0.1" +dependencies = [ + "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quickcheck 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", + "spectral 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pkg-config" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index d131366..d45d587 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,11 @@ homepage = "https://github.com/centerdevice/ceres" travis-ci = { repository = "centerdevice/ceres", branch = "master" } codecov = { repository = "centerdevice/ceres", branch = "master", service = "github" } +[workspace] +members = [ + "crates/pivotal_api" +] + [dependencies] centerdevice = "0.4" clams = "^0.0.16" @@ -33,6 +38,7 @@ mime_guess = "1.8" prettytable-rs = "^0.7" regex = "^1.0" hyper = "0.11.9" # Strongly connected to reqwest +pivotal_api = { path = "crates/pivotal_api" } reqwest = { version = "0.8.6", features = ["unstable"] } rusoto_core = "0.31.0" rusoto_credential = "0.10.0" diff --git a/crates/pivotal_api/Cargo.toml b/crates/pivotal_api/Cargo.toml new file mode 100644 index 0000000..5c3204f --- /dev/null +++ b/crates/pivotal_api/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "pivotal_api" +version = "0.0.1" +authors = ["Lukas Pustina "] +description = "Pivotal API" +repository = "https://github.com/centerdevice/ceres.git" +homepage = "https://github.com/centerdevice/ceres" +workspace = "../.." + +[dependencies] +error-chain = "^0.12" +log = "^0.4" +futures = "0.1" +hyper = "0.11.9" # Strongly connected to reqwest +reqwest = { version = "0.8.6", features = ["unstable"] } +serde = "^1.0" +serde_derive = "^1.0" +serde_json = "^1.0" +tokio-core = "^0.1" + +[dev-dependencies] +quickcheck = "^0.6" +spectral = "^0.6" diff --git a/src/modules/stories/pivotal_api.rs b/crates/pivotal_api/src/lib.rs similarity index 94% rename from src/modules/stories/pivotal_api.rs rename to crates/pivotal_api/src/lib.rs index f96274a..96ca921 100644 --- a/src/modules/stories/pivotal_api.rs +++ b/crates/pivotal_api/src/lib.rs @@ -1,12 +1,33 @@ +#[macro_use] +extern crate error_chain; +extern crate futures; +#[macro_use] +extern crate hyper; +#[macro_use] +extern crate log; +#[macro_use] +extern crate reqwest; +extern crate serde; +#[macro_use] +extern crate serde_derive; +#[macro_use] +extern crate serde_json; + +header! { (XTrackerToken, "X-TrackerToken") => [String] } + use futures::{Future, Stream}; use futures::future::result; use reqwest::header::{ContentType, Connection}; use reqwest::unstable::async::{Client as ReqwestClient}; use serde::de::DeserializeOwned; -use serde_json; -use modules::stories::XTrackerToken; -use modules::stories::errors::*; +error_chain! { + errors { + FailedToQueryPivotalApi { + description("Failed to query Pivotal Tracker API") + } + } +} #[derive(Debug, Serialize, Deserialize)] pub struct Story { diff --git a/src/lib.rs b/src/lib.rs index 7693902..86bb2b2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,12 +12,12 @@ extern crate handlebars; extern crate hubcaps; extern crate ignore; extern crate itertools; -#[macro_use] extern crate hyper; #[macro_use] extern crate log; extern crate mime; extern crate mime_guess; +extern crate pivotal_api; extern crate prettytable; extern crate regex; extern crate reqwest; @@ -28,7 +28,6 @@ extern crate rusoto_sts; extern crate serde; #[macro_use] extern crate serde_derive; -#[macro_use] extern crate serde_json; extern crate service_world; extern crate subprocess; diff --git a/src/modules/stories/export.rs b/src/modules/stories/export.rs index a6b07a1..89e30e0 100644 --- a/src/modules/stories/export.rs +++ b/src/modules/stories/export.rs @@ -7,7 +7,7 @@ use run_config::RunConfig; use output::stories::OutputType; use output::stories::{JsonOutputStory, MarkDownOutputStory, OutputStory}; use modules::{Result as ModuleResult, Error as ModuleError, ErrorKind as ModuleErrorKind, Module}; -use modules::stories::pivotal_api::*; +use pivotal_api::{get_story, get_project_members, Story, ProjectMember}; use modules::stories::errors::*; pub const NAME: &str = "export"; @@ -75,11 +75,13 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result let client = ReqwestClient::new(&core.handle()); let work = get_story(&client, project_id, story_id, &token); - let story = core.run(work)?; + let story = core.run(work) + .chain_err(|| ErrorKind::FailedToQueryPivotalApi)?; debug!("{:#?}", story); let work = get_project_members(&client, project_id, &token); - let members = core.run(work)?; + let members = core.run(work) + .chain_err(|| ErrorKind::FailedToQueryPivotalApi)?; debug!("{:#?}", members); info!("Outputting instance descriptions"); diff --git a/src/modules/stories/mod.rs b/src/modules/stories/mod.rs index 489765f..e602359 100644 --- a/src/modules/stories/mod.rs +++ b/src/modules/stories/mod.rs @@ -26,9 +26,5 @@ mod errors { } } -pub mod pivotal_api; - -header! { (XTrackerToken, "X-TrackerToken") => [String] } - sub_module!("stories", "Manage stories", export, prepare, start); diff --git a/src/modules/stories/prepare.rs b/src/modules/stories/prepare.rs index 3cdb53f..8da5556 100644 --- a/src/modules/stories/prepare.rs +++ b/src/modules/stories/prepare.rs @@ -7,7 +7,7 @@ use tokio_core; use config::CeresConfig as Config; use run_config::RunConfig; use modules::{Result as ModuleResult, Error as ModuleError, ErrorKind as ModuleErrorKind, Module}; -use modules::stories::pivotal_api::*; +use pivotal_api::{create_task, get_story, set_description, Story}; use modules::stories::errors::*; pub const NAME: &str = "prepare"; @@ -80,6 +80,7 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result let client = ReqwestClient::new(&core.handle()); let f = get_story(&client, project_id, story_id, &token) + .map_err(|e| Error::with_chain(e, ErrorKind::FailedToQueryPivotalApi)) .and_then(|story| if story.tasks.is_empty() || force { future::ok(story) @@ -87,7 +88,8 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result future::err(Error::from_kind(ErrorKind::StoryHasTasksAlready)) } ); - let story: Story = core.run(f)?; + let story: Story = core.run(f) + .chain_err(|| ErrorKind::FailedToQueryPivotalApi)?; debug!("{:#?}", story); info!("Creating tasks"); @@ -97,6 +99,7 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result .map(|(pos, x)| { let f = create_task(&client, project_id, story_id, &token, pos+1, x); core.run(f) + .chain_err(|| ErrorKind::FailedToQueryPivotalApi) }) .collect(); let result = result?; @@ -105,7 +108,8 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result info!("Adding description"); let description = format!("{}\n\n{}\n", story.description.unwrap_or_else(|| "".to_string()), NO_RISK_ASSESSMET); let f = set_description(&client, project_id, story_id, &token, &description); - let result = core.run(f)?; + let result = core.run(f) + .chain_err(|| ErrorKind::FailedToQueryPivotalApi)?; debug!("{:#?}", result); Ok(()) diff --git a/src/modules/stories/start.rs b/src/modules/stories/start.rs index 054f257..486dccb 100644 --- a/src/modules/stories/start.rs +++ b/src/modules/stories/start.rs @@ -7,7 +7,7 @@ use tokio_core; use config::CeresConfig as Config; use run_config::RunConfig; use modules::{Result as ModuleResult, Error as ModuleError, ErrorKind as ModuleErrorKind, Module}; -use modules::stories::pivotal_api::*; +use pivotal_api::{get_story, start_story, StoryState}; use modules::stories::errors::*; pub const NAME: &str = "start"; @@ -61,6 +61,7 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result let client = ReqwestClient::new(&core.handle()); let work = get_story(&client, project_id, story_id, &token) + .map_err(|e| Error::with_chain(e, ErrorKind::FailedToQueryPivotalApi)) .and_then(|story| if story.estimate.is_none() { future::err(Error::from_kind(ErrorKind::StoryIsNotEstimated)) @@ -72,6 +73,7 @@ fn do_call(args: &ArgMatches, run_config: &RunConfig, config: &Config) -> Result ) .and_then(|story| start_story(&client, project_id, story.id, &token) + .map_err(|e| Error::with_chain(e, ErrorKind::FailedToQueryPivotalApi)) ); let result = core.run(work)?; diff --git a/src/output/stories/markdown_output.rs b/src/output/stories/markdown_output.rs index 8d22414..98f17a9 100644 --- a/src/output/stories/markdown_output.rs +++ b/src/output/stories/markdown_output.rs @@ -38,7 +38,7 @@ fn render(writer: &mut T, story: &formatting::Story) -> Result<()> { mod formatting { use std::collections::HashMap; - use modules::stories::pivotal_api::{self, Label, PullRequest, StoryState, StoryType, Task}; + use pivotal_api::{self, Label, PullRequest, StoryState, StoryType, Task}; pub trait FromWithPersonLookup<'a, T> { fn from_with(_: &'a T, persons: &HashMap) -> Self; diff --git a/src/output/stories/mod.rs b/src/output/stories/mod.rs index b6751b0..dc75c38 100644 --- a/src/output/stories/mod.rs +++ b/src/output/stories/mod.rs @@ -1,4 +1,4 @@ -use modules::stories::pivotal_api::{ProjectMember, Story}; +use pivotal_api::{ProjectMember, Story}; use std::{io::Write, str::FromStr};