Jelajahi Sumber

Merge pull request #366 from junegunn/diff-origin

PlugDiff to show pending updates as well
Junegunn Choi 10 tahun lalu
induk
melakukan
f695463daf
4 mengubah file dengan 129 tambahan dan 39 penghapusan
  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) |
 | `PlugClean[!]`                      | Remove unused directories (bang version will clean without prompt) |
 | `PlugUpgrade`                       | Upgrade vim-plug itself                                            |
 | `PlugUpgrade`                       | Upgrade vim-plug itself                                            |
 | `PlugStatus`                        | Check the status of plugins                                        |
 | `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  |
 | `PlugSnapshot[!] [output path]`     | Generate script for restoring the current snapshot of the plugins  |
 
 
 ### `Plug` options
 ### `Plug` options

+ 52 - 25
plug.vim

@@ -531,16 +531,20 @@ function! s:syntax()
   syn match plugStar /^*/
   syn match plugStar /^*/
   syn match plugMessage /\(^- \)\@<=.*/
   syn match plugMessage /\(^- \)\@<=.*/
   syn match plugName /\(^- \)\@<=[^ ]*:/
   syn match plugName /\(^- \)\@<=[^ ]*:/
+  syn match plugSha /\%(: \)\@<=[0-9a-z]\{4,}$/
+  syn match plugTag /(tag: [^)]\+)/
   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,plugTag
   syn match plugSha /\(^  \)\@<=[0-9a-z]\{7}/ contained
   syn match plugSha /\(^  \)\@<=[0-9a-z]\{7}/ contained
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugRelDate /([^)]*)$/ contained
   syn match plugNotLoaded /(not loaded)$/
   syn match plugNotLoaded /(not loaded)$/
   syn match plugError /^x.*/
   syn match plugError /^x.*/
+  syn match plugH2 /^.*:\n-\+$/
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
   hi def link plug1       Title
   hi def link plug1       Title
   hi def link plug2       Repeat
   hi def link plug2       Repeat
+  hi def link plugH2      Type
   hi def link plugX       Exception
   hi def link plugX       Exception
   hi def link plugBracket Structure
   hi def link plugBracket Structure
   hi def link plugNumber  Number
   hi def link plugNumber  Number
@@ -557,6 +561,7 @@ function! s:syntax()
   hi def link plugError   Error
   hi def link plugError   Error
   hi def link plugRelDate Comment
   hi def link plugRelDate Comment
   hi def link plugSha     Identifier
   hi def link plugSha     Identifier
+  hi def link plugTag     Constant
 
 
   hi def link plugNotLoaded Comment
   hi def link plugNotLoaded Comment
 endfunction
 endfunction
@@ -1993,41 +1998,63 @@ function! s:section(flags)
   call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
   call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
 endfunction
 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
       redraw
+    endfor
+    if !cnts[origin]
+      call append(5, ['', 'N/A'])
     endif
     endif
   endfor
   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"
     echo "Press 'X' on each block to revert the update"
   endif
   endif
+  normal! gg
+  setlocal nomodifiable
 endfunction
 endfunction
 
 
 function! s:revert()
 function! s:revert()
+  if search('^Pending updates', 'bnW')
+    return
+  endif
+
   let name = s:find_name(line('.'))
   let name = s:find_name(line('.'))
   if empty(name) || !has_key(g:plugs, name) ||
   if empty(name) || !has_key(g:plugs, name) ||
     \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'
     \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'

+ 11 - 7
test/run

@@ -18,7 +18,7 @@ clone() {
   fi
   fi
 }
 }
 
 
-clone_repos() {
+clone_repos() (
   cd /tmp
   cd /tmp
   mkdir -p junegunn vim-scripts jg
   mkdir -p junegunn vim-scripts jg
   for repo in vader.vim goyo.vim rust.vim seoul256.vim vim-easy-align vim-fnr \
   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
   clone junegunn/vim-emoji jg/vim-emoji
   cd junegunn/seoul256.vim && git checkout no-t_co && git checkout master
   cd junegunn/seoul256.vim && git checkout no-t_co && git checkout master
+)
 
 
-  cd "$BASE"
-}
-
-make_dirs() {
+make_dirs() (
   rm -rf "$PLUG_FIXTURES/$1"
   rm -rf "$PLUG_FIXTURES/$1"
   mkdir -p "$PLUG_FIXTURES/$1"
   mkdir -p "$PLUG_FIXTURES/$1"
   cd "$PLUG_FIXTURES/$1"
   cd "$PLUG_FIXTURES/$1"
@@ -51,9 +49,13 @@ make_dirs() {
     call add(g:total_order, s:name)
     call add(g:total_order, s:name)
 EOF
 EOF
   done
   done
+)
 
 
-  cd "$BASE"
-}
+gitinit() (
+  cd "$PLUG_FIXTURES/$1"
+  git init
+  git commit -m 'commit' --allow-empty
+)
 
 
 prepare() {
 prepare() {
   make_dirs xxx/ xxx
   make_dirs xxx/ xxx
@@ -62,9 +64,11 @@ prepare() {
   cat > "$PLUG_FIXTURES/xxx/doc/xxx.txt" << DOC
   cat > "$PLUG_FIXTURES/xxx/doc/xxx.txt" << DOC
 hello *xxx*
 hello *xxx*
 DOC
 DOC
+  gitinit xxx
 
 
   make_dirs yyy/ yyy
   make_dirs yyy/ yyy
   make_dirs yyy/after yyy
   make_dirs yyy/after yyy
+  gitinit yyy
 
 
   make_dirs z1/ z1
   make_dirs z1/ z1
   make_dirs z2/ z2
   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
   PlugUpdate
   AssertExpect 'Already up-to-date', 2
   AssertExpect 'Already up-to-date', 2
   normal D
   normal D
-  AssertEqual 'No updates.', getline(1)
+  AssertEqual '0 plugin(s) updated.', getline(1)
   q
   q
 
 
 Execute (PlugDiff - 'No updates.'):
 Execute (PlugDiff - 'No updates.'):
   PlugDiff
   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
   q
 
 
 Execute (New commits on remote, PlugUpdate, then PlugDiff):
 Execute (New commits on remote, PlugUpdate, then PlugDiff):
@@ -281,7 +285,7 @@ Execute (New commits on remote, PlugUpdate, then PlugDiff):
 
 
   " Now we have updates
   " Now we have updates
   normal D
   normal D
-  AssertEqual 'Last update:', getline(1)
+  AssertEqual '2 plugin(s) updated.', getline(1)
 
 
   " Preview commit
   " Preview commit
   silent! wincmd P
   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 should not report the changes i.e. git log --left-only
   PlugDiff
   PlugDiff
   Log getline(1, '$')
   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
   q
 
 
 **********************************************************************
 **********************************************************************
@@ -1258,9 +1313,13 @@ Execute (Commit hash support):
   AssertEqual ['    PlugUpdate required.',
   AssertEqual ['    PlugUpdate required.',
               \'- vim-emoji: OK'], getline(6, '$')
               \'- vim-emoji: OK'], getline(6, '$')
 
 
-  " Plugins with commit option should not appear in PlugDiff output
+  " PlugDiff should show pending updates for vim-emoji
   PlugDiff
   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
   " Nor in PlugSnapshot output
   PlugSnapshot
   PlugSnapshot