Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cmake/ecbuild_bundle.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ endmacro()
# To switch off a subproject when building a bundle, set the CMake variable
# ``BUNDLE_SKIP_<PNAME>`` where ``PNAME`` is the capitalised project name.
#
# Note: BRANCH, TAG, UPDATE, NOREMOTE, MANUAL, RECURSIVE, and SHALLOW are not
# parsed by ecbuild_bundle itself. They are forwarded verbatim to ecbuild_git
# via the unparsed-arguments mechanism (``${_PAR_UNPARSED_ARGUMENTS}``). Any
# future keyword added to ecbuild_bundle must not clash with an ecbuild_git
# keyword unless intentional forwarding is desired.
#
##############################################################################

macro( ecbuild_bundle )
Expand Down
14 changes: 11 additions & 3 deletions cmake/ecbuild_git.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ endif()
# Do a shallow clone (``--depth 1``) on initial checkout.
# When combined with RECURSIVE, submodules are also fetched at depth 1.
# Cannot be combined with TAG when it's a commit ID (SHA).
# SHALLOW is not switchable and will fail if UPDATE is requested on an existing shallow clone.
# When using the SHALLOW option, attempting to switch branch/tag will result in a failure.
# The SHALLOW option will fail if used in combination with UPDATE.
# The SHALLOW option will fail if used in combination with NOREMOTE.
#
##############################################################################

Expand All @@ -85,7 +87,11 @@ function( ecbuild_git )
endif()

if( _PAR_UPDATE AND _PAR_SHALLOW )
ecbuild_warn("UPDATE and SHALLOW conflict — shallow clones aren't switchable; UPDATE may be ignored or fail.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ecbuild_critical fails? if yes, this changes the behavior, not just a log change as in PR desc. if it's intentional, it's fine.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi.

I was just following the documentation above, which stated: SHALLOW is not switchable and will fail if UPDATE is requested on an existing shallow clone.
Given the inconsistency between implementation and documentation, I decided to err on the side of caution and fail clearly and as early as possible.

ecbuild_critical("Cannot pass both UPDATE and SHALLOW in ecbuild_git.")
endif()

if( _PAR_NOREMOTE AND _PAR_SHALLOW )
ecbuild_critical("Cannot pass both NOREMOTE and SHALLOW in ecbuild_git.")
endif()

if(_PAR_UNPARSED_ARGUMENTS)
Expand Down Expand Up @@ -224,7 +230,9 @@ function( ecbuild_git )
# fetching latest tags and branches

if( _PAR_SHALLOW )
ecbuild_info("${_PAR_DIR} is SHALLOW : Skipping fetch")
ecbuild_info("${_PAR_DIR} is a shallow clone\n"
" * Skipping fetch in order to preserve shallow history.\n"
" * Run 'git fetch --unshallow' manually if full history is needed.")
elseif( NOT _PAR_NOREMOTE )

ecbuild_info("git fetch --all @ ${ABS_PAR_DIR}")
Expand Down
34 changes: 32 additions & 2 deletions tests/ecbuild_bundle_shallow/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@

ecbuild_add_test(
TARGET test_ecbuild_bundle_shallow
TARGET test_ecbuild_bundle_shallow_recursive
TYPE SCRIPT
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run-test.sh
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run-test-shallow-recursive.sh
ENVIRONMENT
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
)

ecbuild_add_test(
TARGET test_ecbuild_bundle_shallow_no_recursive
TYPE SCRIPT
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run-test-shallow-no-recursive.sh
ENVIRONMENT
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
)

ecbuild_add_test(
TARGET test_ecbuild_bundle_shallow_update_fails
TYPE SCRIPT
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run-test-invalid-update.sh
ENVIRONMENT
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
)

ecbuild_add_test(
TARGET test_ecbuild_bundle_shallow_noremote_fails
TYPE SCRIPT
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run-test-invalid-noremote.sh
ENVIRONMENT
CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
CMAKE_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
Expand Down
81 changes: 81 additions & 0 deletions tests/ecbuild_bundle_shallow/run-test-invalid-noremote.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash

set -euo pipefail

ECBUILD_PATH=${CMAKE_SOURCE_DIR}/bin
BINARY_TEST_DIR=${CMAKE_CURRENT_BINARY_DIR}

#
# Redirect HOME to a per-job temp directory so that every git process
# (including subprocesses spawned internally by git-submodule) reads a private
# ~/.gitconfig. This avoids lock contention on the real ~/.gitconfig when
# parallel CI jobs run, and works on all git versions.
#
# GIT_CONFIG_GLOBAL (requires git >= 2.32) and GIT_CONFIG_COUNT (not forwarded
# by git-submodule to its child processes) are not viable alternatives here.
#
# Required on git >= 2.38.1 and on distros that have backported CVE-2022-39253
# (e.g. Debian 11's git 2.30.2).
#
_tmp_home=$(mktemp -d)
export HOME="${_tmp_home}"
trap 'rm -rf "${_tmp_home}"' EXIT
pushd "${HOME}" > /dev/null
git config --global protocol.file.allow always
git config --global user.name "Test User"
git config --global user.email "test@user"
popd > /dev/null

# Add ecbuild to path
export PATH=$ECBUILD_PATH:$PATH

# ---- cleanup -----------------------------------------
[[ -n "${BINARY_TEST_DIR}" ]] || { echo "BINARY_TEST_DIR is not set"; exit 1; }
rm -rf "${BINARY_TEST_DIR}/workspace-invalid-noremote"

WORKSPACE="${BINARY_TEST_DIR}/workspace-invalid-noremote"
BUNDLE_DIR="${WORKSPACE}/bundle"

# ---- create bundle: SHALLOW + NOREMOTE (invalid combination) -
# ecbuild_critical fires before any git operation, so the URL need not exist.
mkdir -p "${BUNDLE_DIR}"
cat > "${BUNDLE_DIR}/CMakeLists.txt" <<EOF
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
find_package( ecbuild 3.12 REQUIRED HINTS ${CMAKE_SOURCE_DIR} )
project( umbrella-bundle LANGUAGES NONE )
ecbuild_bundle_initialize()
ecbuild_bundle(
PROJECT umbrella
GIT "file:///does-not-need-to-exist.git"
BRANCH main
SHALLOW
NOREMOTE
)
ecbuild_bundle_finalize()
EOF

cat > "${BUNDLE_DIR}/VERSION" <<EOF
0.0.1
EOF

# ---- configure should FAIL with a clear error message --------
mkdir -p "${WORKSPACE}/build"
cd "${WORKSPACE}/build"

set +e
output=$( ecbuild --prefix="$(pwd)/install" -- "${BUNDLE_DIR}" 2>&1 )
cmake_status=$?
set -e

if [[ "${cmake_status}" -eq 0 ]]; then
echo "cmake configure should have failed for SHALLOW+NOREMOTE but succeeded: FAIL"
exit 1
fi

if echo "${output}" | grep -q "Cannot pass both NOREMOTE and SHALLOW"; then
echo "SHALLOW+NOREMOTE correctly rejected: PASS"
else
echo "cmake failed but expected error message not found: FAIL"
echo "${output}"
exit 1
fi
81 changes: 81 additions & 0 deletions tests/ecbuild_bundle_shallow/run-test-invalid-update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env bash

set -euo pipefail

ECBUILD_PATH=${CMAKE_SOURCE_DIR}/bin
BINARY_TEST_DIR=${CMAKE_CURRENT_BINARY_DIR}

#
# Redirect HOME to a per-job temp directory so that every git process
# (including subprocesses spawned internally by git-submodule) reads a private
# ~/.gitconfig. This avoids lock contention on the real ~/.gitconfig when
# parallel CI jobs run, and works on all git versions.
#
# GIT_CONFIG_GLOBAL (requires git >= 2.32) and GIT_CONFIG_COUNT (not forwarded
# by git-submodule to its child processes) are not viable alternatives here.
#
# Required on git >= 2.38.1 and on distros that have backported CVE-2022-39253
# (e.g. Debian 11's git 2.30.2).
#
_tmp_home=$(mktemp -d)
export HOME="${_tmp_home}"
trap 'rm -rf "${_tmp_home}"' EXIT
pushd "${HOME}" > /dev/null
git config --global protocol.file.allow always
git config --global user.name "Test User"
git config --global user.email "test@user"
popd > /dev/null

# Add ecbuild to path
export PATH=$ECBUILD_PATH:$PATH

# ---- cleanup -----------------------------------------
[[ -n "${BINARY_TEST_DIR}" ]] || { echo "BINARY_TEST_DIR is not set"; exit 1; }
rm -rf "${BINARY_TEST_DIR}/workspace-invalid-update"

WORKSPACE="${BINARY_TEST_DIR}/workspace-invalid-update"
BUNDLE_DIR="${WORKSPACE}/bundle"

# ---- create bundle: SHALLOW + UPDATE (invalid combination) ---
# ecbuild_critical fires before any git operation, so the URL need not exist.
mkdir -p "${BUNDLE_DIR}"
cat > "${BUNDLE_DIR}/CMakeLists.txt" <<EOF
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
find_package( ecbuild 3.12 REQUIRED HINTS ${CMAKE_SOURCE_DIR} )
project( umbrella-bundle LANGUAGES NONE )
ecbuild_bundle_initialize()
ecbuild_bundle(
PROJECT umbrella
GIT "file:///does-not-need-to-exist.git"
BRANCH main
SHALLOW
UPDATE
)
ecbuild_bundle_finalize()
EOF

cat > "${BUNDLE_DIR}/VERSION" <<EOF
0.0.1
EOF

# ---- configure should FAIL with a clear error message --------
mkdir -p "${WORKSPACE}/build"
cd "${WORKSPACE}/build"

set +e
output=$( ecbuild --prefix="$(pwd)/install" -- "${BUNDLE_DIR}" 2>&1 )
cmake_status=$?
set -e

if [[ "${cmake_status}" -eq 0 ]]; then
echo "cmake configure should have failed for SHALLOW+UPDATE but succeeded: FAIL"
exit 1
fi

if echo "${output}" | grep -q "Cannot pass both UPDATE and SHALLOW"; then
echo "SHALLOW+UPDATE correctly rejected: PASS"
else
echo "cmake failed but expected error message not found: FAIL"
echo "${output}"
exit 1
fi
96 changes: 96 additions & 0 deletions tests/ecbuild_bundle_shallow/run-test-shallow-no-recursive.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash

set -euo pipefail

ECBUILD_PATH=${CMAKE_SOURCE_DIR}/bin
SOURCE_TEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}
BINARY_TEST_DIR=${CMAKE_CURRENT_BINARY_DIR}

#
# Redirect HOME to a per-job temp directory so that every git process
# (including subprocesses spawned internally by git-submodule) reads a private
# ~/.gitconfig. This avoids lock contention on the real ~/.gitconfig when
# parallel CI jobs run, and works on all git versions.
#
# GIT_CONFIG_GLOBAL (requires git >= 2.32) and GIT_CONFIG_COUNT (not forwarded
# by git-submodule to its child processes) are not viable alternatives here.
#
# Required on git >= 2.38.1 and on distros that have backported CVE-2022-39253
# (e.g. Debian 11's git 2.30.2).
#
_tmp_home=$(mktemp -d)
export HOME="${_tmp_home}"
trap 'rm -rf "${_tmp_home}"' EXIT
pushd "${HOME}" > /dev/null
git config --global protocol.file.allow always
git config --global user.name "Test User"
git config --global user.email "test@user"
popd > /dev/null

# Add ecbuild to path
export PATH=$ECBUILD_PATH:$PATH

# ---- cleanup -----------------------------------------
[[ -n "${BINARY_TEST_DIR}" ]] || { echo "BINARY_TEST_DIR is not set"; exit 1; }
rm -rf "${BINARY_TEST_DIR}/workspace-shallow-only"

WORKSPACE="${BINARY_TEST_DIR}/workspace-shallow-only"
BUNDLE_DIR="${WORKSPACE}/bundle"

# ---- setup umbrella project (with submodules) --------
cd "${BINARY_TEST_DIR}"
bash "${SOURCE_TEST_DIR}/setup-umbrella-project.sh" "${WORKSPACE}/projects"

BARE_DIR="${WORKSPACE}/bare-repos"
UMBRELLA_GIT="file://${BARE_DIR}/umbrella.git"

# ---- create bundle: SHALLOW only (no RECURSIVE) ------
mkdir -p "${BUNDLE_DIR}"
cat > "${BUNDLE_DIR}/CMakeLists.txt" <<EOF
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
find_package( ecbuild 3.12 REQUIRED HINTS ${CMAKE_SOURCE_DIR} )
project( umbrella-bundle LANGUAGES NONE )
ecbuild_bundle_initialize()
ecbuild_bundle(
PROJECT umbrella
GIT "${UMBRELLA_GIT}"
BRANCH main
SHALLOW
)
ecbuild_bundle_finalize()
EOF

cat > "${BUNDLE_DIR}/VERSION" <<EOF
0.0.1
EOF

# ---- configure umbrella bundle -----------------------
mkdir -p "${WORKSPACE}/build"
cd "${WORKSPACE}/build"
ecbuild --prefix="$(pwd)/install" -- "${BUNDLE_DIR}"

# ---- check: umbrella is shallow ----------------------
PASS=1

cd "${BUNDLE_DIR}/umbrella"
if [[ "$(git rev-parse --is-shallow-repository)" != "true" ]]; then
echo "Umbrella is not shallow: FAIL"
PASS=0
else
echo "Umbrella is shallow: PASS"
fi

# ---- check: submodules are NOT initialised -----------
# Without RECURSIVE, ecbuild_git skips the submodule update step; the
# submodule directories should exist (as tracked gitlinks) but must not
# contain an initialised git repo (.git file/dir created by submodule init).
for sub in alpha beta gamma; do
if [[ -e "${BUNDLE_DIR}/umbrella/${sub}/.git" ]]; then
echo "Submodule ${sub} is initialised but RECURSIVE was not requested: FAIL"
PASS=0
else
echo "Submodule ${sub} is not initialised: PASS"
fi
done

exit $(( 1 - PASS ))
Loading
Loading