[git-webkit] Support ranges in find
https://bugs.webkit.org/show_bug.cgi?id=241806
<rdar://95601346>
Reviewed by Ryan Haddad.
* Tools/Scripts/libraries/webkitscmpy/setup.py: Bump version.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py:
(Git.commits): Use '..'' instead of '...'
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py:
(Info.main): Support .. based range queries.
(Find): Add 'list' alias.
* Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py:
Canonical link: https://commits.webkit.org/251746@main
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@295741 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Tools/Scripts/libraries/webkitscmpy/setup.py b/Tools/Scripts/libraries/webkitscmpy/setup.py
index 00bda7a..d4d2c69 100644
--- a/Tools/Scripts/libraries/webkitscmpy/setup.py
+++ b/Tools/Scripts/libraries/webkitscmpy/setup.py
@@ -29,7 +29,7 @@
setup(
name='webkitscmpy',
- version='5.0.3',
+ version='5.1.0',
description='Library designed to interact with git and svn repositories.',
long_description=readme(),
classifiers=[
diff --git a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py
index 0f91a65..3a97b61 100644
--- a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py
+++ b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py
@@ -46,7 +46,7 @@
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)
-version = Version(5, 0, 3)
+version = Version(5, 1, 0)
AutoInstall.register(Package('fasteners', Version(0, 15, 0)))
AutoInstall.register(Package('jinja2', Version(2, 11, 3)))
diff --git a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py
index 61f7334..fe98c24 100644
--- a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py
+++ b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/local/git.py
@@ -744,7 +744,7 @@
try:
log = None
log = subprocess.Popen(
- [self.executable(), 'log', '--format=fuller', '--no-decorate', '--date=unix', '{}...{}'.format(end.hash, begin.hash), '--'],
+ [self.executable(), 'log', '--format=fuller', '--no-decorate', '--date=unix', '{}..{}'.format(begin.hash, end.hash), '--'],
cwd=self.root_path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
diff --git a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py
index 93dfbc3..36d8d06 100644
--- a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py
+++ b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/find.py
@@ -57,46 +57,64 @@
return 1
try:
- commit = repository.find(reference, include_log=args.include_log)
- except (local.Scm.Exception, ValueError) as exception:
+ if '..' in reference:
+ if '...' in reference:
+ sys.stderr.write("'find' sub-command only supports '..' notation\n")
+ return 1
+ references = reference.split('..')
+ if len(references) > 2:
+ sys.stderr.write('Can only include two references in a range\n')
+ return 1
+ commits = [commit for commit in repository.commits(begin=dict(argument=references[0]), end=dict(argument=references[1]))]
+ else:
+ commits = [repository.find(reference, include_log=args.include_log)]
+
+ except (local.Scm.Exception, TypeError, 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
+ for commit in commits:
+ 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))
+ print(json.dumps(commits if len(commits) > 1 else commits[0], 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 ''
- ))
+ for commit in commits:
+ 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(u'Title: {}'.format(commit.message.splitlines()[0]))
- try:
- print(u'Author: {}'.format(commit.author))
- except (UnicodeEncodeError, UnicodeDecodeError):
- print('Error: Unable to print commit author name, please file a bug if seeing this locally.')
- 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'))
- print(u'Identifier: {}'.format(commit))
+ previous = False
+ for commit in commits:
+ if previous:
+ print('-' * 20)
+ previous = True
+ if commit.message:
+ print(u'Title: {}'.format(commit.message.splitlines()[0]))
+ try:
+ print(u'Author: {}'.format(commit.author))
+ except (UnicodeEncodeError, UnicodeDecodeError):
+ print('Error: Unable to print commit author name, please file a bug if seeing this locally.')
+ 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'))
+ print(u'Identifier: {}'.format(commit))
- if args.verbose > 0:
- for line in commit.message.splitlines():
- print(u' {}'.format(line))
+ if args.verbose > 0:
+ for line in commit.message.splitlines():
+ print(u' {}'.format(line))
return 0
@@ -104,6 +122,7 @@
class Find(Command):
name = 'find'
help = 'Given an identifier, revision or hash, normalize and print the commit'
+ aliases = ['list']
@classmethod
def parser(cls, parser, loggers=None):
diff --git a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py
index a14aad1..1ba3311 100644
--- a/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py
+++ b/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/find_unittest.py
@@ -156,6 +156,30 @@
'''.format(datetime.fromtimestamp(1601663000).strftime('%a %b %d %H:%M:%S %Y')),
)
+ def test_standard_list(self):
+ with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
+ self.assertEqual(0, program.main(
+ args=('find', '2@main..4@main'),
+ path=self.path,
+ ))
+ self.assertEqual(
+ captured.stdout.getvalue(),
+ '''Title: 8th commit
+Author: Jonathan Bedard <jbedard@apple.com>
+Date: {}
+Revision: 8
+Hash: bae5d1e90999
+Identifier: 4@main
+--------------------
+Title: 4th commit
+Author: Jonathan Bedard <jbedard@apple.com>
+Date: {}
+Revision: 4
+Hash: 1abe25b443e9
+Identifier: 3@main
+'''.format(datetime.fromtimestamp(1601668000).strftime('%a %b %d %H:%M:%S %Y'), datetime.fromtimestamp(1601663000).strftime('%a %b %d %H:%M:%S %Y')),
+ )
+
def test_verbose(self):
with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
self.assertEqual(0, program.main(
@@ -175,6 +199,39 @@
'''.format(datetime.fromtimestamp(1601663000).strftime('%a %b %d %H:%M:%S %Y')),
)
+ def test_quiet(self):
+ with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
+ self.assertEqual(0, program.main(
+ args=('find', '3@main', '-q'),
+ path=self.path,
+ ))
+ self.assertEqual(
+ captured.stdout.getvalue(),
+ '3@main | 1abe25b443e9, r4 | 4th commit\n',
+ )
+
+ def test_failed_list(self):
+ with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
+ self.assertEqual(1, program.main(
+ args=('find', '2@main...4@main', '-q'),
+ path=self.path,
+ ))
+ self.assertEqual(
+ captured.stderr.getvalue(),
+ "'find' sub-command only supports '..' notation\n",
+ )
+
+ def test_quiet_list(self):
+ with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
+ self.assertEqual(0, program.main(
+ args=('find', '2@main..4@main', '-q'),
+ path=self.path,
+ ))
+ self.assertEqual(
+ captured.stdout.getvalue(),
+ '4@main | bae5d1e90999, r8 | 8th commit\n3@main | 1abe25b443e9, r4 | 4th commit\n',
+ )
+
def test_json(self):
with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
self.assertEqual(0, program.main(
@@ -197,6 +254,40 @@
message='4th commit\ngit-svn-id: https://svn.example.org/repository/repository/trunk@4 268f45cc-cd09-0410-ab3c-d52691b4dbfc',
))
+ def test_json_list(self):
+ self.maxDiff = None
+ with OutputCapture() as captured, mocks.local.Git(self.path, git_svn=True), mocks.local.Svn(), MockTime:
+ self.assertEqual(0, program.main(
+ args=('find', '2@main..4@main', '--json'),
+ path=self.path,
+ ))
+
+ decoded = json.loads(captured.stdout.getvalue())
+ self.assertEqual(
+ decoded, [dict(
+ identifier='4@main',
+ hash='bae5d1e90999d4f916a8a15810ccfa43f37a2fd6',
+ revision=8,
+ author=dict(
+ name='Jonathan Bedard',
+ emails=['jbedard@apple.com'],
+ ), timestamp=1601668000,
+ order=0,
+ branch='main',
+ message='8th commit\ngit-svn-id: https://svn.example.org/repository/repository/trunk@8 268f45cc-cd09-0410-ab3c-d52691b4dbfc',
+ ), dict(
+ identifier='3@main',
+ hash='1abe25b443e985f93b90d830e4a7e3731336af4d',
+ revision=4,
+ author=dict(
+ name='Jonathan Bedard',
+ emails=['jbedard@apple.com'],
+ ), timestamp=1601663000,
+ order=0,
+ branch='main',
+ message='4th commit\ngit-svn-id: https://svn.example.org/repository/repository/trunk@4 268f45cc-cd09-0410-ab3c-d52691b4dbfc',
+ )])
+
def test_tag_svn(self):
with OutputCapture() as captured, mocks.local.Git(), mocks.local.Svn(self.path), MockTime:
self.assertEqual(0, program.main(