From 71e371d1f5b6cf1a2229e85dc5482c9971a5258e Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 19 Mar 2025 18:55:13 +0100 Subject: [PATCH] fix: minor issues with dynamic properties (#1887) * fix: actually check if a property can be dynamic * fix checking of cardinalities We were checking only labeled properties, and so missing any more complex property. * fix: test property exporting to TOML * Fix dependencies * Update index before `alr search` * test for static expressions enforcement * test for enforcing singleton properties * Test for conditional test export * Change Pragma Assert into our own Assert procedure * Deprecate license arrays taking advantage of the new checks * Test both table and array test * Test rejection of license arrays --- .gitmodules | 2 +- BREAKING.md | 1 + scripts/ci-github.sh | 3 +- .../alire-conditional_trees-toml_load.adb | 7 ++- src/alire/alire-conditional_trees.adb | 14 ++++++ src/alire/alire-properties-from_toml.adb | 11 ++++ src/alire/alire-properties-from_toml.ads | 43 +++++++++++++++- src/alire/alire-properties-labeled.adb | 5 -- src/alire/alire-properties-labeled.ads | 20 -------- src/alire/alire-properties-tests.adb | 7 ++- src/alire/alire-releases.adb | 43 ++++++++++------ src/alire/alire-toml_adapters.adb | 7 +-- src/alire/alire-toml_adapters.ads | 16 +++--- src/alire/alire.adb | 10 +++- src/alire/alire.ads | 7 ++- testsuite/drivers/helpers.py | 8 +++ .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../index/cr/crate1/crate1-external.toml | 2 +- .../index/cr/crate2/crate2-external.toml | 2 +- .../tests/index/bad-license-array/test.py | 28 +++++++++++ .../tests/index/bad-license-array/test.yaml | 3 ++ .../tests/index/check-cardinality/test.py | 41 +++++++++++++++ .../tests/index/check-cardinality/test.yaml | 4 ++ testsuite/tests/index/check-dynamic/test.py | 50 +++++++++++++++++++ testsuite/tests/index/check-dynamic/test.yaml | 4 ++ .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-0.1.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../index/cr/crate1/crate1-1.0.0.toml | 2 +- .../index/cr/crate2/crate2-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-2.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../my_index/index/cr/crate/crate-1.0.0.toml | 2 +- .../index/cr/crate1/crate1-1.0.0.toml | 2 +- .../index/cr/crate2a/crate2a-2.0.0.toml | 2 +- .../index/cr/crate2b/crate2b-2.0.0.toml | 2 +- .../index/cr/crate3/crate3-3.0.0.toml | 2 +- .../tests/test/conditional-tests/test.py | 49 ++++++++++++++++++ .../tests/test/conditional-tests/test.yaml | 4 ++ 46 files changed, 347 insertions(+), 84 deletions(-) create mode 100644 testsuite/tests/index/bad-license-array/test.py create mode 100644 testsuite/tests/index/bad-license-array/test.yaml create mode 100644 testsuite/tests/index/check-cardinality/test.py create mode 100644 testsuite/tests/index/check-cardinality/test.yaml create mode 100644 testsuite/tests/index/check-dynamic/test.py create mode 100644 testsuite/tests/index/check-dynamic/test.yaml create mode 100644 testsuite/tests/test/conditional-tests/test.py create mode 100644 testsuite/tests/test/conditional-tests/test.yaml diff --git a/.gitmodules b/.gitmodules index 134ebcbe..92d69327 100644 --- a/.gitmodules +++ b/.gitmodules @@ -15,7 +15,7 @@ url = https://github.com/alire-project/simple_logging.git [submodule "deps/ada-toml"] path = deps/ada-toml - url = https://github.com/pmderodat/ada-toml + url = https://github.com/mosteo/ada-toml [submodule "deps/gnatcoll-slim"] path = deps/gnatcoll-slim url = https://github.com/alire-project/gnatcoll-core.git diff --git a/BREAKING.md b/BREAKING.md index 3ca9d289..13e89e4a 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -8,6 +8,7 @@ may change. - alr: removed remote testing in `alr test` command. - alr: added new behavior to `alr test` and a built-in test runner. - manifest: added `[test]` section. +- manifest: array of licenses is no longer supported (SPDX expressions allow multiple licenses). ### We are here diff --git a/scripts/ci-github.sh b/scripts/ci-github.sh index 1183c2c2..f480febd 100755 --- a/scripts/ci-github.sh +++ b/scripts/ci-github.sh @@ -78,7 +78,8 @@ alr settings --global echo ............................ echo ALR SEARCH: -# List releases for the record +# List releases for the record, ensuring no cached interference +alr index --reset-community alr -q -d search --list --external echo ............................ diff --git a/src/alire/alire-conditional_trees-toml_load.adb b/src/alire/alire-conditional_trees-toml_load.adb index 6406ab7f..4c9b0bf8 100644 --- a/src/alire/alire-conditional_trees-toml_load.adb +++ b/src/alire/alire-conditional_trees-toml_load.adb @@ -120,7 +120,7 @@ package body Alire.Conditional_Trees.TOML_Load is return Tree is Table : constant TOML_Adapters.Key_Queue := - From.Descend (Val, "values"); + From.Descend (Val, "properties of " & Key); Case_Result : Tree; -- We store properties coming from cases separately so for the action @@ -145,6 +145,11 @@ package body Alire.Conditional_Trees.TOML_Load is begin exit when Case_Key = ""; -- Table contains no more cases + if not Resolve then + Table.Checked_Error + ("Dynamic expression not allowed for '" & Key & "'"); + end if; + Case_Result.Append (Process_Case (From, Key, Case_Key, Case_Val)); end; diff --git a/src/alire/alire-conditional_trees.adb b/src/alire/alire-conditional_trees.adb index d2e95c43..3cc30f10 100644 --- a/src/alire/alire-conditional_trees.adb +++ b/src/alire/alire-conditional_trees.adb @@ -469,6 +469,10 @@ package body Alire.Conditional_Trees is -- dependencies) -- Array values with same key are consolidated in a single array -- (e.g., actions, which are created as an array of tables). + -- NOTE: for an array of tables (actions, tests), its To_TOML must + -- return an array for each element rather than a single table per + -- element, so here these arrays can be properly identified and + -- appended. begin @@ -494,6 +498,8 @@ package body Alire.Conditional_Trees is case Current.Kind is when TOML_Table => Table.Set (Key, TOML_Adapters.Merge_Tables (Current, Val)); + -- See comment on top if you see a "Ill-shaped TOML + -- information cannot be merged" error reported here. when TOML_Array => case Val.Kind is when TOML.Atom_Value_Kind | TOML.TOML_Table => @@ -532,6 +538,10 @@ package body Alire.Conditional_Trees is This.Value.Constant_Reference.To_TOML); end To_TOML; + ------------- + -- To_TOML -- + ------------- + overriding procedure To_TOML (This : Vector_Node; Parent : TOML.TOML_Value) is begin @@ -546,6 +556,10 @@ package body Alire.Conditional_Trees is end loop; end To_TOML; + ------------- + -- To_TOML -- + ------------- + overriding function To_TOML (This : Tree) return TOML.TOML_Value is Root_Table : constant TOML.TOML_Value := TOML.Create_Table; diff --git a/src/alire/alire-properties-from_toml.adb b/src/alire/alire-properties-from_toml.adb index faab4296..9d67485e 100644 --- a/src/alire/alire-properties-from_toml.adb +++ b/src/alire/alire-properties-from_toml.adb @@ -48,6 +48,17 @@ package body Alire.Properties.From_TOML is exit Process_Property; end if; + -- Check cardinality of the property; by default the parser + -- allows arrays of tables so we must explicitly diagnose + -- tables that should be unique. + + if Val.Kind = TOML_Array and then Cardinality (Prop) = Unique + then + From.Checked_Error + ("Property '" & Key + & "' cannot be an array, it must be a single value"); + end if; + -- If the property is an array of tables (e.g. actions), -- reconstruct items as a single table to redispatch. -- This ensures that properties that can have dynamic diff --git a/src/alire/alire-properties-from_toml.ads b/src/alire/alire-properties-from_toml.ads index 67ed0e5f..6579742d 100644 --- a/src/alire/alire-properties-from_toml.ads +++ b/src/alire/alire-properties-from_toml.ads @@ -79,6 +79,44 @@ package Alire.Properties.From_TOML is Website => True, others => False); + -- Cardinalities say if a property must be a single value or an array. + -- Since we store properties always as elements in a list, we lose this + -- information after load so we use this not only during loading to enforce + -- index correctness, but also during exporting to ensure the proper type + -- (atom/array) is created. + + type Cardinalities is + (Unique, + -- Must be a single value + Multiple + -- We accept either table or array , but we will always export an array + ); + + Cardinality : constant array (Property_Keys) of Cardinalities := + (Actions => Multiple, + Authors => Multiple, + Auto_GPR_With => Unique, + Build_Profiles => Unique, + Build_Switches => Unique, + Configuration => Unique, + Description => Unique, + Environment => Unique, + Executables => Multiple, + GPR_Externals => Unique, + GPR_Set_Externals => Unique, + Hint => Unique, + Licenses => Unique, + Long_Description => Unique, + Maintainers => Multiple, + Maintainers_Logins => Multiple, + Name => Unique, + Notes => Unique, + Project_Files => Multiple, + Version => Unique, + Website => Unique, + Tags => Multiple, + Test => Multiple); + type Loader_Array is array (Property_Keys range <>) of Property_Loader; -- We use the following arrays to determine which properties may appear @@ -147,8 +185,9 @@ package Alire.Properties.From_TOML is Executables | GPR_Set_Externals | Hint | - Project_Files => True, - others => False); + Project_Files | + Test => True, + others => False); function Loader (From : TOML_Adapters.Key_Queue; Loaders : Loader_Array; diff --git a/src/alire/alire-properties-labeled.adb b/src/alire/alire-properties-labeled.adb index d61d619c..56b584c4 100644 --- a/src/alire/alire-properties-labeled.adb +++ b/src/alire/alire-properties-labeled.adb @@ -85,11 +85,6 @@ package body Alire.Properties.Labeled is Val.Item (I).As_String); use all type Conditional.Properties; begin - if Cardinality (L.Name) = Unique and then I > 1 then - raise Checked_Error with - "Expected single value for " & Key; - end if; - -- Label-specific validation: L.Validate (From); diff --git a/src/alire/alire-properties-labeled.ads b/src/alire/alire-properties-labeled.ads index 96155eff..41178fb6 100644 --- a/src/alire/alire-properties-labeled.ads +++ b/src/alire/alire-properties-labeled.ads @@ -53,26 +53,6 @@ package Alire.Properties.Labeled with Preelaborate is -- One word that identify one of the topic convered by a crate ); - type Cardinalities is (Unique, Multiple); -- Are they atoms or arrays? - -- This information is used during loading to enforce index correctness, - -- and during exporting to ensure the proper type (atom/array) is created. - - Cardinality : array (Labels) of Cardinalities := - (Author => Multiple, - Description => Unique, - Executable => Multiple, - Hint => Unique, - Long_Description => Unique, - Maintainer => Multiple, - Maintainers_Logins => Multiple, - Name => Unique, - Notes => Unique, - Path => Multiple, - Project_File => Multiple, - Version => Unique, - Website => Unique, - Tag => Multiple); - type Label (<>) is new Properties.Property and Interfaces.Tomifiable diff --git a/src/alire/alire-properties-tests.adb b/src/alire/alire-properties-tests.adb index a415b597..8f4f3847 100644 --- a/src/alire/alire-properties-tests.adb +++ b/src/alire/alire-properties-tests.adb @@ -26,7 +26,12 @@ package body Alire.Properties.Tests is Res.Set ("directory", Create_String (S.Directory)); Res.Set ("jobs", Create_Integer (Any_Integer (S.Jobs))); - return Res; + + -- To emit an array of tables, we must return an array of 1 element + + return Arr : constant TOML_Value := Create_Array do + Arr.Append (Res); + end return; end To_TOML; --------------- diff --git a/src/alire/alire-releases.adb b/src/alire/alire-releases.adb index df7bcd14..56b7ffa4 100644 --- a/src/alire/alire-releases.adb +++ b/src/alire/alire-releases.adb @@ -11,6 +11,7 @@ with Alire.Formatting; with Alire.Origins.Deployers.System; with Alire.Paths; with Alire.Properties.Bool; +with Alire.Properties.From_TOML; with Alire.Properties.Scenarios; with Alire.TOML_Load; with Alire.Utils.Tables; @@ -1164,9 +1165,10 @@ package body Alire.Releases is Format : Manifest.Sources) return TOML.TOML_Value is - package APL renames Alire.Properties.Labeled; - use all type Alire.Properties.Labeled.Cardinalities; + use all type Alire.Properties.From_TOML.Cardinalities; use TOML_Adapters; + function Tomlify is + new Tomify_Enum (Alire.Properties.From_TOML.Property_Keys); Root : constant TOML.TOML_Value := R.Properties.To_TOML; begin @@ -1187,20 +1189,29 @@ package body Alire.Releases is end if; -- Ensure atoms are atoms and arrays are arrays - for Label in APL.Cardinality'Range loop - if Root.Has (APL.Key (Label)) then - case APL.Cardinality (Label) is - when Unique => - pragma Assert - (Root.Get - (APL.Key (Label)).Kind in TOML.Atom_Value_Kind); - when Multiple => - Root.Set - (APL.Key (Label), - TOML_Adapters.To_Array - (Root.Get (APL.Key (Label)))); - end case; - end if; + for Prop in Alire.Properties.From_TOML.Cardinality'Range loop + declare + Toml_Key : constant String := Tomlify (Prop).As_String; + begin + if Root.Has (Toml_Key) then + case Alire.Properties.From_TOML.Cardinality (Prop) is + when Unique => + Assert + (Root.Get (Toml_Key).Kind in + TOML.Atom_Value_Kind + | TOML.TOML_Table, + "Expected unique value/table for key '" & Toml_Key + & "' but is: " & Root.Get (Toml_Key).Kind'Image, + Unchecked => True); + -- Unchecked as it shouldn't happen if manifest reading + -- did its checks as intended. + when Multiple => + Root.Set + (Toml_Key, + TOML_Adapters.To_Array (Root.Get (Toml_Key))); + end case; + end if; + end; end loop; -- Origin diff --git a/src/alire/alire-toml_adapters.adb b/src/alire/alire-toml_adapters.adb index 6c2460ed..5a0a3791 100644 --- a/src/alire/alire-toml_adapters.adb +++ b/src/alire/alire-toml_adapters.adb @@ -160,11 +160,12 @@ package body Alire.TOML_Adapters is is pragma Unreferenced (Key); begin - if L.Kind = TOML_Table and then R.Kind = L.Kind then + if L.Kind = TOML_Table and then R.Kind = TOML_Table then return TOML.Merge (L, R, Merge_Internal'Access); else - Raise_Checked_Error - ("Ill-shaped TOML information cannot be merged"); + raise Program_Error with + ("Ill-shaped TOML information cannot be merged: " + & "left is " & L.Kind'Image & ", right is " & R.Kind'Image); end if; end Merge_Internal; begin diff --git a/src/alire/alire-toml_adapters.ads b/src/alire/alire-toml_adapters.ads index 46179776..39be73b6 100644 --- a/src/alire/alire-toml_adapters.ads +++ b/src/alire/alire-toml_adapters.ads @@ -147,10 +147,9 @@ package Alire.TOML_Adapters with Preelaborate is function "+" (Vect : AAA.Strings.Vector) return TOML.TOML_Value; function To_Array (V : TOML.TOML_Value) return TOML.TOML_Value with - Pre => V.Kind in TOML.Atom_Value_Kind or else V.Kind = TOML.TOML_Array, Post => To_Array'Result.Kind = TOML.TOML_Array; - -- Take an atom value and return an array of a single element - -- If already an array, do nothing + -- Take a value and return an array of a single element. + -- If already an array, do nothing. function To_Table (Key : String; Val : TOML.TOML_Value) return TOML.TOML_Value with @@ -165,6 +164,12 @@ package Alire.TOML_Adapters with Preelaborate is -- Take some enumeration image and turn it into a TOML-style key, replacing -- every "_" with a "-" and in lower case. + generic + type Enum is (<>); + function Tomify_Enum (E : Enum) return TOML.TOML_Value with + Post => Tomify_Enum'Result.Kind = TOML.TOML_String; + -- As Tomify function, but taking enumeration values directly + function To_Vector (Val : TOML.TOML_Value) return AAA.Strings.Vector with Pre => Val.Kind = TOML.TOML_Array; @@ -174,11 +179,6 @@ package Alire.TOML_Adapters with Preelaborate is Pre => L.Kind in TOML.TOML_Table and then R.Kind in TOML.TOML_Table, Post => Merge_Tables'Result.Kind in TOML.TOML_Table; - generic - type Enum is (<>); - function Tomify_Enum (E : Enum) return TOML.TOML_Value; - -- As the previous function, but taking enumeration values directly. - private use type UString; -- Allows comparisons between strings and unbounded diff --git a/src/alire/alire.adb b/src/alire/alire.adb index 6a0c23b6..eeeb1f83 100644 --- a/src/alire/alire.adb +++ b/src/alire/alire.adb @@ -163,10 +163,16 @@ package body Alire is -- Assert -- ------------ - procedure Assert (Condition : Boolean; Or_Else : String) is + procedure Assert (Condition : Boolean; + Or_Else : String; + Unchecked : Boolean := False) is begin if not Condition then - Raise_Checked_Error (Msg => Or_Else); + if Unchecked then + raise Program_Error with Errors.Set (Or_Else); + else + Raise_Checked_Error (Msg => Or_Else); + end if; end if; end Assert; diff --git a/src/alire/alire.ads b/src/alire/alire.ads index 069c664c..0ced0d8e 100644 --- a/src/alire/alire.ads +++ b/src/alire/alire.ads @@ -238,8 +238,11 @@ package Alire with Preelaborate is -- Does nothing for successful outcomes. Raises Checked_Error with the -- corresponding message set in Alire.Errors otherwise. - procedure Assert (Condition : Boolean; Or_Else : String); - -- Calls Raise_Checked_Error (Or_Else) when Condition is false + procedure Assert (Condition : Boolean; + Or_Else : String; + Unchecked : Boolean := False); + -- Calls Raise_Checked_Error or raises Program_Error when Condition is + -- false, depending on Unchecked. procedure Raise_Checked_Error (Msg : String) with No_Return; -- For errors where we do not return an Outcome_Failure, we log an error diff --git a/testsuite/drivers/helpers.py b/testsuite/drivers/helpers.py index b7a47101..33482e32 100644 --- a/testsuite/drivers/helpers.py +++ b/testsuite/drivers/helpers.py @@ -279,6 +279,14 @@ def md5sum(file): return file_hash.hexdigest() +def append_to_file(filename : str, lines : []) -> None: + """ + Append the given lines to a file + """ + with open(filename, "at") as file: + file.write("\n".join(lines)) + + def prepend_to_file(filename : str, lines : []) -> None: """ Prepend the given lines to a file diff --git a/testsuite/skels/local-index/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/skels/local-index/my_index/index/cr/crate/crate-1.0.0.toml index 97fb716e..b18c7692 100644 --- a/testsuite/skels/local-index/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/skels/local-index/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/cache/sync-attrs/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/cache/sync-attrs/my_index/index/cr/crate/crate-1.0.0.toml index cb71c192..02dc5ea3 100644 --- a/testsuite/tests/cache/sync-attrs/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/cache/sync-attrs/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/externals/bad-versions/my_index/index/cr/crate1/crate1-external.toml b/testsuite/tests/externals/bad-versions/my_index/index/cr/crate1/crate1-external.toml index 92e4a740..dcd0df98 100644 --- a/testsuite/tests/externals/bad-versions/my_index/index/cr/crate1/crate1-external.toml +++ b/testsuite/tests/externals/bad-versions/my_index/index/cr/crate1/crate1-external.toml @@ -1,6 +1,6 @@ description = "Sample crate" name = "crate1" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/externals/bad-versions/my_index/index/cr/crate2/crate2-external.toml b/testsuite/tests/externals/bad-versions/my_index/index/cr/crate2/crate2-external.toml index e83e1390..73b468b3 100644 --- a/testsuite/tests/externals/bad-versions/my_index/index/cr/crate2/crate2-external.toml +++ b/testsuite/tests/externals/bad-versions/my_index/index/cr/crate2/crate2-external.toml @@ -1,6 +1,6 @@ description = "Sample crate" name = "crate2" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/index/bad-license-array/test.py b/testsuite/tests/index/bad-license-array/test.py new file mode 100644 index 00000000..cce4b123 --- /dev/null +++ b/testsuite/tests/index/bad-license-array/test.py @@ -0,0 +1,28 @@ +"""Test that licenses given as arrays are rejected +""" + +from drivers.alr import alr_manifest, init_local_crate, run_alr +from drivers.asserts import assert_substring +import re + +init_local_crate() + +# Replace "licenses" line in alire.toml with an array +with open("alire.toml", "r") as f: + lines = f.readlines() + +new_lines = [] +for line in lines: + if line.strip().startswith("licenses"): + new_lines.append('licenses = ["MIT"]\n') + else: + new_lines.append(line) + +with open("alire.toml", "w") as f: + f.writelines(new_lines) + +p = run_alr('show', complain_on_error=False) +assert_substring('cannot be an array', p.out) + + +print('SUCCESS') diff --git a/testsuite/tests/index/bad-license-array/test.yaml b/testsuite/tests/index/bad-license-array/test.yaml new file mode 100644 index 00000000..fa855459 --- /dev/null +++ b/testsuite/tests/index/bad-license-array/test.yaml @@ -0,0 +1,3 @@ +driver: python-script +indexes: + compiler_only_index: {} diff --git a/testsuite/tests/index/check-cardinality/test.py b/testsuite/tests/index/check-cardinality/test.py new file mode 100644 index 00000000..0de9c061 --- /dev/null +++ b/testsuite/tests/index/check-cardinality/test.py @@ -0,0 +1,41 @@ +""" +Check that arrays are rejected for singleton properties. +""" + +import os +from drivers.alr import init_local_crate, run_alr, alr_manifest +from drivers.asserts import assert_substring +from drivers.helpers import append_to_file, content_of, replace_in_file +import shutil + +init_local_crate() + +# Make a copy of the original manifest +BACKUP = "alire.toml.bak" +shutil.copyfile(alr_manifest(), BACKUP) + + +def check_prop(prop:str) -> None: + # Restore pristine manifest + shutil.copyfile(BACKUP, alr_manifest()) + append_to_file(alr_manifest(), [f"[[{prop}]]"]) + # Types don't matter as the check happens before deserialization + + p = run_alr("show", complain_on_error=False) + assert_substring("cannot be an array", p.out) + + +# Static props +SINGLE_PROPS = [ + "auto-gpr-with", + "build-profiles", + "build-switches", + "configuration", + "environment", + "gpr-set-externals" +] + +for prop in SINGLE_PROPS: + check_prop(prop) + +print("SUCCESS") diff --git a/testsuite/tests/index/check-cardinality/test.yaml b/testsuite/tests/index/check-cardinality/test.yaml new file mode 100644 index 00000000..90178fa7 --- /dev/null +++ b/testsuite/tests/index/check-cardinality/test.yaml @@ -0,0 +1,4 @@ +driver: python-script +indexes: + compiler_only_index: + in_fixtures: true diff --git a/testsuite/tests/index/check-dynamic/test.py b/testsuite/tests/index/check-dynamic/test.py new file mode 100644 index 00000000..7c7405bb --- /dev/null +++ b/testsuite/tests/index/check-dynamic/test.py @@ -0,0 +1,50 @@ +""" +Check that case expressions are rejected for dynamic properties +""" + +import os +from drivers.alr import init_local_crate, run_alr, alr_manifest +from drivers.asserts import assert_substring +from drivers.helpers import append_to_file, content_of, replace_in_file +import shutil + +init_local_crate() + +# Make a copy of the original manifest +BACKUP = "alire.toml.bak" +shutil.copyfile(alr_manifest(), BACKUP) + + +def check_prop(prop:str) -> None: + # Restore pristine manifest + shutil.copyfile(BACKUP, alr_manifest()) + if prop in content_of(alr_manifest()): + replace_in_file(alr_manifest(), prop, f"{prop}.'case(os)'.'...'") + else: + append_to_file(alr_manifest(), [f"{prop}.'case(os)'.'...' = 'whatever'"]) + # Types don't matter as the check happens before deserialization + + p = run_alr("show", complain_on_error=False) + assert_substring("Dynamic expression not allowed", p.out) + + +# Static props +STATIC_PROPS = [ + "authors", + "auto-gpr-with", + "build-switches", + "description", + "gpr-externals", + "licenses", + "long-description", + "maintainers", + "maintainers-logins", + "tags", + "notes", + "website", +] + +for prop in STATIC_PROPS: + check_prop(prop) + +print("SUCCESS") diff --git a/testsuite/tests/index/check-dynamic/test.yaml b/testsuite/tests/index/check-dynamic/test.yaml new file mode 100644 index 00000000..90178fa7 --- /dev/null +++ b/testsuite/tests/index/check-dynamic/test.yaml @@ -0,0 +1,4 @@ +driver: python-script +indexes: + compiler_only_index: + in_fixtures: true diff --git a/testsuite/tests/index/check-enums/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/index/check-enums/my_index/index/cr/crate/crate-1.0.0.toml index 80a7ae1d..29d88da5 100644 --- a/testsuite/tests/index/check-enums/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/index/check-enums/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/index/env-bad-path/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/index/env-bad-path/my_index/index/cr/crate/crate-1.0.0.toml index c61f329a..8c7f81bc 100644 --- a/testsuite/tests/index/env-bad-path/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/index/env-bad-path/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/index/env-path/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/index/env-path/my_index/index/cr/crate/crate-1.0.0.toml index d8d20095..4ff5081d 100644 --- a/testsuite/tests/index/env-path/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/index/env-path/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-0.1.0.toml b/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-0.1.0.toml index ae06716d..67d90ead 100644 --- a/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-0.1.0.toml +++ b/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-0.1.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "0.1.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-1.0.0.toml index cad1d115..43987868 100644 --- a/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/install/binary-release/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/install/independent/my_index/index/cr/crate1/crate1-1.0.0.toml b/testsuite/tests/install/independent/my_index/index/cr/crate1/crate1-1.0.0.toml index 61c8709b..a683c69d 100644 --- a/testsuite/tests/install/independent/my_index/index/cr/crate1/crate1-1.0.0.toml +++ b/testsuite/tests/install/independent/my_index/index/cr/crate1/crate1-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate1" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/install/independent/my_index/index/cr/crate2/crate2-1.0.0.toml b/testsuite/tests/install/independent/my_index/index/cr/crate2/crate2-1.0.0.toml index 77677151..d619f434 100644 --- a/testsuite/tests/install/independent/my_index/index/cr/crate2/crate2-1.0.0.toml +++ b/testsuite/tests/install/independent/my_index/index/cr/crate2/crate2-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate2" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-1.0.0.toml index 1e49be81..3d1eca38 100644 --- a/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-2.0.0.toml b/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-2.0.0.toml index 356abddd..0b276a2e 100644 --- a/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-2.0.0.toml +++ b/testsuite/tests/misc/hashes/my_index/index/cr/crate/crate-2.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "2.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/pin/manifest-invalid-pins/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/pin/manifest-invalid-pins/my_index/index/cr/crate/crate-1.0.0.toml index 97fb716e..b18c7692 100644 --- a/testsuite/tests/pin/manifest-invalid-pins/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/pin/manifest-invalid-pins/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/provides/metadata/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/provides/metadata/my_index/index/cr/crate/crate-1.0.0.toml index 06f65644..d6cc88b9 100644 --- a/testsuite/tests/provides/metadata/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/provides/metadata/my_index/index/cr/crate/crate-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/publish/private-indexes/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/publish/private-indexes/my_index/index/cr/crate/crate-1.0.0.toml index 623a83b9..c63dcf6b 100644 --- a/testsuite/tests/publish/private-indexes/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/publish/private-indexes/my_index/index/cr/crate/crate-1.0.0.toml @@ -5,7 +5,7 @@ description = "Dummy crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/publish/tarball-plaindir-nonstd/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/publish/tarball-plaindir-nonstd/my_index/index/cr/crate/crate-1.0.0.toml index b3dcdea7..b7bf23b7 100644 --- a/testsuite/tests/publish/tarball-plaindir-nonstd/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/publish/tarball-plaindir-nonstd/my_index/index/cr/crate/crate-1.0.0.toml @@ -5,7 +5,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/publish/tarball-repo-nonstd/my_index/index/cr/crate/crate-1.0.0.toml b/testsuite/tests/publish/tarball-repo-nonstd/my_index/index/cr/crate/crate-1.0.0.toml index b3dcdea7..b7bf23b7 100644 --- a/testsuite/tests/publish/tarball-repo-nonstd/my_index/index/cr/crate/crate-1.0.0.toml +++ b/testsuite/tests/publish/tarball-repo-nonstd/my_index/index/cr/crate/crate-1.0.0.toml @@ -5,7 +5,7 @@ description = "Sample crate" name = "crate" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/show/dependents/my_index/index/cr/crate1/crate1-1.0.0.toml b/testsuite/tests/show/dependents/my_index/index/cr/crate1/crate1-1.0.0.toml index 64a52b40..b8fc0e5d 100644 --- a/testsuite/tests/show/dependents/my_index/index/cr/crate1/crate1-1.0.0.toml +++ b/testsuite/tests/show/dependents/my_index/index/cr/crate1/crate1-1.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate1" version = "1.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/show/dependents/my_index/index/cr/crate2a/crate2a-2.0.0.toml b/testsuite/tests/show/dependents/my_index/index/cr/crate2a/crate2a-2.0.0.toml index 61e3c3a3..484fe2f3 100644 --- a/testsuite/tests/show/dependents/my_index/index/cr/crate2a/crate2a-2.0.0.toml +++ b/testsuite/tests/show/dependents/my_index/index/cr/crate2a/crate2a-2.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate2a" version = "2.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/show/dependents/my_index/index/cr/crate2b/crate2b-2.0.0.toml b/testsuite/tests/show/dependents/my_index/index/cr/crate2b/crate2b-2.0.0.toml index 186fef08..02637aec 100644 --- a/testsuite/tests/show/dependents/my_index/index/cr/crate2b/crate2b-2.0.0.toml +++ b/testsuite/tests/show/dependents/my_index/index/cr/crate2b/crate2b-2.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate2b" version = "2.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/show/dependents/my_index/index/cr/crate3/crate3-3.0.0.toml b/testsuite/tests/show/dependents/my_index/index/cr/crate3/crate3-3.0.0.toml index 81b5dd32..9a8b3b9a 100644 --- a/testsuite/tests/show/dependents/my_index/index/cr/crate3/crate3-3.0.0.toml +++ b/testsuite/tests/show/dependents/my_index/index/cr/crate3/crate3-3.0.0.toml @@ -1,7 +1,7 @@ description = "Sample crate" name = "crate3" version = "3.0.0" -licenses = [] +licenses = "MIT" maintainers = ["any@bo.dy"] maintainers-logins = ["someone"] diff --git a/testsuite/tests/test/conditional-tests/test.py b/testsuite/tests/test/conditional-tests/test.py new file mode 100644 index 00000000..14e776ec --- /dev/null +++ b/testsuite/tests/test/conditional-tests/test.py @@ -0,0 +1,49 @@ +""" +Check that conditional tests can be properly processed and exported, both a +single test given as a table or multiple tests given as an array. +""" + +import os +import shutil +from drivers.alr import alr_manifest, init_local_crate, init_local_crate, run_alr +from drivers.helpers import append_to_file +from drivers.asserts import assert_substring + +CRATE="xxx" + +for mode in ["table", "array"]: + + # Remove crate if it exists + shutil.rmtree(CRATE, ignore_errors=True) + + init_local_crate(CRATE, with_test=False) + + # Add a conditional test + test = ["[[test]]"] if mode == "array" else [] + test.extend([ + "[test.'case(os)'.'...']", + "runner = 'alire'" + ]) + append_to_file(alr_manifest(), test) + + # Initialize the test nested crate + init_local_crate("tests", enter=False) + + # Verify the test runs in all platforms + p = run_alr("test") + assert_substring("[ PASS ] tests", p.out) + + # Verify the crate can be shown after resolving conditional expressions (this is + # equivalent to exporting the crate). `--system` is the key flag to force evaluation. + p = run_alr("--format=YAML", "show", "--system") + assert_substring("""\ +"test": + - "directory": "tests" + "jobs": 0 + "runner": "alire" +""", p.out) + + os.chdir("..") + + +print("SUCCESS") diff --git a/testsuite/tests/test/conditional-tests/test.yaml b/testsuite/tests/test/conditional-tests/test.yaml new file mode 100644 index 00000000..90178fa7 --- /dev/null +++ b/testsuite/tests/test/conditional-tests/test.yaml @@ -0,0 +1,4 @@ +driver: python-script +indexes: + compiler_only_index: + in_fixtures: true -- 2.39.5