File tree Expand file tree Collapse file tree
tests/unit/plugins/filter Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
88## [ Unreleased]
99
10+ ### Added
11+
12+ - Add a "parse" filter to get path components
13+
1014## [ 2.2.0] - 2026-01-02
1115
1216### Added
Original file line number Diff line number Diff line change 1+ from __future__ import annotations
2+
3+ from ansible .errors import AnsibleTemplateError
4+ from pathlib import Path
5+
6+
7+ def _parse (path ):
8+ if not isinstance (path , dict ):
9+ raise AnsibleTemplateError (f'parse input expects a dict but was given a { type (path ).__name__ } ' )
10+
11+ p = Path (path ['path' ])
12+
13+ # Parent
14+ parent = str (p .parent )
15+ if parent in ['.' , '/' ]:
16+ parent = ''
17+
18+ # Extension
19+ extension = p .suffix .lstrip ('.' )
20+
21+ return {
22+ 'parent' : parent ,
23+ 'name' : p .name ,
24+ 'stem' : p .stem ,
25+ 'extension' : extension ,
26+ }
27+
28+
29+ class FilterModule (object ):
30+ """ Manala path parse jinja2 filters """
31+
32+ def filters (self ):
33+ return {
34+ 'parse' : _parse ,
35+ }
Original file line number Diff line number Diff line change 1+ ---
2+
3+ DOCUMENTATION :
4+ name : parse
5+ author :
6+ - Manala (@manala)
7+ short_description : Get the components of a path dict
8+ description :
9+ - Returns the components of a path dict.
10+ positional : _input
11+ options :
12+ _input :
13+ description : A path dict.
14+ type : dict
15+ required : true
16+
17+ RETURN :
18+ _value :
19+ description : Components.
20+ type : dict
21+
22+ EXAMPLES : |
23+ - ansible.builtin.debug:
24+ msg:
25+ - >
26+ {'path': 'foo'} | manala.path.parse
Original file line number Diff line number Diff line change 1+ from __future__ import annotations
2+
3+ import unittest
4+ from plugins .filter .parse import _parse as _filter_parse
5+
6+ from ansible .errors import AnsibleTemplateError
7+
8+
9+ class TestParse (unittest .TestCase ):
10+
11+ def test_invalid_inputs (self ):
12+ path = NotImplemented
13+
14+ with self .assertRaisesRegex (AnsibleTemplateError , f'parse input expects a dict but was given a { type (path ).__name__ } ' ):
15+ _filter_parse (path )
16+
17+ def test (self ):
18+ self .assertEqual ({
19+ 'parent' : '' ,
20+ 'name' : '' ,
21+ 'stem' : '' ,
22+ 'extension' : '' ,
23+ } , _filter_parse (
24+ {'path' : '' }
25+ ))
26+
27+ self .assertEqual ({
28+ 'parent' : '' ,
29+ 'name' : 'foo' ,
30+ 'stem' : 'foo' ,
31+ 'extension' : '' ,
32+ } , _filter_parse (
33+ {'path' : 'foo' }
34+ ))
35+
36+ self .assertEqual ({
37+ 'parent' : '' ,
38+ 'name' : 'foo.bar' ,
39+ 'stem' : 'foo' ,
40+ 'extension' : 'bar' ,
41+ } , _filter_parse (
42+ {'path' : 'foo.bar' }
43+ ))
44+
45+ self .assertEqual ({
46+ 'parent' : '' ,
47+ 'name' : 'foo' ,
48+ 'stem' : 'foo' ,
49+ 'extension' : '' ,
50+ } , _filter_parse (
51+ {'path' : '/foo' }
52+ ))
53+
54+ self .assertEqual ({
55+ 'parent' : '' ,
56+ 'name' : 'foo.bar' ,
57+ 'stem' : 'foo' ,
58+ 'extension' : 'bar' ,
59+ } , _filter_parse (
60+ {'path' : '/foo.bar' }
61+ ))
62+
63+ self .assertEqual ({
64+ 'parent' : '/foo/bar' ,
65+ 'name' : 'baz' ,
66+ 'stem' : 'baz' ,
67+ 'extension' : '' ,
68+ } , _filter_parse (
69+ {'path' : '/foo/bar/baz' }
70+ ))
71+
72+ self .assertEqual ({
73+ 'parent' : '/foo/bar' ,
74+ 'name' : 'baz.qux' ,
75+ 'stem' : 'baz' ,
76+ 'extension' : 'qux' ,
77+ } , _filter_parse (
78+ {'path' : '/foo/bar/baz.qux' }
79+ ))
You can’t perform that action at this time.
0 commit comments