How to Run Perl and Ruby Scripts as Tasks in Ant

How can I run perl and ruby scripts as tasks in ant?

You can always use the ant`s exec task to run arbitrary programs, such as ruby and perl. For example and from the docs:

<target name="help">
<exec executable="cmd">
<arg value="/c"/>
<arg value="ant.bat"/>
<arg value="-p"/>
</exec>
</target>

How to run ruby script as a task from ant build?

It looks like you're passing a single arg value with embedded spaces

<arg value="C:\EduTester\others\afterant.rb 1 2 tri four"/>

Is that right? Or should it be either an arg line:

<arg line="C:\EduTester\others\afterant.rb 1 2 tri four"/>

or multiple arg values:

<arg value="C:\EduTester\others\afterant.rb"/>
<arg value="1"/>
<arg value="2"/>
<arg value="tri"/>
<arg value="four"/>

Alternative to ANT as task execution engine?

If you have a modern version of Ant (e.g. 1.8.1) you can use the scriptcondition task/element to run arbitrary scripts with all the control flow of a proper programming language in it.

Something like this:

<condition>
<scriptcondition language="javascript" value="true">
for(var i in self) { println(i); }
self.setValue('true');
</scriptcondition>
</condition>

See also: http://ant.apache.org/manual/index.html

Ant build script to run a batch file, while passing user input to batch file

You can pass parameters using -D switch:

-D<property>=<value>    Defines a property name-value pair on the command line.

and you can refer to this parameter with ${<property>}

For example:

<target name="css-val">
<exec dir="M:\burnjc_view\ServiceTeams\Team 4\Report\CssValidation\bin" executable="cmd" os="Windows 7">
<arg line="/c cssvalFile.bat ${file1} ${file2}"/>
</exec>
</target>

and while running

ant -Dfile1=somefile -Dfile2=somefile build.xml

Hope this helps

use system classpath for ant javac task

Soo... seems I have to answer the question myself. Passing the original classpath to the javac task can be achieved with this:

<!-- load environment into the env property -->
<property environment="env" />

<javac srcdir="${src}" destdir="${obj}"
includes="**/*.java"
excludes="**/package-info.java **/deprecated/*.java"
includeAntRuntime="no" includeJavaRuntime="no"
debug="true" debuglevel="source,lines"
>
<!-- add -classpath option manually -->
<compilerarg value="-classpath" />
<compilerarg value="${env.CLASSPATH}" />
<compilerarg value="-Xlint"/>
</javac>

That does the trick at least so far that the javac task now gets passed the correct classpath. Yet it will still not work, javac now spits these complaints:

[javac] warning: [path] bad path element "D:\local\lib\java\*": no such file or directory
[javac] warning: [path] bad path element "C:\lib\java\*": no such file or directory
[javac] warning: [path] bad path element "C:\lib\java\db\*": no such file or directory

This is a straight lie, these paths do very much exist. I use them all the time, and if I manually craft an equivalent javac invocation at the shell, it works like a charm. I suspect ant's javac doesn't resolve the jar files in those directories. I have to examine that.

UPDATE

It is indeed as I suspected, the wildcard is not resolved to the individual present jar files by the javac task. I managed to do the resolving manually, and now it works as it should. And that resolving was in fact a struggle on its own. So I'll leave the solution here for those poor souls fighting the same stupidity, hopefully before they ask people that have nothing else to do than bullshitting around (yes Anon, talking about you).

Turns out, ant lacks the most basic functionality that you would expect from a build tool. Also turns out that I'm not the first one to notice that. While solutions are rare, there is a very good post about Using JavaScript to make Apache Ant less painful, which really saved my day. Yes, ant can indeed be scripted, which seems not to be widely known, although it is not kept secret. You can safely assume, that Javascript is already available without installing additional libraries if you run ant on Java 6.

Soo... down to business. Here is the thing:

<target name="expand_classpath">
<script language="javascript"><![CDATA[
// the original classpath
var ocp = java.lang.System.getenv("CLASSPATH");
// ... split in parts
var ocp_parts = ocp.split(project.getProperty("path.separator"));

// where our individual jar filenames go,
// together with pure directories from ocp_parts
var expanded_parts = [ ];

for each (var part in ocp_parts) {
if (part.endsWith('*')) {
var dir = part.substring(0, part.length() - 1);
var f = new java.io.File(dir);

// don't know how to construct a java.io.FilenameFilter,
// therefore filter the filenames manually
for each (var file in f.listFiles())
if (file.getPath().endsWith('.jar'))
expanded_parts.push(file.getPath());
} else
expanded_parts.push(part);
}

var expanded = expanded_parts.join(project.getProperty("path.separator"));
project.setProperty("classpath.expanded", expanded);
]]></script>

<!-- <echo message="classpath.expanded = ${classpath.expanded}" /> -->
</target>

<target name="build" depends="expand_classpath">
<mkdir dir="${obj}" />

<javac srcdir="${src}" destdir="${obj}"
classpath="${classpath.expanded}"
includes="**/*.java"
excludes="**/package-info.java **/deprecated/*.java"
includeAntRuntime="no" includeJavaRuntime="no"
debug="true" debuglevel="source,lines"
>
<compilerarg value="-Xlint"/>
<compilerarg value="-Xlint:-fallthrough"/>
</javac>
</target>

Single script to run in both Windows batch and Linux Bash?

What I have done is use cmd’s label syntax as comment marker. The label character, a colon (:), is equivalent to true in most POSIXish shells. If you immediately follow the label character by another character which can’t be used in a GOTO, then commenting your cmd script should not affect your cmd code.

The hack is to put lines of code after the character sequence “:;”. If you’re writing mostly one-liner scripts or, as may be the case, can write one line of sh for many lines of cmd, the following might be fine. Don’t forget that any use of $? must be before your next colon : because : resets $? to 0.

:; echo "Hi, I’m ${SHELL}."; exit $?
@ECHO OFF
ECHO I'm %COMSPEC%

A very contrived example of guarding $?:

:; false; ret=$?
:; [ ${ret} = 0 ] || { echo "Program failed with code ${ret}." >&2; exit 1; }
:; exit
ECHO CMD code.

Another idea for skipping over cmd code is to use heredocs so that sh treats the cmd code as an unused string and cmd interprets it. In this case, we make sure that our heredoc’s delimiter is both quoted (to stop sh from doing any sort of interpretation on its contents when running with sh) and starts with : so that cmd skips over it like any other line starting with :.

:; echo "I am ${SHELL}"
:<<"::CMDLITERAL"
ECHO I am %COMSPEC%
::CMDLITERAL
:; echo "And ${SHELL} is back!"
:; exit
ECHO And back to %COMSPEC%

Depending on your needs or coding style, interlacing cmd and sh code may or may not make sense. Using heredocs is one method to perform such interlacing. This could, however, be extended with the GOTO technique:

:<<"::CMDLITERAL"
@ECHO OFF
GOTO :CMDSCRIPT
::CMDLITERAL

echo "I can write free-form ${SHELL} now!"
if :; then
echo "This makes conditional constructs so much easier because"
echo "they can now span multiple lines."
fi
exit $?

:CMDSCRIPT
ECHO Welcome to %COMSPEC%

Universal comments, of course, can be done with the character sequence : # or :;#. The space or semicolon are necessary because sh considers # to be part of a command name if it is not the first character of an identifier. For example, you might want to write universal comments in the first lines of your file before using the GOTO method to split your code. Then you can inform your reader of why your script is written so oddly:

: # This is a special script which intermixes both sh
: # and cmd code. It is written this way because it is
: # used in system() shell-outs directly in otherwise
: # portable code. See https://stackoverflow.com/questions/17510688
: # for details.
:; echo "This is ${SHELL}"; exit
@ECHO OFF
ECHO This is %COMSPEC%

Thus, some ideas and ways to accomplish sh and cmd-compatible scripts without serious side effects as far as I know (and without having cmd output '#' is not recognized as an internal or external command, operable program or batch file.).



Related Topics



Leave a reply



Submit