You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ant.apache.org by "Ludwig, Michael" <Mi...@delphi-mb.de> on 2010/09/16 16:02:31 UTC

simplify copy with regexpmapper (mapper/regexp)

Consider this filtered view of my directory tree:

src/HTML-XForm/lib
src/ResPath/lib
src/XML-MSXML6/lib

You get the idea, it is:

src/*/lib

Now I want to copy the files below src/*/lib, or most of them.
And I want to strip the leading two directories. I came up with
the following solution, but it is clumsy and I think there is
a better way that I'm missing.

<project default="copy">
  <property name="source.dir" location="src"/>
  <property name="target.dir" location="lib"/>

  <target name="copy">
    <copy todir="${target.dir}">
      <fileset dir="${source.dir}">
        <include name="*/lib/**/*.*"/>
        <exclude name="**/urmel.*"/>
      </fileset>
      <!-- portability: path separator logic redoubled in regexp -->
      <mapper type="regexp" from="^[-_a-zA-Z0-9]*[\\/]lib(.*)" to="\1"/>
    </copy>
  </target>
</project>

What I'm wondering is if there isn't some option like in tools such
as wget (--cut-dirs to shorten the path) or cpio or tar, which in
Ant's case would probably translate to a mapper, like cut-dirs-mapper.

-- 
Michael Ludwig 

Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Michael Ludwig <mi...@gmx.de>.
Stefan Bodewig schrieb am 17.09.2010 um 14:54 (+0200):
> On 2010-09-17, Niklas Matthies wrote:
> > On Fri 2010-09-17 at 14:36h, Stefan Bodewig wrote on user:
> >> On 2010-09-16, Ludwig, Michael wrote:
> 
> >>> What I'm wondering is if there isn't some option like in tools
> >>> such as wget (--cut-dirs to shorten the path) or cpio or tar,
> >>> which in Ant's case would probably translate to a mapper, like
> >>> cut-dirs-mapper.
> 
> >> flatten
> 
> >> Since you really want to remove all dirs, flatten="true" or the
> >> flattenmapper should do what you want.
> 
> > But "flatten" also cuts away all sub-directories.

Exactly. I want to preserve those.

> Absolutely, hence "since you really want to remove all dirs".
> 
> > If for example the files to copy are Java source files under
> > multiple source roots, "flatten" would also remove the Java package
> > directories from the file paths, instead of just the part above the
> > source roots.
> 
> This is correct, but this is not the case in the problem Michael is
> trying to solve.

Well, these aren't Java files, but the requirement is the same.

I may not have specified it clearly enough, but what I want is what to
preserve the structure below the directories to copy, which is the way
the following UNIX utilities do it:

* wget --cut-dirs=2
* tar --strip-components=2
* cd/find/cpio achieves the same thing

-- 
Michael Ludwig

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Michael Ludwig <mi...@gmx.de>.
Niklas Matthies schrieb am 17.09.2010 um 15:08 (+0200):

> Well, Michael wrote "I want to strip the leading two directories", and
> also "/lib/**/*.*", which suggests that there can be directories below
> "lib", and his regex just strips the directories up to "lib".

Right.

> Anyway, I'd be interested in a solution that really only removes a
> prefix of the path.

The regex solution works, but it's unpleasantly hackish, and hackishly
goes back to platform dependency, or at least risks to do so.

With all the clever path stuff in Ant, I feel that I'm missing some easy
way to solve this.
-- 
Michael Ludwig

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Michael Ludwig <mi...@gmx.de>.
Stefan Bodewig schrieb am 20.09.2010 um 17:55 (+0200):
> On 2010-09-17, Niklas Matthies wrote:

> > Anyway, I'd be interested in a solution that really only removes a
> > prefix of the path.
> 
> <http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java>
> or for the full commit including rudimentary documentation and tests
> <http://svn.apache.org/viewvc?view=revision&revision=998962>

Thanks!

> I couldn't figure out from the man-page (and was too lazy to trie) what
> wget does if you specify --cut-dirs=12 but the path is only two levels
> deep.

It'll flatten the structure, like melting butter in the pan.

> The mapper will currently behave in a not-my-business way like
> the regexp mapper does when the from regex doesn't match.

Also fine.

-- 
Michael Ludwig

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-09-17, Niklas Matthies wrote:

> On Fri 2010-09-17 at 14:54h, Stefan Bodewig wrote on user:
>> On 2010-09-17, Niklas Matthies wrote:

>>> But "flatten" also cuts away all sub-directories.

>> Absolutely, hence "since you really want to remove all dirs".

>>> If for example the files to copy are Java source files under multiple
>>> source roots, "flatten" would also remove the Java package directories
>>> from the file paths, instead of just the part above the source roots.

>> This is correct, but this is not the case in the problem Michael is
>> trying to solve.

> Well, Michael wrote "I want to strip the leading two directories", and
> also "/lib/**/*.*", which suggests that there can be directories below
> "lib", and his regex just strips the directories up to "lib".

OK, I missed that part, sorry.

> Anyway, I'd be interested in a solution that really only removes a
> prefix of the path.

<http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/types/mappers/CutDirsMapper.java>
or for the full commit including rudimentary documentation and tests
<http://svn.apache.org/viewvc?view=revision&revision=998962>

I couldn't figure out from the man-page (and was too lazy to trie) what
wget does if you specify --cut-dirs=12 but the path is only two levels
deep.  The mapper will currently behave in a not-my-business way like
the regexp mapper does when the from regex doesn't match.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Niklas Matthies <ml...@nmhq.net>.
On Fri 2010-09-17 at 14:54h, Stefan Bodewig wrote on user:
> On 2010-09-17, Niklas Matthies wrote:
:
> > But "flatten" also cuts away all sub-directories.
> 
> Absolutely, hence "since you really want to remove all dirs".
> 
> > If for example the files to copy are Java source files under multiple
> > source roots, "flatten" would also remove the Java package directories
> > from the file paths, instead of just the part above the source roots.
> 
> This is correct, but this is not the case in the problem Michael is
> trying to solve.

Well, Michael wrote "I want to strip the leading two directories", and
also "/lib/**/*.*", which suggests that there can be directories below
"lib", and his regex just strips the directories up to "lib".

Anyway, I'd be interested in a solution that really only removes a
prefix of the path.

-- Niklas Matthies

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-09-17, Niklas Matthies wrote:

> On Fri 2010-09-17 at 14:36h, Stefan Bodewig wrote on user:
>> On 2010-09-16, Ludwig, Michael wrote:

>>> What I'm wondering is if there isn't some option like in tools such
>>> as wget (--cut-dirs to shorten the path) or cpio or tar, which in
>>> Ant's case would probably translate to a mapper, like cut-dirs-mapper.

>> flatten

>> Since you really want to remove all dirs, flatten="true" or the
>> flattenmapper should do what you want.

> But "flatten" also cuts away all sub-directories.

Absolutely, hence "since you really want to remove all dirs".

> If for example the files to copy are Java source files under multiple
> source roots, "flatten" would also remove the Java package directories
> from the file paths, instead of just the part above the source roots.

This is correct, but this is not the case in the problem Michael is
trying to solve.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Niklas Matthies <ml...@nmhq.net>.
On Fri 2010-09-17 at 14:36h, Stefan Bodewig wrote on user:
> On 2010-09-16, Ludwig, Michael wrote:
> 
> > What I'm wondering is if there isn't some option like in tools such
> > as wget (--cut-dirs to shorten the path) or cpio or tar, which in
> > Ant's case would probably translate to a mapper, like cut-dirs-mapper.
> 
> flatten
> 
> Since you really want to remove all dirs, flatten="true" or the
> flattenmapper should do what you want.

But "flatten" also cuts away all sub-directories. If for example the
files to copy are Java source files under multiple source roots,
"flatten" would also remove the Java package directories from the file
paths, instead of just the part above the source roots.

-- Niklas Matthies

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


Re: simplify copy with regexpmapper (mapper/regexp)

Posted by Stefan Bodewig <bo...@apache.org>.
On 2010-09-16, Ludwig, Michael wrote:

> What I'm wondering is if there isn't some option like in tools such
> as wget (--cut-dirs to shorten the path) or cpio or tar, which in
> Ant's case would probably translate to a mapper, like cut-dirs-mapper.

flatten

Since you really want to remove all dirs, flatten="true" or the
flattenmapper should do what you want.

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@ant.apache.org
For additional commands, e-mail: user-help@ant.apache.org


RE: simplify copy with regexpmapper (mapper/regexp)

Posted by "Ludwig, Michael" <Mi...@delphi-mb.de>.
> Here's working code:
> 
> <project default="copy">
>   <property name="source.dir" location="src"/>
>   <property name="target.dir" location="lib"/>
>   <target name="copy">
>     <copy todir="${target.dir}">
>       <fileset dir="${source.dir}">
>         <include name="*/lib/**/*.*"/>
>         <exclude name="**/urmel.*"/>
>       </fileset>
>       <regexpmapper handledirsep="yes"
>         from="^[-_a-zA-Z0-9]+/lib/(.*)"
>           to="\1" />
>     </copy>
>   </target>
> </project>

One more observation is that the <mapper> is also a "grepper"
(as in "map" and "grep" in Perl), i.e. a filter defining a match
constraint on the input and excluding non-matching content from
the operation.

Michael

RE: simplify copy with regexpmapper (mapper/regexp)

Posted by "Ludwig, Michael" <Mi...@delphi-mb.de>.
> And this is hardly surprising as I was confounding shell patterns and
> regular expressions. The following, while not working, is at least a
> suitable regular expression:
> 
>   <regexpmapper handledirsep="1"
>     from="${source.dir}/[-_a-zA-Z0-9]+/lib/(.*)"
> 	  to="\1" />

But of course, just for the fun of it, I had introduced some other
issues as well.

First, in a regression from what I had already learnt, I resupplied
the ${source.dir} to the mapper. However, ${source.dir} appears to be
the context directory for the copy task, so the character string
representing that path segment is not present in the paths to be
copied.

Second, the @handledirsep was happily switched off because "1" appears
to mean "no", and not "yes" as my intuition told me.

Third, while <regexpmapper> without @handledirsep appears to always copy
the files even when not necessary, <regexpmapper> *with* that attribute
only copies them when necessary, which is something to watch out for
when testing what works and what doesn't.

Here's working code:

<project default="copy">
  <property name="source.dir" location="src"/>
  <property name="target.dir" location="lib"/>
  <target name="copy">
    <copy todir="${target.dir}">
      <fileset dir="${source.dir}">
        <include name="*/lib/**/*.*"/>
        <exclude name="**/urmel.*"/>
      </fileset>
      <regexpmapper handledirsep="yes"
        from="^[-_a-zA-Z0-9]+/lib/(.*)"
          to="\1" />
    </copy>
  </target>
</project>

-- 
Michael Ludwig

RE: simplify copy with regexpmapper (mapper/regexp)

Posted by "Ludwig, Michael" <Mi...@delphi-mb.de>.
> The following does not work for me, though:
> 
> <project default="copy">
>   <property name="source.dir" location="src"/>
>   <property name="target.dir" location="lib"/>
>   <target name="copy">
>     <copy todir="${target.dir}">
>       <fileset dir="${source.dir}">
>         <include name="*/lib/**/*.*"/>
>         <exclude name="**/urmel.*"/>
>       </fileset>
>       <regexpmapper from="${source.dir}/*/lib/(.*)" to="\1" 
> handledirsep="1"/>

And this is hardly surprising as I was confounding shell patterns and
regular expressions. The following, while not working, is at least a
suitable regular expression:

  <regexpmapper handledirsep="1"
    from="${source.dir}/[-_a-zA-Z0-9]+/lib/(.*)"
	  to="\1" />

How is @handledirsep supposed to work?
-- 
Michael Ludwig

RE: simplify copy with regexpmapper (mapper/regexp)

Posted by "Ludwig, Michael" <Mi...@delphi-mb.de>.
> From: Ludwig, Michael

> Unfortunately, however, the <copy> task in Ant 1.8.1 does not support
> a nested <regexmapper>.
> 
>   copy doesn't support the nested "regexmapper" element.

Fortunately, however, it starts supporting it once you spell it correctly:

  <regexpmapper><!-- there's a "p" here, phonetically debatable -->

The following does not work for me, though:

<project default="copy">
  <property name="source.dir" location="src"/>
  <property name="target.dir" location="lib"/>
  <target name="copy">
    <copy todir="${target.dir}">
      <fileset dir="${source.dir}">
        <include name="*/lib/**/*.*"/>
        <exclude name="**/urmel.*"/>
      </fileset>
      <regexpmapper from="${source.dir}/*/lib/(.*)" to="\1" handledirsep="1"/>
    </copy>
  </target>
</project>

-- 
Michael Ludwig

RE: simplify copy with regexpmapper (mapper/regexp)

Posted by "Ludwig, Michael" <Mi...@delphi-mb.de>.
> Now I want to copy the files below src/*/lib, or most of them.
> And I want to strip the leading two directories. I came up with
> the following solution, but it is clumsy and I think there is
> a better way that I'm missing.

It appears to me from the documentation of the Mapper Type [1]
that regexmapper/@handledirsep could be used to accomplish the job.

> <project default="copy">
>   <property name="source.dir" location="src"/>
>   <property name="target.dir" location="lib"/>
> 
>   <target name="copy">
>     <copy todir="${target.dir}">
>       <fileset dir="${source.dir}">
>         <include name="*/lib/**/*.*"/>
>         <exclude name="**/urmel.*"/>
>       </fileset>
>       <!-- portability: path separator logic redoubled in regexp -->
>       <mapper type="regexp" from="^[-_a-zA-Z0-9]*[\\/]lib(.*)" to="\1"/>

It could fit in here.

>     </copy>
>   </target>
> </project>

Unfortunately, however, the <copy> task in Ant 1.8.1 does not support
a nested <regexmapper>.

  copy doesn't support the nested "regexmapper" element.

You need a plain <mapper>, but:

  mapper doesn't support the "handledirsep" attribute

Looks like there is still potential to improve composability.

[1] http://ant.apache.org/manual/Types/mapper.html
-- 
Michael Ludwig