This is an automated email from the ASF dual-hosted git repository.

dcremonini pushed a commit to branch 
feat/allow_digits_in_configuration_key_names
in repository https://gitbox.apache.org/repos/asf/openserverless-task.git

commit 3f0dad68a473491b17c63f7e01a406d54d2efff8
Author: Daniele Cremonini <[email protected]>
AuthorDate: Mon Sep 30 22:09:00 2024 +0200

    feat: allow digit in a non leading position (e.g. MINIO_CONFIG_INGRESS_S3)
---
 util/config/configurator.js                        | 58 +++++++---------------
 util/config/configurator/configurator.ts           |  2 +-
 util/config/configurator/tests/fixtures/valid.json |  6 +++
 util/config/configurator/tests/index.test.ts       | 11 +++-
 4 files changed, 36 insertions(+), 41 deletions(-)

diff --git a/util/config/configurator.js b/util/config/configurator.js
index 8eb7f70..ddd2877 100644
--- a/util/config/configurator.js
+++ b/util/config/configurator.js
@@ -662,7 +662,7 @@ async function askMissingData(missingData) {
     let askedForPassword = false;
     if (Array.isArray(prompt.type)) {
       const selected = await ie({
-        message: `Pick a value for '${key}'`,
+        message: prompt.label || `Pick a value for '${key}'`,
         options: prompt.type.map((v2) => ({ label: v2, value: v2 }))
       });
       if (!selected) {
@@ -672,7 +672,7 @@ async function askMissingData(missingData) {
       inputFromPrompt = selected.toString();
     } else if (prompt.type === "bool") {
       const selected = await ie({
-        message: `Pick a true/false for '${key}'`,
+        message: prompt.label || `Pick a true/false for '${key}'`,
         options: [
           { label: "true", value: "true" },
           { label: "false", value: "false" }
@@ -685,7 +685,7 @@ async function askMissingData(missingData) {
       inputFromPrompt = selected.toString();
     } else if (prompt.type === "password") {
       const input = await re({
-        message: `Enter password value for ${key}`
+        message: prompt.label || `Enter password value for ${key}`
       });
       if (hD(input)) {
         ue("Operation cancelled");
@@ -695,7 +695,7 @@ async function askMissingData(missingData) {
       askedForPassword = true;
     } else {
       const input = await te({
-        message: `Enter value for ${key} (${prompt.type})`
+        message: prompt.label || `Enter value for ${key} (${prompt.type})`
       });
       if (hD(input)) {
         ue("Operation cancelled");
@@ -767,56 +767,36 @@ async function parsePositionalFile(path) {
     return { success: false, message: NotValidJsonMsg };
   }
 }
-function validateConfigJson(body) {
+function isInputConfigValid(body) {
   if (Object.keys(body).length === 0) {
-    return { success: false, message: BadConfigMsg };
+    return false;
   }
   for (const key in body) {
+    console.log("PROD - isInputConfigValid - " + key);
     const value = body[key];
     if (typeof value !== "object") {
-      return { success: false, message: BadConfigMsg };
+      return false;
     }
     if (!value.type) {
-      return { success: false, message: BadConfigMsg };
+      return false;
     }
     if (!["string", "int", "float", "bool", "password"].includes(value.type) 
&& !Array.isArray(value.type)) {
-      return { success: false, message: BadConfigMsg };
+      return false;
     }
   }
   for (const key in body) {
-    if (!/^[A-Z][A-Z_]*[A-Z]$/.test(key)) {
-      return { success: false, message: BadConfigMsg };
+    const resCheck = /^[A-Z][A-Z_]*[A-Z]$/.test(key);
+    console.log("PROD - isInputConfigValid - regexp check - for --- " + key + 
", " + resCheck);
+    if (!/^[A-Z][A-Z0-9]*(_[A-Z][A-Z0-9]*)*$/.test(key)) {
+      return false;
     }
   }
-  return { success: true };
+  return true;
 }
 var OPS = process.env.OPS || "ops";
 var AdditionalArgsMsg = "Additional arguments will be ignored.";
 var NotValidJsonMsg = "Not a valid JSON file";
-var BadConfigMsg = `Bad configuration file. 
-
-The configuration file must be an non-empty JSON with the following structure:
-    
-{
-  "KEY": {
-    type: "string"
-  },
-  "OTHER_KEY": {
-    type: "int"
-  },
-  ...
-} 
-
-The keys must be uppercase words (separated by underscores).
-The value for the "type" key must be either string with the following values:
-- string
-- int
-- float
-- bool
-- password
-
-or an array of strings with specific values (an enum).
-`;
+var BadConfigMsg = "Bad configuration file. Check the help message (-h) to see 
the expected format.";
 var HelpMsg = `
 Usage: config <configjson>
 
@@ -832,6 +812,7 @@ The config.json file must be a JSON file with the following 
structure:
       "type": "string"
     },
     "OTHER_KEY": {
+      "label": "An optional custom message",
       "type": "int"
     },
     ...
@@ -870,9 +851,8 @@ async function main() {
     return process.exit(1);
   }
   const config = jsonRes.body;
-  const validationRes = validateConfigJson(config);
-  if (!validationRes.success) {
-    ue(validationRes.message);
+  if (!isInputConfigValid(config)) {
+    ue(BadConfigMsg);
     return process.exit(1);
   }
   const { exitCode, stderr, stdout } = await $2`${OPS} -config -d`.quiet();
diff --git a/util/config/configurator/configurator.ts 
b/util/config/configurator/configurator.ts
index b24bb35..ec7befa 100644
--- a/util/config/configurator/configurator.ts
+++ b/util/config/configurator/configurator.ts
@@ -306,7 +306,7 @@ export function isInputConfigValid(body: Record<string, 
any>): boolean {
 
   // 3. Check that all the keys are uppercase and can only have underscores 
not at the beginning or end
   for (const key in body) {
-    if (!/^[A-Z][A-Z_]*[A-Z]$/.test(key)) {
+    if (!/^[A-Z][A-Z_]|[0-9]*[A-Z]|[0-9]$/.test(key)) {
       return false;
     }
   }
diff --git a/util/config/configurator/tests/fixtures/valid.json 
b/util/config/configurator/tests/fixtures/valid.json
index 1587c92..8ad24f6 100644
--- a/util/config/configurator/tests/fixtures/valid.json
+++ b/util/config/configurator/tests/fixtures/valid.json
@@ -1,5 +1,11 @@
 {
   "HELLO": {
     "type": "string"
+  },
+  "HELLO3": {
+    "type": "string"
+  },
+  "HELLO_3": {
+    "type": "string"
   }
 }
diff --git a/util/config/configurator/tests/index.test.ts 
b/util/config/configurator/tests/index.test.ts
index bdf74d0..0d10cc3 100644
--- a/util/config/configurator/tests/index.test.ts
+++ b/util/config/configurator/tests/index.test.ts
@@ -56,11 +56,18 @@ describe("validateConfigJson", () => {
   test("valid json", async () => {
     const res = isInputConfigValid({
       HELLO: { type: "string" },
+      HELLO3: { type: "string" },
+      HELLO33: { type: "string" },
+      HELLO_3: { type: "string" },
+      HELLO_33: { type: "string" },
+      HELLO_A_1_B_2: { type: "string" },
+      HELLO_A1B2: { type: "string" },
       HELLO_INT: { type: "int" },
       HELLO_FLOAT: { type: "float" },
       HELLO_BOOL: { type: "bool" },
       HELLOPASS: { type: "password" },
       HELLOENUM: { type: ["a", "b", "c"] },
+      HELLOENUM3: { type: ["a", "b", "c"] },
     });
     expect(res).toBe(true);
   });
@@ -109,6 +116,8 @@ describe("parsePositionalFile", () => {
   test("valid json", async () => {
     const jsonRes = await parsePositionalFile("tests//fixtures/valid.json");
     expect(jsonRes.success).toBe(true);
-    expect(jsonRes.body).toEqual({ HELLO: { type: "string" } });
+    expect(jsonRes.body).toHaveProperty("HELLO", { type: "string" }  );
+    expect(jsonRes.body).toHaveProperty("HELLO3", { type: "string" } );
+    expect(jsonRes.body).toHaveProperty("HELLO_3", { type: "string" });
   });
 });

Reply via email to