diff --git a/RELEASING.md b/RELEASING.md index 198b74d3c..e44fc0da0 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -1,10 +1,11 @@ ## Checklist for releasing a new version 1. [ ] Update version in `Alire.Version`. +1. [ ] Update version in `alire.toml`. 1. [ ] Create test release in own fork. - To verify builds succeed. - As the Windows build can rarely fail, this provides a backup .exe -1. [ ] Create new index version branches if necessary. +1. [ ] In repo `alire-index`: create new index version branches if necessary. - Edit index/index.toml to match. 1. [ ] Ensure the index version is the default branch in the community repos: - alire-index diff --git a/alire.toml b/alire.toml index c0f45b398..25f1e4854 100644 --- a/alire.toml +++ b/alire.toml @@ -1,7 +1,7 @@ name = "alr" description = "Command-line tool from the Alire project" -version = "1.3.0-dev" +version = "2.0-rc1" authors = ["Alejandro R. Mosteo", "Fabien Chouteau", "Pierre-Marie de Rodat"] maintainers = ["alejandro@mosteo.com", "chouteau@adacore.com"] @@ -77,7 +77,7 @@ commit = "9a9c660f9c6f27f5ef75417e7fac7061dff14d78" [pins.semantic_versioning] url = "https://github.com/alire-project/semantic_versioning" -commit = "2f23fc5f6b4855b836b599adf292fed9c0ed4144" +commit = "cc2148cf9c8934fb557b5ae49a3f7947194fa7ee" [pins.simple_logging] url = "https://github.com/alire-project/simple_logging" diff --git a/deps/semantic_versioning b/deps/semantic_versioning index 2f23fc5f6..cc2148cf9 160000 --- a/deps/semantic_versioning +++ b/deps/semantic_versioning @@ -1 +1 @@ -Subproject commit 2f23fc5f6b4855b836b599adf292fed9c0ed4144 +Subproject commit cc2148cf9c8934fb557b5ae49a3f7947194fa7ee diff --git a/doc/catalog-format-spec.md b/doc/catalog-format-spec.md index 0f6071afe..fb065179b 100644 --- a/doc/catalog-format-spec.md +++ b/doc/catalog-format-spec.md @@ -463,9 +463,9 @@ static, i.e. they cannot depend on the context. *monorepo*). - `binary`: optional (defauts to false) boolean used to design the origin - as binary. Binary origins are not compiled and can use dynamic + as binary. Binary origins are not compiled and can optionally use dynamic expressions to narrow down the platform to which they apply. An origin - using a dynamic expression is implicitly tagged as binary; see the + using a dynamic expression must be tagged as binary; see the example below. Examples of origin tables: @@ -497,6 +497,7 @@ static, i.e. they cannot depend on the context. [origin."case(os)".linux."case(host-arch)".x86-64] url = "https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnat-12.1.0-1/gnat-x86_64-linux-12.1.0-1.tar.gz" hashes = ["sha256:df1f36b306359d528799b1de8629a793523347a90c9d4b72efd23c62a7279555"] + binary = true ``` - `available`: optional dynamic boolean expression. If it evaluates to diff --git a/src/alire/alire-index.ads b/src/alire/alire-index.ads index f51ab115e..c9a706275 100644 --- a/src/alire/alire-index.ads +++ b/src/alire/alire-index.ads @@ -44,7 +44,7 @@ package Alire.Index is and then Branch_String (Branch_String'Last) /= '-' and then (for some C of Branch_String => C = '-'); - Community_Branch : constant String := "stable-1.2.1"; + Community_Branch : constant String := "stable-1.3.0"; -- The branch used for the community index. Must be updated when new index -- features are introduced. diff --git a/src/alire/alire-index_features.ads b/src/alire/alire-index_features.ads new file mode 100644 index 000000000..10f81cb1b --- /dev/null +++ b/src/alire/alire-index_features.ads @@ -0,0 +1,16 @@ +with Semantic_Versioning; + +package Alire.Index_Features is + + -- For easier lockstep updates, we keep track of features that we will + -- enable in future index versions. + + subtype Min_Version is Semantic_Versioning.Version; + + use type Min_Version; + + Explicit_Binary_Origin : constant Min_Version := +"1.3.0"; + -- Require that binary origins are explicitly marked as such instead of + -- relying on dynamic expressions. + +end Alire.Index_Features; diff --git a/src/alire/alire-loading.ads b/src/alire/alire-loading.ads new file mode 100644 index 000000000..d5e79deeb --- /dev/null +++ b/src/alire/alire-loading.ads @@ -0,0 +1,25 @@ +with Semantic_Versioning; + +package Alire.Loading with Preelaborate is + + -- Auxiliary type to pass info around while loading things from disk + -- (currently only indexes...) + + type Kinds is (None, Index); + + type Metadata (Kind : Kinds := None) is record + case Kind is + when Index => + Version : Semantic_Versioning.Version; + when None => + null; + end case; + end record; + + function For_Index (Version : Semantic_Versioning.Version) + return Metadata + is (Kind => Index, Version => Version); + + function No_Metadata return Metadata is (Kind => None); + +end Alire.Loading; diff --git a/src/alire/alire-origins.adb b/src/alire/alire-origins.adb index fd7cd8474..cc4004105 100644 --- a/src/alire/alire-origins.adb +++ b/src/alire/alire-origins.adb @@ -2,12 +2,16 @@ with Ada.Directories; with AAA.Strings; +with Alire.Index_Features; +with Alire.Loading; with Alire.Platforms.Current; with Alire.Root; with Alire.URI; with Alire.Utils.TTY; with Alire.VFS; +with Semantic_Versioning; + package body Alire.Origins is ---------- @@ -494,6 +498,42 @@ package body Alire.Origins is & Keys.Archive_Name & "'"); end From_TOML; + ---------------------- + -- Binary_From_TOML -- + ---------------------- + -- This wrapper is used to make sure that a conditional archive is + -- explicitly marked as binary. + function Binary_From_TOML (From : TOML_Adapters.Key_Queue) + return Conditional_Archives.Tree + is + use TOML; + use type Semantic_Versioning.Version; + Table : constant TOML_Adapters.Key_Queue := + From.Descend (From.Unwrap.Get (Keys.Origin), + Context => "binary_archive_data"); + begin + if From.Metadata.Kind not in Loading.None + -- When loading from an `alire.toml` manifest outside of an index, + -- we won't have version metadata, but this is okay as it either is a + -- user manifest (which does not contain an origin) or it is a manifest + -- generated by ourselves for internal use (which always contains the + -- binary property when needed). + and then + From.Metadata.Version >= Index_Features.Explicit_Binary_Origin + and then + (not Table.Unwrap.Has (Keys.Binary) or else + not Table.Unwrap.Get (Keys.Binary).As_Boolean) + then + Raise_Checked_Error + ("Dynamic origins must explicitly set the `binary=true` property" + & " from index version " + & TTY.Bold (Index_Features.Explicit_Binary_Origin.Image) + & " onwards."); + end if; + + return From_TOML (From); + end Binary_From_TOML; + --------------- -- From_TOML -- --------------- @@ -547,7 +587,7 @@ package body Alire.Origins is (Keys.Origin, Table.Unwrap, Context => "binary archive"), - Loader => From_TOML'Access, + Loader => Binary_From_TOML'Access, Resolve => True, Strict => False) with null record))); diff --git a/src/alire/alire-origins.ads b/src/alire/alire-origins.ads index 4ba6664d2..b24327cb8 100644 --- a/src/alire/alire-origins.ads +++ b/src/alire/alire-origins.ads @@ -275,6 +275,7 @@ private package Conditional_Archives is new Conditional_Trees (Values => Archive_Data, Image => Binary_Image); + -- Conditional origins must be binary in the current implementation type Conditional_Archive is new Conditional_Archives.Tree with null record; package Binary_Loader is new Conditional_Archives.TOML_Load; diff --git a/src/alire/alire-toml_adapters.adb b/src/alire/alire-toml_adapters.adb index 4f2d780a1..6c2460ed3 100644 --- a/src/alire/alire-toml_adapters.adb +++ b/src/alire/alire-toml_adapters.adb @@ -110,12 +110,16 @@ package body Alire.TOML_Adapters is -- From -- ---------- - function From (Value : TOML.TOML_Value; - Context : String) return Key_Queue + function From (Value : TOML.TOML_Value; + Context : String; + Metadata : Loading.Metadata := Loading.No_Metadata) + return Key_Queue is begin return This : constant Key_Queue := - (Ada.Finalization.Limited_Controlled with Value => Value) + (Ada.Finalization.Limited_Controlled with + Value => Value, + Metadata => Metadata) do Errors.Open (Context); end return; @@ -125,11 +129,14 @@ package body Alire.TOML_Adapters is -- From -- ---------- - function From (Key : String; - Value : TOML.TOML_Value; - Context : String) return Key_Queue + function From (Key : String; + Value : TOML.TOML_Value; + Context : String; + Metadata : Loading.Metadata := Loading.No_Metadata) + return Key_Queue is (From (Create_Table (Key, Value), - Context)); + Context, + Metadata)); ------------- -- Descend -- @@ -138,7 +145,7 @@ package body Alire.TOML_Adapters is function Descend (Parent : Key_Queue; Value : TOML.TOML_Value; Context : String) return Key_Queue is - (From (Value, Context)); + (From (Value, Context, Parent.Metadata)); ------------------ -- Merge_Tables -- diff --git a/src/alire/alire-toml_adapters.ads b/src/alire/alire-toml_adapters.ads index 20e8262e5..461797762 100644 --- a/src/alire/alire-toml_adapters.ads +++ b/src/alire/alire-toml_adapters.ads @@ -3,6 +3,7 @@ private with Ada.Finalization; with AAA.Strings; use AAA.Strings; private with Alire.Errors; +with Alire.Loading; with TOML; use all type TOML.Any_Value_Kind; @@ -20,13 +21,18 @@ package Alire.TOML_Adapters with Preelaborate is -- Also encapsulates a context that can be used to pinpoint errors better. -- Note: all operations on this type use shallow copies! - function From (Key : String; - Value : TOML.TOML_Value; - Context : String) return Key_Queue; + function Metadata (This : Key_Queue) return Loading.Metadata; + + function From (Key : String; + Value : TOML.TOML_Value; + Context : String; + Metadata : Loading.Metadata := Loading.No_Metadata) + return Key_Queue; -- Convert a key/value pair into a wrapped table as Key_Queue. - function From (Value : TOML.TOML_Value; - Context : String) + function From (Value : TOML.TOML_Value; + Context : String; + Metadata : Loading.Metadata := Loading.No_Metadata) return Key_Queue; -- Create a new queue wrapping a TOML value. @@ -178,12 +184,20 @@ private use type UString; -- Allows comparisons between strings and unbounded type Key_Queue is new Ada.Finalization.Limited_Controlled with record - Value : TOML.TOML_Value; + Value : TOML.TOML_Value; + Metadata : Loading.Metadata; end record; overriding procedure Finalize (This : in out Key_Queue); + -------------- + -- Metadata -- + -------------- + + function Metadata (This : Key_Queue) return Loading.Metadata + is (This.Metadata); + -------------- -- Contains -- -------------- @@ -209,7 +223,7 @@ private Value : TOML.TOML_Value; Context : String) return Key_Queue is - (From (Key, Value, Context)); + (From (Key, Value, Context, Parent.Metadata)); ------------- -- Failure -- diff --git a/src/alire/alire-toml_index.adb b/src/alire/alire-toml_index.adb index 20a53b43e..969b19fda 100644 --- a/src/alire/alire-toml_index.adb +++ b/src/alire/alire-toml_index.adb @@ -3,6 +3,7 @@ with Ada.Directories; with Alire.Config.Builtins; with Alire.Crates; with Alire.Directories; +with Alire.Loading; with Alire.TOML_Adapters; with Alire.Hashes.SHA256_Impl; pragma Unreferenced (Alire.Hashes.SHA256_Impl); @@ -36,6 +37,12 @@ package body Alire.TOML_Index is -- Allow or not unknown values in enums. This isn't easily moved to an -- argument given the current design. + Loading_Index_Version : Semantic_Versioning.Version; + -- FIXME: The version of the index we are currently loading. We should + -- pass this around as a regular argument in here, but it will require + -- a non-trivial refactor. To keep in mind that **index loading cannot be + -- parallelized.** + procedure Set_Error (Result : out Load_Result; Filename, Message : String; @@ -101,7 +108,6 @@ package body Alire.TOML_Index is Filename : constant String := Dirs.Compose (Root, "index.toml"); Value : TOML.TOML_Value; Key : constant String := "version"; - Version : Semantic_Versioning.Version; Suggest_Update : Boolean := False; use type Semantic_Versioning.Version; @@ -162,8 +168,9 @@ package body Alire.TOML_Index is & "only 'version' is expected"); else - Version := Semantic_Versioning.Parse (Value.Get (Key).As_String, - Relaxed => False); + Loading_Index_Version := + Semantic_Versioning.Parse (Value.Get (Key).As_String, + Relaxed => False); -- Check for a branch mismatch first @@ -174,32 +181,34 @@ package body Alire.TOML_Index is -- Check that index version is the expected one, or give minimal -- advice if it does not match. - if Alire.Index.Valid_Versions.Contains (Version) and then - Version /= Alire.Index.Version and then - Warn_Of_Old_Compatible + if Alire.Index.Valid_Versions.Contains (Loading_Index_Version) + and then Loading_Index_Version /= Alire.Index.Version + and then Warn_Of_Old_Compatible then Put_Warning ("Index '" & TTY.Emph (Index.Name) - & "' version (" & Version.Image + & "' version (" & Loading_Index_Version.Image & ") is older than the newest supported by alr (" & Alire.Index.Version.Image & ")", Disable_Config => Config.Builtins.Warning_Old_Index.Key); Suggest_Update := True; - elsif not Alire.Index.Valid_Versions.Contains (Version) then + elsif not Alire.Index.Valid_Versions.Contains (Loading_Index_Version) + then -- Index is either too old or too new - if Alire.Index.Version < Version then + if Alire.Index.Version < Loading_Index_Version then Set_Error (Result, Filename, - "index version (" & Version.Image + "index version (" & Loading_Index_Version.Image & ") is newer than that expected by alr (" & Alire.Index.Version.Image & ")." & " You may have to update alr"); - elsif Version < Semver.Parse (Alire.Index.Min_Compatible_Version) + elsif Loading_Index_Version < Semver.Parse + (Alire.Index.Min_Compatible_Version) then Set_Error (Result, Filename, - "index version (" & Version.Image + "index version (" & Loading_Index_Version.Image & ") is too old. The minimum compatible version is " & Alire.Index.Min_Compatible_Version & ASCII.LF & (if Index.Name = Alire.Index.Community_Name then @@ -225,11 +234,11 @@ package body Alire.TOML_Index is & " changes to the community index."); end if; - if Alire.Index.Version /= Version then + if Alire.Index.Version /= Loading_Index_Version then Trace.Debug ("Expected index version: " & Semantic_Versioning.Image (Alire.Index.Version)); Trace.Debug ("But got index version: " - & Semantic_Versioning.Image (Version)); + & Semantic_Versioning.Image (Loading_Index_Version)); end if; end if; @@ -501,14 +510,16 @@ package body Alire.TOML_Index is (TOML_Adapters.From (Value, Context => - "Loading externals from " & File_Name), + "Loading externals from " & File_Name, + Metadata => Loading.For_Index (Loading_Index_Version)), Strict)); else Index_Release (File_Name, Releases.From_TOML (TOML_Adapters.From (Value, - Context => "Loading release from " & File_Name), + Context => "Loading release from " & File_Name, + Metadata => Loading.For_Index (Loading_Index_Version)), Manifest.Index, Strict)); end if; diff --git a/src/alire/alire-version.ads b/src/alire/alire-version.ads index c13af6e52..c0261614f 100644 --- a/src/alire/alire-version.ads +++ b/src/alire/alire-version.ads @@ -2,7 +2,8 @@ package Alire.Version with Preelaborate is -- Remember to update Alire.Index branch if needed too - Current : constant String := "2.0-dev+beta2"; + Current : constant String := "2.0-rc1"; + -- 2.0.0-rc1: release candidate for 2.0 -- 2.0.0-b1: first public release on the 2.0 branch -- 1.2.1: build switches fix and other minor assorted fixes -- 1.2.0: rpm speed-up, silence propagation warning, early switch parse diff --git a/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/crates/libhello_1.0.0.tgz b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/crates/libhello_1.0.0.tgz new file mode 100644 index 000000000..e0add12ef Binary files /dev/null and b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/crates/libhello_1.0.0.tgz differ diff --git a/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/he/hello_world/hello_world-0.1.0.toml b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/he/hello_world/hello_world-0.1.0.toml new file mode 100644 index 000000000..fd4ff9f17 --- /dev/null +++ b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/he/hello_world/hello_world-0.1.0.toml @@ -0,0 +1,12 @@ +description = "\"Hello, world!\" demonstration project" +name = "hello_world" +version = "0.1.0" +licenses = "GPL-3.0-only" +maintainers = ["user@example.com"] +maintainers-logins = ["mylogin"] + +[origin."case(os)"."..."] # Dynamic requires it to be binary +url = "../../../crates/libhello_1.0.0.tgz" +hashes = ["sha256:c17d6ce87c6997c5f68ea4bfe6134c318073fed38ec0f81ccb1ae2bfdcc0187a"] +# Without binary marker, it should not load for index versions <= 1.3 +# binary=true \ No newline at end of file diff --git a/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/index.toml b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/index.toml new file mode 100644 index 000000000..bad265e4f --- /dev/null +++ b/testsuite/tests/index/origin-dynamic-binary-explicit/my_index/index/index.toml @@ -0,0 +1 @@ +version = "1.1" diff --git a/testsuite/tests/index/origin-dynamic-binary-explicit/test.py b/testsuite/tests/index/origin-dynamic-binary-explicit/test.py new file mode 100644 index 000000000..d86cd7244 --- /dev/null +++ b/testsuite/tests/index/origin-dynamic-binary-explicit/test.py @@ -0,0 +1,31 @@ +""" +Test that dynamic origins require a binary flag for new index versions +""" + +from drivers.alr import run_alr + +# Check basic loading in pre-1.3 versions +p = run_alr('show', 'hello_world') +assert "Origin: (case OS is others => binary archive" in p.out, \ + "Unexpected output: " + p.out + +# Check failure to load for new index versions +with open("my_index/index/index.toml", "w") as f: + f.write("version = '1.3'") + +# Should fail to load +p = run_alr("index", "--check", complain_on_error=False) +assert "Dynamic origins must explicitly set the `binary=true` property" in p.out,\ + f"Unexpected output: {p.out}" + +# Fix the origin +with open("my_index/index/he/hello_world/hello_world-0.1.0.toml", "a") as f: + f.write("binary = true") + +# Should succeed +p = run_alr('show', 'hello_world') +assert "Origin: (case OS is others => binary archive" in p.out, \ + "Unexpected output: " + p.out + + +print('SUCCESS') diff --git a/testsuite/tests/index/origin-dynamic-binary-explicit/test.yaml b/testsuite/tests/index/origin-dynamic-binary-explicit/test.yaml new file mode 100644 index 000000000..9f4d48305 --- /dev/null +++ b/testsuite/tests/index/origin-dynamic-binary-explicit/test.yaml @@ -0,0 +1,5 @@ +driver: python-script +build_mode: both +indexes: + my_index: + in_fixtures: false