diff --git a/Cargo.lock b/Cargo.lock index 5ea88263d..f7b1d05d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -258,7 +258,6 @@ dependencies = [ [[package]] name = "cloudflare" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2377,7 +2376,7 @@ dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "binary-install 0.0.3-alpha (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cloudflare 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudflare 0.4.1", "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2497,7 +2496,6 @@ dependencies = [ "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cloudflare 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59ad92e7809c9c30862f371bdb613d7aaac8a5372332e323ab3e1b978693665c" "checksum config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9107d78ed62b3fa5a86e7d18e647abed48cfd8f8fab6c72f4cdb982d196f7e6" "checksum console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ca57c2c14b8a2bf3105bc9d15574aad80babf6a9c44b1058034cdf8bd169628" "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" diff --git a/Cargo.toml b/Cargo.toml index 677b178e2..ea2f46fc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ clap = "2.32.0" config = "0.9.2" console = "0.7.5" dirs = "1.0.5" -cloudflare = "0.4.1" +cloudflare = { path = "/Users/ashleylewis/cloudflare-rs" } env_logger = "0.6.1" failure = "0.1.5" log = "0.4.6" diff --git a/src/commands/publish/mod.rs b/src/commands/publish/mod.rs index f3adc596a..0dea34949 100644 --- a/src/commands/publish/mod.rs +++ b/src/commands/publish/mod.rs @@ -4,7 +4,7 @@ mod route; pub mod upload_form; pub use package::Package; -use route::{publish_route, Route}; +use route::publish_route; use std::env; use std::path::Path; @@ -101,17 +101,15 @@ fn publish_script( .send()?; let res_status = res.status(); - let res_text = res.text()?; if !res_status.is_success() { + let res_text = res.text()?; failure::bail!(error_msg(res_status, res_text)) } let pattern = if target.route.is_some() { - let route = Route::new(&target)?; - publish_route(&user, &target, &route)?; log::info!("publishing to route"); - route.pattern + publish_route(&user, &target)? } else { log::info!("publishing to subdomain"); publish_to_subdomain(target, user)? diff --git a/src/commands/publish/route.rs b/src/commands/publish/route.rs index 531398dda..654158f0c 100644 --- a/src/commands/publish/route.rs +++ b/src/commands/publish/route.rs @@ -1,64 +1,23 @@ -use serde::{Deserialize, Serialize}; - -use cloudflare::endpoints::workers::{CreateRoute, CreateRouteParams, ListRoutes, WorkersRoute}; +use cloudflare::endpoints::workers::{CreateRoute, CreateRouteParams, ListRoutes}; use cloudflare::framework::apiclient::ApiClient; use cloudflare::framework::HttpApiClientConfig; use crate::http::{api_client, format_error}; use crate::settings::global_user::GlobalUser; -use crate::settings::target::Target; -use crate::terminal::emoji; - -#[derive(Deserialize, PartialEq, Serialize)] -pub struct Route { - script: Option, - pub pattern: String, -} - -impl From<&WorkersRoute> for Route { - fn from(api_route: &WorkersRoute) -> Route { - Route { - script: api_route.script.clone(), - pattern: api_route.pattern.clone(), - } - } -} - -impl Route { - pub fn new(target: &Target) -> Result { - if target - .route - .clone() - .expect("You must provide a zone_id in your wrangler.toml before publishing!") - .is_empty() - { - failure::bail!("You must provide a zone_id in your wrangler.toml before publishing!"); - } - let msg_config_error = format!( - "{} Your project config has an error, check your `wrangler.toml`: `route` must be provided.", - emoji::WARN - ); - Ok(Route { - script: Some(target.name.to_string()), - pattern: target.route.clone().expect(&msg_config_error), - }) - } -} +use crate::settings::target::{Route, Target}; -pub fn publish_route( - user: &GlobalUser, - target: &Target, - route: &Route, -) -> Result<(), failure::Error> { - if route_exists(user, target, route)? { - Ok(()) +pub fn publish_route(user: &GlobalUser, target: &Target) -> Result { + let route = Route::new(&target)?; + if route_exists(user, target, &route)? { + Ok(route.pattern) } else { - create(user, target, route) + create(user, target, &route)?; + Ok(route.pattern) } } fn route_exists(user: &GlobalUser, target: &Target, route: &Route) -> Result { - let routes = get_routes(user, target)?; + let routes = fetch_all(user, target)?; for remote_route in routes { if remote_route == *route { @@ -68,7 +27,7 @@ fn route_exists(user: &GlobalUser, target: &Target, route: &Route) -> Result Result, failure::Error> { +fn fetch_all(user: &GlobalUser, target: &Target) -> Result, failure::Error> { let client = api_client(user, HttpApiClientConfig::default())?; let routes: Vec = match client.request(&ListRoutes { diff --git a/src/settings/target/environment.rs b/src/settings/target/environment.rs index 19edce244..842917fcc 100644 --- a/src/settings/target/environment.rs +++ b/src/settings/target/environment.rs @@ -1,8 +1,6 @@ use super::kv_namespace::KvNamespace; use super::site::Site; -use std::collections::HashMap; - use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -11,7 +9,7 @@ pub struct Environment { pub account_id: Option, pub workers_dev: Option, pub route: Option, - pub routes: Option>, + pub routes: Option>, pub zone_id: Option, pub webpack_config: Option, pub private: Option, diff --git a/src/settings/target/manifest.rs b/src/settings/target/manifest.rs index 5e8bf7cbb..0797480dd 100644 --- a/src/settings/target/manifest.rs +++ b/src/settings/target/manifest.rs @@ -31,7 +31,7 @@ pub struct Manifest { pub workers_dev: Option, #[serde(default = "some_string")] pub route: Option, - pub routes: Option>, + pub routes: Option>, #[serde(default = "some_string")] pub zone_id: Option, pub webpack_config: Option, diff --git a/src/settings/target/mod.rs b/src/settings/target/mod.rs index 02f9292e9..4e19b15b7 100644 --- a/src/settings/target/mod.rs +++ b/src/settings/target/mod.rs @@ -1,6 +1,7 @@ mod environment; mod kv_namespace; mod manifest; +mod route; mod site; mod target; mod target_type; @@ -8,6 +9,7 @@ mod target_type; pub use environment::Environment; pub use kv_namespace::KvNamespace; pub use manifest::Manifest; +pub use route::Route; pub use site::Site; pub use target::Target; pub use target_type::TargetType; diff --git a/src/settings/target/route.rs b/src/settings/target/route.rs new file mode 100644 index 000000000..040c55a04 --- /dev/null +++ b/src/settings/target/route.rs @@ -0,0 +1,42 @@ +use serde::{Deserialize, Serialize}; + +use cloudflare::endpoints::workers::WorkersRoute; + +use crate::settings::target::target::Target; +use crate::terminal::emoji; + +#[derive(Deserialize, PartialEq, Serialize)] +pub struct Route { + pub script: Option, + pub pattern: String, +} + +impl From<&WorkersRoute> for Route { + fn from(api_route: &WorkersRoute) -> Route { + Route { + script: api_route.script.clone(), + pattern: api_route.pattern.clone(), + } + } +} + +impl Route { + pub fn new(target: &Target) -> Result { + if target + .route + .clone() + .expect("You must provide a zone_id in your wrangler.toml before publishing!") + .is_empty() + { + failure::bail!("You must provide a zone_id in your wrangler.toml before publishing!"); + } + let msg_config_error = format!( + "{} Your project config has an error, check your `wrangler.toml`: `route` must be provided.", + emoji::WARN + ); + Ok(Route { + script: Some(target.name.to_string()), + pattern: target.route.clone().expect(&msg_config_error), + }) + } +} diff --git a/src/settings/target/target.rs b/src/settings/target/target.rs index 8c8f341c6..5bb0a9ba9 100644 --- a/src/settings/target/target.rs +++ b/src/settings/target/target.rs @@ -1,9 +1,8 @@ use super::kv_namespace::KvNamespace; - use super::site::Site; use super::target_type::TargetType; +use super::Route; -use std::collections::HashMap; use std::env; use std::path::PathBuf; @@ -19,7 +18,7 @@ pub struct Target { #[serde(rename = "type")] pub target_type: TargetType, pub route: Option, - pub routes: Option>, + pub routes: Option>, pub webpack_config: Option, pub zone_id: Option, pub site: Option, @@ -47,4 +46,31 @@ impl Target { } } } + + pub fn routes(&self) -> Result, failure::Error> { + let mut routes = Vec::new(); + + // we should assert that only one of the two keys is specified in the user's toml. + if self.route.is_some() && self.routes.is_some() { + failure::bail!("You can specify EITHER `route` or `routes` in your wrangler.toml"); + } + + // everything outside of this module should consider `target.routes()` to be a Vec; + // the fact that you can specify singular or plural is a detail of the wrangler.toml contract. + if let Some(single_route) = &self.route { + routes.push(Route { + script: Some(self.name.to_owned()), + pattern: single_route.to_string(), + }); + } else if let Some(multi_route) = &self.routes { + for pattern in multi_route { + routes.push(Route { + script: Some(self.name.to_owned()), + pattern: pattern.to_string(), + }); + } + } + + Ok(routes) + } }