Skip to content

Commit

Permalink
Merge fb463f2 into 6c2e91e
Browse files Browse the repository at this point in the history
  • Loading branch information
jscotka committed Jul 22, 2019
2 parents 6c2e91e + fb463f2 commit 1dc6a1d
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 2 deletions.
1 change: 1 addition & 0 deletions examples/conditions/.fmf/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
15 changes: 15 additions & 0 deletions examples/conditions/main.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
release: 7.0
tags: [default]
/top:
/relevant_everywhere:
tags+: [easy]
/rhel7:
release: 7.1
execute:
how: dependency
components:
- curl
- apache
/rhel8:
release: 8.0

4 changes: 3 additions & 1 deletion fmf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def find(self, name):
return node
return None

def prune(self, whole=False, keys=[], names=[], filters=[]):
def prune(self, whole=False, keys=[], names=[], filters=[], conditions=[]):
""" Filter tree nodes based on given criteria """
for node in self.climb(whole):
# Select only nodes with key content
Expand All @@ -344,6 +344,8 @@ def prune(self, whole=False, keys=[], names=[], filters=[]):
if not all([utils.filter(filter, node.data, regexp=True)
for filter in filters]):
continue
if not all([utils.afilter(filter, node) for filter in conditions]):
continue
# Handle missing attribute as if filter failed
except utils.FilterError:
continue
Expand Down
7 changes: 6 additions & 1 deletion fmf/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def options_select(self):
group.add_argument(
"--filter", dest="filters", action="append", default=[],
help="Apply advanced filter (see 'pydoc fmf.filter')")
group.add_argument(
"--condition", dest="conditions", action="append", default=[],
help="Apply advanced filter based on python logic system. "
"You can use (eg: float(key)==7 or key='value') "
"retyping, logical operands are supported, it is evaluated as bool value")
group.add_argument(
"--whole", dest="whole", action="store_true",
help="Consider the whole tree (leaves only by default)")
Expand Down Expand Up @@ -156,7 +161,7 @@ def show(self, brief=False):
tree = fmf.Tree(path)
for node in tree.prune(
self.options.whole, self.options.keys, self.options.names,
self.options.filters):
self.options.filters, self.options.conditions):
if brief:
show = node.show(brief=True)
else:
Expand Down
9 changes: 9 additions & 0 deletions fmf/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,15 @@ def enabled(self):
return self._mode == COLOR_ON


def afilter(filter, node):
locals().update(node.data)
try:
return eval(filter)
except NameError as e:
raise FilterError("Key is not defined in data: {}".format(e))
except KeyError as e:
raise FilterError("Internal key is not defined: {}".format(e))

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Default Logger
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
14 changes: 14 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,17 @@ def test_init(self):
os.remove(version_path)
with pytest.raises(utils.FormatError):
fmf.cli.main("fmf ls", path)

def test_conditions(self):
""" Advanced filters via conditions """
CONDS = PATH + "/../examples/conditions"
output = fmf.cli.main("fmf ls --condition 'float(release)>=7'", CONDS)
assert len(output.splitlines()) == 3
output = fmf.cli.main("fmf ls --condition 'float(release)>7'", CONDS)
assert len(output.splitlines()) == 2
output = fmf.cli.main("""fmf show --condition "execute['how']=='dependency'" --format "comp: {}\n" --value "data['execute']['components']" """, CONDS)
assert len(output.splitlines()) == 1
assert "'apache'" in output
assert "'curl'" in output
assert "comp: " in output

0 comments on commit 1dc6a1d

Please sign in to comment.