Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

add --preview to kv:key, kv:bulk + kv:namespace #1360

Merged
merged 6 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 225 additions & 29 deletions src/commands/kv/namespace/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,43 @@ use crate::commands::kv;
use crate::http;
use crate::kv::namespace::create;
use crate::settings::global_user::GlobalUser;
use crate::settings::toml::Target;
use crate::settings::toml::{ConfigKvNamespace, KvNamespace, Manifest};
use crate::terminal::message;

pub fn run(
target: &Target,
manifest: &Manifest,
is_preview: bool,
env: Option<&str>,
user: &GlobalUser,
binding: &str,
) -> Result<(), failure::Error> {
kv::validate_target(target)?;
let target = manifest.get_target(env, is_preview)?;
kv::validate_target(&target)?;
validate_binding(binding)?;

let title = format!("{}-{}", target.name, binding);
let msg = format!("Creating namespace with title \"{}\"", title);
message::working(&msg);

let client = http::cf_v4_client(user)?;
let result = create(&client, target, &title);
let result = create(&client, &target, &title);

match result {
Ok(success) => {
let namespace = success.result;
message::success(&format!("Success: {:#?}", namespace));
if target.kv_namespaces.is_empty() {
match env {
Some(env) => message::success(&format!(
"Add the following to your wrangler.toml under [env.{}]:",
env
)),
None => message::success("Add the following to your wrangler.toml:"),
};
println!(
"kv-namespaces = [ \n\
\t {{ binding = \"{}\", id = \"{}\" }} \n\
]",
binding, namespace.id
);
} else {
match env {
Some(env) => message::success(&format!(
"Add the following to your wrangler.toml's \"kv-namespaces\" array in [env.{}]:",
env
)),
None => message::success("Add the following to your wrangler.toml's \"kv-namespaces\" array:"),
};
println!("{{ binding = \"{}\", id = \"{}\" }}", binding, namespace.id);
}
message::success("Success!");
println!(
"{}",
toml_modification_instructions(
KvNamespace {
binding: binding.to_string(),
id: namespace.id,
},
manifest.kv_namespaces.as_ref(),
env,
is_preview,
)
);
}
Err(e) => print!("{}", kv::format_error(e)),
}
Expand All @@ -68,10 +58,216 @@ fn validate_binding(binding: &str) -> Result<(), failure::Error> {
Ok(())
}

fn toml_modification_instructions(
new_namespace: KvNamespace,
all_namespaces: Option<&Vec<ConfigKvNamespace>>,
env: Option<&str>,
is_preview: bool,
) -> String {
let mut msg = "Add the following to your wrangler.toml".to_string();

if all_namespaces.is_some() {
msg.push_str(" in your kv_namespaces array");
}

if let Some(env) = env {
msg.push_str(&format!(" under [env.{}]", env));
}

msg.push_str(":\n");

let existing_namespace = if let Some(all_namespaces) = all_namespaces {
all_namespaces
.iter()
.find(|namespace| namespace.binding == new_namespace.binding)
} else {
None
};

let mut inline_msg = format!("{{ binding = \"{}\", ", &new_namespace.binding);
if let Some(existing_namespace) = existing_namespace {
if is_preview {
inline_msg.push_str(&format!("preview_id = \"{}\"", new_namespace.id));
if let Some(existing_namespace_id) = &existing_namespace.id {
inline_msg.push_str(&format!(", id = \"{}\"", existing_namespace_id));
}
} else {
inline_msg.push_str(&format!("id = \"{}\"", new_namespace.id));
if let Some(existing_namespace_preview_id) = &existing_namespace.preview_id {
inline_msg.push_str(&format!(
", preview_id = \"{}\"",
existing_namespace_preview_id
));
}
}
} else {
if is_preview {
inline_msg.push_str("preview_id");
} else {
inline_msg.push_str("id")
}
inline_msg.push_str(" = \"");
inline_msg.push_str(&new_namespace.id);
inline_msg.push_str("\"");
};
inline_msg.push_str(" }");

if all_namespaces.is_some() {
msg.push_str(&inline_msg);
} else {
msg.push_str(&format!("kv_namespaces = [ \n\t {}\n]", &inline_msg));
}

msg
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_messages_about_env() {
let new_namespace = KvNamespace {
id: "new_preview_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = Some(vec![ConfigKvNamespace {
binding: "BAR".to_string(),
id: Some("production_id".to_string()),
preview_id: None,
}]);

let env = Some("my_env");

let is_preview = true;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("[env.my_env]"));
}

#[test]
fn it_messages_about_preview() {
let new_namespace = KvNamespace {
id: "new_preview_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = Some(vec![ConfigKvNamespace {
binding: "FOO".to_string(),
id: Some("existing_production_id".to_string()),
preview_id: None,
}]);

let env = None;

let is_preview = true;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("{ binding = \"FOO\", preview_id = \"new_preview_id\", id = \"existing_production_id\" }"));
assert!(!msg.contains("kv_namespaces = ["));
}

#[test]
fn it_messages_about_namespaces() {
let new_namespace = KvNamespace {
id: "new_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = None;

let env = None;

let is_preview = false;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("{ binding = \"FOO\", id = \"new_id\" }"));
assert!(msg.contains("kv_namespaces = ["));
}

#[test]
fn it_doesnt_message_about_namespaces() {
let new_namespace = KvNamespace {
id: "new_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = Some(vec![]);

let env = None;

let is_preview = false;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("{ binding = \"FOO\", id = \"new_id\" }"));
assert!(!msg.contains("kv_namespaces = ["));
}

#[test]
fn it_messages_about_overridden_namespaces() {
let new_namespace = KvNamespace {
id: "new_preview_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = Some(vec![
ConfigKvNamespace {
binding: "FOO".to_string(),
id: Some("existing_production_id".to_string()),
preview_id: Some("existing_preview_id".to_string()),
},
ConfigKvNamespace {
binding: "BAR".to_string(),
id: Some("some_prod_id".to_string()),
preview_id: None,
},
]);

let env = None;

let is_preview = true;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("{ binding = \"FOO\", preview_id = \"new_preview_id\", id = \"existing_production_id\" }"));
assert!(!msg.contains("kv_namespaces = ["));
}

#[test]
fn it_messages_when_no_existing_id() {
let new_namespace = KvNamespace {
id: "new_preview_id".to_string(),
binding: "FOO".to_string(),
};

let all_namespaces = Some(vec![
ConfigKvNamespace {
binding: "FOO".to_string(),
id: None,
preview_id: None,
},
ConfigKvNamespace {
binding: "BAR".to_string(),
id: Some("some_prod_id".to_string()),
preview_id: None,
},
]);

let env = None;

let is_preview = true;

let msg =
toml_modification_instructions(new_namespace, all_namespaces.as_ref(), env, is_preview);
assert!(msg.contains("{ binding = \"FOO\", preview_id = \"new_preview_id\" }"));
assert!(!msg.contains("kv_namespaces = ["));
}

#[test]
fn it_can_detect_invalid_binding() {
let invalid_bindings = vec!["hi there", "1234"];
Expand Down
20 changes: 17 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ fn run() -> Result<(), failure::Error> {
let kv_namespace_specifier_group = ArgGroup::with_name("namespace-specifier")
.args(&["binding", "namespace-id"])
.required(true);
let kv_preview_arg = Arg::with_name("preview")
.help("applies the command to the preview namespace when combined with --binding")
.long("preview")
.takes_value(false);

// This arg is for any action that uses environments (e.g. KV subcommands, publish)
let environment_arg = Arg::with_name("env")
Expand Down Expand Up @@ -122,13 +126,15 @@ fn run() -> Result<(), failure::Error> {
.required(true)
.index(1)
)
.arg(kv_preview_arg.clone())
.arg(silent_verbose_arg.clone())
)
.subcommand(
SubCommand::with_name("delete")
.about("Delete namespace")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(silent_verbose_arg.clone())
Expand All @@ -153,6 +159,7 @@ fn run() -> Result<(), failure::Error> {
.about("Put a key-value pair into a namespace")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(
Expand Down Expand Up @@ -197,6 +204,7 @@ fn run() -> Result<(), failure::Error> {
.about("Get a key's value from a namespace")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(
Expand All @@ -212,6 +220,7 @@ fn run() -> Result<(), failure::Error> {
.about("Delete a key and its value from a namespace")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(
Expand All @@ -227,6 +236,7 @@ fn run() -> Result<(), failure::Error> {
.about("List all keys in a namespace. Produces JSON output")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(
Expand All @@ -253,6 +263,7 @@ fn run() -> Result<(), failure::Error> {
.about("Upload multiple key-value pairs to a namespace")
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.arg(kv_preview_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(environment_arg.clone())
.arg(
Expand All @@ -268,6 +279,7 @@ fn run() -> Result<(), failure::Error> {
.arg(kv_binding_arg.clone())
.arg(kv_namespace_id_arg.clone())
.group(kv_namespace_specifier_group.clone())
.arg(kv_preview_arg.clone())
.arg(environment_arg.clone())
.about("Delete multiple keys and their values from a namespace")
.arg(
Expand Down Expand Up @@ -830,15 +842,15 @@ fn run() -> Result<(), failure::Error> {
} else if let Some(kv_matches) = matches.subcommand_matches("kv:namespace") {
let manifest = settings::toml::Manifest::new(config_path)?;
let user = settings::global_user::GlobalUser::new()?;

match kv_matches.subcommand() {
("create", Some(create_matches)) => {
is_preview = create_matches.is_present("preview");
let env = create_matches.value_of("env");
let target = manifest.get_target(env, is_preview)?;
let binding = create_matches.value_of("binding").unwrap();
commands::kv::namespace::create(&target, env, &user, binding)?;
commands::kv::namespace::create(&manifest, is_preview, env, &user, binding)?;
}
("delete", Some(delete_matches)) => {
is_preview = delete_matches.is_present("preview");
let env = delete_matches.value_of("env");
let target = manifest.get_target(env, is_preview)?;
let namespace_id = match delete_matches.value_of("binding") {
Expand Down Expand Up @@ -868,6 +880,7 @@ fn run() -> Result<(), failure::Error> {
let (subcommand, subcommand_matches) = kv_matches.subcommand();
let (target, namespace_id) = match subcommand_matches {
Some(subcommand_matches) => {
is_preview = subcommand_matches.is_present("preview");
let env = subcommand_matches.value_of("env");
let target = manifest.get_target(env, is_preview)?;
let namespace_id = match subcommand_matches.value_of("binding") {
Expand Down Expand Up @@ -931,6 +944,7 @@ fn run() -> Result<(), failure::Error> {
let (subcommand, subcommand_matches) = kv_matches.subcommand();
let (target, namespace_id) = match subcommand_matches {
Some(subcommand_matches) => {
is_preview = subcommand_matches.is_present("preview");
let env = subcommand_matches.value_of("env");
let target = manifest.get_target(env, is_preview)?;
let namespace_id = match subcommand_matches.value_of("binding") {
Expand Down
Loading