Changeset 287115 in webkit


Ignore:
Timestamp:
Dec 15, 2021, 4:51:44 PM (4 years ago)
Author:
Jonathan Bedard
Message:

[reporelaypy] Forward branches to alternate remote
https://bugs.webkit.org/show_bug.cgi?id=234347
<rdar://problem/86526293>

Reviewed by Dewei Zhu.

  • Tools/Scripts/libraries/reporelaypy/reporelaypy/init.py: Bump version.
  • Tools/Scripts/libraries/reporelaypy/reporelaypy/checkout.py:

(Checkout.Encoder.default): Add remotes.
(Checkout.clone): After cloning a repository, add required remotes.
(Checkout.add_remotes): Track remotes in repository.
(Checkout.init): Allow caller to specify set of remotes to be tracked.
(Checkout.push_update): Push update for specified remote.
(Checkout.update_for): Return 'True' and 'False.'
(Checkout.update_all): If a branch is being updated, we should forward that
update to any tracked remotes.

  • Tools/Scripts/libraries/reporelaypy/reporelaypy/hooks.py:

(HookProcessor.process_worker_hook): After updating a branch, forward that
update to any tracked remotes.

  • Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkout_unittest.py:

(CheckoutUnittest.test_constructor_no_sentinal): Capture debug logging.

  • Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkoutroute_unittest.py:

(CheckoutRouteUnittest.test_landing): Capture debug logging.
(CheckoutRouteUnittest.test_invoked_redirect): Ditto.
(CheckoutRouteUnittest.test_trac): Ditto.

  • Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/hooks_unittest.py:

(HooksUnittest.test_process): Test for any error logging.
(HooksUnittest.test_process_branch): Ditto.

  • Tools/Scripts/libraries/reporelaypy/run: Allow caller to specify remote to be tracked.
  • Tools/Scripts/libraries/reporelaypy/setup.py: Bump version.

Canonical link: https://commits.webkit.org/245300@main

Location:
trunk/Tools
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r287105 r287115  
     12021-12-15  Jonathan Bedard  <jbedard@apple.com>
     2
     3        [reporelaypy] Forward branches to alternate remote
     4        https://bugs.webkit.org/show_bug.cgi?id=234347
     5        <rdar://problem/86526293>
     6
     7        Reviewed by Dewei Zhu.
     8
     9        * Scripts/libraries/reporelaypy/reporelaypy/__init__.py: Bump version.
     10        * Scripts/libraries/reporelaypy/reporelaypy/checkout.py:
     11        (Checkout.Encoder.default): Add remotes.
     12        (Checkout.clone): After cloning a repository, add required remotes.
     13        (Checkout.add_remotes): Track remotes in repository.
     14        (Checkout.__init__): Allow caller to specify set of remotes to be tracked.
     15        (Checkout.push_update): Push update for specified remote.
     16        (Checkout.update_for): Return 'True' and 'False.'
     17        (Checkout.update_all): If a branch is being updated, we should forward that
     18        update to any tracked remotes.
     19        * Scripts/libraries/reporelaypy/reporelaypy/hooks.py:
     20        (HookProcessor.process_worker_hook): After updating a branch, forward that
     21        update to any tracked remotes.
     22        * Scripts/libraries/reporelaypy/reporelaypy/tests/checkout_unittest.py:
     23        (CheckoutUnittest.test_constructor_no_sentinal): Capture debug logging.
     24        * Scripts/libraries/reporelaypy/reporelaypy/tests/checkoutroute_unittest.py:
     25        (CheckoutRouteUnittest.test_landing): Capture debug logging.
     26        (CheckoutRouteUnittest.test_invoked_redirect): Ditto.
     27        (CheckoutRouteUnittest.test_trac): Ditto.
     28        * Scripts/libraries/reporelaypy/reporelaypy/tests/hooks_unittest.py:
     29        (HooksUnittest.test_process): Test for any error logging.
     30        (HooksUnittest.test_process_branch): Ditto.
     31        * Scripts/libraries/reporelaypy/run: Allow caller to specify remote to be tracked.
     32        * Scripts/libraries/reporelaypy/setup.py: Bump version.
     33
    1342021-12-15  Don Olmstead  <don.olmstead@sony.com>
    235
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/__init__.py

    r287054 r287115  
    4545    )
    4646
    47 version = Version(0, 3, 1)
     47version = Version(0, 4, 0)
    4848
    4949import webkitflaskpy
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/checkout.py

    r287054 r287115  
    4848                url=obj.url,
    4949                sentinal=obj.sentinal,
     50                remotes=obj.remotes,
    5051            )
    5152            if obj.fallback_repository:
     
    6162
    6263    @staticmethod
    63     def clone(url, path, sentinal_file=None):
     64    def clone(url, path, remotes, sentinal_file=None):
    6465        run([local.Git.executable(), 'clone', url, path], cwd=os.path.dirname(path))
    6566        run([local.Git.executable(), 'config', 'pull.ff', 'only'], cwd=path)
     67
     68        Checkout.add_remotes(local.Git(path), remotes)
    6669
    6770        if sentinal_file:
     
    7073        return 0
    7174
    72     def __init__(self, path, url=None, http_proxy=None, sentinal=True, fallback_url=None, primary=True):
     75    @staticmethod
     76    def add_remotes(repository, remotes):
     77        for name, url in (remotes or {}).items():
     78            run([repository.executable(), 'remote', 'add', name, url], cwd=repository.root_path)
     79
     80    def __init__(self, path, url=None, http_proxy=None, sentinal=True, fallback_url=None, primary=True, remotes=None):
    7381        self.sentinal = sentinal
    7482        self.path = path
    7583        self.url = url
     84        self.remotes = remotes or dict()
    7685        self._repository = None
    7786        self._child_process = None
     
    100109                        self.url, self.repository.url(name='origin'),
    101110                    ))
     111                if primary:
     112                    Checkout.add_remotes(self.repository, remotes)
    102113                return
    103114        except FileNotFoundError:
     
    118129            self._child_process = multiprocessing.Process(
    119130                target=self.clone,
    120                 args=(self.url, path, self.sentinal_file),
     131                args=(self.url, path, self.remotes, self.sentinal_file),
    121132            )
    122133            self._child_process.start()
    123134        else:
    124             self.clone(self.url, path)
     135            self.clone(self.url, path, self.remotes)
    125136
    126137    @property
     
    165176        return False
    166177
     178    def push_update(self, branch=None, remote=None, track=False):
     179        if not remote or remote in ('origin', 'fork'):
     180            return False
     181
     182        branch = branch or self.repository.default_branch
     183        if not track and self.is_updated(branch, remote=remote):
     184            return False
     185
     186        return not run(
     187            [self.repository.executable(), 'push', remote, branch, '-f'],
     188            cwd=self.repository.root_path,
     189        ).returncode
     190
    167191    def update_for(self, branch=None, remote='origin', track=False):
    168192        if not self.repository:
    169193            sys.stderr.write("Cannot update '{}', clone still pending...\n".format(branch))
    170             return None
     194            return False
    171195
    172196        branch = branch or self.repository.default_branch
     
    178202            return False
    179203        elif track and branch not in self.repository.branches_for(remote=remote):
     204            run([self.repository.executable(), 'fetch'], cwd=self.repository.root_path)
    180205            run(
    181206                [self.repository.executable(), 'branch', '--track', branch, 'remotes/{}/{}'.format(remote, branch)],
     
    207232                all_branches.remove(branch)
    208233            self.update_for(branch=branch, remote=remote)
     234            [self.push_update(branch=branch, remote=remote) for remote in self.remotes.keys()]
    209235
    210236        # Then, track all untracked branches
     
    214240                cwd=self.repository.root_path,
    215241            )
     242            [self.push_update(branch=branch, remote=remote) for remote in self.remotes.keys()]
    216243            self.repository.cache.populate(branch=branch)
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/hooks.py

    r287045 r287115  
    2424import hmac
    2525import json
     26import sys
    2627
    2728from flask import current_app, json as fjson, request
     
    6768                    branch = branch[len('refs/heads/'):]
    6869                self.checkout.update_for(branch, track=True)
     70                [self.checkout.push_update(branch=branch, remote=remote, track=True) for remote in self.checkout.remotes.keys()]
    6971            except BaseException as e:
    7072                sys.stderr.write('{}\n'.format(e))
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkout_unittest.py

    r286576 r287115  
    4343
    4444    def test_constructor_no_sentinal(self):
    45         with mocks.local.Git(self.path) as repo:
     45        with mocks.local.Git(self.path) as repo, OutputCapture():
    4646            Checkout(path=self.path, url=repo.remote, sentinal=False)
    4747
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/checkoutroute_unittest.py

    r286576 r287115  
    108108    @mock_app
    109109    def test_landing(self, app=None, client=None):
    110         with mocks.local.Git(self.path) as repo:
     110        with mocks.local.Git(self.path) as repo, OutputCapture():
    111111            app.register_blueprint(CheckoutRoute(
    112112                Checkout(path=self.path, url=repo.remote, sentinal=False),
     
    148148    @mock_app
    149149    def test_invoked_redirect(self, app=None, client=None):
    150         with mocks.local.Git(self.path, git_svn=True) as repo:
     150        with mocks.local.Git(self.path, git_svn=True) as repo, OutputCapture():
    151151            app.register_blueprint(CheckoutRoute(
    152152                Checkout(path=self.path, url=repo.remote, sentinal=False),
     
    163163    @mock_app
    164164    def test_trac(self, app=None, client=None):
    165         with mocks.local.Git(self.path, git_svn=True) as repo:
     165        with mocks.local.Git(self.path, git_svn=True) as repo, OutputCapture():
    166166            app.register_blueprint(CheckoutRoute(
    167167                Checkout(path=self.path, url=repo.remote, sentinal=False),
  • trunk/Tools/Scripts/libraries/reporelaypy/reporelaypy/tests/hooks_unittest.py

    r287045 r287115  
    7272    @mock_app
    7373    def test_process(self, app=None, client=None):
    74         with OutputCapture(), mocks.local.Git(self.path) as repo:
     74        with OutputCapture() as captured, mocks.local.Git(self.path) as repo:
    7575            database = Database()
    7676            app.register_blueprint(HookReceiver(database=database, debug=True))
     
    8989            self.assertEqual(response.json(), [])
    9090
     91        self.assertEqual(captured.stderr.getvalue(), '')
     92
    9193    @mock_app
    9294    def test_process_branch(self, app=None, client=None):
    93         with OutputCapture(), mocks.local.Git(self.path) as repo:
     95        with OutputCapture() as captured, mocks.local.Git(self.path) as repo:
    9496            database = Database()
    9597            app.register_blueprint(HookReceiver(database=database, debug=True))
     
    107109            self.assertEqual(response.status_code, 200)
    108110            self.assertEqual(response.json(), [])
     111
     112        self.assertEqual(captured.stderr.getvalue(), '')
    109113
    110114    @mock_app
  • trunk/Tools/Scripts/libraries/reporelaypy/run

    r287045 r287115  
    7373        help='Fallback repository URL',
    7474    )
     75    group.add_argument(
     76        '--remote', dest='remotes', action='append',
     77        help="Add an additional remote to forward changes to, formatted as 'name:url'",
     78    )
    7579
    7680    group = parser.add_argument_group('Database')
     
    125129    print('Connected to database!')
    126130
     131    remotes = {}
     132    for pair in args.remotes:
     133        name, remote = pair.split(':', 1)
     134        if not remote:
     135            sys.stderr("Invalid forwarding remote '{}'".format(pair))
     136            return 1
     137        remotes[name] = remote
     138
    127139    print('Finding checkout...')
    128140    checkout = Checkout(
     
    132144        sentinal=args.sentinal,
    133145        fallback_url=args.fallback,
     146        remotes=remotes,
    134147    )
    135148    print('Git checkout:')
     
    144157        print('    Polling checkout with interval of {} seconds, doing first poll now...'.format(args.update_interval))
    145158        checkout.update_all()
     159    if remotes:
     160        print('Forwarding updates to:')
     161        for name, url in remotes.items():
     162            print('    {}: {}'.format(name, url))
    146163
    147164    if args.redirector:
  • trunk/Tools/Scripts/libraries/reporelaypy/setup.py

    r287054 r287115  
    3131setup(
    3232    name='reporelaypy',
    33     version='0.3.1',
     33    version='0.4.0',
    3434    description='Library for visualizing, processing and storing test results.',
    3535    long_description=readme(),
Note: See TracChangeset for help on using the changeset viewer.