Skip to content

Commit a04adb7

Browse files
committed
dry-coded rollback command
1 parent 8dbd1db commit a04adb7

File tree

8 files changed

+139
-3
lines changed

8 files changed

+139
-3
lines changed

src/Liip/RMT/Action/BaseAction.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ public function __construct($options = array())
2727
*/
2828
abstract public function execute();
2929

30+
/**
31+
* Rollback the effect of this action
32+
*/
33+
public function rollback()
34+
{
35+
// assume there is nothing to do by default
36+
}
37+
3038
/**
3139
* Return the name of the action as it will be display to the user
3240
*

src/Liip/RMT/Action/VcsCommitAction.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,19 @@ public function execute()
3838

3939
return;
4040
}
41-
$vcs->saveWorkingCopy(
42-
str_replace('%version%', Context::getParam('new-version'), $this->options['commit-message'])
43-
);
41+
$vcs->saveWorkingCopy($this->getCommitMessage(Context::getParam('new-version')));
42+
$this->confirmSuccess();
43+
}
44+
45+
public function rollback()
46+
{
47+
$version = Context::get('version-persister')->getCurrentVersion();
48+
Context::get('vcs')->revertLastCommit($this->getCommitMessage($version));
4449
$this->confirmSuccess();
4550
}
51+
52+
protected function getCommitMessage($version)
53+
{
54+
return str_replace('%version%', $version, $this->options['commit-message']);
55+
}
4656
}

src/Liip/RMT/Action/VcsTagAction.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,12 @@ public function execute()
2727
);
2828
$this->confirmSuccess();
2929
}
30+
31+
public function rollback()
32+
{
33+
$tag = Context::get('version-persister')->getCurrentVersionTag();
34+
Context::get('vcs')->deleteTag($tag);
35+
$this->confirmSuccess();
36+
}
37+
3038
}

src/Liip/RMT/Application.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Liip\RMT\Command\CurrentCommand;
1919
use Liip\RMT\Command\ConfigCommand;
2020
use Liip\RMT\Command\InitCommand;
21+
use Liip\RMT\Command\RollbackCommand;
2122
use Symfony\Component\Console\Input\InputInterface;
2223
use Symfony\Component\Console\Output\OutputInterface;
2324
use Symfony\Component\Console\Application as BaseApplication;
@@ -50,6 +51,7 @@ public function __construct()
5051
// Add command that require the config file
5152
if (file_exists($this->getConfigFilePath())) {
5253
$this->add(new ReleaseCommand());
54+
$this->add(new RollbackCommand());
5355
$this->add(new CurrentCommand());
5456
$this->add(new ChangesCommand());
5557
$this->add(new ConfigCommand());
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the project RMT
5+
*
6+
* Copyright (c) 2013, Liip AG, http://www.liip.ch
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Liip\RMT\Command;
13+
14+
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Output\OutputInterface;
16+
use Liip\RMT\Context;
17+
18+
/**
19+
* Rollback the last release
20+
*/
21+
class RollbackCommand extends BaseCommand
22+
{
23+
/**
24+
* {@inheritdoc}
25+
*/
26+
protected function configure()
27+
{
28+
$this->setName('rollback');
29+
$this->setDescription('Rollback the last release if there was no change since.');
30+
$this->setHelp('The <comment>rollback</comment> should be used to cancel a previously done release.');
31+
}
32+
33+
protected function execute(InputInterface $input, OutputInterface $output)
34+
{
35+
if (count(Context::get('vcs')->getLocalModifications()) > 0) {
36+
Context::get('output')->writeln('<error>Local modifications found. Aborting.</error>');
37+
return;
38+
}
39+
40+
$tag = Context::get('version-persister')->getCurrentVersionTag();
41+
$modifications = Context::get('vcs')->getAllModificationsSince($tag, false, false);
42+
if (count($modifications) > 0) {
43+
Context::get('output')->writeln('<error>There were commits since the last release. Aborting.</error>');
44+
return;
45+
}
46+
47+
$this->rollbackActionListIfExist('post-release-actions');
48+
$this->rollbackActionListIfExist('pre-release-actions');
49+
}
50+
51+
protected function rollbackActionListIfExist($name)
52+
{
53+
$actions = Context::getInstance()->getList($name);
54+
$actions = array_reverse($actions);
55+
foreach ($actions as $num => $action) {
56+
$this->getOutput()->write(++$num.') '.$action->getTitle().' : ');
57+
$action->rollback();
58+
}
59+
}
60+
}

src/Liip/RMT/VCS/Git.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ public function createTag($tagName)
5050
return $this->executeGitCommand("tag $tagName");
5151
}
5252

53+
public function deleteTag($tagName)
54+
{
55+
return $this->executeGitCommand("tag -d $tagName");
56+
}
57+
5358
public function publishTag($tagName, $remote = null)
5459
{
5560
$remote = $remote == null ? 'origin' : $remote;
@@ -68,6 +73,18 @@ public function saveWorkingCopy($commitMsg = '')
6873
$this->executeGitCommand("commit -m \"$commitMsg\"");
6974
}
7075

76+
public function revertLastCommit($commitMsg = null)
77+
{
78+
if (! is_null($commitMsg)) {
79+
$msg = $this->executeGitCommand('log -1 --pretty=%B');
80+
if (count($msg) != 1 || $msg[0] !== $commitMsg) {
81+
return;
82+
}
83+
}
84+
85+
$this->executeGitCommand('reset --hard HEAD~1');
86+
}
87+
7188
public function getCurrentBranch()
7289
{
7390
$branches = $this->executeGitCommand('branch');

src/Liip/RMT/VCS/Hg.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public function createTag($tagName)
5858
return $this->executeHgCommand("tag $tagName");
5959
}
6060

61+
public function deleteTag($tagName)
62+
{
63+
return $this->executeHgCommand("tag --remove $tagName");
64+
}
65+
6166
public function publishTag($tagName, $remote = null)
6267
{
6368
// nothing to do, tags are published with other changes
@@ -75,6 +80,17 @@ public function saveWorkingCopy($commitMsg = '')
7580
$this->executeHgCommand("commit -m \"$commitMsg\"");
7681
}
7782

83+
public function revertLastCommit($commitMsg = null)
84+
{
85+
if (! is_null($commitMsg)) {
86+
$msg = $this->executeHgCommand('log -l 1 -T "{desc}"');
87+
if (count($msg) != 1 || $msg[0] !== $commitMsg) {
88+
return;
89+
}
90+
}
91+
92+
$this->executeHgCommand('reset --hard HEAD~1'); }
93+
7894
public function getCurrentBranch()
7995
{
8096
$data = $this->executeHgCommand('branch');

src/Liip/RMT/VCS/VCSInterface.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ public function getTags();
3232
*/
3333
public function createTag($tagName);
3434

35+
/**
36+
* Delete a tag
37+
*
38+
* @param string $tagName
39+
*/
40+
public function deleteTag($tagName);
41+
3542
/**
3643
* Publish a new created tag
3744
*
@@ -78,6 +85,14 @@ public function getLocalModifications();
7885
*/
7986
public function saveWorkingCopy($commitMsg = '');
8087

88+
/**
89+
* Revert the last commit. If a message is given, only revert
90+
* if the commit message matches.
91+
*
92+
* @param string|null $commitMsg
93+
*/
94+
public function revertLastCommit($commitMsg = null);
95+
8196
/**
8297
* Publish local modification
8398
*

0 commit comments

Comments
 (0)