From 53fc65a4b9001e497a0463c0bee518c14a638fc3 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Fri, 30 Aug 2024 23:13:04 +0100 Subject: [PATCH] Allow cloud instance names to contain '-' and '_' in the org part to support vercel instances (#1361) --- Cargo.lock | 82 ++++++++++++------------------ src/portable/local.rs | 32 +++++++++++- src/portable/options.rs | 10 ++-- tests/shared-client-testcases | 2 +- tests/shared-client-tests/build.rs | 10 +++- 5 files changed, 79 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf26baacc..9e1111cd7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,6 +362,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + [[package]] name = "base64" version = "0.21.7" @@ -380,18 +386,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint 0.4.6", - "num-integer", - "num-traits", - "serde", -] - [[package]] name = "bigdecimal" version = "0.4.5" @@ -400,9 +394,10 @@ checksum = "51d712318a27c7150326677b321a5fa91b55f6d9034ffd67f20319e147d40cee" dependencies = [ "autocfg", "libm", - "num-bigint 0.4.6", + "num-bigint", "num-integer", "num-traits", + "serde", ] [[package]] @@ -1050,9 +1045,9 @@ dependencies = [ "assert_cmd", "async-listen", "backtrace", - "base32", + "base32 0.4.0", "base64 0.21.7", - "bigdecimal 0.4.5", + "bigdecimal", "bitflags 1.3.2", "bitvec", "blake2b_simd", @@ -1100,7 +1095,7 @@ dependencies = [ "nix 0.26.4", "nom", "notify", - "num-bigint 0.4.6", + "num-bigint", "once_cell", "open", "openssl", @@ -1183,7 +1178,7 @@ dependencies = [ [[package]] name = "edgedb-derive" version = "0.5.2" -source = "git+https://github.com/edgedb/edgedb-rust/#f9d784470af6e013051d1503882c1d88c51a5dcb" +source = "git+https://github.com/edgedb/edgedb-rust/#9025de8e629584d91aa91135ab7d81712aa66534" dependencies = [ "proc-macro2", "quote", @@ -1194,7 +1189,7 @@ dependencies = [ [[package]] name = "edgedb-errors" version = "0.4.2" -source = "git+https://github.com/edgedb/edgedb-rust/#f9d784470af6e013051d1503882c1d88c51a5dcb" +source = "git+https://github.com/edgedb/edgedb-rust/#9025de8e629584d91aa91135ab7d81712aa66534" dependencies = [ "bytes", ] @@ -1202,14 +1197,14 @@ dependencies = [ [[package]] name = "edgedb-protocol" version = "0.6.1" -source = "git+https://github.com/edgedb/edgedb-rust/#f9d784470af6e013051d1503882c1d88c51a5dcb" +source = "git+https://github.com/edgedb/edgedb-rust/#9025de8e629584d91aa91135ab7d81712aa66534" dependencies = [ - "bigdecimal 0.4.5", + "bigdecimal", "bitflags 2.6.0", "bytes", "chrono", "edgedb-errors", - "num-bigint 0.4.6", + "num-bigint", "num-traits", "snafu 0.8.4", "uuid", @@ -1218,7 +1213,7 @@ dependencies = [ [[package]] name = "edgedb-tokio" version = "0.5.1" -source = "git+https://github.com/edgedb/edgedb-rust/#f9d784470af6e013051d1503882c1d88c51a5dcb" +source = "git+https://github.com/edgedb/edgedb-rust/#9025de8e629584d91aa91135ab7d81712aa66534" dependencies = [ "anyhow", "arc-swap", @@ -1255,15 +1250,15 @@ dependencies = [ [[package]] name = "edgeql-parser" version = "0.1.0" -source = "git+https://github.com/edgedb/edgedb#897797fc552d53c5f82334e0087c7ab3a813b693" +source = "git+https://github.com/edgedb/edgedb#9d6f484ea8a14a7d1f10c7a334c765fa34924337" dependencies = [ "append-only-vec", - "base32", - "bigdecimal 0.3.1", + "base32 0.5.1", + "bigdecimal", "bumpalo", - "indexmap 1.9.3", + "indexmap 2.5.0", "memchr", - "num-bigint 0.3.3", + "num-bigint", "phf", "serde_json", "sha2", @@ -1708,7 +1703,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -1727,7 +1722,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", @@ -2059,9 +2054,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -2499,18 +2494,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", - "serde", -] - [[package]] name = "num-bigint" version = "0.4.6" @@ -2519,6 +2502,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "serde", ] [[package]] @@ -2553,9 +2537,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -3526,7 +3510,7 @@ version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -4096,9 +4080,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -4214,7 +4198,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", diff --git a/src/portable/local.rs b/src/portable/local.rs index 18b7291c6..d81cd2c10 100644 --- a/src/portable/local.rs +++ b/src/portable/local.rs @@ -405,8 +405,8 @@ pub fn is_valid_local_instance_name(name: &str) -> bool { !was_dash } -pub fn is_valid_cloud_name(name: &str) -> bool { - // For cloud instance name parts (organization slugs and instance names): +pub fn is_valid_cloud_instance_name(name: &str) -> bool { + // For cloud instance name part: // 1. Allow only letters, numbers and single dashes // 2. Must not start or end with a dash // regex: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$ @@ -433,6 +433,34 @@ pub fn is_valid_cloud_name(name: &str) -> bool { !was_dash } +pub fn is_valid_cloud_org_name(name: &str) -> bool { + // For cloud organization slug part: + // 1. Allow only letters, numbers, underscores and single dashes + // 2. Must not end with a dash + // regex: ^-?[a-zA-Z0-9_]+(-[a-zA-Z0-9]+)*$ + let mut chars = name.chars(); + match chars.next() { + Some(c) if c.is_ascii_alphanumeric() || c == '-' || c == '_' => {} + _ => return false, + } + let mut was_dash = false; + for c in chars { + if c == '-' { + if was_dash { + return false; + } else { + was_dash = true; + } + } else { + if !(c.is_ascii_alphanumeric() || c == '_') { + return false; + } + was_dash = false; + } + } + !was_dash +} + #[derive(Debug, thiserror::Error)] #[error("Not a local instance")] pub struct NonLocalInstance; diff --git a/src/portable/options.rs b/src/portable/options.rs index 29cad7ece..5b611030c 100644 --- a/src/portable/options.rs +++ b/src/portable/options.rs @@ -8,7 +8,9 @@ use serde::{Deserialize, Serialize}; use crate::cloud::ops::CloudTier; use crate::commands::ExitCode; use crate::options::{CloudOptions, ConnectionOptions}; -use crate::portable::local::{is_valid_cloud_name, is_valid_local_instance_name}; +use crate::portable::local::{ + is_valid_cloud_instance_name, is_valid_cloud_org_name, is_valid_local_instance_name, +}; use crate::portable::repository::Channel; use crate::portable::ver; use crate::print::{echo, err_marker, warn}; @@ -735,17 +737,17 @@ impl FromStr for InstanceName { type Err = anyhow::Error; fn from_str(name: &str) -> anyhow::Result { if let Some((org_slug, instance_name)) = name.split_once('/') { - if !is_valid_cloud_name(instance_name) { + if !is_valid_cloud_instance_name(instance_name) { anyhow::bail!( "instance name \"{}\" must be a valid identifier, \ regex: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$", instance_name, ); } - if !is_valid_cloud_name(org_slug) { + if !is_valid_cloud_org_name(org_slug) { anyhow::bail!( "org name \"{}\" must be a valid identifier, \ - regex: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$", + regex: ^-?[a-zA-Z0-9_]+(-[a-zA-Z0-9]+)*$", org_slug, ); } diff --git a/tests/shared-client-testcases b/tests/shared-client-testcases index 94099c29e..071f60430 160000 --- a/tests/shared-client-testcases +++ b/tests/shared-client-testcases @@ -1 +1 @@ -Subproject commit 94099c29e0811b0fb1f662b5089fbeaaaa3d4e9f +Subproject commit 071f60430207e331b847e1dcc10cba19c5b5f2f4 diff --git a/tests/shared-client-tests/build.rs b/tests/shared-client-tests/build.rs index 64c87d31b..9d20e003f 100644 --- a/tests/shared-client-tests/build.rs +++ b/tests/shared-client-tests/build.rs @@ -202,7 +202,15 @@ fn connection_{i}() {{ let mut buf = Vec::new(); if let Some(opts) = opts { for (key, value) in opts { - let arg = if let Some(arg) = opt_key_mapping.get(key.as_str()) { + let arg = if key == "instance" { + let argv = value.as_str().unwrap(); + write!( + buf, + r#" + .arg("--instance={argv}")"#, + ); + continue; + } else if let Some(arg) = opt_key_mapping.get(key.as_str()) { arg } else if key == "serverSettings" { continue 'testcase;