Skip to content

Commit

Permalink
[FEATURE] aoe/tagging library checkout-Prozess anpassen
Browse files Browse the repository at this point in the history
whenever a feature or bugfix branch needs to be tagged,
git needs to checkout the branch first to check if a diff exists

1. git is now fetching origin to get all remote branches
2. then git is checking out the branch
2.1 if: no local branch exists git will create it with argument -b
2.2 else: local branch exists, git will checkout the local branch
3 - end. business as usual
  • Loading branch information
michael.sandritter committed Jul 18, 2016
1 parent febab95 commit 032cf9d
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 18 deletions.
10 changes: 6 additions & 4 deletions src/Command/GitCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,14 @@ protected function execute(InputInterface $input, OutputInterface $output)
$output->writeln('<info>Next Tag number is "' . $next . '"</info>');
}

$git->tag($next, $input->getArgument('path'), $input->getOption('branch'));
$git->tag($next, $input->getArgument('path'), $input->getOption('branch'), $output);
} else {
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$output->writeln(
'<info>Skip creating tag "' . $next .
'" because there are no changes since tag "' . $latest . '"</info>'
$output->writeln(sprintf(
'<info>Skip creating tag "%s" because there are no changes since tag "%s"</info>',
$next,
$latest
)
);
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/Vcs/Driver/DriverInterface.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace AOE\Tagging\Vcs\Driver;

use Symfony\Component\Console\Output\OutputInterface;
/**
* @package AOE\Tagging\Vcs\Driver
*/
Expand All @@ -12,9 +13,10 @@ interface DriverInterface
* @param string $tag
* @param string $path
* @param string $branch
* @param OutputInterface $output
* @return void
*/
public function tag($tag, $path, $branch);
public function tag($tag, $path, $branch, OutputInterface $output);

/**
* Returns the latest tag from the given repository.
Expand Down
38 changes: 34 additions & 4 deletions src/Vcs/Driver/GitDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Webcreate\Vcs\Common\Adapter\CliAdapter;
use Webcreate\Vcs\Common\Reference;
use Webcreate\Vcs\Git;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Wrapper Class for Webcreate\Vcs\Git
Expand Down Expand Up @@ -41,17 +42,18 @@ public function __construct($url, $executable = 'git')
* @param string $tag
* @param string $path
* @param string $branch
* @param OutputInterface $output
* @throws \Exception
* @return void
*/
public function tag($tag, $path, $branch)
public function tag($tag, $path, $branch, OutputInterface $output)
{
try {
$this->getGit()->getAdapter()->execute('tag', array($tag), $path);
$this->getGit()->getAdapter()->execute('pull', ['origin', $branch], $path);
$this->getGit()->getAdapter()->execute('fetch', ['--all'], $path);
$this->getGit()->getAdapter()->execute('checkout', ['origin/' . $branch], $path);
$this->getGit()->getAdapter()->execute('push', ['origin', 'origin/' . $branch], $path);
$this->getGit()->getAdapter()->execute('fetch', ['origin'], $path);
$this->checkoutBranch($branch, $path, $output);
$this->getGit()->getAdapter()->execute('push', ['origin', $branch], $path);
$this->getGit()->getAdapter()->execute('push', array('origin', 'tag', $tag), $path);
} catch (\Exception $e) {
$this->getGit()->getAdapter()->execute('reset', array('--hard'), $path);
Expand All @@ -60,6 +62,34 @@ public function tag($tag, $path, $branch)
}
}

/**
* @param $branch
* @param $path
* @param OutputInterface $output
* @throws \Exception
*/
private function checkoutBranch($branch, $path, OutputInterface $output)
{
try {
$this->getGit()->getAdapter()->execute('checkout', ['-b', $branch ,'origin/' . $branch], $path);
} catch (\Exception $e) {
if (preg_match("/A branch named .+ already exists/", $e->getMessage()) === 1) {
$output->writeln(
sprintf(
'<info>checkout -b %s %s failed, because local branch "%s" already exists</info>',
$branch,
'origin/' . $branch,
$branch
)
);
$this->getGit()->getAdapter()->execute('checkout', [$branch], $path);
$output->writeln('<info>checkout local branch: "'. $branch .'"</info>');
} else {
throw $e;
}
}
}

/**
* @param array $files
* @param string $path
Expand Down
115 changes: 106 additions & 9 deletions test/Vcs/Driver/GitDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
namespace AOE\Tagging\Tests\Vcs\Driver;

use AOE\Tagging\Vcs\Driver\GitDriver;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Webcreate\Vcs\Common\Reference;

/**
Expand All @@ -16,6 +15,9 @@ class GitDriverTest extends \PHPUnit_Framework_TestCase
public function shouldTagAndPush()
{
$adapter = $this->givenAnAdapter();
$output = $this->getMockBuilder('Symfony\\Component\\Console\\Output\\OutputInterface')
->disableOriginalConstructor()
->getMock();

$adapter->expects($this->at(0))->method('execute')->with(
'tag',
Expand All @@ -30,12 +32,92 @@ public function shouldTagAndPush()
);

$adapter->expects($this->at(2))->method('execute')->with(
'fetch',
array('origin'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(3))->method('execute')->with(
'checkout',
array('-b', 'feature/myBranch', 'origin/feature/myBranch'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(4))->method('execute')->with(
'push',
array('origin', 'feature/myBranch'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(5))->method('execute')->with(
'push',
array('origin', 'tag', '0.2.5'),
'/home/my/vcs/repo'
);

$git = $this->getMockBuilder('Webcreate\\Vcs\\Git')
->disableOriginalConstructor()
->setMethods(array('getAdapter'))
->getMock();
$git->expects($this->exactly(6))->method('getAdapter')->will($this->returnValue($adapter));

$driver = $this->givenADriver();

$driver->expects($this->exactly(6))->method('getGit')->will(
$this->returnValue($git)
);

/** @var GitDriver $driver */
$driver->tag('0.2.5', '/home/my/vcs/repo', 'feature/myBranch', $output);
}

/**
* @test
*/
public function shouldTagAndPushEvenIfLocalBranchAlreadyExists()
{
$adapter = $this->givenAnAdapter();
$output = $this->getMockBuilder('Symfony\\Component\\Console\\Output\\OutputInterface')
->disableOriginalConstructor()
->getMock();

$adapter->expects($this->at(0))->method('execute')->with(
'tag',
array('0.2.5'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(1))->method('execute')->with(
'pull',
array('origin', 'feature/myBranch'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(2))->method('execute')->with(
'fetch',
array('origin'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(3))->method('execute')->with(
'checkout',
array('-b', 'feature/myBranch', 'origin/feature/myBranch'),
'/home/my/vcs/repo'
)->will($this->throwException(new \Exception('fatal: A branch named feature/myBranch already exists.')));

$adapter->expects($this->at(4))->method('execute')->with(
'checkout',
array('feature/myBranch'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(5))->method('execute')->with(
'push',
array('origin', 'feature/myBranch'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(6))->method('execute')->with(
'push',
array('origin', 'tag', '0.2.5'),
'/home/my/vcs/repo'
Expand All @@ -45,16 +127,16 @@ public function shouldTagAndPush()
->disableOriginalConstructor()
->setMethods(array('getAdapter'))
->getMock();
$git->expects($this->exactly(4))->method('getAdapter')->will($this->returnValue($adapter));
$git->expects($this->exactly(7))->method('getAdapter')->will($this->returnValue($adapter));

$driver = $this->givenADriver();

$driver->expects($this->exactly(4))->method('getGit')->will(
$driver->expects($this->exactly(7))->method('getGit')->will(
$this->returnValue($git)
);

/** @var GitDriver $driver */
$driver->tag('0.2.5', '/home/my/vcs/repo', 'feature/myBranch');
$driver->tag('0.2.5', '/home/my/vcs/repo', 'feature/myBranch', $output);
}

/**
Expand All @@ -64,6 +146,9 @@ public function shouldTagAndPush()
public function shouldCleanOnError()
{
$adapter = $this->givenAnAdapter();
$output = $this->getMockBuilder('Symfony\\Component\\Console\\Output\\OutputInterface')
->disableOriginalConstructor()
->getMock();

$adapter->expects($this->at(0))->method('execute')->with(
'tag',
Expand All @@ -78,18 +163,30 @@ public function shouldCleanOnError()
);

$adapter->expects($this->at(2))->method('execute')->with(
'fetch',
array('origin'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(3))->method('execute')->with(
'checkout',
array('-b', 'master', 'origin/master'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(4))->method('execute')->with(
'push',
array('origin', 'master'),
'/home/my/vcs/repo'
)->will($this->throwException(new \Exception('could not push to remote')));

$adapter->expects($this->at(3))->method('execute')->with(
$adapter->expects($this->at(5))->method('execute')->with(
'reset',
array('--hard'),
'/home/my/vcs/repo'
);

$adapter->expects($this->at(4))->method('execute')->with(
$adapter->expects($this->at(6))->method('execute')->with(
'tag',
array('-d', '0.2.5'),
'/home/my/vcs/repo'
Expand All @@ -99,16 +196,16 @@ public function shouldCleanOnError()
->disableOriginalConstructor()
->setMethods(array('getAdapter'))
->getMock();
$git->expects($this->exactly(5))->method('getAdapter')->will($this->returnValue($adapter));
$git->expects($this->exactly(7))->method('getAdapter')->will($this->returnValue($adapter));

$driver = $this->givenADriver();

$driver->expects($this->exactly(5))->method('getGit')->will(
$driver->expects($this->exactly(7))->method('getGit')->will(
$this->returnValue($git)
);

/** @var GitDriver $driver */
$driver->tag('0.2.5', '/home/my/vcs/repo', 'master');
$driver->tag('0.2.5', '/home/my/vcs/repo', 'master', $output);
}

/**
Expand Down

0 comments on commit 032cf9d

Please sign in to comment.