Title: [271274] trunk/Tools
Revision
271274
Author
[email protected]
Date
2021-01-07 16:35:43 -0800 (Thu, 07 Jan 2021)

Log Message

[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.

Modified Paths

Added Paths

Removed Paths

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)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to