aboutsummaryrefslogtreecommitdiff
path: root/tools/cpm/cmake/package/patch.cmake
diff options
context:
space:
mode:
authorcrueter <crueter@eden-emu.dev>2026-07-06 23:11:39 +0200
committercrueter <crueter@eden-emu.dev>2026-07-06 23:11:39 +0200
commit66b073ab8d427d8fc06ffd715151f372cdde818c (patch)
tree667e34c22f542d809a069738bd762a23786814c7 /tools/cpm/cmake/package/patch.cmake
parent4c65780f11511b20c2e0288a287faace16516d38 (diff)
[cmake] CPMUtil rewrite of the day number 852 (#4130)
Composite PR for several changes to CPMUtil, most notably: - https://git.crueter.xyz/CMake/CPMUtil/pulls/19 - https://git.crueter.xyz/CMake/CPMUtil/pulls/22 - https://git.crueter.xyz/CMake/CPMUtil/pulls/24 - https://git.crueter.xyz/CMake/CPMUtil/pulls/25 These contain a lot of changes that generally simplify control flow and improve ease-of-use. Read those descriptions and patchsets for more info. Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4130 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'tools/cpm/cmake/package/patch.cmake')
-rw-r--r--tools/cpm/cmake/package/patch.cmake155
1 files changed, 155 insertions, 0 deletions
diff --git a/tools/cpm/cmake/package/patch.cmake b/tools/cpm/cmake/package/patch.cmake
new file mode 100644
index 0000000000..3844921827
--- /dev/null
+++ b/tools/cpm/cmake/package/patch.cmake
@@ -0,0 +1,155 @@
+#!/usr/bin/env -S cmake -P
+
+# SPDX-FileCopyrightText: Copyright 2026 crueter
+# SPDX-License-Identifier: LGPL-3.0-or-later
+
+cmake_minimum_required(VERSION 3.31)
+
+include(${CMAKE_CURRENT_LIST_DIR}/../ScriptUtils.cmake)
+
+function(usage)
+ echo([=[
+Usage: cpmutil.sh package patch [PACKAGE]
+
+Create an in-tree patch for the specified package.
+]=])
+endfunction()
+
+set(NO_ALL TRUE)
+
+# arg parsing
+parse_script_args(args)
+
+list(LENGTH args arg_len)
+if(arg_len GREATER 0)
+ list(GET args 0 KEY)
+endif()
+
+if (NOT KEY)
+ fatal("You must provide a key")
+endif()
+
+if (NOT DEFINED DESCRIPTION)
+ fatal("No description provided")
+endif()
+
+parse_key(${KEY})
+get_cache_path(${package} ${version} local_cache)
+
+if (NOT EXISTS ${local_cache})
+ fatal("${package} is not fetched locally")
+endif()
+
+# get last patch number + 1
+list(LENGTH patches patches_len)
+math(EXPR last_index "${patches_len} - 1")
+list(GET patches ${last_index} patch)
+string(REGEX MATCH "[0-9][0-9][0-9][0-9]" number "${patch}")
+math(EXPR new_patchnum "${number} + 1")
+
+# now pad it for filename usage
+set(padded "0000${new_patchnum}")
+string(LENGTH ${padded} total_len)
+math(EXPR start_index "${total_len} - 4")
+string(SUBSTRING ${padded} ${start_index} 4 padded_patch_number)
+
+# this requires Git
+find_package(Git REQUIRED)
+
+# fetch temporary package
+mktempdir(TMP)
+
+set(CACHE_PATH_OVERRIDE ${TMP}/local)
+fetch_package_object()
+
+# make patch dir
+set(patch_dir "${CPMUTIL_PATCH_DIR}/${KEY}")
+file(MAKE_DIRECTORY "${patch_dir}")
+
+# git stuff
+macro(git_cmd out out_status)
+ echo("${GIT_EXECUTABLE} ${ARGN}")
+ # TODO: error handling
+ execute_process(COMMAND ${GIT_EXECUTABLE} ${ARGN}
+ WORKING_DIRECTORY ${CACHE_PATH_OVERRIDE}
+ OUTPUT_VARIABLE ${out}
+ RESULT_VARIABLE ${out_status})
+endmacro()
+
+# initialize
+git_cmd(_ _ init)
+git_cmd(_ _ add -A)
+git_cmd(_ _ commit -m init)
+git_cmd(_ _ "--work-tree=${local_cache}" add -A)
+
+# check for diffs
+git_cmd(_ diff_status diff --cached --quiet)
+git_cmd(out _ diff)
+
+if (diff_status EQUAL 0)
+ echo(${out})
+ echo_error("No differences found between local copy and source")
+ file(REMOVE_RECURSE ${TMP})
+ cmake_language(EXIT 1)
+endif()
+
+# prompt for patch description
+git_cmd(_ commit_status commit -m "${DESCRIPTION}")
+
+# format patch
+git_cmd(patch_content _ format-patch -1 HEAD --stdout)
+
+# now get patch name...
+
+# strip out existing numeric prefix
+string(REGEX REPLACE "^[0-9][0-9][0-9][0-9]-" "" name_part "${DESCRIPTION}")
+# spaces to dashes
+string(REPLACE " " "-" name_part "${name_part}")
+# strip out non-alphanumeric or dash characters
+string(REGEX REPLACE "[^a-zA-Z0-9-]" "" name_part "${name_part}")
+# collapse consecutive dashes
+string(REGEX REPLACE "-+" "-" name_part "${name_part}")
+# strip leading/trailing dashes
+string(REGEX REPLACE "^-|-$" "" name_part "${name_part}")
+
+if (NOT name_part)
+ set(name_part "patch")
+ echo_error("Warning: could not determine patch name")
+endif()
+
+# Truncate to 49 chars (60 - num prefix - `.patch` suffix)
+string(SUBSTRING "${name_part}" 0 49 name_part)
+
+# And remove any trailing dashes
+string(REGEX REPLACE "-$" "" name_part "${name_part}")
+
+# now construct and save patch
+set(patch_name "${padded_patch_number}-${name_part}.patch")
+
+file(WRITE "${patch_dir}/${patch_name}" "${patch_content}")
+
+echo("-- Patch created at ${patch_dir}/${patch_name}")
+file(REMOVE_RECURSE ${TMP})
+
+# Now add to cpmfile.
+get_cpmfile_content(content)
+
+# Build new patches JSON array
+set(new_patches "[")
+if(patches)
+ string(JSON existing GET "${content}" "${KEY}" "patches")
+ string(JSON len LENGTH "${existing}")
+ math(EXPR range_end "${len} - 1")
+ foreach(idx RANGE ${range_end})
+ string(JSON val GET "${existing}" ${idx})
+ string(APPEND new_patches "\"${val}\",")
+ endforeach()
+endif()
+string(APPEND new_patches "\"${patch_name}\"]")
+
+# Update the cpmfile
+string(JSON content SET "${content}" "${KEY}" patches "${new_patches}")
+get_cpmfile_path(file_path)
+file(WRITE "${file_path}" "${content}")
+format_cpmfile()
+