- commit
- 12222b9d2dab2e0c430350d779a8c5c0ffc6e6d2
- parent
- 0d31a6e062ed54029e9976a52a7d3af4028d0eb5
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2025-08-24 06:52
lint
Diffstat
| M | project_stats.py | 57 | +++++++++++++++++++++++++++++++-------------------------- |
1 files changed, 31 insertions, 26 deletions
diff --git a/project_stats.py b/project_stats.py
@@ -1,4 +1,3 @@1 -1 from functools import total_ordering2 1 import argparse 3 2 import asyncio 4 3 import logging @@ -6,10 +5,11 @@ import os 6 5 import re 7 6 import subprocess 8 7 import sys -1 8 from functools import total_ordering 9 910 -1 from dateutil import parser as dt11 10 import aiohttp 12 11 import yaml -1 12 from dateutil import parser as dt 13 13 14 14 try: 15 15 from cheesecake.cheesecake_index import Cheesecake @@ -71,13 +71,13 @@ def r_get(d, *keys): 71 71 72 72 73 73 @total_ordering74 -1 class Claims(object):-1 74 class Claims: 75 75 def __init__(self): 76 76 self._list = [] 77 77 78 78 def _index(self, key): 79 79 i = 080 -1 for k, value in self._list:-1 80 for k, _ in self._list: 81 81 if key == k: 82 82 return i 83 83 i += 1 @@ -96,11 +96,12 @@ class Claims(object): 96 96 def values(self): 97 97 return [value for value, sources in self._list] 98 9899 -1 def format(self, show_sources=True):-1 99 def format(self, *, show_sources=True): 100 100 def _format_claim(value, sources): 101 101 s = str(value) 102 102 if show_sources:103 -1 s += ' (%s)' % ', '.join(sources)-1 103 joined = ', '.join(sources) -1 104 s += f' ({joined})' 104 105 return s 105 106 return '; '.join([_format_claim(v, srcs) for v, srcs in self._list]) 106 107 @@ -108,7 +109,7 @@ class Claims(object): 108 109 return self.values() < other.values() 109 110 110 111111 -1 class ClaimsDict(object):-1 112 class ClaimsDict: 112 113 def __init__(self, keys, short=9): 113 114 self._keys = keys 114 115 self._short = short @@ -137,7 +138,7 @@ class ClaimsDict(object): 137 138 except KeyError: 138 139 return default 139 140140 -1 def format(self, short=False, indent=0, show_sources=True):-1 141 def format(self, *, short=False, indent=0, show_sources=True): 141 142 keys = self._keys[:self._short] if short else self._keys 142 143 lines = [] 143 144 for key in keys: @@ -145,7 +146,7 @@ class ClaimsDict(object): 145 146 formated_value = value.format(show_sources=show_sources) 146 147 if not formated_value: 147 148 continue148 -1 lines.append(' ' * indent + '%s: %s' % (key, formated_value))-1 149 lines.append(' ' * indent + f'{key}: {formated_value}') 149 150 return '\n'.join(lines) 150 151 151 152 @@ -167,7 +168,7 @@ async def get_json(url, user=None, token=None): 167 168 if user is not None: 168 169 # FIXME: not very robust 169 170 url += '&' if '?' in url else '?'170 -1 url += 'login=%s&token=%s' % (user, token)-1 171 url += f'login={user}&token={token}' 171 172 172 173 async with aiohttp.ClientSession() as session: 173 174 async with session.get(url) as resp: @@ -231,7 +232,8 @@ async def get_gitlab(_id, token=None): 231 232 data, issues, pulls = await asyncio.gather( 232 233 _get_json(''), 233 234 _get_json('/issues?state=opened'),234 -1 _get_json('/merge_requests?state=opened'))-1 235 _get_json('/merge_requests?state=opened'), -1 236 ) 235 237 236 238 return { 237 239 'name': data['name'], @@ -248,7 +250,7 @@ async def get_gitlab(_id, token=None): 248 250 249 251 async def get_local(path): 250 252 def git(cmd, *args):251 -1 _cmd = ['git', '-C', path, cmd] + list(args)-1 253 _cmd = ['git', '-C', path, cmd, *args] 252 254 return subprocess.check_output(_cmd).decode('utf8') 253 255 254 256 def get_latest_tag(): @@ -276,7 +278,7 @@ async def get_local(path): 276 278 277 279 278 280 async def get_pypi(name):279 -1 data = await get_json('https://pypi.org/pypi/{}/json'.format(name))-1 281 data = await get_json(f'https://pypi.org/pypi/{name}/json') 280 282 return { 281 283 'version': data['info']['version'], 282 284 'description': data['info']['summary'], @@ -299,7 +301,8 @@ async def get_npm(name): 299 301 'time.created', 300 302 'time.modified', 301 303 stdout=asyncio.subprocess.PIPE,302 -1 stderr=asyncio.subprocess.PIPE)-1 304 stderr=asyncio.subprocess.PIPE, -1 305 ) 303 306 stdout, stderr = await process.communicate() 304 307 if process.returncode != 0: 305 308 return @@ -382,7 +385,8 @@ async def get_project(key, project, config): 382 385 def get_projects(projects_config, config): 383 386 projects_list = aiorun(asyncio.gather(*[ 384 387 get_project(key, project, config)385 -1 for key, project in projects_config.items()]))-1 388 for key, project in projects_config.items() -1 389 ])) 386 390 387 391 projects = {} 388 392 for key, project in zip(projects_config.keys(), projects_list): @@ -406,7 +410,7 @@ def select_config(args): 406 410 if os.path.exists(path): 407 411 return path 408 412409 -1 print('No config file available. Tried %s.' % ', '.join(choices))-1 413 print(f'No config file available. Tried {", ".join(choices)}.') 410 414 sys.exit(1) 411 415 412 416 @@ -422,20 +426,20 @@ def parse_args(): 422 426 parser.add_argument( 423 427 '-l', '--list', 424 428 action='store_true',425 -1 help='only list projects; do not show any stats')-1 429 help='only list projects; do not show any stats', -1 430 ) 426 431 parser.add_argument( 427 432 '-s', '--short', 428 433 action='store_true',429 -1 help='show only basic stats')-1 434 help='show only basic stats', -1 435 ) 430 436 parser.add_argument('-c', '--config')431 -1 parser.add_argument(432 -1 '-z', '--sort',433 -1 metavar='KEY',434 -1 help='sort by key')-1 437 parser.add_argument('-z', '--sort', metavar='KEY', help='sort by key') 435 438 parser.add_argument( 436 439 '-S', '--show-sources', 437 440 action='store_true',438 -1 help='show a source for each claim')-1 441 help='show a source for each claim', -1 442 ) 439 443 440 444 return parser.parse_args() 441 445 @@ -464,11 +468,12 @@ def main(): 464 468 claim = projects[key][args.sort] 465 469 print(key, claim.format(show_sources=False)) 466 470 else:467 -1 claims = projects[key]468 -1 print('%s\n%s\n' % (key, claims.format(-1 471 print(key) -1 472 print(projects[key].format( 469 473 indent=2, 470 474 short=args.short,471 -1 show_sources=args.show_sources)))-1 475 show_sources=args.show_sources, -1 476 )) 472 477 473 478 474 479 if __name__ == '__main__':