If your build fails for whatever reason during a dry run, abort it with ^C^D
(Ctrl+C
followed by Ctrl+D
). tetra
will restore all project files as they were before the build.
You can edit any file generated by tetra - regenerating it later will not overwrite your changes.
tetra
will try to reconcile your edits with a three-way merge,
if that fails you will be warned about any conflicts.
You can generate single files with the following commands:
tetra generate-script
: (re)generates thebuild.sh
file from commands used in the latest successful dry-run;tetra generate-spec
: (re)generates the package spec;tetra generate-kit
: (re)generates the kit tarball and spec;
If you need to modify your project's sources for whatever reason, feel free to do so and then use
tetra patch "my patch message"
to signal your changes.
After that you can retry the dry-run and spec generation: tetra will take care of creating patch files and adding
%patch
instructions for you.
In case you want to swap sources with a completely new archive, discarding all previous patches use
tetra change-sources <archive> "my message"
.
Ant is fully supported. You have a prebundled copy in kit
, and using ant
from a dry-run will use that by default.
Sometimes you will have jar files distributed along with the source archive that will end up in src/
: you don't want
that! Run:
tetra move-jars-to-kit
to have them moved to kit/jars
. The command will generate symlinks back to the originals, so builds will work as
expected.
When generating spec files, it helps to have a pom.xml
in your package directory even if you are not using Maven, as
tetra
will automatically take advantage of information from it to compile many fields, but it's not required.
You can also ask tetra
to find one via tetra get-pom <filename>.jar
.
Maven has the ability of treating complex projects as multi-module sub-projects with an independent life cycle and
pom.xml
file (this is called Maven's Reactor).
You might be interested in building only a part of a multi-module project for your package, you can accomplish that by adding:
--projects project-name1,project-name2
To your mvn
commandline during dry-runs. Note that any dependencies between modules are not automatically resolved,
so you will have to pass to --projects
all of the dependent projects manually.
You might want to supply a different set of Maven repositories to a project, for example in case URLs changed since the
pom.xml
file was written. In order to do that, add the following section to kit/m2/settings.xml
:
<profiles>
<profile>
<id>repos</id>
<repositories>
<!-- Add Maven Central -->
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>repos</activeProfile>
</activeProfiles>
Plugin repositories can be added via <pluginRepositories>
and <pluginRepository>
tags in <profile>
as well.
In case the bundled Ant or Maven versions are not usable in your project for whatever reason and you want to bundle a
different one, just remove their directories from kit
and replace them with your own. tetra
will look for binaries
named ant
or mvn
in kit and use them wherever they are found.
tetra
fully supports projects using Gradle from version 6.1.1 on.
To build a project with a Gradle Wrapper, just use
gradlew
instead of ./gradlew
during dry run.
Please note that Gradle typically ships with libnative
as a platform-dependent binary library. That means you will
need to build the RPM package on an x86_64 host.
Here are special instructions valid for previous versions only, as they require a different procedure to work around the impossibility to relocate Gradle's cache.
-
during your dry-run build, add the
--gradle-user-home /tmp/gradle --project-cache-dir /tmp/gradle-project
-
commandline options to
gradlew
in order to download gradle files in the/tmp
directory instead of your home. -
Typically:
./gradlew --gradle-user-home /tmp/gradle --project-cache-dir /tmp/gradle-project clean build -x test
Note that gradle 1.6 has a bug and it will not honor the
--gradle-user-home
flag. Even if you use a fixed gradle, an old gradlew could not honor it. Use instead:export GRADLE_USER_HOME=/tmp/gradle ./gradlew --project-cache-dir /tmp/gradle-project clean build -x test
-
after the build has finished but prior ending the dry-run, copy all files to your kit with:
cp -r /tmp/gradle* ../../kit/
-
after your build script is generated, remove from
build.sh
the following line:cp -r /tmp/gradle* ../../kit/
-
Then add the following line to
build.sh
in order to restore files fromkit/
to/tmp
beforegradlew
is called:cp -r kit/* /tmp
-
furthermore, add the
--offline
commandline option togradlew
inbuild.sh
to ensure the build will not need -
Internet access.
Note that you cannot put files in kit/
directly because your build would break on relocation, see GRADLE-2690.
Finally note that if you want to upgrade gradle and remove the previous versions, you should remove /tmp/gradle/*
directories, as well as the kit/gradle/*
directories (use git rm
for this). Of course remember to adjust your
gradlew
call, build.gradle
and/or gradle-wrapper.properties
files with the new version.
In case you need to upgrade Gradle (eg. to support a newer JDK), but still on a version lower than 6.1.1, the following procedure can be followed:
# update the Gradle URL to the new version
sed -i "s#distributionUrl=.*#distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip#g" gradle/wrapper/gradle-wrapper.properties
# run Gradle Wrapper to download the latest Gradle version
export GRADLE_USER_HOME=/tmp/gradle
./gradlew wrapper --gradle-version 6.1.1 --project-cache-dir /tmp/gradle-project
# Patch sources. Depending on the project setup you might need additional steps here, see Gradle upgrade documentation
# at https://docs.gradle.org/current/userguide/upgrading_version_6.html
git add gradlew* gradle/wrapper/gradle-wrapper.properties
git commit -m "Update Gradle Wrapper"
# Patch kit
cp -r /tmp/gradle* ../../kit/
cp gradle/wrapper/gradle-wrapper.jar ../../kit
git add ../../kit
git checkout gradle/wrapper/gradle-wrapper.jar
git commit -m "Update Gradle"
Now dry-run again as per the above instructions.
Other build tools are currently not supported out-of-the-box but you can still use them with some manual tweaking. You should basically make sure that:
- a copy of their executables and libraries is stored and gets called from
kit/
- all files automatically downloaded during the build are also stored in
kit
.
Tool-specific instructions for most popular tools follow.
Assuming ivy is used by ant:
- during your dry-run build, add the
-Divy.default.ivy.user.dir=<PATH_TO_PROJECT>/kit/ivy
commandline option toant
- in order to download files in the
kit
directory; - after your build script is generated, replace the path to your project with
$PROJECT_PREFIX
inbuild.sh
to ensure - the build will not need Internet access.
Instructions:
- before starting your dry-run build, copy a binary release to a subdirectory in
kit/
, for examplekit/sbt/
; - during your dry-run build, add the
-Dsbt.global.base=../../kit/sbt-global-base
commandline option tosbt
in order - to download files in the
kit
directory; - if your build also uses Ivy, add
-Dsbt.ivy.home=../../kit/ivy2
as well; - after your build script is generated, add the
"set offline := true"
commandline option tosbt
tobuild.sh
to - ensure the build will not need Internet access.
OBS integration
If you want to submit your package to OBS, you can do so by copying contents of the packages
in a proper OBS project
directory.
Packages will rebuild cleanly in OBS because no Internet access is needed - all files were already downloaded during dry-run and are included in the kit.
Note that the kit packages is only needed at build time by OBS, no end user should ever install it, so you can place it in a non-public project/repository if you so wish.
If your package sources do not ship in a source archive you can use tetra init --no-sources <package_name>
to start a
tetra project without sources. This is in general not recommended but it might be needed if your package sources are
shipped in a format other than tar or zip, or it is distributed in multiple files, etc. Note that most version control
systems allow you to export a checkout of a certain version in tarball form - this is recommended in tetra (and RPM in
general) over using raw source files.
Then you can add sources manually by:
- placing the archives in
packages/<project name>
- unpacking them in
src
- running
tetra change-sources --no-archive
.
tetra
assumes that sources in packages/<project name>
and src
match, except for patches as described above - it is
your responsibility to keep them in sync.
Note that most version control systems are able to produce an archive from a specific revision, using that is
recommended over checking out raw files for tetra
use.
tetra
internally usesgit
to keep track of files, any tetra project is actually also agit
repo. Feel free to- use it as any ordinary git repo, including pushing to a remote repo, rebasing, merging or using GitHub's pull
- requests. Just make sure any
tetra:
comments are preserved; tetra
will commit in itsgit
repo thesrc
andkit
directories during dry-run and any generatedspec
file.- You are free to commit other files but it's not strictly necessary (eg. generated tarballs);
- some Maven plugins like the Eclipse Project ones (Tycho) will save data in
/tmp
- downloaded from the Internet and will produce errors if this data is not there during offline builds. One way to work
- around that is to force Java to use a kit subdirectory as
/tmp
. Add the following option tomvn
during your build:
-Djava.io.tmpdir=<full path to project>/kit/tmp
Use the following option in mvn
in your build.sh file to make it reproducible:
-Djava.io.tmpdir=$PROJECT_PREFIX/kit/tmp
- Tycho builds may also require NSS, so if you get NSS errors be sure to add
mozilla-nss
or an equivalent package in a - BuildRequires: line;
- some badly designed testsuites might not work in OBS. If you are using
mvn
you can add the following option to - disable them:
-DskipTests=true
- if you want to be 100% sure your package builds without network access, you can use scripts in the
utils/
folder to - create a special
nonet
user that cannot use the Internet and retry the build from that user.