contrib/automation/hgautomation/cli.py
changeset 42024 b05a3e28cf24
child 42277 dd6a9723ae2b
equal deleted inserted replaced
42023:bf87d34a675c 42024:b05a3e28cf24
       
     1 # cli.py - Command line interface for automation
       
     2 #
       
     3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 
       
     8 # no-check-code because Python 3 native.
       
     9 
       
    10 import argparse
       
    11 import os
       
    12 import pathlib
       
    13 
       
    14 from . import (
       
    15     aws,
       
    16     HGAutomation,
       
    17     windows,
       
    18 )
       
    19 
       
    20 
       
    21 SOURCE_ROOT = pathlib.Path(os.path.abspath(__file__)).parent.parent.parent.parent
       
    22 DIST_PATH = SOURCE_ROOT / 'dist'
       
    23 
       
    24 
       
    25 def bootstrap_windows_dev(hga: HGAutomation, aws_region):
       
    26     c = hga.aws_connection(aws_region)
       
    27     image = aws.ensure_windows_dev_ami(c)
       
    28     print('Windows development AMI available as %s' % image.id)
       
    29 
       
    30 
       
    31 def build_inno(hga: HGAutomation, aws_region, arch, revision, version):
       
    32     c = hga.aws_connection(aws_region)
       
    33     image = aws.ensure_windows_dev_ami(c)
       
    34     DIST_PATH.mkdir(exist_ok=True)
       
    35 
       
    36     with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
       
    37         instance = insts[0]
       
    38 
       
    39         windows.synchronize_hg(SOURCE_ROOT, revision, instance)
       
    40 
       
    41         for a in arch:
       
    42             windows.build_inno_installer(instance.winrm_client, a,
       
    43                                          DIST_PATH,
       
    44                                          version=version)
       
    45 
       
    46 
       
    47 def build_wix(hga: HGAutomation, aws_region, arch, revision, version):
       
    48     c = hga.aws_connection(aws_region)
       
    49     image = aws.ensure_windows_dev_ami(c)
       
    50     DIST_PATH.mkdir(exist_ok=True)
       
    51 
       
    52     with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
       
    53         instance = insts[0]
       
    54 
       
    55         windows.synchronize_hg(SOURCE_ROOT, revision, instance)
       
    56 
       
    57         for a in arch:
       
    58             windows.build_wix_installer(instance.winrm_client, a,
       
    59                                         DIST_PATH, version=version)
       
    60 
       
    61 
       
    62 def build_windows_wheel(hga: HGAutomation, aws_region, arch, revision):
       
    63     c = hga.aws_connection(aws_region)
       
    64     image = aws.ensure_windows_dev_ami(c)
       
    65     DIST_PATH.mkdir(exist_ok=True)
       
    66 
       
    67     with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
       
    68         instance = insts[0]
       
    69 
       
    70         windows.synchronize_hg(SOURCE_ROOT, revision, instance)
       
    71 
       
    72         for a in arch:
       
    73             windows.build_wheel(instance.winrm_client, a, DIST_PATH)
       
    74 
       
    75 
       
    76 def build_all_windows_packages(hga: HGAutomation, aws_region, revision):
       
    77     c = hga.aws_connection(aws_region)
       
    78     image = aws.ensure_windows_dev_ami(c)
       
    79     DIST_PATH.mkdir(exist_ok=True)
       
    80 
       
    81     with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts:
       
    82         instance = insts[0]
       
    83 
       
    84         winrm_client = instance.winrm_client
       
    85 
       
    86         windows.synchronize_hg(SOURCE_ROOT, revision, instance)
       
    87 
       
    88         for arch in ('x86', 'x64'):
       
    89             windows.purge_hg(winrm_client)
       
    90             windows.build_wheel(winrm_client, arch, DIST_PATH)
       
    91             windows.purge_hg(winrm_client)
       
    92             windows.build_inno_installer(winrm_client, arch, DIST_PATH)
       
    93             windows.purge_hg(winrm_client)
       
    94             windows.build_wix_installer(winrm_client, arch, DIST_PATH)
       
    95 
       
    96 
       
    97 def terminate_ec2_instances(hga: HGAutomation, aws_region):
       
    98     c = hga.aws_connection(aws_region)
       
    99     aws.terminate_ec2_instances(c.ec2resource)
       
   100 
       
   101 
       
   102 def purge_ec2_resources(hga: HGAutomation, aws_region):
       
   103     c = hga.aws_connection(aws_region)
       
   104     aws.remove_resources(c)
       
   105 
       
   106 
       
   107 def run_tests_windows(hga: HGAutomation, aws_region, instance_type,
       
   108                       python_version, arch, test_flags):
       
   109     c = hga.aws_connection(aws_region)
       
   110     image = aws.ensure_windows_dev_ami(c)
       
   111 
       
   112     with aws.temporary_windows_dev_instances(c, image, instance_type,
       
   113                                              disable_antivirus=True) as insts:
       
   114         instance = insts[0]
       
   115 
       
   116         windows.synchronize_hg(SOURCE_ROOT, '.', instance)
       
   117         windows.run_tests(instance.winrm_client, python_version, arch,
       
   118                           test_flags)
       
   119 
       
   120 
       
   121 def get_parser():
       
   122     parser = argparse.ArgumentParser()
       
   123 
       
   124     parser.add_argument(
       
   125         '--state-path',
       
   126         default='~/.hgautomation',
       
   127         help='Path for local state files',
       
   128     )
       
   129     parser.add_argument(
       
   130         '--aws-region',
       
   131         help='AWS region to use',
       
   132         default='us-west-1',
       
   133     )
       
   134 
       
   135     subparsers = parser.add_subparsers()
       
   136 
       
   137     sp = subparsers.add_parser(
       
   138         'bootstrap-windows-dev',
       
   139         help='Bootstrap the Windows development environment',
       
   140     )
       
   141     sp.set_defaults(func=bootstrap_windows_dev)
       
   142 
       
   143     sp = subparsers.add_parser(
       
   144         'build-all-windows-packages',
       
   145         help='Build all Windows packages',
       
   146     )
       
   147     sp.add_argument(
       
   148         '--revision',
       
   149         help='Mercurial revision to build',
       
   150         default='.',
       
   151     )
       
   152     sp.set_defaults(func=build_all_windows_packages)
       
   153 
       
   154     sp = subparsers.add_parser(
       
   155         'build-inno',
       
   156         help='Build Inno Setup installer(s)',
       
   157     )
       
   158     sp.add_argument(
       
   159         '--arch',
       
   160         help='Architecture to build for',
       
   161         choices={'x86', 'x64'},
       
   162         nargs='*',
       
   163         default=['x64'],
       
   164     )
       
   165     sp.add_argument(
       
   166         '--revision',
       
   167         help='Mercurial revision to build',
       
   168         default='.',
       
   169     )
       
   170     sp.add_argument(
       
   171         '--version',
       
   172         help='Mercurial version string to use in installer',
       
   173     )
       
   174     sp.set_defaults(func=build_inno)
       
   175 
       
   176     sp = subparsers.add_parser(
       
   177         'build-windows-wheel',
       
   178         help='Build Windows wheel(s)',
       
   179     )
       
   180     sp.add_argument(
       
   181         '--arch',
       
   182         help='Architecture to build for',
       
   183         choices={'x86', 'x64'},
       
   184         nargs='*',
       
   185         default=['x64'],
       
   186     )
       
   187     sp.add_argument(
       
   188         '--revision',
       
   189         help='Mercurial revision to build',
       
   190         default='.',
       
   191     )
       
   192     sp.set_defaults(func=build_windows_wheel)
       
   193 
       
   194     sp = subparsers.add_parser(
       
   195         'build-wix',
       
   196         help='Build WiX installer(s)'
       
   197     )
       
   198     sp.add_argument(
       
   199         '--arch',
       
   200         help='Architecture to build for',
       
   201         choices={'x86', 'x64'},
       
   202         nargs='*',
       
   203         default=['x64'],
       
   204     )
       
   205     sp.add_argument(
       
   206         '--revision',
       
   207         help='Mercurial revision to build',
       
   208         default='.',
       
   209     )
       
   210     sp.add_argument(
       
   211         '--version',
       
   212         help='Mercurial version string to use in installer',
       
   213     )
       
   214     sp.set_defaults(func=build_wix)
       
   215 
       
   216     sp = subparsers.add_parser(
       
   217         'terminate-ec2-instances',
       
   218         help='Terminate all active EC2 instances managed by us',
       
   219     )
       
   220     sp.set_defaults(func=terminate_ec2_instances)
       
   221 
       
   222     sp = subparsers.add_parser(
       
   223         'purge-ec2-resources',
       
   224         help='Purge all EC2 resources managed by us',
       
   225     )
       
   226     sp.set_defaults(func=purge_ec2_resources)
       
   227 
       
   228     sp = subparsers.add_parser(
       
   229         'run-tests-windows',
       
   230         help='Run tests on Windows',
       
   231     )
       
   232     sp.add_argument(
       
   233         '--instance-type',
       
   234         help='EC2 instance type to use',
       
   235         default='t3.medium',
       
   236     )
       
   237     sp.add_argument(
       
   238         '--python-version',
       
   239         help='Python version to use',
       
   240         choices={'2.7', '3.5', '3.6', '3.7', '3.8'},
       
   241         default='2.7',
       
   242     )
       
   243     sp.add_argument(
       
   244         '--arch',
       
   245         help='Architecture to test',
       
   246         choices={'x86', 'x64'},
       
   247         default='x64',
       
   248     )
       
   249     sp.add_argument(
       
   250         '--test-flags',
       
   251         help='Extra command line flags to pass to run-tests.py',
       
   252     )
       
   253     sp.set_defaults(func=run_tests_windows)
       
   254 
       
   255     return parser
       
   256 
       
   257 
       
   258 def main():
       
   259     parser = get_parser()
       
   260     args = parser.parse_args()
       
   261 
       
   262     local_state_path = pathlib.Path(os.path.expanduser(args.state_path))
       
   263     automation = HGAutomation(local_state_path)
       
   264 
       
   265     if not hasattr(args, 'func'):
       
   266         parser.print_help()
       
   267         return
       
   268 
       
   269     kwargs = dict(vars(args))
       
   270     del kwargs['func']
       
   271     del kwargs['state_path']
       
   272 
       
   273     args.func(automation, **kwargs)