diff --git a/index/alire-index-alire.ads b/index/alire-index-alire.ads index 3b5b097b..1bc3a83f 100644 --- a/index/alire-index-alire.ads +++ b/index/alire-index-alire.ads @@ -27,11 +27,19 @@ package Alire.Index.Alire is Dependencies => Current ("half_life_3") and -- unconditional - If_Platform -- conditional + On_Condition -- conditional (System_Is (GNU_Linux), When_True => At_Least ("elite_horizons", V ("2.0")) and At_Least ("star_citizen", V ("3.0")), -- Wish... - When_False => At_Least ("windows_100", V ("1.0"))), + When_False => At_Least ("windows_100", V ("1.0"))) and + When_Available -- Chained preferences + (Preferred => Within_Major ("alire", V ("1.0")), + Otherwise => Within_Major ("alire", V ("0.0"))) and + When_Available -- Chained preferences + (Preferred => Within_Major ("alire", V ("2.0")), + Otherwise => When_Available -- Chained preferences multi-level + (Preferred => Within_Major ("alire_alt", V ("1.0")), + Otherwise => Within_Major ("alire", V ("0.5")))), Properties => GPR_Extra_Config ("-XProfile=False") and @@ -41,26 +49,26 @@ package Alire.Index.Alire is GPR_Free_Scenario ("Path_To_Something") and -- Known scenario variables - If_Platform + On_Condition (System_Is (Windows), GPR_File ("project_win.gpr")) and - If_Platform + On_Condition (System_Is (GNU_Linux), - If_Platform (Distribution_Is (Ubuntu), -- Nested conditions + On_Condition (Distribution_Is (Ubuntu), -- Nested conditions GPR_File ("project_ubuntu.gpr"))) and -- Conditional project file - If_Platform + On_Condition (System_Is (GNU_Linux), Comment ("Long life the penguin")) and -- Conditions on operating system - If_Platform + On_Condition (not Compiler_Is (GNAT_Unknown), Comment ("Never saw that compiler") and Comment ("But I would like to")) and -- Conditions on compiler version - If_Platform + On_Condition (Version_Is (Ubuntu_Artful), When_True => Comment ("Living on the edge"), When_False => Comment ("I am a rock")) and diff --git a/index/alire-index-dak.ads b/index/alire-index-dak.ads index 09e188ed..ded7ee03 100644 --- a/index/alire-index-dak.ads +++ b/index/alire-index-dak.ads @@ -231,36 +231,36 @@ package Alire.Index.DAK is ); Components_ODBC_V_4_27 : constant Release := - Register (Base & "components_odbc", - V ("4.27"), - Desc_Pre & "(ODBC bindings)" & Desc_Post, - Git (Repo, "47337f8a5dd69404087129d5cca79885d6e8cd3f"), - Dependencies => - Within_Major (Components_V_4_27) and - Current (UnixODBC.V_2_3), + Register (Base & "components_odbc", + V ("4.27"), + Desc_Pre & "(ODBC bindings)" & Desc_Post, + Git (Repo, "47337f8a5dd69404087129d5cca79885d6e8cd3f"), + Dependencies => + Within_Major (Components_V_4_27) and + Current (UnixODBC.V_2_3), - Properties => - GPR_File ("components-odbc.gpr") and - GPR_File ("test_components" / "components-odbc-odbc_bindings_tests.gpr") and + Properties => + GPR_File ("components-odbc.gpr") and + GPR_File ("test_components" / "components-odbc-odbc_bindings_tests.gpr") and - If_Platform - (System_Is (GNU_Linux), - GPR_Extra_Config ("-Xodbc=unixODBC")) and - If_Platform - (System_Is (Windows), - GPR_Extra_Config ("-Xodbc=ODBC32")) and - If_Platform - (Word_Size_Is (Bits_32), - GPR_Extra_Config ("-Xarch=i686")) and - If_Platform - (Word_Size_Is (Bits_64), - GPR_Extra_Config ("-Xarch=x86_64")) and + On_Condition + (System_Is (GNU_Linux), + GPR_Extra_Config ("-Xodbc=unixODBC")) and + On_Condition + (System_Is (Windows), + GPR_Extra_Config ("-Xodbc=ODBC32")) and + On_Condition + (Word_Size_Is (Bits_32), + GPR_Extra_Config ("-Xarch=i686")) and + On_Condition + (Word_Size_Is (Bits_64), + GPR_Extra_Config ("-Xarch=x86_64")) and - Executable ("test_odbc_bindings") and + Executable ("test_odbc_bindings") and - License (GMGPL_2_0) and - Author (DAK_Author) and - Website (DAK_Website) - ); + License (GMGPL_2_0) and + Author (DAK_Author) and + Website (DAK_Website) + ); end Alire.Index.DAK; diff --git a/index/alire-index-libadacrypt.ads b/index/alire-index-libadacrypt.ads index a8afaae2..6a7882f3 100644 --- a/index/alire-index-libadacrypt.ads +++ b/index/alire-index-libadacrypt.ads @@ -11,6 +11,7 @@ package Alire.Index.Libadacrypt is V ("0.8.7"), Prj_Desc, Git (Prj_Repo, "06b4907c6ae6dcdce62339ff8fd2913d7bbbc0d9"), + Properties => Author (Prj_Author) and diff --git a/src/alire-conditional.ads b/src/alire-conditional.ads index 14e2794b..ad4783e8 100644 --- a/src/alire-conditional.ads +++ b/src/alire-conditional.ads @@ -6,11 +6,13 @@ with Alire.Requisites; package Alire.Conditional with Preelaborate is package For_Dependencies is new Conditional_Values (Dependencies.Vectors.Vector, - Dependencies.Vectors."and"); + Dependencies.Vectors."and", + Dependencies.Vectors.Image_One_Line); subtype Dependencies is For_Dependencies.Conditional_Value; package For_Properties is new Conditional_Values (Properties.Vector, - Properties."and"); + Properties."and", + Properties.Image_One_Line); subtype Properties is For_Properties.Conditional_Value; end Alire.Conditional; diff --git a/src/alire-conditional_values.ads b/src/alire-conditional_values.ads index 35446d45..f778e05f 100644 --- a/src/alire-conditional_values.ads +++ b/src/alire-conditional_values.ads @@ -1,5 +1,6 @@ with Alire.Properties; with Alire.Requisites; +with Alire.Utils; private with Ada.Containers.Indefinite_Holders; private with Ada.Containers.Indefinite_Vectors; @@ -7,6 +8,7 @@ private with Ada.Containers.Indefinite_Vectors; generic type Values is private; with function "&" (L, R : Values) return Values; + with function Image (V : Values) return String; package Alire.Conditional_Values with Preelaborate is type Kinds is (Condition, Value, Vector); @@ -34,6 +36,8 @@ package Alire.Conditional_Values with Preelaborate is function All_Values (This : Conditional_Value) return Values; -- Returns all values herein, both true and false, at any depth + function Image_One_Line (This : Conditional_Value) return String; + --------------- -- SINGLES -- --------------- @@ -71,6 +75,10 @@ private type Inner_Node is abstract tagged null record; + function Image (Node : Inner_Node) return String is abstract; + + function Image_Classwide (Node : Inner_Node'Class) return String is (Node.Image); + function Kind (This : Inner_Node'Class) return Kinds; package Holders is new Ada.Containers.Indefinite_Holders (Inner_Node'Class); @@ -83,16 +91,36 @@ private Value : Values; end record; + overriding function Image (V : Value_Inner) return String is + (Image (V.Value)); + type Vector_Inner is new Inner_Node with record Values : Vectors.Vector; end record; + package Non_Primitive is + function One_Liner is new Utils.Image_One_Line + (Vectors, + Vectors.Vector, + Image_Classwide, + " and ", + "(empty condition)"); + end Non_Primitive; + + overriding function Image (V : Vector_Inner) return String is + (Non_Primitive.One_Liner (V.Values)); + type Conditional_Inner is new Inner_Node with record Condition : Requisites.Tree; Then_Value : Conditional_Value; Else_Value : Conditional_Value; end record; + overriding function Image (V : Conditional_Inner) return String is + ("when " & V.Condition.Image & + " then " & V.Then_Value.Image_One_Line & + " else " & V.Else_Value.Image_One_Line); + -------------- -- As_Value -- -------------- @@ -189,8 +217,11 @@ private else Condition)); function Kind (This : Conditional_Value) return Kinds is - (This.Constant_Reference.Kind); + (This.Constant_Reference.Kind); - -- The price of doing this without pointers is this manual dispatching... + function Image_One_Line (This : Conditional_Value) return String is + (if This.Is_Empty + then "(empty condition)" + else This.Constant_Reference.Image); end Alire.Conditional_Values; diff --git a/src/alire-dependencies-vectors.ads b/src/alire-dependencies-vectors.ads index de63f8dd..41576db8 100644 --- a/src/alire-dependencies-vectors.ads +++ b/src/alire-dependencies-vectors.ads @@ -1,5 +1,7 @@ with Ada.Containers.Indefinite_Vectors; +with Alire.Utils; + package Alire.Dependencies.Vectors with Preelaborate is -- Dependencies are a plain list (vector) of individual dependencies @@ -9,6 +11,8 @@ package Alire.Dependencies.Vectors with Preelaborate is type Vector is new Dependency_Vectors.Vector with private; + function Image_One_Line (V : Vector) return String; + function No_Dependencies return Vector; -- Creation of dependency vectors @@ -33,4 +37,21 @@ private Versions : Semantic_Versioning.Version_Set) return Vector is (To_Vector ((Name'Length, Name, To_Holder (Versions)), 1)); + -------------------- + -- Image_One_Line -- + -------------------- + + package Non_Primitives is + function Image_One_Line_Instance is + new Utils.Image_One_Line (Dependency_Vectors, + Vector, + Image, + " and ", + "(no dependencies"); + end Non_Primitives; + + function Image_One_Line (V : Vector) return String renames Non_Primitives.Image_One_Line_Instance; + +-- (if V.Is_Empty then "(no dependencies)" else Image_With_Pos (V, 1)); + end Alire.Dependencies.Vectors; diff --git a/src/alire-index.ads b/src/alire-index.ads index 6380495e..2001a749 100644 --- a/src/alire-index.ads +++ b/src/alire-index.ads @@ -15,6 +15,7 @@ with Alire.Properties.Licenses; with Alire.Properties.Scenarios; with Alire.Releases; with Alire.Requisites; +with Alire.Requisites.Dependencies; with Alire.Requisites.Platform; with Alire.Root_Project; @@ -72,11 +73,13 @@ package Alire.Index is function Packaged_As (S : String) return Origins.Package_Names renames Origins.Packaged_As; - Unavailable : constant Origins.Package_Names := Origins.Unavailable; + function Unavailable return Origins.Package_Names renames Origins.Unavailable; function Native (Distros : Origins.Native_Packages) return Origins.Origin renames Origins.New_Native; - -- Shortcuts to give dependencies: + ------------------ + -- Dependencies -- + ------------------ package Semver renames Semantic_Versioning; @@ -94,11 +97,13 @@ package Alire.Index is -- Simpler if there's no exact release matching the versions we want to say -- Also needed for the generated _alr files which don't know about package names + function Unavailable return Release_Dependencies renames Releases.Unavailable; + -- A never available release + function Current (R : Release) return Release_Dependencies is - (On (R.Project, Semver.Within_Major (Semver.New_Version (Semver.Major (R.Version))))); + (On (R.Project, Semver.Within_Major (R.Version))); -- Within the major of R, -- it will accept the newest/oldest version according to the resolution policy (by default, newest) - -- Note: it might be older than R itself -- These take a release and use its name and version to derive a dependency function Within_Major is new Releases.From_Release (Semver.Within_Major); @@ -125,13 +130,27 @@ package Alire.Index is function Exactly is new Releases.From_Names (Semver.Exactly); function Except is new Releases.From_Names (Semver.Except); + function On_Condition (Condition : Requisites.Tree; + When_True : Release_Dependencies; + When_False : Release_Dependencies := No_Dependencies) + return Release_Dependencies + renames Conditional.For_Dependencies.New_Conditional; + -- Excplicitly conditional + + function When_Available (Preferred : Release_Dependencies; + Otherwise : Release_Dependencies := Releases.Unavailable) + return Release_Dependencies is + (On_Condition (Requisites.Dependencies.New_Requisite (Preferred), + Preferred, + Otherwise)); + -- Chained conditional dependencies (use first available) + function "and" (L, R : Release_Dependencies) return Release_Dependencies renames Conditional.For_Dependencies."and"; ------------------ - -- PROPERTIES -- + -- Properties -- ------------------ - -- (as vectors of conditionals) -- use all type Alire.Dependencies.Vectors.Vector; use all type GPR.Value; @@ -144,18 +163,13 @@ package Alire.Index is use all type Properties.Property'Class; use all type Release_Dependencies; use all type Release_Properties; - use all type Requisites.Tree; - - -- Function for introducing conditional properties depending on platform conditions - function If_Platform (Condition : Requisites.Tree; - When_True : Release_Dependencies; - When_False : Release_Dependencies := No_Dependencies) - return Release_Dependencies renames Conditional.For_Dependencies.New_Conditional; + use all type Requisites.Tree; - function If_Platform (Condition : Requisites.Tree; - When_True : Release_Properties; - When_False : Release_Properties := No_Properties) - return Release_Properties renames Conditional.For_Properties.New_Conditional; + function On_Condition (Condition : Requisites.Tree; + When_True : Release_Properties; + When_False : Release_Properties := No_Properties) + return Release_Properties renames Conditional.For_Properties.New_Conditional; + -- Conditional properties -- Attributes (named pairs of label-value) -- We need them as Properties.Vector (inside conditionals) but also as diff --git a/src/alire-properties-dependencies.ads b/src/alire-properties-dependencies.ads new file mode 100644 index 00000000..d845d34e --- /dev/null +++ b/src/alire-properties-dependencies.ads @@ -0,0 +1,44 @@ +with Alire.Dependencies.Vectors; +with Alire.Properties; + +package Alire.Properties.Dependencies with Preelaborate is + + type Availability_Checker is new Property with private; + + type Checker_Function is access function (Dependencies : Alire.Dependencies.Vectors.Vector) + return Boolean; + -- The platform-bound function that says if a dependency is available + -- Currently, Alr.Query.Is_Resolvable + + function New_Property (Checker : Checker_Function; + Props : Properties.Vector) return Vector; + + function Checker (This : Availability_Checker) return Checker_Function; + + function Properties (This : Availability_Checker) return Properties.Vector; + -- Contained platform properties + +private + + type Availability_Checker is new Property with record + Checker : Checker_Function; -- Needed to check resolution + Properties : Alire.Properties.Vector; -- Needed to materialize the conditional dependencies + end record; + + overriding function Image (This : Availability_Checker) return String is + ("internal availability checker - OMG WHY ARE YOU SEEING THIS"); -- Don't think it should ever seen + + function New_Property (Checker : Checker_Function; + Props : Alire.Properties.Vector) return Vector is + (+Availability_Checker'(Checker => Checker, + Properties => Props)); + + function Checker (This : Availability_Checker) return Checker_Function is + (This.Checker); + + function Properties (This : Availability_Checker) return Alire.Properties.Vector is + (This.Properties); + + -- FIXME currently there is no recursivity detection so mutually dependent packages will enter infinite loop + +end Alire.Properties.Dependencies; diff --git a/src/alire-properties.ads b/src/alire-properties.ads index dc792e38..503cdb04 100644 --- a/src/alire-properties.ads +++ b/src/alire-properties.ads @@ -1,5 +1,7 @@ with Ada.Containers.Indefinite_Vectors; +with Alire.Utils; + package Alire.Properties with Preelaborate is -- Properties are the general mechanism used to store all info about a release. @@ -31,6 +33,8 @@ package Alire.Properties with Preelaborate is function "and" (L, R : Vector) return Vector; function "+" (P : Property'Class) return Vector; + function Image_One_Line (V : Vector) return String; + -- A generic helper to simply store/retrieve e.g. an enumerated type generic type Value is private; @@ -75,4 +79,15 @@ private -- function "and" (L, R : Property'Class) return Vector is (L & R); -- function "and" (L : Vector; R : Property'Class) return Vector is (L & R); + package Non_Primitives is + function Image_One_Line_Instance is + new Utils.Image_One_Line (Vectors, + Vector, + Image_Classwide, + " and ", + "(no properties"); + end Non_Primitives; + + function Image_One_Line (V : Vector) return String renames Non_Primitives.Image_One_Line_Instance; + end Alire.Properties; diff --git a/src/alire-releases.ads b/src/alire-releases.ads index 40186e6e..175d3595 100644 --- a/src/alire-releases.ads +++ b/src/alire-releases.ads @@ -75,6 +75,7 @@ package Alire.Releases with Preelaborate is -- True if some property contains the given string -- Dependency generation helpers for all semantic versioning functions: + -- These are here to avoid a 'body not seen' Program_Error if they were in Index function On (Name : Project_Name; Versions : Semantic_Versioning.Version_Set) @@ -89,7 +90,13 @@ package Alire.Releases with Preelaborate is function From_Names (P : Project_Name; V : Semantic_Versioning.Version) return Conditional.Dependencies; + function Unavailable return Conditional.Dependencies; + -- A never available dependency that is useful in conditional chained dependencies (see Index) + private + + function Unavailable return Conditional.Dependencies is + (On ("alire_unavailable", Semantic_Versioning.Any)); use Properties; function Describe is new Properties.Labeled.Cond_New_Label (Properties.Labeled.Description); @@ -138,8 +145,7 @@ private function Depends (R : Release; P : Properties.Vector) - return Dependencies.Vector is - (R.Dependencies.Evaluate (P)); + return Dependencies.Vector is (R.Dependencies.Evaluate (P)); function Origin (R : Release) return Origins.Origin is (R.Origin); function Available (R : Release) return Requisites.Tree is (R.Available); diff --git a/src/alire-requisites-dependencies.ads b/src/alire-requisites-dependencies.ads new file mode 100644 index 00000000..77584e9e --- /dev/null +++ b/src/alire-requisites-dependencies.ads @@ -0,0 +1,39 @@ +with Alire.Conditional; +with Alire.Properties.Dependencies; + +package Alire.Requisites.Dependencies with Preelaborate is + + -- Special requisite that is fulfilled when a dependency is available on a platform + -- This is checked against a special property that encapsulates the check of + -- actual packages available once the platform is known + + package Typed is new Typed_Requisites (Properties.Dependencies.Availability_Checker); + + type Requisite is new Typed.Requisite with private; + + function New_Requisite (On : Conditional.Dependencies) return Tree; + + overriding function Is_Satisfied (R : Requisite; + P : Properties.Dependencies.Availability_Checker) + return Boolean; + + overriding function Image (R : Requisite) return String; + +private + + type Requisite is new Typed.Requisite with record + Deps : Conditional.Dependencies; + end record; + + function New_Requisite (On : Conditional.Dependencies) return Tree is + (Trees.Leaf (Requisite'(Deps => On))); + + overriding function Is_Satisfied (R : Requisite; + P : Properties.Dependencies.Availability_Checker) + return Boolean is + (P.Checker.all (R.Deps.Evaluate (P.Properties))); + + overriding function Image (R : Requisite) return String is + (R.Deps.Image_One_Line & " resolvable"); + +end Alire.Requisites.Dependencies; diff --git a/src/alire-requisites.ads b/src/alire-requisites.ads index 05294ebf..7fe71854 100644 --- a/src/alire-requisites.ads +++ b/src/alire-requisites.ads @@ -70,8 +70,6 @@ package Alire.Requisites with Preelaborate is then Requisite'Class (R).Is_Satisfied (Compatible_Property (P)) else False); - -- For free we get a requisite that is equality for value properties - end Typed_Requisites; -------------- diff --git a/src/alire-types.ads b/src/alire-types.ads index 7f647330..a739aa06 100644 --- a/src/alire-types.ads +++ b/src/alire-types.ads @@ -1,12 +1,16 @@ with Alire.Conditional; +with Alire.Dependencies; with Alire.Dependencies.Vectors; package Alire.Types with Preelaborate is -- Recopilation of types for convenient use and documentation + subtype Dependency is Dependencies.Dependency; + -- A single dependency on a single project+versions + subtype Platform_Dependencies is Dependencies.Vectors.Vector; - -- A plain vector + -- A plain vector, all dependencies must be met subtype Abstract_Dependencies is Conditional.Dependencies; -- Conditional dependencies as yet unmaterialized for a precise platform diff --git a/src/alire-utils.adb b/src/alire-utils.adb index 7bc4ca10..135bdad8 100644 --- a/src/alire-utils.adb +++ b/src/alire-utils.adb @@ -78,4 +78,26 @@ package body Alire.Utils is end return; end To_Mixed_Case; + -------------------- + -- Image_One_Line -- + -------------------- + + function Image_One_Line (V : Vector) return String is + + use all type Vectors.Index_Type; + + function Image (V : Vector; Pos : Vectors.Index_Type) return String is + (Image (V.Element (Pos)) & + (if Pos = V.Last_Index + then "" + else Separator & Image (V, Pos + 1))); + + begin + if V.Is_Empty then + return When_Empty; + else + return Image (V, V.First_Index); + end if; + end Image_One_Line; + end Alire.Utils; diff --git a/src/alire-utils.ads b/src/alire-utils.ads index 98063792..7a9c2e79 100644 --- a/src/alire-utils.ads +++ b/src/alire-utils.ads @@ -15,6 +15,14 @@ package Alire.Utils with Preelaborate is -- If Str contains Separator, the rhs is returned -- Otherwise "" + generic + with package Vectors is new Ada.Containers.Indefinite_Vectors (<>); + type Vector is new Vectors.Vector with private; + with function Image (Item : Vectors.Element_Type) return String is <>; + Separator : String := " "; + When_Empty : String := "(empty)"; + function Image_One_Line (V : Vector) return String; + -------------------- -- String_Vectors -- --------------------