ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Michael Smith <mich...@sneakerlabs.com>
Subject Path & dir separators (was Re: Ant Principles)
Date Wed, 19 Apr 2000 14:17:42 GMT
"Kuiper, Arnout" wrote:
> Use the "//c/foo/bar" way, Scott proposed. I don't have that much
> problems with this strategy. It lets the users think about using
> full paths. Keep in mind that absolute paths should not be used,
> and this should be a rare situation then. This method has no
> ambiguities.

Actually, since you're talking about the Windows world, you can have UNC
path names.  The //c/foo/bar would conflict with a UNC path referring to a
file 'bar' in the share 'foo' on computer 'c'.  


I hate to put another proposal out there, but...

So far, here's what I think we can all agree on:

 - A developer on a windows platform prefers to use ; and \ as the path 
   and directory separators and desires the ability to use UNC names
   and drive letters followed by colons.  A unix platform developer 
   may prefer to use : and / (and doesn't care about UNC names and drive
   letters).  Mac developers would prefer to use whatever separators are
   used on the mac platform.

 - The build file should be portable to other platforms, but in some
   cases it doesn't need to be.
 
 - It would be nice to support absolute paths, even for a build that must 
   be made on multiple platforms


To allow developers to use the separators that they are accustomed to on
their platform, Ant would add two optional attributes to the project element
in the XML file -- one specifying the path separator and one specifying the
directory separator.  Then, all path and dir separators that appear in the
build file are interpreted based on the ones specified as attributes to the
project element.  If an attribute is omitted, the default for the local
platform is used.

Let me give an example.  I currently develop on the windows platform.  When
I create my build file, I create it looking like this:

  <project>
    <!-- [snip] -->
    <property name="classpath" value="..\classes;..\libs\foo.jar"/>
    <!-- [snip] -->
  </project>

No changes to this build need to be made in order for it to work on the
windows platform.  The default dir and path separators of \ and ; will be
assumed because I'm running on a windows platform.  It will not, however,
work on unix platforms.  To truely make this build file portable to other
platforms, the build file would need to look like:

  <project pathseparator=";" dirseparator="\">
    <!-- [snip] -->
    <property name="classpath" value="..\classes;..\libs\foo.jar"/>
    <!-- [snip] -->
  </project>

This build file can now be properly interpreted on other platforms
(including a Mac!).  An equivalent build file (which works on all platforms)
for a unix developer would like like this:

  <project pathseparator=":" dirseparator="/">
    <!-- [snip] -->
    <property name="classpath" value="../classes:../libs/foo.jar"/>
    <!-- [snip] -->
  </project>

Since I believe developers that build stuff on multiple platforms *know*
that they build stuff on multiple platforms, it shouldn't be a big deal to
require them to put in the separators -- a small price to pay for a truly
portable build file.  

So far, I have assumed that the directory and path separators are consistent
throughout the entire build file.  While in most cases this will be true, it
would be nice to support different separators within the same file.  Why you
might ask?  For absolute paths. A build file may rely on absolute paths to
build properly, and the absolute paths on windows and unix filesystems are
specified differently.  

To solve this problem, I am relying on the usage of the path definition
stuff proposed by Thomas Haas.  In the "element" and "path" elements that
are used to define a bath, a "pathseparator" and "dirseparator" attribute
are optionally added.  (note:  the pathseparator is meaningless in the
"element" element, as it specified only one path element).  The attributes
specified on the path element would override any specified at the project
level.    

For example, consider the following build file created for building on a
unix platform:

<project>
  <!-- [snip] -->
  <somepath>
   <element location="../classes" />
   <path definition="/usr/local/classes:/usr/local/classes/foo.jar" />
  </somepath>
  <!-- [snip] -->
</project>

You could make this "portable" to run under Windows by changing it to the
following:

<project dirseparator="/" pathseparator=":">
  <!-- [snip] -->
  <somepath>
   <element location="../classes" />
   <path definition="/usr/local/classes:/usr/local/classes/foo.jar" />
  </somepath>
  <!-- [snip] -->
</project>

However, while this build file is portable, the build itself isn't portable
because of the absolute paths are not going to be found on a windows
platform.  Using the path level separators, you would add the following to
get the build to work on a Windows platform:

<project dirseparator="/" pathseparator=":">
  <!-- [snip] -->
  <somepath>
   <element location="../classes" />
   <path definition="/usr/local/classes:/usr/local/classes/foo.jar" />
   <path definition="D:\libs;D:\libs\foo.jar" 
         dirseparator="\" pathseparator=";" />
  </somepath>
  <!-- [snip] -->
</project>

Now, the absolute paths will be found on both windows and unix platforms
with only one drawback -- there will be extraneous path information added. 
When on a Unix platform, the paths D:/libs and D:/libs/foo.jar will be added
(they most likely do not exist), and on the windows platform, the paths
\usr\local\classes and \usr\local\classes\foo.jar will be added (which also
are unlikely to exist).

To remove this potential problem, another attribute can be added to the
"path" and "element" elements that specify which platform they should be
added on (very similar to the "os" attribute in the exec taskdef).  This
portable build file would then become:

<project dirseparator="/" pathseparator=":">
  <!-- [snip] -->
  <somepath>
   <element location="../classes" />
   <path definition="/usr/local/classes:/usr/local/classes/foo.jar" 
         os="unix"/>
   <path definition="D:\libs;D:\libs\foo.jar" 
         os="win" dirseparator="\" pathseparator=";" />
  </somepath>
  <!-- [snip] -->
</project>

Then, the path that is built will be 
On unix:
../classes:/usr/local/classes:/usr/local/classes/foo.jar

On windows:
..\classes;D:\libs;D:\libs\foo.jar


We now have a truely portable build file that will work on unix and windows
and includes absolute paths.  To get the build working on a mac, you would
probably need to add path elements to point to foo.jar -- although if you
had just relied on relative paths, your life would have been easier... :)


Sorry this was a bit long...

Regards,
Michael

-- 
michael@sneakerlabs.com
http://www.sneakerlabs.com

Mime
View raw message