1#!/usr/bin/env python3
2
3import re, subprocess, sys
4
5
6DEBUG = False
7DRY_RUN = False
8NUM_KEEP_PER_BOARD = 4
9
10
11def main():
12    ssh_machine = sys.argv[1]
13    ssh_firmware_dir = sys.argv[2]
14
15    # SSH to get list of existing files.
16    p = subprocess.run(
17        ["ssh", ssh_machine, "find", ssh_firmware_dir, "-name", "\\*-unstable-v\\*"],
18        capture_output=True,
19    )
20    if p.returncode != 0:
21        print(p.stderr)
22        return
23    all_files = p.stdout.split(b"\n")
24
25    # Parse all files to organise into boards/date/version.
26    boards = {}
27    for file in all_files:
28        m = re.match(
29            rb"([a-z/.]+)/([A-Za-z0-9_-]+)-(20[0-9]{6})-unstable-(v[0-9.-]+-g[0-9a-f]+).",
30            file,
31        )
32        if not m:
33            continue
34        dir, board, date, version = m.groups()
35        if board not in boards:
36            boards[board] = {}
37        if (date, version) not in boards[board]:
38            boards[board][(date, version)] = []
39        boards[board][(date, version)].append(file)
40
41    # Collect files to remove based on date and version.
42    remove = []
43    for board in boards.values():
44        filelist = [(date, version, files) for (date, version), files in board.items()]
45        filelist.sort(reverse=True)
46        keep = []
47        for date, version, files in filelist:
48            if keep and version == keep[-1]:
49                remove.extend(files)
50            elif len(keep) >= NUM_KEEP_PER_BOARD:
51                remove.extend(files)
52            else:
53                keep.append(version)
54
55    if DEBUG:
56        all_files.sort(reverse=True)
57        for file in all_files:
58            print(file, file in remove)
59        print(len(remove), "/", len(all_files))
60
61    # Do removal of files.
62    for file in remove:
63        file = str(file, "ascii")
64        print("remove:", file)
65        if not DRY_RUN:
66            p = subprocess.run(["ssh", ssh_machine, "/bin/rm", file], capture_output=True)
67            if p.returncode != 0:
68                print(p.stderr)
69
70
71if __name__ == "__main__":
72    main()
73