Skip to content

Commit 50cee51

Browse files
authored
Merge pull request #321 from dflook/fix-summary-outputs
Update operation count outputs
2 parents 21fbee5 + e11f2b6 commit 50cee51

File tree

3 files changed

+157
-5
lines changed

3 files changed

+157
-5
lines changed

image/src/github_actions/commands.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ def generate_delimiter():
99
return ''.join(random.choice(string.ascii_lowercase) for _ in range(20))
1010

1111
def output(name: str, value: Any) -> None:
12+
if not isinstance(value, str):
13+
value = str(value)
14+
1215
if 'GITHUB_OUTPUT' in os.environ and Path(os.environ['GITHUB_OUTPUT']).is_file():
1316
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
1417
if len(value.splitlines()) > 1:

image/src/plan_summary/__main__.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,42 @@
1616
import sys
1717
from github_actions.commands import output
1818

19+
def summary(plan: str) -> dict[str, int]:
20+
operations = {
21+
'add': 0,
22+
'change': 0,
23+
'destroy': 0,
24+
'move': None,
25+
'import': 0
26+
}
27+
28+
to_move = 0
29+
30+
for line in plan.splitlines():
31+
if re.match(r' # \S+ has moved to \S+$', line):
32+
to_move += 1
33+
34+
if not line.startswith('Plan:'):
35+
continue
36+
37+
for op in re.finditer(r'(\d+) to (\w+)', line):
38+
operations[op[2]] = int(op[1])
39+
40+
if operations['move'] is None:
41+
operations['move'] = to_move
42+
43+
return operations
44+
45+
1946
def main() -> None:
20-
"""Entrypoint for terraform-backend"""
47+
"""Entrypoint for plan_summary"""
2148

2249
with open(sys.argv[1]) as f:
2350
plan = f.read()
2451

25-
if match := re.search(r'^Plan: (\d+) to add, (\d+) to change, (\d+) to destroy', plan, re.MULTILINE):
26-
output('to_add', match[1])
27-
output('to_change', match[2])
28-
output('to_destroy', match[3])
52+
for action, count in summary(plan).items():
53+
output(f'to_{action}', count)
54+
2955

3056
if __name__ == '__main__':
3157
sys.exit(main())

tests/test_action_summary.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
from plan_summary.__main__ import summary
2+
3+
4+
def test_summary():
5+
plan = '''An execution plan has been generated and is shown below.
6+
Resource actions are indicated with the following symbols:
7+
+ create
8+
9+
Terraform will perform the following actions:
10+
11+
+ random_string.my_string
12+
id: <computed>
13+
length: "11"
14+
lower: "true"
15+
min_lower: "0"
16+
min_numeric: "0"
17+
min_special: "0"
18+
min_upper: "0"
19+
number: "true"
20+
result: <computed>
21+
special: "true"
22+
upper: "true"
23+
Plan: 1 to add, 0 to change, 0 to destroy.
24+
'''
25+
26+
assert summary(plan) == {
27+
'add': 1,
28+
'change': 0,
29+
'destroy': 0,
30+
'move': 0,
31+
'import': 0
32+
}
33+
34+
def test_summary_import():
35+
plan = '''An execution plan has been generated and is shown below.
36+
Resource actions are indicated with the following symbols:
37+
+ create
38+
39+
Terraform will perform the following actions:
40+
41+
+ random_string.my_string
42+
id: <computed>
43+
length: "11"
44+
lower: "true"
45+
min_lower: "0"
46+
min_numeric: "0"
47+
min_special: "0"
48+
min_upper: "0"
49+
number: "true"
50+
result: <computed>
51+
special: "true"
52+
upper: "true"
53+
Plan: 5 to import, 1 to add, 0 to change, 0 to destroy.
54+
'''
55+
56+
assert summary(plan) == {
57+
'add': 1,
58+
'change': 0,
59+
'destroy': 0,
60+
'move': 0,
61+
'import': 5
62+
}
63+
64+
def test_summary_remove():
65+
plan = '''An execution plan has been generated and is shown below.
66+
Resource actions are indicated with the following symbols:
67+
+ create
68+
69+
Terraform will perform the following actions:
70+
71+
+ random_string.my_string
72+
id: <computed>
73+
length: "11"
74+
lower: "true"
75+
min_lower: "0"
76+
min_numeric: "0"
77+
min_special: "0"
78+
min_upper: "0"
79+
number: "true"
80+
result: <computed>
81+
special: "true"
82+
upper: "true"
83+
Plan: 5 to import, 1 to add, 3 to remove, 0 to change, 0 to destroy.
84+
'''
85+
86+
assert summary(plan) == {
87+
'add': 1,
88+
'change': 0,
89+
'destroy': 0,
90+
'move': 0,
91+
'import': 5,
92+
'remove': 3
93+
}
94+
95+
def test_summary_move():
96+
plan = """Terraform will perform the following actions:
97+
98+
# random_string.your_string has moved to random_string.my_string
99+
resource "random_string" "my_string" {
100+
id = "Iyh3jLKc"
101+
length = 8
102+
# (8 unchanged attributes hidden)
103+
}
104+
105+
# random_string.blah_string has moved to random_string.my_string2
106+
resource "random_string" "my_string2" {
107+
id = "Iyh3jLKc"
108+
length = 8
109+
# (8 unchanged attributes hidden)
110+
}
111+
112+
Plan: 4 to add, 8 to change, 1 to destroy.
113+
"""
114+
115+
actual = summary(plan)
116+
assert actual == {
117+
'add': 4,
118+
'change': 8,
119+
'destroy': 1,
120+
'move': 2,
121+
'import': 0
122+
}
123+

0 commit comments

Comments
 (0)