Diff
Modified: trunk/Tools/ChangeLog (271273 => 271274)
--- trunk/Tools/ChangeLog 2021-01-08 00:30:58 UTC (rev 271273)
+++ trunk/Tools/ChangeLog 2021-01-08 00:35:43 UTC (rev 271274)
@@ -1,3 +1,24 @@
+2021-01-07 Jonathan Bedard <[email protected]>
+
+ [webkitscmpy] Split program into separate files
+ https://bugs.webkit.org/show_bug.cgi?id=220369
+ <rdar://problem/72856906>
+
+ Reviewed by Dewei Zhu.
+
+ * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Bump version.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/canonicalize: Move to webkitscmpy/program/canonicalize.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py: Update imports.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program: Moved from webkitscmpy/program.py.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program.py: Moved to webkitscmpy/program.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py: Moved from webkitscmpy/program.py.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize: Moved from webkitscmpy/canonicalize.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/committer.py: Ditto.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/message.py: Ditto.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/checkout.py: Moved from webkitscmpy/program.py.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/command.py: Moved from webkitscmpy/program.py.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py: Moved from webkitscmpy/program.py.
+
2021-01-07 Wenson Hsieh <[email protected]>
Text fields should not be translated while typing
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py (271273 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py 2021-01-08 00:30:58 UTC (rev 271273)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -46,7 +46,7 @@
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)
-version = Version(0, 7, 2)
+version = Version(0, 7, 3)
AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('monotonic', Version(1, 5)))
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py (271273 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py 2021-01-08 00:30:58 UTC (rev 271273)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -27,8 +27,8 @@
from datetime import datetime
from webkitcorepy import mocks, OutputCapture, StringIO
from webkitscmpy import local, Commit, Contributor
-from webkitscmpy.canonicalize.committer import main as committer_main
-from webkitscmpy.canonicalize.message import main as message_main
+from webkitscmpy.program.canonicalize.committer import main as committer_main
+from webkitscmpy.program.canonicalize.message import main as message_main
class Git(mocks.Subprocess):
Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,70 @@
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import argparse
+import logging
+import os
+import sys
+
+from webkitcorepy import arguments, log as webkitcorepy_log
+from webkitscmpy import local, log, remote
+
+from .canonicalize import Canonicalize
+from .command import Command
+from .checkout import Checkout
+from .find import Find
+
+
+def main(args=None, path=None, loggers=None, contributors=None, identifier_template=None):
+ logging.basicConfig(level=logging.WARNING)
+
+ loggers = [logging.getLogger(), webkitcorepy_log, log] + (loggers or [])
+
+ parser = argparse.ArgumentParser(
+ description='Custom git tooling from the WebKit team to interact with a ' +
+ 'repository using identifers',
+ )
+ arguments.LoggingGroup(parser)
+
+ group = parser.add_argument_group('Repository')
+ group.add_argument(
+ '--path', '-p', '-C',
+ dest='repository', default=path or os.getcwd(),
+ help='Set the repository path or URL to be used',
+ action='',
+ )
+
+ subparsers = parser.add_subparsers(help='sub-command help')
+
+ for program in [Find, Checkout, Canonicalize]:
+ subparser = subparsers.add_parser(program.name, help=program.help)
+ subparser.set_defaults(main=program.main)
+ program.parser(subparser, loggers=loggers)
+
+ parsed = parser.parse_args(args=args)
+
+ if parsed.repository.startswith(('https://', 'http://')):
+ repository = remote.Scm.from_url(parsed.repository, contributors=contributors)
+ else:
+ repository = local.Scm.from_path(path=parsed.repository, contributors=contributors)
+
+ return parsed.main(args=parsed, repository=repository, identifier_template=identifier_template)
Copied: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/__init__.py (from rev 271273, trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/canonicalize/__init__.py) (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/__init__.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/__init__.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,153 @@
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import logging
+import os
+import tempfile
+import subprocess
+import sys
+
+from webkitcorepy import arguments, run, string_utils
+from webkitscmpy import log
+from ..command import Command
+
+
+class Canonicalize(Command):
+ name = 'canonicalize'
+ help = 'Take the set of commits which have not yet been pushed and edit history to normalize the ' +\
+ 'committers with existing contributor mapping and add identifiers to commit messages'
+
+ @classmethod
+ def parser(cls, parser, loggers=None):
+ output_args = arguments.LoggingGroup(
+ parser,
+ loggers=loggers,
+ help='{} amount of logging and `git rebase` information displayed'
+ )
+ output_args.add_argument(
+ '--identifier', '--no-identifier',
+ help='Add in the identifier to commit messages, true by default',
+ action=""
+ dest='identifier',
+ default=True,
+ )
+ output_args.add_argument(
+ '--remote',
+ help='Compare against a different remote',
+ dest='remote',
+ default='origin',
+ )
+
+ @classmethod
+ def main(cls, args, repository, identifier_template=None, **kwargs):
+ if not repository.path:
+ sys.stderr.write('Cannot canonicalize commits on a remote repository\n')
+ return 1
+ if not repository.is_git:
+ sys.stderr.write('Commits can only be canonicalized on a Git repository\n')
+ return 1
+
+ branch = repository.branch
+ if not branch:
+ sys.stderr.write('Failed to determine current branch\n')
+ return -1
+ result = run([
+ repository.executable(), 'rev-list',
+ '--count', '--no-merges',
+ '{remote}/{branch}..{branch}'.format(remote=args.remote, branch=branch),
+ ], capture_output=True, cwd=repository.root_path)
+ if result.returncode:
+ sys.stderr.write('Failed to find local commits\n')
+ return -1
+ difference = int(result.stdout.rstrip())
+ if difference <= 0:
+ print('No local commits to be edited')
+ return 0
+ log.warning('{} to be editted...'.format(string_utils.pluralize(difference, 'commit')))
+
+ base = repository.find('{}~{}'.format(branch, difference))
+ log.info('Base commit is {} (ref {})'.format(base, base.hash))
+
+ log.debug('Saving contributors to temp file to be picked up by child processes')
+ contributors = os.path.join(tempfile.gettempdir(), '{}-contributors.json'.format(os.getpid()))
+ try:
+ with open(contributors, 'w') as file:
+ repository.contributors.save(file)
+
+ message_filter = [
+ '--msg-filter',
+ "{} {} '{}'".format(
+ sys.executable,
+ os.path.join(os.path.dirname(__file__), 'message.py'),
+ identifier_template or 'Identifier: {}',
+ ),
+ ] if args.identifier else []
+
+ with open(os.devnull, 'w') as devnull:
+ subprocess.check_call([
+ repository.executable(), 'filter-branch', '-f',
+ '--env-filter', '''{overwrite_message}
+committerOutput=$({python} {committer_py} {contributor_json})
+KEY=''
+VALUE=''
+for word in $committerOutput; do
+ if [[ $word == GIT_* ]] ; then
+ if [[ $KEY == GIT_* ]] ; then
+ {setting_message}
+ printf -v $KEY "${{VALUE::$((${{#VALUE}} - 1))}}"
+ KEY=''
+ VALUE=''
+ fi
+ fi
+ if [[ "$KEY" == "" ]] ; then
+ KEY="$word"
+ else
+ VALUE="$VALUE$word "
+ fi
+done
+if [[ $KEY == GIT_* ]] ; then
+ {setting_message}
+ printf -v $KEY "${{VALUE::$((${{#VALUE}} - 1))}}"
+fi'''.format(
+ overwrite_message='' if log.level > logging.INFO else 'echo "Overwriting $GIT_COMMIT"',
+ python=sys.executable,
+ committer_py=os.path.join(os.path.dirname(__file__), 'committer.py'),
+ contributor_json=contributors,
+ setting_message='' if log.level > logging.DEBUG else 'echo " $KEY=$VALUE"',
+ ),
+ ] + message_filter + ['{}...{}'.format(branch, base.hash)],
+ cwd=repository.root_path,
+ env={'FILTER_BRANCH_SQUELCH_WARNING': '1', 'PYTHONPATH': ':'.join(sys.path)},
+ stdout=devnull if log.level > logging.WARNING else None,
+ stderr=devnull if log.level > logging.WARNING else None,
+ )
+
+ except subprocess.CalledProcessError:
+ sys.stderr.write('Failed to modify local commit messages\n')
+ return -1
+
+ finally:
+ os.remove(contributors)
+
+ print('{} successfully canonicalized!'.format(string_utils.pluralize(difference, 'commit')))
+
+ return 0
Copied: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/committer.py (from rev 271273, trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/canonicalize/committer.py) (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/committer.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/committer.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import re
+import sys
+
+from webkitcorepy import run
+from webkitscmpy import Contributor, local
+
+EMAIL_RE = re.compile(r'(?P<email>[^@]+@[^@]+)(@.*)?')
+
+
+def canonicalize(name, email, contributors):
+ match = EMAIL_RE.match(email)
+ if match:
+ email = match.group('email')
+
+ contributor = contributors.get(email, contributors.get(email.lower()))
+ if contributor:
+ return contributor.name, email if match else contributor.email
+ contributor = contributors.get(name)
+ if contributor:
+ return contributor.name, contributor.email
+ return name, email
+
+
+def main(contributor_file):
+ REPOSITORY_PATH = os.environ.get('OLDPWD')
+ GIT_COMMIT = os.environ.get('GIT_COMMIT')
+
+ with open(contributor_file, 'r') as file:
+ contributors = Contributor.Mapping.load(file)
+
+ author, author_email = canonicalize(
+ os.environ.get('GIT_AUTHOR_NAME', 'Unknown'),
+ os.environ.get('GIT_AUTHOR_EMAIL', 'null'),
+ contributors,
+ )
+ committer, committer_email = canonicalize(
+ os.environ.get('GIT_COMMITTER_NAME', 'Unknown'),
+ os.environ.get('GIT_COMMITTER_EMAIL', 'null'),
+ contributors,
+ )
+
+ # Attempt to extract patch-by
+ if author_email == committer_email and REPOSITORY_PATH and GIT_COMMIT:
+ log = run(
+ [local.Git.executable(), 'log', GIT_COMMIT, '-1'],
+ cwd=REPOSITORY_PATH, capture_output=True, encoding='utf-8',
+ )
+
+ patch_by = re.search(
+ r'\s+Patch by (?P<author>[^<]+) \<(?P<email>[^<]+)\>.* on \d+-\d+-\d+',
+ log.stdout,
+ )
+ if patch_by:
+ author, author_email = canonicalize(
+ patch_by.group('author'),
+ patch_by.group('email'),
+ contributors,
+ )
+
+ print(u'GIT_AUTHOR_NAME {}'.format(author))
+ print(u'GIT_AUTHOR_EMAIL {}'.format(author_email))
+ print(u'GIT_COMMITTER_NAME {}'.format(committer))
+ print(u'GIT_COMMITTER_EMAIL {}'.format(committer_email))
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1]))
Copied: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/message.py (from rev 271273, trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/canonicalize/message.py) (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/message.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/canonicalize/message.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import os
+import sys
+
+from webkitscmpy.local import Git
+
+
+def main(inputfile, identifier_template):
+ REPOSITORY_PATH = os.environ.get('OLDPWD')
+ GIT_COMMIT = os.environ.get('GIT_COMMIT')
+
+ if not REPOSITORY_PATH:
+ sys.stderr.write('Failed to retrieve repository path\n')
+ return -1
+ if not GIT_COMMIT:
+ sys.stderr.write('Failed to retrieve git hash\n')
+ return -1
+
+ repository = Git(REPOSITORY_PATH)
+ commit = repository.commit(hash=GIT_COMMIT)
+ if not commit:
+ sys.stderr.write("Failed to find '{}' in the repository".format(GIT_COMMIT))
+ return -1
+ if not commit.identifier or not commit.branch:
+ sys.stderr.write("Failed to compute the identifier for '{}'".format(GIT_COMMIT))
+ return -1
+
+ lines = []
+ for line in inputfile.readlines():
+ lines.append(line.rstrip())
+
+ identifier_index = len(lines)
+ if identifier_index and repository.GIT_SVN_REVISION.match(lines[-1]):
+ identifier_index -= 1
+
+ if identifier_index and lines[identifier_index - 1].startswith(identifier_template.format('').split(':')[0]):
+ lines[identifier_index - 1] = identifier_template.format(commit)
+ else:
+ lines.insert(identifier_index, identifier_template.format(commit))
+
+ for line in lines:
+ print(line)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.stdin, sys.argv[1]))
Copied: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/checkout.py (from rev 271273, trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py) (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/checkout.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/checkout.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,65 @@
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+
+from .command import Command
+from webkitcorepy import arguments
+from webkitscmpy import local
+
+
+class Checkout(Command):
+ name = 'checkout'
+ help = 'Given an identifier, revision or hash, normalize and checkout that commit'
+
+ @classmethod
+ def parser(cls, parser, loggers=None):
+ arguments.LoggingGroup(
+ parser,
+ loggers=loggers,
+ help='{} amount of logging and commit information displayed'
+ )
+
+ parser.add_argument(
+ 'argument', nargs=1,
+ type=str, default=None,
+ help='String representation of a commit or branch to be normalized',
+ )
+
+ @classmethod
+ def main(cls, args, repository, **kwargs):
+ if not repository.path:
+ sys.stderr.write("Cannot checkout on remote repository")
+ return 1
+
+ try:
+ commit = repository.checkout(args.argument[0])
+ except (local.Scm.Exception, ValueError) as exception:
+ # ValueErrors and Scm exceptions usually contain enough information to be displayed
+ # to the user as an error
+ sys.stderr.write(str(exception) + '\n')
+ return 1
+
+ if not commit:
+ sys.stderr.write("Failed to map '{}'\n".format(args.argument[0]))
+ return 1
+ return 0
Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/command.py (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/command.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/command.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,40 @@
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+
+
+class Command(object):
+ name = None
+ help = None
+
+ @classmethod
+ def parser(cls, parser):
+ if cls.name is None:
+ raise NotImplementedError('Command does not have a name')
+ if cls.help is None:
+ raise NotImplementedError("'{}' does not have a help message")
+
+ @classmethod
+ def main(cls, args, repository, **kwargs):
+ sys.stderr.write('No command specified\n')
+ return -1
Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py (0 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -0,0 +1,105 @@
+# Copyright (C) 2020, 2021 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import json
+import sys
+
+from .command import Command
+from datetime import datetime
+from webkitcorepy import arguments
+from webkitscmpy import Commit, local
+
+
+class Find(Command):
+ name = 'find'
+ help = 'Given an identifier, revision or hash, normalize and print the commit'
+
+ @classmethod
+ def parser(cls, parser, loggers=None):
+ output_args = arguments.LoggingGroup(
+ parser,
+ loggers=loggers,
+ help='{} amount of logging and commit information displayed'
+ )
+ output_args.add_argument(
+ '--json', '-j',
+ help='Convert the commit to a machine-readable JSON object',
+ action='',
+ dest='json',
+ default=False,
+ )
+ output_args.add_argument(
+ '--log', '--no-log',
+ help='Include the commit message for the requested commit',
+ action=""
+ dest='include_log',
+ default=True,
+ )
+
+ parser.add_argument(
+ 'argument', nargs=1,
+ type=str, default=None,
+ help='String representation of a commit or branch to be normalized',
+ )
+
+ @classmethod
+ def main(cls, args, repository, **kwargs):
+ try:
+ commit = repository.find(args.argument[0], include_log=args.include_log)
+ except (local.Scm.Exception, ValueError) as exception:
+ # ValueErrors and Scm exceptions usually contain enough information to be displayed
+ # to the user as an error
+ sys.stderr.write(str(exception) + '\n')
+ return 1
+
+ if args.verbose > 0 and not commit.message:
+ sys.stderr.write("Failed to find the commit message for '{}'\n".format(commit))
+ return 1
+
+ if args.json:
+ print(json.dumps(commit, cls=Commit.Encoder, indent=4))
+ return 0
+
+ if args.verbose < 0:
+ print('{identifier} | {hash}{revision}{title}'.format(
+ identifier=commit,
+ hash=commit.hash[:Commit.HASH_LABEL_SIZE] if commit.hash else '',
+ revision='{}r{}'.format(', ' if commit.hash else '', commit.revision) if commit.revision else '',
+ title=' | {}'.format(commit.message.splitlines()[0]) if commit.message else ''
+ ))
+ return 0
+
+ if commit.message:
+ print('Title: {}'.format(commit.message.splitlines()[0]))
+ print('Author: {}'.format(commit.author))
+ print('Identifier: {}'.format(commit))
+ print(datetime.fromtimestamp(commit.timestamp).strftime('Date: %a %b %d %H:%M:%S %Y'))
+ if args.verbose > 0 or commit.revision:
+ print('Revision: {}'.format(commit.revision or 'N/A'))
+ if args.verbose > 0 or commit.hash:
+ print('Hash: {}'.format(commit.hash[:Commit.HASH_LABEL_SIZE] if commit.hash else 'N/A'))
+
+ if args.verbose > 0:
+ for line in commit.message.splitlines():
+ print(' {}'.format(line))
+
+ return 0
Deleted: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py (271273 => 271274)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py 2021-01-08 00:30:58 UTC (rev 271273)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program.py 2021-01-08 00:35:43 UTC (rev 271274)
@@ -1,200 +0,0 @@
-# Copyright (C) 2020 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import argparse
-import json
-import logging
-import os
-import sys
-
-from datetime import datetime
-from webkitcorepy import arguments, log as webkitcorepy_log
-from webkitscmpy import Commit, local, log, remote
-
-
-class Command(object):
- name = None
- help = None
-
- @classmethod
- def parser(cls, parser):
- if cls.name is None:
- raise NotImplementedError('Command does not have a name')
- if cls.help is None:
- raise NotImplementedError("'{}' does not have a help message")
-
- @classmethod
- def main(cls, args, repository, **kwargs):
- sys.stderr.write('No command specified\n')
- return -1
-
-
-class Find(Command):
- name = 'find'
- help = 'Given an identifier, revision or hash, normalize and print the commit'
-
- @classmethod
- def parser(cls, parser, loggers=None):
- output_args = arguments.LoggingGroup(
- parser,
- loggers=loggers,
- help='{} amount of logging and commit information displayed'
- )
- output_args.add_argument(
- '--json', '-j',
- help='Convert the commit to a machine-readable JSON object',
- action='',
- dest='json',
- default=False,
- )
- output_args.add_argument(
- '--log', '--no-log',
- help='Include the commit message for the requested commit',
- action=""
- dest='include_log',
- default=True,
- )
-
- parser.add_argument(
- 'argument', nargs=1,
- type=str, default=None,
- help='String representation of a commit or branch to be normalized',
- )
-
- @classmethod
- def main(cls, args, repository, **kwargs):
- try:
- commit = repository.find(args.argument[0], include_log=args.include_log)
- except (local.Scm.Exception, ValueError) as exception:
- # ValueErrors and Scm exceptions usually contain enough information to be displayed
- # to the user as an error
- sys.stderr.write(str(exception) + '\n')
- return 1
-
- if args.verbose > 0 and not commit.message:
- sys.stderr.write("Failed to find the commit message for '{}'\n".format(commit))
- return 1
-
- if args.json:
- print(json.dumps(commit, cls=Commit.Encoder, indent=4))
- return 0
-
- if args.verbose < 0:
- print('{identifier} | {hash}{revision}{title}'.format(
- identifier=commit,
- hash=commit.hash[:Commit.HASH_LABEL_SIZE] if commit.hash else '',
- revision='{}r{}'.format(', ' if commit.hash else '', commit.revision) if commit.revision else '',
- title=' | {}'.format(commit.message.splitlines()[0]) if commit.message else ''
- ))
- return 0
-
- if commit.message:
- print('Title: {}'.format(commit.message.splitlines()[0]))
- print('Author: {}'.format(commit.author))
- print('Identifier: {}'.format(commit))
- print(datetime.fromtimestamp(commit.timestamp).strftime('Date: %a %b %d %H:%M:%S %Y'))
- if args.verbose > 0 or commit.revision:
- print('Revision: {}'.format(commit.revision or 'N/A'))
- if args.verbose > 0 or commit.hash:
- print('Hash: {}'.format(commit.hash[:Commit.HASH_LABEL_SIZE] if commit.hash else 'N/A'))
-
- if args.verbose > 0:
- for line in commit.message.splitlines():
- print(' {}'.format(line))
-
- return 0
-
-
-class Checkout(Command):
- name = 'checkout'
- help = 'Given an identifier, revision or hash, normalize and checkout that commit'
-
- @classmethod
- def parser(cls, parser, loggers=None):
- arguments.LoggingGroup(
- parser,
- loggers=loggers,
- help='{} amount of logging and commit information displayed'
- )
-
- parser.add_argument(
- 'argument', nargs=1,
- type=str, default=None,
- help='String representation of a commit or branch to be normalized',
- )
-
- @classmethod
- def main(cls, args, repository, **kwargs):
- if not repository.path:
- sys.stderr.write("Cannot checkout on remote repository")
- return 1
-
- try:
- commit = repository.checkout(args.argument[0])
- except (local.Scm.Exception, ValueError) as exception:
- # ValueErrors and Scm exceptions usually contain enough information to be displayed
- # to the user as an error
- sys.stderr.write(str(exception) + '\n')
- return 1
-
- if not commit:
- sys.stderr.write("Failed to map '{}'\n".format(args.argument[0]))
- return 1
- return 0
-
-
-def main(args=None, path=None, loggers=None, contributors=None, identifier_template=None):
- logging.basicConfig(level=logging.WARNING)
-
- loggers = [logging.getLogger(), webkitcorepy_log, log] + (loggers or [])
-
- parser = argparse.ArgumentParser(
- description='Custom git tooling from the WebKit team to interact with a ' +
- 'repository using identifers',
- )
- arguments.LoggingGroup(parser)
-
- group = parser.add_argument_group('Repository')
- group.add_argument(
- '--path', '-p', '-C',
- dest='repository', default=path or os.getcwd(),
- help='Set the repository path or URL to be used',
- action='',
- )
-
- subparsers = parser.add_subparsers(help='sub-command help')
-
- from webkitscmpy.canonicalize import Canonicalize
-
- for program in [Find, Checkout, Canonicalize]:
- subparser = subparsers.add_parser(program.name, help=program.help)
- subparser.set_defaults(main=program.main)
- program.parser(subparser, loggers=loggers)
-
- parsed = parser.parse_args(args=args)
-
- if parsed.repository.startswith(('https://', 'http://')):
- repository = remote.Scm.from_url(parsed.repository, contributors=contributors)
- else:
- repository = local.Scm.from_path(path=parsed.repository, contributors=contributors)
-
- return parsed.main(args=parsed, repository=repository, identifier_template=identifier_template)