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