Changeset 268433 in webkit


Ignore:
Timestamp:
Oct 13, 2020 4:53:34 PM (4 years ago)
Author:
Jonathan Bedard
Message:

[webkitscmpy] Add git-webkit find
https://bugs.webkit.org/show_bug.cgi?id=217534
<rdar://problem/70152431>

Reviewed by Dewei Zhu.

  • Scripts/git-webkit: Added.
  • Scripts/libraries/webkitcorepy/webkitcorepy/init.py: Bump version.
  • Scripts/libraries/webkitcorepy/webkitcorepy/arguments.py:

(NoAction.call):
(CountAction): Create an action to increment or decrement a variable by a value.
(CallbackAction): Create an action which will trigger a callback when set.
(LoggingGroup): Create a group which allows the user to change logging behavior.

  • Scripts/libraries/webkitscmpy/git-webkit: Added.
  • Scripts/libraries/webkitscmpy/setup.py: Add webkitscmpy.program and git-webkit.
  • Scripts/libraries/webkitscmpy/webkitscmpy/init.py: Bump version.
  • Scripts/libraries/webkitscmpy/webkitscmpy/commit.py:

(Commit): Make the 12 character hash based on a class variable.

  • Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py:

(Git.default_branch): Fallback to 'master' or 'main' if the remote isn't available.
(Git.find): Use git to match branches and tags to a hash instead of trying to do it ourselves.

  • Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py:

(Scm.find): Add function to convert generic string arguments to a commit, and then find that commit in
the repository.

  • Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py:

(Svn): Support a few different SVN binary paths.

  • Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py: Add rev-parse branch/tag/HEAD -> hash conversion.
  • Scripts/libraries/webkitscmpy/webkitscmpy/program.py: Added.

(Command): Base class for all commands.
(Find):
(Find.parser): Configure parser for 'find' sub-program.
(Find.main): Given an identifier, revision, hash or branch name, find and print the matching commit from
(main): Entry point to git-<project> scripts.

  • Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py: Added.

(TestFind):
(TestFind.test_basic_git):
(TestFind.test_basic_git_svn):
(TestFind.test_basic_svn):
(TestFind.test_branch_tilde):
(TestFind.test_identifier_git):
(TestFind.test_identifier_git_svn):
(TestFind.test_identifier_svn):
(TestFind.test_hash):
(TestFind.test_revision_svn):
(TestFind.test_revision_git_svn):
(TestFind.test_standard):

Location:
trunk/Tools
Files:
2 added
9 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r268431 r268433  
     12020-10-13  Jonathan Bedard  <jbedard@apple.com>
     2
     3        [webkitscmpy] Add `git-webkit find`
     4        https://bugs.webkit.org/show_bug.cgi?id=217534
     5        <rdar://problem/70152431>
     6
     7        Reviewed by Dewei Zhu.
     8
     9        * Scripts/git-webkit: Added.
     10        * Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: Bump version.
     11        * Scripts/libraries/webkitcorepy/webkitcorepy/arguments.py:
     12        (NoAction.__call__):
     13        (CountAction): Create an action to increment or decrement a variable by a value.
     14        (CallbackAction): Create an action which will trigger a callback when set.
     15        (LoggingGroup): Create a group which allows the user to change logging behavior.
     16        * Scripts/libraries/webkitscmpy/git-webkit: Added.
     17        * Scripts/libraries/webkitscmpy/setup.py: Add webkitscmpy.program and git-webkit.
     18        * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Bump version.
     19        * Scripts/libraries/webkitscmpy/webkitscmpy/commit.py:
     20        (Commit): Make the 12 character hash based on a class variable.
     21        * Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py:
     22        (Git.default_branch): Fallback to 'master' or 'main' if the remote isn't available.
     23        (Git.find): Use git to match branches and tags to a hash instead of trying to do it ourselves.
     24        * Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py:
     25        (Scm.find): Add function to convert generic string arguments to a commit, and then find that commit in
     26        the repository.
     27        * Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py:
     28        (Svn): Support a few different SVN binary paths.
     29        * Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py: Add rev-parse branch/tag/HEAD -> hash conversion.
     30        * Scripts/libraries/webkitscmpy/webkitscmpy/program.py: Added.
     31        (Command): Base class for all commands.
     32        (Find):
     33        (Find.parser): Configure parser for 'find' sub-program.
     34        (Find.main): Given an identifier, revision, hash or branch name, find and print the matching commit from
     35        (main): Entry point to git-<project> scripts.
     36        * Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py: Added.
     37        (TestFind):
     38        (TestFind.test_basic_git):
     39        (TestFind.test_basic_git_svn):
     40        (TestFind.test_basic_svn):
     41        (TestFind.test_branch_tilde):
     42        (TestFind.test_identifier_git):
     43        (TestFind.test_identifier_git_svn):
     44        (TestFind.test_identifier_svn):
     45        (TestFind.test_hash):
     46        (TestFind.test_revision_svn):
     47        (TestFind.test_revision_git_svn):
     48        (TestFind.test_standard):
     49
    1502020-10-12  Ryosuke Niwa  <rniwa@webkit.org>
    251
  • trunk/Tools/Scripts/git-webkit

    • Property svn:executable set to *
    r268432 r268433  
     1#!/usr/bin/env python
     2
    13# Copyright (C) 2020 Apple Inc. All rights reserved.
    24#
     
    2123# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2224
    23 import argparse
     25import os
     26import webkitpy
     27import sys
    2428
     29from webkitscmpy import program
    2530
    26 class NoAction(argparse.Action):
    27     def __init__(self, option_strings, dest, **kwargs):
    28         super(NoAction, self).__init__(option_strings, dest, nargs=0, **kwargs)
     31sys.exit(program.main(path=os.path.dirname(__file__)))
    2932
    30     def __call__(self, parser, namespace, values, option_string=None):
    31         setattr(namespace, self.dest, False if option_string.startswith('--no') else True)
  • trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/arguments.py

    r266478 r268433  
    2222
    2323import argparse
     24import logging
     25
     26from webkitcorepy import log
    2427
    2528
     
    3033    def __call__(self, parser, namespace, values, option_string=None):
    3134        setattr(namespace, self.dest, False if option_string.startswith('--no') else True)
     35
     36
     37def CountAction(value=1):
     38    class Action(argparse.Action):
     39        def __init__(self, option_strings, dest, **kwargs):
     40            super(Action, self).__init__(option_strings, dest, nargs=0, **kwargs)
     41
     42        def __call__(self, parser, namespace, values, option_string):
     43            setattr(namespace, self.dest, getattr(namespace, self.dest) + value)
     44
     45    return Action
     46
     47
     48def CallbackAction(action, callback=lambda namespace: None):
     49    class Action(action):
     50        def __call__(self, parser, namespace, values, option_strings):
     51            super(Action, self).__call__(parser, namespace, values, option_strings)
     52            callback(namespace)
     53
     54    return Action
     55
     56
     57def LoggingGroup(parser, loggers=None, default=logging.WARNING, help='{} amount of logging'):
     58    if not isinstance(parser, argparse.ArgumentParser):
     59        raise ValueError('Provided parser is not a {}'.format(type(argparse.ArgumentParser)))
     60
     61    if not loggers:
     62        loggers = [logging.getLogger(), log]
     63    for logger in loggers:
     64        logger.setLevel(default)
     65
     66    def verbose_callback(namespace):
     67        verbosity = getattr(namespace, 'verbose')
     68        log_level = default - verbosity * 10
     69
     70        setattr(namespace, 'log_level', log_level)
     71
     72        for logger in loggers:
     73            logger.setLevel(log_level)
     74
     75    group = parser.add_argument_group('Logging')
     76    group.add_argument(
     77        '--verbose', '-v',
     78        dest='verbose', default=0,
     79        help=help.format('Increase'),
     80        action=CallbackAction(CountAction(value=1), callback=verbose_callback),
     81    )
     82    group.add_argument(
     83        '--quiet', '-q',
     84        dest='verbose', default=0,
     85        help=help.format('Decrease'),
     86        action=CallbackAction(CountAction(value=-1), callback=verbose_callback),
     87    )
     88    return group
  • trunk/Tools/Scripts/libraries/webkitscmpy/git-webkit

    • Property svn:executable set to *
    r268432 r268433  
     1#!/usr/bin/env python
     2
    13# Copyright (C) 2020 Apple Inc. All rights reserved.
    24#
     
    2123# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2224
    23 import argparse
     25import sys
     26
     27from webkitscmpy import program
    2428
    2529
    26 class NoAction(argparse.Action):
    27     def __init__(self, option_strings, dest, **kwargs):
    28         super(NoAction, self).__init__(option_strings, dest, nargs=0, **kwargs)
    29 
    30     def __call__(self, parser, namespace, values, option_string=None):
    31         setattr(namespace, self.dest, False if option_string.startswith('--no') else True)
     30sys.exit(program.main())
  • trunk/Tools/Scripts/libraries/webkitscmpy/setup.py

    r268080 r268433  
    5454        'webkitscmpy.mocks',
    5555        'webkitscmpy.mocks.local',
     56        'webkitscmpy.program',
    5657        'webkitscmpy.test',
    5758    ],
     59    scripts=['git-webkit'],
    5860    install_requires=['python-dateutil', 'webkitcorepy'],
    5961    include_package_data=True,
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py

    r268319 r268433  
    4747    )
    4848
    49 version = Version(0, 1, 3)
     49version = Version(0, 2, 0)
    5050
    5151AutoInstall.register(Package('dateutil', Version(2, 8, 1), pypi_name='python-dateutil'))
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/commit.py

    r268319 r268433  
    3434    IDENTIFIER_RE = re.compile(r'^((?P<branch_point>\d+)\.)?(?P<identifier>-?\d+)(@(?P<branch>\S+))?$')
    3535    NUMBER_RE = re.compile(r'^-?\d*$')
     36    HASH_LABEL_SIZE = 12
    3637
    3738    class Encoder(json.JSONEncoder):
     
    131132
    132133    @classmethod
    133     def parse(cls, arg):
     134    def parse(cls, arg, do_assert=True):
    134135        if cls._parse_identifier(arg):
    135136            return Commit(identifier=arg)
     
    141142            return Commit(hash=arg)
    142143
    143         raise ValueError("'{}' cannot be converted to a commit object".format(arg))
     144        if do_assert:
     145            raise ValueError("'{}' cannot be converted to a commit object".format(arg))
     146        return None
    144147
    145148    def __init__(
     
    212215            result += '\n'
    213216        if self.hash:
    214             result += '    git hash: {}'.format(self.hash[:12])
     217            result += '    git hash: {}'.format(self.hash[:self.HASH_LABEL_SIZE])
    215218            if self.branch:
    216219                result += ' on {}'.format(self.branch)
     
    243246            return 'r{}'.format(self.revision)
    244247        if self.hash:
    245             return self.hash[:12]
     248            return self.hash[:self.HASH_LABEL_SIZE]
    246249        if self.identifier is not None:
    247250            return str(self.identifier)
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py

    r268080 r268433  
    2323
    2424import re
     25import six
    2526
    2627from webkitcorepy import run, decorators, TimeoutExpired
     
    8889        result = run([self.executable, 'rev-parse', '--abbrev-ref', 'origin/HEAD'], cwd=self.path, capture_output=True, encoding='utf-8')
    8990        if result.returncode:
     91            candidates = self.branches
     92            if 'master' in candidates:
     93                return 'master'
     94            if 'main' in candidates:
     95                return 'main'
    9096            return None
    9197        return '/'.join(result.stdout.rstrip().split('/')[1:])
     
    251257            message='\n'.join(line[4:] for line in log.stdout.splitlines()[4:]),
    252258        )
     259
     260    def find(self, argument):
     261        if not isinstance(argument, six.string_types):
     262            raise ValueError("Expected 'argument' to be a string, not '{}'".format(type(argument)))
     263
     264        parsed_commit = Commit.parse(argument, do_assert=False)
     265        if parsed_commit:
     266            return self.commit(
     267                hash=parsed_commit.hash,
     268                revision=parsed_commit.revision,
     269                identifier=parsed_commit.identifier,
     270                branch=parsed_commit.branch,
     271            )
     272
     273        output = run(
     274            [self.executable, 'rev-parse', argument],
     275            cwd=self.root_path, capture_output=True, encoding='utf-8',
     276        )
     277        if output.returncode:
     278            raise ValueError("'{}' is not an arguement recognized by git".format(argument))
     279        return self.commit(hash=output.stdout.rstrip())
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/scm.py

    r268080 r268433  
    2424import logging
    2525import re
     26import six
    2627import sys
    2728
    2829from logging import NullHandler
    29 from webkitscmpy import log
     30from webkitscmpy import log, Commit
    3031
    3132
     
    4950        if local.Svn.is_checkout(path):
    5051            return local.Svn(path)
    51         raise OSError('{} is not a known SCM type')
     52        raise OSError("'{}' is not a known SCM type".format(path))
    5253
    5354    def __init__(self, path, dev_branches=None, prod_branches=None):
     
    9091        raise NotImplementedError()
    9192
     93    def find(self, argument):
     94        if not isinstance(argument, six.string_types):
     95            raise ValueError("Expected 'argument' to be a string, not '{}'".format(type(argument)))
     96
     97        offset = 0
     98        if '~' in argument:
     99            for s in argument.split('~')[1:]:
     100                if s and not s.isdigit():
     101                    raise ValueError("'{}' is not a valid argument to Scm.find()".format(argument))
     102                offset += int(s) if s else 1
     103            argument = argument.split('~')[0]
     104
     105        if argument == 'HEAD':
     106            result = self.commit()
     107
     108        elif argument in self.branches:
     109            result = self.commit(branch=argument)
     110
     111        else:
     112            if offset:
     113                raise ValueError("'~' offsets are not supported for revisions and identifiers")
     114
     115            parsed_commit = Commit.parse(argument)
     116            return self.commit(
     117                hash=parsed_commit.hash,
     118                revision=parsed_commit.revision,
     119                identifier=parsed_commit.identifier,
     120                branch=parsed_commit.branch,
     121            )
     122
     123        if not offset:
     124            return result
     125
     126        return self.commit(
     127            identifier=result.identifier - offset,
     128            branch=result.branch,
     129        )
     130
    92131    def commit(self, hash=None, revision=None, identifier=None, branch=None):
    93132        raise NotImplementedError()
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/svn.py

    r268293 r268433  
    3838
    3939class Svn(Scm):
    40     executable = '/usr/local/bin/svn'
     40    executable = '/usr/bin/svn' if os.path.exists('/usr/bin/svn') else '/usr/local/bin/svn'
    4141    LOG_RE = re.compile(r'r(?P<revision>\d+) \| (?P<email>.*) \| (?P<date>.*)')
    4242    CACHE_VERSION = Version(1)
  • trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py

    r268080 r268433  
    222222                ),
    223223            ), mocks.Subprocess.Route(
     224                local.Git.executable, 'rev-parse', '.*',
     225                cwd=self.path,
     226                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
     227                    returncode=0,
     228                    stdout='{}\n'.format(self.find(args[2]).hash),
     229                ) if self.find(args[2]) else mocks.ProcessCompletion(returncode=128)
     230            ), mocks.Subprocess.Route(
    224231                local.Git.executable, 'log', re.compile(r'.+'), '-1',
    225232                cwd=self.path,
Note: See TracChangeset for help on using the changeset viewer.