Fix the dry run of a log cleanup command

Review the AI's codeEasy10 min

Your task

An AI assistant gave you find /var/log/myapp -name '*.log' -mtime +7 -delete for a nightly cron job. Before it runs unattended, you do a dry run: you list exactly what -delete would remove and read that list. Your tool builds the list from a file listing, so it must match what find would delete, file for file.

An assistant wrote preview_find_delete(file_lines, mtime_plus_days). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • file_lines: one string per file under /var/log/myapp, subfolders included, in the form "path|age", like "/var/log/myapp/app.log|10". The age is the file's age in whole days.
  • mtime_plus_days: the N in -mtime +N, an integer of 0 or more.
  • Return the list of paths find would delete.

Rules the tests check:

  • Split each line at its first |. Skip a line that has no |.
  • Trim whitespace at both ends of the path and of the age. Skip the line when either one is empty after trimming.
  • A valid age is an optional - followed by one or more digits 0 to 9, and nothing else. Skip a line whose age is not valid, such as abc, +9 or 1|2.
  • The basename is the part of the path after its last /, or the whole path when it has no /.
  • A file matches -name '*.log' when its basename ends with .log. Case matters, so APP.LOG does not match, and neither do app.log.1 or app.log.gz. Every basename that ends with .log matches, including .log itself and names that start with a dot.
  • Files in subfolders count the same as files at the top.
  • -mtime +N means strictly more than N days. A matching file is deleted when its age is greater than mtime_plus_days. A file exactly mtime_plus_days days old stays.
  • Return the trimmed path of each deleted file, in input order. Keep duplicates: a file listed twice appears twice.

Examples

preview_find_delete(file_lines: list[str], mtime_plus_days: int) -> list[str]
Example 1
Inputpreview_find_delete(["/var/log/myapp/app.log|10", "/var/log/myapp/app.log.1|30", "/var/log/myapp/access.log|7", "/var/log/myapp/debug.log|8"], 7)
Output["/var/log/myapp/app.log", "/var/log/myapp/debug.log"]
Example 2
Inputpreview_find_delete(["/var/log/myapp/app.log|10", "/var/log/myapp/app.log.1|30", "/var/log/myapp/access.log|7", "/var/log/myapp/debug.log|8"], 0)
Output["/var/log/myapp/app.log", "/var/log/myapp/access.log", "/var/log/myapp/debug.log"]
Example 3
Inputpreview_find_delete(["/var/log/myapp/archive/old.log|365", "/var/log/myapp/notes.txt|400", "/var/log/myapp/app.log.gz|400"], 7)
Output["/var/log/myapp/archive/old.log"]