Title: [281363] trunk/Tools
Revision
281363
Author
jbed...@apple.com
Date
2021-08-20 22:25:07 -0700 (Fri, 20 Aug 2021)

Log Message

[git-webkit] Add pull-request command (Part 2)
https://bugs.webkit.org/show_bug.cgi?id=229089
<rdar://problem/81908751>

Reviewed by Dewei Zhu.

* Scripts/libraries/webkitscmpy/setup.py: Bump version.
* Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
* Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py:
(Git.__init__): Add 'check-ref-format' and 'checkout -b'.
(Git.checkout): Add ability to create branch.
* Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py:
(main): Add Branch command.
* Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py:
(Branch.parser): Allow user to specify engineering branch name.
(Branch.normalize_issue): Turn provided string into eng branch if it isn't already.
(Branch.main): Create eng branch from current checkout state.
* Scripts/libraries/webkitscmpy/webkitscmpy/test/branch_unittest.py:
(TestBranch):
(TestBranch.setUp):
(TestBranch.test_basic_svn):
(TestBranch.test_basic_git):
(TestBranch.test_prompt_git):
(TestBranch.test_invalid_branch):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (281362 => 281363)


--- trunk/Tools/ChangeLog	2021-08-21 03:20:23 UTC (rev 281362)
+++ trunk/Tools/ChangeLog	2021-08-21 05:25:07 UTC (rev 281363)
@@ -1,3 +1,30 @@
+2021-08-20  Jonathan Bedard  <jbed...@apple.com>
+
+        [git-webkit] Add pull-request command (Part 2)
+        https://bugs.webkit.org/show_bug.cgi?id=229089
+        <rdar://problem/81908751>
+
+        Reviewed by Dewei Zhu.
+
+        * Scripts/libraries/webkitscmpy/setup.py: Bump version.
+        * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
+        * Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py:
+        (Git.__init__): Add 'check-ref-format' and 'checkout -b'.
+        (Git.checkout): Add ability to create branch.
+        * Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py:
+        (main): Add Branch command.
+        * Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py:
+        (Branch.parser): Allow user to specify engineering branch name.
+        (Branch.normalize_issue): Turn provided string into eng branch if it isn't already.
+        (Branch.main): Create eng branch from current checkout state.
+        * Scripts/libraries/webkitscmpy/webkitscmpy/test/branch_unittest.py:
+        (TestBranch):
+        (TestBranch.setUp):
+        (TestBranch.test_basic_svn):
+        (TestBranch.test_basic_git):
+        (TestBranch.test_prompt_git):
+        (TestBranch.test_invalid_branch):
+
 2021-08-20  Alex Christensen  <achristen...@webkit.org>
 
         Make UIEventAttribution tests less platform dependent

Modified: trunk/Tools/Scripts/libraries/webkitscmpy/setup.py (281362 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/setup.py	2021-08-21 03:20:23 UTC (rev 281362)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/setup.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -29,7 +29,7 @@
 
 setup(
     name='webkitscmpy',
-    version='1.1.5',
+    version='1.1.6',
     description='Library designed to interact with git and svn repositories.',
     long_description=readme(),
     classifiers=[

Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py (281362 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py	2021-08-21 03:20:23 UTC (rev 281362)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -46,7 +46,7 @@
         "Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
     )
 
-version = Version(1, 1, 5)
+version = Version(1, 1, 6)
 
 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 (281362 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py	2021-08-21 03:20:23 UTC (rev 281362)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -333,10 +333,15 @@
                     stdout='\n'.join(sorted(self.branches_on(args[4]))) + '\n',
                 ) if self.find(args[4]) else mocks.ProcessCompletion(returncode=128),
             ), mocks.Subprocess.Route(
+                self.executable, 'checkout', '-b', re.compile(r'.+'),
+                cwd=self.path,
+                generator=lambda *args, **kwargs:
+                    mocks.ProcessCompletion(returncode=0) if self.checkout(args[3], create=True) else mocks.ProcessCompletion(returncode=1)
+            ), mocks.Subprocess.Route(
                 self.executable, 'checkout', re.compile(r'.+'),
                 cwd=self.path,
                 generator=lambda *args, **kwargs:
-                    mocks.ProcessCompletion(returncode=0) if self.checkout(args[2]) else mocks.ProcessCompletion(returncode=1)
+                    mocks.ProcessCompletion(returncode=0) if self.checkout(args[2], create=False) else mocks.ProcessCompletion(returncode=1)
             ), mocks.Subprocess.Route(
                 self.executable, 'filter-branch', '-f',
                 cwd=self.path,
@@ -381,6 +386,10 @@
                     returncode=0,
                 ),
             ), mocks.Subprocess.Route(
+                self.executable, 'check-ref-format', re.compile(r'.+'),
+                generator=lambda *args, **kwargs:
+                    mocks.ProcessCompletion(returncode=0) if re.match(r'^[A-Za-z0-9-]+/[A-Za-z0-9/-]+$', args[2]) else mocks.ProcessCompletion(),
+            ), mocks.Subprocess.Route(
                 self.executable,
                 cwd=self.path,
                 completion=mocks.ProcessCompletion(
@@ -473,8 +482,23 @@
                     result.add(branch)
         return result
 
-    def checkout(self, something):
+    def checkout(self, something, create=False):
         commit = self.find(something)
+        if create:
+            if commit:
+                return False
+            if self.head.branch == self.default_branch:
+                self.commits[something] = [self.head]
+            else:
+                self.commits[something] = [
+                    commit for commit in self.commits[self.head.branch]
+                    if not commit.branch_point or commit.identifier <= self.head.identifier
+                ]
+            self.commits[something][-1] = Commit.from_json(Commit.Encoder().default(self.head))
+            self.head = self.commits[something][-1]
+            self.head.branch = something
+            return True
+
         if commit:
             self.head = commit
             self.detached = something not in self.commits.keys()

Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py (281362 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py	2021-08-21 03:20:23 UTC (rev 281362)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -26,6 +26,7 @@
 import sys
 
 from .blame import Blame
+from .branch import Branch
 from .canonicalize import Canonicalize
 from .clean import Clean
 from .command import Command
@@ -65,7 +66,7 @@
 
     subparsers = parser.add_subparsers(help='sub-command help')
 
-    programs = [Blame, Canonicalize, Checkout, Clean, Find, Info, Log, Pull, Setup]
+    programs = [Branch, Blame, Canonicalize, Checkout, Clean, Find, Info, Log, Pull, Setup]
     if subversion:
         programs.append(SetupGitSvn)
 

Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py (0 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/branch.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -0,0 +1,78 @@
+# Copyright (C) 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 re
+import sys
+
+from .command import Command
+
+from webkitcorepy import run, Terminal
+from webkitscmpy import local, log
+
+
+class Branch(Command):
+    name = 'branch'
+    help = 'Create a local development branch from the current checkout state'
+
+    PREFIX = 'eng'
+
+    @classmethod
+    def parser(cls, parser, loggers=None):
+        parser.add_argument(
+            '-i', '--issue', '-b', '--bug', '-r',
+            dest='issue', type=str,
+            help='Number (or name) of the issue or bug to create branch for',
+        )
+
+    @classmethod
+    def normalize_issue(cls, issue):
+        if not issue or issue.startswith(cls.PREFIX):
+            return issue
+        return '{}/{}'.format(cls.PREFIX, issue)
+
+    @classmethod
+    def main(cls, args, repository, **kwargs):
+        if not isinstance(repository, local.Git):
+            sys.stderr.write("Can only 'branch' on a native Git repository\n")
+            return 1
+
+        if not args.issue:
+            args.issue = Terminal.input('Branch name: ')
+        args.issue = cls.normalize_issue(args.issue)
+
+        if run([repository.executable(), 'check-ref-format', args.issue], capture_output=True).returncode:
+            sys.stderr.write("'{}' is an invalid branch name, cannot create it\n".format(args.issue))
+            return 1
+
+        remote_re = re.compile('remotes/.+/{}'.format(re.escape(args.issue)))
+        for branch in repository.branches:
+            if branch == args.issue or remote_re.match(branch):
+                sys.stderr.write("'{}' already exists\n".format(args.issue))
+                return 1
+
+        log.warning("Creating the local development branch '{}'...".format(args.issue))
+        if run([repository.executable(), 'checkout', '-b', args.issue], cwd=repository.root_path).returncode:
+            sys.stderr.write("Failed to create '{}'\n".format(args.issue))
+            return 1
+        repository._branch = args.issue  # Assign the cache because of repository.branch's caching
+        print("Created the local development branch '{}'!".format(args.issue))
+        return 0

Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/branch_unittest.py (0 => 281363)


--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/branch_unittest.py	                        (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/branch_unittest.py	2021-08-21 05:25:07 UTC (rev 281363)
@@ -0,0 +1,73 @@
+# Copyright (C) 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 os
+import shutil
+import tempfile
+
+from datetime import datetime
+from webkitcorepy import OutputCapture, testing
+from webkitcorepy.mocks import Time as MockTime, Terminal as MockTerminal
+from webkitscmpy import local, program, mocks
+
+
+class TestBranch(testing.PathTestCase):
+    basepath = 'mock/repository'
+
+    def setUp(self):
+        super(TestBranch, self).setUp()
+        os.mkdir(os.path.join(self.path, '.git'))
+        os.mkdir(os.path.join(self.path, '.svn'))
+
+    def test_basic_svn(self):
+        with OutputCapture() as captured, mocks.local.Git(), mocks.local.Svn(self.path), MockTime:
+            self.assertEqual(1, program.main(
+                args=('branch', '-i', '1234'),
+                path=self.path,
+            ))
+        self.assertEqual(captured.stderr.getvalue(), "Can only 'branch' on a native Git repository\n")
+
+    def test_basic_git(self):
+        with OutputCapture() as captured, mocks.local.Git(self.path), mocks.local.Svn(), MockTime:
+            self.assertEqual(0, program.main(
+                args=('branch', '-i', '1234'),
+                path=self.path,
+            ))
+            self.assertEqual(local.Git(self.path).branch, 'eng/1234')
+        self.assertEqual(captured.root.log.getvalue(), "Creating the local development branch 'eng/1234'...\n")
+        self.assertEqual(captured.stdout.getvalue(), "Created the local development branch 'eng/1234'!\n")
+
+    def test_prompt_git(self):
+        with MockTerminal.input('eng/example'), OutputCapture() as captured, mocks.local.Git(self.path), mocks.local.Svn(), MockTime:
+            self.assertEqual(0, program.main(args=('branch',), path=self.path))
+            self.assertEqual(local.Git(self.path).branch, 'eng/example')
+        self.assertEqual(captured.root.log.getvalue(), "Creating the local development branch 'eng/example'...\n")
+        self.assertEqual(captured.stdout.getvalue(), "Branch name: \nCreated the local development branch 'eng/example'!\n")
+
+    def test_invalid_branch(self):
+        with OutputCapture() as captured, mocks.local.Git(self.path), mocks.local.Svn(), MockTime:
+            self.assertEqual(1, program.main(
+                args=('branch', '-i', 'reject_underscores'),
+                path=self.path,
+            ))
+        self.assertEqual(captured.stderr.getvalue(), "'eng/reject_underscores' is an invalid branch name, cannot create it\n")
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to