view contrib/automation/automation.py @ 45121:b6269741ed42

config: add option to control creation of empty successors during rewrite The default for many history-rewriting commands (e.g. rebase and absorb) is that changesets which would become empty are not created in the target branch. This makes sense if the source branch consists of small fix-up changes. For more advanced workflows that make heavy use of history-editing to create curated patch series, dropping empty changesets is not as important or even undesirable. Some users want to keep the meta-history, e.g. to make finding comments in a code review tool easier or to avoid that divergent bookmarks are created. For that, obsmarkers from the (to-be) empty changeset to the changeset(s) that already made the changes should be added. If a to-be empty changeset is pruned without a successor, adding the obsmarkers is hard because the changeset has to be found within the hidden part of the history. If rebasing in TortoiseHg, it’s easy to miss the fact that the to-be empty changeset was pruned. An empty changeset will function as a reminder that obsmarkers should be added. Martin von Zweigbergk mentioned another advantage. Stripping the successor will de-obsolete the predecessor. If no (empty) successor is created, this won’t be possible. In the future, we may want to consider other behaviors, like e.g. creating the empty successor, but pruning it right away. Therefore this configuration accepts 'skip' and 'keep' instead of being a boolean configuration.
author Manuel Jacob <me@manueljacob.de>
date Sat, 11 Jul 2020 23:53:27 +0200
parents 2372284d9457
children
line wrap: on
line source

#!/usr/bin/env python3
#
# automation.py - Perform tasks on remote machines
#
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

import os
import pathlib
import subprocess
import sys
import venv


HERE = pathlib.Path(os.path.abspath(__file__)).parent
REQUIREMENTS_TXT = HERE / 'requirements.txt'
SOURCE_DIR = HERE.parent.parent
VENV = SOURCE_DIR / 'build' / 'venv-automation'


def bootstrap():
    venv_created = not VENV.exists()

    VENV.parent.mkdir(exist_ok=True)

    venv.create(VENV, with_pip=True)

    if os.name == 'nt':
        venv_bin = VENV / 'Scripts'
        pip = venv_bin / 'pip.exe'
        python = venv_bin / 'python.exe'
    else:
        venv_bin = VENV / 'bin'
        pip = venv_bin / 'pip'
        python = venv_bin / 'python'

    args = [
        str(pip),
        'install',
        '-r',
        str(REQUIREMENTS_TXT),
        '--disable-pip-version-check',
    ]

    if not venv_created:
        args.append('-q')

    subprocess.run(args, check=True)

    os.environ['HGAUTOMATION_BOOTSTRAPPED'] = '1'
    os.environ['PATH'] = '%s%s%s' % (venv_bin, os.pathsep, os.environ['PATH'])

    subprocess.run([str(python), __file__] + sys.argv[1:], check=True)


def run():
    import hgautomation.cli as cli

    # Need to strip off main Python executable.
    cli.main()


if __name__ == '__main__':
    try:
        if 'HGAUTOMATION_BOOTSTRAPPED' not in os.environ:
            bootstrap()
        else:
            run()
    except subprocess.CalledProcessError as e:
        sys.exit(e.returncode)
    except KeyboardInterrupt:
        sys.exit(1)