Skip to content

Commit

Permalink
Require explicit binary=true for all binary origins (#1598)
Browse files Browse the repository at this point in the history
* Package to track future features

* Loading metadata and explicit binary
  • Loading branch information
mosteo authored Feb 29, 2024
1 parent 7d67c4b commit 2bf0f9e
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 37 deletions.
2 changes: 1 addition & 1 deletion alire.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion deps/semantic_versioning
5 changes: 3 additions & 2 deletions doc/catalog-format-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/alire/alire-index.ads
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
16 changes: 16 additions & 0 deletions src/alire/alire-index_features.ads
Original file line number Diff line number Diff line change
@@ -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;
25 changes: 25 additions & 0 deletions src/alire/alire-loading.ads
Original file line number Diff line number Diff line change
@@ -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;
42 changes: 41 additions & 1 deletion src/alire/alire-origins.adb
Original file line number Diff line number Diff line change
Expand Up @@ -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

----------
Expand Down Expand Up @@ -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 --
---------------
Expand Down Expand Up @@ -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)));

Expand Down
1 change: 1 addition & 0 deletions src/alire/alire-origins.ads
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 15 additions & 8 deletions src/alire/alire-toml_adapters.adb
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 --
Expand All @@ -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 --
Expand Down
28 changes: 21 additions & 7 deletions src/alire/alire-toml_adapters.ads
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.

Expand Down Expand Up @@ -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 --
--------------
Expand All @@ -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 --
Expand Down
43 changes: 27 additions & 16 deletions src/alire/alire-toml_index.adb
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
Binary file not shown.
Loading

0 comments on commit 2bf0f9e

Please sign in to comment.