I have been trying to find solution in other posts but no one seems to be accurate.
I am struggling to find way to delete duplicate lines from a file.
From ex, a file RTNameList.txt has contents as
DBParticipant:JdbcDataSource:appdb
DBParticipant:JdbcDataSource:appdb
HttpType:HttpClientConfiguration:Prochttp
HttpType:HttpClientConfiguration:Prochttp
I want only unique line to be written to another file RTNameList-Final.txt .PLease advise best solution using Ant script.
I used below and it does not work.
<loadfile srcfile="${ScriptFilesPath}/RTNameList.txt" property="src.file.head">
<filterchain>
<sortfilter/>
<uniqfilter/>
</filterchain>
</loadfile>
<echo file="${ScriptFilesPath}/RTNameList-Final.txt">${src.file.head}</echo>
Expected output: File RTNameList-Final.txt should have contents as
DBParticipant:JdbcDataSource:appdb
HttpType:HttpClientConfiguration:Prochttp
Ant is not a programming language. The following example uses an embedded groovy script to process the file.
Example
├── build.xml
├── src
│ └── duplicates.txt
└── target
└── duplicatesRemoved.txt
src/duplicates.txt
DBParticipant:JdbcDataSource:appdb
DBParticipant:JdbcDataSource:appdb
HttpType:HttpClientConfiguration:Prochttp
HttpType:HttpClientConfiguration:Prochttp
target/duplicatesRemoved.txt
DBParticipant:JdbcDataSource:appdb
HttpType:HttpClientConfiguration:Prochttp
build.xml
<project name="demo" default="build">
<available classname="org.codehaus.groovy.ant.Groovy" property="groovy.installed"/>
<target name="build" depends="install-groovy">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
ant.mkdir(dir:"target")
def dups = [:]
new File("target/duplicatesRemoved.txt").withWriter { w ->
new File("src/duplicates.txt").withReader { r ->
r.readLines().each {
if (!dups.containsKey(it)) {
dups[it] = it
w.println(it)
}
}
}
}
</groovy>
</target>
<target name="install-groovy" unless="groovy.installed">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.3.6/groovy-all-2.3.6.jar"/>
<fail message="Groovy has been installed. Run the build again"/>
</target>
</project>
Related
I have created ant target that is supposed to delete the bottom line of a file and then echo it out to a file of a different name. The code that I'm using for the target is:
<loadfile srcfile="/dir/example/file.txt" property="last.line.removed">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.TailFilter">
<param name="lines" value="-1"/>
<param name="skip" value="1"/>
</filterreader>
</filterchain>
</loadfile>
<echo message="${last.line.removed}" file="/dir/example/file2.txt" append="true"/>
I have ran this target in the build on its own and it is just echoing back the original file rather than removing the bottom line.
If anyone could tell me why this doesn't work or a better way of doing it then it'd be much appreciated.
I could not replicate the problem...
Example
Running the code produces the expected result (demonstrated by the diff command):
$ ant
$ diff src/file.txt target/file.txt
2d1
< how are you?
Project files
├── build.xml
├── src
│ └── file.txt
└── target
└── file.txt
build.xml
<project name="demo" default="build">
<target name="build">
<mkdir dir="target"/>
<loadfile srcfile="src/file.txt" property="last.line.removed">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.TailFilter">
<param name="lines" value="-1"/>
<param name="skip" value="1"/>
</filterreader>
</filterchain>
</loadfile>
<echo message="${last.line.removed}" file="target/file.txt" append="true"/>
</target>
<target name="clean">
<delete dir="target"/>
</target>
</project>
src/file.txt
hello world
how are you?
target/file.txt
hello world
Background: I read names from an XML file and want to map them to source and target paths for a build task. I am not an experienced Ant user and I'm looking for a way to that is
”readable”
robust and
can be used to determine if targets are out of date (preferably using tasks from Ant or Ant Contrib).
Sample xml:
<list><value>The first name<value><value>The second name</value></list>
Desired resultset:
${dir}/The first name.${ext}
${dir}/The second name.${ext}
I can build the path to each file using pathconvert or mappedresources but I haven't been able to map either result back to a collection of file resources that I can use in a dependset. Is there an elegant solution to this problem?
ANT is not a programming language. Easy to embed groovy.
Example
├── build.xml
├── sample.xml
├── src
│ ├── file1.txt
│ ├── file2.txt
│ └── file3.txt
└── target
├── file1.txt
└── file2.txt
Run as follows
$ ant
Buildfile: /.../build.xml
install-groovy:
build:
[copy] Copying 2 files to /.../target
[copy] Copying /.../src/file1.txt to /.../target/file1.txt
[copy] Copying /.../src/file2.txt to /.../target/file2.txt
BUILD SUCCESSFUL
sample.xml
<list>
<value>file1</value>
<value>file2</value>
</list>
build.xml
<project name="demo" default="build">
<!--
================
Build properties
================
-->
<property name="src.dir" location="src"/>
<property name="src.ext" value="txt"/>
<property name="build.dir" location="target"/>
<available classname="org.codehaus.groovy.ant.Groovy" property="groovy.installed"/>
<!--
===========
Build targets
===========
-->
<target name="build" depends="install-groovy" description="Build the project">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
def xmllist = new XmlSlurper().parse(new File("sample.xml"))
ant.copy(todir:properties["build.dir"], verbose:true, overwrite:true) {
fileset(dir:properties["src.dir"]) {
xmllist.value.each {
include(name:"${it}.${properties["src.ext"]}")
}
}
}
</groovy>
</target>
<target name="clean" description="Cleanup project workspace">
<delete dir="${build.dir}"/>
</target>
<target name="install-groovy" description="Install groovy" unless="groovy.installed">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.3.6/groovy-all-2.3.6.jar"/>
<fail message="Groovy has been installed. Run the build again"/>
</target>
</project>
Problem in running ant showing error Could not load definitions from resource axis-tasks.properties. It could not be found :
Here is the snapshot of build.xml on which the problem occurs
<target name="axis" depends="prepare">
<taskdef resource="axis-tasks.properties"/>
<axis-wsdl2java url="${webconsole.base}/src/myservice.wsdl"
output="${axis.output}">
<mapping
namespace="urn:myservice"
package="com.company.service" />
<mapping
namespace="http://webserviceurl.com"
package="com.company.service" />
</axis-wsdl2java>
</target>
When running ant shows following errors :
/build.xml:76: Problem: failed to create task or type axis-wsdl2java
Cause: The name is undefined.
Action: Check the spelling.
Action: Check that any custom tasks/types have been declared.
Action: Check that any <presetdef>/<macrodef> declarations have taken place.
Environment properties :
export TMPDIR=$HOME/tmp
export RELEASE=$HOME/Release
export JAVA_HOME=/usr/java/current
export ANT_HOME=/usr/local/apache-ant-1.6.5
export PATH=$JAVA_HOME/bin:$ANT_HOME/bin:$PATH
Additional information
Actually, we have two build machines. First one has only root user and we have created /home/user folders manually e.g. /home/rajan etc. In this machine when we run ant as root from /home/rajan/R7_SP1_UTF8/vermaraj_R7_SP1/vobs/project/ip_src/AdminWebConsole ant works properly.
echo $PATH = /usr/java/current/bin:/usr/local/apache-ant-1.6.5/bin:/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
On the second machine, we have created individual user accounts and when we try and run ant either as root or rajan from /home/rajan/R7_SP1_UTF8/vermaraj_R7_SP1/vobs/project/ip_src/AdminWebConsole ant does not works properly.
echo $PATH : /usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
Also, in both the build machines echo $CLASSPATH is empty
locate axis-ant.jar gives output as :
/home/Rajan/R7_SP1_UTF8/vermaraj_R7_SP1/vobs/project/ip_src/AdminWebConsole/lib/axis-ant.jar
/home/Rajan/R7_SP1_UTF8/vermaraj_R7_SP1/vobs/project/ip_src/AdminWebConsole/output/war/WEB-INF/lib/axis-ant.jar
/usr/local/apache-ant-1.6.5/lib/axis-ant.jar
ivy is not an option as this is part of very big code base, it may create problems if we add additional libraries.
The ANT task does appear to have a complex set of dependencies. I would recommend adding the ivy extension to manage these.
Example
├── build.xml
├── src
│ └── myservice.wsdl
└── target
└── output
└── com
└── examples
└── www
└── wsdl
└── HelloService_wsdl
├── Hello_BindingStub.java
├── Hello_PortType.java
├── Hello_Service.java
└── Hello_ServiceLocator.java
build.xml
<project name="demo" default="axis" xmlns:ivy="antlib:org.apache.ivy.ant">
<!--
================
Build properties
================
-->
<property name="build.dir" location="target"/>
<property name="axis.output" location="${build.dir}/output"/>
<available classname="org.apache.ivy.Main" property="ivy.installed"/>
<!--
===========
Targets
===========
-->
<target name="install-ivy" description="Install ivy" unless="ivy.installed">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
<fail message="Ivy has been installed. Run the build again"/>
</target>
<target name="resolve" depends="install-ivy" description="Use ivy to resolve classpaths">
<ivy:cachepath pathid="build.path">
<dependency org="org.apache.axis" name="axis-ant" rev="1.4" />
<dependency org="org.apache.axis" name="axis" rev="1.4" />
<dependency org="org.apache.axis" name="axis-jaxrpc" rev="1.4"/>
<dependency org="commons-logging" name="commons-logging" rev="1.1.1" />
<dependency org="commons-discovery" name="commons-discovery" rev="0.4" />
<dependency org="wsdl4j" name="wsdl4j" rev="1.6.2" />
</ivy:cachepath>
</target>
<target name="axis" depends="resolve" description="Run Axis task">
<taskdef resource="axis-tasks.properties" classpathref="build.path"/>
<mkdir dir="${axis.output}"/>
<axis-wsdl2java url="src/myservice.wsdl" output="${axis.output}">
<mapping namespace="urn:myservice" package="com.company.service" />
<mapping namespace="http://webserviceurl.com" package="com.company.service" />
</axis-wsdl2java>
</target>
<target name="clean" description="Clean workspace">
<delete dir="${build.dir}"/>
</target>
<target name="clean-all" depends="clean" description="Purge ivy cache">
<ivy:cleancache/>
</target>
</project>
axis-task.properties is part of axis-ant.jar, but it is not available for ant :
/build.xml:76: Problem: failed to create task or type axis-wsdl2java
it need's to be on ant classpath.
A simple way - but not recommended - is to put all axis jars in ANT_HOME/lib but that will pollute the ant core installation. Better put in it's own path as described here on axis.apache.org
Another way is to put all your ant addon libraries or third party jars in a special folder and make it available for ant via ANT_ARGS environment variable.
Either put this line in ANT_HOME/bin/ant.sh :
ANT_ARGS="-lib /usr/local/ant_xtralibs:/usr/local/ant_testlibs"
export ANT_ARGS
or create your own startscript as described here
Platform: Ubuntu 16.04 LTS
First of all, for that statement to be valid you need to use Axis 1 (download: here) and not Axis 2.
Then follow the instructions here to specify, among others, the classpath to be used.
Prior to that, the axis.home properties must be set manually in the build.xml from your binary installation root dir, i.e. /opt/local/axis-1_4/, or read from your environment variable AXIS_HOME,pointing to the same dir, like this:
<property environment="env"/>
<property name="axis.home" value="${env.AXIS_HOME}"/>
or set in the build.properties file.
Your *.jar subdir path could differ from ${axis.home}/build/lib, in my case it's ${axis.home}/lib.
I need a build script to be able to copy a folder with all its nested files and folders to another folder. The destination folder already contains its own files and folders, and its nested folder structure can overlap with the source folder. Having executed some commands, I then need to delete only the files that were copied.
Example:
src_folder
subfolder1
file1
dest_folder
subfolder1
file2
file3
Here I need to delete only dest_folder/subfolder1/file1
Is there a way to do this with Ant? If not, can you suggest an alternative build tool that makes this possible?
One way to accomplish similar results would be to back up dest_folder, but it has a lot of files and it takes too long to copy it.
Example
Project files
├── build.xml
├── dest_folder
│ └── subfolder1
│ ├── file2
│ └── file3
└── src_folder
└── subfolder1
└── file1
Build output
$ ant
Buildfile: build.xml
copy-files:
[copy] Copying 1 file to dest_folder
[copy] Copying src_folder/subfolder1/file1 to dest_folder/subfolder1/file1
run-cmd-on-files-in-dest-folder:
[apply] dest_folder/subfolder1/file1
clean-files:
[delete] Deleting dest_folder/subfolder1/file1
build.xml
<project name="demo" default="run">
<target name="run" depends="copy-files,run-cmd-on-files-in-dest-folder,clean-files"/>
<target name="copy-files">
<copy todir="dest_folder" verbose="true">
<fileset dir="src_folder"/>
</copy>
</target>
<target name="run-cmd-on-files-in-dest-folder">
<apply executable="echo">
<srcfile/>
<fileset dir="dest_folder">
<present present="both" targetdir="src_folder"/>
</fileset>
</apply>
</target>
<target name="clean-files">
<delete verbose="true">
<fileset dir="dest_folder">
<present present="both" targetdir="src_folder"/>
</fileset>
</delete>
</target>
</project>
I need to process a directory if it has at least one modified file in it. I wrote a block that reduces a fileset to a unique list of the directories that contain those files, but I think this would be easier if there was a way to do this without the script.
Is there a way?
Tricky to do this with core ANT.
Here's an example using an embedded groovy script:
<project name="demo" default="process-modified-dirs">
<path id="build.path">
<pathelement location="/path/to/groovy-all/jar/groovy-all-2.1.1.jar"/>
</path>
<fileset id="modifiedfiles" dir="src">
<modified/>
</fileset>
<target name="process-modified-dirs">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="build.path"/>
<groovy>
dirs = project.references.modifiedfiles.collect {
new File(it.toString()).parent
}
dirs.unique().each {
ant.echo("Do something with this dir: ${it}")
}
</groovy>
</target>
</project>