Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapper support for PathConvert task. #925

Merged
merged 2 commits into from
May 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 81 additions & 59 deletions classes/phing/tasks/system/PathConvert.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class PathConvert extends Task

public $from = null;
public $to = null;
private $mapper;

/**
* constructor
Expand Down Expand Up @@ -110,7 +111,6 @@ public function createMap()
return $entry;
}


/**
* Set targetos to a platform to one of
* "windows", "unix", "netware", or "os/2"; required unless
Expand Down Expand Up @@ -201,85 +201,93 @@ public function main()
$savedPathSep = $this->pathSep;// may be altered in validateSetup
$savedDirSep = $this->dirSep;// may be altered in validateSetup

// If we are a reference, create a Path from the reference
if ($this->isReference()) {
$this->path = new Path($this->getProject());
$this->path = $this->path->createPath();
try {

$obj = $this->refid->getReferencedObject($this->getProject());
// If we are a reference, create a Path from the reference
if ($this->isReference()) {
$this->path = new Path($this->getProject());
$this->path = $this->path->createPath();

if ($obj instanceof Path) {
$this->path->setRefid($this->refid);
} elseif ($obj instanceof FileSet) {
$fs = $obj;
$obj = $this->refid->getReferencedObject($this->getProject());

$this->path->addFileset($fs);
} elseif ($obj instanceof DirSet) {
$ds = $obj;
if ($obj instanceof Path) {
$this->path->setRefid($this->refid);
} elseif ($obj instanceof FileSet) {
$fs = $obj;

$this->path->addDirset($ds);
} elseif ($obj instanceof FileList) {
$fl = $obj;
$this->path->addFileset($fs);
} elseif ($obj instanceof DirSet) {
$ds = $obj;

$this->path->addFilelist($fl);
} else {
throw new BuildException("'refid' does not refer to a "
. "path, fileset, dirset, or "
. "filelist.");
$this->path->addDirset($ds);
} elseif ($obj instanceof FileList) {
$fl = $obj;

$this->path->addFilelist($fl);
} else {
throw new BuildException("'refid' does not refer to a "
. "path, fileset, dirset, or "
. "filelist.");
}
}
}

$this->validateSetup();// validate our setup
$this->validateSetup();// validate our setup

// Currently, we deal with only two path formats: Unix and Windows
// And Unix is everything that is not Windows
// (with the exception for NetWare and OS/2 below)
// Currently, we deal with only two path formats: Unix and Windows
// And Unix is everything that is not Windows
// (with the exception for NetWare and OS/2 below)

// for NetWare and OS/2, piggy-back on Windows, since here and
// in the apply code, the same assumptions can be made as with
// windows - that \\ is an OK separator, and do comparisons
// case-insensitive.
$fromDirSep = $this->onWindows ? "\\" : "/";
// for NetWare and OS/2, piggy-back on Windows, since here and
// in the apply code, the same assumptions can be made as with
// windows - that \\ is an OK separator, and do comparisons
// case-insensitive.
$fromDirSep = $this->onWindows ? "\\" : "/";

$rslt = '';
$rslt = '';

// Get the list of path components in canonical form
$elems = $this->path->listPaths();
// Get the list of path components in canonical form
$elems = $this->path->listPaths();

foreach ($elems as $key => $elem) {
if (is_string($elem)) {
$elem = new Path($this->project, $elem);
$mapperImpl = $this->mapper === null ? new IdentityMapper() : $this->mapper->getImplementation();
foreach ($elems as &$elem) {
$mapped = $mapperImpl->main($elem);
for ($m = 0; $mapped !== null && $m < count($mapped); ++$m) {
$elem = $mapped[$m];
}
}
$elem = $this->mapElement($elem);// Apply the path prefix map
unset($elem);
foreach ($elems as $key => $elem) {
$elem = $this->mapElement($elem);// Apply the path prefix map

// Now convert the path and file separator characters from the
// current os to the target os.
// Now convert the path and file separator characters from the
// current os to the target os.

if ($key !== 0) {
$rslt .= $this->pathSep;
}
if ($key !== 0) {
$rslt .= $this->pathSep;
}

$rslt .= str_replace($fromDirSep, $this->dirSep, $elem);
}
$rslt .= str_replace($fromDirSep, $this->dirSep, $elem);
}

// Place the result into the specified property,
// unless setonempty == false
$value = $rslt;
if ($this->setonempty) {
$this->log("Set property " . $this->property . " = " . $value,
Project::MSG_VERBOSE);
$this->getProject()->setNewProperty($this->property, $value);
} else {
if ($rslt !== '') {
// Place the result into the specified property,
// unless setonempty == false
$value = $rslt;
if ($this->setonempty) {
$this->log("Set property " . $this->property . " = " . $value,
Project::MSG_VERBOSE);
$this->getProject()->setNewProperty($this->property, $value);
} else {
if ($rslt !== '') {
$this->log("Set property " . $this->property . " = " . $value,
Project::MSG_VERBOSE);
$this->getProject()->setNewProperty($this->property, $value);
}
}
} finally {
$this->path = $savedPath;
$this->dirSep = $savedDirSep;
$this->pathSep = $savedPathSep;
}

$this->path = $savedPath;
$this->dirSep = $savedDirSep;
$this->pathSep = $savedPathSep;
}

/**
Expand All @@ -290,7 +298,7 @@ public function main()
* @param string $elem The path element to apply the map to
* @return String Updated element
*/
private function mapElement(Path $elem)
private function mapElement($elem)
{
$size = count($this->prefixMap);

Expand All @@ -315,6 +323,20 @@ private function mapElement(Path $elem)
return $elem;
}

/**
* @throws BuildException
* @throws IOException
*/
public function createMapper()
{
if ($this->mapper !== null) {
throw new BuildException("Cannot define more than one mapper", $this->getLocation());
}
$this->mapper = new Mapper($this->project);

return $this->mapper;
}

/**
* Validate that all our parameters have been properly initialized.
*
Expand Down
3 changes: 3 additions & 0 deletions docs/guide/en/source/appendixes/coretasks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2749,6 +2749,9 @@ verbose="true" failonerror="false" /></programlisting>
<para>Nested <literal>map</literal> elements can be specified to map Windows
drive letters to Unix paths, and vice-versa.
</para>
<para>A single nested <literal>mapper</literal> element can be specified to perform any of various filename
transformations.
</para>
<table>
<title>Attributes</title>
<tgroup cols="5">
Expand Down
39 changes: 39 additions & 0 deletions etc/phing-grammar.rng
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
<ref name="phingcall"/>
<ref name="phingversion"/>
<ref name="php"/>
<ref name="pathconvert"/>
<ref name="property"/>
<ref name="record"/>
<ref name="reflexive"/>
Expand Down Expand Up @@ -1979,6 +1980,44 @@
</element>
</define>

<define name="pathconvert">
<element name="pathconvert">
<interleave>
<optional>
<attribute name="targetos"/>
</optional>
<optional>
<attribute name="dirsep"/>
</optional>
<optional>
<attribute name="pathsep"/>
</optional>
<optional>
<attribute name="property"/>
</optional>
<optional>
<attribute name="refid"/>
</optional>
<optional>
<attribute name="setonempty"/>
</optional>
</interleave>
<interleave>
<optional>
<element name="map">
<interleave>
<attribute name="from"/>
<attribute name="to"/>
</interleave>
</element>
</optional>
<optional>
<ref name="mapper"/>
</optional>
</interleave>
</element>
</define>

<define name="property">
<element name="property">
<interleave>
Expand Down
16 changes: 16 additions & 0 deletions test/classes/phing/tasks/system/PathConvertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,20 @@ public function testDirChar()
$this->executeTarget(__FUNCTION__);
$this->assertPropertyEquals('def|ghi', 'def|ghi');
}

public function testMap()
{
$this->assertTarget('testmap');
}

public function testMapper()
{
$this->assertTarget('testmapper');
}

private function assertTarget(string $target)
{
$this->executeTarget($target);
$this->assertEquals("test#" . 'PathConvertTest.xml', $this->getProject()->getProperty('result'));
}
}
18 changes: 18 additions & 0 deletions test/etc/tasks/system/PathConvertTest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PathConvertTest" default="test" basedir=".">

<path id="testpath">
<pathelement path="${phing.file}" />
</path>

<target name="testDirChar">
<pathconvert property="def|ghi" dirsep="|">
<map from="${project.basedir}/abc/" to=''/>
<path dir="abc/def/ghi"/>
</pathconvert>
</target>

<target name="testmap">
<pathconvert property="result" dirsep="#">
<path refid="testpath" />
<map from="${project.basedir}" to="test" />
</pathconvert>
</target>

<target name="testmapper">
<pathconvert property="result" dirsep="#">
<path refid="testpath" />
<mapper type="glob" from="${project.basedir}*" to="test*" />
</pathconvert>
</target>

</project>