From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: bob.c.feng@intel.com) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by groups.io with SMTP; Mon, 10 Jun 2019 22:29:02 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 10 Jun 2019 22:29:02 -0700 X-ExtLoop1: 1 Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga008.fm.intel.com with ESMTP; 10 Jun 2019 22:29:02 -0700 Received: from fmsmsx102.amr.corp.intel.com (10.18.124.200) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 10 Jun 2019 22:29:02 -0700 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by FMSMSX102.amr.corp.intel.com (10.18.124.200) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 10 Jun 2019 22:29:01 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.10]) by shsmsx102.ccr.corp.intel.com ([169.254.2.134]) with mapi id 14.03.0415.000; Tue, 11 Jun 2019 13:28:59 +0800 From: "Bob Feng" To: Leif Lindholm , "devel@edk2.groups.io" CC: "Gao, Liming" , "Zhu, Yonghong" , Andrew Fish , Laszlo Ersek , "Kinney, Michael D" Subject: Re: [PATCH 2/2] BaseTools: add script to configure local git options Thread-Topic: [PATCH 2/2] BaseTools: add script to configure local git options Thread-Index: AQHVH4NAFghkcXADZk6BJSrKY/o59KaV7dfw Date: Tue, 11 Jun 2019 05:28:58 +0000 Message-ID: <08650203BA1BD64D8AD9B6D5D74A85D160135695@SHSMSX101.ccr.corp.intel.com> References: <20190610115410.13458-3-leif.lindholm@linaro.org> In-Reply-To: <20190610115410.13458-3-leif.lindholm@linaro.org> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: bob.c.feng@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable This patch looks good to me. Reviewed-by: Bob Feng =20 -----Original Message----- From: Leif Lindholm [mailto:leif.lindholm@linaro.org]=20 Sent: Monday, June 10, 2019 7:54 PM To: devel@edk2.groups.io Cc: Feng, Bob C ; Gao, Liming ;= Zhu, Yonghong ; Andrew Fish ; Las= zlo Ersek ; Kinney, Michael D Subject: [PATCH 2/2] BaseTools: add script to configure local git options Patch contribution and review is greatly simplified by following the steps = described in "Laszlo's unkempt guide": https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-= guide-for-edk2-contributors-and-maintainers but there are a lot of tedious manual steps in there, so here is a python s= cript that configures all options I am aware of *for the repository the scr= ipt is executed from*. Signed-off-by: Leif Lindholm Acked-by: Laszlo Ersek --- BaseTools/Scripts/SetupGit.py | 204 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 204 insertions(+) create mode 100644 BaseTools/Scripts/SetupGit.py diff --git a/BaseTools/Scripts/SetupGit.py b/BaseTools/Scripts/SetupGit.py = new file mode 100644 index 0000000000..3d39d3b35f --- /dev/null +++ b/BaseTools/Scripts/SetupGit.py @@ -0,0 +1,204 @@ +## @file +# Set up the git configuration for contributing to TianoCore projects=20 +# # Copyright (c) 2019, Linaro Ltd. All rights reserved.
# # =20 +SPDX-License-Identifier: BSD-2-Clause-Patent # + +from __future__ import print_function +import argparse +import os.path +import re +import sys + +try: + import git +except ImportError: + print('Unable to load gitpython module - please install and try again.= ') + sys.exit(1) + +try: + # Try Python 2 'ConfigParser' module first since helpful lib2to3 will + # otherwise automagically load it with the name 'configparser' + import ConfigParser +except ImportError: + # Otherwise, try loading the Python 3 'configparser' under an alias + try: + import configparser as ConfigParser + except ImportError: + print("Unable to load configparser/ConfigParser module - please in= stall and try again!") + sys.exit(1) + + +# Assumptions: Script is in edk2/BaseTools/Scripts, +# templates in edk2/BaseTools/Conf +CONFDIR =3D os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(= __file__))), + 'Conf') + +UPSTREAMS =3D [ + {'name': 'edk2', + 'repo': 'https://github.com/tianocore/edk2.git', + 'list': 'devel@edk2.groups.io'}, + {'name': 'edk2-platforms', + 'repo': 'https://github.com/tianocore/edk2-platforms.git', + 'list': 'devel@edk2.groups.io', 'prefix': 'edk2-platforms'}, + {'name': 'edk2-non-osi', + 'repo': 'https://github.com/tianocore/edk2-non-osi.git', + 'list': 'devel@edk2.groups.io', 'prefix': 'edk2-non-osi'} + ] + +# The minimum version required for all of the below options to work=20 +MIN_GIT_VERSION =3D (1, 9, 0) + +# Set of options to be set identically for all repositories OPTIONS =3D [ + {'section': 'am', 'option': 'keepcr', 'value': True}, + {'section': 'am', 'option': 'signoff', 'value': True}, + {'section': 'cherry-pick', 'option': 'signoff', 'value': True}, + {'section': 'color', 'option': 'diff', 'value': True}, + {'section': 'color', 'option': 'grep', 'value': 'auto'= }, + {'section': 'commit', 'option': 'signoff', 'value': True}, + {'section': 'core', 'option': 'abbrev', 'value': 12}, + {'section': 'core', 'option': 'attributesFile', + 'value': os.path.join(CONFDIR, 'gitattributes').replace('\\', '/')}, + {'section': 'core', 'option': 'whitespace', 'value': 'cr-at= -eol'}, + {'section': 'diff', 'option': 'algorithm', 'value': 'patie= nce'}, + {'section': 'diff', 'option': 'orderFile', + 'value': os.path.join(CONFDIR, 'diff.order').replace('\\', '/')}, + {'section': 'diff', 'option': 'renames', 'value': 'copie= s'}, + {'section': 'diff', 'option': 'statGraphWidth', 'value': '20'}, + {'section': 'diff "ini"', 'option': 'xfuncname', + 'value': '^\\\\[[A-Za-z0-9_., ]+]'}, + {'section': 'format', 'option': 'coverLetter', 'value': True}, + {'section': 'format', 'option': 'numbered', 'value': True}, + {'section': 'format', 'option': 'signoff', 'value': False}= , + {'section': 'notes', 'option': 'rewriteRef', 'value': 'refs/= notes/commits'}, + {'section': 'sendemail', 'option': 'chainreplyto', 'value': False}= , + {'section': 'sendemail', 'option': 'thread', 'value': True}, + ] + + +def locate_repo(): + """Opens a Repo object for the current tree, searching upwards in the = directory hierarchy.""" + try: + repo =3D git.Repo(path=3D'.', search_parent_directories=3DTrue) + except (git.InvalidGitRepositoryError, git.NoSuchPathError): + print("It doesn't look like we're inside a git repository - aborti= ng.") + sys.exit(2) + return repo + + +def fuzzy_match_repo_url(one, other): + """Compares two repository URLs, ignoring protocol and optional traili= ng '.git'.""" + oneresult =3D re.match(r'.*://(?P.*?)(\.git)*$', one) + otherresult =3D re.match(r'.*://(?P.*?)(\.git)*$',=20 +other) + + if oneresult and otherresult: + onestring =3D oneresult.group('oneresult') + otherstring =3D otherresult.group('otherresult') + if onestring =3D=3D otherstring: + return True + + return False + + +def get_upstream(url): + """Extracts the dict for the current repo origin.""" + for upstream in UPSTREAMS: + if fuzzy_match_repo_url(upstream['repo'], url): + return upstream + print("Unknown upstream '%s' - aborting!" % url) + sys.exit(3) + + +def check_versions(): + """Checks versions of dependencies.""" + version =3D git.cmd.Git().version_info + + if version < MIN_GIT_VERSION: + print('Need git version %d.%d or later!' % (version[0], version[1]= )) + sys.exit(4) + + +def write_config_value(repo, section, option, data): + """.""" + with repo.config_writer(config_level=3D'repository') as configwriter: + configwriter.set_value(section, option, data) + + +if __name__ =3D=3D '__main__': + check_versions() + + PARSER =3D argparse.ArgumentParser( + description=3D'Sets up a git repository according to TianoCore rul= es.') + PARSER.add_argument('-c', '--check', + help=3D'check current config only, printing what w= ould be changed', + action=3D'store_true', + required=3DFalse) + PARSER.add_argument('-f', '--force', + help=3D'overwrite existing settings conflicting wi= th program defaults', + action=3D'store_true', + required=3DFalse) + PARSER.add_argument('-v', '--verbose', + help=3D'enable more detailed output', + action=3D'store_true', + required=3DFalse) + ARGS =3D PARSER.parse_args() + + REPO =3D locate_repo() + if REPO.bare: + print('Bare repo - please check out an upstream one!') + sys.exit(6) + + URL =3D REPO.remotes.origin.url + + UPSTREAM =3D get_upstream(URL) + if not UPSTREAM: + print("Upstream '%s' unknown, aborting!" % URL) + sys.exit(7) + + # Set a list email address if our upstream wants it + if 'list' in UPSTREAM: + OPTIONS.append({'section': 'sendemail', 'option': 'to', + 'value': UPSTREAM['list']}) + # Append a subject prefix entry to OPTIONS if our upstream wants it + if 'prefix' in UPSTREAM: + OPTIONS.append({'section': 'format', 'option': 'subjectPrefix', + 'value': "PATCH " + UPSTREAM['prefix']}) + + CONFIG =3D REPO.config_reader(config_level=3D'repository') + + for entry in OPTIONS: + exists =3D False + try: + # Make sure to read boolean/int settings as real type rather t= han strings + if isinstance(entry['value'], bool): + value =3D CONFIG.getboolean(entry['section'], entry['optio= n']) + elif isinstance(entry['value'], int): + value =3D CONFIG.getint(entry['section'], entry['option']) + else: + value =3D CONFIG.get(entry['section'], entry['option']) + + exists =3D True + # Don't bail out from options not already being set + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + pass + + if exists: + if value =3D=3D entry['value']: + if ARGS.verbose: + print("%s.%s already set (to '%s')" % (entry['section'= ], + entry['option']= , value)) + else: + if ARGS.force: + write_config_value(REPO, entry['section'], entry['opti= on'], entry['value']) + else: + print("Not overwriting existing %s.%s value:" % (entry= ['section'], + entry= ['option'])) + print(" '%s' !=3D '%s'" % (value, entry['value'])) + print(" add '-f' to command line to force overwriting= existing settings") + else: + print("%s.%s =3D> '%s'" % (entry['section'], entry['option'], = entry['value'])) + if not ARGS.check: + write_config_value(REPO, entry['section'],=20 + entry['option'], entry['value']) -- 2.11.0