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

PlugDiff to show pending updates as well

Related: #348
Junegunn Choi 10 лет назад
Родитель
Сommit
e6f40479ee
4 измененных файлов с 129 добавлено и 39 удалено
  1. 1 1
      README.md
  2. 52 25
      plug.vim
  3. 11 7
      test/run
  4. 65 6
      test/workflow.vader

+ 1 - 1
README.md

@@ -104,7 +104,7 @@ Reload .vimrc and `:PlugInstall` to install plugins.
 | `PlugClean[!]`                      | Remove unused directories (bang version will clean without prompt) |
 | `PlugUpgrade`                       | Upgrade vim-plug itself                                            |
 | `PlugStatus`                        | Check the status of plugins                                        |
-| `PlugDiff`                          | See the updated changes from the previous PlugUpdate               |
+| `PlugDiff`                          | Examine changes from the previous update and the pending changes   |
 | `PlugSnapshot[!] [output path]`     | Generate script for restoring the current snapshot of the plugins  |
 
 ### `Plug` options

+ 52 - 25
plug.vim

@@ -531,16 +531,20 @@ function! s:syntax()
   syn match plugStar /^*/
   syn match plugMessage /\(^- \)\@<=.*/
   syn match plugName /\(^- \)\@<=[^ ]*:/
+  syn match plugSha /\%(: \)\@<=[0-9a-z]\{4,}$/
+  syn match plugTag /(tag: [^)]\+)/
   syn match plugInstall /\(^+ \)\@<=[^:]*/
   syn match plugUpdate /\(^* \)\@<=[^:]*/
-  syn match plugCommit /^  [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha
+  syn match plugCommit /^  [0-9a-z]\{7} .*/ contains=plugRelDate,plugSha,plugTag
   syn match plugSha /\(^  \)\@<=[0-9a-z]\{7}/ contained
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugNotLoaded /(not loaded)$/
   syn match plugError /^x.*/
+  syn match plugH2 /^.*:\n-\+$/
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   hi def link plug1       Title
   hi def link plug2       Repeat
+  hi def link plugH2      Type
   hi def link plugX       Exception
   hi def link plugBracket Structure
   hi def link plugNumber  Number
@@ -557,6 +561,7 @@ function! s:syntax()
   hi def link plugError   Error
   hi def link plugRelDate Comment
   hi def link plugSha     Identifier
+  hi def link plugTag     Constant
 
   hi def link plugNotLoaded Comment
 endfunction
@@ -1993,41 +1998,63 @@ function! s:section(flags)
   call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
 endfunction
 
-function! s:diff()
-  call s:prepare()
-  call append(0, 'Collecting updated changes ...')
-  normal! gg
-  redraw
+function! s:format_git_log(line)
+  let [sha, refs, subject, date] = split(a:line, nr2char(1))
+  let tag = matchstr(refs, 'tag: [^,)]\+')
+  let tag = empty(tag) ? ' ' : ' ('.tag.') '
+  return printf('  %s%s%s (%s)', sha, tag, subject, date)
+endfunction
 
-  let cnt = 0
-  for [k, v] in filter(items(g:plugs), '!has_key(v:val[1], "commit")')
-    if !isdirectory(v.dir) || !s:is_managed(k)
-      continue
-    endif
+function! s:append_ul(lnum, text)
+  call append(a:lnum, ['', a:text, repeat('-', len(a:text))])
+endfunction
 
-    let diff = s:system_chomp('git log --left-only --pretty=format:"%h %s (%cr)" "HEAD...HEAD@{1}"', v.dir)
-    if !empty(diff)
-      call append(1, '')
-      call append(2, '- '.k.':')
-      call append(3, map(s:lines(diff), '"  ". v:val'))
-      let cnt += 1
-      normal! gg
+function! s:diff()
+  call s:prepare()
+  call append(0, ['Collecting changes ...', ''])
+  let cnts = [0, 0]
+  let bar = ''
+  let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)')
+  call s:progress_bar(2, bar, len(total))
+  for origin in [1, 0]
+    call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
+    for [k, v] in reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))'))))
+      let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..'
+      let diff = s:system_chomp('git log --pretty=format:"%h%x01%d%x01%s%x01%cr" '.s:shellesc(range), v.dir)
+      if !empty(diff)
+        let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
+        call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))
+        let cnts[origin] += 1
+      endif
+      let bar .= '='
+      call s:progress_bar(2, bar, len(total))
+      normal! 2G
       redraw
+    endfor
+    if !cnts[origin]
+      call append(5, ['', 'N/A'])
     endif
   endfor
+  call setline(1, printf('%d plugin(s) updated.', cnts[0])
+        \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : ''))
 
-  call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
-  nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
-  nnoremap <silent> <buffer> o    :silent! call <SID>preview_commit()<cr>
-  nnoremap <silent> <buffer> X    :call <SID>revert()<cr>
-  normal! gg
-  setlocal nomodifiable
-  if cnt > 0
+  if cnts[0] || cnts[1]
+    nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
+    nnoremap <silent> <buffer> o    :silent! call <SID>preview_commit()<cr>
+  endif
+  if cnts[0]
+    nnoremap <silent> <buffer> X :call <SID>revert()<cr>
     echo "Press 'X' on each block to revert the update"
   endif
+  normal! gg
+  setlocal nomodifiable
 endfunction
 
 function! s:revert()
+  if search('^Pending updates', 'bnW')
+    return
+  endif
+
   let name = s:find_name(line('.'))
   if empty(name) || !has_key(g:plugs, name) ||
     \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'

+ 11 - 7
test/run

@@ -18,7 +18,7 @@ clone() {
   fi
 }
 
-clone_repos() {
+clone_repos() (
   cd /tmp
   mkdir -p junegunn vim-scripts jg
   for repo in vader.vim goyo.vim rust.vim seoul256.vim vim-easy-align vim-fnr \
@@ -31,11 +31,9 @@ clone_repos() {
 
   clone junegunn/vim-emoji jg/vim-emoji
   cd junegunn/seoul256.vim && git checkout no-t_co && git checkout master
+)
 
-  cd "$BASE"
-}
-
-make_dirs() {
+make_dirs() (
   rm -rf "$PLUG_FIXTURES/$1"
   mkdir -p "$PLUG_FIXTURES/$1"
   cd "$PLUG_FIXTURES/$1"
@@ -51,9 +49,13 @@ make_dirs() {
     call add(g:total_order, s:name)
 EOF
   done
+)
 
-  cd "$BASE"
-}
+gitinit() (
+  cd "$PLUG_FIXTURES/$1"
+  git init
+  git commit -m 'commit' --allow-empty
+)
 
 prepare() {
   make_dirs xxx/ xxx
@@ -62,9 +64,11 @@ prepare() {
   cat > "$PLUG_FIXTURES/xxx/doc/xxx.txt" << DOC
 hello *xxx*
 DOC
+  gitinit xxx
 
   make_dirs yyy/ yyy
   make_dirs yyy/after yyy
+  gitinit yyy
 
   make_dirs z1/ z1
   make_dirs z2/ z2

+ 65 - 6
test/workflow.vader

@@ -262,12 +262,16 @@ Execute (PlugUpdate only to find out plugins are up-to-date, D key to check):
   PlugUpdate
   AssertExpect 'Already up-to-date', 2
   normal D
-  AssertEqual 'No updates.', getline(1)
+  AssertEqual '0 plugin(s) updated.', getline(1)
   q
 
 Execute (PlugDiff - 'No updates.'):
   PlugDiff
-  AssertEqual 'No updates.', getline(1)
+  Log getline(1, '$')
+  AssertEqual '0 plugin(s) updated.', getline(1)
+  Assert empty(mapcheck('o'))
+  Assert empty(mapcheck('X'))
+  Assert empty(mapcheck("\<cr>"))
   q
 
 Execute (New commits on remote, PlugUpdate, then PlugDiff):
@@ -281,7 +285,7 @@ Execute (New commits on remote, PlugUpdate, then PlugDiff):
 
   " Now we have updates
   normal D
-  AssertEqual 'Last update:', getline(1)
+  AssertEqual '2 plugin(s) updated.', getline(1)
 
   " Preview commit
   silent! wincmd P
@@ -367,7 +371,58 @@ Execute (contd. PlugDiff should not show inverted history):
   " PlugDiff should not report the changes i.e. git log --left-only
   PlugDiff
   Log getline(1, '$')
-  AssertEqual 'No updates.', getline(1)
+  AssertEqual '0 plugin(s) updated.', getline(1)
+  q
+
+**********************************************************************
+~ PlugDiff to see the pending changes
+**********************************************************************
+
+Execute (PlugDiff):
+  call plug#begin()
+  call plug#end()
+  PlugClean!
+
+  call plug#begin()
+  Plug 'file://'.expand('$PLUG_FIXTURES').'/xxx'
+  Plug 'file://'.expand('$PLUG_FIXTURES').'/yyy'
+  call plug#end()
+  PlugInstall
+  Log getline(1, '$')
+
+  call system('cd "$PLUG_FIXTURES/xxx" && git commit --allow-empty -m update-xxx && git tag -f xxx')
+  call system('cd "$PLUG_FIXTURES/yyy" && git tag -f yyy && git commit --allow-empty -m update-yyy && git tag -f zzz')
+
+  let g:plugs.yyy.tag = 'yyy'
+  PlugUpdate
+  Log getline(1, '$')
+
+  PlugDiff
+  " 1 plugin(s) updated. 1 plugin(s) have pending updates.
+  " [==]
+  "
+  " Last update:
+  " ------------
+  "
+  " - xxx:
+  "   166cfff (tag: xxx) update-xxx (1 second ago)
+  "
+  " Pending updates:
+  " ----------------
+  "
+  " - yyy: (tag: yyy)
+  "   c0a064b (tag: zzz) update-yyy (1 second ago)
+  "
+  Log getline(1, '$')
+  AssertEqual 15, line('$')
+  AssertEqual '1 plugin(s) updated. 1 plugin(s) have pending updates.', getline(1)
+  AssertEqual '[==]', getline(2)
+  AssertEqual '- yyy: (tag: yyy)', getline(13)
+  Assert getline(8) =~ '(tag: xxx)'
+  Assert getline(14) =~ '(tag: zzz)'
+  Assert !empty(mapcheck('o'))
+  Assert !empty(mapcheck('X'))
+  Assert !empty(mapcheck("\<cr>"))
   q
 
 **********************************************************************
@@ -1258,9 +1313,13 @@ Execute (Commit hash support):
   AssertEqual ['    PlugUpdate required.',
               \'- vim-emoji: OK'], getline(6, '$')
 
-  " Plugins with commit option should not appear in PlugDiff output
+  " PlugDiff should show pending updates for vim-emoji
   PlugDiff
-  AssertEqual 'No updates.', getline(1)
+  Log getline(1, '$')
+  AssertEqual '0 plugin(s) updated. 1 plugin(s) have pending updates.', getline(1)
+  Assert !empty(mapcheck('o'))
+  Assert empty(mapcheck('X'))
+  Assert !empty(mapcheck("\<cr>"))
 
   " Nor in PlugSnapshot output
   PlugSnapshot