mageekguy\atoum\scripts\git\pusher: lines coverage

99% of 747

OPs

95% of 179

Lines

76% of 78

Branches

100% of 39

Paths
Method OPs OPs % Lines Line % Branches Branches % Paths Path %
mageekguy\atoum\scripts\git\pusher::__construct() 34 100% 8 100% 1 0% 1 100%
mageekguy\atoum\scripts\git\pusher::setRemote() 13 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::getRemote() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::setTagFile() 26 100% 7 100% 5 100% 2 100%
mageekguy\atoum\scripts\git\pusher::getTagFile() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::setTaggerEngine() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::getTaggerEngine() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::setWorkingDirectory() 16 100% 3 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::getWorkingDirectory() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::setGit() 16 100% 2 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::getGit() 6 100% 1 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::tagMajorVersion() 11 100% 3 100% 1 0% 1 100%
mageekguy\atoum\scripts\git\pusher::tagMinorVersion() 11 100% 3 100% 1 0% 1 100%
mageekguy\atoum\scripts\git\pusher::tagPatchVersion() 11 100% 3 100% 1 0% 1 100%
mageekguy\atoum\scripts\git\pusher::setArgumentHandlers() 99 100% 48 81% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::doRun() 151 99% 29 100% 26 88% 9 100%
mageekguy\atoum\scripts\git\pusher::getNextVersion() 69 97% 23 100% 7 71% 3 100%
mageekguy\atoum\scripts\git\pusher::tagSrcWith() 25 100% 4 100% 1 100% 1 100%
mageekguy\atoum\scripts\git\pusher::tagStableVersion() 44 100% 7 100% 5 60% 2 100%
mageekguy\atoum\scripts\git\pusher::createGitTag() 37 100% 6 100% 5 60% 2 100%
mageekguy\atoum\scripts\git\pusher::tagDevelopmentVersion() 45 100% 7 100% 5 60% 2 100%
mageekguy\atoum\scripts\git\pusher::pushToRemote() 43 100% 8 100% 5 60% 2 100%
mageekguy\atoum\scripts\git\pusher::pushTagToRemote() 50 100% 9 100% 5 60% 2 100%
#
1
<?php
2

                    
3
namespace mageekguy\atoum\scripts\git;
4

                    
5
use
6
	mageekguy\atoum,
7
	mageekguy\atoum\script,
8
	mageekguy\atoum\scripts,
9
	mageekguy\atoum\exceptions,
10
	mageekguy\atoum\cli\commands
11
;
12

                    
13
class pusher extends script\configurable
14
{
15
	const defaultRemote = 'origin';
16
	const defaultTagFile = '.tag';
17
	const versionPattern = '$Rev: %s $';
18
	const majorVersion = 1;
19
	const minorVersion = 2;
20
	const patchVersion = 3;
21

                    
22
	protected $remote = '';
23
	protected $tagFile = null;
24
	protected $workingDirectory = '';
25
	protected $taggerEngine = null;
26
	protected $git = null;
27
	protected $tagMajorVersion = false;
28
	protected $tagMinorVersion = false;
29

                    
30
	public function __construct($name, atoum\adapter $adapter = null)100%
31
	{
32
		parent::__construct($name, $adapter);
33

                    
34
		$this
35
			->setRemote()
36
			->setTagFile()
37
			->setTaggerEngine()
38
			->setWorkingDirectory()
39
			->setGit()
40
		;
41
	}
42

                    
43
	public function setRemote($remote = null)100%
44
	{
45
		$this->remote = $remote ?: self::defaultRemote;
46

                    
47
		return $this;
48
	}
49

                    
50
	public function getRemote()100%
51
	{
52
		return $this->remote;
53
	}
54

                    
55
	public function setTagFile($tagFile = null)100%
56
	{
57
		if ($tagFile !== null)
58
		{
59
			$tagFile = (string) $tagFile;
60
		}
61
		else
62
		{
63
			$tagFile = $this->getDirectory() . self::defaultTagFile;
64
		}
65

                    
66
		$this->tagFile = $tagFile;
67

                    
68
		return $this;
69
	}
70

                    
71
	public function getTagFile()100%
72
	{
73
		return $this->tagFile;
74
	}
75

                    
76
	public function setTaggerEngine(scripts\tagger\engine $engine = null)100%
77
	{
78
		$this->taggerEngine = $engine ?: new scripts\tagger\engine();
79

                    
80
		return $this;
81
	}
82

                    
83
	public function getTaggerEngine()100%
84
	{
85
		return $this->taggerEngine;
86
	}
87

                    
88
	public function setWorkingDirectory($workingDirectory = null)100%
89
	{
90
		$this->workingDirectory = $workingDirectory ?: $this->adapter->getcwd();
91

                    
92
		return $this;
93
	}
94

                    
95
	public function getWorkingDirectory()100%
96
	{
97
		return $this->workingDirectory;
98
	}
99

                    
100
	public function setGit(commands\git $git = null)100%
101
	{
102
		$this->git = $git ?: new commands\git();
103

                    
104
		return $this;
105
	}
106

                    
107
	public function getGit()100%
108
	{
109
		return $this->git;
110
	}
111

                    
112
	public function tagMajorVersion()100%
113
	{
114
		$this->tagMajorVersion = true;
115
		$this->tagMinorVersion = false;
116
	}
117

                    
118
	public function tagMinorVersion()100%
119
	{
120
		$this->tagMajorVersion = false;
121
		$this->tagMinorVersion = true;
122
	}
123

                    
124

                    
125
	public function tagPatchVersion()100%
126
	{
127
		$this->tagMajorVersion = false;
128
		$this->tagMinorVersion = false;
129
	}
130

                    
131
	protected function setArgumentHandlers()81%
132
	{
133
		parent::setArgumentHandlers()
134
			->addArgumentHandler(
135
				function($script, $argument, $remote) {
136
					if (sizeof($remote) != 1)
137
					{
138
						throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $remote, $script->getName()));
139
					}
140

                    
141
					$script->setRemote(reset($remote));
142
				},
143
				array('-tr', '--to-remote'),
144
				'<string>',
145
				$this->locale->_('<string> will be used as remote')
146
			)
147
			->addArgumentHandler(
148
				function($script, $argument, $tagFile) {
149
					if (sizeof($tagFile) != 1)
150
					{
151
						throw new exceptions\logic\invalidArgument(sprintf($script->getLocale()->_('Bad usage of %s, do php %s --help for more informations'), $argument, $script->getName()));
152
					}
153

                    
154
					$script->setTagFile(reset($tagFile));
155
				},
156
				array('-tf', '--tag-file'),
157
				'<path>',
158
				$this->locale->_('File <path> will be used to store last tag')
159
			)
160
			->addArgumentHandler(
161
				function($script, $argument, $value) {
162
					$script->tagMajorVersion();
163
				},
164
				array('-MR', '--major-release'),
165
				null,
166
				$this->locale->_('Tag a new major version')
167
			)
168
			->addArgumentHandler(
169
				function($script, $argument, $value) {
170
					$script->tagMinorVersion();
171
				},
172
				array('-mr', '--minor-release'),
173
				null,
174
				$this->locale->_('Tag a new minor version')
175
			)
176
			->addArgumentHandler(
177
				function($script, $argument, $value) {
178
					$script->tagPatchVersion();
179
				},
180
				array('-pr', '--patch-release'),
181
				null,
182
				$this->locale->_('Tag a new patch version')
183
			)
184
		;
185

                    
186
		return $this;
187
	}
188

                    
189
	protected function doRun()100%
190
	{
191
		try
192
		{
193
			$tag = @file_get_contents($this->tagFile);
194

                    
195
			if ($tag === false)
196
			{
197
				throw new exceptions\runtime('Unable to read \'' . $this->tagFile . '\'');
198
			}
199

                    
200
			$tag = $this->getNextVersion(trim($tag));
201

                    
202
			if (@file_put_contents($this->tagFile, $tag) === false)
203
			{
204
				throw new exceptions\runtime('Unable to write in \'' . $this->tagFile . '\'');
205
			}
206

                    
207
			$this->taggerEngine->setSrcDirectory($this->workingDirectory);
208

                    
209
			if ($this->tagStableVersion($tag) === true)
210
			{
211
				if ($this->createGitTag($tag) === true)
212
				{
213
					if ($this->tagDevelopmentVersion('DEVELOPMENT-' . $tag) === true)
214
					{
215
						if ($this->pushToRemote($tag) === true)
216
						{
217
							if ($this->pushTagToRemote($tag) === true)
218
							{
219
								$this->writeInfo('Tag \'' . $tag . '\' successfully sent to remote \'' . $this->remote . '\'');
220
							}
221
						}
222
					}
223
				}
224
			}
225

                    
226
		}
227
		catch (\exception $exception)
228
		{
229
			$this->writeError($exception->getMessage());
230
		}
231

                    
232
		return $this;
233
	}
234

                    
235
	protected function getNextVersion($tag)100%
236
	{
237
		$versionPattern = '/^(\d+)\.(\d+)\.(\d+)$/';
238
		$increment = function($position) {
239
			return function($matches) use ($position) {
240
				for ($i = 1; $i <= 3; $i++)
241
				{
242
					if ($i > $position)
243
					{
244
						$matches[$i] = 0;
245
					}
246

                    
247
					if ($i === $position)
248
					{
249
						$matches[$i] += 1;
250
					}
251
				}
252

                    
253
				return implode('.', array_slice($matches, 1));
254
			};
255
		};
256

                    
257
		if ($this->tagMajorVersion === true)
258
		{
259
			return preg_replace_callback($versionPattern, $increment(self::majorVersion), $tag);
260
		}
261

                    
262
		if ($this->tagMinorVersion === true)
263
		{
264
			return preg_replace_callback($versionPattern, $increment(self::minorVersion), $tag);
265
		}
266

                    
267
		return preg_replace_callback($versionPattern, $increment(self::patchVersion), $tag);
268
	}
269

                    
270
	private function tagSrcWith($tag)100%
271
	{
272
		$this->taggerEngine
273
			->setVersion(sprintf(static::versionPattern, $tag))
274
			->tagVersion()
275
		;
276

                    
277
		return $this;
278
	}
279

                    
280
	private function tagStableVersion($tag)100%
281
	{
282
		$this->tagSrcWith($tag);
283

                    
284
		try
285
		{
286
			$this->git->addAllAndCommit('Set version to ' . $tag . '.');
287
		}
288
		catch (\exception $exception)
289
		{
290
			$this->writeError($exception->getMessage());
291

                    
292
			$this->git->checkoutAllFiles();
293

                    
294
			return false;
295
		}
296

                    
297
		return true;
298
	}
299

                    
300
	private function createGitTag($tag)100%
301
	{
302
		try
303
		{
304
			$this->git->createTag($tag);
305
		}
306
		catch (\exception $exception)
307
		{
308
			$this->writeError($exception->getMessage());
309

                    
310
			$this->git->resetHardTo('HEAD~1');
311

                    
312
			return false;
313
		}
314

                    
315
		return true;
316
	}
317

                    
318
	private function tagDevelopmentVersion($tag)100%
319
	{
320
		$this->tagSrcWith($tag);
321

                    
322
		try
323
		{
324
			$this->git->addAllAndCommit('Set version to ' . $tag . '.');
325
		}
326
		catch (\exception $exception)
327
		{
328
			$this->writeError($exception->getMessage());
329

                    
330
			$this->git->resetHardTo('HEAD~1');
331

                    
332
			return false;
333
		}
334

                    
335
		return true;
336
	}
337

                    
338
	private function pushToRemote($tag)100%
339
	{
340
		try
341
		{
342
			$this->git->push($this->remote);
343
		}
344
		catch (\exception $exception)
345
		{
346
			$this->writeError($exception->getMessage());
347

                    
348
			$this->git
349
				->deleteLocalTag($tag)
350
				->resetHardTo('HEAD~2')
351
			;
352

                    
353
			return false;
354
		}
355

                    
356
		return true;
357
	}
358

                    
359
	private function pushTagToRemote($tag)100%
360
	{
361
		try
362
		{
363
			$this->git->pushTag($tag, $this->remote);
364
		}
365
		catch (\exception $exception)
366
		{
367
			$this->writeError($exception->getMessage());
368

                    
369
			$this->git
370
				->deleteLocalTag($tag)
371
				->resetHardTo('HEAD~2')
372
				->forcePush($this->remote)
373
			;
374

                    
375
			return false;
376
		}
377

                    
378
		return true;
379
	}
380
}