From eb1e0b81af88fab15a0bfadfb7e132d99a507ab2 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Tue, 12 Sep 2023 14:27:59 +0200 Subject: [PATCH 1/6] New `ALR_TRACEBACK_ENABLED` env. var. (#1450) * Add traceback enabling env var * Test for new config var --- .gitmodules | 3 + alire.gpr | 1 + alire.toml | 2 + alr_env.gpr | 1 + deps/dirty_booleans | 1 + src/alire/alire-builds-hashes.adb | 4 +- src/alire/alire-environment-loading.adb | 173 ++++++++++++++++++ src/alire/alire-environment-loading.ads | 24 +++ src/alire/alire-environment.adb | 181 ++----------------- src/alire/alire-environment.ads | 25 +-- src/alire/alire-roots.adb | 6 +- src/alire/alire.adb | 3 +- testsuite/tests/misc/env-traceback/test.py | 36 ++++ testsuite/tests/misc/env-traceback/test.yaml | 1 + 14 files changed, 268 insertions(+), 193 deletions(-) create mode 160000 deps/dirty_booleans create mode 100644 src/alire/alire-environment-loading.adb create mode 100644 src/alire/alire-environment-loading.ads create mode 100644 testsuite/tests/misc/env-traceback/test.py create mode 100644 testsuite/tests/misc/env-traceback/test.yaml diff --git a/.gitmodules b/.gitmodules index 5d4d3201c..fc56fd8ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -57,3 +57,6 @@ [submodule "deps/diskflags"] path = deps/diskflags url = https://github.com/mosteo/diskflags +[submodule "deps/dirty_booleans"] + path = deps/dirty_booleans + url = https://github.com/mosteo/dirty_booleans diff --git a/alire.gpr b/alire.gpr index e7c8f2b45..3490e92de 100644 --- a/alire.gpr +++ b/alire.gpr @@ -4,6 +4,7 @@ with "alire_common"; with "ajunitgen"; with "ansiada"; with "clic"; +with "dirty_booleans"; with "diskflags"; with "gnatcoll"; with "minirest"; diff --git a/alire.toml b/alire.toml index 31dfb506d..0647d91cc 100644 --- a/alire.toml +++ b/alire.toml @@ -20,6 +20,7 @@ ada_toml = "~0.3" ajunitgen = "^1.0.1" ansiada = "^1.0" clic = "~0.3" +dirty_booleans = "~0.1" diskflags = "~0.1" gnatcoll = "^21" minirest = "~0.3" @@ -49,6 +50,7 @@ windows = { ALIRE_OS = "windows" } aaa = { url = "https://github.com/mosteo/aaa", commit = "ecc38772bd4a6b469b54c62363766ea1c0e9f912" } ada_toml = { url = "https://github.com/mosteo/ada-toml", commit = "da4e59c382ceb0de6733d571ecbab7ea4919b33d" } clic = { url = "https://github.com/alire-project/clic", commit = "6879b90876a1c918b4e112f59c6db0e25b713f52" } +dirty_booleans = { url = "https://github.com/mosteo/dirty_booleans", branch = "main" } diskflags = { url = "https://github.com/mosteo/diskflags", branch = "main" } gnatcoll = { url = "https://github.com/alire-project/gnatcoll-core.git", commit = "4e663b87a028252e7e074f054f8f453661397166" } minirest = { url = "https://github.com/mosteo/minirest.git", commit = "9a9c660f9c6f27f5ef75417e7fac7061dff14d78" } diff --git a/alr_env.gpr b/alr_env.gpr index dda7596d8..0fbb9ba12 100644 --- a/alr_env.gpr +++ b/alr_env.gpr @@ -14,6 +14,7 @@ aggregate project Alr_Env is "deps/ajunitgen", "deps/ansi", "deps/clic", + "deps/dirty_booleans", "deps/diskflags", "deps/gnatcoll-slim", "deps/minirest", diff --git a/deps/dirty_booleans b/deps/dirty_booleans new file mode 160000 index 000000000..05c40d88e --- /dev/null +++ b/deps/dirty_booleans @@ -0,0 +1 @@ +Subproject commit 05c40d88ecfe109e575ec8b21dd6ffa2e61df1dc diff --git a/src/alire/alire-builds-hashes.adb b/src/alire/alire-builds-hashes.adb index b80dddcb8..324f29eb8 100644 --- a/src/alire/alire-builds-hashes.adb +++ b/src/alire/alire-builds-hashes.adb @@ -1,6 +1,6 @@ with Alire.Crate_Configuration.Hashes; with Alire.Directories; -with Alire.Environment; +with Alire.Environment.Loading; with Alire.GPR; with Alire.Hashes.SHA256_Impl; with Alire.Paths; @@ -249,7 +249,7 @@ package body Alire.Builds.Hashes is Trace.Debug ("build hashing root " & Root.Path); This.Hashes.Clear; - Environment.Load (Context, Root, For_Hashing => True); + Environment.Loading.Load (Context, Root, For_Hashing => True); Env := Context.Get_All; Root.Configuration.Ensure_Complete; diff --git a/src/alire/alire-environment-loading.adb b/src/alire/alire-environment-loading.adb new file mode 100644 index 000000000..7c2a72071 --- /dev/null +++ b/src/alire/alire-environment-loading.adb @@ -0,0 +1,173 @@ +with Alire_Early_Elaboration; +with Alire.Environment.Formatting; +with Alire.GPR; +with Alire.Platforms.Current; +with Alire.Properties.Scenarios; +with Alire.Releases; +with Alire.Solutions; +with Alire.Toolchains.Solutions; +with Alire.Utils.TTY; + +with GNAT.IO; + +package body Alire.Environment.Loading is + + ---------- + -- Load -- + ---------- + + Already_Warned : Boolean := False; + + procedure Load (This : in out Context; + Root : in out Alire.Roots.Root; + For_Hashing : Boolean := False) + is + Solution : constant Solutions.Solution := + Toolchains.Solutions.Add_Toolchain (Root.Solution); + Tool_Root : Roots.Editable.Root := + Roots.Editable.New_Root (Root); + -- We use a copy of the base root to add the toolchain elements that + -- might be missing from its solution + begin + Tool_Root.Set (Solution); + + -- Load platform environment + Alire.Platforms.Current.Load_Environment (This); + + -- Warnings when setting up an incomplete environment + + if not Solution.Is_Complete then + Trace.Debug ("Generating possibly incomplete environment" + & " because of missing dependencies"); + + -- Normally we would generate a warning, but since that will pollute + -- the output making it unusable, for once we write directly to + -- stderr (unless quiet is in effect): + + if not Alire_Early_Elaboration.Switch_Q and then not Already_Warned + then + Already_Warned := True; + + GNAT.IO.Put_Line + (GNAT.IO.Standard_Error, + TTY.Warn ("warn:") + & " Generating possibly incomplete environment" + & " because of missing dependencies"); + end if; + end if; + + -- Project paths for all releases in the solution, implicitly defined by + -- supplied project files. + + if not For_Hashing then + declare + Sorted_Paths : constant AAA.Strings.Set := + Tool_Root.Current.Project_Paths; + begin + if not Sorted_Paths.Is_Empty then + for Path of reverse Sorted_Paths loop + -- Reverse should not matter as our paths shouldn't overlap, + -- but at least is nicer for user inspection to respect + -- alphabetical order. + + This.Prepend ("GPR_PROJECT_PATH", Path, "crates"); + end loop; + end if; + end; + end if; + + -- Custom definitions provided by each release + + for Rel of Solution.Releases.Including (Root.Release) loop + Load (This => This, + Root => Tool_Root, + Crate => Rel.Name, + For_Hashing => For_Hashing); + end loop; + + This.Set ("ALIRE", "True", "Alire"); + end Load; + + ---------- + -- Load -- + ---------- + + procedure Load (This : in out Context; + Root : in out Roots.Editable.Root; + Crate : Crate_Name; + For_Hashing : Boolean := False) + is + Env : constant Properties.Vector := Root.Current.Environment; + Rel : constant Releases.Release := Root.Current.Release (Crate); + Origin : constant String := Rel.Name_Str; + + Release_Base : constant String + := (if For_Hashing + then Rel.Base_Folder + else Root.Current.Release_Base (Rel.Name, Roots.For_Build)); + -- Before we can known the Release_Base, we supplant it with its + -- simple name. This shouldn't be a problem for hashing, as this + -- is only used for $CRATE_ROOT paths, and the important parts + -- that might merit a hash change are the rest of the path. + begin + Trace.Debug ("Loading environment for crate " + & Alire.Utils.TTY.Name (Crate) + & " release: " & Rel.Milestone.TTY_Image); + + -- Environment variables defined in the crate manifest + for Act of Rel.Environment (Env) loop + Trace.Debug ("Processing env entry: " & Act.Name + & " of type " & Act.Action'Image + & " with value " & Act.Value); + begin + declare + Value : constant String := + Formatting.Format (Release_Base, Act.Value); + begin + case Act.Action is + + when Properties.Environment.Set => + + This.Set (Act.Name, Value, Origin & " (env)"); + + when Properties.Environment.Append => + + This.Append (Act.Name, Value, Origin & " (env)"); + + when Properties.Environment.Prepend => + + This.Prepend (Act.Name, Value, Origin & " (env)"); + + end case; + end; + exception + when Formatting.Unknown_Formatting_Key => + Raise_Checked_Error + ("Unknown environment variable formatting key in var '" & + Act.Name & " of '" & Origin & "'"); + end; + end loop; + + -- Environment variables for GPR external scenario variables + for Property of Rel.On_Platform_Properties (Env) loop + if Property in Alire.Properties.Scenarios.Property'Class then + declare + use all type Alire.GPR.Variable_Kinds; + Variable : constant Alire.GPR.Variable + := Alire.Properties.Scenarios.Property (Property).Value; + begin + if Variable.Kind = External then + This.Set (Variable.Name, Variable.External_Value, + Origin & " (gpr ext)"); + end if; + end; + end if; + end loop; + + -- Set the crate PREFIX location for access to resources + This.Set (AAA.Strings.To_Upper_Case (+Rel.Name) & "_ALIRE_PREFIX", + Release_Base, + "Crate prefix for resources location"); + end Load; + +end Alire.Environment.Loading; diff --git a/src/alire/alire-environment-loading.ads b/src/alire/alire-environment-loading.ads new file mode 100644 index 000000000..2a6d741c2 --- /dev/null +++ b/src/alire/alire-environment-loading.ads @@ -0,0 +1,24 @@ +with Alire.Roots.Editable; + +package Alire.Environment.Loading is + + procedure Load (This : in out Context; + Root : in out Alire.Roots.Root; + For_Hashing : Boolean := False); + -- Load the environment variables of a releases found in the workspace + -- Solution (GPR_PROJECT_PATH and custom variables) in the context. If + -- For_Hashing, skip or mock actions that require the build hash which is + -- part of the build path. We use this to gather all configuration when + -- paths aren't yet known (as they depend on the hash that is computed + -- from the configuration which will become itself part of the path). + +private + + procedure Load (This : in out Context; + Root : in out Roots.Editable.Root; + Crate : Crate_Name; + For_Hashing : Boolean := False); + -- Load the environment variables of a release (GPR_PROJECT_PATH and custom + -- variables) in the context. See note in previous Load about For_Hashing. + +end Alire.Environment.Loading; diff --git a/src/alire/alire-environment.adb b/src/alire/alire-environment.adb index 4aa71d4b8..1a34cc841 100644 --- a/src/alire/alire-environment.adb +++ b/src/alire/alire-environment.adb @@ -2,21 +2,11 @@ with GNAT.OS_Lib; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; -with Alire_Early_Elaboration; -with Alire.Environment.Formatting; with Alire.Errors; with Alire.Properties.Environment; use Alire.Properties.Environment; with Alire.OS_Lib; -with Alire.GPR; -with Alire.Properties.Scenarios; -with Alire.Releases; -with Alire.Roots.Editable; -with Alire.Solutions; -with Alire.Toolchains.Solutions; -with Alire.Utils.TTY; -with Alire.Platforms.Current; -with GNAT.IO; +with Dirty_Booleans; package body Alire.Environment is @@ -77,163 +67,6 @@ package body Alire.Environment is This.Add (Name, Action); end Prepend; - ---------- - -- Load -- - ---------- - - Already_Warned : Boolean := False; - - procedure Load (This : in out Context; - Root : in out Alire.Roots.Root; - For_Hashing : Boolean := False) - is - Solution : constant Solutions.Solution := - Toolchains.Solutions.Add_Toolchain (Root.Solution); - Tool_Root : Roots.Editable.Root := - Roots.Editable.New_Root (Root); - -- We use a copy of the base root to add the toolchain elements that - -- might be missing from its solution - begin - Tool_Root.Set (Solution); - - -- Load platform environment - Alire.Platforms.Current.Load_Environment (This); - - -- Warnings when setting up an incomplete environment - - if not Solution.Is_Complete then - Trace.Debug ("Generating possibly incomplete environment" - & " because of missing dependencies"); - - -- Normally we would generate a warning, but since that will pollute - -- the output making it unusable, for once we write directly to - -- stderr (unless quiet is in effect): - - if not Alire_Early_Elaboration.Switch_Q and then not Already_Warned - then - Already_Warned := True; - - GNAT.IO.Put_Line - (GNAT.IO.Standard_Error, - TTY.Warn ("warn:") - & " Generating possibly incomplete environment" - & " because of missing dependencies"); - end if; - end if; - - -- Project paths for all releases in the solution, implicitly defined by - -- supplied project files. - - if not For_Hashing then - declare - Sorted_Paths : constant AAA.Strings.Set := - Tool_Root.Current.Project_Paths; - begin - if not Sorted_Paths.Is_Empty then - for Path of reverse Sorted_Paths loop - -- Reverse should not matter as our paths shouldn't overlap, - -- but at least is nicer for user inspection to respect - -- alphabetical order. - - This.Prepend ("GPR_PROJECT_PATH", Path, "crates"); - end loop; - end if; - end; - end if; - - -- Custom definitions provided by each release - - for Rel of Solution.Releases.Including (Root.Release) loop - This.Load (Root => Tool_Root, - Crate => Rel.Name, - For_Hashing => For_Hashing); - end loop; - - This.Set ("ALIRE", "True", "Alire"); - end Load; - - ---------- - -- Load -- - ---------- - - procedure Load (This : in out Context; - Root : in out Roots.Editable.Root; - Crate : Crate_Name; - For_Hashing : Boolean := False) - is - Env : constant Properties.Vector := Root.Current.Environment; - Rel : constant Releases.Release := Root.Current.Release (Crate); - Origin : constant String := Rel.Name_Str; - - Release_Base : constant String - := (if For_Hashing - then Rel.Base_Folder - else Root.Current.Release_Base (Rel.Name, Roots.For_Build)); - -- Before we can known the Release_Base, we supplant it with its - -- simple name. This shouldn't be a problem for hashing, as this - -- is only used for $CRATE_ROOT paths, and the important parts - -- that might merit a hash change are the rest of the path. - begin - Trace.Debug ("Loading environment for crate " - & Alire.Utils.TTY.Name (Crate) - & " release: " & Rel.Milestone.TTY_Image); - - -- Environment variables defined in the crate manifest - for Act of Rel.Environment (Env) loop - Trace.Debug ("Processing env entry: " & Act.Name - & " of type " & Act.Action'Image - & " with value " & Act.Value); - begin - declare - Value : constant String := - Formatting.Format (Release_Base, Act.Value); - begin - case Act.Action is - - when Properties.Environment.Set => - - This.Set (Act.Name, Value, Origin & " (env)"); - - when Properties.Environment.Append => - - This.Append (Act.Name, Value, Origin & " (env)"); - - when Properties.Environment.Prepend => - - This.Prepend (Act.Name, Value, Origin & " (env)"); - - end case; - end; - exception - when Formatting.Unknown_Formatting_Key => - Raise_Checked_Error - ("Unknown environment variable formatting key in var '" & - Act.Name & " of '" & Origin & "'"); - end; - end loop; - - -- Environment variables for GPR external scenario variables - for Property of Rel.On_Platform_Properties (Env) loop - if Property in Alire.Properties.Scenarios.Property'Class then - declare - use all type Alire.GPR.Variable_Kinds; - Variable : constant Alire.GPR.Variable := - Alire.Properties.Scenarios.Property (Property).Value; - begin - if Variable.Kind = External then - This.Set (Variable.Name, Variable.External_Value, - Origin & " (gpr ext)"); - end if; - end; - end if; - end loop; - - -- Set the crate PREFIX location for access to resources - This.Set (AAA.Strings.To_Upper_Case (+Rel.Name) & "_ALIRE_PREFIX", - Release_Base, - "Crate prefix for resources location"); - end Load; - ----------------- -- Print_Shell -- ----------------- @@ -420,4 +253,16 @@ package body Alire.Environment is end return; end Get_All; + ----------------------- + -- Traceback_Enabled -- + ----------------------- + + function Traceback_Enabled return Boolean + is + package Dirty is new Dirty_Booleans; + use type Dirty.Boolean; + begin + return Dirty.Value (OS_Lib.Getenv (Traceback, "false")) = True; + end Traceback_Enabled; + end Alire.Environment; diff --git a/src/alire/alire-environment.ads b/src/alire/alire-environment.ads index e15784491..778e33d16 100644 --- a/src/alire/alire-environment.ads +++ b/src/alire/alire-environment.ads @@ -2,7 +2,6 @@ with Ada.Strings.Unbounded; with Alire.Properties; with Alire.Platforms; -limited with Alire.Roots.Editable; private with Ada.Strings.Unbounded.Hash; private with Ada.Containers.Vectors; @@ -10,7 +9,7 @@ private with Ada.Containers.Hashed_Maps; private with Alire.Properties.Environment; private with Ada.Containers.Generic_Array_Sort; -package Alire.Environment is +package Alire.Environment with Preelaborate is Config : constant String := "ALR_CONFIG"; -- Folder where current alr will look for configuration @@ -18,6 +17,11 @@ package Alire.Environment is Testsuite : constant String := "ALR_TESTSUITE"; -- If defined, we are running under the testsuite harness + Traceback : constant String := "ALR_TRACEBACK_ENABLED"; + -- If set to True/1, dump unexpected exceptions to console (same as `-d`) + + function Traceback_Enabled return Boolean; + type Context is tagged limited private; procedure Set (This : in out Context; Name, Value, Origin : String); @@ -29,16 +33,6 @@ package Alire.Environment is procedure Prepend (This : in out Context; Name, Value, Origin : String); -- Prepend a value to a variable in the context - procedure Load (This : in out Context; - Root : in out Alire.Roots.Root; - For_Hashing : Boolean := False); - -- Load the environment variables of a releases found in the workspace - -- Solution (GPR_PROJECT_PATH and custom variables) in the context. If - -- For_Hashing, skip or mock actions that require the build hash which is - -- part of the build path. We use this to gather all configuration when - -- paths aren't yet known (as they depend on the hash that is computed - -- from the configuration which will become itself part of the path). - procedure Export (This : Context); -- Export the environment variables built from the variables previously -- loaded and defined in the context to the OS. @@ -111,11 +105,4 @@ private procedure Add (This : in out Context; Name : String; Action : Env_Action); - procedure Load (This : in out Context; - Root : in out Roots.Editable.Root; - Crate : Crate_Name; - For_Hashing : Boolean := False); - -- Load the environment variables of a release (GPR_PROJECT_PATH and custom - -- variables) in the context. See note in previous Load about For_Hashing. - end Alire.Environment; diff --git a/src/alire/alire-roots.adb b/src/alire/alire-roots.adb index 23f83ab95..1b2fd5048 100644 --- a/src/alire/alire-roots.adb +++ b/src/alire/alire-roots.adb @@ -4,7 +4,7 @@ with Alire.Builds; with Alire.Conditional; with Alire.Dependencies.Containers; with Alire.Directories; -with Alire.Environment; +with Alire.Environment.Loading; with Alire.Errors; with Alire.Flags; with Alire.Install; @@ -218,7 +218,7 @@ package body Alire.Roots is is begin return Context : Alire.Environment.Context do - Context.Load (This); + Alire.Environment.Loading.Load (Context, This); end return; end Build_Context; @@ -1120,7 +1120,7 @@ package body Alire.Roots is procedure Export_Build_Environment (This : in out Root) is Context : Alire.Environment.Context; begin - Context.Load (This); + Alire.Environment.Loading.Load (Context, This); Context.Export; end Export_Build_Environment; diff --git a/src/alire/alire.adb b/src/alire/alire.adb index 3e2ea7eff..42c814ae0 100644 --- a/src/alire/alire.adb +++ b/src/alire/alire.adb @@ -1,5 +1,6 @@ with AAA.Debug; +with Alire.Environment; with Alire.Errors; with Alire.Warnings; with Alire.Utils.TTY; @@ -76,7 +77,7 @@ package body Alire is Log (Exception_Information (E), Level); Log ("--->8--- Exception dump end ----->8---", Level); - if Log_Debug then + if Log_Debug or else Environment.Traceback_Enabled then Err_Log (Exception_Name (E)); Err_Log (Full_Msg); Err_Log (Exception_Information (E)); diff --git a/testsuite/tests/misc/env-traceback/test.py b/testsuite/tests/misc/env-traceback/test.py new file mode 100644 index 000000000..fb2dceaea --- /dev/null +++ b/testsuite/tests/misc/env-traceback/test.py @@ -0,0 +1,36 @@ +""" +Check ALR_TRACEBACK_ENABLED env var +""" + +import os +from drivers.alr import run_alr +from drivers.asserts import assert_eq, assert_match + +def check_no_traceback(): + assert_eq('ERROR: Raising forcibly\n' + 'ERROR: alr encountered an unexpected error,' + ' re-run with -d for details.\n', + run_alr("dev", "--raise", + debug=False, complain_on_error=False).out) + + +def check_traceback(): + assert_match(".*0x", # appears in both symbolic and raw tracebacks + run_alr("dev", "--raise", + debug=False, complain_on_error=False).out) + + +# By default (no `-d` or ALR_TRACEBACK_ENABLED) we don't get a backtrace + +check_no_traceback() +for val in ["", "0", "false", "no"]: + os.environ['ALR_TRACEBACK_ENABLED'] = val + check_no_traceback() + +# With ALR_TRACEBACK_ENABLED we do get a backtrace + +for val in ["1", "true", "yes"]: + os.environ['ALR_TRACEBACK_ENABLED'] = val + check_traceback() + +print('SUCCESS') diff --git a/testsuite/tests/misc/env-traceback/test.yaml b/testsuite/tests/misc/env-traceback/test.yaml new file mode 100644 index 000000000..32c747b3f --- /dev/null +++ b/testsuite/tests/misc/env-traceback/test.yaml @@ -0,0 +1 @@ +driver: python-script From afd93970f856a2018fd293da48c5706523cf2133 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 13 Sep 2023 09:58:59 +0200 Subject: [PATCH 2/6] Use the same Find function in "show" as in "show --jekyll" (#1452) This fixes #1402. --- src/alr/alr-commands-show.adb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alr/alr-commands-show.adb b/src/alr/alr-commands-show.adb index ebaff44f0..4730cd8a3 100644 --- a/src/alr/alr-commands-show.adb +++ b/src/alr/alr-commands-show.adb @@ -230,7 +230,7 @@ package body Alr.Commands.Show is Rel : constant Alire.Releases.Release := (if Current then Cmd.Root.Release - else Query.Find (Name, Versions, Query_Policy)); + else Cmd.Find_Target_Release (Name, Versions, Current)); begin Put_Line ("---"); Put_Line ("layout: crate"); From 698a71251830132ef4a7f9538dc5ca0b8d7d9992 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 13 Sep 2023 11:59:22 +0200 Subject: [PATCH 3/6] Remove old release-sharing mechanism remnants (#1451) --- src/alire/alire-dependencies-states.adb | 6 -- src/alire/alire-dependencies-states.ads | 21 +------ src/alire/alire-solutions-diffs.adb | 24 -------- src/alire/alire-solutions.adb | 14 ++--- src/alire/alire-solutions.ads | 3 +- src/alire/alire-solver.adb | 57 ++++--------------- src/alire/alire-solver.ads | 5 -- src/alire/alire-toolchains-solutions.adb | 3 +- src/alire/alire-toolchains.adb | 11 ++-- src/alire/alire-toolchains.ads | 6 +- .../tests/solver/compiler-installed/test.py | 14 ++--- .../tests/solver/compiler-mixing/test.py | 16 +++--- .../tests/solver/compiler-priorities/test.py | 14 ++--- .../tests/solver/compiler-selected/test.py | 8 +-- testsuite/tests/toolchain/directories/test.py | 6 +- 15 files changed, 58 insertions(+), 150 deletions(-) diff --git a/src/alire/alire-dependencies-states.adb b/src/alire/alire-dependencies-states.adb index 818db6a76..44e75ab18 100644 --- a/src/alire/alire-dependencies-states.adb +++ b/src/alire/alire-dependencies-states.adb @@ -58,7 +58,6 @@ package body Alire.Dependencies.States is Pinned : constant String := "pinned"; Reason : constant String := "reason"; Release : constant String := "release"; - Shared : constant String := "shared"; Transitivity : constant String := "transitivity"; Versions : constant String := "versions"; @@ -124,8 +123,6 @@ package body Alire.Dependencies.States is "release: " & (+Crate)), Manifest.Index, Strict => False)); -- because it may come from elsewhere - Data.Shared := - From.Checked_Pop (Keys.Shared, TOML_Boolean).As_Boolean; end case; return Data; @@ -194,9 +191,6 @@ package body Alire.Dependencies.States is (Keys.Release, This.Fulfilled.Release.Constant_Reference.To_TOML (Manifest.Index)); - Table.Set - (Keys.Shared, - Create_Boolean (This.Fulfilled.Shared)); end case; end To_TOML; diff --git a/src/alire/alire-dependencies-states.ads b/src/alire/alire-dependencies-states.ads index 597ae86c3..3b7b27427 100644 --- a/src/alire/alire-dependencies-states.ads +++ b/src/alire/alire-dependencies-states.ads @@ -68,8 +68,7 @@ package Alire.Dependencies.States is -- Modify transitivity in a copy of Base function Solving (Base : State; - Using : Releases.Release; - Shared : Boolean := False) + Using : Releases.Release) return State with Pre => Using.Provides (Base.Crate); -- Uses release to fulfill this dependency in a copy of Base @@ -108,8 +107,6 @@ package Alire.Dependencies.States is function Is_Provided (This : State) return Boolean; -- True when the release name is different from the dependency crate - function Is_Shared (This : State) return Boolean; - function Is_User_Pinned (This : State) return Boolean; -- From the POV of users, pinning to version or linking to dir is a pin @@ -227,7 +224,6 @@ private Opt_Rel : Stored_Release; -- This might not be filled-in when Solved => Release : Stored_Release; -- This is always valid - Shared : Boolean; -- The release is from shared install when Missed => Reason : Missed_Reasons := Skipped; -- Until solving is attempted when others => null; @@ -319,9 +315,6 @@ private & (if This.Has_Release then ",release" else "") - & (if This.Is_Shared - then ",installed" - else "") else "") & (if This.Pinning.Pinned then ",pin=" & This.Pinning.Version.Image @@ -353,9 +346,6 @@ private function Is_Provided (This : State) return Boolean is (This.Has_Release and then This.Release.Name /= This.Crate); - function Is_Shared (This : State) return Boolean - is (This.Fulfilled.Fulfillment = Solved and then This.Fulfilled.Shared); - function Is_Solved (This : State) return Boolean is (This.Fulfilled.Fulfillment = Solved); @@ -538,14 +528,12 @@ private ------------- function Solving (Base : State; - Using : Releases.Release; - Shared : Boolean := False) + Using : Releases.Release) return State is (Base.As_Dependency with Name_Len => Base.Name_Len, Fulfilled => (Fulfillment => Solved, - Release => To_Holder (Using), - Shared => Shared), + Release => To_Holder (Using)), Pinning => Base.Pinning, Transitivity => Base.Transitivity); @@ -582,9 +570,6 @@ private & (if This.Has_Release then "," & TTY.OK ("release") else "") - & (if This.Is_Shared - then "," & TTY.Emph ("installed") - else "") else "") & (if This.Pinning.Pinned then "," & TTY.Emph ("pin") diff --git a/src/alire/alire-solutions-diffs.adb b/src/alire/alire-solutions-diffs.adb index d102b5afd..ed854037e 100644 --- a/src/alire/alire-solutions-diffs.adb +++ b/src/alire/alire-solutions-diffs.adb @@ -22,7 +22,6 @@ package body Alire.Solutions.Diffs is Unpinned, -- A release being unpinned Unchanged, -- An unchanged dependency/release Missing, -- A missing dependency - Shared, -- A release used from the shared installed releases Binary -- A binary, system or external release ); @@ -42,7 +41,6 @@ package body Alire.Solutions.Diffs is when Unpinned => TTY.Emph (U ("🎈")), -- alts: π©’πŸŽˆ when Unchanged => TTY.OK (U ("=")), when Missing => TTY.Error (U ("❗")), -- alts: βš οΈβ—β€ΌοΈ - when Shared => TTY.Emph (U ("♻️ ")), -- alts: β™»β™»οΈβ™ΌπŸ«΄ when Binary => TTY.Warn (U ("πŸ“¦"))) else (case Change is @@ -55,7 +53,6 @@ package body Alire.Solutions.Diffs is when Unpinned => U ("o"), when Unchanged => U ("="), when Missing => U ("!"), - when Shared => U ("i"), when Binary => U ("b") )); @@ -179,25 +176,6 @@ package body Alire.Solutions.Diffs is end if; end Fulfil_Change; - -------------------- - -- Sharing_Change -- - -------------------- - - procedure Sharing_Change is - begin - if (not Has_Former or else not Former.Is_Shared) - and then Has_Latter and then Latter.Is_Shared - then - Add_Change (Chg, Icon (Shared), TTY.Emph ("installed")); - - elsif Has_Former and then Former.Is_Shared - and then Has_Latter and then not Latter.Is_Shared - then - Add_Change (Chg, "", TTY.Emph ("local")); - - end if; - end Sharing_Change; - -------------------------- -- transitivity_changed -- -------------------------- @@ -369,8 +347,6 @@ package body Alire.Solutions.Diffs is Fulfil_Change; - Sharing_Change; - Provider_Change; Transitivity_Changed; diff --git a/src/alire/alire-solutions.adb b/src/alire/alire-solutions.adb index 02797e698..ce1274cd3 100644 --- a/src/alire/alire-solutions.adb +++ b/src/alire/alire-solutions.adb @@ -429,8 +429,7 @@ package body Alire.Solutions is Release : Alire.Releases.Release; Env : Properties.Vector; For_Dependency : Optional.Crate_Name := Optional.Crate_Names.Empty; - Add_Dependency : Boolean := False; - Shared : Boolean := False) + Add_Dependency : Boolean := False) return Solution is Dep_Name : constant Crate_Name := (if Add_Dependency @@ -459,8 +458,7 @@ package body Alire.Solutions is Result.Dependencies := Result.Dependencies.Including (Result.State (Dep_Name).Solving - (Release.Whenever (Env), - Shared => Shared)); + (Release.Whenever (Env))); -- TODO: remove this Whenever once dynamic expr can be exported elsif Result.State (Dep_Name).Is_Hinted then Result := Result.Hinting (Result.State (Dep_Name).As_Dependency); @@ -484,7 +482,7 @@ package body Alire.Solutions is Result.Dependencies := Result.Dependencies.Including (This.State (Dep.Crate) - .Solving (Release.Whenever (Env), Shared => Shared)); + .Solving (Release.Whenever (Env))); end if; end loop; @@ -743,8 +741,6 @@ package body Alire.Solutions is else "") & (if Dep.Is_Pinned or else Dep.Is_Linked then TTY.Emph (" (pinned)") - elsif Dep.Is_Shared - then TTY.Emph (" (installed)") else "") & (if Detailed then " (origin: " @@ -1466,10 +1462,10 @@ package body Alire.Solutions is begin -- Visit first dependencies that do not have releases (and hence no - -- dependencies) or that are preinstalled. + -- dependencies). for Dep of This.Dependencies loop - if not Dep.Has_Release or else Dep.Is_Shared then + if not Dep.Has_Release then Visit (Dep); end if; end loop; diff --git a/src/alire/alire-solutions.ads b/src/alire/alire-solutions.ads index ca6a1e498..cacac1885 100644 --- a/src/alire/alire-solutions.ads +++ b/src/alire/alire-solutions.ads @@ -97,8 +97,7 @@ package Alire.Solutions is Release : Alire.Releases.Release; Env : Properties.Vector; For_Dependency : Optional.Crate_Name := Optional.Crate_Names.Empty; - Add_Dependency : Boolean := False; - Shared : Boolean := False) + Add_Dependency : Boolean := False) return Solution with Pre => Add_Dependency xor diff --git a/src/alire/alire-solver.adb b/src/alire/alire-solver.adb index fe6adab4e..867b82a40 100644 --- a/src/alire/alire-solver.adb +++ b/src/alire/alire-solver.adb @@ -257,7 +257,7 @@ package body Alire.Solver is -- to select the solver behavior (e.g. stop after the first complete -- solution is found). - Installed : constant Releases.Containers.Release_Set := + Tools : constant Releases.Containers.Release_Set := Toolchains.Available (Detect_Externals => Options.Detecting = Detect); @@ -396,8 +396,7 @@ package body Alire.Solver is ------------------ procedure Expand_Value (Dep : Dependencies.Dependency; - Raw_Dep : Dependencies.Dependency; - Allow_Shared : Boolean) is + Raw_Dep : Dependencies.Dependency) is -- Dep is the unique dependency in the solution that aglutinates -- all dependencies on the same crate that have been seen to date. -- Raw_Dep, instead, is the simple dependency that is being tested @@ -509,11 +508,11 @@ package body Alire.Solver is Trace.Debug ("SOLVER: gnat PASS " & Boolean' - (Installed.Contains (R))'Image + (Tools.Contains (R))'Image & " for " & R.Milestone.TTY_Image & " due to installed compiler availability."); - return Installed.Contains (R); + return Tools.Contains (R); else @@ -530,10 +529,8 @@ package body Alire.Solver is ----------- procedure Check (R : Release; - Is_Shared : Boolean; Is_Reused : Boolean) is - use all type Origins.Kinds; begin -- Special compiler checks are hardcoded when the dependency is @@ -614,7 +611,6 @@ package body Alire.Solver is ("SOLVER: dependency FROZEN: " & R.Milestone.Image & " to satisfy " & Dep.TTY_Image & (if Is_Reused then " with REUSED" else "") & - (if Is_Shared then " with INSTALLED" else "") & (if not R.Provides.Is_Empty then " also providing " & R.Provides.Image_One_Line else "") & @@ -632,10 +628,7 @@ package body Alire.Solver is Solution => Solution.Including (R, Props, For_Dependency => - Optional.Crate_Names.Unit (Dep.Crate), - Shared => - Is_Shared or else - R.Origin.Kind = Binary_Archive))); + Optional.Crate_Names.Unit (Dep.Crate)))); end; end if; end Check; @@ -741,7 +734,7 @@ package body Alire.Solver is Trace.Debug ("SOLVER short-cutting due to version pin" & " with valid release in index"); - Check (Release, Is_Shared => False, Is_Reused => False); + Check (Release, Is_Reused => False); end loop; -- There may be no satisfying releases, or even so the @@ -788,22 +781,6 @@ package body Alire.Solver is -- will have to), we should do this globally since this is -- information common to all search states. - ------------------ - -- Check_Shared -- - ------------------ - - procedure Check_Shared is - begin - - -- Solve with all installed dependencies that satisfy it - - for R of reverse Installed.Satisfying (Dep) loop - Satisfiable := True; - Check (R, Is_Shared => True, Is_Reused => False); - end loop; - - end Check_Shared; - use type Alire.Dependencies.Dependency; --------------------- @@ -893,8 +870,6 @@ package body Alire.Solver is for In_Sol of Solution.Dependencies_Providing (Dep.Crate) loop if In_Sol.Has_Release then Check (In_Sol.Release, - Is_Shared => - In_Sol.Is_Shared, Is_Reused => True); end if; end loop; @@ -903,17 +878,6 @@ package body Alire.Solver is end if; - if Allow_Shared then - - -- There is a shared release we can use for this dependency; we - -- prefer this option first. If more solutions than the first - -- complete one are sought, we can still try without the shared - -- release. - - Check_Shared; - - end if; - if Pins.Depends_On (Dep.Crate) and then Pins.State (Dep.Crate).Is_Pinned then @@ -959,9 +923,9 @@ package body Alire.Solver is (R.Satisfies (Dep) and then (Dep.Crate /= GNAT_Crate or else - Installed.Contains (R))); + Tools.Contains (R))); - Check (R, Is_Shared => False, Is_Reused => False); + Check (R, Is_Reused => False); end Consider; begin Trace.Debug ("SOLVER: considering" @@ -1191,10 +1155,10 @@ package body Alire.Solver is -- Add or merge dependency .Dependency (State.Target.Value.Crate), -- And use it in expansion - Raw_Dep => State.Target.Value, + Raw_Dep => State.Target.Value -- We also pass the plain dependency for the -- Seen collection inside the search state. - Allow_Shared => Options.Sharing = Allow_Shared); + ); elsif State.Target.Is_Vector then if State.Target.Conjunction = Anded then @@ -1362,7 +1326,6 @@ package body Alire.Solver is Exhaustive => Options.Exhaustive, Detecting => Options.Detecting, Hinting => Options.Hinting, - Sharing => Options.Sharing, Timeout => Options.Timeout, Timeout_More => Options.Timeout_More, Elapsed => Timer.Elapsed, diff --git a/src/alire/alire-solver.ads b/src/alire/alire-solver.ads index 238811388..7eb7d6c7d 100644 --- a/src/alire/alire-solver.ads +++ b/src/alire/alire-solver.ads @@ -57,10 +57,6 @@ package Alire.Solver is -- releases will be used normally; otherwise a crate with only externals -- will always cause failure. - type Sharing_Policies is (Allow_Shared, Only_Local); - -- * Allow_Shared: crates in the shared config can appear in solutions. - -- * Only_Local: only crates in the local workspace will be used. - type Timeout_Policies is (Ask, -- Normal interaction with user Stop, -- Abort at first timeout @@ -134,7 +130,6 @@ package Alire.Solver is -- only the given Completeness is used. Detecting : Detection_Policies := Detect; Hinting : Hinting_Policies := Hint; - Sharing : Sharing_Policies := Allow_Shared; On_Timeout : Timeout_Policies := Ask; Timeout : Duration := 5.0; diff --git a/src/alire/alire-toolchains-solutions.adb b/src/alire/alire-toolchains-solutions.adb index 11a53119c..288cf8ebc 100644 --- a/src/alire/alire-toolchains-solutions.adb +++ b/src/alire/alire-toolchains-solutions.adb @@ -58,8 +58,7 @@ package body Alire.Toolchains.Solutions is (Target => Tool_Milestone (Tool), Detect_Externals => Tool_Is_External (Tool)), Env => Root.Platform_Properties, - Add_Dependency => True, - Shared => True); + Add_Dependency => True); else Trace.Debug ("Toolchain environment: tool not in solution nor " & "defined by the user: " & Tool.TTY_Image); diff --git a/src/alire/alire-toolchains.adb b/src/alire/alire-toolchains.adb index a96abbe3a..5ba56ec9c 100644 --- a/src/alire/alire-toolchains.adb +++ b/src/alire/alire-toolchains.adb @@ -191,7 +191,7 @@ package body Alire.Toolchains is -- whole system. We only offer external compilers detected in the -- environment.) - -- Deploy as a shared install unless external + -- Deploy to toolchains location unless external if Release.Origin.Is_Index_Provided then Toolchains.Deploy (Release); @@ -503,7 +503,7 @@ package body Alire.Toolchains is Stop := False; if Kind (Item) = Directory then if Exists (Full_Name (Item) / Paths.Crate_File_Name) then - Trace.Debug ("Detected shared release at " + Trace.Debug ("Detected toolchain release at " & TTY.URL (Full_Name (Item))); Result.Include @@ -512,12 +512,13 @@ package body Alire.Toolchains is Source => Manifest.Index, Strict => True)); else - Warnings.Warn_Once ("Unexpected folder in shared crates path: " - & TTY.URL (Full_Name (Item))); + Warnings.Warn_Once + ("Unexpected folder in toolchain crates path: " + & TTY.URL (Full_Name (Item))); end if; else - Warnings.Warn_Once ("Unexpected file in shared crates path: " + Warnings.Warn_Once ("Unexpected file in toolchain crates path: " & TTY.URL (Full_Name (Item))); end if; end Detect; diff --git a/src/alire/alire-toolchains.ads b/src/alire/alire-toolchains.ads index 4b232b45e..d2848e071 100644 --- a/src/alire/alire-toolchains.ads +++ b/src/alire/alire-toolchains.ads @@ -125,8 +125,8 @@ package Alire.Toolchains is -- Constraint_Error if not among Available. function Path return Any_Path; - -- Returns the base folder in which all shared releases live, defaults to - -- /toolchains + -- Returns the base folder in which all toolchain releases live, defaults + -- to /toolchains procedure Deploy (Release : Releases.Release; Location : Any_Path := Path); @@ -139,7 +139,7 @@ package Alire.Toolchains is or else raise Checked_Error with Errors.Set ("Requested release is not installed: " & Release.Milestone.TTY_Image); - -- Remove a release from the shared location for the configuration + -- Remove a release from the toolchains location for the configuration procedure Remove (Target : Milestones.Milestone; diff --git a/testsuite/tests/solver/compiler-installed/test.py b/testsuite/tests/solver/compiler-installed/test.py index 25a59082d..2b2e95373 100644 --- a/testsuite/tests/solver/compiler-installed/test.py +++ b/testsuite/tests/solver/compiler-installed/test.py @@ -31,7 +31,7 @@ # Check that a generic dependency results in the external being used alr_with("gnat") -match_solution(f"gnat={version} (gnat_external) (installed)", escape=True) +match_solution(f"gnat={version} (gnat_external)", escape=True) # Check that requesting a version different to the one externally available # results in missing compiler, as Alire won't try to install one. @@ -44,34 +44,34 @@ run_alr("toolchain", "--install", "gnat_cross_2") run_alr("update") -match_solution("gnat=1.0.0 (gnat_cross_2) (installed)", escape=True) +match_solution("gnat=1.0.0 (gnat_cross_2)", escape=True) # Likewise, if we install a native compiler, it will be preferred to a # cross-compiler. run_alr("toolchain", "--install", "gnat_native") run_alr("update") -match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True) +match_solution("gnat=8888.0.0 (gnat_native)", escape=True) # If we remove the version exclusion, the external compiler will still be # preferred as there is no selected compiler yet. alr_with("gnat", delete=True, manual=False) alr_with("gnat") -match_solution(f"gnat={version} (gnat_external) (installed)", escape=True) +match_solution(f"gnat={version} (gnat_external)", escape=True) # But, if the user selects a compiler as preferred, it will be used first run_alr("config", "--set", "toolchain.use.gnat", "gnat_cross_2=7777.0.0") run_alr("update") -match_solution("gnat=1.0.0 (gnat_cross_2) (installed)", escape=True) +match_solution("gnat=1.0.0 (gnat_cross_2)", escape=True) # Finally, if the crate requests explicitly an uninstalled compiler, it will be # downloaded, installed, and used before the rest of installed compilers. alr_with("gnat_cross_1") -match_solution("gnat=9999.0.0 (gnat_cross_1) (installed)", escape=True) -match_solution("gnat_cross_1=9999.0.0 (installed)", escape=True) +match_solution("gnat=9999.0.0 (gnat_cross_1)", escape=True) +match_solution("gnat_cross_1=9999.0.0", escape=True) # Verify it was actually installed p = run_alr("toolchain") assert_match(".*gnat_cross_1\s+9999.0.0\s+Available", p.out) diff --git a/testsuite/tests/solver/compiler-mixing/test.py b/testsuite/tests/solver/compiler-mixing/test.py index 8323a5b14..a8fd3fc3c 100644 --- a/testsuite/tests/solver/compiler-mixing/test.py +++ b/testsuite/tests/solver/compiler-mixing/test.py @@ -39,14 +39,14 @@ # gnat x gnat results in the external available compiler being used, preferred # over the native also available compiler (but not selected) -match_solution(f"gnat={version} (gnat_external) (installed)", +match_solution(f"gnat={version} (gnat_external)", escape=True) # If we add a precise dependency on e.g. the installed native compiler, this # should override the external compiler alr_with("gnat_native") -match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True) -match_solution("gnat_native=8888.0.0 (installed)", escape=True) +match_solution("gnat=8888.0.0 (gnat_native)", escape=True) +match_solution("gnat_native=8888.0.0", escape=True) # Let us swap the generic dependency with a targeted dependency, starting from # scratch @@ -57,8 +57,8 @@ alr_with("gnat") # In this case the only possible solution is with the targeted compiler -match_solution("gnat=" + e("8888.0.0 (gnat_native) (installed)") + ".*" + - "gnat_native=" + e("8888.0.0 (installed)") + ".*") +match_solution("gnat=" + e("8888.0.0 (gnat_native)") + ".*" + + "gnat_native=" + e("8888.0.0") + ".*") # Second, we check a root targeted gnat with both dependencies @@ -69,8 +69,8 @@ # In this case the only possible solution is with the targeted compiler. The # Generic dependency also appears, coming from the dep_generic crate -match_solution("gnat=" + e("8888.0.0 (gnat_native) (installed)") + ".*" + - "gnat_native=" + e("8888.0.0 (installed)") + ".*") +match_solution("gnat=" + e("8888.0.0 (gnat_native)") + ".*" + + "gnat_native=" + e("8888.0.0") + ".*") # Last combination is targeted x targeted os.chdir("..") @@ -80,7 +80,7 @@ # In this case the only possible solution is with the targeted compiler. The # generic dependency no longer exists, as nobody requested a generic gnat. -match_solution("gnat_native=" + e("8888.0.0 (installed)") + ".*") +match_solution("gnat_native=" + e("8888.0.0") + ".*") p = run_alr("with", "--solve") assert "gnat=" not in p.out, "Unexpected output" diff --git a/testsuite/tests/solver/compiler-priorities/test.py b/testsuite/tests/solver/compiler-priorities/test.py index 82b69aa77..9b469d60e 100644 --- a/testsuite/tests/solver/compiler-priorities/test.py +++ b/testsuite/tests/solver/compiler-priorities/test.py @@ -37,13 +37,13 @@ # Check that a generic dependency results in the external being used alr_with("gnat") -match_solution(f"gnat={version} (gnat_external) (installed)", escape=True) +match_solution(f"gnat={version} (gnat_external)", escape=True) # Check that adding a second dependency on native packaged compiler is honored. # Both dependencies should appear in the solution. alr_with("gnat_native") -match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True) -match_solution("gnat_native=8888.0.0 (installed)", escape=True) +match_solution("gnat=8888.0.0 (gnat_native)", escape=True) +match_solution("gnat_native=8888.0.0", escape=True) # The previous dependency also should have caused the installation of the # native compiler as an available compiler, which we will check: @@ -67,7 +67,7 @@ # Depend on any gnat. Since no default is selected, the external one is used, # even if other installed compilers are newer (cross_2=9999) alr_with("gnat") -match_solution(f"gnat={version} (gnat_external) (installed)", escape=True) +match_solution(f"gnat={version} (gnat_external)", escape=True) # Depend on any gnat but the externally available. Since we have gnat_native=8888 # and gnat_cross_1=9999, normal version comparison would select the cross @@ -95,7 +95,7 @@ run_alr("config", "--global", "--set", "toolchain.use.gnat", "gnat_cross_1=9999") run_alr("update") -match_solution("gnat=9999.0.0 (gnat_cross_1) (installed)", escape=True) +match_solution("gnat=9999.0.0 (gnat_cross_1)", escape=True) # Check that a targeted compiler is retrieved when needed. Note that another # cross-compiler is still selected as default, but since we need a different @@ -103,11 +103,11 @@ init_local_crate("zzz") alr_with("gnat") # Will be solved with the selected cross compiler 1 -match_solution("gnat=9999.0.0 (gnat_cross_1) (installed)", escape=True) +match_solution("gnat=9999.0.0 (gnat_cross_1)", escape=True) alr_with("gnat_cross_2") # Now, this compiler should appear in the solution and be available, as it # overrides the preferred compiler -match_solution("gnat_cross_2=1.0.0 (installed)", escape=True) +match_solution("gnat_cross_2=1.0.0", escape=True) print('SUCCESS') diff --git a/testsuite/tests/solver/compiler-selected/test.py b/testsuite/tests/solver/compiler-selected/test.py index 2c4006274..0b9072e37 100644 --- a/testsuite/tests/solver/compiler-selected/test.py +++ b/testsuite/tests/solver/compiler-selected/test.py @@ -18,19 +18,19 @@ alr_with("gnat*") # Will appear in the solution as generic fulfilled by the preferred compiler -match_solution("gnat=8888.0.0 (gnat_native) (installed)", escape=True) +match_solution("gnat=8888.0.0 (gnat_native)", escape=True) # Selecting another default will cause a corresponding change in the solution run_alr("config", "--set", "toolchain.use.gnat", "gnat_cross_2=1") run_alr("update") -match_solution("gnat=1.0.0 (gnat_cross_2) (installed)", escape=True) +match_solution("gnat=1.0.0 (gnat_cross_2)", escape=True) # Adding another incompatible compiler dependency should result in overriding # the configured one alr_with("gnat_cross_1") # Both dependencies will appear in the solution, matching the same crate -match_solution("gnat=9999.0.0 \(gnat_cross_1\) \(installed\).*" - "gnat_cross_1=9999.0.0 \(installed\)") +match_solution("gnat=9999.0.0 \(gnat_cross_1\).*" + "gnat_cross_1=9999.0.0") print('SUCCESS') diff --git a/testsuite/tests/toolchain/directories/test.py b/testsuite/tests/toolchain/directories/test.py index 34c98be25..808d97e20 100644 --- a/testsuite/tests/toolchain/directories/test.py +++ b/testsuite/tests/toolchain/directories/test.py @@ -1,5 +1,5 @@ """ -Check created folders are where expected when installing binary compiler crates +Check created folders are where expected when downloading binary compiler crates """ import os @@ -49,7 +49,7 @@ def check_content(crate): # nor in local folder init_local_crate("xxx") alr_with("gnat_external") -match_solution("gnat_external=.* \(installed\)") +match_solution("gnat_external=.*") paths = contents(cache_dir, "gnat_external") assert len(paths) == 0, "Unexpected contents: " + str(paths) paths = contents(".", "gnat_external") @@ -58,7 +58,7 @@ def check_content(crate): # Require a cross compiler and verify it is automatically installed alr_with("gnat_external", delete=True, manual=False) alr_with("gnat_cross_1") -match_solution("gnat_cross_1=.* \(installed\)") +match_solution("gnat_cross_1=.*") check_content("gnat_cross_1") print('SUCCESS') From 5641f848ce98be6f4b9060162b6627cbc3be753d Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 13 Sep 2023 14:58:58 +0200 Subject: [PATCH 4/6] Fix bug in dependency traversal order (#1445) * Fix bug in solution traversal related to linked releases * New test * CI fixes --- src/alire/alire-solutions.adb | 15 +++++++-- .../tests/crate_config/no-rebuilds/test.py | 1 - testsuite/tests/solver/traverse-order/test.py | 33 +++++++++++++++++++ .../tests/solver/traverse-order/test.yaml | 3 ++ 4 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 testsuite/tests/solver/traverse-order/test.py create mode 100644 testsuite/tests/solver/traverse-order/test.yaml diff --git a/src/alire/alire-solutions.adb b/src/alire/alire-solutions.adb index ce1274cd3..7fce6794f 100644 --- a/src/alire/alire-solutions.adb +++ b/src/alire/alire-solutions.adb @@ -1433,6 +1433,7 @@ package body Alire.Solutions is Root : Alire.Releases.Containers.Optional := Alire.Releases.Containers.Optional_Releases.Empty) is + Rels : constant Release_Map := This.Releases; Pending : State_Map := This.Dependencies; Visited : Containers.Crate_Name_Sets.Set; Round : Natural := 0; @@ -1485,16 +1486,24 @@ package body Alire.Solutions is for Dep of Pending loop - if not Dep.Is_Solved then - Trace.Debug ("Round" & Round'Img & ": NOOP " + if Dep.Is_Missing then + -- This leaves solved/linked to visit + Trace.Debug ("Round" & Round'Img & ": VISIT ready (missing) " & Dep.Release.Milestone.Image); To_Remove.Insert (Dep.Crate, Dep); elsif + -- Some dependency is still unvisited, either under its own + -- name or through some alias. These nested fors may merit + -- optimization in the future? (for some Rel_Dep of Dep.Release.Flat_Dependencies (Alire.Root.Platform_Properties) => - not Visited.Contains (Rel_Dep.Crate)) + not Visited.Contains (Rel_Dep.Crate) + and then + not (for some Rel of Rels => + Visited.Contains (Rel.Name) + and then Rel.Provides (Rel_Dep.Crate))) then Trace.Debug ("Round" & Round'Img & ": SKIP not-ready " & Dep.Release.Milestone.Image); diff --git a/testsuite/tests/crate_config/no-rebuilds/test.py b/testsuite/tests/crate_config/no-rebuilds/test.py index 29b8c16a3..7715f9c24 100644 --- a/testsuite/tests/crate_config/no-rebuilds/test.py +++ b/testsuite/tests/crate_config/no-rebuilds/test.py @@ -2,7 +2,6 @@ Ensure that no unnecessary rebuilds happend due to crate config generation """ -import os from drivers.alr import alr_with, init_local_crate, run_alr from drivers.asserts import assert_match from drivers.helpers import prepend_to_file diff --git a/testsuite/tests/solver/traverse-order/test.py b/testsuite/tests/solver/traverse-order/test.py new file mode 100644 index 000000000..dec303163 --- /dev/null +++ b/testsuite/tests/solver/traverse-order/test.py @@ -0,0 +1,33 @@ +""" +Check that a linked dependency is considered during solution traversal +""" + +from glob import glob +import re +from drivers.alr import alr_with, init_local_crate, run_alr +from drivers.asserts import assert_eq, assert_match + +run_alr("get", "libhello") +init_local_crate() +run_alr("with", f"--use={glob('../libhello_*')[0]}") +alr_with("hello") # Libhello is already linked + +# Verify the solution is as expected +p = run_alr("with", "--solve", quiet=False) +assert_match(".*" + re.escape("""\ +Dependencies (solution): + hello=1.0.1 (origin: filesystem) + libhello=1.0.0 (pinned) (origin: ../libhello_1.0.0_filesystem) +"""), + p.out) + +# Verify that linked libhello prevents visiting hello too soon. This depends on +# debug output which is not very nice but there's no simple alternative. +p = run_alr("-vv", "build", quiet=False) + +assert_match(".*Round 1: SKIP not-ready hello=1.0.1" + ".*Round 1: VISIT ready libhello=1.0.0" + ".*Round 2: VISIT ready hello=1.0.1", + p.out) + +print('SUCCESS') diff --git a/testsuite/tests/solver/traverse-order/test.yaml b/testsuite/tests/solver/traverse-order/test.yaml new file mode 100644 index 000000000..872fc1274 --- /dev/null +++ b/testsuite/tests/solver/traverse-order/test.yaml @@ -0,0 +1,3 @@ +driver: python-script +indexes: + basic_index: {} From be16d2c6aa850a7da516cb285c3e6b436019e019 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 13 Sep 2023 15:01:38 +0200 Subject: [PATCH 5/6] Cosmetic change to binary origin image when unavailable (#1446) --- src/alire/alire-origins.adb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/alire/alire-origins.adb b/src/alire/alire-origins.adb index ac4e6b867..53378ebd2 100644 --- a/src/alire/alire-origins.adb +++ b/src/alire/alire-origins.adb @@ -669,6 +669,8 @@ package body Alire.Origins is Source_Image (This.Data.Src_Archive) elsif This.Data.Bin_Archive.Is_Value then Binary_Image (This.Data.Bin_Archive.As_Data) + elsif This.Data.Bin_Archive.Is_Empty then + "(unavailable on current platform)" else This.Data.Bin_Archive.Image_One_Line), when System => From 10dbf0c799c43e470792dc8c7b7185d46a62dbe7 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Wed, 13 Sep 2023 17:29:02 +0200 Subject: [PATCH 6/6] Cleanup after shared releases impl (#1448) * Omit default mention in shared deps help * Remove Export_Env arguments all-around Now that we delay all actions to build time, we can set environment just at that time and avoid complications. * Debug workflow and dependency hashes * Self-review --- .github/workflows/ci-toolchain.yml | 6 +-- src/alire/alire-builds-hashes.adb | 14 ++++-- src/alire/alire-builds-hashes.ads | 9 ++++ src/alire/alire-config-builtins.ads | 2 +- src/alire/alire-roots.adb | 52 ++++++---------------- src/alire/alire-roots.ads | 2 - src/alr/alr-commands-get.adb | 5 +-- src/alr/alr-commands-install.adb | 3 +- testsuite/drivers/helpers.py | 6 +++ testsuite/tests/config/shared-deps/test.py | 28 +++++------- 10 files changed, 57 insertions(+), 70 deletions(-) diff --git a/.github/workflows/ci-toolchain.yml b/.github/workflows/ci-toolchain.yml index b54d81871..7a0046aa6 100644 --- a/.github/workflows/ci-toolchain.yml +++ b/.github/workflows/ci-toolchain.yml @@ -50,8 +50,8 @@ jobs: - name: Show dependencies/pins run: ./bin/alr -n -q with --solve || ./bin/alr -n -v -d with --solve - - name: Show build environment - run: ./bin/alr -n printenv + - name: Show build environment, with debug fallback + run: ./bin/alr -n printenv || ./bin/alr -n -v -d printenv - shell: bash run: mv ./bin ./bin-old @@ -76,4 +76,4 @@ jobs: - name: Run testsuite run: cd testsuite; ./run.py -E - shell: bash \ No newline at end of file + shell: bash diff --git a/src/alire/alire-builds-hashes.adb b/src/alire/alire-builds-hashes.adb index 324f29eb8..16692c29f 100644 --- a/src/alire/alire-builds-hashes.adb +++ b/src/alire/alire-builds-hashes.adb @@ -1,6 +1,7 @@ with Alire.Crate_Configuration.Hashes; with Alire.Directories; with Alire.Environment.Loading; +with Alire.Errors; with Alire.GPR; with Alire.Hashes.SHA256_Impl; with Alire.Paths; @@ -193,9 +194,16 @@ package body Alire.Builds.Hashes is if Target.Origin.Requires_Build and then Target.Satisfies (Dep) then - Add ("dependency", - Target.Milestone.Image, - This.Hashes (Target.Name)); + if This.Contains (Target.Name) then + Add ("dependency", + Target.Milestone.Image, + This.Hashes (Target.Name)); + else + raise Program_Error with Errors.Set + (Rel.Milestone.Image & " depends on " + & Target.Milestone.Image + & " but hash is not yet computed?"); + end if; end if; end loop; end loop; diff --git a/src/alire/alire-builds-hashes.ads b/src/alire/alire-builds-hashes.ads index 95622386a..e11fa58a2 100644 --- a/src/alire/alire-builds-hashes.ads +++ b/src/alire/alire-builds-hashes.ads @@ -10,6 +10,8 @@ package Alire.Builds.Hashes is procedure Clear (This : in out Hasher); -- Remove any cached hashes + function Contains (This : in out Hasher; Name : Crate_Name) return Boolean; + function Is_Empty (This : Hasher) return Boolean; -- Says if the Hasher has been used or not @@ -57,4 +59,11 @@ private Inputs : Crate_Input_Maps.Map; end record; + -------------- + -- Contains -- + -------------- + + function Contains (This : in out Hasher; Name : Crate_Name) return Boolean + is (This.Hashes.Contains (Name)); + end Alire.Builds.Hashes; diff --git a/src/alire/alire-config-builtins.ads b/src/alire/alire-config-builtins.ads index b297ad28c..2212837dc 100644 --- a/src/alire/alire-config-builtins.ads +++ b/src/alire/alire-config-builtins.ads @@ -11,7 +11,7 @@ package Alire.Config.Builtins is Def => False, Help => "When true, dependencies are downloaded and built in a shared " - & "location inside the global cache. When false (default), " + & "location inside the global cache. When false, " & "dependencies are sandboxed in each workspace."); Distribution_Disable_Detection : constant Builtin := New_Builtin diff --git a/src/alire/alire-roots.adb b/src/alire/alire-roots.adb index 1b2fd5048..ab79d6160 100644 --- a/src/alire/alire-roots.adb +++ b/src/alire/alire-roots.adb @@ -39,7 +39,6 @@ package body Alire.Roots is function Build (This : in out Root; Cmd_Args : AAA.Strings.Vector; - Export_Build_Env : Boolean; Build_All_Deps : Boolean := False; Saved_Profiles : Boolean := True) return Boolean @@ -198,9 +197,7 @@ package body Alire.Roots is -- Now, after the corresponding config files are in place end if; - if Export_Build_Env or else not Builds.Sandboxed_Dependencies then - This.Export_Build_Environment; - end if; + This.Export_Build_Environment; This.Traverse (Build_Single_Release'Access); @@ -235,7 +232,15 @@ package body Alire.Roots is This.Build_Hasher.Compute (This); end if; - return This.Build_Hasher.Hash (Name); + if This.Build_Hasher.Contains (Name) then + return This.Build_Hasher.Hash (Name); + else + Trace.Error + ("Requested build hash of release " & Name.As_String + & " not among solution states:"); + This.Solution.Print_States (" ", Error); + raise Program_Error; + end if; end Build_Hash; -------------- @@ -253,7 +258,6 @@ package body Alire.Roots is (This : in out Root; Prefix : Absolute_Path; Build : Boolean := True; - Export_Env : Boolean := True; Print_Solution : Boolean := True) is use AAA.Strings; @@ -411,12 +415,11 @@ package body Alire.Roots is if Build then Assert (This.Build (Cmd_Args => AAA.Strings.Empty_Vector, - Export_Build_Env => Export_Env, Build_All_Deps => True), Or_Else => "Build failed, cannot perform installation"); end if; - if Export_Env then + if not Build then This.Export_Build_Environment; end if; @@ -744,37 +747,11 @@ package body Alire.Roots is begin - -- Prepare environment for any post-fetch actions. This must be done - -- after the lockfile on disk is written, since the root will read - -- dependencies from there. Post-fetch may happen even with shared - -- builds for linked and binary dependencies. - - if Builds.Sandboxed_Dependencies then - This.Export_Build_Environment; - else - null; - -- When using shared dependencies we have a conflict between crates - -- "in-place" (without syncing, e.g. links/binaries), which should - -- have its post-fetch run immediately, and regular crates, which - -- get the post-fetch run after sync. Since the complete environment - -- cannot be known for the former until build time (as config could - -- be incomplete otherwise), we need to delay post-fetch for all - -- crates to build time, in a follow-up PR. Meanwhile, in some corner - -- cases post-fetch could fail when using shared deps (in-place - -- crates with a post-fetch that relies on the environment). - - -- TODO: delay post-fetch for binary/linked crates to the build - -- moment too. Do this for both sandboxed/shared, for the sake - -- of simplicity? - end if; - - -- Visit dependencies in a safe order to be fetched, and their actions - -- ran + -- Visit dependencies in a safe order to be fetched This.Traverse (Doing => Deploy_Release'Access); - -- Show hints for missing externals to the user after all the noise of - -- dependency post-fetch compilations. + -- Show hints for missing externals to the user This.Solution.Print_Hints (This.Environment); @@ -843,9 +820,6 @@ package body Alire.Roots is end Sync_Release; begin - -- Prepare environment for any post-fetch actions - This.Export_Build_Environment; - -- Visit dependencies in safe order This.Traverse (Doing => Sync_Release'Access); end Sync_Builds; diff --git a/src/alire/alire-roots.ads b/src/alire/alire-roots.ads index 98fbc60a9..ceda622fe 100644 --- a/src/alire/alire-roots.ads +++ b/src/alire/alire-roots.ads @@ -255,7 +255,6 @@ package Alire.Roots is function Build (This : in out Root; Cmd_Args : AAA.Strings.Vector; - Export_Build_Env : Boolean; Build_All_Deps : Boolean := False; Saved_Profiles : Boolean := True) return Boolean; @@ -287,7 +286,6 @@ package Alire.Roots is (This : in out Root; Prefix : Absolute_Path; Build : Boolean := True; - Export_Env : Boolean := True; Print_Solution : Boolean := True); -- Call gprinstall on the releases in solution using --prefix=Prefix diff --git a/src/alr/alr-commands-get.adb b/src/alr/alr-commands-get.adb index 0ecf8e370..70a7aff38 100644 --- a/src/alr/alr-commands-get.adb +++ b/src/alr/alr-commands-get.adb @@ -190,12 +190,9 @@ package body Alr.Commands.Get is (Crate => Cmd.Root.Name, Profile => Alire.Utils.Switches.Release); - -- The complete build environment has been set up already by - -- Deploy_Dependencies, so we must not do it again. Build_OK := Cmd.Root.Build (Cmd_Args => AAA.Strings.Empty_Vector, - Saved_Profiles => False, - Export_Build_Env => False); + Saved_Profiles => False); end if; else Build_OK := True; diff --git a/src/alr/alr-commands-install.adb b/src/alr/alr-commands-install.adb index 35a9679d4..3bcf17019 100644 --- a/src/alr/alr-commands-install.adb +++ b/src/alr/alr-commands-install.adb @@ -63,8 +63,7 @@ package body Alr.Commands.Install is & " is already installed, use " & TTY.Terminal ("--force") & " to reinstall"); when New_Install | Reinstall | Replace => - Cmd.Root.Install (Prefix => Prefix, - Export_Env => True); + Cmd.Root.Install (Prefix => Prefix); end case; else diff --git a/testsuite/drivers/helpers.py b/testsuite/drivers/helpers.py index a7813bcb6..6b3c04bb6 100644 --- a/testsuite/drivers/helpers.py +++ b/testsuite/drivers/helpers.py @@ -256,6 +256,12 @@ def replace_in_file(filename : str, old : str, new : str): file.write(old_contents.replace(old, new)) +def neutral_path(path : str) -> str: + """ + Return a path with all separators replaced by '/'. + """ + return path.replace('\\', '/') + class FileLock(): """ A filesystem-level lock for tests executed from different threads but diff --git a/testsuite/tests/config/shared-deps/test.py b/testsuite/tests/config/shared-deps/test.py index 2a8a39dee..9adf1a9df 100644 --- a/testsuite/tests/config/shared-deps/test.py +++ b/testsuite/tests/config/shared-deps/test.py @@ -9,7 +9,12 @@ from drivers.alr import (alr_builds_dir, alr_vault_dir, alr_with, alr_workspace_cache, init_local_crate, run_alr) from drivers.asserts import assert_contents, assert_file_exists -from drivers.helpers import lines_of +from drivers.helpers import contents, lines_of, neutral_path + + +def check_in(file : str, expected : str) -> bool: + assert file in expected, f"Missing file '{file}' in\n{expected}" + vault_dir = alr_vault_dir() build_dir = alr_builds_dir() @@ -46,21 +51,12 @@ run_alr("build") base = builds.find_dir("hello_1.0.1_filesystem") -assert_contents(base, - [f'{base}/alire', - f'{base}/alire.toml', - f'{base}/alire/build_hash_inputs', - f'{base}/alire/flags', - f'{base}/alire/flags/complete_copy', - f'{base}/alire/flags/post_fetch_done', - f'{base}/config', - f'{base}/config/hello_config.ads', - f'{base}/config/hello_config.gpr', - f'{base}/config/hello_config.h', - f'{base}/hello.gpr', - f'{base}/obj', - f'{base}/src', - f'{base}/src/hello.adb']) +# There's too much object files and the like, check a few critical files: +files = contents(base) # This returns "normalized" paths (with '/' separators) +nbase = neutral_path(base) +check_in(f'{nbase}/config/hello_config.ads', files) # config was generated +check_in(f'{nbase}/alire/flags/post_fetch_done', files) # actions were run +check_in(f'{nbase}/obj/b__hello.ads', files) # build took place # And that the crate usual cache dir doesn't exist assert not os.path.exists(alr_workspace_cache())