33
0
mirror of https://github.com/joomla-extensions/patchtester.git synced 2024-12-23 03:19:00 +00:00

[4.0] Patch tester enhancement for joomla4 (pre-compiled diff) (#227)

[4.0] Patch tester enhancement for joomla4 (pre-compiled diff)
This commit is contained in:
Hannes Papenberg 2019-10-17 18:37:40 +02:00 committed by GitHub
commit f96dfdb9a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 991 additions and 306 deletions

View File

@ -42,43 +42,61 @@ class ResetController extends AbstractController
$testsModel = new TestsModel(null, Factory::getDbo());
// Check the applied patches in the database first
$appliedPatches = $testsModel->getAppliedPatches();
$appliedPatches = $pullModel->getPatchesDividedInProcs();
if (count($appliedPatches))
if (count($appliedPatches['git']))
{
$revertErrored = false;
// Let's try to cleanly revert all applied patches
foreach ($appliedPatches as $patch)
foreach ($appliedPatches['git'] as $patch)
{
try
{
$pullModel->revert($patch->id);
$pullModel->revertWithGitHub($patch->id);
}
catch (\RuntimeException $e)
{
$revertErrored = true;
}
}
}
// If we errored out reverting patches, we'll need to truncate the table
if ($revertErrored)
if (count($appliedPatches['ci']))
{
$revertErrored = false;
// Let's try to cleanly revert all applied patches with ci
foreach ($appliedPatches['ci'] as $patch)
{
try
{
$testsModel->truncateTable();
$pullModel->revertWithCIServer($patch->insert_id);
}
catch (\RuntimeException $e)
{
$hasErrors = true;
$this->getApplication()->enqueueMessage(
Text::sprintf('COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE', $e->getMessage()), 'error'
);
$revertErrored = true;
}
}
}
// If we errored out reverting patches, we'll need to truncate the table
if ($revertErrored)
{
try
{
$testsModel->truncateTable();
}
catch (\RuntimeException $e)
{
$hasErrors = true;
$this->getApplication()->enqueueMessage(
Text::sprintf('COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE', $e->getMessage()), 'error'
);
}
}
// Now truncate the pulls table
try
{

View File

@ -62,4 +62,34 @@ abstract class Helper
return new GitHub($options);
}
/**
* Initializes the CI Settings
*
* @return Registry
*
* @since 3.0
*/
public static function initializeCISettings()
{
$params = ComponentHelper::getParams('com_patchtester');
$options = new Registry;
// Set CI server address for the request
$options->set('server.url', $params->get('ci_server', 'https://ci.joomla.org:444'));
// Set name of the zip archive
$options->set('zip.name', 'build.zip');
$options->set('zip.log.name', 'deleted_files.log');
// Set temp archive for extracting and downloading files
$options->set('folder.temp', Factory::getConfig()->get('tmp_path'));
$options->set('folder.backups', JPATH_COMPONENT . '/backups');
// Set full url for addressing the file
$options->set('zip.url', $options->get('server.url') . '/artifacts/joomla/joomla-cms/4.0-dev/%s/patchtester/' . $options->get('zip.name'));
return $options;
}
}

View File

@ -8,12 +8,17 @@
namespace PatchTester\Model;
use Joomla\Archive\Zip;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Filesystem\Path;
use Joomla\CMS\Http\Response;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Version;
use Joomla\Filesystem\File;
use Joomla\Filesystem\Folder;
use PatchTester\GitHub\Exception\UnexpectedResponse;
use PatchTester\GitHub\GitHub;
use PatchTester\Helper;
/**
@ -134,6 +139,193 @@ class PullModel extends AbstractModel
return $parsedFiles;
}
/**
* Patches the code with the supplied pull request
* However uses different methods for different repositories.
*
* @param integer $id ID of the pull request to apply
*
* @return boolean
*
* @since 3.0
*
* @throws \RuntimeException
*/
public function apply($id)
{
$params = ComponentHelper::getParams('com_patchtester');
// Decide based on repository settings whether patch will be applied through Github or CIServer
if (version_compare(JVERSION, "4", "ge") && (bool) $params->get('ci_switch', 1))
{
return $this->applyWithCIServer($id);
}
else
{
return $this->applyWithGitHub($id);
}
}
/**
* Patches the code with the supplied pull request
*
* @param integer $id ID of the pull request to apply
*
* @return boolean
*
* @since 3.0
*
* @throws \RuntimeException
*/
private function applyWithCIServer($id)
{
// Get the CIServer Registry
$ciSettings = Helper::initializeCISettings();
// Get the Github object
$github = Helper::initializeGithub();
// Retrieve pullData for sha later on.
try
{
$pull = $this->retrieveGitHubData($github, $id);
$sha = $pull->head->sha;
}
catch (\RuntimeException $e)
{
// Catch the Exception and continue, because the hash is not that
// necessary for applying patches
$sha = "Error:429";
}
// Create tmp folder if it does not exist
if (!file_exists($ciSettings->get('folder.temp')))
{
Folder::create($ciSettings->get('folder.temp'));
}
$tempPath = $ciSettings->get('folder.temp') . "/$id";
$backupsPath = $ciSettings->get('folder.backups') . "/$id";
$delLogPath = $tempPath . '/' . $ciSettings->get('zip.log.name');
$zipPath = $tempPath . '/' . $ciSettings->get('zip.name');
$serverZipPath = sprintf($ciSettings->get('zip.url'), $id);
// Patch has already been applied
if (file_exists($backupsPath))
{
return false;
}
// Check if zip folder exists on server
$serverHeaders = @get_headers($serverZipPath);
if (!$serverHeaders || $serverHeaders[0] != 'HTTP/1.1 200 OK')
{
throw new \RuntimeException(Text::_('COM_PATCHTESTER_SERVER_RESPONDED_NOT_200'));
}
Folder::create($tempPath);
file_put_contents($zipPath, fopen($serverZipPath, "r"));
// Check if zip folder could have been downloaded
if (!file_exists($zipPath))
{
Folder::delete($tempPath);
throw new \RuntimeException(Text::_('COM_PATCHTESTER_ZIP_DOES_NOT_EXIST'));
}
$zip = new Zip;
if (!$zip->extract($zipPath, $tempPath))
{
Folder::delete($tempPath);
throw new \RuntimeException(Text::_('COM_PATCHTESTER_ZIP_EXTRACT_FAILED'));
}
// Remove zip to avoid get listing afterwards
File::delete($zipPath);
// Get files from deleted_logs
$deletedFiles = (file($delLogPath) ? file($delLogPath) : array());
$deletedFiles = array_map('trim', $deletedFiles);
if (file_exists($delLogPath))
{
// Remove deleted_logs to avoid get listing afterwards
File::delete($delLogPath);
}
// Retrieve all files and merge them into one array
$files = Folder::files($tempPath, null, true, true);
$files = str_replace(Path::clean("$tempPath\\"), '', $files);
$files = array_merge($files, $deletedFiles);
Folder::create($backupsPath);
// Moves existent files to backup and replace them or creates new one if they don't exist
foreach ($files as $key => $file)
{
try
{
$filePath = explode("\\", Path::clean($file));
array_pop($filePath);
$filePath = implode("\\", $filePath);
// Deleted_logs returns files as well as folder, if value is folder, unset and skip
if (is_dir(JPATH_ROOT . "/$file"))
{
unset($files[$key]);
continue;
}
if (file_exists(JPATH_ROOT . "/$file"))
{
// Create directories if they don't exist until file
if (!file_exists("$backupsPath/$filePath"))
{
Folder::create("$backupsPath/$filePath");
}
File::move(JPATH_ROOT . "/$file", "$backupsPath/$file");
}
if (file_exists("$tempPath/$file"))
{
// Create directories if they don't exist until file
if (!file_exists(JPATH_ROOT . "/$filePath") || !is_dir(JPATH_ROOT . "/$filePath"))
{
Folder::create(JPATH_ROOT . "/$filePath");
}
File::copy("$tempPath/$file", JPATH_ROOT . "/$file");
}
}
catch (\RuntimeException $e)
{
Folder::delete($tempPath);
Folder::move($backupsPath, $backupsPath . "_failed");
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_FAILED_APPLYING_PATCH', $file, $e->getMessage()));
}
}
// Clear temp folder and store applied patch in database
Folder::delete($tempPath);
$lastInserted = $this->saveAppliedPatch($id, $files, $sha);
// Write or create patch chain for correct order of patching
$this->appendPatchChain($lastInserted, $id);
// Change the media version
$version = new Version;
$version->refreshMediaVersion();
return true;
}
/**
* Patches the code with the supplied pull request
*
@ -142,40 +334,15 @@ class PullModel extends AbstractModel
* @return boolean
*
* @since 2.0
*
* @throws \RuntimeException
*/
public function apply($id)
private function applyWithGitHub($id)
{
// Get the Github object
$github = Helper::initializeGithub();
try
{
$rateResponse = $github->getRateLimit();
$rate = json_decode($rateResponse->body);
}
catch (UnexpectedResponse $e)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB', $e->getMessage()), $e->getCode(), $e);
}
// If over the API limit, we can't build this list
if ($rate->resources->core->remaining == 0)
{
throw new \RuntimeException(
Text::sprintf('COM_PATCHTESTER_API_LIMIT_LIST', Factory::getDate($rate->resources->core->reset))
);
}
try
{
$pullResponse = $github->getPullRequest($this->getState()->get('github_user'), $this->getState()->get('github_repo'), $id);
$pull = json_decode($pullResponse->body);
}
catch (UnexpectedResponse $e)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB', $e->getMessage()), $e->getCode(), $e);
}
$pull = $this->retrieveGitHubData($github, $id);
if (is_null($pull->head->repo))
{
@ -199,6 +366,11 @@ class PullModel extends AbstractModel
$parsedFiles = $this->parseFileList($files);
if (!count($parsedFiles))
{
return false;
}
foreach ($parsedFiles as $file)
{
switch ($file->action)
@ -314,25 +486,7 @@ class PullModel extends AbstractModel
unset($file->body);
}
$record = (object) array(
'pull_id' => $pull->number,
'data' => json_encode($parsedFiles),
'patched_by' => Factory::getUser()->id,
'applied' => 1,
'applied_version' => JVERSION,
);
$db = $this->getDb();
$db->insertObject('#__patchtester_tests', $record);
// Insert the retrieved commit SHA into the pulls table for this item
$db->setQuery(
$db->getQuery(true)
->update('#__patchtester_pulls')
->set('sha = ' . $db->quote($pull->head->sha))
->where($db->quoteName('pull_id') . ' = ' . (int) $id)
)->execute();
$this->saveAppliedPatch($pull->number, $parsedFiles, $pull->head->sha);
// Change the media version
$version = new Version;
@ -341,8 +495,215 @@ class PullModel extends AbstractModel
return true;
}
/**
* Patches the code with the supplied pull request
*
* @param GitHub $github github object
* @param integer $id Id of the pull request
*
* @return Response
*
* @since 2.0
*
* @throws \RuntimeException
*/
private function retrieveGitHubData($github, $id)
{
try
{
$rateResponse = $github->getRateLimit();
$rate = json_decode($rateResponse->body);
}
catch (UnexpectedResponse $e)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB', $e->getMessage()), $e->getCode(), $e);
}
// If over the API limit, we can't build this list
if ($rate->resources->core->remaining == 0)
{
throw new \RuntimeException(
Text::sprintf('COM_PATCHTESTER_API_LIMIT_LIST', Factory::getDate($rate->resources->core->reset))
);
}
try
{
$pullResponse = $github->getPullRequest($this->getState()->get('github_user'), $this->getState()->get('github_repo'), $id);
$pull = json_decode($pullResponse->body);
}
catch (UnexpectedResponse $e)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB', $e->getMessage()), $e->getCode(), $e);
}
return $pull;
}
/**
* Saves the applied patch into database
*
* @param integer $id ID of the applied pull request
* @param array $fileList List of files
* @param string $sha sha-key from pull request
*
* @return integer $id last inserted id
*
* @since 3.0
*/
private function saveAppliedPatch($id, $fileList, $sha = null)
{
$record = (object) array(
'pull_id' => $id,
'data' => json_encode($fileList),
'patched_by' => Factory::getUser()->id,
'applied' => 1,
'applied_version' => JVERSION,
);
$db = $this->getDb();
$db->insertObject('#__patchtester_tests', $record);
$insertId = $db->insertid();
if (!is_null($sha))
{
// Insert the retrieved commit SHA into the pulls table for this item
$db->setQuery(
$db->getQuery(true)
->update('#__patchtester_pulls')
->set('sha = ' . $db->quote($sha))
->where($db->quoteName('pull_id') . ' = ' . (int) $id)
)->execute();
}
return $insertId;
}
/**
* Reverts the specified pull request
* However uses different methods for different repositories.
*
* @param integer $id ID of the pull request to revert
*
* @return boolean
*
* @since 3.0
* @throws \RuntimeException
*/
public function revert($id)
{
$params = ComponentHelper::getParams('com_patchtester');
// Decide based on repository settings whether patch will be applied through Github or CIServer
if (version_compare(JVERSION, "4", "ge") && ((bool) $params->get('ci_switch', 1) || $id === $this->getPatchChain($id)->insert_id))
{
return $this->revertWithCIServer($id);
}
else
{
return $this->revertWithGitHub($id);
}
}
/**
* Reverts the specified pull request with CIServer options
*
* @param integer $id ID of the pull request to revert
*
* @return boolean
*
* @since 3.0
* @throws \RuntimeException
*/
public function revertWithCIServer($id)
{
// Get the CIServer Registry
$ciSettings = Helper::initializeCISettings();
$testRecord = $this->getTestRecord($id);
// Get PatchChain as array, remove any EOL set by php
$patchChain = $this->getPatchChain(-1);
// Allow only reverts in order of the patch chain
if ($patchChain->insert_id != $id)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_NOT_IN_ORDER_OF_PATCHCHAIN', $patchChain->pull_id));
}
else
{
$this->removeLastChain($patchChain->insert_id);
}
// We don't want to restore files from an older version
if ($testRecord->applied_version != JVERSION)
{
return $this->removeTest($testRecord);
}
$files = json_decode($testRecord->data);
if (!$files)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_ERROR_READING_DATABASE_TABLE', __METHOD__, htmlentities($testRecord->data)));
}
$backupsPath = $ciSettings->get('folder.backups') . "/$testRecord->pull_id";
foreach ($files as $file)
{
try
{
$filePath = explode("\\", $file);
array_pop($filePath);
$filePath = implode("\\", $filePath);
// Delete file from root of it exists
if (file_Exists(JPATH_ROOT . "/$file"))
{
File::delete(JPATH_ROOT . "/$file");
// Move from backup, if it exists there
if (file_exists("$backupsPath/$file"))
{
File::move("$backupsPath/$file", JPATH_ROOT . "/$file");
}
// If folder is empty, remove it as well
if (count(glob(JPATH_ROOT . "/$filePath/*")) === 0)
{
Folder::delete(JPATH_ROOT . "/$filePath");
}
}
// Move from backup, if file exists there - got deleted by patch
elseif (file_exists("$backupsPath/$file"))
{
if (!file_exists(JPATH_ROOT . "/$filePath"))
{
Folder::create(JPATH_ROOT . "/$filePath");
}
File::move("$backupsPath/$file", JPATH_ROOT . "/$file");
}
}
catch (\RuntimeException $e)
{
throw new \RuntimeException(Text::sprintf('COM_PATCHTESTER_FAILED_REVERT_PATCH', $file, $e->getMessage()));
}
}
Folder::delete($backupsPath);
// Change the media version
$version = new Version;
$version->refreshMediaVersion();
return $this->removeTest($testRecord);
}
/**
* Reverts the specified pull request with Github Requests
*
* @param integer $id ID of the pull request to revert
*
@ -351,16 +712,9 @@ class PullModel extends AbstractModel
* @since 2.0
* @throws \RuntimeException
*/
public function revert($id)
public function revertWithGitHub($id)
{
$db = $this->getDb();
$testRecord = $db->setQuery(
$db->getQuery(true)
->select('*')
->from('#__patchtester_tests')
->where('id = ' . (int) $id)
)->loadObject();
$testRecord = $this->getTestRecord($id);
// We don't want to restore files from an older version
if ($testRecord->applied_version != JVERSION)
@ -475,7 +829,7 @@ class PullModel extends AbstractModel
$db->getQuery(true)
->update('#__patchtester_pulls')
->set('sha = ' . $db->quote(''))
->where($db->quoteName('pull_id') . ' = ' . (int) $testRecord->pull_id)
->where($db->quoteName('id') . ' = ' . (int) $testRecord->id)
)->execute();
// And delete the record from the tests table
@ -487,4 +841,152 @@ class PullModel extends AbstractModel
return true;
}
/**
* Retrieves test data from database by specific id
*
* @param integer $id ID of the record
*
* @return stdClass $testRecord The record looking for
*
* @since 3.0.0
*/
private function getTestRecord($id)
{
$db = $this->getDb();
return $db->setQuery(
$db->getQuery(true)
->select('*')
->from('#__patchtester_tests')
->where('id = ' . (int) $id)
)->loadObject();
}
/**
* Retrieves a list of patches in chain
*
* @return mixed
*
* @since 3.0
*/
private function getPatchChains()
{
$db = $this->getDb();
$db->setQuery(
$db->getQuery(true)
->select('*')
->from($db->quoteName('#__patchtester_chain'))
->order('id DESC')
);
return $db->loadObjectList('pull_id');
}
/**
* Returns a chain by specific value, returns the last
* element on $id = -1 and the first on $id = null
*
* @param integer $id specific id of a pull
*
* @return stdClass $chain last chain of the table
*
* @since 3.0.0
*/
private function getPatchChain($id = null)
{
$db = $this->getDb();
$query = $db->getQuery(true)
->select('*')
->from('#__patchtester_chain');
if (!is_null($id) && $id !== -1)
{
$query = $query->where('insert_id =' . (int) $id);
}
if ($id === -1)
{
$query = $query->order('id DESC');
}
if (is_null($id))
{
$query = $query->order('id ASC');
}
return $db->setQuery($query, 0, 1)->loadObject();
}
/**
* Returns a two dimensional array with applied patches
* by the github or ci procedure
*
* @return array two-dimensional array with github patches
* and ci patches
*
* @since 3.0.0
*/
public function getPatchesDividedInProcs()
{
$db = $this->getDb();
$appliedByGit = $db->setQuery(
$db->getQuery(true)
->select('tests.id, tests.pull_id')
->from('#__patchtester_tests tests')
->leftJoin('#__patchtester_chain chain', 'tests.id = chain.insert_id')
->where('chain.insert_id IS NULL')
)->loadObjectList('pull_id');
$appliedByCI = $this->getPatchChains();
return array('git' => $appliedByGit, 'ci' => $appliedByCI);
}
/**
* Adds a value to the patch chain in the database
*
* @param integer $insertId ID of the patch in the database
* @param integer $pullId ID of the pull request
*
* @return integer $insertId last inserted element
*
* @since 3.0.0
*/
private function appendPatchChain($insertId, $pullId)
{
$record = (object) array(
'insert_id' => $insertId,
'pull_id' => $pullId,
);
$db = $this->getDb();
$db->insertObject('#__patchtester_chain', $record);
return $db->insertid();
}
/**
* Removes the last value of the chain
*
* @param integer $insertId ID of the patch in the database
*
* @return void
*
* @since 3.0.0
*/
private function removeLastChain($insertId)
{
$db = $this->getDb();
$db->setQuery(
$db->getQuery(true)
->delete('#__patchtester_chain')
->where('insert_id = ' . (int) $insertId)
)->execute();
}
}

View File

@ -21,8 +21,8 @@ HTMLHelper::_('script', 'com_patchtester/fetcher.js', array('version' => 'auto',
<div id="patchtester-container">
<h1 id="patchtester-progress-header"><?php echo Text::_('COM_PATCHTESTER_FETCH_INITIALIZING'); ?></h1>
<p id="patchtester-progress-message"><?php echo Text::_('COM_PATCHTESTER_FETCH_INITIALIZING_DESCRIPTION'); ?></p>
<div id="progress" class="progress progress-striped active">
<div id="progress-bar" class="bar bar-success" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<div id="progress" class="progress">
<div id="progress-bar" class="progress-bar progress-bar-striped progress-bar-animated bg-success" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" role="progressbar"></div>
</div>
<input id="patchtester-token" type="hidden" name="<?php echo Factory::getSession()->getFormToken(); ?>" value="1" />
</div>

View File

@ -10,7 +10,7 @@ use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Router\Route;
/** @var \PatchTester\View\Pulls\PullsHtmlView $this */
/** @var \PatchTester\View\Pulls\PullsHtmlView $this */
HTMLHelper::_('behavior.core');
HTMLHelper::_('bootstrap.tooltip');
@ -18,35 +18,47 @@ HTMLHelper::_('formbehavior.chosen', 'select');
HTMLHelper::_('stylesheet', 'com_patchtester/octicons.css', array('version' => '3.5.0', 'relative' => true));
HTMLHelper::_('script', 'com_patchtester/patchtester.js', array('version' => 'auto', 'relative' => true));
$listOrder = $this->escape($this->state->get('list.fullordering', 'a.pull_id DESC'));
$listOrder = $this->escape($this->state->get('list.fullordering', 'a.pull_id DESC'));
$filterApplied = $this->escape($this->state->get('filter.applied'));
$filterBranch = $this->escape($this->state->get('filter.branch'));
$filterRtc = $this->escape($this->state->get('filter.rtc'));
$filterBranch = $this->escape($this->state->get('filter.branch'));
$filterRtc = $this->escape($this->state->get('filter.rtc'));
?>
<form action="<?php echo Route::_('index.php?option=com_patchtester&view=pulls'); ?>" method="post" name="adminForm" id="adminForm" data-order="<?php echo $listOrder; ?>">
<form action="<?php echo Route::_('index.php?option=com_patchtester&view=pulls'); ?>" method="post" name="adminForm"
id="adminForm" data-order="<?php echo $listOrder; ?>">
<div id="j-main-container">
<div id="filter-bar" class="btn-toolbar">
<div class="filter-search btn-group pull-left">
<label for="filter_search" class="element-invisible"><?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?></label>
<input type="text" name="filter_search" placeholder="<?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" id="filter_search" value="<?php echo $this->escape($this->state->get('filter.search')); ?>" title="<?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" />
<label for="filter_search"
class="element-invisible"><?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?></label>
<input type="text" name="filter_search"
placeholder="<?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>"
id="filter_search" value="<?php echo $this->escape($this->state->get('filter.search')); ?>"
title="<?php echo Text::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>"/>
</div>
<div class="btn-group pull-left hidden-phone">
<button class="btn tip hasTooltip" type="submit" title="<?php echo Text::_('JSEARCH_FILTER_SUBMIT'); ?>"><i class="icon-search"></i></button>
<button class="btn tip hasTooltip" type="button" onclick="document.getElementById('filter_search').value='';this.form.submit();" title="<?php echo Text::_('JSEARCH_FILTER_CLEAR'); ?>"><i class="icon-remove"></i></button>
<button class="btn tip hasTooltip" type="submit"
title="<?php echo Text::_('JSEARCH_FILTER_SUBMIT'); ?>"><i class="icon-search"></i></button>
<button class="btn tip hasTooltip" type="button"
onclick="document.getElementById('filter_search').value='';this.form.submit();"
title="<?php echo Text::_('JSEARCH_FILTER_CLEAR'); ?>"><i class="icon-remove"></i></button>
</div>
<div class="btn-group pull-right hidden-phone">
<label for="limit" class="element-invisible"><?php echo Text::_('JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC'); ?></label>
<label for="limit"
class="element-invisible"><?php echo Text::_('JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC'); ?></label>
<?php echo $this->pagination->getLimitBox(); ?>
</div>
<div class="btn-group pull-right">
<label for="list_fullordering" class="element-invisible"><?php echo Text::_('JGLOBAL_SORT_BY'); ?></label>
<select name="list_fullordering" id="list_fullordering" class="input-medium" onchange="this.form.submit();">
<label for="list_fullordering"
class="element-invisible"><?php echo Text::_('JGLOBAL_SORT_BY'); ?></label>
<select name="list_fullordering" id="list_fullordering" class="input-medium"
onchange="this.form.submit();">
<option value=""><?php echo Text::_('JGLOBAL_SORT_BY'); ?></option>
<?php echo HTMLHelper::_('select.options', $this->getSortFields(), 'value', 'text', $listOrder);?>
<?php echo HTMLHelper::_('select.options', $this->getSortFields(), 'value', 'text', $listOrder); ?>
</select>
</div>
<div class="btn-group pull-right">
<label for="filter_applied" class="element-invisible"><?php echo Text::_('JSEARCH_TOOLS_DESC'); ?></label>
<label for="filter_applied"
class="element-invisible"><?php echo Text::_('JSEARCH_TOOLS_DESC'); ?></label>
<select name="filter_applied" class="input-medium" onchange="this.form.submit();">
<option value=""><?php echo Text::_('COM_PATCHTESTER_FILTER_APPLIED_PATCHES'); ?></option>
<option value="yes"<?php if ($filterApplied == 'yes') echo ' selected="selected"'; ?>><?php echo Text::_('COM_PATCHTESTER_APPLIED'); ?></option>
@ -62,10 +74,11 @@ $filterRtc = $this->escape($this->state->get('filter.rtc'));
</select>
</div>
<div class="btn-group pull-right">
<label for="filter_branch" class="element-invisible"><?php echo Text::_('JSEARCH_TOOLS_DESC'); ?></label>
<label for="filter_branch"
class="element-invisible"><?php echo Text::_('JSEARCH_TOOLS_DESC'); ?></label>
<select name="filter_branch" class="input-medium" onchange="this.form.submit();">
<option value=""><?php echo Text::_('COM_PATCHTESTER_FILTER_BRANCH'); ?></option>
<?php echo HTMLHelper::_('select.options', $this->branches, 'text', 'text', $filterBranch, false);?>
<?php echo HTMLHelper::_('select.options', $this->branches, 'text', 'text', $filterBranch, false); ?>
</select>
</div>
</div>
@ -77,46 +90,46 @@ $filterRtc = $this->escape($this->state->get('filter.rtc'));
<?php else : ?>
<table class="table table-striped">
<thead>
<tr>
<th width="5%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_PULL_ID'); ?>
</th>
<th class="nowrap">
<?php echo Text::_('JGLOBAL_TITLE'); ?>
</th>
<th width="8%" class="nowrap center hidden-phone">
<?php echo Text::_('COM_PATCHTESTER_BRANCH'); ?>
</th>
<th width="8%" class="nowrap center hidden-phone">
<?php echo Text::_('COM_PATCHTESTER_READY_TO_COMMIT'); ?>
</th>
<th width="8%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_GITHUB'); ?>
</th>
<?php if ($this->trackerAlias !== false) : ?>
<tr>
<th width="5%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_PULL_ID'); ?>
</th>
<th class="nowrap">
<?php echo Text::_('JGLOBAL_TITLE'); ?>
</th>
<th width="8%" class="nowrap center hidden-phone">
<?php echo Text::_('COM_PATCHTESTER_BRANCH'); ?>
</th>
<th width="8%" class="nowrap center hidden-phone">
<?php echo Text::_('COM_PATCHTESTER_READY_TO_COMMIT'); ?>
</th>
<th width="8%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_GITHUB'); ?>
</th>
<?php if ($this->trackerAlias !== false) : ?>
<th width="8%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_JISSUES'); ?>
</th>
<?php endif; ?>
<th width="10%" class="nowrap center">
<?php echo Text::_('JSTATUS'); ?>
</th>
<th width="15%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_TEST_THIS_PATCH'); ?>
</th>
</tr>
<?php endif; ?>
<th width="10%" class="nowrap center">
<?php echo Text::_('JSTATUS'); ?>
</th>
<th width="15%" class="nowrap center">
<?php echo Text::_('COM_PATCHTESTER_TEST_THIS_PATCH'); ?>
</th>
</tr>
</thead>
<tbody>
<?php echo $this->loadTemplate('items'); ?>
<?php echo $this->loadTemplate('items'); ?>
</tbody>
</table>
<?php endif; ?>
<?php echo $this->pagination->getListFooter(); ?>
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="pull_id" id="pull_id" value="" />
<input type="hidden" name="task" value=""/>
<input type="hidden" name="boxchecked" value="0"/>
<input type="hidden" name="pull_id" id="pull_id" value=""/>
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</form>

View File

@ -16,58 +16,64 @@ foreach ($this->items as $i => $item) :
if ($item->applied) :
$status = ' class="success"';
endif;
?>
<tr<?php echo $status; ?>>
<td class="center">
<?php echo $item->pull_id; ?>
</td>
<td>
<span class="hasTooltip" title="<strong>Info</strong><br/><?php echo $this->escape($item->description); ?>"><?php echo $this->escape($item->title); ?></span>
<?php if ($item->applied) : ?>
<div class="small">
<span class="label label-info"><?php echo Text::sprintf('COM_PATCHTESTER_APPLIED_COMMIT_SHA', substr($item->sha, 0, 10)); ?></span>
</div>
?>
<tr<?php echo $status; ?>>
<td class="center">
<?php echo $item->pull_id; ?>
</td>
<td>
<span class="hasTooltip"
title="<strong>Info</strong><br/><?php echo $this->escape($item->description); ?>"><?php echo $this->escape($item->title); ?></span>
<?php if ($item->applied) : ?>
<div class="small">
<span class="label label-info"><?php echo Text::sprintf('COM_PATCHTESTER_APPLIED_COMMIT_SHA', substr($item->sha, 0, 10)); ?></span>
</div>
<?php endif; ?>
</td>
<td class="center hidden-phone">
<?php echo $this->escape($item->branch); ?>
</td>
<td class="center hidden-phone">
<?php if ($item->is_rtc) : ?>
<span class="label label-success"><?php echo Text::_('JYES'); ?></span>
<?php else : ?>
<span class="label label-primary"><?php echo Text::_('JNO'); ?></span>
<?php endif; ?>
</td>
<td class="center">
<a class="btn btn-small btn-info" href="<?php echo $item->pull_url; ?>" target="_blank">
<span class="octicon octicon-mark-github"></span> <?php echo Text::_('COM_PATCHTESTER_GITHUB'); ?>
</a>
</td>
<?php if ($this->trackerAlias !== false) : ?>
<td class="center">
<a class="btn btn-small btn-warning"
href="https://issues.joomla.org/tracker/<?php echo $this->trackerAlias; ?>/<?php echo $item->pull_id; ?>"
target="_blank">
<i class="icon-joomla"></i> <?php echo Text::_('COM_PATCHTESTER_JISSUE'); ?>
</a>
</td>
<?php endif; ?>
</td>
<td class="center hidden-phone">
<?php echo $this->escape($item->branch); ?>
</td>
<td class="center hidden-phone">
<?php if ($item->is_rtc) : ?>
<span class="label label-success"><?php echo Text::_('JYES'); ?></span>
<?php else : ?>
<span class="label label-primary"><?php echo Text::_('JNO'); ?></span>
<?php endif; ?>
</td>
<td class="center">
<a class="btn btn-small btn-info" href="<?php echo $item->pull_url; ?>" target="_blank">
<span class="octicon octicon-mark-github"></span> <?php echo Text::_('COM_PATCHTESTER_GITHUB'); ?>
</a>
</td>
<?php if ($this->trackerAlias !== false) : ?>
<td class="center">
<a class="btn btn-small btn-warning" href="https://issues.joomla.org/tracker/<?php echo $this->trackerAlias; ?>/<?php echo $item->pull_id; ?>" target="_blank">
<i class="icon-joomla"></i> <?php echo Text::_('COM_PATCHTESTER_JISSUE'); ?>
</a>
</td>
<?php endif; ?>
<td class="center">
<?php if ($item->applied) : ?>
<div>
<span class="label label-success"><?php echo Text::_('COM_PATCHTESTER_APPLIED'); ?></span>
</div>
<?php else : ?>
<span class="label">
<td class="center">
<?php if ($item->applied) : ?>
<div>
<span class="label label-success"><?php echo Text::_('COM_PATCHTESTER_APPLIED'); ?></span>
</div>
<?php else : ?>
<span class="label">
<?php echo Text::_('COM_PATCHTESTER_NOT_APPLIED'); ?>
</span>
<?php endif; ?>
</td>
<td class="center">
<?php if ($item->applied) : ?>
<a class="btn btn-small btn-success" href="javascript:PatchTester.submitpatch('revert', '<?php echo (int) $item->applied; ?>');"><?php echo Text::_('COM_PATCHTESTER_REVERT_PATCH'); ?></a><br />
<?php else : ?>
<a class="btn btn-small btn-primary" href="javascript:PatchTester.submitpatch('apply', '<?php echo (int) $item->pull_id; ?>');"><?php echo Text::_('COM_PATCHTESTER_APPLY_PATCH'); ?></a>
<?php endif; ?>
</td>
</tr>
<?php endif; ?>
</td>
<td class="center">
<?php if ($item->applied) : ?>
<button type="button" class="btn btn-sm btn-success submitPatch"
data-task="revert-<?php echo (int) $item->applied; ?>"><?php echo Text::_('COM_PATCHTESTER_REVERT_PATCH'); ?></button>
<br/>
<?php else : ?>
<button type="button" class="btn btn-sm btn-primary submitPatch"
data-task="apply-<?php echo (int) $item->pull_id; ?>"><?php echo Text::_('COM_PATCHTESTER_APPLY_PATCH'); ?></button>
<?php endif; ?>
</td>
</tr>
<?php endforeach;

View File

@ -2,19 +2,19 @@
<config>
<fieldset
name="repositories"
label="COM_PATCHTESTER_FIELDSET_REPOSITORIES_LABEL"
description="COM_PATCHTESTER_FIELDSET_REPOSITORIES_DESC"
>
name="repositories"
label="COM_PATCHTESTER_FIELDSET_REPOSITORIES_LABEL"
description="COM_PATCHTESTER_FIELDSET_REPOSITORIES_DESC"
>
<field
name="repository"
type="list"
label="COM_PATCHTESTER_FIELD_REPOSITORY_LABEL"
description="COM_PATCHTESTER_FIELD_REPOSITORY_DESC"
default="joomla:joomla-cms"
onchange="if (jQuery(this).val() != 'custom') { var parts = jQuery(this).val().split(':'); } else { var parts = ['', '']; } document.getElementById('jform_org').value = parts[0]; document.getElementById('jform_repo').value = parts[1];"
>
name="repository"
type="list"
label="COM_PATCHTESTER_FIELD_REPOSITORY_LABEL"
description="COM_PATCHTESTER_FIELD_REPOSITORY_DESC"
default="joomla:joomla-cms"
onchange="if (jQuery(this).val() != 'custom') { var parts = jQuery(this).val().split(':'); } else { var parts = ['', '']; } document.getElementById('jform_org').value = parts[0]; document.getElementById('jform_repo').value = parts[1];"
>
<option value="joomla:joomla-cms">COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_JOOMLA_CMS</option>
<option value="joomla-extensions:patchtester">COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_PATCHTESTER</option>
<option value="joomla-extensions:install-from-web-client">COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_INSTALL_FROM_WEB</option>
@ -23,42 +23,41 @@
</field>
<field
name="org"
type="text"
label="COM_PATCHTESTER_FIELD_ORG_LABEL"
description="COM_PATCHTESTER_FIELD_ORG_DESC"
default="joomla"
id="org"
showon="repository:custom"
name="org"
type="text"
label="COM_PATCHTESTER_FIELD_ORG_LABEL"
description="COM_PATCHTESTER_FIELD_ORG_DESC"
default="joomla"
id="org"
showon="repository:custom"
/>
<field
name="repo"
type="text"
label="COM_PATCHTESTER_FIELD_REPO_LABEL"
description="COM_PATCHTESTER_FIELD_REPO_DESC"
default="joomla-cms"
id="repo"
showon="repository:custom"
name="repo"
type="text"
label="COM_PATCHTESTER_FIELD_REPO_LABEL"
description="COM_PATCHTESTER_FIELD_REPO_DESC"
default="joomla-cms"
id="repo"
showon="repository:custom"
/>
</fieldset>
<fieldset
name="authentication"
label="COM_PATCHTESTER_FIELDSET_AUTHENTICATION_LABEL"
description="COM_PATCHTESTER_FIELDSET_AUTHENTICATION_DESC"
>
name="authentication"
label="COM_PATCHTESTER_FIELDSET_AUTHENTICATION_LABEL"
description="COM_PATCHTESTER_FIELDSET_AUTHENTICATION_DESC"
>
<field
name="gh_auth"
type="list"
label="COM_PATCHTESTER_FIELD_GH_AUTH_LABEL"
description="COM_PATCHTESTER_FIELD_GH_AUTH_DESC"
default=""
onchange="jQuery('#jform_gh_user, #jform_gh_password, #jform_gh_token').val('');"
>
name="gh_auth"
type="list"
label="COM_PATCHTESTER_FIELD_GH_AUTH_LABEL"
description="COM_PATCHTESTER_FIELD_GH_AUTH_DESC"
default=""
onchange="jQuery('#jform_gh_user, #jform_gh_password, #jform_gh_token').val('');"
>
<option value="">JNONE</option>
<option value="credentials">COM_PATCHTESTER_FIELD_GH_AUTH_OPTION_CREDENTIALS</option>
<option value="token">COM_PATCHTESTER_FIELD_GH_AUTH_OPTION_TOKEN</option>
@ -66,49 +65,77 @@
<!-- Note: Default username is a space to avoid browser autocomplete. -->
<field
name="gh_user"
type="text"
label="COM_PATCHTESTER_FIELD_GH_USER_LABEL"
description="COM_PATCHTESTER_FIELD_GH_USER_DESC"
autocomplete="off"
default=" "
showon="gh_auth:credentials"
name="gh_user"
type="text"
label="COM_PATCHTESTER_FIELD_GH_USER_LABEL"
description="COM_PATCHTESTER_FIELD_GH_USER_DESC"
autocomplete="off"
default=" "
showon="gh_auth:credentials"
/>
<field
name="gh_password"
type="password"
label="COM_PATCHTESTER_FIELD_GH_PASSWORD_LABEL"
description="COM_PATCHTESTER_FIELD_GH_PASSWORD_DESC"
autocomplete="off"
default=""
showon="gh_auth:credentials"
name="gh_password"
type="password"
label="COM_PATCHTESTER_FIELD_GH_PASSWORD_LABEL"
description="COM_PATCHTESTER_FIELD_GH_PASSWORD_DESC"
autocomplete="off"
default=""
showon="gh_auth:credentials"
/>
<field
name="gh_token"
type="text"
label="COM_PATCHTESTER_FIELD_GH_TOKEN_LABEL"
description="COM_PATCHTESTER_FIELD_GH_TOKEN_DESC"
showon="gh_auth:token"
name="gh_token"
type="text"
label="COM_PATCHTESTER_FIELD_GH_TOKEN_LABEL"
description="COM_PATCHTESTER_FIELD_GH_TOKEN_DESC"
showon="gh_auth:token"
/>
</fieldset>
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC"
>
name="ci_settings"
label="COM_PATCHTESTER_FIELDSET_CI_SETTINGS"
description="COM_PATCHTESTER_FIELDSET_CI_SETTINGS_DESC"
>
<field
name="rules"
type="rules"
name="ci_server"
type="text"
label="COM_PATCHTESTER_FIELD_CI_SERVER_NAME"
description="COM_PATCHTESTER_FIELD_CI_SERVER_NAME_DESC"
autocomplete="off"
default="https://ci.joomla.org:444"
/>
<field
name="ci_switch"
type="list"
label="COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH"
description="COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_DESC"
default="1"
>
<option value="1">COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_ON</option>
<option value="0">COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_OFF</option>
</field>
</fieldset>
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
component="com_patchtester"
filter="rules"
validate="rules"
section="component"
description="JCONFIG_PERMISSIONS_DESC"
>
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
component="com_patchtester"
filter="rules"
validate="rules"
section="component"
/>
</fieldset>

View File

@ -19,3 +19,10 @@ CREATE TABLE IF NOT EXISTS `#__patchtester_tests` (
`applied_version` varchar(25) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;
CREATE TABLE IF NOT EXISTS `#__patchtester_chain` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`insert_id` int(11) NOT NULL,
`pull_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;

View File

@ -1,2 +1,3 @@
DROP TABLE IF EXISTS `#__patchtester_pulls`;
DROP TABLE IF EXISTS `#__patchtester_tests`;
DROP TABLE IF EXISTS `#__patchtester_chain`;

View File

@ -19,3 +19,10 @@ CREATE TABLE IF NOT EXISTS "#__patchtester_tests" (
"applied_version" character varying(25) NOT NULL,
PRIMARY KEY ("id")
);
CREATE TABLE IF NOT EXISTS "#__patchtester_chain" (
"id" serial NOT NULL,
"insert_id" bigint NOT NULL,
"pull_id" bigint NOT NULL,
PRIMARY KEY ("id")
);

View File

@ -1,2 +1,3 @@
DROP TABLE IF EXISTS "#__patchtester_pulls";
DROP TABLE IF EXISTS "#__patchtester_tests";
DROP TABLE IF EXISTS "#__patchtester_chain";

View File

@ -25,3 +25,13 @@ CREATE TABLE [#__patchtester_tests](
[id] ASC
) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
);
CREATE TABLE [#__patchtester_chain] (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[insert_id] [bigint] NOT NULL,
[pull_id] [bigint] NOT NULL,
CONSTRAINT [PK_#__patchtester_chain] PRIMARY KEY CLUSTERED
(
[id] ASC
) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
);

View File

@ -1,2 +1,3 @@
DROP TABLE [#__patchtester_pulls];
DROP TABLE [#__patchtester_tests];
DROP TABLE [#__patchtester_chain];

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS `#__patchtester_chain` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`insert_id` int(11) NOT NULL,
`pull_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;

View File

@ -0,0 +1,6 @@
CREATE TABLE IF NOT EXISTS "#__patchtester_chain" (
"id" serial NOT NULL,
"insert_id" bigint NOT NULL,
"pull_id" bigint NOT NULL,
PRIMARY KEY (`id`)
);

View File

@ -0,0 +1,9 @@
CREATE TABLE [#__patchtester_chain] (
[id] [bigint] IDENTITY(1,1) NOT NULL,
[insert_id] [bigint] NOT NULL,
[pull_id] [bigint] NOT NULL,
CONSTRAINT [PK_#__patchtester_chain] PRIMARY KEY CLUSTERED
(
[id] ASC
) WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF)
);

View File

@ -28,6 +28,8 @@ COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE="Fehler beim Leeren der Pulls-Tabel
COM_PATCHTESTER_ERROR_TRUNCATING_TESTS_TABLE="Fehler beim Leeren der Tests-Tabelle %s"
COM_PATCHTESTER_ERROR_UNSUPPORTED_ENCODING="Die Patch-Dateien sind in mit einem nicht unterstützten Format codiert."
COM_PATCHTESTER_ERROR_VIEW_NOT_FOUND="Ansicht nicht gefunden [Name, Format]: %1$s, %2$s"
COM_PATCHTESTER_FAILED_APPLYING_PATCH="Der Patch konnte nicht angewendet werden aufgrund eines Problems mit %1$s. %2$s"
COM_PATCHTESTER_FAILED_REVERT_PATCH="Der Patch konnte nicht zurückgesetzt werden aufgrund eines Problems mit %1$s. %2$s"
COM_PATCHTESTER_FETCH_AN_ERROR_HAS_OCCURRED="Fehler beim Abrufen der Daten von GitHub."
COM_PATCHTESTER_FETCH_COMPLETE_CLOSE_WINDOW="Alle Daten wurden abgerufen. Schließen Sie bitte dieses Popup um die Seite neu zu laden."
COM_PATCHTESTER_FETCH_INITIALIZING="Vorbereitungen für das Abrufen der Daten von GitHub"
@ -57,10 +59,18 @@ COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_PATCHTESTER="Joomla! Patch-Tester Kompon
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_INSTALL_FROM_WEB="Joomla! Webkataloginstallations-Plugin"
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_WEBLINKS="Joomla! Weblinks-Paket"
COM_PATCHTESTER_FIELD_REPOSITORY_CUSTOM="Benutzerdefiniert"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME="CI Server Adresse"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME_DESC="Server Adresse für das Herunterladen kompilierter Patches."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH="Switch CI Integration"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_DESC="Schaltet die CI Integration an oder aus."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_ON="An"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_OFF="Aus"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_DESC="Konfigurationswerte für GitHub Repository"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_LABEL="GitHub Repository"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_DESC="Konfigurationswerte für GitHub Authentifizierung"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_LABEL="GitHub Authentifizierung"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS="CI Server Einstellungen"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS_DESC="Konfigurationswerte für CI Server Patching"
COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S="Die zu löschende Datei existiert nicht: %s"
COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S="Die zu ändernde Datei existiert nicht: %s"
COM_PATCHTESTER_FILTER_APPLIED_PATCHES="Angewendete Patches filtern"
@ -75,6 +85,7 @@ COM_PATCHTESTER_NO_CREDENTIALS="In den Optionen wurden noch keine Benutzerdaten
COM_PATCHTESTER_NO_FILES_TO_PATCH="Es sind keine Dateien aus diesem Pull Request zu patchen. Dies kann bedeuten, dass die Dateien des Pull Requests in Ihrer Installation nicht vorhanden sind."
COM_PATCHTESTER_NO_ITEMS="Es wurden noch keine Daten von Github abgerufen. Klicken Sie auf 'Daten abrufen' um die aktuellen Daten von Github zu holen."
COM_PATCHTESTER_NOT_APPLIED="Nicht angewendet"
COM_PATCHTESTER_NOT_IN_ORDER_OF_PATCHCHAIN="Der Patch kann nicht zurückgesetzt werden, es muss zunächst erstmal der Patch mit der Pull ID %s zurückgesetzt werden."
COM_PATCHTESTER_NOT_RTC="Nicht RTC"
COM_PATCHTESTER_PULL_ID="Pull-ID"
COM_PATCHTESTER_PULL_ID_ASC="Pull-ID aufsteigend"
@ -91,9 +102,11 @@ COM_PATCHTESTER_RESET_OK="Die Daten wurden erfolgreich zurück gesetzt."
COM_PATCHTESTER_REVERT_OK="Der Patch wurde erfolgreich entfernt"
COM_PATCHTESTER_REVERT_PATCH="Patch entfernen"
COM_PATCHTESTER_RTC="RTC"
COM_PATCHTESTER_SERVER_RESPONDED_NOT_200="Es konnte entweder keine Verbindung zum Server aufgebaut werden oder der angegebene Pull Request existiert nicht auf dem Server."
COM_PATCHTESTER_TEST_THIS_PATCH="Diesen Patch testen"
COM_PATCHTESTER_TOOLBAR_FETCH_DATA="Daten abrufen"
COM_PATCHTESTER_TOOLBAR_RESET="Zurücksetzen"
COM_PATCHTESTER_VIEW_ON_GITHUB="Auf GitHub ansehen"
COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER="Im Joomla! Issue Tracker ansehen"
COM_PATCHTESTER_ZIP_DOES_NOT_EXIST="Der Patch konnte nicht angewendet werden, weil er nicht vom Server heruntergeladen werden konnte."
COM_PATCHTESTER_ZIP_EXTRACT_FAILED="Der Patch konnte nicht angewendet werden, weil nicht entpackt werden konnte."

View File

@ -27,6 +27,8 @@ COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE="Error truncating the pulls table:
COM_PATCHTESTER_ERROR_TRUNCATING_TESTS_TABLE="Error truncating the tests table: %s"
COM_PATCHTESTER_ERROR_UNSUPPORTED_ENCODING="The patch's files are encoded in an unsupported format."
COM_PATCHTESTER_ERROR_VIEW_NOT_FOUND="View not found [name, format]: %1$s, %2$s"
COM_PATCHTESTER_FAILED_APPLYING_PATCH="Patch could not be applied due to exception with %1$s. %2$s"
COM_PATCHTESTER_FAILED_REVERT_PATCH="Patch could not be reverted due to exception with %1$s. %2$s"
COM_PATCHTESTER_FETCH_AN_ERROR_HAS_OCCURRED="An error has occurred while fetching the data from GitHub."
COM_PATCHTESTER_FETCH_COMPLETE_CLOSE_WINDOW="All data has been retrieved. Please close this modal window to refresh the page."
COM_PATCHTESTER_FETCH_INITIALIZING="Preparing to fetch GitHub data"
@ -56,10 +58,18 @@ COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_PATCHTESTER="Joomla! Patch Tester Compon
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_INSTALL_FROM_WEB="Joomla! Install From Web Plugin"
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_WEBLINKS="Joomla! Weblinks Package"
COM_PATCHTESTER_FIELD_REPOSITORY_CUSTOM="Custom"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME="CI Server Address"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME_DESC="Server address for obtaining compiled patches."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH="Switch CI Integration"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_DESC="Turn CI integration on or off."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_ON="On"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_OFF="Off"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_DESC="Configuration Values for GitHub Repository"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_LABEL="GitHub Repository"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_DESC="Configuration Values for GitHub Authentication"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_LABEL="GitHub Authentication"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS="CI Server Settings"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS_DESC="Configuration Values for CI Server Patching"
COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S="The file marked for deletion does not exist: %s"
COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S="The file marked for modification does not exist: %s"
COM_PATCHTESTER_FILTER_APPLIED_PATCHES="Filter Applied Patches"
@ -74,6 +84,7 @@ COM_PATCHTESTER_NO_CREDENTIALS="You have not entered your user credentials in th
COM_PATCHTESTER_NO_FILES_TO_PATCH="There are no files to patch from this pull request. This may mean that the files in the pull request are not present in your installation."
COM_PATCHTESTER_NO_ITEMS="No data has been retrieved from GitHub, please click the 'Fetch Data' button in the toolbar to retrieve the open pull requests."
COM_PATCHTESTER_NOT_APPLIED="Not Applied"
COM_PATCHTESTER_NOT_IN_ORDER_OF_PATCHCHAIN="You can't revert this patch, you need to revert the patch with the pull id %s first."
COM_PATCHTESTER_NOT_RTC="Not RTC"
COM_PATCHTESTER_PULL_ID="Pull ID"
COM_PATCHTESTER_PULL_ID_ASC="Pull ID ascending"
@ -90,8 +101,11 @@ COM_PATCHTESTER_RESET_OK="The reset process has completed successfully."
COM_PATCHTESTER_REVERT_OK="Patch successfully reverted"
COM_PATCHTESTER_REVERT_PATCH="Revert Patch"
COM_PATCHTESTER_RTC="RTC"
COM_PATCHTESTER_SERVER_RESPONDED_NOT_200="The patch could not be applied either due to missing connection to the server or missing patch on the server."
COM_PATCHTESTER_TEST_THIS_PATCH="Test This Patch"
COM_PATCHTESTER_TOOLBAR_FETCH_DATA="Fetch Data"
COM_PATCHTESTER_TOOLBAR_RESET="Reset"
COM_PATCHTESTER_VIEW_ON_GITHUB="View on GitHub"
COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER="View on Joomla! Issue Tracker"
COM_PATCHTESTER_ZIP_DOES_NOT_EXIST="The patch could not be applied, because it couldn't be retrieved from server."
COM_PATCHTESTER_ZIP_EXTRACT_FAILED="The patch could not be applied, because it couldn't be extracted."

View File

@ -28,6 +28,8 @@ COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE="Error truncating the pulls table:
COM_PATCHTESTER_ERROR_TRUNCATING_TESTS_TABLE="Error truncating the tests table: %s"
COM_PATCHTESTER_ERROR_UNSUPPORTED_ENCODING="The patch's files are encoded in an unsupported format."
COM_PATCHTESTER_ERROR_VIEW_NOT_FOUND="View not found [name, format]: %1$s, %2$s"
COM_PATCHTESTER_FAILED_APPLYING_PATCH="Patch could not be applied due to exception with %1$s. %2$s"
COM_PATCHTESTER_FAILED_REVERT_PATCH="Patch could not be reverted due to exception with %1$s. %2$s"
COM_PATCHTESTER_FETCH_AN_ERROR_HAS_OCCURRED="An error has occurred while fetching the data from GitHub."
COM_PATCHTESTER_FETCH_COMPLETE_CLOSE_WINDOW="All data has been retrieved. Please close this modal window to refresh the page."
COM_PATCHTESTER_FETCH_INITIALIZING="Preparing to fetch GitHub data"
@ -57,10 +59,18 @@ COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_PATCHTESTER="Joomla! Patch Tester Compon
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_INSTALL_FROM_WEB="Joomla! Install From Web Plugin"
COM_PATCHTESTER_FIELD_REPOSITORY_OPTION_WEBLINKS="Joomla! Weblinks Package"
COM_PATCHTESTER_FIELD_REPOSITORY_CUSTOM="Custom"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME="CI Server Address"
COM_PATCHTESTER_FIELD_CI_SERVER_NAME_DESC="Server address for obtaining compiled patches."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH="Switch CI Integration"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_DESC="Turn CI integration on or off."
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_ON="On"
COM_PATCHTESTER_FIELD_CI_SERVER_SWITCH_OPTION_OFF="Off"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_DESC="Configuration Values for GitHub Repository"
COM_PATCHTESTER_FIELDSET_REPOSITORIES_LABEL="GitHub Repository"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_DESC="Configuration Values for GitHub Authentication"
COM_PATCHTESTER_FIELDSET_AUTHENTICATION_LABEL="GitHub Authentication"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS="CI Server Settings"
COM_PATCHTESTER_FIELDSET_CI_SETTINGS_DESC="Configuration Values for CI Server Patching"
COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S="The file marked for deletion does not exist: %s"
COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S="The file marked for modification does not exist: %s"
COM_PATCHTESTER_FILTER_APPLIED_PATCHES="Filter Applied Patches"
@ -75,6 +85,7 @@ COM_PATCHTESTER_NO_CREDENTIALS="You have not entered your user credentials in th
COM_PATCHTESTER_NO_FILES_TO_PATCH="There are no files to patch from this pull request. This may mean that the files in the pull request are not present in your installation."
COM_PATCHTESTER_NO_ITEMS="No data has been retrieved from GitHub, please click the 'Fetch Data' button in the toolbar to retrieve the open pull requests."
COM_PATCHTESTER_NOT_APPLIED="Not Applied"
COM_PATCHTESTER_NOT_IN_ORDER_OF_PATCHCHAIN="You can't revert this patch, you need to revert the patch with the pull id %s first."
COM_PATCHTESTER_NOT_RTC="Not RTC"
COM_PATCHTESTER_PULL_ID="Pull ID"
COM_PATCHTESTER_PULL_ID_ASC="Pull ID ascending"
@ -91,9 +102,11 @@ COM_PATCHTESTER_RESET_OK="The reset process has completed successfully."
COM_PATCHTESTER_REVERT_OK="Patch successfully reverted"
COM_PATCHTESTER_REVERT_PATCH="Revert Patch"
COM_PATCHTESTER_RTC="RTC"
COM_PATCHTESTER_SERVER_RESPONDED_NOT_200="The patch could not be applied either due to missing connection to the server or missing patch on the server."
COM_PATCHTESTER_TEST_THIS_PATCH="Test This Patch"
COM_PATCHTESTER_TOOLBAR_FETCH_DATA="Fetch Data"
COM_PATCHTESTER_TOOLBAR_RESET="Reset"
COM_PATCHTESTER_VIEW_ON_GITHUB="View on GitHub"
COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER="View on Joomla! Issue Tracker"
COM_PATCHTESTER_ZIP_DOES_NOT_EXIST="The patch could not be applied, because it couldn't be retrieved from server."
COM_PATCHTESTER_ZIP_EXTRACT_FAILED="The patch could not be applied, because it couldn't be extracted."

View File

@ -17,56 +17,60 @@ foreach ($this->items as $i => $item) :
$status = ' class="table-active"';
endif;
?>
<tr<?php echo $status; ?>>
<th scope="row" class="text-center">
<?php echo $item->pull_id; ?>
</th>
<td>
<span><?php echo $this->escape($item->title); ?></span>
<div role="tooltip" id="tip<?php echo $i; ?>">
<?php echo $this->escape($item->description); ?>
</div>
<div class="row">
<div class="col-md-auto">
<a class="badge badge-info" href="<?php echo $item->pull_url; ?>" target="_blank">
<?php echo Text::_('COM_PATCHTESTER_VIEW_ON_GITHUB'); ?>
</a>
<tr<?php echo $status; ?>>
<th scope="row" class="text-center">
<?php echo $item->pull_id; ?>
</th>
<td>
<span><?php echo $this->escape($item->title); ?></span>
<div role="tooltip" id="tip<?php echo $i; ?>">
<?php echo $this->escape($item->description); ?>
</div>
<div class="col-md-auto">
<a class="badge badge-info" href="https://issues.joomla.org/tracker/<?php echo $this->trackerAlias; ?>/<?php echo $item->pull_id; ?>" target="_blank">
<?php echo Text::_('COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER'); ?>
</a>
</div>
<?php if ($item->applied) : ?>
<div class="row">
<div class="col-md-auto">
<span class="badge badge-info"><?php echo Text::sprintf('COM_PATCHTESTER_APPLIED_COMMIT_SHA', substr($item->sha, 0, 10)); ?></span>
<a class="badge badge-info" href="<?php echo $item->pull_url; ?>" target="_blank">
<?php echo Text::_('COM_PATCHTESTER_VIEW_ON_GITHUB'); ?>
</a>
</div>
<div class="col-md-auto">
<a class="badge badge-info"
href="https://issues.joomla.org/tracker/<?php echo $this->trackerAlias; ?>/<?php echo $item->pull_id; ?>"
target="_blank">
<?php echo Text::_('COM_PATCHTESTER_VIEW_ON_JOOMLA_ISSUE_TRACKER'); ?>
</a>
</div>
<?php if ($item->applied) : ?>
<div class="col-md-auto">
<span class="badge badge-info"><?php echo Text::sprintf('COM_PATCHTESTER_APPLIED_COMMIT_SHA', substr($item->sha, 0, 10)); ?></span>
</div>
<?php endif; ?>
</div>
</td>
<td class="d-none d-md-table-cell text-center">
<?php echo $this->escape($item->branch); ?>
</td>
<td class="d-none d-md-table-cell text-center">
<?php if ($item->is_rtc) : ?>
<span class="badge badge-success"><?php echo Text::_('JYES'); ?></span>
<?php else : ?>
<span class="badge badge-secondary"><?php echo Text::_('JNO'); ?></span>
<?php endif; ?>
</div>
</td>
<td class="d-none d-md-table-cell text-center">
<?php echo $this->escape($item->branch); ?>
</td>
<td class="d-none d-md-table-cell text-center">
<?php if ($item->is_rtc) : ?>
<span class="badge badge-success"><?php echo Text::_('JYES'); ?></span>
<?php else : ?>
<span class="badge badge-secondary"><?php echo Text::_('JNO'); ?></span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($item->applied) : ?>
<span class="badge badge-success"><?php echo Text::_('COM_PATCHTESTER_APPLIED'); ?></span>
<?php else : ?>
<span class="badge badge-secondary"><?php echo Text::_('COM_PATCHTESTER_NOT_APPLIED'); ?></span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($item->applied) : ?>
<button class="btn btn-sm btn-success" onclick="PatchTester.submitpatch('revert', '<?php echo (int) $item->applied; ?>');"><?php echo Text::_('COM_PATCHTESTER_REVERT_PATCH'); ?></button>
<?php else : ?>
<button class="btn btn-sm btn-primary" onclick="PatchTester.submitpatch('apply', '<?php echo (int) $item->pull_id; ?>');"><?php echo Text::_('COM_PATCHTESTER_APPLY_PATCH'); ?></button>
<?php endif; ?>
</td>
</tr>
</td>
<td class="text-center">
<?php if ($item->applied) : ?>
<span class="badge badge-success"><?php echo Text::_('COM_PATCHTESTER_APPLIED'); ?></span>
<?php else : ?>
<span class="badge badge-secondary"><?php echo Text::_('COM_PATCHTESTER_NOT_APPLIED'); ?></span>
<?php endif; ?>
</td>
<td class="text-center">
<?php if ($item->applied) : ?>
<button type="button" class="btn btn-sm btn-success submitPatch"
data-task="revert-<?php echo (int) $item->applied; ?>"><?php echo Text::_('COM_PATCHTESTER_REVERT_PATCH'); ?></button>
<?php else : ?>
<button type="button" class="btn btn-sm btn-primary submitPatch"
data-task="apply-<?php echo (int) $item->pull_id; ?>"><?php echo Text::_('COM_PATCHTESTER_APPLY_PATCH'); ?></button>
<?php endif; ?>
</td>
</tr>
<?php endforeach;

View File

@ -5,7 +5,6 @@ rm -rf build/packages && mkdir build/packages
composer install --no-dev -o
cp -r administrator/components/com_patchtester build/packaging/admin
cp -r administrator/templates/atum/html/com_patchtester build/packaging/atum
cp -r administrator/templates/hathor/html/com_patchtester build/packaging/hathor
cp -r media/com_patchtester build/packaging/media
rm -rf build/packaging/admin/backups/*.txt
mv build/packaging/admin/patchtester.xml build/packaging/patchtester.xml

View File

@ -112,7 +112,7 @@ if (typeof Joomla === 'undefined') {
jQuery('#progress').remove();
}
});
}
};
initialize();
};

View File

@ -9,27 +9,25 @@ if (typeof Joomla === 'undefined') {
throw new Error('PatchTester JavaScript requires the Joomla core JavaScript API')
}
!function (Joomla, window, document) {
'use strict';
document.addEventListener("DOMContentLoaded", function (event) {
window.PatchTester = {
/**
* Process the patch action
*
* @param {String} task The task to perform
* @param {Number} id The item ID
*/
submitpatch: function (task, id) {
var idField = document.getElementById('pull_id');
idField.value = id;
var submitPatch = document.querySelectorAll(".submitPatch");
var pullIdForm = document.querySelector("#pull_id");
Joomla.submitform(task);
}
};
/**
* EventListener which listens on submitPatch Button,
* checks if it is an apply or revert method and
* processes the patch action
*
* @param {Event} event
*/
submitPatch.forEach(function (element) {
element.addEventListener("click", function (event) {
var currentTarget = event.currentTarget;
var data = currentTarget.dataset.task.split("-");
Joomla.submitbutton = function (task) {
if (task != 'reset' || confirm(Joomla.JText._('COM_PATCHTESTER_CONFIRM_RESET', 'Resetting will attempt to revert all applied patches and removes all backed up files. This may result in a corrupted environment. Are you sure you want to continue?'))) {
Joomla.submitform(task);
}
};
}(Joomla, window, document);
pullIdForm.value = data[1];
Joomla.submitform(data[0]);
});
});
});