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.
This commit is contained in:
2021-10-23 17:24:45 +01:00
parent 5602475542
commit bcbd01778d

View File

@@ -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