Skip to content

Commit

Permalink
Fixes #566 - Add set of tasks for working with Mercurial
Browse files Browse the repository at this point in the history
* 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
kenguest authored and mrook committed May 18, 2016
1 parent 89ff14e commit bbd6430
Show file tree
Hide file tree
Showing 39 changed files with 2,965 additions and 2 deletions.
13 changes: 11 additions & 2 deletions classes/phing/tasks/defaults.properties
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,17 @@ gitlog=phing.tasks.ext.git.GitLogTask
gittag=phing.tasks.ext.git.GitTagTask
gitcommit=phing.tasks.ext.git.GitCommitTask
gitdescribe=phing.tasks.ext.git.GitDescribeTask
phpunit3=phing.tasks.ext.phpunit.PHPUnitTask
phpunit3report=phing.tasks.ext.phpunit.PHPUnitReportTask
hgadd=phing.tasks.ext.hg.HgAddTask
hgarchive=phing.tasks.ext.hg.HgArchiveTask
hgclone=phing.tasks.ext.hg.HgCloneTask
hgcommit=phing.tasks.ext.hg.HgCommitTask
hginit=phing.tasks.ext.hg.HgInitTask
hglog=phing.tasks.ext.hg.HgLogTask
hgpull=phing.tasks.ext.hg.HgPullTask
hgpush=phing.tasks.ext.hg.HgPushTask
hgrevert=phing.tasks.ext.hg.HgRevertTask
hgtag=phing.tasks.ext.hg.HgTagTask
hgupdate=phing.tasks.ext.hg.HgUpdateTask
phpunit=phing.tasks.ext.phpunit.PHPUnitTask
phpunitreport=phing.tasks.ext.phpunit.PHPUnitReportTask
coverage-setup=phing.tasks.ext.coverage.CoverageSetupTask
Expand Down
210 changes: 210 additions & 0 deletions classes/phing/tasks/ext/hg/HgAddTask.php
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;
}
}
100 changes: 100 additions & 0 deletions classes/phing/tasks/ext/hg/HgArchiveTask.php
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);
}
}
}
Loading

0 comments on commit bbd6430

Please sign in to comment.