refactor: route bash app name validation through go

The bash and go validators previously each kept their own copy of the regex, which had to be updated in lockstep. Both bash wrappers now invoke the existing common binary via the same pattern as `verify_app_name`, leaving go as the single source of truth. The legacy `IsValidAppNameOld` rule is also widened to allow underscores again so apps created under the old naming rules can still be looked up through `VerifyAppName`'s either-rule fallback.
This commit is contained in:
Jose Diaz-Gonzalez
2026-05-09 13:02:54 -04:00
parent 93f87a0f07
commit dbac12e9f1
4 changed files with 43 additions and 15 deletions

View File

@@ -931,18 +931,18 @@ func IsValidAppName(appName string) error {
return errors.New("App name must begin with lowercase alphanumeric character, and may only contain lowercase alphanumerics, dots, and hyphens")
}
// isValidAppNameOld verifies that the app name matches the old naming restrictions
func isValidAppNameOld(appName string) error {
// IsValidAppNameOld verifies that the app name matches the old naming restrictions
func IsValidAppNameOld(appName string) error {
if appName == "" {
return errors.New("Please specify an app to run the command on")
}
r, _ := regexp.Compile("^[a-z0-9][a-z0-9.-]*$")
r, _ := regexp.Compile("^[a-z0-9][a-z0-9._-]*$")
if r.MatchString(appName) {
return nil
}
return errors.New("App name must begin with lowercase alphanumeric character, and may only contain lowercase alphanumerics, dots, and hyphens")
return errors.New("App name must begin with lowercase alphanumeric character, and may only contain lowercase alphanumerics, dots, hyphens, and underscores")
}
// AppDoesNotExist wraps error to include the app name
@@ -981,7 +981,7 @@ func VarArgs(arguments []string, skip int) []string {
// naming conventions exists
func VerifyAppName(appName string) error {
newErr := IsValidAppName(appName)
oldErr := isValidAppNameOld(appName)
oldErr := IsValidAppNameOld(appName)
if newErr != nil && oldErr != nil {
return newErr
}

View File

@@ -94,6 +94,36 @@ func TestCommonIsValidAppName(t *testing.T) {
}
}
func TestCommonIsValidAppNameOld(t *testing.T) {
RegisterTestingT(t)
validNames := []string{
"myapp",
"my-app",
"my.app",
"my_app",
"legacy_app_name",
"app_v2",
}
for _, name := range validNames {
Expect(IsValidAppNameOld(name)).To(Succeed(), "expected %q to be a valid app name", name)
}
invalidNames := []string{
"app;id",
"app$cmd",
"app|cat",
"app/cmd",
"app:cmd",
"App",
"-app",
"_app",
"",
}
for _, name := range invalidNames {
Expect(IsValidAppNameOld(name)).To(HaveOccurred(), "expected %q to be rejected", name)
}
}
func TestCommonIsValidAppNameRejectsShellMetacharacters(t *testing.T) {
RegisterTestingT(t)
invalidNames := []string{

View File

@@ -222,22 +222,14 @@ fn-is-valid-app-name() {
declare desc="verify that the app name matches naming restrictions"
local APP="$1"
[[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ "$APP" =~ ^[a-z0-9][a-z0-9.-]*$ ]]; then
return 0
fi
return 1
"$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet is-valid-app-name "$APP"
}
fn-is-valid-app-name-old() {
declare desc="verify that the app name matches the old naming restrictions"
local APP="$1"
[[ -z "$APP" ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ "$APP" =~ ^[a-z0-9][a-z0-9.-]*$ ]]; then
return 0
fi
return 1
"$PLUGIN_CORE_AVAILABLE_PATH/common/common" --quiet is-valid-app-name-old "$APP"
}
fn-plugn-trigger-exists() {

View File

@@ -86,6 +86,12 @@ func main() {
} else {
fmt.Print("false")
}
case "is-valid-app-name":
appName := flag.Arg(1)
err = common.IsValidAppName(appName)
case "is-valid-app-name-old":
appName := flag.Arg(1)
err = common.IsValidAppNameOld(appName)
case "verify-app-name":
appName := flag.Arg(1)
err = common.VerifyAppName(appName)