This commit is contained in:
Alexandre Carlton 2014-11-30 11:28:29 +00:00
commit 8927add53d
3 changed files with 134 additions and 40 deletions

View File

@ -81,6 +81,7 @@ Reload .vimrc and `:PlugInstall` to install plugins.
| `dir` | Custom directory for the plugin | | `dir` | Custom directory for the plugin |
| `do` | Post-update hook (string or funcref) | | `do` | Post-update hook (string or funcref) |
| `on` | On-demand loading: Commands or `<Plug>`-mappings | | `on` | On-demand loading: Commands or `<Plug>`-mappings |
| `needs` | Check for executables before installing/updating |
| `for` | On-demand loading: File types | | `for` | On-demand loading: File types |
| `frozen` | Do not update unless explicitly specified | | `frozen` | Do not update unless explicitly specified |

107
plug.vim
View File

@ -75,7 +75,7 @@ let s:mac_gui = has('gui_macvim') && has('gui_running')
let s:is_win = has('win32') || has('win64') let s:is_win = has('win32') || has('win64')
let s:nvim = exists('##JobActivity') && !s:is_win let s:nvim = exists('##JobActivity') && !s:is_win
let s:me = resolve(expand('<sfile>:p')) let s:me = resolve(expand('<sfile>:p'))
let s:base_spec = { 'branch': 'master', 'frozen': 0 } let s:base_spec = { 'branch': 'master', 'frozen': 0, 'needs': [] }
let s:TYPE = { let s:TYPE = {
\ 'string': type(''), \ 'string': type(''),
\ 'list': type([]), \ 'list': type([]),
@ -876,6 +876,10 @@ function! s:update_vim()
call s:tick() call s:tick()
endfunction endfunction
function! s:missing_executables(executables)
return filter(copy(s:to_a(a:executables)), '!executable(v:val)')
endfunction
function! s:tick() function! s:tick()
while 1 " Without TCO, Vim stack is bound to explode while 1 " Without TCO, Vim stack is bound to explode
if empty(s:update.todo) if empty(s:update.todo)
@ -894,25 +898,31 @@ while 1 " Without TCO, Vim stack is bound to explode
call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...') call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
redraw redraw
if !new let executables = s:missing_executables(spec.needs)
let [valid, msg] = s:git_valid(spec, 0) if !empty(executables)
if valid let msg = 'Please install '. join(executables, ', ') . '.'
if pull let s:jobs[name] = { 'running': 0, 'result': msg, 'error': 1 }
call s:spawn(name, else
\ printf('git checkout -q %s 2>&1 && git pull --progress --no-rebase origin %s 2>&1 && git submodule update --init --recursive 2>&1', if !new
\ s:shellesc(spec.branch), s:shellesc(spec.branch)), { 'dir': spec.dir }) let [valid, msg] = s:git_valid(spec, 0)
if valid
if pull
call s:spawn(name,
\ printf('git checkout -q %s 2>&1 && git pull --progress --no-rebase origin %s 2>&1 && git submodule update --init --recursive 2>&1',
\ s:shellesc(spec.branch), s:shellesc(spec.branch)), { 'dir': spec.dir })
else
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 }
endif
else else
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 } let s:jobs[name] = { 'running': 0, 'result': msg, 'error': 1 }
endif endif
else else
let s:jobs[name] = { 'running': 0, 'result': msg, 'error': 1 } call s:spawn(name,
\ printf('git clone --progress --recursive %s -b %s %s 2>&1',
\ s:shellesc(spec.uri),
\ s:shellesc(spec.branch),
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 })
endif endif
else
call s:spawn(name,
\ printf('git clone --progress --recursive %s -b %s %s 2>&1',
\ s:shellesc(spec.uri),
\ s:shellesc(spec.branch),
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 })
endif endif
if !s:jobs[name].running if !s:jobs[name].running
@ -961,6 +971,17 @@ function! s:update_ruby()
pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil } pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil }
end end
def which cmd
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
exts.each { |ext|
exe = File.join(path, "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe)
}
end
return nil
end
require 'thread' require 'thread'
require 'fileutils' require 'fileutils'
require 'timeout' require 'timeout'
@ -1088,39 +1109,45 @@ function! s:update_ruby()
threads << Thread.new { threads << Thread.new {
while pair = take1.call while pair = take1.call
name = pair.first name = pair.first
dir, uri, branch = pair.last.values_at *%w[dir uri branch] dir, uri, branch, needs = pair.last.values_at *%w[dir uri branch needs]
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 exists = File.directory? dir
needs = needs.kind_of?(Array) ? needs : [needs]
executables = needs.select{ |exe| !which exe }
ok, result = ok, result =
if exists if executables.empty?
dir = esc dir if exists
ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil dir = esc dir
current_uri = data.lines.to_a.last ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil
if !ret current_uri = data.lines.to_a.last
if data =~ /^Interrupted|^Timeout/ if !ret
[false, data] if data =~ /^Interrupted|^Timeout/
[false, data]
else
[false, [data.chomp, "PlugClean required."].join($/)]
end
elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '')
[false, ["Invalid URI: #{current_uri}",
"Expected: #{uri}",
"PlugClean required."].join($/)]
else else
[false, [data.chomp, "PlugClean required."].join($/)] if pull
log.call name, 'Updating ...', :update
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && (git pull --no-rebase origin #{branch} #{progress} 2>&1 && #{subm})", name, :update, nil
else
[true, skip]
end
end end
elsif current_uri.sub(/git::?@/, '') != uri.sub(/git::?@/, '')
[false, ["Invalid URI: #{current_uri}",
"Expected: #{uri}",
"PlugClean required."].join($/)]
else else
if pull d = esc dir.sub(%r{[\\/]+$}, '')
log.call name, 'Updating ...', :update log.call name, 'Installing ...', :install
bt.call "#{cd} #{dir} && git checkout -q #{branch} 2>&1 && (git pull --no-rebase origin #{branch} #{progress} 2>&1 && #{subm})", name, :update, nil bt.call "git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1", name, :install, proc {
else FileUtils.rm_rf dir
[true, skip] }
end
end end
else else
d = esc dir.sub(%r{[\\/]+$}, '') [false, "Please install " + executables.join(", ") + " first."]
log.call name, 'Installing ...', :install
bt.call "git clone #{progress} --recursive #{uri} -b #{branch} #{d} 2>&1", name, :install, proc {
FileUtils.rm_rf dir
}
end end
mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok
log.call name, result, ok log.call name, result, ok

View File

@ -613,6 +613,72 @@ Execute (Retry failed tasks):
AssertExpect! '[xxx]', 1 AssertExpect! '[xxx]', 1
q q
**********************************************************************
~ Build requirements check (`needs` option)
**********************************************************************
Execute (Cleanup):
call plug#begin()
call plug#end()
PlugClean!
q
Execute (Single uninstalled executable):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'needs': 'does-not-exist' }
call plug#end()
PlugInstall
AssertExpect 'Please install does-not-exist first.', 0
q
Assert !isdirectory(g:plugs['vim-easy-align'].dir),
\ 'vim-easy-align should not exist'
Execute (Multiple uninstalled executables):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'needs': ['does-not-exist', 'also-non-existent'] }
call plug#end()
PlugInstall
AssertExpect 'Please install does-not-exist, also-non-existent first.', 0
q
Assert !isdirectory(g:plugs['vim-easy-align'].dir),
\ 'vim-easy-align should not exist'
Execute (Multiple uninstalled/installed executables):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'needs': ['does-not-exist', 'sh'] }
call plug#end()
PlugInstall
AssertExpect 'Please install does-not-exist first.', 0
q
Assert !isdirectory(g:plugs['vim-easy-align'].dir),
\ 'vim-easy-align should not exist'
Execute (Single installed executable):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'needs': 'sh' }
call plug#end()
PlugInstall!
q
Assert isdirectory(g:plugs['vim-easy-align'].dir),
\ 'vim-easy-align should exist'
Execute (Cleanup):
call plug#begin()
call plug#end()
PlugClean!
q
Execute (Multiple installed executables):
call plug#begin()
Plug 'junegunn/vim-easy-align', { 'needs': ['sh', 'bash'] }
call plug#end()
PlugInstall!
q
Assert isdirectory(g:plugs['vim-easy-align'].dir),
\ 'vim-easy-align should exist'
********************************************************************** **********************************************************************
~ Post-update hook (`do` option) ~ Post-update hook (`do` option)
********************************************************************** **********************************************************************