Mercurial > hg
view contrib/phab-clean.py @ 48390:322525db4c98
status: use filesystem time boundary to invalidate racy mtime
We record the filesystem time at the start of the status walk and use that as a
boundary to detect files that might be modified during (or right after) the
status run without the mtime allowing that edition to be detected. We
currently do this at a second precision. In a later patch, we will use
nanosecond precision when available.
To cope with "broken" time on the file system where file could be in the
future, we also keep mtime for file over one day in the future. See inline
comment for details.
Large file tests get a bit more confused as we reduce the odds for race
condition.
As a "side effect", the win32text extension is happy again.
Differential Revision: https://phab.mercurial-scm.org/D11794
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 18 Nov 2021 13:12:40 +0100 |
parents | c102b704edb5 |
children | 6000f5b25c9b |
line wrap: on
line source
#!/usr/bin/env python3 # # A small script to automatically reject idle Diffs # # you need to set the PHABBOT_USER and PHABBOT_TOKEN environment variable for authentication from __future__ import absolute_import, print_function import datetime import os import sys import phabricator MESSAGE = """There seems to have been no activities on this Diff for the past 3 Months. By policy, we are automatically moving it out of the `need-review` state. Please, move it back to `need-review` without hesitation if this diff should still be discussed. :baymax:need-review-idle: """ PHAB_URL = "https://phab.mercurial-scm.org/api/" USER = os.environ.get("PHABBOT_USER", "baymax") TOKEN = os.environ.get("PHABBOT_TOKEN") NOW = datetime.datetime.now() # 3 months in seconds DELAY = 60 * 60 * 24 * 30 * 3 def get_all_diff(phab): """Fetch all the diff that the need review""" return phab.differential.query( status="status-needs-review", order="order-modified", paths=[('HG', None)], ) def filter_diffs(diffs, older_than): """filter diffs to only keep the one unmodified sin <older_than> seconds""" olds = [] for d in diffs: modified = int(d['dateModified']) modified = datetime.datetime.fromtimestamp(modified) d["idleFor"] = idle_for = NOW - modified if idle_for.total_seconds() > older_than: olds.append(d) return olds def nudge_diff(phab, diff): """Comment on the idle diff and reject it""" diff_id = int(d['id']) phab.differential.createcomment( revision_id=diff_id, message=MESSAGE, action="reject" ) if not USER: print( "not user specified please set PHABBOT_USER and PHABBOT_TOKEN", file=sys.stderr, ) elif not TOKEN: print( "not api-token specified please set PHABBOT_USER and PHABBOT_TOKEN", file=sys.stderr, ) sys.exit(1) phab = phabricator.Phabricator(USER, host=PHAB_URL, token=TOKEN) phab.connect() phab.update_interfaces() print('Hello "%s".' % phab.user.whoami()['realName']) diffs = get_all_diff(phab) print("Found %d Diffs" % len(diffs)) olds = filter_diffs(diffs, DELAY) print("Found %d old Diffs" % len(olds)) for d in olds: diff_id = d['id'] status = d['statusName'] modified = int(d['dateModified']) idle_for = d["idleFor"] msg = 'nudging D%s in "%s" state for %s' print(msg % (diff_id, status, idle_for)) # uncomment to actually affect phab nudge_diff(phab, d)