Page MenuHomePhabricator

D8600.id20389.diff
No OneTemporary

D8600.id20389.diff

diff --git a/resources/sql/autopatches/20140321.harbor.1.bxaction.sql b/resources/sql/autopatches/20140321.harbor.1.bxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140321.harbor.1.bxaction.sql
@@ -0,0 +1,21 @@
+CREATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildsteptransaction (
+ id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ objectPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ viewPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ editPolicy VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ commentPHID VARCHAR(64) COLLATE utf8_bin,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) NOT NULL COLLATE utf8_bin,
+ oldValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ newValue LONGTEXT NOT NULL COLLATE utf8_bin,
+ contentSource LONGTEXT NOT NULL COLLATE utf8_bin,
+ metadata LONGTEXT NOT NULL COLLATE utf8_bin,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+
+ UNIQUE KEY `key_phid` (phid),
+ KEY `key_object` (objectPHID)
+
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -712,7 +712,12 @@
'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php',
'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php',
'HarbormasterBuildStep' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStep.php',
+ 'HarbormasterBuildStepCoreCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php',
+ 'HarbormasterBuildStepCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php',
+ 'HarbormasterBuildStepEditor' => 'applications/harbormaster/editor/HarbormasterBuildStepEditor.php',
'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php',
+ 'HarbormasterBuildStepTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php',
+ 'HarbormasterBuildStepTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildStepTransactionQuery.php',
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.php',
'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
@@ -3306,8 +3311,18 @@
array(
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
+ 2 => 'PhabricatorCustomFieldInterface',
+ ),
+ 'HarbormasterBuildStepCoreCustomField' =>
+ array(
+ 0 => 'HarbormasterBuildStepCustomField',
+ 1 => 'PhabricatorStandardCustomFieldInterface',
),
+ 'HarbormasterBuildStepCustomField' => 'PhabricatorCustomField',
+ 'HarbormasterBuildStepEditor' => 'PhabricatorApplicationTransactionEditor',
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'HarbormasterBuildStepTransaction' => 'PhabricatorApplicationTransaction',
+ 'HarbormasterBuildStepTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'HarbormasterBuildTarget' =>
array(
0 => 'HarbormasterDAO',
diff --git a/src/applications/harbormaster/controller/HarbormasterStepEditController.php b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
--- a/src/applications/harbormaster/controller/HarbormasterStepEditController.php
+++ b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
@@ -27,85 +27,39 @@
$plan = $step->getBuildPlan();
$implementation = $step->getStepImplementation();
- $implementation->validateSettingDefinitions();
- $settings = $implementation->getSettings();
+
+ $field_list = PhabricatorCustomField::getObjectFields(
+ $step,
+ PhabricatorCustomField::ROLE_EDIT);
+ $field_list
+ ->setViewer($viewer)
+ ->readFieldsFromStorage($step);
$errors = array();
+ $validation_exception = null;
if ($request->isFormPost()) {
- foreach ($implementation->getSettingDefinitions() as $name => $opt) {
- $readable_name = $this->getReadableName($name, $opt);
- $value = $this->getValueFromRequest($request, $name, $opt['type']);
-
- // TODO: This won't catch any validation issues unless the field
- // is missing completely. How should we check if the user is
- // required to enter an integer?
- if ($value === null) {
- $errors[] = $readable_name.' is not valid.';
- } else {
- $step->setDetail($name, $value);
- }
- }
+ $xactions = $field_list->buildFieldTransactionsFromRequest(
+ new HarbormasterBuildStepTransaction(),
+ $request);
- if (!$errors) {
- $step->save();
+ $editor = id(new HarbormasterBuildStepEditor())
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContentSourceFromRequest($request);
+
+ try {
+ $editor->applyTransactions($step, $xactions);
return id(new AphrontRedirectResponse())
->setURI($this->getApplicationURI('plan/'.$plan->getID().'/'));
+ } catch (PhabricatorApplicationTransactionValidationException $ex) {
+ $validation_exception = $ex;
}
}
$form = id(new AphrontFormView())
->setUser($viewer);
- // We need to render out all of the fields for the settings that
- // the implementation has.
- foreach ($implementation->getSettingDefinitions() as $name => $opt) {
- if ($request->isFormPost()) {
- $value = $this->getValueFromRequest($request, $name, $opt['type']);
- } else {
- $value = $settings[$name];
- }
-
- switch ($opt['type']) {
- case BuildStepImplementation::SETTING_TYPE_STRING:
- case BuildStepImplementation::SETTING_TYPE_INTEGER:
- $control = id(new AphrontFormTextControl())
- ->setLabel($this->getReadableName($name, $opt))
- ->setName($name)
- ->setValue($value);
- break;
- case BuildStepImplementation::SETTING_TYPE_BOOLEAN:
- $control = id(new AphrontFormCheckboxControl())
- ->setLabel($this->getReadableName($name, $opt))
- ->setName($name)
- ->setValue($value);
- break;
- case BuildStepImplementation::SETTING_TYPE_ARTIFACT:
- $filter = $opt['artifact_type'];
- $available_artifacts =
- BuildStepImplementation::loadAvailableArtifacts(
- $plan,
- $step,
- $filter);
- $options = array();
- foreach ($available_artifacts as $key => $type) {
- $options[$key] = $key;
- }
- $control = id(new AphrontFormSelectControl())
- ->setLabel($this->getReadableName($name, $opt))
- ->setName($name)
- ->setValue($value)
- ->setOptions($options);
- break;
- default:
- throw new Exception("Unable to render field with unknown type.");
- }
-
- if (isset($opt['description'])) {
- $control->setCaption($opt['description']);
- }
-
- $form->appendChild($control);
- }
+ $field_list->appendFieldsToForm($form);
$form->appendChild(
id(new AphrontFormSubmitControl())
@@ -115,7 +69,7 @@
$box = id(new PHUIObjectBoxView())
->setHeaderText('Edit Step: '.$implementation->getName())
- ->setValidationException(null)
+ ->setValidationException($validation_exception)
->setForm($form);
$crumbs = $this->buildApplicationCrumbs();
@@ -127,11 +81,23 @@
$variables = $this->renderBuildVariablesTable();
+ $xactions = id(new HarbormasterBuildStepTransactionQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($step->getPHID()))
+ ->execute();
+
+ $xaction_view = id(new PhabricatorApplicationTransactionView())
+ ->setUser($viewer)
+ ->setObjectPHID($step->getPHID())
+ ->setTransactions($xactions)
+ ->setShouldTerminate(true);
+
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$variables,
+ $xaction_view,
),
array(
'title' => $implementation->getName(),
@@ -139,31 +105,6 @@
));
}
- public function getReadableName($name, $opt) {
- $readable_name = $name;
- if (isset($opt['name'])) {
- $readable_name = $opt['name'];
- }
- return $readable_name;
- }
-
- public function getValueFromRequest(AphrontRequest $request, $name, $type) {
- switch ($type) {
- case BuildStepImplementation::SETTING_TYPE_STRING:
- case BuildStepImplementation::SETTING_TYPE_ARTIFACT:
- return $request->getStr($name);
- break;
- case BuildStepImplementation::SETTING_TYPE_INTEGER:
- return $request->getInt($name);
- break;
- case BuildStepImplementation::SETTING_TYPE_BOOLEAN:
- return $request->getBool($name);
- break;
- default:
- throw new Exception("Unsupported setting type '".$type."'.");
- }
- }
-
private function renderBuildVariablesTable() {
$viewer = $this->getRequest()->getUser();
diff --git a/src/applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php b/src/applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php
@@ -0,0 +1,41 @@
+<?php
+
+final class HarbormasterBuildStepCoreCustomField
+ extends HarbormasterBuildStepCustomField
+ implements PhabricatorStandardCustomFieldInterface {
+
+ public function getStandardCustomFieldNamespace() {
+ return 'harbormaster:core';
+ }
+
+ public function createFields($object) {
+ $specs = $object->getStepImplementation()->getFieldSpecifications();
+ return PhabricatorStandardCustomField::buildStandardFields($this, $specs);
+ }
+
+ public function shouldUseStorage() {
+ return false;
+ }
+
+ public function readValueFromObject(PhabricatorCustomFieldInterface $object) {
+ $key = $this->getProxy()->getRawStandardFieldKey();
+ $this->setValueFromStorage($object->getDetail($key));
+ }
+
+ public function applyApplicationTransactionInternalEffects(
+ PhabricatorApplicationTransaction $xaction) {
+ $object = $this->getObject();
+ $key = $this->getProxy()->getRawStandardFieldKey();
+
+ $this->setValueFromApplicationTransactions($xaction->getNewValue());
+ $value = $this->getValueForStorage();
+
+ $object->setDetail($key, $value);
+ }
+
+ public function applyApplicationTransactionExternalEffects(
+ PhabricatorApplicationTransaction $xaction) {
+ return;
+ }
+
+}
diff --git a/src/applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php b/src/applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php
@@ -0,0 +1,6 @@
+<?php
+
+abstract class HarbormasterBuildStepCustomField
+ extends PhabricatorCustomField {
+
+}
diff --git a/src/applications/harbormaster/editor/HarbormasterBuildStepEditor.php b/src/applications/harbormaster/editor/HarbormasterBuildStepEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/editor/HarbormasterBuildStepEditor.php
@@ -0,0 +1,6 @@
+<?php
+
+final class HarbormasterBuildStepEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+}
diff --git a/src/applications/harbormaster/query/HarbormasterBuildStepTransactionQuery.php b/src/applications/harbormaster/query/HarbormasterBuildStepTransactionQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/query/HarbormasterBuildStepTransactionQuery.php
@@ -0,0 +1,10 @@
+<?php
+
+final class HarbormasterBuildStepTransactionQuery
+ extends PhabricatorApplicationTransactionQuery {
+
+ public function getTemplateApplicationTransaction() {
+ return new HarbormasterBuildStepTransaction();
+ }
+
+}
diff --git a/src/applications/harbormaster/step/BuildStepImplementation.php b/src/applications/harbormaster/step/BuildStepImplementation.php
--- a/src/applications/harbormaster/step/BuildStepImplementation.php
+++ b/src/applications/harbormaster/step/BuildStepImplementation.php
@@ -2,16 +2,9 @@
abstract class BuildStepImplementation {
- private $settings;
-
- const SETTING_TYPE_STRING = 'string';
- const SETTING_TYPE_INTEGER = 'integer';
- const SETTING_TYPE_BOOLEAN = 'boolean';
- const SETTING_TYPE_ARTIFACT = 'artifact';
-
public static function getImplementations() {
$symbols = id(new PhutilSymbolLoader())
- ->setAncestorClass("BuildStepImplementation")
+ ->setAncestorClass('BuildStepImplementation')
->setConcreteOnly(true)
->selectAndLoadSymbols();
return ipull($symbols, 'name');
@@ -33,7 +26,7 @@
* The description of the implementation, based on the current settings.
*/
public function getDescription() {
- return '';
+ return $this->getGenericDescription();
}
/**
@@ -55,43 +48,12 @@
}
/**
- * Validate the current settings of this build step.
- */
- public function validateSettings() {
- return true;
- }
-
- /**
* Loads the settings for this build step implementation from a build
* step or target.
*/
public final function loadSettings($build_object) {
- $this->settings = array();
- $this->validateSettingDefinitions();
- foreach ($this->getSettingDefinitions() as $name => $opt) {
- $this->settings[$name] = $build_object->getDetail($name);
- }
- return $this->settings;
- }
-
- /**
- * Validates that the setting definitions for this implementation are valid.
- */
- public final function validateSettingDefinitions() {
- foreach ($this->getSettingDefinitions() as $name => $opt) {
- if (!isset($opt['type'])) {
- throw new Exception(
- 'Setting definition \''.$name.
- '\' is missing type requirement.');
- }
- }
- }
-
- /**
- * Return an array of settings for this step implementation.
- */
- public function getSettingDefinitions() {
- return array();
+ $this->settings = $build_object->getDetails();
+ return $this;
}
/**
@@ -197,4 +159,8 @@
return call_user_func($function, $pattern, $argv);
}
+ public function getFieldSpecifications() {
+ return array();
+ }
+
}
diff --git a/src/applications/harbormaster/step/CommandBuildStepImplementation.php b/src/applications/harbormaster/step/CommandBuildStepImplementation.php
--- a/src/applications/harbormaster/step/CommandBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/CommandBuildStepImplementation.php
@@ -74,22 +74,6 @@
}
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['command'] === null || !is_string($settings['command'])) {
- return false;
- }
- if ($settings['hostartifact'] === null ||
- !is_string($settings['hostartifact'])) {
- return false;
- }
-
- // TODO: Check if the host artifact is provided by previous build steps.
-
- return true;
- }
-
public function getArtifactInputs() {
return array(
array(
@@ -100,19 +84,19 @@
);
}
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'command' => array(
- 'name' => 'Command',
- 'description' => 'The command to execute on the remote machine.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING),
+ 'name' => pht('Command'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
'hostartifact' => array(
- 'name' => 'Host Artifact',
- 'description' =>
- 'The host artifact that determines what machine the command '.
- 'will run on.',
- 'type' => BuildStepImplementation::SETTING_TYPE_ARTIFACT,
- 'artifact_type' => HarbormasterBuildArtifact::TYPE_HOST));
+ 'name' => pht('Host'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
+ );
}
}
diff --git a/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
@@ -34,10 +34,7 @@
$log_body = $build->createLog($build_target, $uri, 'http-body');
$start = $log_body->start();
- $method = 'POST';
- if ($settings['method'] !== '') {
- $method = $settings['method'];
- }
+ $method = nonempty(idx($settings, 'method'), 'POST');
list($status, $body, $headers) = id(new HTTPSFuture($uri))
->setMethod($method)
@@ -52,42 +49,17 @@
}
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['uri'] === null || !is_string($settings['uri'])) {
- return false;
- }
-
- $methods = array(
- 'GET' => true,
- 'POST' => true,
- 'DELETE' => true,
- 'PUT' => true,
- );
-
- $method = idx($settings, 'method');
- if (strlen($method)) {
- if (empty($methods[$method])) {
- return false;
- }
- }
-
- return true;
- }
-
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'uri' => array(
- 'name' => 'URI',
- 'description' => pht('The URI to request.'),
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING,
+ 'name' => pht('URI'),
+ 'type' => 'text',
+ 'required' => true,
),
'method' => array(
- 'name' => 'Method',
- 'description' =>
- pht('Request type. Should be GET, POST, PUT, or DELETE.'),
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING,
+ 'name' => pht('HTTP Method'),
+ 'type' => 'select',
+ 'options' => array_fuse(array('POST', 'GET', 'PUT', 'DELETE')),
),
);
}
diff --git a/src/applications/harbormaster/step/LeaseHostBuildStepImplementation.php b/src/applications/harbormaster/step/LeaseHostBuildStepImplementation.php
--- a/src/applications/harbormaster/step/LeaseHostBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/LeaseHostBuildStepImplementation.php
@@ -51,19 +51,6 @@
$artifact->save();
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['name'] === null || !is_string($settings['name'])) {
- return false;
- }
- if ($settings['platform'] === null || !is_string($settings['platform'])) {
- return false;
- }
-
- return true;
- }
-
public function getArtifactOutputs() {
return array(
array(
@@ -74,17 +61,19 @@
);
}
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'name' => array(
- 'name' => 'Artifact Name',
- 'description' =>
- 'The name of the artifact to reference in future build steps.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING),
+ 'name' => pht('Artifact Name'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
'platform' => array(
- 'name' => 'Platform',
- 'description' => 'The platform of the host.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING));
+ 'name' => pht('Platform'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
+ );
}
}
diff --git a/src/applications/harbormaster/step/PublishFragmentBuildStepImplementation.php b/src/applications/harbormaster/step/PublishFragmentBuildStepImplementation.php
--- a/src/applications/harbormaster/step/PublishFragmentBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/PublishFragmentBuildStepImplementation.php
@@ -57,22 +57,6 @@
}
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['path'] === null || !is_string($settings['path'])) {
- return false;
- }
- if ($settings['artifact'] === null ||
- !is_string($settings['artifact'])) {
- return false;
- }
-
- // TODO: Check if the file artifact is provided by previous build steps.
-
- return true;
- }
-
public function getArtifactInputs() {
return array(
array(
@@ -83,19 +67,19 @@
);
}
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'path' => array(
- 'name' => 'Path',
- 'description' =>
- 'The path of the fragment that will be published.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING),
+ 'name' => pht('Path'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
'artifact' => array(
- 'name' => 'File Artifact',
- 'description' =>
- 'The file artifact that will be published to Phragment.',
- 'type' => BuildStepImplementation::SETTING_TYPE_ARTIFACT,
- 'artifact_type' => HarbormasterBuildArtifact::TYPE_FILE));
+ 'name' => pht('File Artifact'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
+ );
}
}
diff --git a/src/applications/harbormaster/step/SleepBuildStepImplementation.php b/src/applications/harbormaster/step/SleepBuildStepImplementation.php
--- a/src/applications/harbormaster/step/SleepBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/SleepBuildStepImplementation.php
@@ -25,24 +25,15 @@
sleep($settings['seconds']);
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['seconds'] === null) {
- return false;
- }
- if (!is_int($settings['seconds'])) {
- return false;
- }
- return true;
- }
-
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'seconds' => array(
- 'name' => 'Seconds',
- 'description' => 'The number of seconds to sleep for.',
- 'type' => BuildStepImplementation::SETTING_TYPE_INTEGER));
+ 'name' => pht('Seconds'),
+ 'type' => 'int',
+ 'required' => true,
+ 'caption' => pht('The number of seconds to sleep for.'),
+ ),
+ );
}
}
diff --git a/src/applications/harbormaster/step/UploadArtifactBuildStepImplementation.php b/src/applications/harbormaster/step/UploadArtifactBuildStepImplementation.php
--- a/src/applications/harbormaster/step/UploadArtifactBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/UploadArtifactBuildStepImplementation.php
@@ -51,25 +51,6 @@
$artifact->save();
}
- public function validateSettings() {
- $settings = $this->getSettings();
-
- if ($settings['path'] === null || !is_string($settings['path'])) {
- return false;
- }
- if ($settings['name'] === null || !is_string($settings['name'])) {
- return false;
- }
- if ($settings['hostartifact'] === null ||
- !is_string($settings['hostartifact'])) {
- return false;
- }
-
- // TODO: Check if the host artifact is provided by previous build steps.
-
- return true;
- }
-
public function getArtifactInputs() {
return array(
array(
@@ -90,28 +71,24 @@
);
}
- public function getSettingDefinitions() {
+ public function getFieldSpecifications() {
return array(
'path' => array(
- 'name' => 'Path',
- 'description' =>
- 'The path of the file that should be retrieved. Note that on '.
- 'Windows machines running FreeSSHD, this path will be relative '.
- 'to the SFTP root path (configured under the SFTP tab). You can '.
- 'not specify an absolute path for Windows machines.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING),
+ 'name' => pht('Path'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
'name' => array(
- 'name' => 'Local Name',
- 'description' =>
- 'The name for the file when it is stored in Phabricator.',
- 'type' => BuildStepImplementation::SETTING_TYPE_STRING),
+ 'name' => pht('Local Name'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
'hostartifact' => array(
- 'name' => 'Host Artifact',
- 'description' =>
- 'The host artifact that determines what machine the command '.
- 'will run on.',
- 'type' => BuildStepImplementation::SETTING_TYPE_ARTIFACT,
- 'artifact_type' => HarbormasterBuildArtifact::TYPE_HOST));
+ 'name' => pht('Host Artifact'),
+ 'type' => 'text',
+ 'required' => true,
+ ),
+ );
}
}
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
--- a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
@@ -1,7 +1,9 @@
<?php
final class HarbormasterBuildStep extends HarbormasterDAO
- implements PhabricatorPolicyInterface {
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorCustomFieldInterface {
protected $buildPlanPHID;
protected $className;
@@ -9,6 +11,7 @@
protected $sequence;
private $buildPlan = self::ATTACHABLE;
+ private $customFields = self::ATTACHABLE;
public function getConfiguration() {
return array(
@@ -83,4 +86,25 @@
public function describeAutomaticCapability($capability) {
return pht('A build step has the same policies as its build plan.');
}
+
+/* -( PhabricatorCustomFieldInterface )------------------------------------ */
+
+ public function getCustomFieldSpecificationForRole($role) {
+ return array();
+ }
+
+ public function getCustomFieldBaseClass() {
+ return 'HarbormasterBuildStepCustomField';
+ }
+
+ public function getCustomFields() {
+ return $this->assertAttached($this->customFields);
+ }
+
+ public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
+ $this->customFields = $fields;
+ return $this;
+ }
+
+
}
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php
@@ -0,0 +1,14 @@
+<?php
+
+final class HarbormasterBuildStepTransaction
+ extends PhabricatorApplicationTransaction {
+
+ public function getApplicationName() {
+ return 'harbormaster';
+ }
+
+ public function getApplicationTransactionType() {
+ return HarbormasterPHIDTypeBuildStep::TYPECONST;
+ }
+
+}
diff --git a/src/applications/maniphest/field/ManiphestConfiguredCustomField.php b/src/applications/maniphest/field/ManiphestConfiguredCustomField.php
--- a/src/applications/maniphest/field/ManiphestConfiguredCustomField.php
+++ b/src/applications/maniphest/field/ManiphestConfiguredCustomField.php
@@ -8,7 +8,7 @@
return 'maniphest';
}
- public function createFields() {
+ public function createFields($object) {
$config = PhabricatorEnv::getEnvConfig(
'maniphest.custom-field-definitions',
array());
diff --git a/src/applications/people/customfield/PhabricatorUserConfiguredCustomField.php b/src/applications/people/customfield/PhabricatorUserConfiguredCustomField.php
--- a/src/applications/people/customfield/PhabricatorUserConfiguredCustomField.php
+++ b/src/applications/people/customfield/PhabricatorUserConfiguredCustomField.php
@@ -8,7 +8,7 @@
return 'user';
}
- public function createFields() {
+ public function createFields($object) {
return PhabricatorStandardCustomField::buildStandardFields(
$this,
PhabricatorEnv::getEnvConfig('user.custom-field-definitions', array()));
diff --git a/src/applications/project/customfield/PhabricatorProjectConfiguredCustomField.php b/src/applications/project/customfield/PhabricatorProjectConfiguredCustomField.php
--- a/src/applications/project/customfield/PhabricatorProjectConfiguredCustomField.php
+++ b/src/applications/project/customfield/PhabricatorProjectConfiguredCustomField.php
@@ -8,7 +8,7 @@
return 'project';
}
- public function createFields() {
+ public function createFields($object) {
return PhabricatorStandardCustomField::buildStandardFields(
$this,
PhabricatorEnv::getEnvConfig(
diff --git a/src/applications/project/customfield/PhabricatorProjectDescriptionField.php b/src/applications/project/customfield/PhabricatorProjectDescriptionField.php
--- a/src/applications/project/customfield/PhabricatorProjectDescriptionField.php
+++ b/src/applications/project/customfield/PhabricatorProjectDescriptionField.php
@@ -3,7 +3,7 @@
final class PhabricatorProjectDescriptionField
extends PhabricatorProjectStandardCustomField {
- public function createFields() {
+ public function createFields($object) {
return PhabricatorStandardCustomField::buildStandardFields(
$this,
array(
diff --git a/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php b/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php
--- a/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php
+++ b/src/infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php
@@ -43,9 +43,14 @@
foreach ($faux_spec as $key => $spec) {
unset($faux_spec[$key]['disabled']);
}
+
+ // TODO: We might need to build a real object here eventually.
+ $faux_object = null;
+
$fields = PhabricatorCustomField::buildFieldList(
$field_base_class,
- $faux_spec);
+ $faux_spec,
+ $faux_object);
$list_id = celerity_generate_unique_node_id();
$input_id = celerity_generate_unique_node_id();
diff --git a/src/infrastructure/customfield/field/PhabricatorCustomField.php b/src/infrastructure/customfield/field/PhabricatorCustomField.php
--- a/src/infrastructure/customfield/field/PhabricatorCustomField.php
+++ b/src/infrastructure/customfield/field/PhabricatorCustomField.php
@@ -60,7 +60,10 @@
"object of class '{$obj_class}'.");
}
- $fields = PhabricatorCustomField::buildFieldList($base_class, $spec);
+ $fields = PhabricatorCustomField::buildFieldList(
+ $base_class,
+ $spec,
+ $object);
foreach ($fields as $key => $field) {
if (!$field->shouldEnableForRole($role)) {
@@ -97,7 +100,7 @@
/**
* @task apps
*/
- public static function buildFieldList($base_class, array $spec) {
+ public static function buildFieldList($base_class, array $spec, $object) {
$field_objects = id(new PhutilSymbolLoader())
->setAncestorClass($base_class)
->loadObjects();
@@ -106,7 +109,7 @@
$from_map = array();
foreach ($field_objects as $field_object) {
$current_class = get_class($field_object);
- foreach ($field_object->createFields() as $field) {
+ foreach ($field_object->createFields($object) as $field) {
$key = $field->getFieldKey();
if (isset($fields[$key])) {
$original_class = $from_map[$key];
@@ -200,10 +203,11 @@
* For general implementations, the general field implementation can return
* multiple field instances here.
*
+ * @param object The object to create fields for.
* @return list<PhabricatorCustomField> List of fields.
* @task core
*/
- public function createFields() {
+ public function createFields($object) {
return array($this);
}
@@ -239,9 +243,9 @@
* @task core
*/
public function shouldEnableForRole($role) {
- if ($this->proxy) {
- return $this->proxy->shouldEnableForRole($role);
- }
+
+ // NOTE: All of these calls proxy individually, so we don't need to
+ // proxy this call as a whole.
switch ($role) {
case self::ROLE_APPLICATIONTRANSACTIONS:
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomField.php
@@ -3,6 +3,7 @@
abstract class PhabricatorStandardCustomField
extends PhabricatorCustomField {
+ private $rawKey;
private $fieldKey;
private $fieldName;
private $fieldValue;
@@ -40,6 +41,7 @@
$template = clone $template;
$standard = id(clone $types[$type])
+ ->setRawStandardFieldKey($key)
->setFieldKey($full_key)
->setFieldConfig($value)
->setApplicationField($template);
@@ -142,6 +144,15 @@
return $this->required;
}
+ public function setRawStandardFieldKey($raw_key) {
+ $this->rawKey = $raw_key;
+ return $this;
+ }
+
+ public function getRawStandardFieldKey() {
+ return $this->rawKey;
+ }
+
/* -( PhabricatorCustomField )--------------------------------------------- */

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 23, 7:51 PM (3 w, 5 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/by/sf/22jmdyq42aahce7y
Default Alt Text
D8600.id20389.diff (33 KB)

Event Timeline