From adcdf7c5e65b6c625b6278d9dc56ce97858fc3ac Mon Sep 17 00:00:00 2001 From: "Alejandro R. Mosteo" Date: Wed, 8 Nov 2023 23:15:25 +0100 Subject: [PATCH] Fix bug for interactive crate descr ending with " --- src/alr/alr-commands-init.adb | 56 ++++++++++--------- .../tests/init/interactive-inputs/test.py | 55 ++++++++++++++++++ .../tests/init/interactive-inputs/test.yaml | 2 + 3 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 testsuite/tests/init/interactive-inputs/test.py create mode 100644 testsuite/tests/init/interactive-inputs/test.yaml diff --git a/src/alr/alr-commands-init.adb b/src/alr/alr-commands-init.adb index ec5117c20..da28005aa 100644 --- a/src/alr/alr-commands-init.adb +++ b/src/alr/alr-commands-init.adb @@ -19,6 +19,7 @@ with CLIC.TTY; use CLIC.TTY; package body Alr.Commands.Init is + package TIO renames Ada.Wide_Wide_Text_IO; package UI renames Alire.Utils.User_Input; type Crate_Kind is (Library, Binary); @@ -42,8 +43,6 @@ package body Alr.Commands.Init is procedure Generate (Cmd : Command; Info : Crate_Init_Info) is - - package TIO renames Ada.Wide_Wide_Text_IO; use AAA.Strings; For_Library : constant Boolean := Info.Kind = Library; @@ -78,15 +77,22 @@ package body Alr.Commands.Init is Table.Set ("key", TOML.Create_String (S)); -- Remove excess whitespace and quotation - return - Trim - (Trim - (Trim (Tail (TOML.Dump_As_String (Table), '=')), - ASCII.LF), - '"'); + declare + Result : constant String := + Trim + (Trim + (Tail (TOML.Dump_As_String (Table), '='), + ASCII.LF)); + begin + -- Trimming the TOML quotes at the extremes fails for a + -- string with quotes at the extremes of the string because + -- Ada.Strings.Trim removes those too! So just remove the + -- quotes we know are there. + return Result (Result'First + 1 .. Result'Last - 1); + end; end Escape; - function Q (S : String) return String is ("""" & Escape (S) & """"); + function Q (S : String) return String is ('"' & Escape (S) & '"'); -- Quote string function Q (S : Unbounded_String) return String @@ -242,23 +248,7 @@ package body Alr.Commands.Init is ----------------------- procedure Generate_Manifest is - use Alire.Config; begin - if Builtins.User_Email.Is_Empty or else - Builtins.User_Name.Is_Empty or else - Builtins.User_Github_Login.Is_Empty - then - AAA.Text_IO.Put_Paragraph - ("Alire needs some user information to initialize the crate" - & " author and maintainer, for eventual submission to" - & " the Alire community index. This information will be" - & " interactively requested now."); - TIO.New_Line; - TIO.Put_Line - ("You can edit this information at any time with 'alr config'"); - TIO.New_Line; - end if; - declare -- Retrieve initial values from config or user. Only the name may -- require encoding, as emails and logins cannot contain strange @@ -590,6 +580,7 @@ package body Alr.Commands.Init is procedure Execute (Cmd : in out Command; Args : AAA.Strings.Vector) is + use Alire.Config; Info : Crate_Init_Info; begin @@ -597,6 +588,21 @@ package body Alr.Commands.Init is Reportaise_Wrong_Arguments ("Please provide either --bin or --lib"); end if; + if Builtins.User_Email.Is_Empty or else + Builtins.User_Name.Is_Empty or else + Builtins.User_Github_Login.Is_Empty + then + AAA.Text_IO.Put_Paragraph + ("Alire needs some user information to initialize the crate" + & " author and maintainer, for eventual submission to" + & " the Alire community index. This information will be" + & " interactively requested now."); + TIO.New_Line; + TIO.Put_Line + ("You can edit this information at any time with 'alr config'"); + TIO.New_Line; + end if; + Query_Crate_Name (Args, Info); if Cmd.Bin then diff --git a/testsuite/tests/init/interactive-inputs/test.py b/testsuite/tests/init/interactive-inputs/test.py new file mode 100644 index 000000000..e874729e6 --- /dev/null +++ b/testsuite/tests/init/interactive-inputs/test.py @@ -0,0 +1,55 @@ +""" +Validate tricky user inputs during crate initialization +""" + +import os +import shutil + +from drivers.alr import run_alr, run_alr_interactive +from drivers.asserts import assert_eq + + +def check(descr: str = "", name: str = ""): + """ + Initialize a crate with given description and name + """ + run_alr_interactive(['init', '--bin', 'xxx'], + output=['> ' for _ in range(7)], + input=[descr, # Description + name, # Full user name + '', # Github login + '', # Email + '', # License + '', # Tags + ''], # Website + timeout=3) + + # Check that it can be shown, which will load the manifest + os.chdir("xxx") + p = run_alr("show") + + # Verify the description and author in output match the input + + # Description is in first line after the ": " + assert_eq(p.out.splitlines()[0].split(": ", 1)[1], descr) + + # Author is in the fourth line after the ": " + assert_eq(p.out.splitlines()[3].split(": ", 1)[1], name) + + # Prepare for next iteration + os.chdir("..") + shutil.rmtree("xxx") + + # Unset the user information so it is re-asked next time + run_alr('config', '--global', '--unset', 'user.name') + # Other fields are not being set because they use the defaults so don't + # require unsetting. + + +# Try a few tricky inputs +check('hello "world"', 'Robert "Bobby" Tables') +check('"hello" "world"', '"Bobby" Robert Tables') +check('""""""', '"Bobby" Robert "Tables"') + + +print('SUCCESS') diff --git a/testsuite/tests/init/interactive-inputs/test.yaml b/testsuite/tests/init/interactive-inputs/test.yaml new file mode 100644 index 000000000..187c05aa3 --- /dev/null +++ b/testsuite/tests/init/interactive-inputs/test.yaml @@ -0,0 +1,2 @@ +driver: python-script +indexes: {}