From 1ce9a2256c37925ae5bf573a1d4d9d9c491ec2d9 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Mon, 6 Nov 2023 11:15:17 +0100 Subject: [PATCH] Generate loadable project during `alr init` (#1486) --- src/alire/alire-directories.adb | 3 +- src/alire/alire-directories.ads | 2 +- src/alire/alire-lockfiles.adb | 6 ++-- src/alire/alire-lockfiles.ads | 6 ++-- src/alire/alire-roots-optional.adb | 2 +- src/alire/alire-roots.adb | 14 ++++++++-- src/alire/alire-roots.ads | 9 +++--- src/alr/alr-commands-init.adb | 18 ++++++++++++ .../tests/workflows/init-options/test.py | 28 +++++++++++++++++++ 9 files changed, 72 insertions(+), 16 deletions(-) diff --git a/src/alire/alire-directories.adb b/src/alire/alire-directories.adb index 2ac879377..b845cfdd7 100644 --- a/src/alire/alire-directories.adb +++ b/src/alire/alire-directories.adb @@ -492,7 +492,8 @@ package body Alire.Directories is use Ada.Directories; use Ada.Exceptions; use Ada.Strings.Unbounded; - procedure Free is new Ada.Unchecked_Deallocation (String, Destination); + procedure Free is + new Ada.Unchecked_Deallocation (Absolute_Path, Destination); Freeable : Destination := This.Enter; begin if This.Enter /= null diff --git a/src/alire/alire-directories.ads b/src/alire/alire-directories.ads index 87f7e3e94..452d42d73 100644 --- a/src/alire/alire-directories.ads +++ b/src/alire/alire-directories.ads @@ -134,7 +134,7 @@ package Alire.Directories is -- This type simplifies staying in a folder during the life of a scope. -- Once the scope ends, the current folder is set back to the one it was. - type Destination is access String; + type Destination is access Absolute_Path; Stay : constant Destination; type Guard (Enter : Destination := Stay) is limited private; diff --git a/src/alire/alire-lockfiles.adb b/src/alire/alire-lockfiles.adb index d6a424a99..20f60109a 100644 --- a/src/alire/alire-lockfiles.adb +++ b/src/alire/alire-lockfiles.adb @@ -27,7 +27,7 @@ package body Alire.Lockfiles is -- File_Name -- --------------- - function File_Name (Root_Dir : Any_Path) return Any_Path + function File_Name (Root_Dir : Absolute_Path) return Absolute_Path is (Root_Dir / Paths.Working_Folder_Inside_Root / Simple_Name); --------------- @@ -57,7 +57,7 @@ package body Alire.Lockfiles is -- Read -- ---------- - function Read (Filename : Any_Path) return Contents is + function Read (Filename : Absolute_Path) return Contents is begin Trace.Debug ("Reading persistent contents from " & Filename); @@ -119,7 +119,7 @@ package body Alire.Lockfiles is ----------- procedure Write (Contents : Lockfiles.Contents; - Filename : Any_Path) + Filename : Absolute_Path) is use Ada.Text_IO; File : File_Type; diff --git a/src/alire/alire-lockfiles.ads b/src/alire/alire-lockfiles.ads index 2e7835965..01a219d62 100644 --- a/src/alire/alire-lockfiles.ads +++ b/src/alire/alire-lockfiles.ads @@ -23,18 +23,18 @@ package Alire.Lockfiles is end record; -- Information that goes in the lockfile - function File_Name (Root_Dir : Any_Path) return Any_Path; + function File_Name (Root_Dir : Absolute_Path) return Absolute_Path; -- Return the location /path/to/crate/dir/alire.lock, filename included, -- given the root directory where the crate is deployed. - function Read (Filename : Any_Path) return Contents; + function Read (Filename : Absolute_Path) return Contents; -- Read contents from the given lockfile function Validity (File : Any_Path) return Validities; -- Check if given file is a valid lockfile procedure Write (Contents : Lockfiles.Contents; - Filename : Any_Path); + Filename : Absolute_Path); -- Write persistent contents to a file overriding diff --git a/src/alire/alire-roots-optional.adb b/src/alire/alire-roots-optional.adb index 4b2c60c60..bc0224eeb 100644 --- a/src/alire/alire-roots-optional.adb +++ b/src/alire/alire-roots-optional.adb @@ -54,7 +54,7 @@ package body Alire.Roots.Optional is (R => Releases.From_Manifest (Crate_File, Manifest.Local, Strict => True), - Path => Ada.Directories.Full_Name (Path), + Path => Directories.Current, Env => Alire.Root.Platform_Properties)) do -- Crate loaded properly, we can return a valid root here diff --git a/src/alire/alire-roots.adb b/src/alire/alire-roots.adb index e56a900ae..2451e82c9 100644 --- a/src/alire/alire-roots.adb +++ b/src/alire/alire-roots.adb @@ -48,9 +48,17 @@ package body Alire.Roots is This.Set_Build_Profiles (Crate_Configuration.Last_Build_Profiles); end if; + -- Right after initialization, a Root may lack a solution, which is + -- needed for configuration generation, so ensure there is one. + + if not This.Has_Lockfile then + This.Set (Solutions.Empty_Valid_Solution); + end if; + + -- Proceed to load configuration, which must be complete before building + This.Load_Configuration; This.Configuration.Ensure_Complete; - -- For proceeding to build, the configuration must be complete -- Ensure sources are up to date @@ -1517,7 +1525,7 @@ package body Alire.Roots is -- Dependencies_Dir -- ---------------------- - function Dependencies_Dir (This : in out Root) return Any_Path + function Dependencies_Dir (This : in out Root) return Absolute_Path is (if Builds.Sandboxed_Dependencies then This.Cache_Dir / Paths.Deps_Folder_Inside_Cache_Folder else Paths.Vault.Path); @@ -1561,7 +1569,7 @@ package body Alire.Roots is -------------------- procedure Write_Solution (Solution : Solutions.Solution; - Lockfile : String) + Lockfile : Absolute_Path) is begin Lockfiles.Write (Contents => (Solution => Solution), diff --git a/src/alire/alire-roots.ads b/src/alire/alire-roots.ads index a5623b9e8..ca9eab8f0 100644 --- a/src/alire/alire-roots.ads +++ b/src/alire/alire-roots.ads @@ -347,7 +347,7 @@ package Alire.Roots is function Cache_Dir (This : Root) return Absolute_Path; -- The "alire/cache" dir inside the root path, containing releases and pins - function Dependencies_Dir (This : in out Root) return Any_Path; + function Dependencies_Dir (This : in out Root) return Absolute_Path; -- The path at which dependencies are deployed, which will -- be either Paths.Vault.Path if dependencies are shared, or -- /alire/cache/dependencies when dependencies are @@ -368,11 +368,11 @@ private -- Force loading of the configuration; useful since the auto-load is not -- triggered when doing This.Configuration here. - function Load_Solution (Lockfile : String) return Solutions.Solution + function Load_Solution (Lockfile : Absolute_Path) return Solutions.Solution is (Lockfiles.Read (Lockfile).Solution); procedure Write_Solution (Solution : Solutions.Solution; - Lockfile : String); + Lockfile : Absolute_Path); -- Wrapper for use with Cached_Solutions package Cached_Solutions is new AAA.Caches.Files @@ -408,7 +408,8 @@ private -- These values, if different from "", mean this is a temporary root Manifest : Unbounded_Absolute_Path; Lockfile : Unbounded_Absolute_Path; - end record; + end record + with Type_Invariant => Check_Absolute_Path (+Root.Path); overriding procedure Adjust (This : in out Root); diff --git a/src/alr/alr-commands-init.adb b/src/alr/alr-commands-init.adb index ab770466e..ec5117c20 100644 --- a/src/alr/alr-commands-init.adb +++ b/src/alr/alr-commands-init.adb @@ -5,7 +5,9 @@ with Ada.Wide_Wide_Text_IO; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Alire.Config.Builtins; +with Alire.Roots.Optional; with Alire.Utils.User_Input.Query_Config; + with CLIC.User_Input; with GNATCOLL.VFS; use GNATCOLL.VFS; @@ -325,6 +327,18 @@ package body Alr.Commands.Init is TIO.Put_Line (File, WW (S)); end Put_Line; + --------------------- + -- Generate_Config -- + --------------------- + + procedure Generate_Config is + Root : constant Alire.Roots.Optional.Root := + Alire.Roots.Optional.Detect_Root (+Directory.Full_Name); + begin + Root.Value.Build_Prepare (Saved_Profiles => False, + Force_Regen => False); + end Generate_Config; + begin -- Crate dir Directory.Make_Dir; @@ -343,6 +357,10 @@ package body Alr.Commands.Init is Generate_Manifest; + if not Cmd.No_Skel then + Generate_Config; + end if; + Alire.Put_Success (TTY.Emph (Lower_Name) & " initialized successfully."); end Generate; diff --git a/testsuite/tests/workflows/init-options/test.py b/testsuite/tests/workflows/init-options/test.py index ffabdc0b9..3e3e95f11 100644 --- a/testsuite/tests/workflows/init-options/test.py +++ b/testsuite/tests/workflows/init-options/test.py @@ -15,10 +15,22 @@ complain_on_error=False) assert_match(".*Identifiers must be.*", p.out) +# In the following, config files must already exist so the project is +# immediately loadable by editors. Other artifacts under 'alire/' are created +# during configuration generation. + # Plain init run_alr('init', '--bin', 'xxx') compare(contents('xxx'), ['xxx/.gitignore', + 'xxx/alire', 'xxx/alire.toml', + 'xxx/alire/alire.lock', + 'xxx/alire/build_hash_inputs', + 'xxx/alire/config.toml', + 'xxx/config', + 'xxx/config/xxx_config.ads', + 'xxx/config/xxx_config.gpr', + 'xxx/config/xxx_config.h', 'xxx/share', 'xxx/share/xxx', 'xxx/src', @@ -30,7 +42,15 @@ run_alr('init', '--bin', 'aaa') compare(contents('aaa'), ['aaa/.gitignore', 'aaa/aaa.gpr', + 'aaa/alire', 'aaa/alire.toml', + 'aaa/alire/alire.lock', + 'aaa/alire/build_hash_inputs', + 'aaa/alire/config.toml', + 'aaa/config', + 'aaa/config/aaa_config.ads', + 'aaa/config/aaa_config.gpr', + 'aaa/config/aaa_config.h', 'aaa/share', 'aaa/share/aaa', 'aaa/src', @@ -65,7 +85,15 @@ os.chdir('zzz') run_alr('init', '--bin', '--in-place', 'zzz') compare(contents('.'), ['./.gitignore', + './alire', './alire.toml', + './alire/alire.lock', + './alire/build_hash_inputs', + './alire/config.toml', + './config', + './config/zzz_config.ads', + './config/zzz_config.gpr', + './config/zzz_config.h', './share', './share/zzz', './src',