1#!/usr/bin/env python3
2
3# Copyright (c) 2009 Giampaolo Rodola'. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""
8Prints release announce based on HISTORY.rst file content.
9See: https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode
10"""
11
12import os
13import re
14import subprocess
15import sys
16
17from psutil import __version__ as PRJ_VERSION
18
19
20HERE = os.path.abspath(os.path.dirname(__file__))
21ROOT = os.path.realpath(os.path.join(HERE, '..', '..'))
22HISTORY = os.path.join(ROOT, 'HISTORY.rst')
23PRINT_HASHES_SCRIPT = os.path.join(
24    ROOT, 'scripts', 'internal', 'print_hashes.py')
25
26PRJ_NAME = 'psutil'
27PRJ_URL_HOME = 'https://github.com/giampaolo/psutil'
28PRJ_URL_DOC = 'http://psutil.readthedocs.io'
29PRJ_URL_DOWNLOAD = 'https://pypi.org/project/psutil/#files'
30PRJ_URL_WHATSNEW = \
31    'https://github.com/giampaolo/psutil/blob/master/HISTORY.rst'
32
33template = """\
34Hello all,
35I'm glad to announce the release of {prj_name} {prj_version}:
36{prj_urlhome}
37
38About
39=====
40
41psutil (process and system utilities) is a cross-platform library for \
42retrieving information on running processes and system utilization (CPU, \
43memory, disks, network) in Python. It is useful mainly for system \
44monitoring, profiling and limiting process resources and management of \
45running processes. It implements many functionalities offered by command \
46line tools such as: ps, top, lsof, netstat, ifconfig, who, df, kill, free, \
47nice, ionice, iostat, iotop, uptime, pidof, tty, taskset, pmap. It \
48currently supports Linux, Windows, macOS, Sun Solaris, FreeBSD, OpenBSD, \
49NetBSD and AIX, both 32-bit and 64-bit architectures.  Supported Python \
50versions are 2.6, 2.7 and 3.4+. PyPy is also known to work.
51
52What's new
53==========
54
55{changes}
56
57Links
58=====
59
60- Home page: {prj_urlhome}
61- Download: {prj_urldownload}
62- Documentation: {prj_urldoc}
63- What's new: {prj_urlwhatsnew}
64
65Hashes
66======
67
68{hashes}
69
70--
71
72Giampaolo - https://gmpy.dev/about
73"""
74
75
76def get_changes():
77    """Get the most recent changes for this release by parsing
78    HISTORY.rst file.
79    """
80    with open(HISTORY) as f:
81        lines = f.readlines()
82
83    block = []
84
85    # eliminate the part preceding the first block
86    for i, line in enumerate(lines):
87        line = lines.pop(0)
88        if line.startswith('===='):
89            break
90    lines.pop(0)
91
92    for i, line in enumerate(lines):
93        line = lines.pop(0)
94        line = line.rstrip()
95        if re.match(r"^- \d+_: ", line):
96            num, _, rest = line.partition(': ')
97            num = ''.join([x for x in num if x.isdigit()])
98            line = "- #%s: %s" % (num, rest)
99
100        if line.startswith('===='):
101            break
102        block.append(line)
103
104    # eliminate bottom empty lines
105    block.pop(-1)
106    while not block[-1]:
107        block.pop(-1)
108
109    return "\n".join(block)
110
111
112def main():
113    changes = get_changes()
114    hashes = subprocess.check_output(
115        [sys.executable, PRINT_HASHES_SCRIPT, 'dist/']).strip().decode()
116    print(template.format(
117        prj_name=PRJ_NAME,
118        prj_version=PRJ_VERSION,
119        prj_urlhome=PRJ_URL_HOME,
120        prj_urldownload=PRJ_URL_DOWNLOAD,
121        prj_urldoc=PRJ_URL_DOC,
122        prj_urlwhatsnew=PRJ_URL_WHATSNEW,
123        changes=changes,
124        hashes=hashes,
125    ))
126
127
128if __name__ == '__main__':
129    main()
130