2014-12-25 12:50:28 -07:00
#!/usr/bin/env bash
set -e
2015-07-22 08:00:17 -07:00
set -u
2016-08-14 05:19:46 -07:00
# Use privileged mode, which e.g. skips using CDPATH.
2016-08-11 05:09:50 -07:00
set -p
2022-05-28 09:49:58 -07:00
# https://www.shellcheck.net/wiki/SC2031
shopt -s lastpipe
2014-11-21 06:39:35 -07:00
2020-04-02 07:56:14 -07:00
# Ensure that the user has a bash that supports -A
2020-04-07 00:31:26 -07:00
if [ [ " ${ BASH_VERSINFO [0] } " -lt 4 ] ] ; then
2020-05-31 10:27:05 -07:00
>& 2 echo " error: script requires bash 4+ (you have ${ BASH_VERSION } ). "
2020-04-02 07:56:14 -07:00
exit 1
fi
2016-09-12 04:40:55 -07:00
readonly NVIM_SOURCE_DIR = " ${ NVIM_SOURCE_DIR :- $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) /.. " && pwd ) } "
readonly VIM_SOURCE_DIR_DEFAULT = " ${ NVIM_SOURCE_DIR } /.vim-src "
2015-03-05 19:49:03 -07:00
readonly VIM_SOURCE_DIR = " ${ VIM_SOURCE_DIR :- ${ VIM_SOURCE_DIR_DEFAULT } } "
2021-07-01 09:37:03 -07:00
BASENAME = " $( basename " ${ 0 } " ) "
readonly BASENAME
2016-02-08 16:05:49 -07:00
readonly BRANCH_PREFIX = "vim-"
2014-11-21 06:39:35 -07:00
2016-01-23 04:05:04 -07:00
CREATED_FILES = ( )
2015-01-07 12:52:10 -07:00
usage( ) {
2017-12-25 19:38:42 -07:00
echo "Port Vim patches to Neovim"
2023-12-12 14:48:48 -07:00
echo "https://neovim.io/doc/user/dev_vimpatch.html"
2015-03-05 19:49:03 -07:00
echo
2015-07-22 08:00:17 -07:00
echo " Usage: ${ BASENAME } [-h | -l | -p vim-revision | -r pr-number] "
2015-03-05 19:49:03 -07:00
echo
echo "Options:"
2015-07-22 08:00:17 -07:00
echo " -h Show this message and exit."
2019-07-29 22:45:59 -07:00
echo " -l [git-log opts] List missing Vim patches."
echo " -L [git-log opts] List missing Vim patches (for scripts)."
2020-01-26 06:50:25 -07:00
echo " -m {vim-revision} List previous (older) missing Vim patches."
2017-12-25 19:38:42 -07:00
echo " -M List all merged patch-numbers (at current v:version)."
echo " -p {vim-revision} Download and generate a Vim patch. vim-revision"
2022-10-21 03:56:09 -07:00
echo " can be a Vim version (8.1.xxx) or a Git hash."
2017-12-25 19:38:42 -07:00
echo " -P {vim-revision} Download, generate and apply a Vim patch."
echo " -g {vim-revision} Download a Vim patch."
2022-03-04 19:11:31 -07:00
echo " -s [pr args] Create a vim-patch pull request."
2017-12-25 19:38:42 -07:00
echo " -r {pr-number} Review a vim-patch pull request."
2019-06-08 05:02:30 -07:00
echo " -V Clone the Vim source code to \$VIM_SOURCE_DIR."
2015-03-05 19:49:03 -07:00
echo
2019-06-08 05:02:30 -07:00
echo " \$VIM_SOURCE_DIR controls where Vim sources are found"
2017-12-10 17:58:55 -07:00
echo " (default: ' ${ VIM_SOURCE_DIR_DEFAULT } ') "
2019-07-29 22:45:59 -07:00
echo
echo "Examples:"
echo
echo " - List missing patches for a given file (in the Vim source):"
echo " $0 -l -- src/edit.c "
2015-01-07 12:52:10 -07:00
}
2018-03-08 04:58:16 -07:00
msg_ok( ) {
2018-06-19 06:27:32 -07:00
printf '\e[32m✔\e[0m %s\n' " $@ "
2018-03-08 04:58:16 -07:00
}
msg_err( ) {
2019-06-09 07:13:06 -07:00
printf '\e[31m✘\e[0m %s\n' " $@ " >& 2
2018-03-08 04:58:16 -07:00
}
2015-07-22 08:00:17 -07:00
# Checks if a program is in the user's PATH, and is executable.
check_executable( ) {
2016-05-16 20:41:41 -07:00
test -x " $( command -v " ${ 1 } " ) "
}
require_executable( ) {
if ! check_executable " ${ 1 } " ; then
2015-07-22 08:00:17 -07:00
>& 2 echo " ${ BASENAME } : ' ${ 1 } ' not found in PATH or not executable. "
exit 1
fi
}
2016-01-23 04:05:04 -07:00
clean_files( ) {
if [ [ ${# CREATED_FILES [@] } -eq 0 ] ] ; then
return
fi
echo
echo "Created files:"
local file
2016-05-11 15:09:39 -07:00
for file in " ${ CREATED_FILES [@] } " ; do
2016-01-23 04:05:04 -07:00
echo " • ${ file } "
done
read -p "Delete these files (Y/n)? " -n 1 -r reply
echo
2016-12-21 19:17:01 -07:00
if [ [ " ${ reply } " = = n ] ] ; then
2016-01-23 04:05:04 -07:00
echo "You can use 'git clean' to remove these files when you're done."
2016-12-21 19:17:01 -07:00
else
rm -- " ${ CREATED_FILES [@] } "
2016-01-23 04:05:04 -07:00
fi
}
2015-01-07 12:52:10 -07:00
get_vim_sources( ) {
2016-05-16 20:41:41 -07:00
require_executable git
2015-07-22 08:00:17 -07:00
2015-01-07 12:52:10 -07:00
if [ [ ! -d ${ VIM_SOURCE_DIR } ] ] ; then
2018-03-08 04:58:16 -07:00
echo " Cloning Vim into: ${ VIM_SOURCE_DIR } "
2016-04-08 10:54:50 -07:00
git clone https://github.com/vim/vim.git " ${ VIM_SOURCE_DIR } "
2016-01-08 17:12:36 -07:00
cd " ${ VIM_SOURCE_DIR } "
2019-10-16 06:44:38 -07:00
elif [ [ " ${ 1 - } " = = update ] ] ; then
2018-08-20 08:41:00 -07:00
cd " ${ VIM_SOURCE_DIR } "
2018-08-20 23:37:49 -07:00
if ! [ -d ".git" ] \
&& ! [ " $( git rev-parse --show-toplevel) " = " ${ VIM_SOURCE_DIR } " ] ; then
2018-03-08 04:58:16 -07:00
msg_err " ${ VIM_SOURCE_DIR } does not appear to be a git repository. "
2015-08-18 21:21:11 -07:00
echo " Please remove it and try again."
exit 1
fi
2018-03-08 04:58:16 -07:00
echo " Updating Vim sources: ${ VIM_SOURCE_DIR } "
2019-06-08 05:02:30 -07:00
if git pull --ff; then
msg_ok "Updated Vim sources."
else
2018-03-08 04:58:16 -07:00
msg_err "Could not update Vim sources; ignoring error."
2019-06-08 05:02:30 -07:00
fi
2019-10-16 06:44:38 -07:00
else
cd " ${ VIM_SOURCE_DIR } "
2015-01-07 12:52:10 -07:00
fi
}
2015-07-22 08:00:17 -07:00
commit_message( ) {
2023-08-12 19:34:25 -07:00
if [ [ " ${ vim_message } " = = " vim-patch: ${ vim_version } : " * ] ] ; then
printf '%s\n\n%s\n\n%s' " ${ vim_message } " " ${ vim_commit_url } " " ${ vim_coauthors } "
2017-12-16 19:42:08 -07:00
else
2023-08-12 19:34:25 -07:00
printf 'vim-patch:%s\n\n%s\n\n%s\n\n%s' " $vim_version " " $vim_message " " $vim_commit_url " " $vim_coauthors "
2017-12-16 19:42:08 -07:00
fi
2015-07-22 08:00:17 -07:00
}
2016-04-21 18:56:20 -07:00
find_git_remote( ) {
2021-10-02 06:15:01 -07:00
local git_remote
if [ [ " ${ 1 - } " = = fork ] ] ; then
git_remote = $( git remote -v | awk '$2 !~ /github.com[:\/]neovim\/neovim/ && $3 == "(fetch)" {print $1; exit}' )
else
git_remote = $( git remote -v | awk '$2 ~ /github.com[:\/]neovim\/neovim/ && $3 == "(fetch)" {print $1; exit}' )
fi
2019-07-29 22:45:59 -07:00
if [ [ -z " $git_remote " ] ] ; then
git_remote = "origin"
fi
echo " $git_remote "
2016-04-21 18:56:20 -07:00
}
2019-07-29 22:45:59 -07:00
# Assign variables for a given Vim tag, patch version, or commit.
2019-10-16 06:44:38 -07:00
# Might exit in case it cannot be found, after updating Vim sources.
2015-07-22 08:00:17 -07:00
assign_commit_details( ) {
2019-07-29 22:45:59 -07:00
local vim_commit_ref
if [ [ ${ 1 } = ~ v?[ 0-9] \. [ 0-9] \. [ 0-9] { 3,4} ] ] ; then
2015-08-25 23:07:31 -07:00
# Interpret parameter as version number (tag).
2019-07-29 22:45:59 -07:00
if [ [ " ${ 1 : 0 : 1 } " = = v ] ] ; then
vim_version = " ${ 1 : 1 } "
vim_tag = " ${ 1 } "
else
vim_version = " ${ 1 } "
vim_tag = " v ${ 1 } "
fi
vim_commit_ref = " $vim_tag "
2017-12-16 19:42:08 -07:00
local munge_commit_line = true
2015-01-07 12:52:10 -07:00
else
# Interpret parameter as commit hash.
2017-03-21 03:28:13 -07:00
vim_version = " ${ 1 : 0 : 12 } "
2017-12-16 19:42:08 -07:00
vim_tag =
2019-07-29 22:45:59 -07:00
vim_commit_ref = " $vim_version "
2017-12-16 19:42:08 -07:00
local munge_commit_line = false
2015-01-07 12:52:10 -07:00
fi
2015-08-25 23:07:31 -07:00
2019-10-16 06:44:38 -07:00
local get_vim_commit_cmd = " git -C ${ VIM_SOURCE_DIR } log -1 --format=%H ${ vim_commit_ref } -- "
vim_commit = $( $get_vim_commit_cmd 2>& 1) || {
# Update Vim sources.
get_vim_sources update
vim_commit = $( $get_vim_commit_cmd 2>& 1) || {
>& 2 msg_err " Couldn't find Vim revision ' ${ vim_commit_ref } ': git error: ${ vim_commit } . "
exit 3
}
2019-07-29 22:45:59 -07:00
}
2015-08-25 23:07:31 -07:00
vim_commit_url = " https://github.com/vim/vim/commit/ ${ vim_commit } "
2019-07-29 22:45:59 -07:00
vim_message = " $( git -C " ${ VIM_SOURCE_DIR } " log -1 --pretty= 'format:%B' " ${ vim_commit } " \
2024-02-16 05:19:26 -07:00
| sed -Ee 's/(\W)(#[0-9]{1,})/\1vim\/vim\2/g' ) "
2023-08-12 20:27:31 -07:00
local vim_coauthor0
vim_coauthor0 = " $( git -C " ${ VIM_SOURCE_DIR } " log -1 --pretty= 'format:Co-authored-by: %an <%ae>' " ${ vim_commit } " ) "
2023-08-12 19:34:25 -07:00
# Extract co-authors from the commit message.
2023-08-12 20:27:31 -07:00
vim_coauthors = " $( echo " ${ vim_message } " | ( grep -E '^Co-authored-by: ' || true ) | (grep -Fxv " ${ vim_coauthor0 } " || true))"
vim_coauthors = " $( echo " ${ vim_coauthor0 } " ; echo " ${ vim_coauthors } " ) "
2023-08-12 19:34:25 -07:00
# Remove Co-authored-by and Signed-off-by lines from the commit message.
2023-08-15 17:50:11 -07:00
vim_message = " $( echo " ${ vim_message } " | grep -Ev '^(Co-authored|Signed-off)-by: ' ) "
2017-12-16 19:42:08 -07:00
if [ [ ${ munge_commit_line } = = "true" ] ] ; then
2015-07-22 08:00:17 -07:00
# Remove first line of commit message.
2023-08-15 17:50:11 -07:00
vim_message = " $( echo " ${ vim_message } " | sed -Ee '1s/^patch /vim-patch:/' ) "
2015-07-22 08:00:17 -07:00
fi
2016-01-23 13:45:21 -07:00
patch_file = " vim- ${ vim_version } .patch "
2015-07-22 08:00:17 -07:00
}
2016-10-19 06:43:04 -07:00
# Patch surgery
2016-09-12 04:40:55 -07:00
preprocess_patch( ) {
local file = " $1 "
2021-10-30 09:04:04 -07:00
local nvim = "nvim -u NONE -n -i NONE --headless"
2016-09-12 04:40:55 -07:00
2021-02-03 16:53:27 -07:00
# Remove Filelist, README
local na_files = 'Filelist\|README.*'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/\<\%(' " ${ na_files } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2021-02-03 16:53:27 -07:00
# Remove *.proto, Make*, INSTALL*, gui_*, beval.*, some if_*, gvim, libvterm, tee, VisVim, xpm, xxd
2023-01-03 03:07:43 -07:00
local na_src = 'auto\|configure.*\|GvimExt\|hardcopy.*\|libvterm\|proto\|tee\|VisVim\|xpm\|xxd\|Make.*\|INSTALL.*\|beval.*\|gui.*\|if_cscop\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@<!\%(' " ${ na_src } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2016-09-12 04:40:55 -07:00
2023-08-23 04:32:11 -07:00
# Remove runtime/print/
local na_rt = 'print\/.*'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/\<\%(' " ${ na_rt } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2022-10-16 23:52:40 -07:00
2018-11-04 14:59:39 -07:00
# Remove unwanted Vim doc files.
2023-01-03 03:07:43 -07:00
local na_doc = 'channel\.txt\|if_cscop\.txt\|netbeans\.txt\|os_\w\+\.txt\|print\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|vim9\.txt\|sponsor\.txt\|intro\.txt\|tags'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/doc/\<\%(' " ${ na_doc } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2016-09-12 04:40:55 -07:00
2017-03-21 03:28:13 -07:00
# Remove "Last change ..." changes in doc files.
2>/dev/null $nvim --cmd 'set dir=/tmp' +'%s/^@@.*\n.*For Vim version.*Last change.*\n.*For Vim version.*Last change.*//' +w +q " $file "
2021-02-03 16:53:27 -07:00
# Remove gui, option, setup, screen dumps, testdir/Make_*.mak files
2022-04-10 23:41:26 -07:00
local na_src_testdir = 'gen_opt_test\.vim\|gui_.*\|Make_amiga\.mak\|Make_dos\.mak\|Make_ming\.mak\|Make_vms\.mms\|dumps/.*\.dump\|setup_gui\.vim'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/testdir/\<\%(' " ${ na_src_testdir } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2016-09-12 04:40:55 -07:00
2021-02-03 16:53:27 -07:00
# Remove testdir/test_*.vim files
2023-11-13 01:40:34 -07:00
local na_src_testdir = 'balloon.*\|behave\.vim\|channel.*\|crypt\.vim\|cscope\.vim\|gui.*\|hardcopy\.vim\|job_fails\.vim\|json\.vim\|listener\.vim\|mzscheme\.vim\|netbeans.*\|paste\.vim\|popupwin.*\|python2\.vim\|pyx2\.vim\|restricted\.vim\|shortpathname\.vim\|sound\.vim\|tcl\.vim\|terminal.*\|xxd\.vim'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/testdir/\<test_\%(' " ${ na_src_testdir } " '\)\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2021-02-03 16:53:27 -07:00
2023-11-13 01:40:34 -07:00
# Remove N/A src/*.[ch] files: sound.c, version.c
local na_src_c = 'sound\|version'
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\<\%(' " ${ na_src_c } " '\)\.[ch]\>@exe "norm! d/\\v(^diff)|%$\r"' +w +q " $file "
2017-12-10 16:54:25 -07:00
2016-11-17 09:27:13 -07:00
# Remove some *.po files. #5622
2022-04-10 23:41:26 -07:00
local na_po = 'sjiscorr\.c\|ja\.sjis\.po\|ko\.po\|pl\.cp1250\.po\|pl\.po\|ru\.cp1251\.po\|uk\.cp1251\.po\|zh_CN\.cp936\.po\|zh_CN\.po\|zh_TW\.po'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/po/\<\%(' ${ na_po } '\)\>@exe "norm! d/\\v(^diff)|%$\r"+' +w +q " $file "
2017-11-07 12:25:34 -07:00
# Remove vimrc_example.vim
local na_vimrcexample = 'vimrc_example\.vim'
2023-09-07 16:51:53 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/\<\%(' ${ na_vimrcexample } '\)\>@exe "norm! d/\\v(^diff)|%$\r"+' +w +q " $file "
2016-11-17 09:27:13 -07:00
2023-03-06 20:13:04 -07:00
# Rename src/testdir/ paths to test/old/testdir/
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab])\/src\/testdir/\1\/test\/old\/testdir/g' \
2023-03-06 20:13:04 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2016-09-12 04:40:55 -07:00
# Rename src/ paths to src/nvim/
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src)/\1\/nvim/g' \
2018-10-13 12:05:07 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2018-10-13 09:41:44 -07:00
2020-11-01 11:18:29 -07:00
# Rename evalfunc.c to eval/funcs.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/evalfunc\.c/\1\/eval\/funcs.c/g' \
2020-11-01 11:18:29 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-07-22 06:14:17 -07:00
# Rename evalvars.c to eval/vars.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/evalvars\.c/\1\/eval\/vars.c/g' \
2022-07-22 06:14:17 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2020-11-01 11:22:52 -07:00
# Rename userfunc.c to eval/userfunc.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/userfunc\.c/\1\/eval\/userfunc.c/g' \
2020-11-01 11:22:52 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-11-29 01:47:29 -07:00
# Rename evalbuffer.c to eval/buffer.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/evalbuffer\.c/\1\/eval\/buffer.c/g' \
2022-11-29 01:47:29 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
# Rename evalwindow.c to eval/window.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/evalwindow\.c/\1\/eval\/window.c/g' \
2022-11-29 01:47:29 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-06-23 06:17:11 -07:00
# Rename map.c to mapping.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/map\.c/\1\/mapping.c/g' \
2022-06-23 06:17:11 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-08-11 21:58:52 -07:00
# Rename profiler.c to profile.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/profiler\.c/\1\/profile.c/g' \
2022-08-11 21:58:52 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-08-12 00:41:43 -07:00
# Rename scriptfile.c to runtime.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/scriptfile\.c/\1\/runtime.c/g' \
2022-08-12 00:41:43 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2020-11-01 11:18:29 -07:00
# Rename session.c to ex_session.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/session\.c/\1\/ex_session.c/g' \
2020-11-01 10:13:33 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-03-17 21:47:08 -07:00
# Rename highlight.c to highlight_group.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/highlight\.c/\1\/highlight_group.c/g' \
2023-08-12 20:27:31 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
# Rename locale.c to os/lang.c
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/locale\.c/\1\/os\/lang.c/g' \
2022-03-17 21:47:08 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-05-12 05:19:29 -07:00
# Rename keymap.h to keycodes.h
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/keymap\.h/\1\/keycodes.h/g' \
2022-05-12 05:19:29 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2023-09-29 23:41:34 -07:00
# Rename option.h to option_vars.h
LC_ALL = C sed -Ee 's/( [ab]\/src\/nvim)\/option\.h/\1\/option_vars.h/g' \
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2022-05-24 19:31:32 -07:00
# Rename terminal.txt to nvim_terminal_emulator.txt
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/runtime\/doc)\/terminal\.txt/\1\/nvim_terminal_emulator.txt/g' \
2022-05-24 19:31:32 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2018-10-13 09:41:44 -07:00
# Rename test_urls.vim to check_urls.vim
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab])\/runtime\/doc\/test(_urls\.vim)/\1\/scripts\/check\2/g' \
2018-10-13 09:41:44 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2018-10-13 12:02:57 -07:00
# Rename path to check_colors.vim
2023-08-15 17:50:11 -07:00
LC_ALL = C sed -Ee 's/( [ab]\/runtime)\/colors\/(tools\/check_colors\.vim)/\1\/\2/g' \
2018-10-13 12:02:57 -07:00
" $file " > " $file " .tmp && mv " $file " .tmp " $file "
2016-09-12 04:40:55 -07:00
}
2022-10-24 06:27:52 -07:00
uncrustify_patch( ) {
2022-10-29 17:05:50 -07:00
git diff --quiet || {
>& 2 echo 'Vim source working tree dirty, aborting.'
exit 1
}
2022-10-24 06:27:52 -07:00
2023-05-26 07:22:56 -07:00
local patch_path = " $NVIM_SOURCE_DIR " /build/vim_patch
2022-10-24 06:27:52 -07:00
rm -rf " $patch_path "
2022-10-29 17:05:50 -07:00
mkdir -p " $patch_path " /{ a,b}
2022-10-24 06:27:52 -07:00
2022-10-29 17:05:50 -07:00
local commit = " $1 "
for file in $( git diff-tree --name-only --no-commit-id -r --diff-filter= a " $commit " ) ; do
git --work-tree= " $patch_path " /a checkout --quiet " $commit " ~ -- " $file "
2022-10-24 06:27:52 -07:00
done
2022-10-29 17:05:50 -07:00
for file in $( git diff-tree --name-only --no-commit-id -r --diff-filter= d " $commit " ) ; do
git --work-tree= " $patch_path " /b checkout --quiet " $commit " -- " $file "
2022-10-24 06:27:52 -07:00
done
2022-10-29 17:05:50 -07:00
git reset --quiet --hard HEAD
2022-10-24 06:27:52 -07:00
# If the difference are drastic enough uncrustify may need to be used more
# than once. This is obviously a bug that needs to be fixed on uncrustify's
# end, but in the meantime this workaround is sufficient.
for _ in { 1..2} ; do
2023-05-26 07:22:56 -07:00
" $NVIM_SOURCE_DIR " /build/usr/bin/uncrustify -c " $NVIM_SOURCE_DIR " /src/uncrustify.cfg -q --replace --no-backup " $patch_path " /{ a,b} /src/*.[ ch]
2022-10-24 06:27:52 -07:00
done
2022-10-29 17:05:50 -07:00
( cd " $patch_path " && ( git --no-pager diff --no-index --no-prefix --patch --unified= 5 --color= never a/ b/ || true ) )
2022-10-24 06:27:52 -07:00
}
2017-12-16 13:38:53 -07:00
get_vimpatch( ) {
2015-07-22 08:00:17 -07:00
get_vim_sources
assign_commit_details " ${ 1 } "
2015-01-07 12:52:10 -07:00
2018-03-08 04:58:16 -07:00
msg_ok " Found Vim revision ' ${ vim_commit } '. "
2015-01-07 12:52:10 -07:00
2016-09-12 04:40:55 -07:00
local patch_content
2023-05-26 07:22:56 -07:00
if check_executable " $NVIM_SOURCE_DIR " /build/usr/bin/uncrustify; then
2022-10-24 06:27:52 -07:00
patch_content = " $( uncrustify_patch " ${ vim_commit } " ) "
else
patch_content = " $( git --no-pager show --unified= 5 --color= never -1 --pretty= medium " ${ vim_commit } " ) "
fi
2015-01-07 12:52:10 -07:00
2016-09-12 04:40:55 -07:00
cd " ${ NVIM_SOURCE_DIR } "
2016-12-12 18:48:55 -07:00
printf "Creating patch...\n"
echo " $patch_content " > " ${ NVIM_SOURCE_DIR } / ${ patch_file } "
printf "Pre-processing patch...\n"
preprocess_patch " ${ NVIM_SOURCE_DIR } / ${ patch_file } "
2018-08-20 08:41:00 -07:00
msg_ok " Saved patch to ' ${ NVIM_SOURCE_DIR } / ${ patch_file } '. "
2016-12-12 18:48:55 -07:00
}
stage_patch( ) {
2017-12-16 13:38:53 -07:00
get_vimpatch " $1 "
2017-11-06 16:29:19 -07:00
local try_apply = " ${ 2 :- } "
2016-12-12 18:48:55 -07:00
2021-10-02 06:15:01 -07:00
local nvim_remote
nvim_remote = " $( find_git_remote) "
2016-05-11 15:09:39 -07:00
local checked_out_branch
checked_out_branch = " $( git rev-parse --abbrev-ref HEAD) "
2016-04-21 18:56:20 -07:00
2016-02-08 16:05:49 -07:00
if [ [ " ${ checked_out_branch } " = = ${ BRANCH_PREFIX } * ] ] ; then
2018-03-08 04:58:16 -07:00
msg_ok " Current branch ' ${ checked_out_branch } ' seems to be a vim-patch "
2016-02-08 16:05:49 -07:00
echo " branch; not creating a new branch."
else
2021-10-02 06:15:01 -07:00
printf '\nFetching "%s/master".\n' " ${ nvim_remote } "
2022-01-03 04:07:57 -07:00
if output = " $( git fetch " $nvim_remote " master 2>& 1) " ; then
msg_ok " $output "
else
msg_err " $output "
exit 1
fi
2016-02-08 16:05:49 -07:00
2016-12-12 18:48:55 -07:00
local nvim_branch = " ${ BRANCH_PREFIX } ${ vim_version } "
2016-02-08 16:05:49 -07:00
echo
2021-10-02 06:15:01 -07:00
echo " Creating new branch ' ${ nvim_branch } ' based on ' ${ nvim_remote } /master'. "
2016-09-12 04:40:55 -07:00
cd " ${ NVIM_SOURCE_DIR } "
2022-01-03 04:07:57 -07:00
if output = " $( git checkout -b " $nvim_branch " " $nvim_remote /master " 2>& 1) " ; then
msg_ok " $output "
else
msg_err " $output "
exit 1
fi
2016-02-08 16:05:49 -07:00
fi
2016-09-13 03:18:07 -07:00
printf "\nCreating empty commit with correct commit message.\n"
2022-01-03 04:07:57 -07:00
if output = " $( commit_message | git commit --allow-empty --file 2>& 1 -) " ; then
msg_ok " $output "
else
msg_err " $output "
exit 1
fi
2015-01-07 12:52:10 -07:00
2019-06-08 05:42:17 -07:00
local ret = 0
2017-11-06 16:29:19 -07:00
if test -n " $try_apply " ; then
if ! check_executable patch; then
2018-03-08 04:58:16 -07:00
printf "\n"
msg_err "'patch' command not found\n"
2017-11-06 16:29:19 -07:00
else
printf "\nApplying patch...\n"
2019-06-08 06:06:16 -07:00
patch -p1 --fuzz= 1 --no-backup-if-mismatch < " ${ patch_file } " || ret = $?
2017-11-06 16:29:19 -07:00
fi
printf "\nInstructions:\n Proceed to port the patch.\n"
else
2018-06-19 06:27:32 -07:00
printf '\nInstructions:\n Proceed to port the patch.\n Try the "patch" command (or use "%s -P ..." next time):\n patch -p1 < %s\n' " ${ BASENAME } " " ${ patch_file } "
2017-11-06 16:29:19 -07:00
fi
2016-09-13 03:18:07 -07:00
2018-06-19 06:27:32 -07:00
printf '
Stage your changes ( "git add ..." ) , then use "git commit --amend" to commit.
2016-09-13 03:18:07 -07:00
2018-06-19 06:27:32 -07:00
To port more patches ( if any) related to %s,
run "%s" again.
2016-09-13 03:18:07 -07:00
* Do this only for _related_ patches ( otherwise it increases the
size of the pull request, making it harder to review)
2022-03-04 19:11:31 -07:00
When you are done , try "%s -s" to create the pull request,
or "%s -s --draft" to create a draft pull request.
2016-09-13 03:18:07 -07:00
See the wiki for more information:
2023-12-12 14:48:48 -07:00
* https://neovim.io/doc/user/dev_vimpatch.html
2022-05-28 09:49:58 -07:00
' " ${ vim_version } " " ${ BASENAME } " " ${ BASENAME } " " ${ BASENAME } "
2019-06-08 05:42:17 -07:00
return $ret
2015-01-07 12:52:10 -07:00
}
2021-08-03 10:52:48 -07:00
gh_pr( ) {
2022-03-04 19:11:31 -07:00
local pr_title
local pr_body
pr_title = " $1 "
pr_body = " $2 "
shift 2
gh pr create --title " ${ pr_title } " --body " ${ pr_body } " " $@ "
2016-05-16 20:53:56 -07:00
}
git_hub_pr( ) {
2021-08-03 10:52:48 -07:00
local pr_message
pr_message = " $( printf '%s\n\n%s\n' " $1 " " $2 " ) "
2022-03-04 19:11:31 -07:00
shift 2
git hub pull new -m " ${ pr_message } " " $@ "
2016-05-16 20:53:56 -07:00
}
2016-01-23 13:45:21 -07:00
submit_pr( ) {
2016-05-16 20:41:41 -07:00
require_executable git
2016-05-16 20:53:56 -07:00
local push_first
push_first = 1
local submit_fn
2021-08-03 10:52:48 -07:00
if check_executable gh; then
submit_fn = "gh_pr"
2016-05-16 20:53:56 -07:00
elif check_executable git-hub; then
push_first = 0
submit_fn = "git_hub_pr"
else
2021-08-03 10:52:48 -07:00
>& 2 echo " ${ BASENAME } : 'gh' or 'git-hub' not found in PATH or not executable. "
>& 2 echo " Get it here: https://cli.github.com/"
2016-05-16 20:53:56 -07:00
exit 1
fi
2016-01-23 13:45:21 -07:00
2016-09-12 04:40:55 -07:00
cd " ${ NVIM_SOURCE_DIR } "
2016-05-11 15:09:39 -07:00
local checked_out_branch
checked_out_branch = " $( git rev-parse --abbrev-ref HEAD) "
2016-02-08 16:05:49 -07:00
if [ [ " ${ checked_out_branch } " != ${ BRANCH_PREFIX } * ] ] ; then
2018-03-08 04:58:16 -07:00
msg_err " Current branch ' ${ checked_out_branch } ' doesn't seem to be a vim-patch branch. "
2016-01-23 13:45:21 -07:00
exit 1
fi
2021-10-02 06:15:01 -07:00
local nvim_remote
nvim_remote = " $( find_git_remote) "
2016-05-11 15:09:39 -07:00
local pr_body
2021-10-02 06:15:01 -07:00
pr_body = " $( git log --grep= vim-patch --reverse --format= '#### %s%n%n%b%n' " ${ nvim_remote } " /master..HEAD) "
2016-05-11 15:09:39 -07:00
local patches
2017-12-16 19:42:08 -07:00
# Extract just the "vim-patch:X.Y.ZZZZ" or "vim-patch:sha" portion of each log
2021-10-02 06:15:01 -07:00
patches = ( " $( git log --grep= vim-patch --reverse --format= '%s' " ${ nvim_remote } " /master..HEAD | sed 's/: .*//' ) " )
2020-09-04 05:46:46 -07:00
# shellcheck disable=SC2206
patches = ( ${ patches [@]//vim-patch : } ) # Remove 'vim-patch:' prefix for each item in array.
2016-05-11 15:09:39 -07:00
local pr_title = " ${ patches [*] } " # Create space-separated string from array.
2016-02-08 16:05:49 -07:00
pr_title = " ${ pr_title // /, } " # Replace spaces with commas.
2021-08-03 10:52:48 -07:00
pr_title = " $( printf 'vim-patch:%s' " ${ pr_title #, } " ) "
2016-01-23 13:45:21 -07:00
2016-05-16 20:53:56 -07:00
if [ [ $push_first -ne 0 ] ] ; then
2021-10-02 06:15:01 -07:00
local push_remote
push_remote = " $( git config --get branch." ${ checked_out_branch } " .pushRemote || true ) "
if [ [ -z " $push_remote " ] ] ; then
push_remote = " $( git config --get remote.pushDefault || true ) "
if [ [ -z " $push_remote " ] ] ; then
push_remote = " $( git config --get branch." ${ checked_out_branch } " .remote || true ) "
if [ [ -z " $push_remote " ] ] || [ [ " $push_remote " = = " $nvim_remote " ] ] ; then
push_remote = " $( find_git_remote fork) "
fi
fi
fi
echo " Pushing to ' ${ push_remote } / ${ checked_out_branch } '. "
2022-01-03 04:07:57 -07:00
if output = " $( git push " $push_remote " " $checked_out_branch " 2>& 1) " ; then
msg_ok " $output "
else
msg_err " $output "
exit 1
fi
2016-05-16 20:53:56 -07:00
echo
fi
2016-01-23 13:45:21 -07:00
echo "Creating pull request."
2022-03-04 19:11:31 -07:00
if output = " $( $submit_fn " $pr_title " " $pr_body " " $@ " 2>& 1) " ; then
2022-01-03 04:07:57 -07:00
msg_ok " $output "
else
msg_err " $output "
exit 1
fi
2016-01-23 13:45:21 -07:00
echo
echo "Cleaning up files."
2016-02-08 16:05:49 -07:00
local patch_file
2016-05-11 15:09:39 -07:00
for patch_file in " ${ patches [@] } " ; do
2016-02-08 16:05:49 -07:00
patch_file = " vim- ${ patch_file } .patch "
2016-09-12 04:40:55 -07:00
if [ [ ! -f " ${ NVIM_SOURCE_DIR } / ${ patch_file } " ] ] ; then
2016-02-08 16:05:49 -07:00
continue
fi
2016-09-12 04:40:55 -07:00
rm -- " ${ NVIM_SOURCE_DIR } / ${ patch_file } "
2018-03-08 04:58:16 -07:00
msg_ok " Removed ' ${ NVIM_SOURCE_DIR } / ${ patch_file } '. "
2016-02-08 16:05:49 -07:00
done
2016-01-23 13:45:21 -07:00
}
2017-12-16 13:38:53 -07:00
# Gets all Vim commits since the "start" commit.
list_vim_commits( ) { (
2022-10-21 03:56:09 -07:00
cd " ${ VIM_SOURCE_DIR } " && git log --reverse v8.1.0000..HEAD " $@ "
2017-12-16 13:38:53 -07:00
) }
2015-01-07 12:52:10 -07:00
2017-12-25 19:38:42 -07:00
# Prints all (sorted) "vim-patch:xxx" tokens found in the Nvim git log.
2017-12-16 13:38:53 -07:00
list_vimpatch_tokens( ) {
2019-04-11 15:26:52 -07:00
# Use sed…{7,7} to normalize (internal) Git hashes (for tokens caches).
git -C " ${ NVIM_SOURCE_DIR } " log -E --grep= 'vim-patch:[^ ,{]{7,}' \
| grep -oE 'vim-patch:[^ ,{:]{7,}' \
2017-12-16 13:38:53 -07:00
| sort \
2019-04-11 15:26:52 -07:00
| uniq \
2023-08-15 17:50:11 -07:00
| sed -nEe 's/^(vim-patch:([0-9]+\.[^ ]+|[0-9a-z]{7,7})).*/\1/p'
2017-12-16 13:38:53 -07:00
}
2017-12-25 19:38:42 -07:00
# Prints all patch-numbers (for the current v:version) for which there is
# a "vim-patch:xxx" token in the Nvim git log.
list_vimpatch_numbers( ) {
# Transform "vim-patch:X.Y.ZZZZ" to "ZZZZ".
2019-06-08 05:02:30 -07:00
list_vimpatch_tokens | while read -r vimpatch_token; do
2023-08-15 17:50:11 -07:00
echo " $vimpatch_token " | grep -F '8.1.' | sed -Ee 's/.*vim-patch:8\.1\.([0-9a-z]+).*/\1/'
2017-12-25 19:38:42 -07:00
done
}
2019-12-24 00:15:18 -07:00
declare -A tokens
declare -A vim_commit_tags
_set_tokens_and_tags( ) {
2019-12-25 05:02:23 -07:00
set +u # Avoid "unbound variable" with bash < 4.4 below.
2019-12-24 00:15:18 -07:00
if [ [ -n " ${ tokens [*] } " ] ] ; then
return
fi
2019-12-25 05:02:23 -07:00
set -u
2019-12-24 00:15:18 -07:00
# Find all "vim-patch:xxx" tokens in the Nvim git log.
for token in $( list_vimpatch_tokens) ; do
tokens[ $token ] = 1
done
# Create an associative array mapping Vim commits to tags.
eval " vim_commit_tags=(
2023-09-07 15:56:57 -07:00
$( git -C " ${ VIM_SOURCE_DIR } " show-ref --tags --dereference \
2023-09-07 16:28:46 -07:00
| sed -nEe 's/^([0-9a-f]+) refs\/tags\/(v[0-9.]+)(\^\{\})?$/["\1"]="\2"/p' )
2019-12-24 00:15:18 -07:00
) "
# Exit in case of errors from the above eval (empty vim_commit_tags).
if ! ( ( " ${# vim_commit_tags [@] } " ) ) ; then
msg_err "Could not get Vim commits/tags."
exit 1
fi
}
2017-12-16 13:38:53 -07:00
# Prints a newline-delimited list of Vim commits, for use by scripts.
2020-01-26 07:20:51 -07:00
# "$1": use extended format? (with subject)
2019-07-29 22:45:59 -07:00
# "$@" is passed to list_vim_commits, as extra arguments to git-log.
2017-12-16 13:38:53 -07:00
list_missing_vimpatches( ) {
2019-12-24 00:15:18 -07:00
local -a missing_vim_patches = ( )
_set_missing_vimpatches " $@ "
2019-12-27 22:11:38 -07:00
set +u # Avoid "unbound variable" with bash < 4.4 below.
2019-12-24 00:15:18 -07:00
for line in " ${ missing_vim_patches [@] } " ; do
printf '%s\n' " $line "
done
2019-12-27 22:11:38 -07:00
set -u
2019-12-24 00:15:18 -07:00
}
# Sets / appends to missing_vim_patches (useful to avoid a subshell when
# used multiple times to cache tokens/vim_commit_tags).
2020-01-26 07:20:51 -07:00
# "$1": use extended format? (with subject)
# "$@": extra arguments to git-log.
2019-12-24 00:15:18 -07:00
_set_missing_vimpatches( ) {
2019-04-11 15:26:52 -07:00
local token vim_commit vim_tag patch_number
2019-08-30 07:46:29 -07:00
declare -a git_log_args
2019-10-13 14:09:09 -07:00
local extended_format = $1 ; shift
if [ [ " $extended_format " = = 1 ] ] ; then
git_log_args = ( "--format=%H %s" )
else
git_log_args = ( "--format=%H" )
fi
2019-08-30 07:46:29 -07:00
# Massage arguments for git-log.
declare -A git_log_replacements = (
[ ^\( .*/\) ?src/nvim/\( .*\) ] = "\${BASH_REMATCH[1]}src/\${BASH_REMATCH[2]}"
2023-03-07 19:46:09 -07:00
[ ^\( .*/\) ?test/old/\( .*\) ] = "\${BASH_REMATCH[1]}src/\${BASH_REMATCH[2]}"
2019-08-30 07:46:29 -07:00
[ ^\( .*/\) ?\. vim-src/\( .*\) ] = "\${BASH_REMATCH[2]}"
)
2019-12-24 00:15:18 -07:00
local i j
2019-08-30 07:46:29 -07:00
for i in " $@ " ; do
for j in " ${ !git_log_replacements[@] } " ; do
if [ [ " $i " = ~ $j ] ] ; then
eval " git_log_args+=( ${ git_log_replacements [ $j ] } ) "
continue 2
fi
done
git_log_args += ( " $i " )
done
2017-12-16 13:38:53 -07:00
2019-12-24 00:15:18 -07:00
_set_tokens_and_tags
2019-06-08 05:18:35 -07:00
2017-12-16 13:38:53 -07:00
# Get missing Vim commits
2019-09-03 01:12:02 -07:00
set +u # Avoid "unbound variable" with bash < 4.4 below.
2019-10-13 14:09:09 -07:00
local vim_commit info
while IFS = ' ' read -r line; do
2017-12-16 13:38:53 -07:00
# Check for vim-patch:<commit_hash> (usually runtime updates).
2019-10-13 14:09:09 -07:00
token = " vim-patch: ${ line : 0 : 7 } "
2019-04-11 15:26:52 -07:00
if [ [ " ${ tokens [ $token ]- } " ] ] ; then
continue
2015-01-07 12:52:10 -07:00
fi
2019-10-13 14:09:09 -07:00
# Get commit hash, and optional info from line. This is used in
# extended mode, and when using e.g. '--format' manually.
vim_commit = ${ line %% * }
if [ [ " $vim_commit " = = " $line " ] ] ; then
info =
else
info = ${ line #* }
if [ [ -n $info ] ] ; then
2022-10-21 03:56:09 -07:00
# Remove any "patch 8.1.0902: " prefixes, and prefix with ": ".
2019-10-13 14:09:09 -07:00
info = " : ${ info #patch* : } "
fi
fi
2019-06-08 05:18:35 -07:00
vim_tag = " ${ vim_commit_tags [ $vim_commit ]- } "
if [ [ -n " $vim_tag " ] ] ; then
2019-04-11 15:26:52 -07:00
# Check for vim-patch:<tag> (not commit hash).
patch_number = " vim-patch: ${ vim_tag : 1 } " # "v7.4.0001" => "7.4.0001"
if [ [ " ${ tokens [ $patch_number ]- } " ] ] ; then
continue
fi
2019-12-24 00:15:18 -07:00
missing_vim_patches += ( " $vim_tag $info " )
2019-04-11 15:26:52 -07:00
else
2019-12-24 00:15:18 -07:00
missing_vim_patches += ( " $vim_commit $info " )
2017-12-10 16:49:44 -07:00
fi
2019-10-13 14:09:09 -07:00
done < <( list_vim_commits " ${ git_log_args [@] } " )
2019-09-03 01:12:02 -07:00
set -u
2017-12-10 16:49:44 -07:00
}
# Prints a human-formatted list of Vim commits, with instructional messages.
2019-08-30 07:46:29 -07:00
# Passes "$@" onto list_missing_vimpatches (args for git-log).
2017-12-16 13:38:53 -07:00
show_vimpatches( ) {
2019-10-16 06:44:38 -07:00
get_vim_sources update
printf "Vim patches missing from Neovim:\n"
2017-12-10 16:49:44 -07:00
2019-06-09 07:01:19 -07:00
local -A runtime_commits
2023-08-15 17:50:11 -07:00
for commit in $( git -C " ${ VIM_SOURCE_DIR } " log --format= "%H %D" -- runtime | sed -Ee 's/,\? tag: / /g' ) ; do
2019-06-09 07:01:19 -07:00
runtime_commits[ $commit ] = 1
done
2022-02-07 19:07:00 -07:00
list_missing_vimpatches 1 " $@ " | while read -r vim_commit; do
2019-06-09 07:01:19 -07:00
if [ [ " ${ runtime_commits [ $vim_commit ]- } " ] ] ; then
2018-06-19 06:27:32 -07:00
printf ' • %s (+runtime)\n' " ${ vim_commit } "
2017-12-10 16:49:44 -07:00
else
2018-06-19 06:27:32 -07:00
printf ' • %s\n' " ${ vim_commit } "
2015-01-07 12:52:10 -07:00
fi
2022-02-07 19:07:00 -07:00
done
2015-01-07 12:52:10 -07:00
2019-11-08 12:47:58 -07:00
cat << EOF
Instructions:
2019-10-16 06:44:38 -07:00
To port one of the above patches to Neovim, execute this script with the patch revision as argument and follow the instructions, e.g.
2022-10-21 03:56:09 -07:00
'${BASENAME} -p v8.1.1234' , or '${BASENAME} -P v8.1.1234'
2018-06-19 06:27:32 -07:00
NOTE: Please port the _oldest_ patch if you possibly can.
2019-11-08 12:47:58 -07:00
You can use '${BASENAME} -l path/to/file' to see what patches are missing for a file.
EOF
2015-01-07 12:52:10 -07:00
}
2019-12-24 00:15:18 -07:00
list_missing_previous_vimpatches_for_patch( ) {
local for_vim_patch = " ${ 1 } "
local vim_commit vim_tag
assign_commit_details " ${ for_vim_patch } "
local file
local -a missing_list
local -a fnames
while IFS = read -r line ; do
fnames += ( " $line " )
2021-05-11 18:47:43 -07:00
done < <( git -C " ${ VIM_SOURCE_DIR } " diff-tree --no-commit-id --name-only -r " ${ vim_commit } " -- . ':!src/version.c' )
2019-12-24 00:15:18 -07:00
local i = 0
local n = ${# fnames [@] }
printf '=== getting missing patches for %d files ===\n' " $n "
if [ [ -z " ${ vim_tag } " ] ] ; then
printf 'NOTE: "%s" is not a Vim tag - listing all oldest missing patches\n' " ${ for_vim_patch } " >& 2
fi
for fname in " ${ fnames [@] } " ; do
i = $(( i+1 ))
printf '[%.*d/%d] %s: ' " ${# n } " " $i " " $n " " $fname "
local -a missing_vim_patches = ( )
_set_missing_vimpatches 1 -- " ${ fname } "
2020-01-19 08:05:23 -07:00
set +u # Avoid "unbound variable" with bash < 4.4 below.
2021-05-11 18:28:54 -07:00
for missing_vim_commit_info in " ${ missing_vim_patches [@] } " ; do
if [ [ -z " ${ missing_vim_commit_info } " ] ] ; then
printf -- "-\r"
2019-12-24 00:15:18 -07:00
else
2021-05-11 18:28:54 -07:00
printf -- "-\r"
local missing_vim_commit = " ${ missing_vim_commit_info %% : * } "
if [ [ -z " ${ vim_tag } " ] ] || [ [ " ${ missing_vim_commit } " < " ${ vim_tag } " ] ] ; then
printf -- "%s\n" " $missing_vim_commit_info "
missing_list += ( " $missing_vim_commit_info " )
else
printf -- "-\r"
fi
2019-12-24 00:15:18 -07:00
fi
2021-05-11 18:28:54 -07:00
done
2020-01-19 08:05:23 -07:00
set -u
2019-12-24 00:15:18 -07:00
done
2020-01-11 13:09:54 -07:00
set +u # Avoid "unbound variable" with bash < 4.4 below.
2019-12-24 00:15:18 -07:00
if [ [ -z " ${ missing_list [*] } " ] ] ; then
msg_ok 'no missing previous Vim patches'
2020-01-26 07:07:41 -07:00
set -u
2019-12-24 00:15:18 -07:00
return 0
fi
2020-01-11 13:09:54 -07:00
set -u
2019-12-24 00:15:18 -07:00
local -a missing_unique
2020-10-15 18:52:44 -07:00
local stat
2019-12-24 00:15:18 -07:00
while IFS = read -r line; do
2020-01-26 07:21:33 -07:00
local commit = " ${ line %% : * } "
2020-10-15 18:52:44 -07:00
stat = " $( git -C " ${ VIM_SOURCE_DIR } " show --format= --shortstat " ${ commit } " ) "
2020-01-26 07:21:33 -07:00
missing_unique += ( " $( printf '%s\n %s' " $line " " $stat " ) " )
2019-12-24 00:15:18 -07:00
done < <( printf '%s\n' " ${ missing_list [@] } " | sort -u)
msg_err " $( printf '%d missing previous Vim patches:' ${# missing_unique [@] } ) "
printf ' - %s\n' " ${ missing_unique [@] } "
return 1
}
2016-01-23 04:05:04 -07:00
review_commit( ) {
2016-09-13 03:18:07 -07:00
local nvim_commit_url = " ${ 1 } "
local nvim_patch_url = " ${ nvim_commit_url } .patch "
2015-07-22 08:00:17 -07:00
local git_patch_prefix = 'Subject: \[PATCH\] '
2016-09-13 03:18:07 -07:00
local nvim_patch
nvim_patch = " $( curl -Ssf " ${ nvim_patch_url } " ) "
2016-05-11 15:09:39 -07:00
local vim_version
2023-08-15 17:50:11 -07:00
vim_version = " $( head -n 4 <<< " ${ nvim_patch } " | sed -nEe 's/' " ${ git_patch_prefix } " 'vim-patch:([a-z0-9.]*)(:.*){0,1}$/\1/p' ) "
2015-07-22 08:00:17 -07:00
2016-01-23 04:05:04 -07:00
echo
2015-07-22 08:00:17 -07:00
if [ [ -n " ${ vim_version } " ] ] ; then
2018-03-08 04:58:16 -07:00
msg_ok " Detected Vim patch ' ${ vim_version } '. "
2015-07-22 08:00:17 -07:00
else
2018-03-08 04:58:16 -07:00
msg_err "Could not detect the Vim patch number."
2016-02-08 16:05:49 -07:00
echo " This script assumes that the PR contains only commits"
echo " with 'vim-patch:XXX' in their title."
2016-12-15 07:09:52 -07:00
echo
2018-06-19 06:27:32 -07:00
printf -- '%s\n\n' " $( head -n 4 <<< " ${ nvim_patch } " ) "
2016-12-15 07:09:52 -07:00
local reply
read -p "Continue reviewing (y/N)? " -n 1 -r reply
2016-12-21 19:17:01 -07:00
if [ [ " ${ reply } " = = y ] ] ; then
2016-12-15 07:09:52 -07:00
echo
return
fi
2015-07-22 08:00:17 -07:00
exit 1
fi
assign_commit_details " ${ vim_version } "
2018-07-10 16:54:44 -07:00
echo
echo "Creating files."
echo " ${ nvim_patch } " > " ${ NVIM_SOURCE_DIR } /n ${ patch_file } "
msg_ok " Saved pull request diff to ' ${ NVIM_SOURCE_DIR } /n ${ patch_file } '. "
CREATED_FILES += ( " ${ NVIM_SOURCE_DIR } /n ${ patch_file } " )
2021-10-30 09:04:04 -07:00
local nvim = "nvim -u NONE -n -i NONE --headless"
2018-07-10 16:54:44 -07:00
2>/dev/null $nvim --cmd 'set dir=/tmp' +'1,/^$/g/^ /-1join' +w +q " ${ NVIM_SOURCE_DIR } /n ${ patch_file } "
2016-05-11 15:09:39 -07:00
local expected_commit_message
expected_commit_message = " $( commit_message) "
local message_length
message_length = " $( wc -l <<< " ${ expected_commit_message } " ) "
local commit_message
2018-07-10 16:54:44 -07:00
commit_message = " $( tail -n +4 " ${ NVIM_SOURCE_DIR } /n ${ patch_file } " | head -n " ${ message_length } " ) "
2022-01-03 04:07:57 -07:00
if [ [ " ${ commit_message # " $git_patch_prefix " } " = = " ${ expected_commit_message } " ] ] ; then
2018-03-08 04:58:16 -07:00
msg_ok "Found expected commit message."
2015-07-22 08:00:17 -07:00
else
2018-03-08 04:58:16 -07:00
msg_err "Wrong commit message."
2015-07-22 08:00:17 -07:00
echo " Expected:"
echo " ${ expected_commit_message } "
echo " Actual:"
2022-01-03 04:07:57 -07:00
echo " ${ commit_message # " $git_patch_prefix " } "
2015-07-22 08:00:17 -07:00
fi
2017-12-16 13:38:53 -07:00
get_vimpatch " ${ vim_version } "
2016-09-12 04:40:55 -07:00
CREATED_FILES += ( " ${ NVIM_SOURCE_DIR } / ${ patch_file } " )
2015-07-22 08:00:17 -07:00
echo
echo "Launching nvim."
2016-09-12 04:40:55 -07:00
nvim -c " cd ${ NVIM_SOURCE_DIR } " \
-O " ${ NVIM_SOURCE_DIR } / ${ patch_file } " " ${ NVIM_SOURCE_DIR } /n ${ patch_file } "
2016-01-23 04:05:04 -07:00
}
review_pr( ) {
2016-05-16 20:41:41 -07:00
require_executable curl
require_executable nvim
require_executable jq
2016-01-23 04:05:04 -07:00
get_vim_sources
local pr = " ${ 1 } "
echo
echo " Downloading data for pull request # ${ pr } . "
2020-03-31 19:40:33 -07:00
local -a pr_commit_urls
while IFS = read -r pr_commit_url; do
pr_commit_urls += ( " $pr_commit_url " )
done < <( curl -Ssf " https://api.github.com/repos/neovim/neovim/pulls/ ${ pr } /commits " \
| jq -r '.[].html_url' )
2016-01-23 04:05:04 -07:00
echo " Found ${# pr_commit_urls [@] } commit(s). "
local pr_commit_url
local reply
2016-05-11 15:09:39 -07:00
for pr_commit_url in " ${ pr_commit_urls [@] } " ; do
2016-01-23 13:45:21 -07:00
review_commit " ${ pr_commit_url } "
2016-01-23 04:05:04 -07:00
if [ [ " ${ pr_commit_url } " != " ${ pr_commit_urls [-1] } " ] ] ; then
read -p "Continue with next commit (Y/n)? " -n 1 -r reply
echo
2016-12-21 19:17:01 -07:00
if [ [ " ${ reply } " = = n ] ] ; then
2016-01-23 04:05:04 -07:00
break
fi
fi
done
clean_files
2015-07-22 08:00:17 -07:00
}
2019-12-24 00:15:18 -07:00
while getopts "hlLmMVp:P:g:r:s" opt; do
2015-07-22 08:00:17 -07:00
case ${ opt } in
h)
usage
exit 0
; ;
l)
2019-07-29 22:45:59 -07:00
shift # remove opt
show_vimpatches " $@ "
2017-12-10 16:49:44 -07:00
exit 0
; ;
L)
2019-07-29 22:45:59 -07:00
shift # remove opt
2019-10-13 14:09:09 -07:00
list_missing_vimpatches 0 " $@ "
2015-07-22 08:00:17 -07:00
exit 0
; ;
2017-12-25 19:38:42 -07:00
M)
list_vimpatch_numbers
exit 0
; ;
2019-12-24 00:15:18 -07:00
m)
shift # remove opt
list_missing_previous_vimpatches_for_patch " $@ "
exit 0
; ;
2015-07-22 08:00:17 -07:00
p)
2016-12-12 18:48:55 -07:00
stage_patch " ${ OPTARG } "
2019-06-08 05:42:17 -07:00
exit
2016-12-12 18:48:55 -07:00
; ;
2017-11-06 16:29:19 -07:00
P)
stage_patch " ${ OPTARG } " TRY_APPLY
exit 0
; ;
2016-12-12 18:48:55 -07:00
g)
2017-12-16 13:38:53 -07:00
get_vimpatch " ${ OPTARG } "
2015-07-22 08:00:17 -07:00
exit 0
; ;
r)
review_pr " ${ OPTARG } "
exit 0
; ;
2016-01-23 13:45:21 -07:00
s)
2022-03-04 19:11:31 -07:00
shift # remove opt
submit_pr " $@ "
2016-01-23 13:45:21 -07:00
exit 0
; ;
2017-12-10 17:58:55 -07:00
V)
2019-10-16 06:44:38 -07:00
get_vim_sources update
2017-12-10 17:58:55 -07:00
exit 0
; ;
2015-07-22 08:00:17 -07:00
*)
exit 1
; ;
esac
done
usage
# vim: et sw=2