From bcbd01778d416b99205c51f348a543489889f66d Mon Sep 17 00:00:00 2001 From: Jim Myhrberg Date: Sat, 23 Oct 2021 17:24:45 +0100 Subject: [PATCH] fix(patch): resolve emacs-29 symlink patches to their real URL Annoyingly, when downloading raw files from GitHub, symlinks do not return the content of the symlink target, but instead it simply returns the symlink target path (../emacs-28/fix-window-role.patch). Hence we have to check the patch file content, and if it contains only a single line of text, we assume it's a symlink, and resolve it relative to the original download URL. --- build-emacs-for-macos | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/build-emacs-for-macos b/build-emacs-for-macos index 1f4e9f9..d30a5d1 100755 --- a/build-emacs-for-macos +++ b/build-emacs-for-macos @@ -717,7 +717,14 @@ class Build info "Downloading patch: #{patch[:url]}" run_cmd('curl', '-L#', patch[:url], '-o', patch_file) - apply_patch({ file: patch_file }, target) + real_patch_url = detect_github_symlink_patch(patch[:url], patch_file) + if real_patch_url + FileUtils.rm(patch_file) + apply_patch({ url: real_patch_url }, target) + else + apply_patch({ file: patch_file }, target) + end + elsif patch[:replace] err 'Patch replace input error' unless patch[:replace].size == 3 @@ -735,6 +742,30 @@ class Build f.close end end + + # When downloading raw files from GitHub, if the target file is a symlink, it + # will return the actual target path of the symlink instead of the content of + # the target file. Hence we have to check if the patch file we have downloaded + # contains one and only one line, and if so, assume it's a symlink. + def detect_github_symlink_patch(original_url, patch_file) + lines = [] + + # read first two lines + File.open(patch_file) do |f| + lines << f.gets + lines << f.gets + end + + # if the file contains more than one line of text, it's not a symlink. + return unless lines[1].nil? + + symlink_target = lines[0].strip + # Assume patch file content is something along the lines of + # "../emacs-28/fix-window-role.patch", hence we resolve it relative to the + # original url. + info "patch is symlink to #{symlink_target}" + URI.join(original_url, symlink_target).to_s + end end class AbstractEmbedder