-
-
Notifications
You must be signed in to change notification settings - Fork 320
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #566 - Add set of tasks for working with Mercurial
* Add hg tasks and some supporting documentation. * Fix some minor bugs. * Work on documentation. * Documentation task attributes and tweak handlers. * Add fileset as a supported nested tag by HgAdd. * Unit tests for hginit * Unit tests for hgClone * Unit tests for HgAdd * Unit test for HgArchive * Unit tests for HgCommit * Unit tests for HgLog * Unit tests for HgPull * Unit tests for HgPush. Also some refactoring. * Unit tests for HgRevert * Unit tests for HgTag (and some small bug fixes) * unit tests for HgUpdate * Improve test re hglog's maxCount attribute. * Array declaration must be 5.3 compatible. * Tweak pulling in vendor/autoload.php * Fix reference for hgupdate task * fix require for HgBaseTask.php * Add reference to siad007/versioncontrol_hg * Additional tweak re composer * versioncontrol_hg * Comment out one HgTag test for now. * Tweaks re PHP versions/compatibility. * Hg* tasks only available on 5.4+. Update docs. * Avoid 'use' command in Hg tasks...
- Loading branch information
Showing
39 changed files
with
2,965 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
<?php | ||
/** | ||
* Utilise Mercurial from within Phing. | ||
* | ||
* PHP Version 5.4 | ||
* | ||
* @category Tasks | ||
* @package phing.tasks.ext | ||
* @author Ken Guest <kguest@php.net> | ||
* @license LGPL (see http://www.gnu.org/licenses/lgpl.html) | ||
* @link https://github.com/kenguest/Phing-HG | ||
*/ | ||
|
||
/** | ||
* Pull in Base class. | ||
*/ | ||
require_once 'phing/tasks/ext/hg/HgBaseTask.php'; | ||
|
||
/** | ||
* Integration/Wrapper for hg add | ||
* | ||
* @category Tasks | ||
* @package phing.tasks.ext.hg | ||
* @author Ken Guest <kguest@php.net> | ||
* @license LGPL (see http://www.gnu.org/licenses/lgpl.html) | ||
* @link HgAddTask.php | ||
*/ | ||
class HgAddTask extends HgBaseTask | ||
{ | ||
/** | ||
* Linked filesets | ||
* | ||
* @var string | ||
*/ | ||
protected $filesets = array(); | ||
/** | ||
* Array of files to ignore | ||
* | ||
* @var string[] | ||
*/ | ||
protected $ignoreFile = array(); | ||
|
||
/** | ||
* Adds a fileset of files to add to the repository. | ||
* | ||
* @param FileSet $fileset Set of files to add to the repository. | ||
* | ||
* @return void | ||
*/ | ||
public function addFileSet(FileSet $fileset) | ||
{ | ||
$this->filesets[] = $fileset; | ||
} | ||
|
||
/** | ||
* The main entry point method. | ||
* | ||
* @throws BuildException | ||
* @return void | ||
*/ | ||
public function main() | ||
{ | ||
$filesAdded = false; | ||
$clone = $this->getFactoryInstance('add'); | ||
$clone->setQuiet($this->getQuiet()); | ||
|
||
$cwd = getcwd(); | ||
$project = $this->getProject(); | ||
if ($this->repository === '') { | ||
$dir = $project->getProperty('application.startdir'); | ||
} else { | ||
$dir = $this->repository; | ||
} | ||
|
||
if (!file_exists($dir)) { | ||
throw new BuildException("\"$dir\" does not exist."); | ||
} elseif (!is_dir($dir)) { | ||
throw new BuildException("\"$dir\" is not a directory."); | ||
} | ||
|
||
chdir($dir); | ||
|
||
if (file_exists('.hgignore')) { | ||
$this->loadIgnoreFile(); | ||
} | ||
if (count($this->filesets)) { | ||
$this->log('filesets set', Project::MSG_DEBUG); | ||
/** | ||
* $fs is a FileSet | ||
* | ||
* @var $fs FileSet | ||
*/ | ||
foreach ($this->filesets as $fs) { | ||
$ds = $fs->getDirectoryScanner($project); | ||
$fromDir = $fs->getDir($project); | ||
if ($fromDir->getName() === '.') { | ||
$statusClone = $this->getFactoryInstance('status'); | ||
$statusClone->setUnknown(true); | ||
$statusClone->setNoStatus(true); | ||
$statusClone->setRepository($this->getRepository()); | ||
$statusOut = $statusClone->execute(); | ||
if ($statusOut !== '') { | ||
$files = explode(PHP_EOL, $statusOut); | ||
foreach ($files as $file) { | ||
if ($file != '') { | ||
$clone->addFile($file); | ||
$filesAdded = true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
if ($filesAdded) { | ||
try { | ||
$this->log("Executing: " . $clone->asString(), Project::MSG_INFO); | ||
$output = $clone->execute(); | ||
if ($output !== '') { | ||
$this->log($output); | ||
} | ||
} catch(Exception $ex) { | ||
$msg = $ex->getMessage(); | ||
$this->log("Exception: $msg", Project::MSG_INFO); | ||
$p = strpos($msg, 'hg returned:'); | ||
if ($p !== false) { | ||
$msg = substr($msg, $p + 13); | ||
} | ||
chdir($cwd); | ||
throw new BuildException($msg); | ||
} | ||
} | ||
chdir($cwd); | ||
} | ||
|
||
/** | ||
* Load .hgignore file. | ||
* | ||
* @return void | ||
*/ | ||
public function loadIgnoreFile() | ||
{ | ||
$ignores = array(); | ||
$lines = file('.hgignore'); | ||
foreach ($lines as $line) { | ||
$nline = trim($line); | ||
$nline = preg_replace('/\/\*$/', '/', $nline); | ||
$ignores[] = $nline; | ||
} | ||
$this->ignoreFile = $ignores; | ||
} | ||
|
||
/** | ||
* Determine if a file is to be ignored. | ||
* | ||
* @param string $file filename | ||
* | ||
* @return bool | ||
*/ | ||
public function fileIsIgnored($file) | ||
{ | ||
$line = $this->ignoreFile[0]; | ||
$mode = 'regexp'; | ||
$ignored = false; | ||
if (preg_match('#^syntax\s*:\s*(glob|regexp)$#', $line, $matches) | ||
|| $matches[1] === 'glob' | ||
) { | ||
$mode = 'glob'; | ||
} | ||
if ($mode === 'glob') { | ||
$ignored = $this->ignoredByGlob($file); | ||
} elseif ($mode === 'regexp') { | ||
$ignored = $this->ignoredByRegex($file); | ||
} | ||
return $ignored; | ||
} | ||
|
||
/** | ||
* Determine if file is ignored by glob pattern. | ||
* | ||
* @param string $file filename | ||
* | ||
* @return bool | ||
*/ | ||
public function ignoredByGlob($file) | ||
{ | ||
$lfile = $file; | ||
if (strpos($lfile, './') === 0) { | ||
$lfile = substr($lfile, 2); | ||
} | ||
foreach ($this->ignoreFile as $line) { | ||
if (strpos($lfile, $line) === 0) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Is file ignored by regex? | ||
* | ||
* @param string $file Filename | ||
* | ||
* @return bool | ||
*/ | ||
public function ignoredByRegex($file) | ||
{ | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
<?php | ||
/** | ||
* Utilise Mercurial from within Phing. | ||
* | ||
* PHP Version 5.4 | ||
* | ||
* @category Tasks | ||
* @package phing.tasks.ext | ||
* @author Ken Guest <kguest@php.net> | ||
* @license LGPL (see http://www.gnu.org/licenses/lgpl.html) | ||
* @link https://github.com/kenguest/Phing-HG | ||
*/ | ||
|
||
/** | ||
* Pull in Base class. | ||
*/ | ||
require_once 'phing/tasks/ext/hg/HgBaseTask.php'; | ||
|
||
/** | ||
* Integration/Wrapper for hg archive | ||
* | ||
* @category Tasks | ||
* @package phing.tasks.ext.hg | ||
* @author Ken Guest <kguest@php.net> | ||
* @license LGPL (see http://www.gnu.org/licenses/lgpl.html) | ||
* @link HgArchiveTask.php | ||
*/ | ||
class HgArchiveTask extends HgBaseTask | ||
{ | ||
/** | ||
* Which revision to archive. | ||
* | ||
* @var string | ||
*/ | ||
protected $revision = ''; | ||
|
||
/** | ||
* Name of destination archive file. | ||
* | ||
* @var string | ||
*/ | ||
protected $destination = null; | ||
|
||
/** | ||
* Set revision attribute | ||
* | ||
* @param string $revision Revision | ||
* | ||
* @return void | ||
*/ | ||
public function setRevision($revision) | ||
{ | ||
$this->revision = $revision; | ||
} | ||
|
||
/** | ||
* Set Destination attribute | ||
* | ||
* @param string $destination Destination filename | ||
* | ||
* @return void | ||
*/ | ||
public function setDestination($destination) | ||
{ | ||
$this->destination = $destination; | ||
} | ||
|
||
/** | ||
* The main entry point for the task. | ||
* | ||
* @return void | ||
*/ | ||
public function main() | ||
{ | ||
$clone = $this->getFactoryInstance('archive'); | ||
if ($this->revision !== '') { | ||
$clone->setRev($this->revision); | ||
} | ||
|
||
if ($this->destination === null) { | ||
throw new BuildException("Destination must be set."); | ||
} | ||
$clone->setDestination($this->destination); | ||
|
||
try { | ||
$this->log("Executing: " . $clone->asString(), Project::MSG_INFO); | ||
$output = $clone->execute(); | ||
if ($output !== '') { | ||
$this->log(PHP_EOL . $output); | ||
} | ||
} catch(Exception $ex) { | ||
$msg = $ex->getMessage(); | ||
$p = strpos($msg, 'hg returned:'); | ||
if ($p !== false) { | ||
$msg = substr($msg, $p + 13); | ||
} | ||
throw new BuildException($msg); | ||
} | ||
} | ||
} |
Oops, something went wrong.