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

Bugfix for nested empty tables in manifest #906

Merged
merged 3 commits into from
Jan 4, 2022
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
10 changes: 5 additions & 5 deletions src/alire/alire-conditional_trees-case_nodes.adb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package body Alire.Conditional_Trees.Case_Nodes is
return Tree'Class;

overriding
function Flatten (This : Case_Node) return Node'Class;
function Flatten (This : Case_Node) return Tree'Class;

overriding
function Image (This : Case_Node) return String;
Expand Down Expand Up @@ -183,23 +183,23 @@ package body Alire.Conditional_Trees.Case_Nodes is
-------------

overriding
function Flatten (This : Case_Node) return Node'Class is
function Flatten (This : Case_Node) return Tree'Class is
Flat : Tree;
begin
for Key of This.Cases.Keys (Exclude_Others => True, Ada_Like => False)
loop
if not This.Cases.Element (+Key).Is_Empty then
Flat := Flat and To_Tree (This.Cases.Element (+Key).Root.Flatten);
Flat := Flat and Tree (This.Cases.Element (+Key).Root.Flatten);
end if;
end loop;

if This.Cases.Has_Others then
if not This.Cases.Other.Is_Empty then
Flat := Flat and To_Tree (This.Cases.Other.Root.Flatten);
Flat := Flat and Tree (This.Cases.Other.Root.Flatten);
end if;
end if;

return Flat.Root;
return Flat;
end Flatten;

-------------------------
Expand Down
36 changes: 18 additions & 18 deletions src/alire/alire-conditional_trees.adb
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,17 @@ package body Alire.Conditional_Trees is
-------------

overriding
function Flatten (This : Vector_Node) return Node'Class is
function Flatten (This : Vector_Node) return Tree'Class is
Result : Tree;
begin
for Child of This.Values loop
case This.Conjunction is
when Anded => Result := Result and Child.Flatten.To_Tree;
when Ored => Result := Result or Child.Flatten.To_Tree;
when Anded => Result := Result and Tree (Child.Flatten);
when Ored => Result := Result or Tree (Child.Flatten);
end case;
end loop;

return Result.Root;
return Result;
end Flatten;

----------
Expand Down Expand Up @@ -276,27 +276,27 @@ package body Alire.Conditional_Trees is

function Enumerate (This : Tree) return Collection is
Col : Collection with Warnings => Off;

procedure Visit (Inner : Node'Class) is
Flat : constant Node'Class := Inner.Flatten;
-- This call recursively should result in a flat vector at worst
begin
if Flat in Leaf_Node then
Append (Col, Leaf_Node (Flat).Value.Constant_Reference);
elsif Flat in Vector_Node then
for Child of Vector_Node (Flat).Values loop
Flat : constant Tree :=
(if This.Is_Empty
then This
else Tree (This.Constant_Reference.Flatten));
begin
if not Flat.Is_Empty then
if Flat.Constant_Reference in Leaf_Node then
Append (Col, Leaf_Node (Flat.Constant_Reference.Element.all)
.Value.Constant_Reference);
elsif Flat.Constant_Reference in Vector_Node then
for Child of Vector_Node (Flat.Constant_Reference.Element.all)
.Values
loop
Append (Col, Leaf_Node (Child).Value.Constant_Reference);
end loop;
else
raise Program_Error with
"Flattened nodes must be leaves or vectors";
end if;
end Visit;

begin
if not This.Is_Empty then
Visit (This.Constant_Reference);
end if;

return Col;
end Enumerate;

Expand Down
21 changes: 11 additions & 10 deletions src/alire/alire-conditional_trees.ads
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,6 @@ package Alire.Conditional_Trees with Preelaborate is
function Leaf_Count (This : Node) return Positive is abstract;
-- Return leaves under this node; for non-leaf nodes, obtain recursively.

function Flatten (This : Node) return Node'Class is abstract;
-- with Post'Class => Flatten'Result in Leaf_Node or else
-- Flatten'Result in Vector_Node;
-- Above Post kept for reference but gnat bugs out during instantiation.
-- Recursively merge all subtree elements in a single value or vector.
-- Since it cannot result in an empty tree, it returns a proper node.

procedure Recursive_Traversal
(This : in out Node;
Apply : access procedure (Value : in out Values)) is abstract;
Expand All @@ -93,6 +86,14 @@ package Alire.Conditional_Trees with Preelaborate is
-- used to store conditional/dynamic properties and dependencies.
-- Iteration is only over direct children, when the tree is AND/OR vector.

function Flatten (This : Node) return Tree'Class is abstract
with Post'Class => Flatten'Result.Is_Empty or else
Flatten'Result.Is_Value or else
Flatten'Result.Is_Vector;
-- Above Post kept for reference but gnat bugs out during instantiation.
-- Recursively merge all subtree elements in a single value or vector. It
-- can result in an empty tree if a vector is empty, so it returns a tree.

function Root (This : Tree) return Node'Class
with Pre => not This.Is_Empty;

Expand Down Expand Up @@ -321,7 +322,7 @@ private
Unused : Properties.Vector) return Tree'Class;

overriding
function Flatten (This : Leaf_Node) return Node'Class;
function Flatten (This : Leaf_Node) return Tree'Class;

overriding
function Is_Conditional (N : Leaf_Node) return Boolean;
Expand Down Expand Up @@ -364,7 +365,7 @@ private
return Tree'Class is (New_Leaf (This.Value.Element));

overriding
function Flatten (This : Leaf_Node) return Node'Class is (This);
function Flatten (This : Leaf_Node) return Tree'Class is (To_Tree (This));

overriding
function Is_Conditional (N : Leaf_Node) return Boolean is (False);
Expand Down Expand Up @@ -399,7 +400,7 @@ private
return Tree'Class;

overriding
function Flatten (This : Vector_Node) return Node'Class;
function Flatten (This : Vector_Node) return Tree'Class;

function Conjunction (This : Vector_Node) return Conjunctions;

Expand Down
21 changes: 21 additions & 0 deletions testsuite/tests/index/empty-dependency-case/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Test that an empty nested table in dependencies does not cause an error.
Bugfix #906: https://github.com/alire-project/alire/pull/906
"""

from drivers.alr import run_alr, init_local_crate, alr_manifest
from drivers.asserts import assert_match

init_local_crate()

# Create the problematic table
with open(alr_manifest(), "at") as manifest:
manifest.write("[[depends-on]]\n")
manifest.write("[depends-on.'case(os)'.linux."
"'case(distribution)'.ubuntu]\n")

# The following command failed pre-bugfix, all is OK if it does not complain
p = run_alr("update")


print('SUCCESS')
3 changes: 3 additions & 0 deletions testsuite/tests/index/empty-dependency-case/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
driver: python-script
indexes:
basic_index: {}