PAnt build tool comes with several Ant tasks to facilitate the use of Jython/Python from Ant.
PAnt tasks have a number of advantages over built-in <script language="jython"> way of invoking Jython from Ant:
Example:
Ant code:
<jythonInit pythonPathRef="python.path" />
<property name="testProp" value="testVal" />
<jython>
print "Property from ant:", testProp
# define a var that we can use in other scripts
s="test"
</jython>
<jython>
print "Var created earlier: ",s
</jython>
<jython import="from testmodule import *" exec="test(testProp)" />
"testmodule" python code:
from pant.pant import project
def test (prop):
print "Passed parameter: ",prop
print "Test property: ", project.properties["testProp"]
Please refer to this build.xml file for more examples.
The tasks can be used independently of PAnt python code.
jythonInit is invoked multiple times. The repeating calls are simply ignored.jythonInit automatically adds pant.pant module to PYTHONPATH.
Attributes:
jythonInit will set python.home system property and will automatically add ${python.home}/Lib to the python path if ${python.home}/Lib exists.Nested elements:
pythonPath - python.path to use defined using Ant path-like structure. Required if "pythonPathRef" attribute was not provided.
Special properties:
log.python.path - if set to "true", jythonInit will print python path to Ant log. Default: false.
jython does not print python stack trace in case of an exception. To see the trace, run Ant in verbose mode using "-v" or use "-Dverbose.jython=true" property.
Attributes:
mod.fun() although you could combine multiple statements separated by ";". Required if "execfile" was not provided.exec="import mod;mod.fun()". Optional.Nested elements:
Inline text with python code.
Special properties:
verbose.jython - if set to "true", jython will print additional information about executing python code to Ant log. Default: false.
Creates Ant targets from a python module. Functions that will be used as targets have to be marked using "@target" decorator as described here.
Python module name is used as Ant project name. Target overriding works the same way with Ant import task. In other words, targets defined using pimport will override targets previously defined using "import" or "pimport" tasks.
Attributes:
module - python module to create targets from. The module has to be available from python.path specified using jythonInit.
I am very interested in both your Jython task and PAnt, but both download links are broken. Do you have these available elsewhere?
The links are now fixed. Also, I’ll be uploading an updated version of jythonTask in the next few days.
Interesting work, but configured elements within tasks, like manifest in jar or file in filelist are not supported. Do you plan to fix it?
Hi Michel. It is certainly supported. A nested element is represented by a nested dictionary. E.g.,
ant.copy( todir=”${target.dir}”, overwrite=”true”,
fileset=dict( dir=”.”, includes=”*.xml” ),
filterchain=dict( expandproperties={} ) )
Repeating elements are represented as a list of dictionaries:
filelist=dict(dir=my_dir, file=[{"name":"foo.xml"},{"name":bar.xml"}] )
Or, you can also use suffixes with underscores:
filelist=dict(dir=my_dir, file_foo={”name”:”foo.xml”},file_bar={”name”:bar.xml”} )
Let me know if it does not work for you.
Thank you for your answer. What i meant was that for particular nested elements called ‘configured element’, like for example the element ‘manifest’ nested in ‘jar’ instead of being specified in an attribute of ‘jar’, pant does not configure those element properly . Just try the pant equivalent of:
and check the jar, you’ll see that the manifest is not populated as wanted.
the same for etc…
Sorry the example did not appear in my previous post because of xml the pant example is:
@target(description=”JARs the Task”)
def jar():
“JARs the Task”
zipfileset = dict(src=”dist/libs/lucene-core-2.4.1.jar”)
filelist = dict(dir=”dist/libs”, file=dict(name=”htmlgen.jar”))
manifest = dict(attribute={”name”:”Main-Class”, “value”:”search.Main”})
ant.jar(destfile=”debug/debugpant.jar”, basedir=”bin”,
zipfileset=zipfileset, filelist=filelist, manifest=manifest)
pant works formally on it except that the jar manifest does not contain the Main-Class attribute and the specified libs…..
Michel, I was able to reproduce the issue, I think I know what the problem is. I’ll try to release a fix shortly. Thanks.
It took me a little longer than anticipated, but the bug affecting manifest and several other tasks is now fixed: http://myarch.com/pant-2-0-1-is-released.
Nice work. I found this project after investigating the adoption of gant.
I’will start to usa Pant as build system for my current J2EE project.
I’m using a new decorator to ensure that target functions (if directly invoked by python) runs only once:
def once(f):
to_run = False
def wrap(*args):
if not to_run:
return
return f(*args)
return wrap
The I define my tasks as:
@once
@target(depends=”clean1″)
def compile():
…
I think that this could be the behavior of the @target decorator
Hi Guancio,
I’m trying to understand why it would be desirable for a target function to only run once. Can you explain?
Cheers,
Dear Alexander,
the main reason to execute target function once is because they represent ant target :D.
Using pant I have two way (that can be mixed) to implements dependencies.
The first one is to declare ant target dependencies. If f1 depends on f2 and f3, and both f2 and f3 depends on f4, If I require the execution of the task f1(formally the dask implemented by f1) f4 will be executed only once.
The former approach is to manually call the function f2 and f3 inside the body of f1. In this case the function f4 will be executed twice.