Skip to content
This repository has been archived by the owner on Sep 23, 2023. It is now read-only.

Commit

Permalink
Allow patches to be updated
Browse files Browse the repository at this point in the history
Fixes #54
  • Loading branch information
edg2s committed Feb 28, 2022
1 parent d724828 commit d2422d3
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 9 deletions.
2 changes: 1 addition & 1 deletion delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
'<td data-label="Wiki" class="wiki"><a href="wikis/' . $wiki . '/w" title="' . $wiki . '">' . substr( $wiki, 0, 10 ) . '</a></td>' .
'<td data-label="Patches" class="patches">' . $patches . '</td>' .
'<td data-label="Linked tasks" class="linkedTasks">' . $linkedTasks . '</td>' .
'<td data-label="Time" class="date">' . date( 'Y-m-d H:i:s', $wikiData[ 'created' ] ) . '</td>' .
'<td data-label="Time" class="date">' . date( 'Y-m-d H:i:s', $wikiData[ 'updated' ] ) . '</td>' .
( $useOAuth ? '<td data-label="Creator">' . ( $creator ? user_link( $creator ) : '?' ) . '</td>' : '' ) .
'</tr>' .
'</table>';
Expand Down
2 changes: 1 addition & 1 deletion editcounts.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
],
];

$results = $mysqli->query( 'SELECT wiki FROM wikis WHERE !deleted ORDER BY created DESC' );
$results = $mysqli->query( 'SELECT wiki FROM wikis WHERE !deleted ORDER BY updated DESC' );
if ( !$results ) {
die( $mysqli->error );
}
Expand Down
16 changes: 12 additions & 4 deletions includes.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,21 @@ function insert_wiki_data( string $wiki, string $creator, int $created, string $
global $mysqli;
$stmt = $mysqli->prepare( '
INSERT INTO wikis
(wiki, creator, created, branch)
VALUES(?, ?, FROM_UNIXTIME(?), ?)
(wiki, creator, created, updated, branch)
VALUES(?, ?, FROM_UNIXTIME(?), FROM_UNIXTIME(?), ?)
' );
if ( !$stmt ) {
echo $mysqli->error;
}
$stmt->bind_param( 'ssis', $wiki, $creator, $created, $branch );
$stmt->bind_param( 'ssis', $wiki, $creator, $created, $created, $branch );
$stmt->execute();
$stmt->close();
}

function wiki_update_timestamp( string $wiki ) {
global $mysqli;
$stmt = $mysqli->prepare( 'UPDATE wikis SET updated = NOW() WHERE wiki = ?' );
$stmt->bind_param( 's', $wiki );
$stmt->execute();
$stmt->close();
}
Expand Down Expand Up @@ -77,7 +85,7 @@ function get_wiki_data( string $wiki ): array {
global $mysqli;

$stmt = $mysqli->prepare( '
SELECT wiki, creator, UNIX_TIMESTAMP( created ) created, patches, branch, announcedTasks, timeToCreate, deleted
SELECT wiki, creator, UNIX_TIMESTAMP( created ) created, UNIX_TIMESTAMP( updated ) updated, patches, branch, announcedTasks, timeToCreate, deleted
FROM wikis WHERE wiki = ?
' );
if ( !$stmt ) {
Expand Down
7 changes: 4 additions & 3 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@
$username = $user ? $user->username : null;

$stmt = $mysqli->prepare( '
SELECT wiki, creator, UNIX_TIMESTAMP( created ) created, patches, branch, announcedTasks, timeToCreate, deleted
SELECT wiki, creator, UNIX_TIMESTAMP( updated ) updated, patches, branch, announcedTasks, timeToCreate, deleted
FROM wikis
WHERE !deleted
ORDER BY IF( creator = ?, 1, 0 ) DESC, created DESC
ORDER BY IF( creator = ?, 1, 0 ) DESC, updated DESC
' );
if ( !$stmt ) {
die( $mysqli->error );
Expand Down Expand Up @@ -330,6 +330,7 @@

$actions = [];
if ( $canDelete ) {
$actions[] = '<a href="update.php?wiki=' . $wiki . '">Update</a>';
$actions[] = '<a href="delete.php?wiki=' . $wiki . '">Delete</a>';
}
if ( $canCreate ) {
Expand All @@ -346,7 +347,7 @@
'</td>' .
'<td data-label="Patches" class="patches">' . $patches . '</td>' .
'<td data-label="Linked tasks" class="linkedTasks">' . $linkedTasks . '</td>' .
'<td data-label="Time" class="date">' . date( 'Y-m-d H:i:s', $wikiData[ 'created' ] ) . '</td>' .
'<td data-label="Time" class="date">' . date( 'Y-m-d H:i:s', $wikiData[ 'updated' ] ) . '</td>' .
( $useOAuth ? '<td data-label="Creator">' . ( $creator ? user_link( $creator ) : '?' ) . '</td>' : '' ) .
( $canAdmin ? '<td data-label="Time to create">' . ( $wikiData['timeToCreate'] ? $wikiData['timeToCreate'] . 's' : '' ) . '</td>' : '' ) .
( count( $actions ) ?
Expand Down
3 changes: 3 additions & 0 deletions new/applypatch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ set -ex

cd $PATCHDEMO/wikis/$NAME/$REPO

# Required when updating an existing wiki
git reset --hard origin/master

git fetch origin $REF

# Apply $HASH and its parent commits up to $BASE on top of current HEAD.
Expand Down
6 changes: 6 additions & 0 deletions sql/patchdemo.sql
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ ALTER TABLE `tasks`

ALTER TABLE `wikis`
ADD COLUMN IF NOT EXISTS `branch` VARCHAR(64) NOT NULL AFTER `patches`;

ALTER TABLE `wikis`
ADD COLUMN `updated` DATETIME NOT NULL AFTER `created`,
ADD INDEX `updated` (`updated`);

UPDATE wikis SET updated = created;
190 changes: 190 additions & 0 deletions update.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
<?php

use Symfony\Component\Yaml\Yaml;

require_once "includes.php";

include "header.php";

ob_implicit_flush( true );

if ( $useOAuth && !$user ) {
echo oauth_signin_prompt();
die();
}

$wiki = $_GET['wiki'];
$wikiData = get_wiki_data( $wiki );

if ( !can_delete( $wikiData['creator'] ) ) {
die( '<p>You are not allowed to update this wiki.</p>' );
}

function abandon( string $errHtml ) {
die( $errHtml );
}

echo '<p>Updating wiki <a class="wiki" href="wikis/' . $wiki . '/w" title="' . $wiki . '">' . $wiki . '</a>.</p>';

echo '<div class="consoleLog">';

$patchesApplied = [];
$patchesToUpdate = [];
$linkedTasks = [];
$commands = [];
$usedRepos = [];

foreach ( $wikiData['patchList'] as $patch => $patchData ) {
$r = $patchData['r'];
$data = gerrit_query( "changes/?q=change:$r&o=LABELS&o=CURRENT_REVISION", true );

// get the info
$repo = $data[0]['project'];
$base = 'origin/' . $data[0]['branch'];
$revision = $data[0]['current_revision'];
$ref = $data[0]['revisions'][$revision]['ref'];
$id = $data[0]['id'];

$repos = get_repo_data();
if ( !isset( $repos[ $repo ] ) ) {
$repo = htmlentities( $repo );
abandon( "Repository <em>$repo</em> not supported" );
}
$path = $repos[ $repo ];
$usedRepos[] = $repo;

if (
$config[ 'requireVerified' ] &&
( $data[0]['labels']['Verified']['approved']['_account_id'] ?? null ) !== 75
) {
// The patch doesn't have V+2, check if the uploader is trusted
$uploaderId = $data[0]['revisions'][$revision]['uploader']['_account_id'];
$uploader = gerrit_query( 'accounts/' . $uploaderId, true );
if ( !is_trusted_user( $uploader['email'] ) ) {
abandon( "Patch must be approved (Verified+2) by jenkins-bot, or uploaded by a trusted user" );
}
}

$patch = $data[0]['_number'] . ',' . $data[0]['revisions'][$revision]['_number'];
$patchesApplied[] = $patch;

$r = $patchData['r'];
$pOld = (int)$patchData['p'];
$pNew = $data[0]['revisions'][$revision]['_number'];
if ( $pNew > $pOld ) {
echo "<strong>Updating change $r from patchset $pOld to $pNew.</strong>";
} else {
echo "<strong>Change $r is already using the latest patchset ($pOld).</strong>";
continue;
}

$patchesToUpdate[] = $patch;

$commands[] = [
[
'REPO' => $path,
'REF' => $ref,
'BASE' => $base,
'HASH' => $revision,
],
__DIR__ . '/new/applypatch.sh'
];

$relatedChanges = [];
$relatedChanges[] = [ $data[0]['_number'], $data[0]['revisions'][$revision]['_number'] ];

// Look at all commits in this patch's tree for cross-repo dependencies to add
$data = gerrit_query( "changes/$id/revisions/$revision/related", true );
// Ancestor commits only, not descendants
$foundCurr = false;
foreach ( $data['changes'] as $change ) {
if ( $foundCurr ) {
// Querying by change number is allegedly deprecated, but the /related API doesn't return the 'id'
$relatedChanges[] = [ $change['_change_number'], $change['_revision_number'] ];
}
$foundCurr = $foundCurr || $change['commit']['commit'] === $revision;
}

foreach ( $relatedChanges as [ $c, $r ] ) {
$data = gerrit_query( "changes/$c/revisions/$r/commit", true );

preg_match_all( '/^Depends-On: (.+)$/m', $data['message'], $m );
foreach ( $m[1] as $changeid ) {
if ( !in_array( $changeid, $patches, true ) ) {
// The entry we add here will be processed by the topmost foreach
$patches[] = $changeid;
}
}
}
}
$usedRepos = array_unique( $usedRepos );

$baseEnv = [
'PATCHDEMO' => __DIR__,
'NAME' => $wiki,
];

if ( !count( $commands ) ) {
abandon( 'No patches to update.' );
}

$error = shell_echo( __DIR__ . '/new/unlink.sh', $baseEnv );
if ( $error ) {
abandon( "Could not un-duplicate wiki." );
}

foreach ( $commands as $i => $command ) {
$error = shell_echo( $command[1], $baseEnv + $command[0] );
if ( $error ) {
abandon( "Could not apply patch {$patchesToUpdate[$i]}" );
}
}

$composerInstallRepos = Yaml::parse( file_get_contents( __DIR__ . '/repository-lists/composerinstall.yaml' ) );
foreach ( $usedRepos as $repo ) {
if ( in_array( $repo, $composerInstallRepos, true ) ) {
$error = shell_echo( __DIR__ . '/new/composerinstall.sh',
$baseEnv + [
// Variable used by composer itself, not our script
'COMPOSER_HOME' => __DIR__ . '/composer',
'REPO_TARGET' => $repos[$repo],
]
);
if ( $error ) {
abandon( "Could not fetch dependencies for <em>$repo</em>" );
}
}
}

$mainPage = "\n\nThis wiki was updated on ~~~~~ with the following newer patches:";
foreach ( $patchesToUpdate as $patch ) {
preg_match( '`([0-9]+),([0-9]+)`', $patch, $matches );
list( $t, $r, $p ) = $matches;

$data = gerrit_query( "changes/$r/revisions/$p/commit", true );
if ( $data ) {
$t = $t . ': ' . $data[ 'subject' ];
get_linked_tasks( $data['message'], $linkedTasks );
}

$t = htmlentities( $t );

$mainPage .= "\n:* [{$config['gerritUrl']}/r/c/$r/$p <nowiki>$t</nowiki>]";
}

$error = shell_echo( __DIR__ . '/new/postupdate.sh',
$baseEnv + [
'MAINPAGE' => $mainPage,
]
);
if ( $error ) {
abandon( "Could not update wiki content" );
}

// Update DB record with _all_ patches applied (include those which weren't updated)
wiki_add_patches( $wiki, $patchesApplied );
wiki_update_timestamp( $wiki );

echo "Done!";

echo '</div>';

0 comments on commit d2422d3

Please sign in to comment.