mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-30 01:10:58 +01:00
Make various minor Harbormaster UI improvements
Summary: Ref T1049. Tweaks some of the UI and code to improve / clean it up a bit. Test Plan: Ran build plans, browsed UI. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T1049 Differential Revision: https://secure.phabricator.com/D8603
This commit is contained in:
parent
cec8d10731
commit
25f91567a7
15 changed files with 268 additions and 195 deletions
|
@ -20,97 +20,21 @@ final class HarbormasterBuildableViewController
|
|||
->withIDs(array($id))
|
||||
->needBuildableHandles(true)
|
||||
->needContainerHandles(true)
|
||||
->needBuilds(true)
|
||||
->executeOne();
|
||||
if (!$buildable) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$build_list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
foreach ($buildable->getBuilds() as $build) {
|
||||
$view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName(pht('Build %d', $build->getID()))
|
||||
->setHeader($build->getName())
|
||||
->setHref($view_uri);
|
||||
// Pull builds and build targets.
|
||||
$builds = id(new HarbormasterBuildQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildablePHIDs(array($buildable->getPHID()))
|
||||
->needBuildTargets(true)
|
||||
->execute();
|
||||
|
||||
switch ($build->getBuildStatus()) {
|
||||
case HarbormasterBuild::STATUS_INACTIVE:
|
||||
$item->setBarColor('grey');
|
||||
$item->addAttribute(pht('Inactive'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_PENDING:
|
||||
$item->setBarColor('blue');
|
||||
$item->addAttribute(pht('Pending'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_WAITING:
|
||||
$item->setBarColor('violet');
|
||||
$item->addAttribute(pht('Waiting'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_BUILDING:
|
||||
$item->setBarColor('yellow');
|
||||
$item->addAttribute(pht('Building'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_PASSED:
|
||||
$item->setBarColor('green');
|
||||
$item->addAttribute(pht('Passed'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_FAILED:
|
||||
$item->setBarColor('red');
|
||||
$item->addAttribute(pht('Failed'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_ERROR:
|
||||
$item->setBarColor('red');
|
||||
$item->addAttribute(pht('Unexpected Error'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_STOPPED:
|
||||
$item->setBarColor('black');
|
||||
$item->addAttribute(pht('Stopped'));
|
||||
break;
|
||||
}
|
||||
$buildable->attachBuilds($builds);
|
||||
|
||||
if ($build->isRestarting()) {
|
||||
$item->addIcon('backward', pht('Restarting'));
|
||||
} else if ($build->isStopping()) {
|
||||
$item->addIcon('stop', pht('Stopping'));
|
||||
} else if ($build->isResuming()) {
|
||||
$item->addIcon('play', pht('Resuming'));
|
||||
}
|
||||
|
||||
$build_id = $build->getID();
|
||||
|
||||
$restart_uri = "build/restart/{$build_id}/buildable/";
|
||||
$resume_uri = "build/resume/{$build_id}/buildable/";
|
||||
$stop_uri = "build/stop/{$build_id}/buildable/";
|
||||
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('backward')
|
||||
->setName(pht('Restart'))
|
||||
->setHref($this->getApplicationURI($restart_uri))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$build->canRestartBuild()));
|
||||
|
||||
if ($build->canResumeBuild()) {
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('play')
|
||||
->setName(pht('Resume'))
|
||||
->setHref($this->getApplicationURI($resume_uri))
|
||||
->setWorkflow(true));
|
||||
} else {
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('stop')
|
||||
->setName(pht('Stop'))
|
||||
->setHref($this->getApplicationURI($stop_uri))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$build->canStopBuild()));
|
||||
}
|
||||
|
||||
$build_list->addItem($item);
|
||||
}
|
||||
$build_list = $this->buildBuildList($buildable);
|
||||
|
||||
$title = pht("Buildable %d", $id);
|
||||
|
||||
|
@ -233,4 +157,137 @@ final class HarbormasterBuildableViewController
|
|||
|
||||
}
|
||||
|
||||
private function buildBuildList(HarbormasterBuildable $buildable) {
|
||||
$viewer = $this->getRequest()->getUser();
|
||||
|
||||
$build_list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
foreach ($buildable->getBuilds() as $build) {
|
||||
$view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName(pht('Build %d', $build->getID()))
|
||||
->setHeader($build->getName())
|
||||
->setHref($view_uri);
|
||||
|
||||
switch ($build->getBuildStatus()) {
|
||||
case HarbormasterBuild::STATUS_INACTIVE:
|
||||
$item->setBarColor('grey');
|
||||
$item->addAttribute(pht('Inactive'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_PENDING:
|
||||
$item->setBarColor('blue');
|
||||
$item->addAttribute(pht('Pending'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_WAITING:
|
||||
$item->setBarColor('violet');
|
||||
$item->addAttribute(pht('Waiting'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_BUILDING:
|
||||
$item->setBarColor('yellow');
|
||||
$item->addAttribute(pht('Building'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_PASSED:
|
||||
$item->setBarColor('green');
|
||||
$item->addAttribute(pht('Passed'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_FAILED:
|
||||
$item->setBarColor('red');
|
||||
$item->addAttribute(pht('Failed'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_ERROR:
|
||||
$item->setBarColor('red');
|
||||
$item->addAttribute(pht('Unexpected Error'));
|
||||
break;
|
||||
case HarbormasterBuild::STATUS_STOPPED:
|
||||
$item->setBarColor('black');
|
||||
$item->addAttribute(pht('Stopped'));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($build->isRestarting()) {
|
||||
$item->addIcon('backward', pht('Restarting'));
|
||||
} else if ($build->isStopping()) {
|
||||
$item->addIcon('stop', pht('Stopping'));
|
||||
} else if ($build->isResuming()) {
|
||||
$item->addIcon('play', pht('Resuming'));
|
||||
}
|
||||
|
||||
$build_id = $build->getID();
|
||||
|
||||
$restart_uri = "build/restart/{$build_id}/buildable/";
|
||||
$resume_uri = "build/resume/{$build_id}/buildable/";
|
||||
$stop_uri = "build/stop/{$build_id}/buildable/";
|
||||
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('backward')
|
||||
->setName(pht('Restart'))
|
||||
->setHref($this->getApplicationURI($restart_uri))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$build->canRestartBuild()));
|
||||
|
||||
if ($build->canResumeBuild()) {
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('play')
|
||||
->setName(pht('Resume'))
|
||||
->setHref($this->getApplicationURI($resume_uri))
|
||||
->setWorkflow(true));
|
||||
} else {
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('stop')
|
||||
->setName(pht('Stop'))
|
||||
->setHref($this->getApplicationURI($stop_uri))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$build->canStopBuild()));
|
||||
}
|
||||
|
||||
$targets = $build->getBuildTargets();
|
||||
|
||||
if ($targets) {
|
||||
$target_list = id(new PHUIStatusListView());
|
||||
foreach ($targets as $target) {
|
||||
switch ($target->getTargetStatus()) {
|
||||
case HarbormasterBuildTarget::STATUS_PENDING:
|
||||
$icon = 'time-green';
|
||||
break;
|
||||
case HarbormasterBuildTarget::STATUS_PASSED:
|
||||
$icon = 'accept-green';
|
||||
break;
|
||||
case HarbormasterBuildTarget::STATUS_FAILED:
|
||||
$icon = 'reject-red';
|
||||
break;
|
||||
default:
|
||||
$icon = 'question';
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
$impl = $target->getImplementation();
|
||||
$name = $impl->getName();
|
||||
} catch (Exception $ex) {
|
||||
$name = $target->getClassName();
|
||||
}
|
||||
|
||||
$target_list->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon($icon)
|
||||
->setTarget(pht('Target %d', $target->getID()))
|
||||
->setNote($name));
|
||||
}
|
||||
|
||||
$target_box = id(new PHUIBoxView())
|
||||
->addPadding(PHUI::PADDING_SMALL)
|
||||
->appendChild($target_list);
|
||||
|
||||
$item->appendChild($target_box);
|
||||
}
|
||||
|
||||
$build_list->addItem($item);
|
||||
}
|
||||
|
||||
return $build_list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,19 +22,16 @@ final class HarbormasterStepAddController
|
|||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if ($plan === null) {
|
||||
throw new Exception("Build plan not found!");
|
||||
if (!$plan) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$implementations =
|
||||
HarbormasterBuildStepImplementation::getImplementations();
|
||||
|
||||
$cancel_uri = $this->getApplicationURI('plan/'.$plan->getID().'/');
|
||||
|
||||
if ($request->isDialogFormPost()) {
|
||||
$class = $request->getStr('step-type');
|
||||
if (!in_array($class, $implementations)) {
|
||||
return $this->createDialog($implementations, $cancel_uri);
|
||||
if (!HarbormasterBuildStepImplementation::getImplementation($class)) {
|
||||
return $this->createDialog($cancel_uri);
|
||||
}
|
||||
|
||||
$steps = $plan->loadOrderedBuildSteps();
|
||||
|
@ -51,38 +48,30 @@ final class HarbormasterStepAddController
|
|||
return id(new AphrontRedirectResponse())->setURI($edit_uri);
|
||||
}
|
||||
|
||||
return $this->createDialog($implementations, $cancel_uri);
|
||||
return $this->createDialog($cancel_uri);
|
||||
}
|
||||
|
||||
function createDialog(array $implementations, $cancel_uri) {
|
||||
private function createDialog($cancel_uri) {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$control = id(new AphrontFormRadioButtonControl())
|
||||
->setName('step-type');
|
||||
|
||||
foreach ($implementations as $implementation_name) {
|
||||
$implementation = new $implementation_name();
|
||||
$control
|
||||
->addButton(
|
||||
$implementation_name,
|
||||
$implementation->getName(),
|
||||
$implementation->getGenericDescription());
|
||||
$all = HarbormasterBuildStepImplementation::getImplementations();
|
||||
foreach ($all as $class => $implementation) {
|
||||
$control->addButton(
|
||||
$class,
|
||||
$implementation->getName(),
|
||||
$implementation->getGenericDescription());
|
||||
}
|
||||
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setTitle(pht('Add New Step'))
|
||||
->setUser($viewer)
|
||||
->addSubmitButton(pht('Add Build Step'))
|
||||
->addCancelButton($cancel_uri);
|
||||
$dialog->appendChild(
|
||||
phutil_tag(
|
||||
'p',
|
||||
array(),
|
||||
pht(
|
||||
'Select what type of build step you want to add: ')));
|
||||
$dialog->appendChild($control);
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add New Step'))
|
||||
->addSubmitButton(pht('Add Build Step'))
|
||||
->addCancelButton($cancel_uri)
|
||||
->appendParagraph(pht('Choose a type of build step to add:'))
|
||||
->appendChild($control);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ final class HarbormasterBuildQuery
|
|||
private $buildStatuses;
|
||||
private $buildablePHIDs;
|
||||
private $buildPlanPHIDs;
|
||||
private $needBuildTargets;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -34,6 +35,11 @@ final class HarbormasterBuildQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function needBuildTargets($need_targets) {
|
||||
$this->needBuildTargets = $need_targets;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new HarbormasterBuild();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
@ -102,6 +108,24 @@ final class HarbormasterBuildQuery
|
|||
$build->attachUnprocessedCommands($unprocessed_commands);
|
||||
}
|
||||
|
||||
if ($this->needBuildTargets) {
|
||||
$targets = id(new HarbormasterBuildTargetQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->setParentQuery($this)
|
||||
->withBuildPHIDs($build_phids)
|
||||
->execute();
|
||||
|
||||
// TODO: Some day, when targets have dependencies, we should toposort
|
||||
// these. For now, just put them into chronological order.
|
||||
$targets = array_reverse($targets);
|
||||
|
||||
$targets = mgroup($targets, 'getBuildPHID');
|
||||
foreach ($page as $build) {
|
||||
$build_targets = idx($targets, $build->getPHID(), array());
|
||||
$build->attachBuildTargets($build_targets);
|
||||
}
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,32 @@
|
|||
abstract class HarbormasterBuildStepImplementation {
|
||||
|
||||
public static function getImplementations() {
|
||||
$symbols = id(new PhutilSymbolLoader())
|
||||
return id(new PhutilSymbolLoader())
|
||||
->setAncestorClass('HarbormasterBuildStepImplementation')
|
||||
->setConcreteOnly(true)
|
||||
->selectAndLoadSymbols();
|
||||
return ipull($symbols, 'name');
|
||||
->loadObjects();
|
||||
}
|
||||
|
||||
public static function getImplementation($class) {
|
||||
$base = idx(self::getImplementations(), $class);
|
||||
|
||||
if ($base) {
|
||||
return (clone $base);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function requireImplementation($class) {
|
||||
if (!$class) {
|
||||
throw new Exception(pht('No implementation is specified!'));
|
||||
}
|
||||
|
||||
$implementation = self::getImplementation($class);
|
||||
if (!$implementation) {
|
||||
throw new Exception(pht('No such implementation "%s" exists!', $class));
|
||||
}
|
||||
|
||||
return $implementation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,4 +184,16 @@ abstract class HarbormasterBuildStepImplementation {
|
|||
return array();
|
||||
}
|
||||
|
||||
protected function formatSettingForDescription($key, $default = null) {
|
||||
return $this->formatValueForDescription($this->getSetting($key, $default));
|
||||
}
|
||||
|
||||
protected function formatValueForDescription($value) {
|
||||
if (strlen($value)) {
|
||||
return phutil_tag('strong', array(), $value);
|
||||
} else {
|
||||
return phutil_tag('em', array(), pht('(null)'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,12 +12,10 @@ final class HarbormasterCommandBuildStepImplementation
|
|||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return pht(
|
||||
'Run \'%s\' on \'%s\'.',
|
||||
$settings['command'],
|
||||
$settings['hostartifact']);
|
||||
'Run command %s on host %s.',
|
||||
$this->formatSettingForDescription('command'),
|
||||
$this->formatSettingForDescription('hostartifact'));
|
||||
}
|
||||
|
||||
public function execute(
|
||||
|
|
|
@ -12,11 +12,16 @@ final class HarbormasterHTTPRequestBuildStepImplementation
|
|||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
$domain = null;
|
||||
$uri = $this->getSetting('uri');
|
||||
if ($uri) {
|
||||
$domain = id(new PhutilURI($uri))->getDomain();
|
||||
}
|
||||
|
||||
$uri = new PhutilURI($settings['uri']);
|
||||
$domain = $uri->getDomain();
|
||||
return pht('Make an HTTP %s request to %s', $settings['method'], $domain);
|
||||
return pht(
|
||||
'Make an HTTP %s request to %s.',
|
||||
$this->formatSettingForDescription('method', 'POST'),
|
||||
$this->formatValueForDescription($domain));
|
||||
}
|
||||
|
||||
public function execute(
|
||||
|
|
|
@ -11,16 +11,6 @@ final class HarbormasterLeaseHostBuildStepImplementation
|
|||
return pht('Obtain a lease on a Drydock host for performing builds.');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return pht(
|
||||
'Obtain a lease on a Drydock host whose platform is \'%s\' and store '.
|
||||
'the resulting lease in a host artifact called \'%s\'.',
|
||||
$settings['platform'],
|
||||
$settings['name']);
|
||||
}
|
||||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
|
|
@ -12,12 +12,10 @@ final class HarbormasterPublishFragmentBuildStepImplementation
|
|||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return pht(
|
||||
'Publish file artifact \'%s\' to the fragment path \'%s\'.',
|
||||
$settings['artifact'],
|
||||
$settings['path']);
|
||||
'Publish file artifact %s as fragment %s.',
|
||||
$this->formatSettingForDescription('artifact'),
|
||||
$this->formatSettingForDescription('path'));
|
||||
}
|
||||
|
||||
public function execute(
|
||||
|
|
|
@ -12,9 +12,9 @@ final class HarbormasterSleepBuildStepImplementation
|
|||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return pht('Sleep for %s seconds.', $settings['seconds']);
|
||||
return pht(
|
||||
'Sleep for %s seconds.',
|
||||
$this->formatSettingForDescription('seconds'));
|
||||
}
|
||||
|
||||
public function execute(
|
||||
|
|
|
@ -11,10 +11,6 @@ final class HarbormasterThrowExceptionBuildStep
|
|||
return pht('Throw an exception.');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht('Throw an exception.');
|
||||
}
|
||||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
|
|
@ -4,20 +4,18 @@ final class HarbormasterUploadArtifactBuildStepImplementation
|
|||
extends HarbormasterBuildStepImplementation {
|
||||
|
||||
public function getName() {
|
||||
return pht('Upload Artifact');
|
||||
return pht('Upload File');
|
||||
}
|
||||
|
||||
public function getGenericDescription() {
|
||||
return pht('Upload an artifact from a Drydock host to Phabricator.');
|
||||
return pht('Upload a file from a host to Phabricator.');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
$settings = $this->getSettings();
|
||||
|
||||
return pht(
|
||||
'Upload artifact located at \'%s\' on \'%s\'.',
|
||||
$settings['path'],
|
||||
$settings['hostartifact']);
|
||||
'Upload %s from %s.',
|
||||
$this->formatSettingForDescription('path'),
|
||||
$this->formatSettingForDescription('hostartifact'));
|
||||
}
|
||||
|
||||
public function execute(
|
||||
|
|
|
@ -13,12 +13,6 @@ final class HarbormasterWaitForPreviousBuildStepImplementation
|
|||
'before continuing.');
|
||||
}
|
||||
|
||||
public function getDescription() {
|
||||
return pht(
|
||||
'Wait for previous commits to finish building the current plan '.
|
||||
'before continuing.');
|
||||
}
|
||||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
|
|
@ -9,6 +9,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
|
||||
private $buildable = self::ATTACHABLE;
|
||||
private $buildPlan = self::ATTACHABLE;
|
||||
private $buildTargets = self::ATTACHABLE;
|
||||
private $unprocessedCommands = self::ATTACHABLE;
|
||||
|
||||
/**
|
||||
|
@ -102,6 +103,15 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
return $this->assertAttached($this->buildPlan);
|
||||
}
|
||||
|
||||
public function getBuildTargets() {
|
||||
return $this->assertAttached($this->buildTargets);
|
||||
}
|
||||
|
||||
public function attachBuildTargets(array $targets) {
|
||||
$this->buildTargets = $targets;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isBuilding() {
|
||||
return $this->getBuildStatus() === self::STATUS_PENDING ||
|
||||
$this->getBuildStatus() === self::STATUS_WAITING ||
|
||||
|
|
|
@ -16,6 +16,7 @@ final class HarbormasterBuildTarget extends HarbormasterDAO
|
|||
|
||||
private $build = self::ATTACHABLE;
|
||||
private $buildStep = self::ATTACHABLE;
|
||||
private $implementation;
|
||||
|
||||
public static function initializeNewBuildTarget(
|
||||
HarbormasterBuild $build,
|
||||
|
@ -82,24 +83,14 @@ final class HarbormasterBuildTarget extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function getImplementation() {
|
||||
if ($this->className === null) {
|
||||
throw new Exception("No implementation set for the given target.");
|
||||
if ($this->implementation === null) {
|
||||
$obj = HarbormasterBuildStepImplementation::requireImplementation(
|
||||
$this->className);
|
||||
$obj->loadSettings($this);
|
||||
$this->implementation = $obj;
|
||||
}
|
||||
|
||||
static $implementations = null;
|
||||
if ($implementations === null) {
|
||||
$implementations =
|
||||
HarbormasterBuildStepImplementation::getImplementations();
|
||||
}
|
||||
|
||||
$class = $this->className;
|
||||
if (!in_array($class, $implementations)) {
|
||||
throw new Exception(
|
||||
"Class name '".$class."' does not extend BuildStepImplementation.");
|
||||
}
|
||||
$implementation = newv($class, array());
|
||||
$implementation->loadSettings($this);
|
||||
return $implementation;
|
||||
return $this->implementation;
|
||||
}
|
||||
|
||||
|
||||
|
@ -147,8 +138,7 @@ final class HarbormasterBuildTarget extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht(
|
||||
'Users must be able to see a build to view its build targets.');
|
||||
return pht('Users must be able to see a build to view its build targets.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ final class HarbormasterBuildStep extends HarbormasterDAO
|
|||
|
||||
private $buildPlan = self::ATTACHABLE;
|
||||
private $customFields = self::ATTACHABLE;
|
||||
private $implementation;
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
|
@ -46,24 +47,14 @@ final class HarbormasterBuildStep extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function getStepImplementation() {
|
||||
if ($this->className === null) {
|
||||
throw new Exception("No implementation set for the given step.");
|
||||
if ($this->implementation === null) {
|
||||
$obj = HarbormasterBuildStepImplementation::requireImplementation(
|
||||
$this->className);
|
||||
$obj->loadSettings($this);
|
||||
$this->implementation = $obj;
|
||||
}
|
||||
|
||||
static $implementations = null;
|
||||
if ($implementations === null) {
|
||||
$implementations =
|
||||
HarbormasterBuildStepImplementation::getImplementations();
|
||||
}
|
||||
|
||||
$class = $this->className;
|
||||
if (!in_array($class, $implementations)) {
|
||||
throw new Exception(
|
||||
"Class name '".$class."' does not extend BuildStepImplementation.");
|
||||
}
|
||||
$implementation = newv($class, array());
|
||||
$implementation->loadSettings($this);
|
||||
return $implementation;
|
||||
return $this->implementation;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue