nested for and properties using Ant - ant

i have list of 10 properties file say 1.properties , 2 .pro ....10.properties
and another file called total.properties which has all the file properties names .
now the problem is print all file contents which are mentioned in total.properies files
Using ant script.
Eg:
1.properties
name:rajesh
languesknown:en,sp
2.properties
name:kumar
languesknown:en,fr,wd
total.properties
numbers: 1,2
output:
name:rajesh
languesknown:en,sp
name:kumar
languesknown:en,fr,wd
USing ant script.
i tried by
but everytime its printing first record i.e 1.properties but its iterating twice depends on no of contents in total properties . so could any one help on this ?

ANT is not a scripting language. Best way to do this is embed a scripting language. The following example uses Groovy
Example
├── build.xml
└── src
├── 10.properties
├── 1.properties
├── 2.properties
├── 3.properties
├── 4.properties
├── 5.properties
├── 6.properties
├── 7.properties
├── 8.properties
├── 9.properties
└── total.properties
build.xml
<project name="demo" default="print-properties">
<target name="bootstrap">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.7/groovy-all-2.1.7.jar"/>
</target>
<target name="print-properties">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
new File("src/total.properties").eachLine {
def props = new File("src/${it}")
println props.name
println props.text
}
</groovy>
</target>
</project>
Notes
The "bootstrap" target installs the groovy task jar
The script reads each line of the "total.properties" file and then prints the name and contents of each filename found.

Related

How to resolve a dependency in an external package workspace_file?

Trying to use a target in the build_file from an external package imported through http_archive that has dependencies defined in the external package workspace via the workspace_file attribute fails. I'm using Bazel 0.27.0 on Debian Testing.
The documentation only talks about referencing targets in the provided build_file, but I could not find any information how one could reference a dependency defined in the provided workspace_file in the provided build_file.
The usual #stringtemplate3//jar syntax fails, but I don't know how I could include a reference to the imported archive which according to the manual would have to start with #antlr3_runtimes.
The project layout looks like this:
├── antlr.BUILD
├── antlr.WORKSPACE
├── BUILD
├── external_dependency
│ └── src
│ └── main
│ └── java
│ └── bazel
│ ├── BUILD
│ └── Hello.java
├── LICENSE
└── WORKSPACE
The WORKSPACE definition looks like this:
workspace(name="bazel")
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "antlr3_runtimes",
sha256 = "d4f7d3c38c5523f8009ff37528e5797c81adb454be6acc9af507cfcb41f2016f",
strip_prefix = "antlr3-master",
urls = ["https://github.com/ibre5041/antlr3/archive/master.tar.gz"],
build_file = "#//:antlr.BUILD",
workspace_file = "#//:antlr.WORKSPACE",
)
It seems that the provided workspace_file is not even analyzed. The build already fails when it tries to resolve the dependencies in the custom build file.
A repro can be found here: https://github.com/marcohu/bazel
bazel build //... shows this error message:
ERROR: /home/user/.cache/bazel/_bazel_user/64492308e78c9898c41f12c18dd29b63/external/antlr3_runtimes/BUILD.bazel:43:1: no such package '#stringtemplate3//jar': The repository '#stringtemplate3' could not be resolved and referenced by '#antlr3_runtimes//:antlr3_tool'
ERROR: Analysis of target '//external_dependency/src/main/java/bazel:hello' failed; build aborted: no such package '#stringtemplate3//jar': The repository '#stringtemplate3' could not be resolved
I reported this in the Bazel issue tracker, but it got rejected with a hint to post here.
Is this use case something that is just not possible? Or did I got the syntax wrong?
At least as of now (I suppose this statement may change in the future versions), bazel does not directly support transitive external dependencies. WORKSPACE file would still get read in even in your case and if it contained entirely broken syntax it'd still fail, but it does not get "acted upon" and you could (currently) for instance load from non-existing labels or call undefined functions and would still be left none the wiser for a nested WORKSPACE.
You essentially have two options:
Repeat your nested dependencies (http_archive rules) in your "parent"/top WORKSPACE.
You can define a function(s) with corresponding repository rules that you load and call in your "parent"/top WORKSPACE.
Bazel actually does support the transitive fetching of jvm dependencies. https://github.com/bazelbuild/rules_jvm_external
WORKSPACE
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
rules_jvm_external_tag = "2.0.1"
rules_jvm_external_sha = "55e8d3951647ae3dffde22b4f7f8dee11b3f70f3f89424713debd7076197eaca"
http_archive(
name = "rules_jvm_external",
sha256 = rules_jvm_external_sha,
strip_prefix = "rules_jvm_external-%s" % rules_jvm_external_tag,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % rules_jvm_external_tag,
)
load("#rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
name = "maven",
artifacts = [
"io.grpc:grpc-netty-shaded:1.22.1",
"io.grpc:grpc-api:1.22.1",
"io.grpc:grpc-testing:1.22.1",
"io.grpc:grpc-core:1.22.1",
"junit:junit:4.12",
],
repositories = [
"https://jcenter.bintray.com/",
"https://repo1.maven.org/maven2",
],
)
BUILD
...
java_library(
name = "hyphenation-service",
srcs = ["src/test/java/com/example/hyphenation/HyphenationServiceTest.java"],
deps = ["#maven//:io_grpc_grpc_core"]
)
...
Example repository https://github.com/mancini0/bazel-grpc-playground

name conflicts of .so file in android binary

I'm linking a cc_library to an android_binary and getting a naming issue. Can someone tells me how to solve it?
The cc_library:
cc_library(
name = "native_library",
srcs = glob(["libs/**/*.so"])
)
The contents of libs directory:
libs
├── armeabi
│   ├── libSound.so
│   ├── libSec.so
│   ├── libWatch.so
│   └── libTec.so
├── armeabi-v7a
│   ├── libSound.so
│   ├── libSec.so
│   └── libWatch.so
├── x86
│   ├── libSound.so
│   ├── libSec.so
│   ├── libWatch.so
│   └── libTec.so
|—— other jars
And The error messages are like this:
ERROR: /the/path/to/BUILD:10:1: in android_binary rule //:debug_apk: Each library in the transitive closure must have a unique basename to avoid name collisions when packaged into an apk, but two libraries have the basename 'libSound.so': libs/armeabi/libSound.so and libs/armeabi-v7a/libSound.so.
...
An alternate approach that takes advantage of android_binary's --fat_apk_cpu flag and does not require renaming your libraries:
android_binary will build each cc_library once for each architecture specified by --fat_apk_cpu. The default of --fat_apk_cpu is just armeabi-v7a. This is known as the "Android split transition". When it builds each cc_library, that cc_library gets passed a --cpu flag from the list in --fat_apk_cpu. We can define config_setting rules that read these flags, and use a select statement in the cc_library, so that your cc_library contains different .so files depending on which architecture that it is built for.
For example:
# BUILD
CPUS = ["armeabi", "armeabi-v7a", "x86"]
[config_setting(name = cpu, values = {"cpu": cpu}) for cpu in CPUS]
cc_library(
name = "native_library",
srcs = select(
{":%s" % cpu : glob(["libs/%s/*.so" % cpu]) for cpu in CPUS}
),
)
android_binary(
name = "app",
srcs = glob(["*.java"]),
manifest = "AndroidManifest.xml",
deps = [":native_library"],
)
And then on the command line you can specify which architectures you want present in the final APK.
$ bazel build --fat_apk_cpu=armeabi,armeabi-v7a,x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
lib/armeabi-v7a/libWatch.so
lib/armeabi-v7a/libSound.so
lib/armeabi-v7a/libSec.so
lib/armeabi-v7a/libTec.so
lib/armeabi/libWatch.so
lib/armeabi/libSound.so
lib/armeabi/libSec.so
lib/armeabi/libTec.so
$ bazel build --fat_apk_cpu=x86 //:app
$ zipinfo -1 bazel-bin/app.apk | grep \.so$
lib/x86/libWatch.so
lib/x86/libSound.so
lib/x86/libSec.so
lib/x86/libTec.so
Specifying only one architecture to build for can speed up your development builds. For example, if you use an x86 emulator while you develop, you don't need the armeabi and armeabi-v7a .so files.
I might be wrong but it's the limitation of apk layout, so I'm afraid you just cannot have that named libs in a fat apk. Is renaming libs into libSound-armeabi.so etc an option for you?

Translate ant script that creates a jar file into sbt

I have an ant file called jarPLCExample.xml that takes some class files and produces a jar file. What would the <jar> tag section of this file look like in sbt?
<project name="jar_myplc" default="jar_myplc" basedir=".">
<property file="../resources/v2.properties"/>
<property name="dist.dir" value="C://where_jar_files_go/lib"/>
<property name="dist.file" value="${dist.dir}/PLC.jar"/>
<target name="jar_myplc">
<tstamp>
<format property="TODAY" pattern="dd/MM/yyyy hh:mm aa" locale="au"/>
</tstamp>
<delete file="${dist.file}" quiet="true"/>
<jar destfile="${dist.file}">
<fileset dir="${v2.out.root}" includes="com/companyname/server/applic/**/*.class"/>
<fileset dir="${v2.out.root}" includes="com/companyname/common/utils/SeaDef*.class"/>
</jar>
<copy file="${dist.file}" todir="C:/deploy"/>
</target>
sbt-assembly no good for this as it seems you can exclude and include jars, but not source file packages and source file names as needs to be done here.
Obviously important to 'go with the flow': I expect sbt will want to compile from source, so no need to explicitly use .class files as the ant task above does.
I already have a build.sbt in the base directory, and it would be sensible to call this file jarPLCExample.sbt, but I don't know how to get sbt to load one particular file. So instead I will have two projects in the one file and manually set the current project by changing their order. (As they both have the same key the second one seems to overwrite the first one - the projects command will always show only one project).
This answer has two shortcomings. It only includes the applic directory rather than all directories (recursively) below applic. Also it will pick up all SeaDef*.class, no matter which directories they are in.
def filter3(file: File, greatGrandParent:String, grandParent:String, parent:String, excludes:List[String]):Boolean = {
file.getParentFile.getName == parent &&
file.getParentFile.getParentFile.getName == grandParent &&
file.getParentFile.getParentFile.getParentFile.getName == greatGrandParent &&
!excludes.exists( _ == file.getName)
}
/*
* <fileset dir="${v2.out.root}" includes="com/companyname/server/applic/**/*.class"/>
* <fileset dir="${v2.out.root}" includes="com/companyname/common/utils/SeaDef*.class"/>
*/
lazy val jarPLCExample = project.in(file(".")).
settings(commonSettings: _*).
settings(
includeFilter in (Compile, unmanagedSources) :=
new SimpleFileFilter(file => filter3(file, "companyname", "server", "applic", List())) ||
new SimpleFileFilter(file => file.getName.startsWith("SeaDef"))
)

listing all files and subdirectories using ant

I am trying to create a rpm package using ant task for that I need to create specfile which will have all the file names in the following format
%attr(0755, root, root) %dir dir1
%attr(0755, root, root) %dir dir1/dir2
%attr(0755, root, root) %dir dir1/dir2/dir3
%attr(0500, root, root) dir1/file1
%attr(0500, root, root) dir1/dir2/file1
I have such directory structure created during my build process but using ant I am not able to list all the files and directories which I can then write into my specfile
following is what I have tried to list the files but it does not differentiate between files and directory , moreover I need some way to iterate over the list.
<fileset id="dist.contents" dir="${nativePackageDir}" includes="**"/> |
<property name="prop.dist.contents" refid="dist.contents"/> | <target name="javaobject-library" depends="props">
<echo>${prop.dist.contents}</echo>
<dirset id="dist.contents" dir="${nativePackageDir}" includes="*"/>
<property name="prop.dist.contents" refid="dist.contents"/>
<echo>${prop.dist.contents}</echo>
Using dirset instead of fileset should fix your problem.
You simply have to write in java an ant task implementation, to which you'll provide as parameters the input directory and the path of the specfile you want to be written.
I find it better and more manageable to have reusable ant tasks in java, instead of having gigantic ant xml files.

What classpath do I need for an Ant taskdef?

I'm new to Ant.
Can someone please tell me what value to put for the 'classpathref' for taskdef?
Will it be the path of the class file?
If yes can an example be given because I tried that and its not working for me.
In the taskdef, the classpathref should be a reference to a previously defined path.
The path should include a jar archive that holds the class implementing the task,
or it should point to the directory in the file system that is the root of the class hierarchy.
This would not be the actual directory that holds your class if your class resides in a package.
Here's an example.
MyTask.java:
package com.x.y.z;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class MyTask extends Task
{
// The method executing the task
public void execute() throws BuildException {
System.out.println( "MyTask is running" );
}
}
Note that the package name is com.x.y.z, so when deployed -
lets say the classes are put under a directory called classes - we might see the class here in the file system:
$ ls classes/com/x/y/z
MyTask.class
Here's a simple build.xml that uses the task:
<project name="MyProject" basedir=".">
<path id="my.classes">
<pathelement path="${basedir}/classes" />
</path>
<taskdef name="mytask" classpathref="my.classes" classname="com.x.y.z.MyTask"/>
<mytask />
</project>
Note that the classpathref given points at the classes directory - the root of the class hierarchy.
When run, we get:
$ ant
Buildfile: .../build.xml
[mytask] MyTask is running
You can do similar using an explicit classpath, rather than a 'classpathref', for example:
<property name="my.classes" value="${basedir}/classes" />
<taskdef name="mytask" classpath="${my.classes}" classname="com.x.y.z.MyTask"/>

Resources