#!/bin/bash # Copyright (C) 2024 Red Hat, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # Generates the 'source tarball' for JDK projects. # # Example 1: # When used from local repo set REPO_ROOT pointing to file:// with your repo. # If your local repo follows upstream forests conventions, it may be enough to # set OPENJDK_URL. # # Example 2: # This will read the OpenJDK feature version from the spec file, then create a # tarball from the most recent tag for that version in the upstream Git # repository. # # $ OPENJDK_LATEST=1 ./generate_source_tarball.sh # [...] # Tarball is: temp-generated-source-tarball-ujD/openjdk-17.0.10+6-ea.tar.xz # # Unless you use OPENJDK_LATEST, you have to set PROJECT_NAME, REPO_NAME and # VERSION, e.g.: # # PROJECT_NAME=openjdk # REPO_NAME=jdk17u # VERSION=jdk-17.0.10+7 # # or to e.g., prepare systemtap, icedtea7's jstack and other tapsets: # # VERSION=6327cf1cea9e # REPO_NAME=icedtea7-2.6 # PROJECT_NAME=release # OPENJDK_URL=http://icedtea.classpath.org/hg/ # TO_COMPRESS="*/tapset" # # They are used to create correct name and are used in construction of sources # URL (unless REPO_ROOT is set). # # This script creates a single source tarball out of the repository based on the # given tag and removes code not allowed in Fedora/RHEL. set -e OPENJDK_URL_DEFAULT=https://github.com COMPRESSION_DEFAULT=xz if [ "$1" = "help" ] ; then echo "Behaviour may be specified by setting the following variables:" echo echo "VERSION - the version of the specified OpenJDK project" echo " (required unless OPENJDK_LATEST is set)" echo "PROJECT_NAME - the name of the OpenJDK project being archived" echo " (needed to compute REPO_ROOT and/or" echo " FILE_NAME_ROOT automatically;" echo " optional if they are set explicitly)" echo "REPO_NAME - the name of the OpenJDK repository" echo " (needed to compute REPO_ROOT automatically;" echo " optional if REPO_ROOT is set explicitly)" echo "OPENJDK_URL - the URL to retrieve code from" echo " (defaults to ${OPENJDK_URL_DEFAULT})" echo "COMPRESSION - the compression type to use" echo " (defaults to ${COMPRESSION_DEFAULT})" echo "FILE_NAME_ROOT - name of the archive, minus extensions" echo " (defaults to PROJECT_NAME-VERSION)" echo "REPO_ROOT - the location of the Git repository to archive" echo " (defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME.git)" echo "TO_COMPRESS - what part of clone to pack" echo " (defaults to ${VERSION})" echo "BOOT_JDK - the bootstrap JDK to satisfy the configure run" echo " (defaults to packaged JDK version)" echo "WITH_TEMP - run in a temporary directory" echo " (defaults to disabled)" echo "OPENJDK_LATEST - deduce VERSION from most recent upstream tag" echo " (implies WITH_TEMP, computes everything else" echo " automatically; Note: accesses network to read" echo " tag list from remote Git repository)" exit 1; fi if [ "$OPENJDK_LATEST" != "" ] ; then FEATURE_VERSION=$(echo '%featurever' \ | rpmspec --shell ./*.spec 2>/dev/null \ | grep --after-context 1 featurever \ | tail --lines 1) PROJECT_NAME=openjdk REPO_NAME=jdk"${FEATURE_VERSION}"u # Skip -ga tags since those are the same as the most recent non-ga tag, and # the non-ga tag is the one that is used to generated the official source # tarball. For example: # ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10-ga^{} # 25a2e6c20c9a96853714284cabc6b456eb095070 refs/tags/jdk-17.0.10-ga # ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10+7^{} # e49c5749b10f3e90274b72e9279f794fdd191d27 refs/tags/jdk-17.0.10+7 VERSION=$(git ls-remote --tags --refs --sort=-version:refname \ "${OPENJDK_URL_DEFAULT}/${PROJECT_NAME}/${REPO_NAME}.git" \ "jdk-${FEATURE_VERSION}*" \ | grep --invert-match '\-ga$' \ | head --lines 1 | cut --characters 52-) FILE_NAME_ROOT=open${VERSION} WITH_TEMP=1 fi if [ "$WITH_TEMP" != "" ] ; then pushd "$(mktemp --directory temp-generated-source-tarball-XXX)" fi if [ "$VERSION" = "" ] ; then echo "No VERSION specified" exit 2 fi echo "Version: ${VERSION}" NUM_VER=${VERSION##jdk-} RELEASE_VER=${NUM_VER%%+*} BUILD_VER=${NUM_VER##*+} MAJOR_VER=${RELEASE_VER%%.*} echo "Major version is ${MAJOR_VER}, release ${RELEASE_VER}, build ${BUILD_VER}" if [ "$BOOT_JDK" = "" ] ; then echo "No boot JDK specified". BOOT_JDK=/usr/lib/jvm/java-${MAJOR_VER}-openjdk; echo -n "Checking for ${BOOT_JDK}..."; if [ -d "${BOOT_JDK}" ] && [ -x "${BOOT_JDK}"/bin/java ] ; then echo "Boot JDK found at ${BOOT_JDK}"; else echo "Not found"; PREV_VER=$((MAJOR_VER - 1)); BOOT_JDK=/usr/lib/jvm/java-${PREV_VER}-openjdk; echo -n "Checking for ${BOOT_JDK}..."; if [ -d ${BOOT_JDK} ] && [ -x ${BOOT_JDK}/bin/java ] ; then echo "Boot JDK found at ${BOOT_JDK}"; else echo "Not found"; exit 4; fi fi else echo "Boot JDK: ${BOOT_JDK}"; fi if [ "$OPENJDK_URL" = "" ] ; then OPENJDK_URL=${OPENJDK_URL_DEFAULT} echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}" else echo "OpenJDK URL: ${OPENJDK_URL}" fi if [ "$COMPRESSION" = "" ] ; then # rhel 5 needs tar.gz COMPRESSION=${COMPRESSION_DEFAULT} fi echo "Creating a tar.${COMPRESSION} archive" if [ "$FILE_NAME_ROOT" = "" ] ; then if [ "$PROJECT_NAME" = "" ] ; then echo "No PROJECT_NAME specified, needed by FILE_NAME_ROOT" exit 1 fi FILE_NAME_ROOT=${PROJECT_NAME}-${VERSION} echo "No file name root specified; default to ${FILE_NAME_ROOT}" fi if [ "$REPO_ROOT" = "" ] ; then if [ "$PROJECT_NAME" = "" ] ; then echo "No PROJECT_NAME specified, needed by REPO_ROOT" exit 1 fi if [ "$REPO_NAME" = "" ] ; then echo "No REPO_NAME specified, needed by REPO_ROOT" exit 3 fi REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}.git" echo "No repository root specified; default to ${REPO_ROOT}" fi; if [ "$TO_COMPRESS" = "" ] ; then TO_COMPRESS="${VERSION}" echo "No targets to be compressed specified ; default to ${TO_COMPRESS}" fi; echo -e "Settings:" echo -e "\tVERSION: ${VERSION}" echo -e "\tPROJECT_NAME: ${PROJECT_NAME}" echo -e "\tREPO_NAME: ${REPO_NAME}" echo -e "\tOPENJDK_URL: ${OPENJDK_URL}" echo -e "\tCOMPRESSION: ${COMPRESSION}" echo -e "\tFILE_NAME_ROOT: ${FILE_NAME_ROOT}" echo -e "\tREPO_ROOT: ${REPO_ROOT}" echo -e "\tTO_COMPRESS: ${TO_COMPRESS}" echo -e "\tBOOT_JDK: ${BOOT_JDK}" if [ -d "${FILE_NAME_ROOT}" ] ; then echo "exists exists exists exists exists exists exists " echo "reusing reusing reusing reusing reusing reusing " echo "${FILE_NAME_ROOT}" STAT_TIME="$(stat --format=%Y "${FILE_NAME_ROOT}")" TAR_TIME="$(date --date=@"${STAT_TIME}" --iso-8601=seconds)" else mkdir "${FILE_NAME_ROOT}" pushd "${FILE_NAME_ROOT}" echo "Cloning ${VERSION} root repository from ${REPO_ROOT}" git clone --depth=1 -b "${VERSION}" "${REPO_ROOT}" "${VERSION}" pushd "${VERSION}" TAR_TIME="$(git log --max-count 1 --format=%cI)" popd popd fi pushd "${FILE_NAME_ROOT}" # Generate .src-rev so build has knowledge of the revision the tarball was # created from mkdir build pushd build sh "${PWD}"/../"${VERSION}"/configure --with-boot-jdk="${BOOT_JDK}" make store-source-revision popd rm -rf build EA_PART="$(awk -F= \ '/^DEFAULT_PROMOTED_VERSION_PRE/ { if ($2) print "-"$2 }' \ "${VERSION}"/make/conf/version-numbers.conf)" TARBALL_BASE=${FILE_NAME_ROOT}${EA_PART}.tar pushd "${VERSION}" # Omit commit checks, history, and GHA from archive. for skip in .jcheck .hgtags .hgignore .gitattributes .gitignore .github do echo "${skip}"" export-ignore" >> .git/info/attributes done # Do not bother with --mtime here; specify it to tar below. # Unforunately, git-archive sorts added files like .src-rev at the end; # retar below to use GNU tar --sort=name ordering which sorts .src-rev # at the start. git archive --output "${TARBALL_BASE}" --prefix="${VERSION}"/ \ --add-file=.src-rev --format=tar "${VERSION}" popd mv "${VERSION}" "${VERSION}".git tar xf "${VERSION}".git/"${TARBALL_BASE}" echo "Compressing remaining forest" if [ "$COMPRESSION" = "xz" ] ; then SWITCH=cJf else SWITCH=czf fi TARBALL_NAME=${TARBALL_BASE}.${COMPRESSION} XZ_OPT=${XZ_OPT-"-T0"} \ tar --mtime="${TAR_TIME}" --owner=root --group=root --sort=name \ -$SWITCH "${TARBALL_NAME}" "${TO_COMPRESS}" mv "${TARBALL_NAME}" .. popd if [ "$WITH_TEMP" != "" ] ; then echo "Tarball is: $(realpath --relative-to=.. .)/${TARBALL_NAME}" popd else echo -n "Done. You may want to remove the uncompressed version" echo " - $FILE_NAME_ROOT" fi # Local Variables: # compile-command: "shellcheck generate_source_tarball.sh" # fill-column: 80 # indent-tabs-mode: nil # sh-basic-offset: 4 # End: