- Antlion
- Welcome
- License
-
- How-To Guides
- Getting Started
- Libraries
- Artifacts
- Subprojects
- Repositories
- Policy Strategies
- Format Strings
- Extending Antlion
- FAQ
-
- Tutorials
- First Tutorial: Simple
-
- Ant Tasks
-
<artifact>
-
<libraryDef>
-
-
<library>
-
<library-policy>
-
-
inner processors
-
-
inner repositories
-
<library-type>
-
<library-repository>
-
<library-urlrepository>
-
<library-mavenrepository>
-
<library-repositoryset>
-
<create-artifact>
-
<subprojects>
-
<run-subproject>
-
<replace-target>
-
- Optional Tasks
- About optional tasks
- RegexpTokenFormatter
-
|
Fequently Asked Questions for Antlion
|
Before you get into the FAQ, you'll need to learn a little about the
language used in it:
- module:
A build process and source files that generates a distribution.
- project:
a collection of one or more modules, built at the same time.
Usually, some modules may depend upon other modules before they can
be built.
If you have any suggestions for more FAQs, please post them to the forums.
Q2: When should I run an Artifact or a Project?
|
A:
If your project has a library dependency upon a generated file or other
long-term created thing from another project, then reference it via the
artifact terminology and set of tasks. This is useful when you need that
artifact to compile or test your code.
However, if you need to bundle that artifact with your current project, then
you are better off running that artifact's build as a separate project.
What's the difference? In general, building just the artifact will
only run the minimal build targets to create a working file. This
means things like unit tests and documentation are skipped. When you run
the project, then the full build can be run, helping to ensure that the built
file(s) works as expected.
This is why, currently, Antlion does not allow passing any parameters to
an artifact's build: the artifact's build file should know exactly how to
make this minimal artifact without external pushing and prodding. If you
need an odd alternate build method for an artifact, then look into creating
another Ant target to use as the artifact's build target.
|
|
Q3: How do I specify dependencies on a bootstrapped library?
|
A:
Let's say that you've developed a project that formally releases an Ant task,
but your project also relies on that Ant task to perform your build. This means
you need to bootstrap that Ant task: build it in an informal way
before it gets formally built. This can also be called self-hosting,
or eating your own dog food.
The <subprojects> task allows for adding external
dependencies into the build, but it's not just for formal dependencies.
The trick is to mirror the standard build in a file called something like
bootstrap.xml for that specific module, whose sole duty is to
take the smallest number of steps to build a bootstrap version of the module's
distribution library. This bootstrap version isn't for formal distribution,
but other modules use it to perform their builds.
To fit this into the Antlion's bag of tricks, you create another file
called bootstrap-artifacts.xml to mirror the
artifacts.xml file for that module. This bootstrap version will
allow other modules to reference the bootstrap version and build the bootstrap
library without much hacking.
|
|
Q4: How do I allow for developers to use a head build of a sibling module, but formal builds pull from a repository?
|
A:
Normally, for a dependent sibling module, you want to use the
<artifact>
tag in the <library> . However, one situation where
this doesn't apply is when a project has lots of independent modules, each on
their own build cycle. For instance, the Apache Jakarta project is under one
CVS roof, but each module is built independent of the other.
Here, a "snapshot" version of the library may be appropriate. A module would
publish the formal build somewhere to a "snapshot" location. If you want to keep
a history of builds, then the formal build would also publish to that historical
location. (For snapshots, be sure to read the corresponding faq on
them to ensure you don't fall into a pitfall.)
Then, each dependent module would add another repository that would look to this
"internal" published site (this could very well could be open to the internet),
with a "snapshot" version capability. When the module runs, it would try to load
the snapshot version.
However, the question here is to also allow a developer to build a local copy of
the dependent module, then build the other module using the local recent version.
This would allow a developer to see how a change in one module affects others.
To solve this, add another repository before the "internal" publish repository,
like so:
|
|
|
|
<repository dir="${published.rootdir}"
format="[module]/exports/[artifact].[type]" />
<urlrepository refid="internal-published-site" />
|
|
|
|
|
The build would define the published.rootdir Ant property to the
root directory of the tree. The developer's build would either find the local
version with the first repository, or revert to pulling from the published
site. Like this, the formal build would always use the local version. However,
if you want the formal build to use the published site, then you can have
the formal build set the property published.rootdir (either
through a special properties file or passed in when it runs) to a directory
that doesn't exist. This ensures that the published site is always used.
|
|
Q5: Why is the common 'SNAPSHOT' usage broken?
|
A:
The short answer is because of branches.
When you create a new branch, you don't want to change out the "SNAPSHOT"
labels with a specific version. You would only create a specific version
once it has been officially published, but the branch will want to use
the current "head" version of an artifact for that branch.
Now, let's look at an example developer cycle. In some CM tools, branches
are represented in their own trees (ala Perforce), but usually the
library repository is independent of the code tree. So, the developer
is tasked to work on bug fixes in version 3 of her product, and also
tasked to add new features to the trunk. The project is divided such that
module B depends upon the output of module A.
If our developer adds new features to module B of the trunk, and runs a build
of that module, the library repository should now store a SNAPSHOT revision
of module B's artifact as it exists in the trunk.
Then she moves to fix the bug in version 3. Since the bug only lives in
module A, she writes unit tests first (of course), then fixes the bug.
However, since it has a dependency on module B, module A's build will
look in the library repository to grab the SNAPSHOT version of module B,
which happens to be the version from the trunk, not version 3! Therefore,
her local build will not work like it should.
To fix this issue, make a clean separation between
snapshot repositories and published repositories. When publishing the
SNAPSHOT version, put it in a local repository for the branch. This way,
branches won't be touching each other. There's nothing wrong with storing
all the third-party repositories in a location outside a branch (as long
as it is properly maintained for backwards compatibility with old branches),
but built artifacts that haven't been officially published need to live with
the code that built it.
|
|
|
|
|