Diff
Modified: trunk/Tools/ChangeLog (280738 => 280739)
--- trunk/Tools/ChangeLog 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/ChangeLog 2021-08-06 22:16:34 UTC (rev 280739)
@@ -1,3 +1,46 @@
+2021-08-06 Jonathan Bedard <jbed...@apple.com>
+
+ [git-webkit] Add setup function
+ https://bugs.webkit.org/show_bug.cgi?id=225985
+ <rdar://problem/78226729>
+
+ Reviewed by Dewei Zhu.
+
+ * Scripts/libraries/webkitcorepy/setup.py: Bump version.
+ * Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py: Ditto.
+ * Scripts/libraries/webkitcorepy/webkitcorepy/credentials.py:
+ (credentials): Key should be pulled from environment variable with key_name in it.
+ * Scripts/libraries/webkitscmpy/setup.py: Bump version.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py: Ditto.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py:
+ (Git): Move config regexes.
+ (Git.__init__): Add `git remote add`, `git config` and `git fetch fork`.
+ (Git.config): Add user.email to default configuration.
+ (Git.edit_config): Modify configuration file.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/mocks/remote/git_hub.py:
+ (GitHub): Add list of forks.
+ (GitHub.__enter__): Correctly mock token.
+ (GitHub.request): Add fork check and fork addition.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py:
+ (main): Add setup function.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py:
+ (GitHub.credentials): Strip email domain, guide user on token permissions.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/program/setup.py: Added.
+ (Setup.github): Ensure that GitHub credentials are in the keychain.
+ (Setup.git): Set the user for the repository, along with merge strategy.
+ (Setup.parser):
+ (Setup.main):
+ * Scripts/libraries/webkitscmpy/webkitscmpy/test/git_unittest.py:
+ (test_config): Change user name.
+ (test_global_config): Ditto.
+ * Scripts/libraries/webkitscmpy/webkitscmpy/test/setup_unittest.py: Added.
+ (TestSetup):
+ (TestSetup.setUp):
+ (TestSetup.test_svn):
+ (TestSetup.test_github):
+ (TestSetup.test_git):
+ (TestSetup.test_github_checkout):
+
2021-08-06 Fujii Hironori <hironori.fu...@sony.com>
[Win][WebKitTestRunner] WTR::PlatformWebView leaks m_view (WKViewRef)
Modified: trunk/Tools/Scripts/libraries/webkitcorepy/setup.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitcorepy/setup.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/setup.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -30,7 +30,7 @@
setup(
name='webkitcorepy',
- version='0.8.0',
+ version='0.8.1',
description='Library containing various Python support classes and functions.',
long_description=readme(),
classifiers=[
Modified: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/__init__.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -40,7 +40,7 @@
from webkitcorepy.measure_time import MeasureTime
from webkitcorepy.nested_fuzzy_dict import NestedFuzzyDict
-version = Version(0, 8, 0)
+version = Version(0, 8, 1)
from webkitcorepy.autoinstall import Package, AutoInstall
if sys.version_info > (3, 0):
Modified: trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/credentials.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/credentials.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitcorepy/webkitcorepy/credentials.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -38,7 +38,7 @@
return _cache.get(name)
username = os.environ.get('{}_USERNAME'.format(name.upper()))
- key = os.environ.get('{}_{}'.format(name.upper(), name.upper()))
+ key = os.environ.get('{}_{}'.format(name.upper(), key_name.upper()))
if username and key:
_cache[name] = (username, key)
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/setup.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/setup.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/setup.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -29,7 +29,7 @@
setup(
name='webkitscmpy',
- version='1.0.6',
+ version='1.1.0',
description='Library designed to interact with git and svn repositories.',
long_description=readme(),
classifiers=[
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/__init__.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -46,7 +46,7 @@
"Please install webkitcorepy with `pip install webkitcorepy --extra-index-url <package index URL>`"
)
-version = Version(1, 0, 6)
+version = Version(1, 1, 0)
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 (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/local/git.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -35,6 +35,15 @@
class Git(mocks.Subprocess):
+ # Parse a .git/config that looks like this
+ # [core]
+ # repositoryformatversion = 0
+ # [branch "main"]
+ # remote = origin
+ # merge = refs/heads/main
+ RE_SINGLE_TOP = re.compile(r'^\[\s*(?P<key>\S+)\s*\]')
+ RE_MULTI_TOP = re.compile(r'^\[\s*(?P<keya>\S+) "(?P<keyb>\S+)"\s*\]')
+ RE_ELEMENT = re.compile(r'^\s+(?P<key>\S+)\s*=\s*(?P<value>\S+)')
def __init__(
self, path='/.invalid-git', datafile=None,
@@ -189,6 +198,12 @@
stderr="fatal: No such remote '{}'\n".format(args[3]),
),
), mocks.Subprocess.Route(
+ self.executable, 'remote', 'add', re.compile(r'.+'),
+ cwd=self.path,
+ completion=mocks.ProcessCompletion(
+ returncode=0,
+ ),
+ ), mocks.Subprocess.Route(
self.executable, 'branch', '-a',
cwd=self.path,
generator=lambda *args, **kwargs: mocks.ProcessCompletion(
@@ -355,6 +370,17 @@
stdout='\n'.join(['{}={}'.format(key, value) for key, value in Git.config().items()])
),
), mocks.Subprocess.Route(
+ self.executable, 'config', re.compile(r'.+'), re.compile(r'.+'),
+ cwd=self.path,
+ generator=lambda *args, **kwargs:
+ self.edit_config(args[2], args[3]),
+ ), mocks.Subprocess.Route(
+ self.executable, 'fetch', 'fork',
+ cwd=self.path,
+ completion=mocks.ProcessCompletion(
+ returncode=0,
+ ),
+ ), mocks.Subprocess.Route(
self.executable,
cwd=self.path,
completion=mocks.ProcessCompletion(
@@ -590,34 +616,50 @@
def config(context):
if isinstance(context, type):
return {
- 'user.name': 'tap...@webkit.org',
+ 'user.name': 'Tim Apple',
+ 'user.email': 'tap...@webkit.org',
'sendemail.transferencoding': 'base64',
}
- # Parse a .git/config that looks like this
- # [core]
- # repositoryformatversion = 0
- # [branch "main"]
- # remote = origin
- # merge = refs/heads/main
- RE_SINGLE_TOP = re.compile(r'^\[\s*(?P<key>\S+)\s*\]')
- RE_MULTI_TOP = re.compile(r'^\[\s*(?P<keya>\S+) "(?P<keyb>\S+)"\s*\]')
- RE_ELEMENT = re.compile(r'^\s+(?P<key>\S+)\s*=\s*(?P<value>\S+)')
-
top = None
result = Git.config()
with open(os.path.join(context.path, '.git', 'config'), 'r') as configfile:
for line in configfile.readlines():
- match = RE_MULTI_TOP.match(line)
+ match = context.RE_MULTI_TOP.match(line)
if match:
top = '{}.{}'.format(match.group('keya'), match.group('keyb'))
continue
- match = RE_SINGLE_TOP.match(line)
+ match = context.RE_SINGLE_TOP.match(line)
if match:
top = match.group('key')
continue
- match = RE_ELEMENT.match(line)
+ match = context.RE_ELEMENT.match(line)
if top and match:
result['{}.{}'.format(top, match.group('key'))] = match.group('value')
return result
+
+ def edit_config(self, key, value):
+ with open(os.path.join(self.path, '.git', 'config'), 'r') as configfile:
+ lines = [line for line in configfile.readlines()]
+
+ key_a = key.split('.')[0]
+ key_b = '.'.join(key.split('.')[1:])
+
+ did_print = False
+ with open(os.path.join(self.path, '.git', 'config'), 'w') as configfile:
+ for line in lines:
+ match = self.RE_ELEMENT.match(line)
+ if not match or match.group('key') != key_b:
+ configfile.write(line)
+ match = self.RE_MULTI_TOP.match(line)
+ if not match or '{}.{}'.format(match.group('keya'), match.group('keyb')) != key_a:
+ continue
+ configfile.write('\t{}={}\n'.format(key_b, value))
+ did_print = True
+
+ if not did_print:
+ configfile.write('[{}]\n'.format(key_a))
+ configfile.write('\t{}={}\n'.format(key_b, value))
+
+ return mocks.ProcessCompletion(returncode=0)
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/remote/git_hub.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/remote/git_hub.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/mocks/remote/git_hub.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -39,6 +39,7 @@
self.default_branch = default_branch
self.remote = remote
+ self.forks = []
hostname = self.remote.split('/')[0]
self.api_remote = 'api.{hostname}/repos/{repo}'.format(
hostname=hostname,
@@ -62,7 +63,7 @@
def __enter__(self):
prefix = self.remote.split('/')[0].replace('.', '_').upper()
username_key = '{}_USERNAME'.format(prefix)
- token_key = '{}_ACCESS_TOKEN'.format(prefix)
+ token_key = '{}_TOKEN'.format(prefix)
self._environment = {
username_key: os.environ.get(username_key),
token_key: os.environ.get(token_key),
@@ -315,4 +316,24 @@
if stripped_url.startswith('{}/tree/'.format(self.remote)):
return self._parents_of_request(url="" ref=stripped_url.split('/')[-1])
+ # Check for existance of forked repo
+ if stripped_url.startswith('{}/repos'.format(self.api_remote.split('/')[0])) and stripped_url.split('/')[-1] == self.remote.split('/')[-1]:
+ username = stripped_url.split('/')[-2]
+ if username in self.forks or username == self.remote.split('/')[-2]:
+ return mocks.Response.fromJson(dict(
+ owmer=dict(
+ login=username,
+ ), fork=username in self.forks,
+ name=stripped_url.split('/')[-1],
+ full_name='/'.join(stripped_url.split('/')[-2:]),
+ ), url=""
+ return mocks.Response.create404(url)
+
+ # Add fork
+ if stripped_url.startswith('{}/forks'.format(self.api_remote)) and method == 'POST':
+ username = kwargs.get('json', {}).get('owner', None)
+ if username:
+ self.forks.append(username)
+ return mocks.Response.fromJson({}) if username else mocks.Response.create404(url)
+
return mocks.Response.create404(url)
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/__init__.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -33,6 +33,7 @@
from .log import Log
from .pull import Pull
from .setup_git_svn import SetupGitSvn
+from .setup import Setup
from webkitcorepy import arguments, log as webkitcorepy_log
from webkitscmpy import local, log, remote
@@ -63,7 +64,7 @@
subparsers = parser.add_subparsers(help='sub-command help')
- programs = [Find, Info, Checkout, Canonicalize, Pull, Clean, Log, Blame]
+ programs = [Find, Info, Checkout, Canonicalize, Pull, Clean, Log, Blame, Setup]
if subversion:
programs.append(SetupGitSvn)
Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/setup.py (0 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/setup.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/program/setup.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -0,0 +1,213 @@
+# 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 requests
+import sys
+
+from .command import Command
+from requests.auth import HTTPBasicAuth
+from webkitcorepy import arguments, run, Terminal
+from webkitscmpy import log, local, remote
+
+
+class Setup(Command):
+ name = 'setup'
+ help = 'Configure local settings for the current repository'
+
+ @classmethod
+ def github(cls, args, repository, **kwargs):
+ log.warning('Saving GitHub credentials in system credential store...')
+ username, access_token = repository.credentials(required=True)
+ log.warning('GitHub credentials saved via Keyring!')
+
+ log.warning('Verifying user owned fork...')
+ auth = HTTPBasicAuth(username, access_token)
+ response = requests.get('{}/repos/{}/{}'.format(
+ repository.api_url,
+ username,
+ repository.name,
+ ), auth=auth, headers=dict(Accept='application/vnd.github.v3+json'))
+ if response.status_code == 200:
+ log.warning("User already owns a fork of '{}'!".format(repository.name))
+ return 0
+
+ if repository.owner == username or args.defaults or Terminal.choose(
+ "Create a private fork of '{}' belonging to '{}'".format(repository.name, username),
+ default='No',
+ ) == 'No':
+ log.warning("Continuing without forking '{}'".format(repository.name))
+ return 1
+
+ response = requests.post('{}/repos/{}/{}/forks'.format(
+ repository.api_url,
+ repository.owner,
+ repository.name,
+ ), json=dict(
+ owner=username,
+ description="{}'s fork of {}".format(username, repository.name),
+ private=True,
+ ), auth=auth, headers=dict(Accept='application/vnd.github.v3+json'))
+ if response.status_code not in (200, 202):
+ sys.stderr.write("Failed to create a fork of '{}' belonging to '{}'\n".format(repository.name, username))
+ return 1
+ log.warning("Created a private fork of '{}' belonging to '{}'!".format(repository.name, username))
+ return 0
+
+ @classmethod
+ def git(cls, args, repository, **kwargs):
+ global_config = local.Git.config()
+ result = 0
+
+ email = global_config.get('user.email')
+ log.warning('Setting git user email for {}...'.format(repository.root_path))
+ if not email or args.defaults is False or (not args.defaults and Terminal.choose(
+ "Set '{}' as the git user email".format(email),
+ default='Yes',
+ ) == 'No'):
+ email = Terminal.input('Git user email: ')
+
+ if run(
+ [local.Git.executable(), 'config', 'user.email', email], capture_output=True, cwd=repository.root_path,
+ ).returncode:
+ sys.stderr.write('Failed to set the git user email to {}\n'.format(email))
+ result += 1
+ else:
+ log.warning("Set git user email to '{}'".format(email))
+
+ name = repository.contributors.get(email)
+ if name:
+ name = name.name
+ else:
+ name = global_config.get('user.name')
+ log.warning('Setting git user name for {}...'.format(repository.root_path))
+ if not name or args.defaults is False or (not args.defaults and Terminal.choose(
+ "Set '{}' as the git user name".format(name),
+ default='Yes',
+ ) == 'No'):
+ name = Terminal.input('Git user name: ')
+ if run(
+ [local.Git.executable(), 'config', 'user.name', name], capture_output=True, cwd=repository.root_path,
+ ).returncode:
+ sys.stderr.write('Failed to set the git user name to {}\n'.format(name))
+ result += 1
+ else:
+ log.warning("Set git user name to '{}'".format(name))
+
+ log.warning('Setting better Objective-C diffing behavior...')
+ result += run(
+ [local.Git.executable(), 'config', 'diff.objcpp.xfuncname', '^[-+@a-zA-Z_].*$'],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+ result += run(
+ [local.Git.executable(), 'config', 'diff.objcppheader.xfuncname', '^[@a-zA-Z_].*$'],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+ log.warning('Set better Objective-C diffing behavior!')
+
+ if args.defaults or Terminal.choose(
+ 'Auto-color status, diff, and branch?'.format(email),
+ default='Yes',
+ ) == 'Yes':
+ for command in ('status', 'diff', 'branch'):
+ result += run(
+ [local.Git.executable(), 'config', 'color.{}'.format(command), 'auto'],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+
+ log.warning('Using {} merge strategy'.format('merge commits as a' if args.merge else 'a rebase'))
+ if run(
+ [local.Git.executable(), 'config', 'pull.rebase', 'false' if args.merge else 'true'],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode:
+ sys.stderr.write('Failed to use {} as the merge strategy\n'.format('merge commits' if args.merge else 'rebase'))
+ result += 1
+
+ # Only configure GitHub if the URL is a GitHub URL
+ rmt = repository.remote()
+ if not isinstance(rmt, remote.GitHub):
+ return result
+
+ code = cls.github(args, rmt, **kwargs)
+ result += code
+ if code:
+ return result
+
+ username, _ = rmt.credentials(required=True)
+ log.warning("Adding forked remote as '{}' and 'fork'...".format(username))
+ url = ""
+
+ if '://' in url:
+ fork_remote = '{}://{}/{}/{}.git'.format(url.split(':')[0], url.split('/')[2], username, rmt.name)
+ elif ':' in url:
+ fork_remote = '{}:{}/{}.git'.format(url.split(':')[0], username, rmt.name)
+ else:
+ return result + 1
+
+ available_remotes = []
+ for name in [username, 'fork']:
+ returncode = run(
+ [repository.executable(), 'remote', 'add', name, fork_remote],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+ if returncode == 3:
+ returncode = run(
+ [repository.executable(), 'remote', 'set-url', name, fork_remote],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+ if returncode:
+ sys.stderr.write("Failed to add remote '{}'\n".format(name))
+ result += 1
+ else:
+ available_remotes.append(name)
+ log.warning("Added remote '{}'".format(name))
+
+ if 'fork' not in available_remotes:
+ return result
+ log.warning("Fetching '{}'".format(fork_remote))
+ return run(
+ [repository.executable(), 'fetch', 'fork'],
+ capture_output=True, cwd=repository.root_path,
+ ).returncode
+
+ @classmethod
+ def parser(cls, parser, loggers=None):
+ parser.add_argument(
+ '--defaults', '--no-defaults', action="" default=None,
+ help='Do not prompt the user for defaults, always use (or do not use) them',
+ )
+ parser.add_argument(
+ '--merge', '--no-merge', action="" default=False,
+ help='Use a merge-commit workflow instead of a rebase workflow',
+ )
+
+ @classmethod
+ def main(cls, args, repository, **kwargs):
+ if isinstance(repository, local.Git):
+ return cls.git(args, repository, **kwargs)
+
+ if isinstance(repository, remote.GitHub):
+ return cls.github(args, repository, **kwargs)
+
+ sys.stderr.write('No setup required for {}\n'.format(
+ getattr(repository, 'root_path', getattr(repository, 'url', '?')),
+ ))
+ return 1
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/remote/git_hub.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -1,4 +1,4 @@
-# Copyright (C) 2020 Apple Inc. All rights reserved.
+# 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
@@ -63,13 +63,18 @@
)
def credentials(self, required=True):
- return credentials(
+ username, token = credentials(
url=""
required=required,
name=self.url.split('/')[2].replace('.', '_').upper(),
- prompt="GitHub's API\nPlease generate a 'Personal access token' via 'Developer settings' for your user",
+ prompt='''GitHub's API
+Please generate a 'Personal access token' via 'Developer settings' with 'repo' and 'workflow' access
+for your {} user'''.format(self.url.split('/')[2]),
key_name='token',
)
+ if username:
+ username = username.split('@')[0]
+ return username, token
@property
def is_git(self):
Modified: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/git_unittest.py (280738 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/git_unittest.py 2021-08-06 22:13:32 UTC (rev 280738)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/git_unittest.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -411,7 +411,7 @@
with mocks.local.Git(self.path, git_svn=True) as m:
repo = local.Git(self.path)
- self.assertEqual(repo.config()['user.name'], 'tap...@webkit.org')
+ self.assertEqual(repo.config()['user.name'], 'Tim Apple')
self.assertEqual(repo.config()['core.filemode'], 'true')
self.assertEqual(repo.config()['remote.origin.url'], 'g...@example.org:/mock/repository')
self.assertEqual(repo.config()['svn-remote.svn.url'], 'https://svn.example.org/repository/webkit')
@@ -419,7 +419,7 @@
def test_global_config(self):
with mocks.local.Git(self.path, git_svn=True), OutputCapture():
- self.assertEqual(local.Git.config()['user.name'], 'tap...@webkit.org')
+ self.assertEqual(local.Git.config()['user.name'], 'Tim Apple')
self.assertEqual(local.Git.config()['sendemail.transferencoding'], 'base64')
Added: trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/setup_unittest.py (0 => 280739)
--- trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/setup_unittest.py (rev 0)
+++ trunk/Tools/Scripts/libraries/webkitscmpy/webkitscmpy/test/setup_unittest.py 2021-08-06 22:16:34 UTC (rev 280739)
@@ -0,0 +1,137 @@
+# 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 os
+
+from webkitcorepy import OutputCapture, testing
+from webkitcorepy.mocks import Time as MockTime, Terminal as MockTerminal
+from webkitscmpy import program, mocks
+
+
+class TestSetup(testing.PathTestCase):
+ basepath = 'mock/repository'
+
+ def setUp(self):
+ super(TestSetup, self).setUp()
+ os.mkdir(os.path.join(self.path, '.git'))
+ os.mkdir(os.path.join(self.path, '.svn'))
+
+ def test_svn(self):
+ with OutputCapture() as captured, mocks.local.Git(), mocks.local.Svn(self.path):
+ self.assertEqual(1, program.main(
+ args=('setup',),
+ path=self.path,
+ ))
+ self.assertEqual(captured.stderr.getvalue(), 'No setup required for {}\n'.format(self.path))
+
+ def test_github(self):
+ with OutputCapture() as captured, MockTerminal.input('y'), mocks.remote.GitHub() as remote:
+ self.assertEqual(0, program.main(
+ args=('-C', 'https://{}'.format(remote.remote), 'setup'),
+ path=self.path,
+ ))
+
+ self.assertEqual(captured.stdout.getvalue(), "Create a private fork of 'WebKit' belonging to 'username' (Yes/No): \n")
+ self.assertEqual(captured.stderr.getvalue(), '')
+ self.assertEqual(
+ captured.root.log.getvalue(),
+ '''Saving GitHub credentials in system credential store...
+GitHub credentials saved via Keyring!
+Verifying user owned fork...
+Created a private fork of 'WebKit' belonging to 'username'!
+''',
+ )
+
+ def test_git(self):
+ with OutputCapture() as captured, mocks.local.Git(self.path) as repo, mocks.local.Svn():
+ self.assertEqual(0, program.main(
+ args=('setup', '--defaults'),
+ path=self.path,
+ ))
+
+ config = repo.config()
+ self.assertEqual('^[-+@a-zA-Z_].*$', config.get('diff.objcpp.xfuncname', ''))
+ self.assertEqual('^[@a-zA-Z_].*$', config.get('diff.objcppheader.xfuncname', ''))
+ self.assertEqual('auto', config.get('color.status', ''))
+ self.assertEqual('auto', config.get('color.diff', ''))
+ self.assertEqual('auto', config.get('color.branch', ''))
+ self.assertEqual('true', config.get('pull.rebase', ''))
+
+ self.assertEqual(captured.stdout.getvalue(), '')
+ self.assertEqual(captured.stderr.getvalue(), '')
+ self.assertEqual(
+ captured.root.log.getvalue(),
+ '''Setting git user email for {repository}...
+Set git user email to 'tap...@webkit.org'
+Setting git user name for {repository}...
+Set git user name to 'Tim Apple'
+Setting better Objective-C diffing behavior...
+Set better Objective-C diffing behavior!
+Using a rebase merge strategy
+'''.format(repository=self.path),
+ )
+
+ def test_github_checkout(self):
+ with OutputCapture() as captured, mocks.remote.GitHub() as remote, \
+ MockTerminal.input('n', 'commit...@webkit.org', 'n', 'Committer', 'n', 'y'), \
+ mocks.local.Git(self.path, remote='https://{}'.format(remote.remote)) as repo:
+
+ self.assertEqual(0, program.main(
+ args=('setup',),
+ path=self.path,
+ ))
+
+ config = repo.config()
+ self.assertNotIn('color.status', config)
+ self.assertEqual('Committer', config.get('user.name', ''))
+ self.assertEqual('commit...@webkit.org', config.get('user.email', ''))
+
+ self.assertEqual(
+ captured.stdout.getvalue(),
+ '''Set 'tap...@webkit.org' as the git user email (Yes/No):
+Git user email:
+Set 'Tim Apple' as the git user name (Yes/No):
+Git user name:
+Auto-color status, diff, and branch? (Yes/No):
+Create a private fork of 'WebKit' belonging to 'username' (Yes/No):
+''')
+ self.assertEqual(captured.stderr.getvalue(), '')
+ self.maxDiff = None
+ self.assertEqual(
+ captured.root.log.getvalue(),
+ '''Setting git user email for {repository}...
+Set git user email to 'commit...@webkit.org'
+Setting git user name for {repository}...
+Set git user name to 'Committer'
+Setting better Objective-C diffing behavior...
+Set better Objective-C diffing behavior!
+Using a rebase merge strategy
+Saving GitHub credentials in system credential store...
+GitHub credentials saved via Keyring!
+Verifying user owned fork...
+Created a private fork of 'WebKit' belonging to 'username'!
+Adding forked remote as 'username' and 'fork'...
+Added remote 'username'
+Added remote 'fork'
+Fetching 'https://github.example.com/username/WebKit.git'
+'''.format(repository=self.path),
+ )