diff --git a/README.md b/README.md index 59d0c9c..9700498 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,11 @@ takes a single argument. ```vim function! BuildYCM(info) - " info is a dictionary with two fields - " - name: name of the plugin - " - status: 'installed' or 'updated' - if a:info.status == 'installed' + " info is a dictionary with 3 fields + " - name: name of the plugin + " - status: 'installed', 'updated', or 'unchanged' + " - force: set on PlugInstall! or PlugUpdate! + if a:info.status == 'installed' || a:info.force !./install.sh endif endfunction @@ -145,7 +146,10 @@ endfunction Plug 'Valloric/YouCompleteMe', { 'do': function('BuildYCM') } ``` -Both forms of post-update hook are executed inside the directory of the plugin. +Both forms of post-update hook are executed inside the directory of the plugin +and only run when the repository has changed, but you can force it to run +unconditionally with the bang-versions of the commands: `PlugInstall!` and +`PlugUpdate!`. Make sure to escape BARs when you write `do` option inline as they are mistakenly recognized as command separator for Plug command. diff --git a/plug.vim b/plug.vim index 9952e8b..fb5084e 100644 --- a/plug.vim +++ b/plug.vim @@ -109,8 +109,8 @@ function! plug#begin(...) let g:plugs_order = [] command! -nargs=+ -bar Plug call s:add() - command! -nargs=* -complete=customlist,s:names PlugInstall call s:install() - command! -nargs=* -complete=customlist,s:names PlugUpdate call s:update() + command! -nargs=* -bang -complete=customlist,s:names PlugInstall call s:install(!empty(''), ) + command! -nargs=* -bang -complete=customlist,s:names PlugUpdate call s:update(!empty(''), ) command! -nargs=0 -bang PlugClean call s:clean('' == '!') command! -nargs=0 PlugUpgrade if s:upgrade() | call s:upgrade_specs() | execute 'source '. s:me | endif command! -nargs=0 PlugStatus call s:status() @@ -365,12 +365,12 @@ function! s:infer_properties(name, repo) endif endfunction -function! s:install(...) - call s:update_impl(0, a:000) +function! s:install(force, ...) + call s:update_impl(0, a:force, a:000) endfunction -function! s:update(...) - call s:update_impl(1, a:000) +function! s:update(force, ...) + call s:update_impl(1, a:force, a:000) endfunction function! s:helptags() @@ -470,15 +470,16 @@ function! s:assign_name() silent! execute 'f '.fnameescape(name) endfunction -function! s:do(pull, todo) +function! s:do(pull, force, todo) for [name, spec] in items(a:todo) if !isdirectory(spec.dir) continue endif execute 'cd '.s:esc(spec.dir) let installed = has_key(s:prev_update.new, name) - if installed || (a:pull && - \ !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"'))) + let updated = installed ? 0 : + \ (a:pull && !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"'))) + if a:force || installed || updated call append(3, '- Post-update hook for '. name .' ... ') let type = type(spec.do) if type == s:TYPE.string @@ -493,7 +494,8 @@ function! s:do(pull, todo) endtry elseif type == s:TYPE.funcref try - call spec.do({ 'name': name, 'status': (installed ? 'installed' : 'updated') }) + let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') + call spec.do({ 'name': name, 'status': status, 'force': a:force }) let result = 'Done!' catch let result = 'Error: ' . v:exception @@ -530,7 +532,7 @@ function! s:retry() if empty(s:prev_update.errors) return endif - call s:update_impl(s:prev_update.pull, + call s:update_impl(s:prev_update.pull, s:prev_update.force, \ extend(copy(s:prev_update.errors), [s:prev_update.threads])) endfunction @@ -542,7 +544,7 @@ function! s:names(...) return filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)') endfunction -function! s:update_impl(pull, args) abort +function! s:update_impl(pull, force, args) abort let st = reltime() let args = copy(a:args) let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ? @@ -568,7 +570,7 @@ function! s:update_impl(pull, args) abort if !isdirectory(g:plug_home) call mkdir(g:plug_home, 'p') endif - let s:prev_update = { 'errors': [], 'pull': a:pull, 'new': {}, 'threads': threads } + let s:prev_update = { 'errors': [], 'pull': a:pull, 'force': a:force, 'new': {}, 'threads': threads } if has('ruby') && threads > 1 try let imd = &imd @@ -598,7 +600,7 @@ function! s:update_impl(pull, args) abort else call s:update_serial(a:pull, todo) endif - call s:do(a:pull, filter(copy(todo), 'has_key(v:val, "do")')) + call s:do(a:pull, a:force, filter(copy(todo), 'has_key(v:val, "do")')) call s:finish(a:pull) call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(st)))[0] . ' sec.') endfunction diff --git a/test/workflow.vader b/test/workflow.vader index 2ffb743..8efddc3 100644 --- a/test/workflow.vader +++ b/test/workflow.vader @@ -621,6 +621,14 @@ Execute (When already installed): Assert !filereadable(g:plugs['vim-easy-align'].dir.'/installed2'), \ 'vim-easy-align/installed2 should not exist' Assert !filereadable(g:plugs['vim-pseudocl'].dir.'/installed2'), + \ 'vim-pseudocl/installed2 should not exist' + +Execute (PlugInstall!): + PlugInstall! + q + Assert filereadable(g:plugs['vim-easy-align'].dir.'/installed2'), + \ 'vim-easy-align/installed2 should exist' + Assert filereadable(g:plugs['vim-pseudocl'].dir.'/installed2'), \ 'vim-pseudocl/installed2 should exist' Execute (When already updated): @@ -634,11 +642,19 @@ Execute (When already updated): Assert !filereadable(g:plugs['vim-easy-align'].dir.'/updated2'), \ 'vim-easy-align/updated2 should not exist' Assert !filereadable(g:plugs['vim-pseudocl'].dir.'/updated2'), + \ 'vim-pseudocl/updated2 should not exist' + +Execute (PlugUpdate!): + PlugUpdate! + q + Assert filereadable(g:plugs['vim-easy-align'].dir.'/updated2'), + \ 'vim-easy-align/updated2 should exist' + Assert filereadable(g:plugs['vim-pseudocl'].dir.'/updated2'), \ 'vim-pseudocl/updated2 should exist' Execute (Using Funcref): function! PlugUpdated(info) - call system('touch '. a:info.name . a:info.status . len(a:info)) + call system('touch '. a:info.name . a:info.status . a:info.force . len(a:info)) endfunction call plug#begin() @@ -652,11 +668,26 @@ Execute (Using Funcref): PlugUpdate Log getline(1, '$') q - Assert filereadable(g:plugs['vim-easy-align'].dir.'/vim-easy-alignupdated2'), - \ 'vim-easy-align/vim-easy-alignupdated2 should exist' - Assert filereadable(g:plugs['vim-pseudocl'].dir.'/vim-pseudoclinstalled2'), - \ 'vim-pseudocl/vim-pseudoclinstalled2 should exist' + Assert filereadable(g:plugs['vim-easy-align'].dir.'/vim-easy-alignupdated03'), + \ 'vim-easy-align/vim-easy-alignupdated03 should exist' + Assert filereadable(g:plugs['vim-pseudocl'].dir.'/vim-pseudoclinstalled03'), + \ 'vim-pseudocl/vim-pseudoclinstalled03 should exist' + call system('rm -rf '.g:plugs['vim-pseudocl'].dir) + PlugInstall! + q + Assert filereadable(g:plugs['vim-easy-align'].dir.'/vim-easy-alignunchanged13'), + \ 'vim-easy-align/vim-easy-alignunchanged13 should exist' + Assert filereadable(g:plugs['vim-pseudocl'].dir.'/vim-pseudoclinstalled13'), + \ 'vim-pseudocl/vim-pseudoclinstalled13 should exist' + + call system('cd '.g:plugs['vim-easy-align'].dir.' && git reset --hard HEAD^') + PlugUpdate! + q + Assert filereadable(g:plugs['vim-easy-align'].dir.'/vim-easy-alignupdated13'), + \ 'vim-easy-align/vim-easy-alignupdated13 should exist' + Assert filereadable(g:plugs['vim-pseudocl'].dir.'/vim-pseudoclunchanged13'), + \ 'vim-pseudocl/vim-pseudoclunchanged13 should exist' ********************************************************************** ~ Overriding `dir`