Skip to content

Commit 395984e

Browse files
committed
Merge branch 'feat/diag_purge_file' into 'master'
feat(tools): enable passing the purge file as an argument to diag Closes IDF-11825 See merge request espressif/esp-idf!36659
2 parents 9b876d9 + 7216d11 commit 395984e

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Purge format description for idf.py diag
2+
3+
Once diagnostic information is collected, the purge file is utilized to remove
4+
any sensitive data from the gathered files. By default, the purge file located
5+
at `tools/idf_py_actions/diag/purge/purge.yml` is used unless it is specified
6+
with the --purge argument, in which case the default file is not used.
7+
8+
## Overview of Purge Structure
9+
10+
It is a straightforward YAML file that includes a list of regular expressions
11+
and the corresponding strings that should replace any matches.
12+
13+
- regex: regular expression to look for
14+
repl: substitute string for match
15+
16+
The `regex.sub` function from Python is used internally.
File renamed without changes.

tools/idf_py_actions/diag_ext.py

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ def log(level: int, msg: str, prefix: str) -> None:
116116
else:
117117
log_prefix = ''
118118

119-
msg = textwrap.indent(msg, prefix=log_prefix)
120-
121119
if LOG_FILE:
122120
try:
123121
log_msg = textwrap.indent(msg, prefix=f'{prefix} ')
@@ -131,6 +129,8 @@ def log(level: int, msg: str, prefix: str) -> None:
131129
if level > LOG_LEVEL:
132130
return
133131

132+
msg = textwrap.indent(msg, prefix=log_prefix)
133+
134134
if not LOG_COLORS or level not in (LOG_FATAL, LOG_ERROR, LOG_WARNING):
135135
print(msg, file=sys.stderr)
136136
sys.stderr.flush()
@@ -257,11 +257,8 @@ def diff_dirs(dir1: Path, dir2: Path) -> None:
257257
dbg(line.strip())
258258

259259

260-
def redact_files(dir1: Path, dir2: Path) -> None:
260+
def redact_files(dir1: Path, dir2: Path, purge: list) -> None:
261261
"""Show differences in files between two directories."""
262-
purge_path = Path(__file__).parent / 'diag' / 'purge.yml'
263-
with open(purge_path, 'r') as f:
264-
purge = yaml.safe_load(f.read())
265262

266263
regexes: List = []
267264
for entry in purge:
@@ -488,6 +485,47 @@ def validate_recipe(recipe: Dict) -> None:
488485
raise RuntimeError(f'Unknown command "{cmd}" in step "{step_name}"')
489486

490487

488+
def validate_purge(purge: Any) -> None:
489+
"""Validate the loaded purge file. This is done manually to avoid any
490+
dependencies and to provide more informative error messages.
491+
"""
492+
493+
if type(purge) is not list:
494+
raise RuntimeError(f'Purge is not of type "list"')
495+
496+
regex_keys = ['regex', 'repl']
497+
498+
for entry in purge:
499+
if type(entry) is not dict:
500+
raise RuntimeError(f'Purge entry "{entry}" is not of type "dict"')
501+
502+
if 'regex' in entry:
503+
for key in entry:
504+
if key not in regex_keys:
505+
raise RuntimeError((f'Unknown purge key "{key}" in "{entry}", '
506+
f'expecting "{regex_keys}"'))
507+
508+
regex = entry.get('regex')
509+
repl = entry.get('repl')
510+
511+
# Required arguments
512+
if type(regex) is not str:
513+
raise RuntimeError(f'Argument "regex" for purge entry "{entry}" is not of type "str"')
514+
try:
515+
re.compile(regex)
516+
except re.error as e:
517+
raise RuntimeError((f'Argument "regex" for purge entry "{entry}" is not '
518+
f'a valid regular expression: {e}'))
519+
520+
if not repl:
521+
raise RuntimeError(f'Purge entry "{entry}" is missing "repl" argument')
522+
if type(repl) is not str:
523+
raise RuntimeError(f'Argument "repl" for purge entry "{entry}" is not of type "str"')
524+
525+
else:
526+
raise RuntimeError(f'Unknown purge entry "{entry}"')
527+
528+
491529
def get_output_path(src: Optional[str],
492530
dst: Optional[str],
493531
step: Dict,
@@ -934,6 +972,7 @@ def create(action: str,
934972
check_recipes: bool,
935973
cmdl_recipes: Tuple,
936974
cmdl_tags: Tuple,
975+
purge_file: str,
937976
append: bool,
938977
output: Optional[str]) -> None:
939978

@@ -1032,11 +1071,25 @@ def create(action: str,
10321071
except Exception:
10331072
die(f'File "{recipe_file}" is not a valid diagnostic file')
10341073

1074+
# Load purge file
1075+
dbg(f'Purge file: {purge_file}')
1076+
try:
1077+
with open(purge_file, 'r') as f:
1078+
purge = yaml.safe_load(f.read())
1079+
except Exception:
1080+
die(f'Cannot load purge file "{purge_file}"')
1081+
1082+
# Validate purge file
1083+
try:
1084+
validate_purge(purge)
1085+
except Exception:
1086+
die(f'File "{purge_file}" is not a valid purge file')
1087+
10351088
# Cook recipes
10361089
try:
10371090
for recipe_file, recipe in recipes.items():
10381091
desc = recipe.get('description')
1039-
dbg(f'Processing recipe "{desc} "file "{recipe_file}"')
1092+
dbg(f'Processing recipe "{desc}" file "{recipe_file}"')
10401093
print(f'{desc}')
10411094
process_recipe(recipe)
10421095
except Exception:
@@ -1050,9 +1103,9 @@ def create(action: str,
10501103
LOG_FILE = None
10511104

10521105
try:
1053-
redact_files(TMP_DIR_REPORT_PATH, TMP_DIR_REPORT_REDACTED_PATH)
1106+
redact_files(TMP_DIR_REPORT_PATH, TMP_DIR_REPORT_REDACTED_PATH, purge)
10541107
except Exception:
1055-
err(f'The redaction was unsuccessful.')
1108+
err(f'The redaction was unsuccessful')
10561109

10571110
try:
10581111
shutil.move(TMP_DIR_REPORT_REDACTED_PATH, output_dir_path)
@@ -1142,6 +1195,15 @@ def action_extensions(base_actions: Dict, project_path: str) -> Any:
11421195
'and the report directory specified with the --zip option with a zip '
11431196
'extension is used for the zip file archive.')
11441197
},
1198+
{
1199+
'names': ['-p', '--purge', 'purge_file'],
1200+
'metavar': 'PATH',
1201+
'type': str,
1202+
'default': str(Path(__file__).parent / 'diag' / 'purge' / 'purge.yml'),
1203+
'help': ('Purge file PATH containing a description of what information '
1204+
'should be redacted from the resulting report. '
1205+
'Default is "tools/idf_py_actions/diag/purge/purge.yml"')
1206+
},
11451207
],
11461208
},
11471209
},

0 commit comments

Comments
 (0)