contrib/automation/hgautomation/cli.py
changeset 42024 b05a3e28cf24
child 42304 dd6a9723ae2b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contrib/automation/hgautomation/cli.py	Fri Mar 15 11:24:08 2019 -0700
@@ -0,0 +1,273 @@
+# cli.py - Command line interface for automation
+#
+# 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.
+
+# no-check-code because Python 3 native.
+
+import argparse
+import os
+import pathlib
+
+from . import (
+    aws,
+    HGAutomation,
+    windows,
+)
+
+
+SOURCE_ROOT = pathlib.Path(os.path.abspath(__file__)).parent.parent.parent.parent
+DIST_PATH = SOURCE_ROOT / 'dist'
+
+
+def bootstrap_windows_dev(hga: HGAutomation, aws_region):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+    print('Windows development AMI available as %s' % image.id)
+
+
+def build_inno(hga: HGAutomation, aws_region, arch, revision, version):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+    DIST_PATH.mkdir(exist_ok=True)
+
+    with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
+        instance = insts[0]
+
+        windows.synchronize_hg(SOURCE_ROOT, revision, instance)
+
+        for a in arch:
+            windows.build_inno_installer(instance.winrm_client, a,
+                                         DIST_PATH,
+                                         version=version)
+
+
+def build_wix(hga: HGAutomation, aws_region, arch, revision, version):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+    DIST_PATH.mkdir(exist_ok=True)
+
+    with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
+        instance = insts[0]
+
+        windows.synchronize_hg(SOURCE_ROOT, revision, instance)
+
+        for a in arch:
+            windows.build_wix_installer(instance.winrm_client, a,
+                                        DIST_PATH, version=version)
+
+
+def build_windows_wheel(hga: HGAutomation, aws_region, arch, revision):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+    DIST_PATH.mkdir(exist_ok=True)
+
+    with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
+        instance = insts[0]
+
+        windows.synchronize_hg(SOURCE_ROOT, revision, instance)
+
+        for a in arch:
+            windows.build_wheel(instance.winrm_client, a, DIST_PATH)
+
+
+def build_all_windows_packages(hga: HGAutomation, aws_region, revision):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+    DIST_PATH.mkdir(exist_ok=True)
+
+    with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
+        instance = insts[0]
+
+        winrm_client = instance.winrm_client
+
+        windows.synchronize_hg(SOURCE_ROOT, revision, instance)
+
+        for arch in ('x86', 'x64'):
+            windows.purge_hg(winrm_client)
+            windows.build_wheel(winrm_client, arch, DIST_PATH)
+            windows.purge_hg(winrm_client)
+            windows.build_inno_installer(winrm_client, arch, DIST_PATH)
+            windows.purge_hg(winrm_client)
+            windows.build_wix_installer(winrm_client, arch, DIST_PATH)
+
+
+def terminate_ec2_instances(hga: HGAutomation, aws_region):
+    c = hga.aws_connection(aws_region)
+    aws.terminate_ec2_instances(c.ec2resource)
+
+
+def purge_ec2_resources(hga: HGAutomation, aws_region):
+    c = hga.aws_connection(aws_region)
+    aws.remove_resources(c)
+
+
+def run_tests_windows(hga: HGAutomation, aws_region, instance_type,
+                      python_version, arch, test_flags):
+    c = hga.aws_connection(aws_region)
+    image = aws.ensure_windows_dev_ami(c)
+
+    with aws.temporary_windows_dev_instances(c, image, instance_type,
+                                             disable_antivirus=True) as insts:
+        instance = insts[0]
+
+        windows.synchronize_hg(SOURCE_ROOT, '.', instance)
+        windows.run_tests(instance.winrm_client, python_version, arch,
+                          test_flags)
+
+
+def get_parser():
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument(
+        '--state-path',
+        default='~/.hgautomation',
+        help='Path for local state files',
+    )
+    parser.add_argument(
+        '--aws-region',
+        help='AWS region to use',
+        default='us-west-1',
+    )
+
+    subparsers = parser.add_subparsers()
+
+    sp = subparsers.add_parser(
+        'bootstrap-windows-dev',
+        help='Bootstrap the Windows development environment',
+    )
+    sp.set_defaults(func=bootstrap_windows_dev)
+
+    sp = subparsers.add_parser(
+        'build-all-windows-packages',
+        help='Build all Windows packages',
+    )
+    sp.add_argument(
+        '--revision',
+        help='Mercurial revision to build',
+        default='.',
+    )
+    sp.set_defaults(func=build_all_windows_packages)
+
+    sp = subparsers.add_parser(
+        'build-inno',
+        help='Build Inno Setup installer(s)',
+    )
+    sp.add_argument(
+        '--arch',
+        help='Architecture to build for',
+        choices={'x86', 'x64'},
+        nargs='*',
+        default=['x64'],
+    )
+    sp.add_argument(
+        '--revision',
+        help='Mercurial revision to build',
+        default='.',
+    )
+    sp.add_argument(
+        '--version',
+        help='Mercurial version string to use in installer',
+    )
+    sp.set_defaults(func=build_inno)
+
+    sp = subparsers.add_parser(
+        'build-windows-wheel',
+        help='Build Windows wheel(s)',
+    )
+    sp.add_argument(
+        '--arch',
+        help='Architecture to build for',
+        choices={'x86', 'x64'},
+        nargs='*',
+        default=['x64'],
+    )
+    sp.add_argument(
+        '--revision',
+        help='Mercurial revision to build',
+        default='.',
+    )
+    sp.set_defaults(func=build_windows_wheel)
+
+    sp = subparsers.add_parser(
+        'build-wix',
+        help='Build WiX installer(s)'
+    )
+    sp.add_argument(
+        '--arch',
+        help='Architecture to build for',
+        choices={'x86', 'x64'},
+        nargs='*',
+        default=['x64'],
+    )
+    sp.add_argument(
+        '--revision',
+        help='Mercurial revision to build',
+        default='.',
+    )
+    sp.add_argument(
+        '--version',
+        help='Mercurial version string to use in installer',
+    )
+    sp.set_defaults(func=build_wix)
+
+    sp = subparsers.add_parser(
+        'terminate-ec2-instances',
+        help='Terminate all active EC2 instances managed by us',
+    )
+    sp.set_defaults(func=terminate_ec2_instances)
+
+    sp = subparsers.add_parser(
+        'purge-ec2-resources',
+        help='Purge all EC2 resources managed by us',
+    )
+    sp.set_defaults(func=purge_ec2_resources)
+
+    sp = subparsers.add_parser(
+        'run-tests-windows',
+        help='Run tests on Windows',
+    )
+    sp.add_argument(
+        '--instance-type',
+        help='EC2 instance type to use',
+        default='t3.medium',
+    )
+    sp.add_argument(
+        '--python-version',
+        help='Python version to use',
+        choices={'2.7', '3.5', '3.6', '3.7', '3.8'},
+        default='2.7',
+    )
+    sp.add_argument(
+        '--arch',
+        help='Architecture to test',
+        choices={'x86', 'x64'},
+        default='x64',
+    )
+    sp.add_argument(
+        '--test-flags',
+        help='Extra command line flags to pass to run-tests.py',
+    )
+    sp.set_defaults(func=run_tests_windows)
+
+    return parser
+
+
+def main():
+    parser = get_parser()
+    args = parser.parse_args()
+
+    local_state_path = pathlib.Path(os.path.expanduser(args.state_path))
+    automation = HGAutomation(local_state_path)
+
+    if not hasattr(args, 'func'):
+        parser.print_help()
+        return
+
+    kwargs = dict(vars(args))
+    del kwargs['func']
+    del kwargs['state_path']
+
+    args.func(automation, **kwargs)