cmake_minimum_required(VERSION 3.16)

set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_OUTPUT_FILE_PREFIX "${PROJECT_SOURCE_DIR}/dist")
set(CPACK_VERBATIM_VARIABLES YES)

set(SourceIgnoreFiles 
  ".cache"
  ".copr"
  ".clang-format"
  ".clangd"
  ".git/"
  ".gitea/"
  ".github/"
  ".gitignore"
  ".idea"
  "CMakeCache.txt"
  "CMakeFiles/"
  "CPackConfig.cmake$"
  "CPackSourceConfig.cmake"
  "CTestTestfile.cmake"
  "Makefile"
  "_CPack_Packages/"
  "build/"
  "cmake-build*"
  "cmake_install.cmake"
  "dist/"
  "temp/"
)

# Escape any '.' and '/' characters
string(REPLACE "." "\\\." SourceIgnoreFiles "${SourceIgnoreFiles}")
string(REPLACE "/" "\\\/" SourceIgnoreFiles "${SourceIgnoreFiles}")

# Override install prefix for package target
string(REGEX REPLACE "^/(.*)" "\\1" 
  CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
)
set(CPACK_SET_DESTDIR ON)

set(CPACK_GENERATOR "TGZ")
set(CPACK_PACKAGE_TOPLEVEL_TAG "noarch")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}.${CPACK_PACKAGE_TOPLEVEL_TAG}")
set(CPACK_IGNORE_FILES "${SourceIgnoreFiles}")
set(CPACK_OUTPUT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CPackConfig.cmake")
configure_file(
  "${PROJECT_SOURCE_DIR}/cmake/CPackConfig.cmake.in"
  "${PROJECT_BINARY_DIR}/CPackConfig.cmake"
  @ONLY
)

set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_TOPLEVEL_TAG "src")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}.${CPACK_SOURCE_TOPLEVEL_TAG}")
set(CPACK_SOURCE_IGNORE_FILES "${SourceIgnoreFiles}")
set(CPACK_SOURCE_OUTPUT_CONFIG_FILE "${PROJECT_BINARY_DIR}/CPackSourceConfig.cmake")
configure_file(
  "${PROJECT_SOURCE_DIR}/cmake/CPackConfig.cmake.in"
  "${PROJECT_BINARY_DIR}/CPackSourceConfig.cmake"
  @ONLY
)

if(BUILD_RPMS)
execute_process(
  COMMAND cat "${CMAKE_CURRENT_SOURCE_DIR}/changelog.txt"
  OUTPUT_VARIABLE CPACK_RPM_CHANGELOG
)

execute_process(
  COMMAND bash -c
    "head -1 \"${CMAKE_CURRENT_SOURCE_DIR}/changelog.txt\" \
      | grep -iPo '.*${CPACK_PACKAGE_VERSION}-\\K[\\d]' \
      | tr -d '\\n' \
      | grep -P '\\d' \
    || echo -n 1 \
    "
  OUTPUT_VARIABLE CPACK_RPM_PACKAGE_RELEASE
)

CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/packaging/pkg.spec.in"
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.spec"
  @ONLY 
  IMMEDIATE
)

set(CPACK_GENERATOR "RPM")
set(CPACK_SOURCE_GENERATOR "RPM")
set(CPACK_RPM_USER_PACKAGE_SOURCES ON)
set(CPACK_RPM_USER_PACKAGE_SOURCE "${CPACK_OUTPUT_FILE_PREFIX}/${CPACK_SOURCE_PACKAGE_FILE_NAME}")
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.spec")
endif()

include(CPack)

add_custom_target(build-rpms)
add_custom_target(no-build-rpms)

add_custom_command(
  TARGET build-rpms
  POST_BUILD
  COMMAND "${CMAKE_COMMAND}"
    -DBUILD_RPMS=ON
    -B "${CMAKE_BINARY_DIR}"
    -S "${CMAKE_SOURCE_DIR}"
  VERBATIM
  USES_TERMINAL
)

add_custom_command(
  TARGET no-build-rpms
  POST_BUILD
  COMMAND "${CMAKE_COMMAND}"
    -DBUILD_RPMS=OFF
    -B "${CMAKE_BINARY_DIR}"
    -S "${CMAKE_SOURCE_DIR}"
  VERBATIM
  USES_TERMINAL
)

add_custom_target(srpm
  COMMAND "${CMAKE_COMMAND}"
    --build "${CMAKE_BINARY_DIR}"
    --target package_source
  DEPENDS build-rpms
  VERBATIM
  USES_TERMINAL
)

add_custom_target(rpms
  COMMAND rpmbuild
    --rebuild
    --define "_rpmdir ${CPACK_OUTPUT_FILE_PREFIX}"
    "${CPACK_OUTPUT_FILE_PREFIX}/${PROJECT_NAME}-${PROJECT_VERSION}-?.fc??.src.rpm"
  DEPENDS build-rpms srpm
  VERBATIM
  USES_TERMINAL
)

add_custom_command(
  TARGET rpms
  POST_BUILD
  COMMAND /bin/sh -c "find \
    \"${CPACK_OUTPUT_FILE_PREFIX}/\" \
    -mindepth 2 -type f -exec mv {} \"${CPACK_OUTPUT_FILE_PREFIX}/\" \; \
    && find \"${CPACK_OUTPUT_FILE_PREFIX}\" \
    -type d -empty -delete \
  "
  VERBATIM
  USES_TERMINAL
)

add_custom_target(sdist
  COMMAND "${CMAKE_COMMAND}"
    --build "${CMAKE_BINARY_DIR}"
    --target package_source
  DEPENDS no-build-rpms
  VERBATIM
  USES_TERMINAL
)

add_custom_target(bdist
  COMMAND "${CMAKE_COMMAND}"
    --build "${CMAKE_BINARY_DIR}"
    --target package
  DEPENDS no-build-rpms
  VERBATIM
  USES_TERMINAL
)

# vim: ts=2:sw=2:sts=2:et:syntax=cmake
