Skip to content

Latest commit

 

History

History
284 lines (199 loc) · 11.6 KB

SPECIAL_CASES.md

File metadata and controls

284 lines (199 loc) · 11.6 KB

Special cases

Failing dry-runs

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.

Generating files multiple times

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 the build.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;

Patches

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 builds

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: only build a subset of a multi-module project

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.

Maven: add or override repositories

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.

Use different Ant or Maven versions

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.

Gradle

Recent versions (>= 6.1.1)

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.

Older versions (<6.1.1)

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 from kit/ to /tmp before gradlew is called:

     cp -r kit/* /tmp
  • furthermore, add the --offline commandline option to gradlew in build.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.

Upgrading Gradle to versions older than 6.1.1

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

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.

ivy

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 to ant
  • in order to download files in the kit directory;
  • after your build script is generated, replace the path to your project with $PROJECT_PREFIX in build.sh to ensure
  • the build will not need Internet access.

sbt

Instructions:

  • before starting your dry-run build, copy a binary release to a subdirectory in kit/, for example kit/sbt/;
  • during your dry-run build, add the -Dsbt.global.base=../../kit/sbt-global-base commandline option to sbt 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 to sbt to build.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.

Packaging software without a source archive

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.

Gotchas

  • tetra internally uses git to keep track of files, any tetra project is actually also a git 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 its git repo the src and kit directories during dry-run and any generated spec 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 to mvn 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.