Skip to content

Commit

Permalink
Merge pull request #115 from palantirnet/keep-artifact
Browse files Browse the repository at this point in the history
Allow keeping the result of an artifact build without cleaning it up
  • Loading branch information
becw authored Nov 20, 2018
2 parents d497081 + d39b712 commit 7afd060
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 29 deletions.
4 changes: 2 additions & 2 deletions docs/artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ All artifact configuration should be in your project's base properties file, `.t

## Runtime flags

* `push` - Value should be `y` or `n`. When this flag is provided, it will bypass the "Push artifact changes?" prompt.
* `artifact.result` - Value should be `push`, `keep`, or `discard`. When this flag is provided, it will bypass the "Push artifact changes?" prompt.

```
$> phing artifact -Dpush=y
$> phing artifact -Dartifact.result=keep
```

## Examples
Expand Down
129 changes: 129 additions & 0 deletions src/TheBuild/SelectOneTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php
/**
* @file SelectOneTask.php
*
* Interactively select one item from a comma-separated list.
*
* - If the propertyName property is already set, the task does nothing
* - If there is only one item in the list, the user is not prompted
* - If the list is empty, validation fails
* - If there are multiple items in the list, the user will be prompted to
* select one using a multiple choice menu
*
* @code
* <taskdef name="selectone" classname="TheBuild\SelectOneTask" />
* <selectone list="red,green,blue" propertyName="color" />
* <selectone list="red:green:blue" propertyName="color" delimiter=":" message="Choose a color:" />
* @endcode
*
* @copyright 2018 Palantir.net, Inc.
*/

namespace TheBuild;

use BuildException;
use Project;


class SelectOneTask extends \Task {

/**
* @var string
* Required. List of values to select among.
*/
protected $list = '';

/**
* @var string
* String to split the list by.
*/
protected $delimiter = ',';

/**
* @var string
* Required. Property to populate with the selected value.
*/
protected $propertyName = '';

/**
* @var string
* Message to display to the user when more than one key is available.
*/
protected $message = 'Select one:';


/**
* Select menu.
*/
public function main() {
$this->validate();

$project = $this->getProject();

if ($existing_value = $this->project->getProperty($this->propertyName)) {
$this->log("Using {$this->propertyName} = '{$existing_value}' (existing value)", Project::MSG_INFO);
return;
}

$keys = array_map('trim', explode($this->delimiter, $this->list));

if (count($keys) > 1) {
// Prompt for input.
$request = new MenuInputRequest($this->message);
$request->setOptions($keys);

$this->project->getInputHandler()->handleInput($request);

$value = $request->getInput();
}
elseif (count($keys) == 1) {
$value = current($keys);
$this->log("Using {$this->propertyName} = '{$value}' (one value found)", Project::MSG_INFO);
}

if ($value) {
$project->setNewProperty($this->propertyName, $value);
}
}


/**
* Verify that the required attributes are set.
*/
public function validate() {
foreach (['list', 'propertyName'] as $attribute) {
if (empty($this->$attribute)) {
throw new BuildException("$attribute attribute is required.", $this->location);
}
}
}

/**
* @param string $value
*/
public function setList($value) {
$this->list = $value;
}

/**
* @param string $value
*/
public function setDelimiter($value) {
$this->delimiter = $value;
}

/**
* @param string $value
*/
public function setPropertyName($value) {
$this->propertyName = $value;
}

/**
* @param string $value
*/
public function setMessage($value) {
$this->message = $value;
}

}
68 changes: 47 additions & 21 deletions tasks/artifact.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@

<phingcall target="artifact-commit" />

<phingcall target="artifact-optionalPush" />

<phingcall target="artifact-resetState" />
<phingcall target="artifact-finish" />
</target>


Expand Down Expand Up @@ -276,38 +274,66 @@
</target>


<target name="artifact-optionalPush">
<target name="artifact-finish">
<selectone list="push,keep,discard" propertyName="artifact.result" message="Push artifact changes to the '${artifact.git.remote_branch}' branch?" />

<if>
<or>
<equals arg1="${push}" arg2="" />
<not><isset property="push" /></not>
</or>
<equals arg1="${artifact.result}" arg2="push" />
<then>
<input propertyName="push" message="Push artifact changes to the '${artifact.git.remote_branch}' branch?" validArgs="y,n" />
<!-- Push the changes, delete the temporary branch, and keep any tag that was created. -->
<phingcall target="artifact-push" />
<phingcall target="artifact-resetState" />
</then>
</if>

<if>
<equals arg1="${push}" arg2="y" />
<equals arg1="${artifact.result}" arg2="keep" />
<then>
<echo>Pushing changes.</echo>
<exec dir="${artifact.directory}" command="git push ${artifact.git.remote_name} ${artifact.git.temporary_branch}:${artifact.git.remote_branch}" checkreturn="true" />
<!-- Keep the temporary branch, but delete any tag that was created, since if we run the artifact
generation again, the tag should be re-created against the regenerated artifact. -->
<phingcall target="artifact-cleanupTag" />
<echo>Artifact changes are in the temporary branch '${artifact.git.temporary_branch}'</echo>
</then>
</if>

<!-- If this is a build of a tag, push the new artifact tag. -->
<if>
<equals arg1="${artifact.git.no_tag}" arg2="0" />
<then>
<exec dir="${artifact.directory}" command="git push ${artifact.git.remote_name} ${artifact.git.artifact_tag}" checkreturn="true" />
</then>
</if>
<if>
<equals arg1="${artifact.result}" arg2="discard" />
<then>
<!-- Delete the temporary branch and any tag that was created. -->
<phingcall target="artifact-cleanupTag" />
<phingcall target="artifact-resetState" />
</then>
</if>
</target>


<target name="artifact-push">
<echo>Pushing changes.</echo>
<exec dir="${artifact.directory}" command="git push ${artifact.git.remote_name} ${artifact.git.temporary_branch}:${artifact.git.remote_branch}" checkreturn="true" />

<!-- If this is a build of a tag, push the new artifact tag. -->
<if>
<equals arg1="${artifact.git.no_tag}" arg2="0" />
<then>
<exec dir="${artifact.directory}" command="git push ${artifact.git.remote_name} ${artifact.git.artifact_tag}" checkreturn="true" />
</then>
</if>
</target>


<target name="artifact-cleanupTag">
<if>
<equals arg1="${artifact.git.no_tag}" arg2="0" />
<then>
<exec dir="${artifact.directory}" command="git tag -d ${artifact.git.artifact_tag}" checkreturn="true" logoutput="true" />
</then>
</if>
</target>


<target name="artifact-resetState">
<exec dir="${artifact.directory}" command="chmod -R 750 * " checkreturn="true" logoutput="true" />
<exec dir="${artifact.directory}" command="git checkout -- ." checkreturn="true" logoutput="true" />
<exec dir="${artifact.directory}" command="chmod -R 750 ." checkreturn="true" logoutput="true" />
<exec dir="${artifact.directory}" command="git reset --hard HEAD" checkreturn="true" logoutput="true" />
<exec dir="${artifact.directory}" command="git checkout ${artifact.git.remote_base_branch}" checkreturn="true" logoutput="true" />
<exec dir="${artifact.directory}" command="git clean -ffd" checkreturn="true" />
<exec dir="${artifact.directory}" command="git branch -D ${artifact.git.temporary_branch}" checkreturn="true" logoutput="true" />
Expand Down
15 changes: 9 additions & 6 deletions tasks/the-build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<!-- Provide the <selectpropertykey /> task. -->
<taskdef name="selectpropertykey" classname="TheBuild\SelectPropertyKeyTask" />

<!-- Provide the <selectone /> task. -->
<taskdef name="selectone" classname="TheBuild\SelectOneTask" />


<!-- Alias the build directory to the Phing start directory. -->
<property name="build.dir" value="${application.startdir}" />
Expand Down Expand Up @@ -92,15 +95,15 @@


<!-- Configure the composer command, depending on whether `composer` or `composer.phar` is available. -->
<exec command="command -V composer" returnProperty="composer.not_available.composer" />
<exec command="command -V composer.phar" returnProperty="composer.not_available.composer_phar" />
<exec command="command -v composer" outputProperty="composer.path.composer" />
<exec command="command -v composer.phar" outputProperty="composer.path.composer_phar" />
<if>
<isfalse value="${composer.not_available.composer}" />
<then><property name="composer.composer" value="composer" /></then>
<not><equals arg1="${composer.path.composer}" arg2="" /></not>
<then><property name="composer.composer" value="${composer.path.composer}" /></then>
</if>
<if>
<isfalse value="${composer.not_available.composer_phar}" />
<then><property name="composer.composer" value="composer.phar" /></then>
<not><equals arg1="${composer.path.composer_phar}" arg2="" /></not>
<then><property name="composer.composer" value="${composer.path.composer_phar}" /></then>
</if>


Expand Down

0 comments on commit 7afd060

Please sign in to comment.