You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Peter Reilly <pe...@gmail.com> on 2006/11/23 19:09:11 UTC

.ant/lib at project level

I have been setting up a new project here and
had been wondering how to allow antunit and ant-contrib
to be added without too much messing around.
I do not want to get the developers to place the antlibs
in ~/.ant/lib or $ANT_HOME/lib, - different projects
will use different antlibs and I do not want to
pollute the project class paths with unneeded jars.
Work arounds of using <typedef> in the build file is possible
but ikky.

I then had a brainwave, why not have a .ant/lib directory
in the project directory (defined as the directory
that contains the build file).

This would act in the same way as ~/.ant/lib, any
jar files in this directory will be added to the Project
classpath by Launcher.  This would allow antlibs
to be added to a project (via source code control) without configuration,
it would also allow ant's optional tasks to be using with modifing
~/.ant/lib or $ANT_HOME/lib (or using the -lib command
line option).

The diff is:
Index: src/main/org/apache/tools/ant/launch/Launcher.java

===================================================================

--- src/main/org/apache/tools/ant/launch/Launcher.java	(revision 478174)

+++ src/main/org/apache/tools/ant/launch/Launcher.java	(working copy)

@@ -35,6 +35,9 @@

  */
 public class Launcher {

+    /** The default build file name. {@value} */
+    public static final String DEFAULT_BUILD_FILENAME = "build.xml";
+
     /**
      * The Ant Home (installation) Directory property.
      * {@value}
@@ -70,6 +73,15 @@

         ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB;

     /**
+     * The location of a per-project library directory.
+     * <p>
+     * This is currently the same as the {@link #USER_LIBDIR}
+     * relative to the build file.
+     */
+    public static final String PROJECT_LIBDIR = USER_LIBDIR;
+
+
+    /**
      * The startup class that is to be run.
      * {@value}
      */
@@ -157,6 +169,8 @@

             throws LaunchException, MalformedURLException {
         String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
         File antHome = null;
+        String buildFileName = null;
+        String findFileName = null;

         File sourceJar = Locator.getClassSource(getClass());
         File jarDir = sourceJar.getParentFile();
@@ -204,6 +218,28 @@

                 noUserLib = true;
             } else if (args[i].equals("--noclasspath") ||
args[i].equals("-noclasspath")) {
                 noClassPath = true;
+            } else if (args[i].equals("-find") || args[i].equals("-s")) {
+                if (i == args.length - 1) {
+                    findFileName = DEFAULT_BUILD_FILENAME;
+                    argList.add(args[i]);
+                } else {
+                    findFileName = args[i + 1];
+                    argList.add(args[i]);
+                    argList.add(args[i + 1]);
+                    i++;
+                }
+            } else if (args[i].equals("-buildfile")
+                       || args[i].equals("-file")
+                       || args[i].equals("-f")) {
+                if (i == args.length - 1) {
+                    buildFileName = DEFAULT_BUILD_FILENAME;
+                    argList.add(args[i]);
+                } else {
+                    buildFileName = args[i + 1];
+                    argList.add(args[i]);
+                    argList.add(args[i + 1]);
+                    i++;
+                }
             } else if (args[i].equals("-main")) {
                 if (i == args.length - 1) {
                     throw new LaunchException("The -main argument must "
@@ -252,20 +288,34 @@

             System.setProperty(ANTLIBDIR_PROPERTY,
antLibDir.getAbsolutePath());
         }
         URL[] systemJars = Locator.getLocationURLs(antLibDir);
-
+        System.out.println("HERE I AM");
         File userLibDir
             = new File(System.getProperty(USER_HOMEDIR), USER_LIBDIR);

         URL[] userJars = noUserLib ? new URL[0] :
Locator.getLocationURLs(userLibDir);
+        File projectLibDir = findProjectAntLib(buildFileName, findFileName);

-        int numJars = libJars.length + userJars.length + systemJars.length;
+        URL[] projectJars = (projectLibDir == null)
+            ? new URL[0] : Locator.getLocationURLs(projectLibDir);
+
+        int numJars = libJars.length + projectJars.length
+            + userJars.length + systemJars.length;
         if (toolsJar != null) {
             numJars++;
         }
         URL[] jars = new URL[numJars];
         System.arraycopy(libJars, 0, jars, 0, libJars.length);
-        System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
-        System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
+        System.arraycopy(
+            projectJars, 0, jars,
+            libJars.length,
+            projectJars.length);
+        System.arraycopy(
+            userJars, 0, jars,
+            libJars.length + projectJars.length,
+            userJars.length);
+        System.arraycopy(
+            systemJars, 0, jars,
+            libJars.length + projectJars.length + userJars.length,
             systemJars.length);

         if (toolsJar != null) {
@@ -309,4 +359,69 @@

         }
         return exitCode;
     }
+
+    /**
+     * Search parent directories for the build file.
+     * This is a near copy of same method from Main.java,
+     * but this method does not throw an exception if the
+     * build file cannot be found, instead it returns null.
+     * <p>
+     * Takes the given target as a suffix to append to each
+     * parent directory in search of a build file.  Once the
+     * root of the file-system has been reached an exception
+     * is thrown.
+     *
+     * @param start  Leaf directory of search.
+     *               Must not be <code>null</code>.
+     * @param filename  Suffix filename to look for in parents.
+     *                Must not be <code>null</code>.
+     *
+     * @return A handle to the build file if one is found, null
+     *         if not found.
+     *
+     * @exception BuildException if no build file is found
+     */
+    private File findBuildFile(String start, String filename) {
+        File parent = new File(new File(start).getAbsolutePath());
+        File file = new File(parent, filename);
+
+        // check if the target file exists in the current directory
+        while (!file.exists()) {
+            // change to parent directory
+            parent = file.getParentFile();
+
+            // if parent is null, then we are at the root of the fs,
+            // retunr null as we cannot find the file
+            if (parent == null) {
+                return null;
+            }
+
+            // refresh our file handle
+            file = new File(parent, filename);
+        }
+
+        return file;
+    }
+
+    private File findProjectAntLib(String buildName, String findName) {
+        File buildFile = null;
+        if (buildName != null) {
+            buildFile = new File(buildName).getAbsoluteFile();
+        } else if (findName != null) {
+            buildFile = findBuildFile(
+                System.getProperty("user.dir"), findName);
+        } else {
+            buildFile = new File(DEFAULT_BUILD_FILENAME).getAbsoluteFile();
+        }
+        File buildDir = buildFile.getParentFile();
+        if (buildDir == null) {
+            return null;
+        }
+        File projectAntLib = new File(buildDir, PROJECT_LIBDIR);
+        if (projectAntLib.isDirectory()) {
+            return projectAntLib;
+        } else {
+            return null;
+        }
+    }
 }

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


Re: seemingly infinite loop in Project class

Posted by Peter Reilly <pe...@gmail.com>.
On 11/24/06, Martijn Kruithof <jk...@apache.org> wrote:
> Peter Reilly schreef:
> > On 11/23/06, Dave Brosius <db...@apache.org> wrote:
> >>     protected void fireMessageLogged(Project project, String message,
> >>                                      int priority) {
> >>         fireMessageLogged(project, message, priority);
> >>     }
> > That does incorrect.....
> > It possible should be fireMessageLogged(project, message, null,
> > priority).
> > The question is why is there so many variants of fireMessageLogged(),
> > +Event
> > - they are protected methods - so they can only be used by derived
> > classses
> > of Project and by classes within o.a.t.a ?
> >
> > Peter
> Yep it is incorrect.
>
> I have added, and not removed the methods because of backward
> compatibility.

Ahh, yes they are in ant 1.6.5.

Peter


> In my view protected methods are just as public as public
> methods (we may have users we do not know of, and they would be
> rightfully using it). If they would have been package scoped I would not
> have mercy.
>
> Martijn
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

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


Re: seemingly infinite loop in Project class

Posted by Martijn Kruithof <jk...@apache.org>.
Peter Reilly schreef:
> On 11/23/06, Dave Brosius <db...@apache.org> wrote:
>>     protected void fireMessageLogged(Project project, String message,
>>                                      int priority) {
>>         fireMessageLogged(project, message, priority);
>>     }
> That does incorrect.....
> It possible should be fireMessageLogged(project, message, null, 
> priority).
> The question is why is there so many variants of fireMessageLogged(), 
> +Event
> - they are protected methods - so they can only be used by derived 
> classses
> of Project and by classes within o.a.t.a ?
>
> Peter
Yep it is incorrect.

I have added, and not removed the methods because of backward 
compatibility. In my view protected methods are just as public as public 
methods (we may have users we do not know of, and they would be 
rightfully using it). If they would have been package scoped I would not 
have mercy.

Martijn

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


Re: seemingly infinite loop in Project class

Posted by Peter Reilly <pe...@gmail.com>.
On 11/23/06, Dave Brosius <db...@apache.org> wrote:
>     protected void fireMessageLogged(Project project, String message,
>                                      int priority) {
>         fireMessageLogged(project, message, priority);
>     }
That does incorrect.....
It possible should be fireMessageLogged(project, message, null, priority).
The question is why is there so many variants of fireMessageLogged(), +Event
- they are protected methods - so they can only be used by derived classses
of Project and by classes within o.a.t.a ?

Peter

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

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


seemingly infinite loop in Project class

Posted by Dave Brosius <db...@apache.org>.
    protected void fireMessageLogged(Project project, String message,
                                     int priority) {
        fireMessageLogged(project, message, priority);
    }

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


Re: .ant/lib at project level

Posted by Peter Reilly <pe...@gmail.com>.
On 11/27/06, Steve Loughran <st...@apache.org> wrote:
> Peter Reilly wrote:
> > On 11/24/06, Steve Loughran <st...@apache.org> wrote:
>
> >>
> >> Right now the workstation to my right is doing an ivy-manged build of
> >> three different codebases, from different CVS/SVN repositories, using
> >> the <buildlist > task to create an ordered list of all projects that
> >> declare interdependencies in their ivy files.
> >>
> >> In a world like that, whose .ant/lib files get picked up? the first?
> >
> > The .ant/lib would be the master build file's directory - since
> > this is the one that used by oata.launch.Launcher from ant.bat/ant sh file
> >
> > In your case, I do not know that ivy/buildlist does to call
> > the multiple projects build files,
> > I assume that the <ant> task will be used, in this
> > case the .ant/lib directories of the controlled projects
> > will be ignored.
>
>
> yes, ivy:buildlist ignores the files in subdirs, and as you say,
> <subant> will pick up the main directories builds.
>
> But I dont want to have to create a .lib dir for every sub project in a
> build. somehow they have to pick up the  parent's .lib dir. Otherwise
> unless you play a lot with symlinks or SVN, you cannot use this feature
> in hierarchical projects.

Perhaps a seach for .ant directory option could be added so that
sub-projects in a hiearchical structure could pick up the master
.ant directory.

This would have to be an option to ant.bat or ant, as we
would not want this to be the default behaviour.

Peter

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

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


Re: .ant/lib at project level

Posted by Steve Loughran <st...@apache.org>.
Peter Reilly wrote:
> On 11/24/06, Steve Loughran <st...@apache.org> wrote:

>>
>> Right now the workstation to my right is doing an ivy-manged build of
>> three different codebases, from different CVS/SVN repositories, using
>> the <buildlist > task to create an ordered list of all projects that
>> declare interdependencies in their ivy files.
>>
>> In a world like that, whose .ant/lib files get picked up? the first?
> 
> The .ant/lib would be the master build file's directory - since
> this is the one that used by oata.launch.Launcher from ant.bat/ant sh file
> 
> In your case, I do not know that ivy/buildlist does to call
> the multiple projects build files,
> I assume that the <ant> task will be used, in this
> case the .ant/lib directories of the controlled projects
> will be ignored.


yes, ivy:buildlist ignores the files in subdirs, and as you say, 
<subant> will pick up the main directories builds.

But I dont want to have to create a .lib dir for every sub project in a 
build. somehow they have to pick up the  parent's .lib dir. Otherwise 
unless you play a lot with symlinks or SVN, you cannot use this feature 
in hierarchical projects.

-steve


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


Re: .ant/lib at project level

Posted by Peter Reilly <pe...@gmail.com>.
On 11/24/06, Steve Loughran <st...@apache.org> wrote:
> Peter Reilly wrote:
>  > I have been setting up a new project here and
>  > had been wondering how to allow antunit and ant-contrib
>  > to be added without too much messing around.
>  > I do not want to get the developers to place the antlibs
>  > in ~/.ant/lib or $ANT_HOME/lib, - different projects
>  > will use different antlibs and I do not want to
>  > pollute the project class paths with unneeded jars.
>  > Work arounds of using <typedef> in the build file is possible
>  > but ikky.
>  >
>  > I then had a brainwave, why not have a .ant/lib directory
>  > in the project directory (defined as the directory
>  > that contains the build file).
>  >
>  > This would act in the same way as ~/.ant/lib, any
>  > jar files in this directory will be added to the Project
>  > classpath by Launcher.  This would allow antlibs
>  > to be added to a project (via source code control) without configuration,
>  > it would also allow ant's optional tasks to be using with modifing
>  > ~/.ant/lib or $ANT_HOME/lib (or using the -lib command
>  > line option).
>
> I can see the appeal of this, but I have a concern.
>
> Right now the workstation to my right is doing an ivy-manged build of
> three different codebases, from different CVS/SVN repositories, using
> the <buildlist > task to create an ordered list of all projects that
> declare interdependencies in their ivy files.
>
> In a world like that, whose .ant/lib files get picked up? the first?

The .ant/lib would be the master build file's directory - since
this is the one that used by oata.launch.Launcher from ant.bat/ant sh file

In your case, I do not know that ivy/buildlist does to call
the multiple projects build files,
I assume that the <ant> task will be used, in this
case the .ant/lib directories of the controlled projects
will be ignored.

Peter


> all? If I exit a project, does its stuff get undeclared?
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
> For additional commands, e-mail: dev-help@ant.apache.org
>
>

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


Re: .ant/lib at project level

Posted by Steve Loughran <st...@apache.org>.
Peter Reilly wrote:
 > I have been setting up a new project here and
 > had been wondering how to allow antunit and ant-contrib
 > to be added without too much messing around.
 > I do not want to get the developers to place the antlibs
 > in ~/.ant/lib or $ANT_HOME/lib, - different projects
 > will use different antlibs and I do not want to
 > pollute the project class paths with unneeded jars.
 > Work arounds of using <typedef> in the build file is possible
 > but ikky.
 >
 > I then had a brainwave, why not have a .ant/lib directory
 > in the project directory (defined as the directory
 > that contains the build file).
 >
 > This would act in the same way as ~/.ant/lib, any
 > jar files in this directory will be added to the Project
 > classpath by Launcher.  This would allow antlibs
 > to be added to a project (via source code control) without configuration,
 > it would also allow ant's optional tasks to be using with modifing
 > ~/.ant/lib or $ANT_HOME/lib (or using the -lib command
 > line option).

I can see the appeal of this, but I have a concern.

Right now the workstation to my right is doing an ivy-manged build of 
three different codebases, from different CVS/SVN repositories, using 
the <buildlist > task to create an ordered list of all projects that 
declare interdependencies in their ivy files.

In a world like that, whose .ant/lib files get picked up? the first? 
all? If I exit a project, does its stuff get undeclared?


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


Re: .ant/lib at project level

Posted by Peter Reilly <pe...@gmail.com>.
On 12/1/06, Stefan Bodewig <bo...@apache.org> wrote:
> On Thu, 23 Nov 2006, Peter Reilly <pe...@gmail.com> wrote:
>
> > I then had a brainwave, why not have a .ant/lib directory
> > in the project directory (defined as the directory
> > that contains the build file).
>
> I can see how this would be useful.  OTOH I fear that would be too
> much magic.


> You could achive the same with a simple piece fo shell script in
> ~/.antrc, couldn't you?

I do not think so,
the idea is that it is project specific, so the shell script
would have to do some processing - it would thus
not be possible to port to windows.
Peter


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

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


Re: .ant/lib at project level

Posted by Stefan Bodewig <bo...@apache.org>.
On Thu, 23 Nov 2006, Peter Reilly <pe...@gmail.com> wrote:

> I then had a brainwave, why not have a .ant/lib directory
> in the project directory (defined as the directory
> that contains the build file).

I can see how this would be useful.  OTOH I fear that would be too
much magic.

You could achive the same with a simple piece fo shell script in
~/.antrc, couldn't you?

Stefan

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