Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load configuration earlier from proper location #1501

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/alire/alire-config-edit-early_load.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package body Alire.Config.Edit.Early_Load is

-----------------
-- Load_Config --
-----------------

procedure Load_Config is
begin
Alire.Config.Edit.Load_Config;
end Load_Config;

end Alire.Config.Edit.Early_Load;
7 changes: 7 additions & 0 deletions src/alire/alire-config-edit-early_load.ads
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package Alire.Config.Edit.Early_Load is

procedure Load_Config;
-- For internal use of Alire_Early_Elaboration, DO NOT CALL otherwise.
-- This should be hidden but that would require a non-trivial refactoring.

end Alire.Config.Edit.Early_Load;
10 changes: 4 additions & 6 deletions src/alire/alire-config-edit.adb
Original file line number Diff line number Diff line change
Expand Up @@ -138,25 +138,26 @@ package body Alire.Config.Edit is

procedure Load_Config is
begin
DB.Clear;
DB_Instance.Clear;

for Lvl in Level loop
if Lvl /= Local or else Directories.Detect_Root_Path /= "" then
CLIC.Config.Load.From_TOML (C => DB,
CLIC.Config.Load.From_TOML (C => DB_Instance,
Origin => Lvl'Img,
Path => Filepath (Lvl),
Check => Valid_Builtin'Access);
end if;
end loop;

Config_Loaded := True;

-- Set variables elsewhere

Platforms.Current.Disable_Distribution_Detection :=
Config.Builtins.Distribution_Disable_Detection.Get;
if Platforms.Current.Disable_Distribution_Detection then
Trace.Debug ("Distribution detection disabled by configuration");
end if;

end Load_Config;

Default_Config_Path : constant Absolute_Path := Platforms.Folders.Config;
Expand Down Expand Up @@ -314,7 +315,4 @@ package body Alire.Config.Edit is
end loop;
end Print_Builtins_Doc;

begin
Load_Config;

end Alire.Config.Edit;
3 changes: 2 additions & 1 deletion src/alire/alire-config-edit.ads
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ private
procedure Load_Config;
-- Clear and reload all configuration. Also set some values elsewhere
-- used to break circularities. Bottom line, this procedure must leave
-- the program-wide configuration ready.
-- the program-wide configuration ready. This is done during startup from
-- Alire_Early_Elaboration so config is available ASAP.

end Alire.Config.Edit;
14 changes: 14 additions & 0 deletions src/alire/alire-config.adb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ with Alire.Config.Edit;

package body Alire.Config is

--------
-- DB --
--------

function DB return access constant CLIC.Config.Instance
is
begin
if Config_Loaded then
return DB_Instance'Access;
else
raise Program_Error with "Attempt to use config database too early";
end if;
end DB;

---------
-- Get --
---------
Expand Down
8 changes: 6 additions & 2 deletions src/alire/alire-config.ads
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ with CLIC.Config;

package Alire.Config is

DB : CLIC.Config.Instance;
-- The Alire user configuration database
function DB return access constant CLIC.Config.Instance;

type Level is (Global, Local);
-- Ordering is important, as Globals are loaded first and overridden by any
Expand Down Expand Up @@ -83,6 +82,11 @@ package Alire.Config is

private

Config_Loaded : Boolean := False;

DB_Instance : aliased CLIC.Config.Instance;
-- The Alire user configuration database

type Builtin_Option is tagged record
Key : Ada.Strings.Unbounded.Unbounded_String;
Kind : Builtin_Kind;
Expand Down
1 change: 1 addition & 0 deletions src/alire/alire-index.ads
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
private with Alire_Early_Elaboration;
pragma Elaborate_All (Alire_Early_Elaboration);
pragma Unreferenced (Alire_Early_Elaboration);

with Alire.Config.Builtins;
Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-toolchains.adb
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ package body Alire.Toolchains is
Level : Config.Level;
Fail_If_Unset : Boolean := True) is
begin
if CLIC.Config.Defined (Config.DB, Tool_Key (Crate)) and then
if CLIC.Config.Defined (Config.DB.all, Tool_Key (Crate)) and then
not CLIC.Config.Edit.Unset
(Config.Edit.Filepath (Level),
Tool_Key (Crate))
Expand Down
72 changes: 53 additions & 19 deletions src/alire/alire_early_elaboration.adb
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
with Ada.Text_IO;
with AAA.Strings;

with Alire;
with Ada.Directories;

with Alire.Config.Edit.Early_Load;

with GNAT.Command_Line;
with GNAT.OS_Lib;
with GNAT.IO;

with Interfaces.C_Streams;

with Simple_Logging.Filtering;

package body Alire_Early_Elaboration is

-----------------
-- Early_Error --
-----------------

procedure Early_Error (Text : String) is
begin
GNAT.IO.Put_Line ("ERROR: " & Text);
GNAT.OS_Lib.OS_Exit (1);
end Early_Error;

----------------
-- Add_Scopes --
----------------
Expand Down Expand Up @@ -39,8 +52,7 @@ package body Alire_Early_Elaboration is
then
-- Bypass debug channel, which was not entirely set up.
-- Otherwise we get unwanted location/entity info already.
Ada.Text_IO.Put_Line ("ERROR: Invalid logging filters.");
GNAT.OS_Lib.OS_Exit (1);
Early_Error ("Invalid logging filters.");
end if;
end Add_Scopes;

Expand All @@ -59,37 +71,56 @@ package body Alire_Early_Elaboration is

procedure Check_Switches is

----------------------
-- Check_Long_Debug --
----------------------
---------------------
-- Set_Config_Path --
---------------------

procedure Set_Config_Path (Path : String) is
package Adirs renames Ada.Directories;
begin
if not Adirs.Exists (Path) then
Early_Error
("Invalid non-existing configuration path: " & Path);
elsif Adirs.Kind (Path) not in Adirs.Directory then
Early_Error
("Given configuration path is not a directory: " & Path);
else
Alire.Config.Edit.Set_Path (Adirs.Full_Name (Path));
end if;
end Set_Config_Path;

-----------------------
-- Check_Long_Switch --
-----------------------
-- Take care manually of the -debug[ARG] optional ARG, since the
-- simple Getopt below doesn't for us:
procedure Check_Long_Debug (Switch : String) is
Target : constant String := "--debug";
procedure Check_Long_Switch (Switch : String) is
use AAA.Strings;
begin
if Switch (Switch'First) /= '-' then
Subcommand_Seen := True;

elsif Switch'Length >= Target'Length and then
Switch (Switch'First ..
Switch'First + Target'Length - 1) = Target
then
elsif Has_Prefix (Switch, "--debug") then
Switch_D := True;
Add_Scopes
(Switch (Switch'First + Target'Length .. Switch'Last));
Add_Scopes (Tail (Switch, "="));
elsif Has_Prefix (Switch, "--config") then
Set_Config_Path (Tail (Switch, "="));
end if;
end Check_Long_Debug;
end Check_Long_Switch;

begin
loop
-- We use the simpler Getopt form to avoid built-in help and other
-- shenanigans.
case Getopt ("* d? --debug? q v c=") is
case Getopt ("* d? --debug? q v c= --config=") is
when ASCII.NUL =>
exit;
when '*' =>
if not Subcommand_Seen then
Check_Long_Debug (Full_Switch);
Check_Long_Switch (Full_Switch);
end if;
when 'c' =>
if not Subcommand_Seen then
Set_Config_Path (Parameter);
end if;
when 'd' =>
if not Subcommand_Seen then
Expand Down Expand Up @@ -147,6 +178,9 @@ package body Alire_Early_Elaboration is
if Switch_D then
Alire.Log_Debug := True;
end if;

-- Load config ASAP
Alire.Config.Edit.Early_Load.Load_Config;
end Early_Switch_Detection;

-------------------
Expand Down
3 changes: 3 additions & 0 deletions src/alire/os_windows/alire-platforms-current__windows.adb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ with GNAT.OS_Lib;

with AAA.Strings;

with Alire_Early_Elaboration;
pragma Unreferenced (Alire_Early_Elaboration);

with Alire.Environment;
with Alire.OS_Lib; use Alire.OS_Lib;
with Alire.Config.Builtins.Windows;
Expand Down
4 changes: 2 additions & 2 deletions src/alr/alr-commands-config.adb
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ package body Alr.Commands.Config is
when 0 =>
Trace.Always
(CLIC.Config.Info.List
(Alire.Config.DB,
(Alire.Config.DB.all,
Filter => ".*",
Show_Origin => Cmd.Show_Origin).Flatten (ASCII.LF));
when 1 =>
Trace.Always
(CLIC.Config.Info.List
(Alire.Config.DB,
(Alire.Config.DB.all,
Filter => Args.First_Element,
Show_Origin => Cmd.Show_Origin).Flatten (ASCII.LF));
when others =>
Expand Down
17 changes: 10 additions & 7 deletions src/alr/alr-commands.adb
Original file line number Diff line number Diff line change
Expand Up @@ -492,12 +492,15 @@ package body Alr.Commands is
if Command_Line_Config_Path /= null and then
Command_Line_Config_Path.all /= ""
then
declare
Config_Path : constant Alire.Absolute_Path
:= Ada.Directories.Full_Name (Command_Line_Config_Path.all);
begin
Alire.Config.Edit.Set_Path (Config_Path);
end;
-- Just verify that early processing catched it
pragma Assert
(Alire.Config.Edit.Path =
Ada.Directories.Full_Name (Command_Line_Config_Path.all),
"Unexpected mismatch of config paths:"
& Alire.New_Line
& "Early: " & Alire.Config.Edit.Path
& Alire.New_Line
& "Late : " & Command_Line_Config_Path.all);
end if;

-- chdir(2) if necessary.
Expand All @@ -514,7 +517,7 @@ package body Alr.Commands is

Set_Builtin_Aliases;

Sub_Cmd.Load_Aliases (Alire.Config.DB);
Sub_Cmd.Load_Aliases (Alire.Config.DB.all);

Sub_Cmd.Execute;
Log ("alr " & Sub_Cmd.What_Command & " done", Detail);
Expand Down
29 changes: 29 additions & 0 deletions testsuite/tests/config/early-loading/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Test for bug #1496, in which a configuration at a non-default location was
loaded too late.
"""

import os
from drivers.alr import run_alr
from drivers.asserts import assert_eq, assert_match

# Create a custom configuration dir + file
custom_config = "custom_config"
os.mkdir(custom_config)
with open(os.path.join(custom_config, "config.toml"), "w") as f:
f.write("test_value = 42\n")

expected = "test_value=42\n"

# Verify proper loading with both short and long config options
assert_eq(expected,
run_alr("-c", custom_config, "config", "--global").out)
assert_eq(expected,
run_alr(f"--config={custom_config}", "config", "--global").out)

# Verify also when using environment variable
os.environ["ALR_CONFIG"] = os.path.abspath(custom_config)
assert_eq(expected,
run_alr("config", "--global").out)

print('SUCCESS')
7 changes: 7 additions & 0 deletions testsuite/tests/config/early-loading/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
driver: python-script
build_mode: both # one of shared, sandboxed, both (default)
indexes:
compiler_only_index: {}
# Note that shared builds require a detected compiler to be able to compute
# build hashes, which is needed for many subcommands: build, get, printenv,
# update...
2 changes: 1 addition & 1 deletion testsuite/tests/config/relative_config_path/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from drivers.asserts import assert_eq
from drivers.helpers import lines_of

run_alr("--config", ".", "config", "--global",
run_alr("--config=.", "config", "--global",
"--set", "some_config_key", "true")


Expand Down
Loading