1#!/usr/bin/env python3
2# Copyright (c) 2020-2023 Intel Corp.
3# SPDX-License-Identifier: Apache-2.0
4
5"""
6Syntax of file:
7    [
8        {
9            "version": "<commit>",
10            "date": "<date>",
11            "weekly: False,
12        },
13    ]
14"""
15
16import argparse
17import json
18import os
19import tempfile
20import urllib.request
21from datetime import datetime
22
23from git import Git
24
25VERSIONS_FILE = "versions.json"
26
27
28def parse_args():
29    parser = argparse.ArgumentParser(
30        description="Manage versions to be tested.", allow_abbrev=False
31    )
32    parser.add_argument('-l', '--list', action="store_true", help="List all published versions")
33    parser.add_argument('-u', '--update', help="Update versions file from tree.")
34    parser.add_argument('-L', '--latest', action="store_true", help="Get latest published version")
35    parser.add_argument('-w', '--weekly', action="store_true", help="Mark as weekly")
36    parser.add_argument('-W', '--list-weekly', action="store_true", help="List weekly commits")
37    parser.add_argument('-v', '--verbose', action="store_true", help="Verbose output")
38    return parser.parse_args()
39
40
41def get_versions():
42    data = None
43    with tempfile.NamedTemporaryFile() as fo:
44        if not os.path.exists('versions.json'):
45            url = 'https://testing.zephyrproject.org/daily_tests/versions.json'
46            urllib.request.urlretrieve(url, fo.name)
47        with open(fo.name) as fp:
48            data = json.load(fp)
49    return data
50
51
52def handle_compat(item):
53    item_compat = {}
54    if isinstance(item, str):
55        item_compat['version'] = item
56        item_compat['weekly'] = False
57        item_compat['date'] = None
58    else:
59        item_compat = item
60
61    return item_compat
62
63
64def show_versions(weekly=False):
65    data = get_versions()
66    for item in data:
67        item_compat = handle_compat(item)
68        is_weekly = item_compat.get('weekly', False)
69        if weekly and not is_weekly:
70            continue
71        wstr = ""
72        datestr = ""
73        if args.verbose:
74            if is_weekly:
75                wstr = "(marked for weekly testing)"
76            if item_compat.get('date'):
77                pdate = datetime.strptime(item_compat['date'], '%Y-%m-%dT%H:%M:%S.%f')
78                date = pdate.strftime("%b %d %Y %H:%M:%S")
79                datestr = f"published on {date}"
80            print(f"- {item_compat['version']} {datestr} {wstr}")
81        else:
82            print(f"{item_compat['version']}")
83
84
85def show_latest():
86    data = get_versions()
87    latest = data[-1]
88    item_compat = handle_compat(latest)
89
90    ver = item_compat.get("version")
91    date = item_compat.get("date", False)
92    is_weekly = item_compat.get('weekly')
93    datestr = ""
94    if date:
95        datestr = f"published on {date}"
96    if args.verbose:
97        print(f"Latest version is {ver} {datestr}")
98    if args.verbose and is_weekly:
99        print("This version is marked for weekly testing.")
100
101    if not args.verbose:
102        print(f"{ver}")
103
104
105def update(git_tree, is_weekly=False):
106    g = Git(git_tree)
107    today = datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')
108    version = g.describe("--abbrev=12")
109    published = False
110    data = get_versions()
111
112    if not is_weekly:
113        wday = datetime.today().strftime('%A')
114        if wday == 'Monday':
115            is_weekly = True
116
117    found = list(
118        filter(
119            lambda item: (isinstance(item, dict) and item.get('version') == version)
120            or item == version,
121            data,
122        )
123    )
124    if found:
125        published = True
126        print("version already published")
127    else:
128        print(f"New version {version}, adding to file...")
129
130    if data and not published:
131        with open(VERSIONS_FILE, "w") as versions:
132            item = {}
133            item['version'] = version
134            item['date'] = today
135            item['weekly'] = is_weekly
136            data.append(item)
137            json.dump(data, versions)
138
139
140def main():
141    global args
142
143    args = parse_args()
144    if args.update:
145        update(args.update, args.weekly)
146    elif args.list or args.list_weekly:
147        show_versions(weekly=args.list_weekly)
148    elif args.latest:
149        show_latest()
150    else:
151        print("You did not specify any options")
152
153
154if __name__ == "__main__":
155    main()
156