Просмотр исходного кода

Post-update hook (`do` option)

Junegunn Choi 11 лет назад
Родитель
Сommit
f98c8456fa
3 измененных файлов с 152 добавлено и 17 удалено
  1. 1 0
      README.md
  2. 61 16
      plug.vim
  3. 90 1
      test/workflow.vader

+ 1 - 0
README.md

@@ -76,6 +76,7 @@ Reload .vimrc and `:PlugInstall` to install plugins.
 | -------------- | -------------------------------------------------------------------- |
 | -------------- | -------------------------------------------------------------------- |
 | `branch`/`tag` | Branch or tag of the repository to use                               |
 | `branch`/`tag` | Branch or tag of the repository to use                               |
 | `rtp`          | Subdirectory that contains Vim plugin                                |
 | `rtp`          | Subdirectory that contains Vim plugin                                |
+| `do`           | Post-update hook (string of funcref)                                 |
 | `on`           | On-demand loading: Commands or <Plug>-mappings                       |
 | `on`           | On-demand loading: Commands or <Plug>-mappings                       |
 | `for`          | On-demand loading: File types                                        |
 | `for`          | On-demand loading: File types                                        |
 | `frozen`       | Do not install/update plugin unless explicitly given as the argument |
 | `frozen`       | Do not install/update plugin unless explicitly given as the argument |

+ 61 - 16
plug.vim

@@ -9,14 +9,24 @@
 "
 "
 " Edit your .vimrc
 " Edit your .vimrc
 "
 "
-"   call plug#begin()
+"   call plug#begin('~/.vim/plugged')
 "
 "
+"   " Make sure you use single quotes
 "   Plug 'junegunn/seoul256.vim'
 "   Plug 'junegunn/seoul256.vim'
 "   Plug 'junegunn/vim-easy-align'
 "   Plug 'junegunn/vim-easy-align'
-"   Plug 'junegunn/goyo.vim', { 'on': 'Goyo' }
-"   " Plug 'user/repo1', 'branch_or_tag'
-"   " Plug 'user/repo2', { 'rtp': 'vim/plugin/dir', 'branch': 'branch_or_tag' }
-"   " ...
+"
+"   " On-demand loading
+"   Plug 'scrooloose/nerdtree', { 'on':  'NERDTreeToggle' }
+"   Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
+"
+"   " Using git URL
+"   Plug 'https://github.com/junegunn/vim-github-dashboard.git'
+"
+"   " Plugin options
+"   Plug 'nsf/gocode', { 'tag': 'go.weekly.2012-03-13', 'rtp': 'vim' }
+"
+"   " Locally-managed plugin
+"   Plug '~/.fzf'
 "
 "
 "   call plug#end()
 "   call plug#end()
 "
 "
@@ -354,7 +364,8 @@ function! s:syntax()
   syn match plugDash /^-/
   syn match plugDash /^-/
   syn match plugPlus /^+/
   syn match plugPlus /^+/
   syn match plugStar /^*/
   syn match plugStar /^*/
-  syn match plugName /\(^- \)\@<=[^:]*/
+  syn match plugMessage /\(^- \)\@<=.*/
+  syn match plugName /\(^- \)\@<=[^ ]*:/
   syn match plugInstall /\(^+ \)\@<=[^:]*/
   syn match plugInstall /\(^+ \)\@<=[^:]*/
   syn match plugUpdate /\(^* \)\@<=[^:]*/
   syn match plugUpdate /\(^* \)\@<=[^:]*/
   syn match plugCommit /^  [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
   syn match plugCommit /^  [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
@@ -372,6 +383,7 @@ function! s:syntax()
   hi def link plugPlus    Constant
   hi def link plugPlus    Constant
   hi def link plugStar    Boolean
   hi def link plugStar    Boolean
 
 
+  hi def link plugMessage Function
   hi def link plugName    Label
   hi def link plugName    Label
   hi def link plugInstall Function
   hi def link plugInstall Function
   hi def link plugUpdate  Type
   hi def link plugUpdate  Type
@@ -430,6 +442,32 @@ function! s:assign_name()
   silent! execute "f ".fnameescape(name)
   silent! execute "f ".fnameescape(name)
 endfunction
 endfunction
 
 
+function! s:do(pull, todo)
+  for [name, spec] in items(a:todo)
+    execute 'cd '.s:esc(spec.dir)
+    if has_key(s:prev_update.new, name) || (a:pull &&
+      \ !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"')))
+      call append(3, '- Post-update hook for '. name .' ... ')
+      let type = type(spec.do)
+      if type == 1 " String
+        call system(spec.do)
+        let result = v:shell_error ? ('Exit status: '.v:shell_error) : 'Done!'
+      elseif type == 2 " Funcref
+        try
+          call spec.do()
+          let result = 'Done!'
+        catch
+          let result = 'Error: ' . v:exception
+        endtry
+      else
+        let result = 'Error: Invalid type!'
+      endif
+      call setline(4, getline(4) . result)
+    endif
+    cd -
+  endfor
+endfunction
+
 function! s:finish(pull)
 function! s:finish(pull)
   call append(3, '- Finishing ... ')
   call append(3, '- Finishing ... ')
   redraw
   redraw
@@ -486,8 +524,11 @@ function! s:update_impl(pull, args) abort
   normal! 2G
   normal! 2G
   redraw
   redraw
 
 
+  if !isdirectory(g:plug_home)
+    call mkdir(g:plug_home, 'p')
+  endif
   let len = len(g:plugs)
   let len = len(g:plugs)
-  let s:prev_update = { 'errors': [], 'pull': a:pull, 'threads': threads }
+  let s:prev_update = { 'errors': [], 'pull': a:pull, 'new': {}, 'threads': threads }
   if has('ruby') && threads > 1
   if has('ruby') && threads > 1
     try
     try
       let imd = &imd
       let imd = &imd
@@ -517,6 +558,7 @@ function! s:update_impl(pull, args) abort
   else
   else
     call s:update_serial(a:pull, todo)
     call s:update_serial(a:pull, todo)
   endif
   endif
+  call s:do(a:pull, filter(copy(todo), 'has_key(v:val, "do")'))
   if len(g:plugs) > len
   if len(g:plugs) > len
     call plug#end()
     call plug#end()
   endif
   endif
@@ -562,20 +604,21 @@ function! s:update_serial(pull, todo)
         execute 'cd '.s:esc(spec.dir)
         execute 'cd '.s:esc(spec.dir)
         let [valid, msg] = s:git_valid(spec, 0, 0)
         let [valid, msg] = s:git_valid(spec, 0, 0)
         if valid
         if valid
-          let result = a:pull ?
+          if a:pull
+            let result =
             \ s:system(
             \ s:system(
             \ printf('git checkout -q %s 2>&1 && git pull origin %s 2>&1 && git submodule update --init --recursive 2>&1',
             \ printf('git checkout -q %s 2>&1 && git pull origin %s 2>&1 && git submodule update --init --recursive 2>&1',
-            \   s:shellesc(spec.branch), s:shellesc(spec.branch))) : 'Already installed'
-          let error = a:pull ? v:shell_error != 0 : 0
+            \   s:shellesc(spec.branch), s:shellesc(spec.branch)))
+            let [result, error] = [result, v:shell_error != 0]
+          else
+            let [result, error] = ['Already installed', 0]
+          endif
         else
         else
           let result = msg
           let result = msg
           let error = 1
           let error = 1
         endif
         endif
         cd -
         cd -
       else
       else
-        if !isdirectory(base)
-          call mkdir(base, 'p')
-        endif
         let result = s:system(
         let result = s:system(
               \ printf('git clone --recursive %s -b %s %s 2>&1 && cd %s && git submodule update --init --recursive 2>&1',
               \ printf('git clone --recursive %s -b %s %s 2>&1 && cd %s && git submodule update --init --recursive 2>&1',
               \ s:shellesc(spec.uri),
               \ s:shellesc(spec.uri),
@@ -583,6 +626,7 @@ function! s:update_serial(pull, todo)
               \ s:shellesc(substitute(spec.dir, '[\/]\+$', '', '')),
               \ s:shellesc(substitute(spec.dir, '[\/]\+$', '', '')),
               \ s:shellesc(spec.dir)))
               \ s:shellesc(spec.dir)))
         let error = v:shell_error != 0
         let error = v:shell_error != 0
+        if !error | let s:prev_update.new[name] = 1 | endif
       endif
       endif
       let bar .= error ? 'x' : '='
       let bar .= error ? 'x' : '='
       if error
       if error
@@ -773,8 +817,9 @@ function! s:update_parallel(pull, todo, threads)
             dir, uri, branch = pair.last.values_at *%w[dir uri branch]
             dir, uri, branch = pair.last.values_at *%w[dir uri branch]
             branch = esc branch
             branch = esc branch
             subm = "git submodule update --init --recursive 2>&1"
             subm = "git submodule update --init --recursive 2>&1"
+            exists = File.directory? dir
             ok, result =
             ok, result =
-              if File.directory? dir
+              if exists
                 dir = esc dir
                 dir = esc dir
                 ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil
                 ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil
                 current_uri = data.lines.to_a.last
                 current_uri = data.lines.to_a.last
@@ -797,11 +842,11 @@ function! s:update_parallel(pull, todo, threads)
                   end
                   end
                 end
                 end
               else
               else
-                FileUtils.mkdir_p(base)
                 d = esc dir.sub(%r{[\\/]+$}, '')
                 d = esc dir.sub(%r{[\\/]+$}, '')
                 log.call name, 'Installing ...', :install
                 log.call name, 'Installing ...', :install
                 bt.call "(git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1 && cd #{esc dir} && #{subm})", name, :install
                 bt.call "(git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1 && cd #{esc dir} && #{subm})", name, :install
               end
               end
+            mtx.synchronize { VIM::command("let s:prev_update.new['#{name}'] = 1") } if !exists && ok
             log.call name, result, ok
             log.call name, result, ok
           end
           end
         } if running
         } if running
@@ -1082,7 +1127,7 @@ function! s:diff()
     endif
     endif
 
 
     execute 'cd '.s:esc(v.dir)
     execute 'cd '.s:esc(v.dir)
-    let diff = system('git log --pretty=format:"%h %s (%cr)" "HEAD@{0}...HEAD@{1}"')
+    let diff = system('git log --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"')
     if !v:shell_error && !empty(diff)
     if !v:shell_error && !empty(diff)
       call append(1, '')
       call append(1, '')
       call append(2, '- '.k.':')
       call append(2, '- '.k.':')

+ 90 - 1
test/workflow.vader

@@ -396,7 +396,7 @@ Expect (Aligned code):
   a  = 1
   a  = 1
   aa = 2
   aa = 2
 
 
-Given (nothing):
+Given:
 Execute (Partial PlugUpdate):
 Execute (Partial PlugUpdate):
   PlugUpdate vim-redis
   PlugUpdate vim-redis
   q
   q
@@ -576,6 +576,94 @@ Execute (Retry failed tasks):
   AssertExpect! '[xxx]', 1
   AssertExpect! '[xxx]', 1
   q
   q
 
 
+**********************************************************************
+~ Post-update hook (`do` option)
+**********************************************************************
+
+Execute (Cleanup):
+  call plug#begin()
+  call plug#end()
+  PlugClean!
+
+Execute (On install):
+  call plug#begin()
+  Plug 'junegunn/vim-easy-align', { 'do': 'touch installed' }
+  Plug 'junegunn/vim-pseudocl'
+  call plug#end()
+
+  PlugInstall
+  q
+
+  Assert filereadable(g:plugs['vim-easy-align'].dir.'/installed'),
+    \ 'vim-easy-align/installed should exist'
+  Assert !filereadable(g:plugs['vim-pseudocl'].dir.'/installed'),
+    \ 'vim-pseudocl/installed should not exist'
+
+Execute (On update):
+  call plug#begin()
+  Plug 'junegunn/vim-easy-align', { 'do': 'touch updated' }
+  Plug 'junegunn/vim-pseudocl', { 'do': 'touch updated' }
+  call plug#end()
+
+  " Reset for updates
+  call system('cd '.g:plugs['vim-pseudocl'].dir.' && git reset --hard HEAD^')
+
+  PlugUpdate
+  Log getline(1, '$')
+  q
+
+  Assert !filereadable(g:plugs['vim-easy-align'].dir.'/updated'),
+    \ 'vim-easy-align/updated should not exist'
+  Assert filereadable(g:plugs['vim-pseudocl'].dir.'/updated'),
+    \ 'vim-pseudocl/updated should exist'
+
+Execute (When already installed):
+  call plug#begin()
+  Plug 'junegunn/vim-easy-align', { 'do': 'touch installed2' }
+  Plug 'junegunn/vim-pseudocl', { 'do': 'touch installed2' }
+  call plug#end()
+
+  PlugInstall
+  q
+  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 exist'
+
+Execute (When already updated):
+  call plug#begin()
+  Plug 'junegunn/vim-easy-align', { 'do': 'touch updated2' }
+  Plug 'junegunn/vim-pseudocl', { 'do': 'touch updated2' }
+  call plug#end()
+
+  PlugUpdate
+  q
+  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 exist'
+
+Execute (Using Funcref):
+  function! PlugUpdated()
+    call system('touch me')
+  endfunction
+
+  call plug#begin()
+  Plug 'junegunn/vim-easy-align', { 'do': function('PlugUpdated') }
+  Plug 'junegunn/vim-pseudocl',   { 'do': function('PlugUpdated') }
+  call plug#end()
+
+  call system('cd '.g:plugs['vim-easy-align'].dir.' && git reset --hard HEAD^')
+  call system('rm -rf '.g:plugs['vim-pseudocl'].dir)
+
+  PlugUpdate
+  Log getline(1, '$')
+  q
+  Assert filereadable(g:plugs['vim-easy-align'].dir.'/me'),
+    \ 'vim-easy-align/me should exist'
+  Assert filereadable(g:plugs['vim-pseudocl'].dir.'/me'),
+    \ 'vim-pseudocl/me should exist'
+
 Execute (Cleanup):
 Execute (Cleanup):
   call system('rm -rf '.temp_plugged)
   call system('rm -rf '.temp_plugged)
   call rename('fzf', 'fzf-staged')
   call rename('fzf', 'fzf-staged')
@@ -586,6 +674,7 @@ Execute (Cleanup):
   unlet temp_plugged vader plug basertp save_rtp repo lnum fzf
   unlet temp_plugged vader plug basertp save_rtp repo lnum fzf
   delf PlugStatusSorted
   delf PlugStatusSorted
   delf AssertExpect
   delf AssertExpect
+  delf PlugUpdated
   delc AssertExpect
   delc AssertExpect
 
 
   Restore
   Restore