Updating plug.vim
This commit is contained in:
parent
d1efb55ea9
commit
9baa5e7e8c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
.vim/plugged
|
.vim/plugged
|
||||||
.vim/.netrwhist
|
.vim/.netrwhist
|
||||||
|
.vim/autoload/plug.vim.old
|
||||||
|
@ -73,6 +73,7 @@ let s:plug_tab = get(s:, 'plug_tab', -1)
|
|||||||
let s:plug_buf = get(s:, 'plug_buf', -1)
|
let s:plug_buf = get(s:, 'plug_buf', -1)
|
||||||
let s:mac_gui = has('gui_macvim') && has('gui_running')
|
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:py2 = has('python') && !s:is_win
|
||||||
let s:ruby = has('ruby') && (v:version >= 703 || v:version == 702 && has('patch374'))
|
let s:ruby = has('ruby') && (v:version >= 703 || v:version == 702 && has('patch374'))
|
||||||
let s:nvim = has('nvim') && !s:is_win
|
let s:nvim = has('nvim') && !s:is_win
|
||||||
let s:me = resolve(expand('<sfile>:p'))
|
let s:me = resolve(expand('<sfile>:p'))
|
||||||
@ -235,18 +236,22 @@ function! s:trim(str)
|
|||||||
return substitute(a:str, '[\/]\+$', '', '')
|
return substitute(a:str, '[\/]\+$', '', '')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:git_version_requirement(...)
|
function! s:version_requirement(val, min)
|
||||||
let s:git_version = get(s:, 'git_version',
|
for idx in range(0, len(a:min) - 1)
|
||||||
\ map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)'))
|
let v = get(a:val, idx, 0)
|
||||||
for idx in range(0, a:0 - 1)
|
if v < a:min[idx] | return 0
|
||||||
let v = get(s:git_version, idx, 0)
|
elseif v > a:min[idx] | return 1
|
||||||
if v < a:000[idx] | return 0
|
|
||||||
elseif v > a:000[idx] | return 1
|
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
return 1
|
return 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:git_version_requirement(...)
|
||||||
|
let s:git_version = get(s:, 'git_version',
|
||||||
|
\ map(split(split(s:system('git --version'))[-1], '\.'), 'str2nr(v:val)'))
|
||||||
|
return s:version_requirement(s:git_version, a:000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:progress_opt(base)
|
function! s:progress_opt(base)
|
||||||
return a:base && !s:is_win &&
|
return a:base && !s:is_win &&
|
||||||
\ s:git_version_requirement(1, 7, 1) ? '--progress' : ''
|
\ s:git_version_requirement(1, 7, 1) ? '--progress' : ''
|
||||||
@ -422,8 +427,10 @@ function! s:add(repo, ...)
|
|||||||
let name = fnamemodify(repo, ':t:s?\.git$??')
|
let name = fnamemodify(repo, ':t:s?\.git$??')
|
||||||
let spec = extend(s:infer_properties(name, repo),
|
let spec = extend(s:infer_properties(name, repo),
|
||||||
\ a:0 == 1 ? s:parse_options(a:1) : s:base_spec)
|
\ a:0 == 1 ? s:parse_options(a:1) : s:base_spec)
|
||||||
|
if !has_key(g:plugs, name)
|
||||||
|
call add(g:plugs_order, name)
|
||||||
|
endif
|
||||||
let g:plugs[name] = spec
|
let g:plugs[name] = spec
|
||||||
let g:plugs_order += [name]
|
|
||||||
let s:loaded[name] = 0
|
let s:loaded[name] = 0
|
||||||
catch
|
catch
|
||||||
return s:err(v:exception)
|
return s:err(v:exception)
|
||||||
@ -434,12 +441,9 @@ function! s:parse_options(arg)
|
|||||||
let opts = copy(s:base_spec)
|
let opts = copy(s:base_spec)
|
||||||
let type = type(a:arg)
|
let type = type(a:arg)
|
||||||
if type == s:TYPE.string
|
if type == s:TYPE.string
|
||||||
let opts.branch = a:arg
|
let opts.tag = a:arg
|
||||||
elseif type == s:TYPE.dict
|
elseif type == s:TYPE.dict
|
||||||
call extend(opts, a:arg)
|
call extend(opts, a:arg)
|
||||||
if has_key(opts, 'tag')
|
|
||||||
let opts.branch = remove(opts, 'tag')
|
|
||||||
endif
|
|
||||||
if has_key(opts, 'dir')
|
if has_key(opts, 'dir')
|
||||||
let opts.dir = s:dirpath(expand(opts.dir))
|
let opts.dir = s:dirpath(expand(opts.dir))
|
||||||
endif
|
endif
|
||||||
@ -606,6 +610,7 @@ function! s:prepare()
|
|||||||
endif
|
endif
|
||||||
silent! unmap <buffer> <cr>
|
silent! unmap <buffer> <cr>
|
||||||
silent! unmap <buffer> L
|
silent! unmap <buffer> L
|
||||||
|
silent! unmap <buffer> o
|
||||||
silent! unmap <buffer> X
|
silent! unmap <buffer> X
|
||||||
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
|
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap cursorline modifiable
|
||||||
setf vim-plug
|
setf vim-plug
|
||||||
@ -718,6 +723,15 @@ function! s:update_impl(pull, force, args) abort
|
|||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if !s:is_win && s:git_version_requirement(2, 3)
|
||||||
|
let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : ''
|
||||||
|
let $GIT_TERMINAL_PROMPT = 0
|
||||||
|
for plug in values(todo)
|
||||||
|
let plug.uri = substitute(plug.uri,
|
||||||
|
\ '^https://git::@github\.com', 'https://github.com', '')
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
if !isdirectory(g:plug_home)
|
if !isdirectory(g:plug_home)
|
||||||
try
|
try
|
||||||
call mkdir(g:plug_home, 'p')
|
call mkdir(g:plug_home, 'p')
|
||||||
@ -735,7 +749,7 @@ function! s:update_impl(pull, force, args) abort
|
|||||||
\ 'pull': a:pull,
|
\ 'pull': a:pull,
|
||||||
\ 'force': a:force,
|
\ 'force': a:force,
|
||||||
\ 'new': {},
|
\ 'new': {},
|
||||||
\ 'threads': (s:ruby || s:nvim) ? min([len(todo), threads]) : 1,
|
\ 'threads': (s:py2 || s:ruby || s:nvim) ? min([len(todo), threads]) : 1,
|
||||||
\ 'bar': '',
|
\ 'bar': '',
|
||||||
\ 'fin': 0
|
\ 'fin': 0
|
||||||
\ }
|
\ }
|
||||||
@ -744,13 +758,25 @@ function! s:update_impl(pull, force, args) abort
|
|||||||
call append(0, ['', ''])
|
call append(0, ['', ''])
|
||||||
normal! 2G
|
normal! 2G
|
||||||
|
|
||||||
if s:ruby && s:update.threads > 1
|
" Python version requirement (>= 2.7)
|
||||||
|
if s:py2 && !s:ruby && !s:nvim && s:update.threads > 1
|
||||||
|
redir => pyv
|
||||||
|
silent python import platform; print(platform.python_version())
|
||||||
|
redir END
|
||||||
|
let s:py2 = s:version_requirement(
|
||||||
|
\ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 7])
|
||||||
|
endif
|
||||||
|
if (s:py2 || s:ruby) && !s:nvim && s:update.threads > 1
|
||||||
try
|
try
|
||||||
let imd = &imd
|
let imd = &imd
|
||||||
if s:mac_gui
|
if s:mac_gui
|
||||||
set noimd
|
set noimd
|
||||||
endif
|
endif
|
||||||
|
if s:ruby
|
||||||
call s:update_ruby()
|
call s:update_ruby()
|
||||||
|
else
|
||||||
|
call s:update_python()
|
||||||
|
endif
|
||||||
catch
|
catch
|
||||||
let lines = getline(4, '$')
|
let lines = getline(4, '$')
|
||||||
let printed = {}
|
let printed = {}
|
||||||
@ -777,6 +803,9 @@ function! s:update_impl(pull, force, args) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:update_finish()
|
function! s:update_finish()
|
||||||
|
if exists('s:git_terminal_prompt')
|
||||||
|
let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt
|
||||||
|
endif
|
||||||
if s:switch_in()
|
if s:switch_in()
|
||||||
call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'has_key(v:val, "do")'))
|
call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'has_key(v:val, "do")'))
|
||||||
call s:finish(s:update.pull)
|
call s:finish(s:update.pull)
|
||||||
@ -937,13 +966,16 @@ 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
|
||||||
|
|
||||||
|
let checkout = s:shellesc(has_key(spec, 'tag') ? spec.tag : spec.branch)
|
||||||
|
let merge = s:shellesc(has_key(spec, 'tag') ? spec.tag : 'origin/'.spec.branch)
|
||||||
|
|
||||||
if !new
|
if !new
|
||||||
let [valid, msg] = s:git_valid(spec, 0)
|
let [valid, msg] = s:git_valid(spec, 0)
|
||||||
if valid
|
if valid
|
||||||
if pull
|
if pull
|
||||||
call s:spawn(name,
|
call s:spawn(name,
|
||||||
\ printf('(git fetch %s 2>&1 && git checkout -q %s 2>&1 && git merge --ff-only origin/%s 2>&1 && git submodule update --init --recursive 2>&1)',
|
\ printf('(git fetch %s 2>&1 && git checkout -q %s 2>&1 && git merge --ff-only %s 2>&1 && git submodule update --init --recursive 2>&1)',
|
||||||
\ prog, s:shellesc(spec.branch), s:shellesc(spec.branch)), { 'dir': spec.dir })
|
\ prog, checkout, merge), { 'dir': spec.dir })
|
||||||
else
|
else
|
||||||
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 }
|
let s:jobs[name] = { 'running': 0, 'result': 'Already installed', 'error': 0 }
|
||||||
endif
|
endif
|
||||||
@ -955,7 +987,7 @@ while 1 " Without TCO, Vim stack is bound to explode
|
|||||||
\ printf('git clone %s --recursive %s -b %s %s 2>&1',
|
\ printf('git clone %s --recursive %s -b %s %s 2>&1',
|
||||||
\ prog,
|
\ prog,
|
||||||
\ s:shellesc(spec.uri),
|
\ s:shellesc(spec.uri),
|
||||||
\ s:shellesc(spec.branch),
|
\ checkout,
|
||||||
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 })
|
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 })
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -968,6 +1000,386 @@ while 1 " Without TCO, Vim stack is bound to explode
|
|||||||
endwhile
|
endwhile
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:update_python()
|
||||||
|
python << EOF
|
||||||
|
""" Due to use of signals this function is POSIX only. """
|
||||||
|
import datetime
|
||||||
|
import functools
|
||||||
|
import os
|
||||||
|
import Queue
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
import threading as thr
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
import vim
|
||||||
|
|
||||||
|
G_PULL = vim.eval('s:update.pull') == '1'
|
||||||
|
G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1
|
||||||
|
G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)'))
|
||||||
|
G_PROGRESS = vim.eval('s:progress_opt(1)')
|
||||||
|
G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads'))
|
||||||
|
G_STOP = thr.Event()
|
||||||
|
|
||||||
|
class CmdTimedOut(Exception):
|
||||||
|
pass
|
||||||
|
class CmdFailed(Exception):
|
||||||
|
pass
|
||||||
|
class InvalidURI(Exception):
|
||||||
|
pass
|
||||||
|
class Action(object):
|
||||||
|
INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-']
|
||||||
|
|
||||||
|
class GLog(object):
|
||||||
|
ON = None
|
||||||
|
LOGDIR = None
|
||||||
|
@classmethod
|
||||||
|
def write(cls, msg):
|
||||||
|
if cls.ON is None:
|
||||||
|
cls.ON = int(vim.eval('get(g:, "plug_log_on", 0)'))
|
||||||
|
cls.LOGDIR = os.path.expanduser(vim.eval('get(g:, "plug_logs", "~/plug_logs")'))
|
||||||
|
if cls.ON:
|
||||||
|
if not os.path.exists(cls.LOGDIR):
|
||||||
|
os.makedirs(cls.LOGDIR)
|
||||||
|
cls._write(msg)
|
||||||
|
@classmethod
|
||||||
|
def _write(cls, msg):
|
||||||
|
name = thr.current_thread().name
|
||||||
|
fname = cls.LOGDIR + os.path.sep + name
|
||||||
|
with open(fname, 'ab') as flog:
|
||||||
|
ltime = datetime.datetime.now().strftime("%H:%M:%S.%f")
|
||||||
|
msg = '[{},{}] {}{}'.format(name, ltime, msg, '\n')
|
||||||
|
flog.write(msg)
|
||||||
|
|
||||||
|
class Buffer(object):
|
||||||
|
def __init__(self, lock, num_plugs):
|
||||||
|
self.bar = ''
|
||||||
|
self.event = 'Updating' if vim.eval('s:update.pull') == '1' else 'Installing'
|
||||||
|
self.is_win = vim.eval('s:is_win') == '1'
|
||||||
|
self.lock = lock
|
||||||
|
self.maxy = int(vim.eval('winheight(".")'))
|
||||||
|
self.num_plugs = num_plugs
|
||||||
|
|
||||||
|
def _where(self, name):
|
||||||
|
""" Find first line with name in current buffer. Return line num. """
|
||||||
|
found, lnum = False, 0
|
||||||
|
matcher = re.compile('^[-+x*] {}:'.format(name))
|
||||||
|
for line in vim.current.buffer:
|
||||||
|
if matcher.search(line) is not None:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
lnum += 1
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
lnum = -1
|
||||||
|
return lnum
|
||||||
|
|
||||||
|
def header(self):
|
||||||
|
curbuf = vim.current.buffer
|
||||||
|
curbuf[0] = self.event + ' plugins ({}/{})'.format(len(self.bar), self.num_plugs)
|
||||||
|
|
||||||
|
num_spaces = self.num_plugs - len(self.bar)
|
||||||
|
curbuf[1] = '[{}{}]'.format(self.bar, num_spaces * ' ')
|
||||||
|
|
||||||
|
vim.command('normal! 2G')
|
||||||
|
if not self.is_win:
|
||||||
|
vim.command('redraw')
|
||||||
|
|
||||||
|
def write(self, *args, **kwargs):
|
||||||
|
with self.lock:
|
||||||
|
self._write(*args, **kwargs)
|
||||||
|
|
||||||
|
def _write(self, action, name, lines):
|
||||||
|
first, rest = lines[0], lines[1:]
|
||||||
|
msg = ['{} {}{}{}'.format(action, name, ': ' if first else '', first)]
|
||||||
|
padded_rest = [' ' + line for line in rest]
|
||||||
|
msg.extend(padded_rest)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if action == Action.ERROR:
|
||||||
|
self.bar += 'x'
|
||||||
|
vim.command("call add(s:update.errors, '{}')".format(name))
|
||||||
|
elif action == Action.DONE:
|
||||||
|
self.bar += '='
|
||||||
|
|
||||||
|
curbuf = vim.current.buffer
|
||||||
|
lnum = self._where(name)
|
||||||
|
if lnum != -1: # Found matching line num
|
||||||
|
del curbuf[lnum]
|
||||||
|
if lnum > self.maxy and action in {Action.INSTALL, Action.UPDATE}:
|
||||||
|
lnum = 3
|
||||||
|
else:
|
||||||
|
lnum = 3
|
||||||
|
curbuf.append(msg, lnum)
|
||||||
|
|
||||||
|
self.header()
|
||||||
|
except vim.error:
|
||||||
|
GLog.write('Buffer Update FAILED.')
|
||||||
|
|
||||||
|
class Command(object):
|
||||||
|
def __init__(self, cmd, cmd_dir=None, timeout=60, ntries=3, cb=None, clean=None):
|
||||||
|
self.cmd = cmd
|
||||||
|
self.cmd_dir = cmd_dir
|
||||||
|
self.timeout = timeout
|
||||||
|
self.ntries = ntries
|
||||||
|
self.callback = cb if cb else (lambda msg: None)
|
||||||
|
self.clean = clean
|
||||||
|
|
||||||
|
def attempt_cmd(self):
|
||||||
|
""" Tries to run the command, returns result if no exceptions. """
|
||||||
|
attempt = 0
|
||||||
|
finished = False
|
||||||
|
limit = self.timeout
|
||||||
|
|
||||||
|
while not finished:
|
||||||
|
try:
|
||||||
|
attempt += 1
|
||||||
|
result = self.timeout_cmd()
|
||||||
|
finished = True
|
||||||
|
except CmdTimedOut:
|
||||||
|
if attempt != self.ntries:
|
||||||
|
for count in range(3, 0, -1):
|
||||||
|
if G_STOP.is_set():
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
msg = 'Timeout. Will retry in {} second{} ...'.format(
|
||||||
|
count, 's' if count != 1 else '')
|
||||||
|
self.callback([msg])
|
||||||
|
time.sleep(1)
|
||||||
|
self.timeout += limit
|
||||||
|
self.callback(['Retrying ...'])
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def timeout_cmd(self):
|
||||||
|
""" Execute a cmd & poll for callback. Returns list of output.
|
||||||
|
Raises CmdFailed -> return code for Popen isn't 0
|
||||||
|
Raises CmdTimedOut -> command exceeded timeout without new output
|
||||||
|
"""
|
||||||
|
proc = None
|
||||||
|
first_line = True
|
||||||
|
try:
|
||||||
|
tfile = tempfile.NamedTemporaryFile()
|
||||||
|
proc = subprocess.Popen(self.cmd, cwd=self.cmd_dir, stdout=tfile,
|
||||||
|
stderr=subprocess.STDOUT, shell=True, preexec_fn=os.setsid)
|
||||||
|
while proc.poll() is None:
|
||||||
|
# Yield this thread
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
if G_STOP.is_set():
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
|
if first_line or random.random() < G_LOG_PROB:
|
||||||
|
first_line = False
|
||||||
|
line = nonblock_read(tfile.name)
|
||||||
|
if line:
|
||||||
|
self.callback([line])
|
||||||
|
|
||||||
|
time_diff = time.time() - os.path.getmtime(tfile.name)
|
||||||
|
if time_diff > self.timeout:
|
||||||
|
raise CmdTimedOut(['Timeout!'])
|
||||||
|
|
||||||
|
tfile.seek(0)
|
||||||
|
result = [line.rstrip() for line in tfile]
|
||||||
|
|
||||||
|
if proc.returncode != 0:
|
||||||
|
msg = ['']
|
||||||
|
msg.extend(result)
|
||||||
|
raise CmdFailed(msg)
|
||||||
|
except:
|
||||||
|
if proc and proc.poll() is None:
|
||||||
|
os.killpg(proc.pid, signal.SIGTERM)
|
||||||
|
if self.clean:
|
||||||
|
self.clean()
|
||||||
|
raise
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
class Plugin(object):
|
||||||
|
def __init__(self, name, args, buf, lock):
|
||||||
|
self.name = name
|
||||||
|
self.args = args
|
||||||
|
self.buf = buf
|
||||||
|
self.lock = lock
|
||||||
|
tag = args.get('tag', 0)
|
||||||
|
self.checkout = esc(tag if tag else args['branch'])
|
||||||
|
self.merge = esc(tag if tag else 'origin/' + args['branch'])
|
||||||
|
|
||||||
|
def manage(self):
|
||||||
|
try:
|
||||||
|
if os.path.exists(self.args['dir']):
|
||||||
|
self.update()
|
||||||
|
else:
|
||||||
|
self.install()
|
||||||
|
with self.lock:
|
||||||
|
vim.command("let s:update.new['{}'] = 1".format(self.name))
|
||||||
|
except (CmdTimedOut, CmdFailed, InvalidURI) as exc:
|
||||||
|
self.write(Action.ERROR, self.name, exc.message)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
G_STOP.set()
|
||||||
|
self.write(Action.ERROR, self.name, ['Interrupted!'])
|
||||||
|
except:
|
||||||
|
# Any exception except those above print stack trace
|
||||||
|
msg = 'Trace:\n{}'.format(traceback.format_exc().rstrip())
|
||||||
|
self.write(Action.ERROR, self.name, msg.split('\n'))
|
||||||
|
raise
|
||||||
|
|
||||||
|
def install(self):
|
||||||
|
target = self.args['dir']
|
||||||
|
|
||||||
|
def clean(target):
|
||||||
|
def _clean():
|
||||||
|
try:
|
||||||
|
shutil.rmtree(target)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return _clean
|
||||||
|
|
||||||
|
self.write(Action.INSTALL, self.name, ['Installing ...'])
|
||||||
|
callback = functools.partial(self.buf.write, Action.INSTALL, self.name)
|
||||||
|
cmd = 'git clone {} --recursive {} -b {} {} 2>&1'.format(
|
||||||
|
G_PROGRESS, self.args['uri'], self.checkout, esc(target))
|
||||||
|
com = Command(cmd, None, G_TIMEOUT, G_RETRIES, callback, clean(target))
|
||||||
|
result = com.attempt_cmd()
|
||||||
|
self.write(Action.DONE, self.name, result[-1:])
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
match = re.compile(r'git::?@')
|
||||||
|
actual_uri = re.sub(match, '', self.repo_uri())
|
||||||
|
expect_uri = re.sub(match, '', self.args['uri'])
|
||||||
|
if actual_uri != expect_uri:
|
||||||
|
msg = ['',
|
||||||
|
'Invalid URI: {}'.format(actual_uri),
|
||||||
|
'Expected {}'.format(expect_uri),
|
||||||
|
'PlugClean required.']
|
||||||
|
raise InvalidURI(msg)
|
||||||
|
|
||||||
|
if G_PULL:
|
||||||
|
self.write(Action.UPDATE, self.name, ['Updating ...'])
|
||||||
|
callback = functools.partial(self.buf.write, Action.UPDATE, self.name)
|
||||||
|
cmds = ['git fetch {}'.format(G_PROGRESS),
|
||||||
|
'git checkout -q {}'.format(self.checkout),
|
||||||
|
'git merge --ff-only {}'.format(self.merge),
|
||||||
|
'git submodule update --init --recursive']
|
||||||
|
cmd = ' 2>&1 && '.join(cmds)
|
||||||
|
GLog.write(cmd)
|
||||||
|
com = Command(cmd, self.args['dir'], G_TIMEOUT, G_RETRIES, callback)
|
||||||
|
result = com.attempt_cmd()
|
||||||
|
GLog.write(result)
|
||||||
|
self.write(Action.DONE, self.name, result[-1:])
|
||||||
|
else:
|
||||||
|
self.write(Action.DONE, self.name, ['Already installed'])
|
||||||
|
|
||||||
|
def repo_uri(self):
|
||||||
|
cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url'
|
||||||
|
command = Command(cmd, self.args['dir'], G_TIMEOUT, G_RETRIES)
|
||||||
|
result = command.attempt_cmd()
|
||||||
|
return result[-1]
|
||||||
|
|
||||||
|
def write(self, action, name, msg):
|
||||||
|
GLog.write('{} {}: {}'.format(action, name, '\n'.join(msg)))
|
||||||
|
self.buf.write(action, name, msg)
|
||||||
|
|
||||||
|
class PlugThread(thr.Thread):
|
||||||
|
def __init__(self, tname, args):
|
||||||
|
super(PlugThread, self).__init__()
|
||||||
|
self.tname = tname
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
thr.current_thread().name = self.tname
|
||||||
|
work_q, lock, buf = self.args
|
||||||
|
|
||||||
|
try:
|
||||||
|
while not G_STOP.is_set():
|
||||||
|
name, args = work_q.get_nowait()
|
||||||
|
GLog.write('{}: Dir {}'.format(name, args['dir']))
|
||||||
|
plug = Plugin(name, args, buf, lock)
|
||||||
|
plug.manage()
|
||||||
|
work_q.task_done()
|
||||||
|
except Queue.Empty:
|
||||||
|
GLog.write('Queue now empty.')
|
||||||
|
|
||||||
|
class RefreshThread(thr.Thread):
|
||||||
|
def __init__(self, lock):
|
||||||
|
super(RefreshThread, self).__init__()
|
||||||
|
self.lock = lock
|
||||||
|
self.running = True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while self.running:
|
||||||
|
with self.lock:
|
||||||
|
vim.command('noautocmd normal! a')
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self.running = False
|
||||||
|
|
||||||
|
def esc(name):
|
||||||
|
return '"' + name.replace('"', '\"') + '"'
|
||||||
|
|
||||||
|
def nonblock_read(fname):
|
||||||
|
""" Read a file with nonblock flag. Return the last line. """
|
||||||
|
fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK)
|
||||||
|
buf = os.read(fread, 100000)
|
||||||
|
os.close(fread)
|
||||||
|
|
||||||
|
line = buf.rstrip('\r\n')
|
||||||
|
left = max(line.rfind('\r'), line.rfind('\n'))
|
||||||
|
if left != -1:
|
||||||
|
left += 1
|
||||||
|
line = line[left:]
|
||||||
|
|
||||||
|
return line
|
||||||
|
|
||||||
|
def main():
|
||||||
|
thr.current_thread().name = 'main'
|
||||||
|
GLog.write('')
|
||||||
|
if GLog.ON and os.path.exists(GLog.LOGDIR):
|
||||||
|
shutil.rmtree(GLog.LOGDIR)
|
||||||
|
|
||||||
|
threads = []
|
||||||
|
nthreads = int(vim.eval('s:update.threads'))
|
||||||
|
plugs = vim.eval('s:update.todo')
|
||||||
|
mac_gui = vim.eval('s:mac_gui') == '1'
|
||||||
|
is_win = vim.eval('s:is_win') == '1'
|
||||||
|
GLog.write('Plugs: {}'.format(plugs))
|
||||||
|
GLog.write('PULL: {}, WIN: {}, MAC: {}'.format(G_PULL, is_win, mac_gui))
|
||||||
|
GLog.write('Num Threads: {}'.format(nthreads))
|
||||||
|
|
||||||
|
lock = thr.Lock()
|
||||||
|
buf = Buffer(lock, len(plugs))
|
||||||
|
work_q = Queue.Queue()
|
||||||
|
for work in plugs.items():
|
||||||
|
work_q.put(work)
|
||||||
|
|
||||||
|
GLog.write('Starting Threads')
|
||||||
|
for num in range(nthreads):
|
||||||
|
tname = 'PlugT-{0:02}'.format(num)
|
||||||
|
thread = PlugThread(tname, (work_q, lock, buf))
|
||||||
|
thread.start()
|
||||||
|
threads.append(thread)
|
||||||
|
if mac_gui:
|
||||||
|
rthread = RefreshThread(lock)
|
||||||
|
rthread.start()
|
||||||
|
|
||||||
|
GLog.write('Joining Live Threads')
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
if mac_gui:
|
||||||
|
rthread.stop()
|
||||||
|
rthread.join()
|
||||||
|
GLog.write('Cleanly Exited Main')
|
||||||
|
|
||||||
|
main()
|
||||||
|
EOF
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:update_ruby()
|
function! s:update_ruby()
|
||||||
ruby << EOF
|
ruby << EOF
|
||||||
module PlugStream
|
module PlugStream
|
||||||
@ -1069,7 +1481,7 @@ function! s:update_ruby()
|
|||||||
if iswin
|
if iswin
|
||||||
Timeout::timeout(timeout) do
|
Timeout::timeout(timeout) do
|
||||||
tmp = VIM::evaluate('tempname()')
|
tmp = VIM::evaluate('tempname()')
|
||||||
system("#{cmd} > #{tmp}")
|
system("(#{cmd}) > #{tmp}")
|
||||||
data = File.read(tmp).chomp
|
data = File.read(tmp).chomp
|
||||||
File.unlink tmp rescue nil
|
File.unlink tmp rescue nil
|
||||||
end
|
end
|
||||||
@ -1132,13 +1544,14 @@ 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, tag = pair.last.values_at *%w[dir uri branch tag]
|
||||||
branch = esc branch
|
checkout = esc(tag ? tag : branch)
|
||||||
|
merge = esc(tag ? tag : "origin/#{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
|
||||||
ok, result =
|
ok, result =
|
||||||
if exists
|
if exists
|
||||||
dir = esc dir
|
dir = iswin ? dir : esc(dir)
|
||||||
ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil
|
ret, data = bt.call "#{cd} #{dir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config remote.origin.url", nil, nil, nil
|
||||||
current_uri = data.lines.to_a.last
|
current_uri = data.lines.to_a.last
|
||||||
if !ret
|
if !ret
|
||||||
@ -1154,7 +1567,7 @@ function! s:update_ruby()
|
|||||||
else
|
else
|
||||||
if pull
|
if pull
|
||||||
log.call name, 'Updating ...', :update
|
log.call name, 'Updating ...', :update
|
||||||
bt.call "#{cd} #{dir} && (git fetch #{progress} 2>&1 && git checkout -q #{branch} 2>&1 && git merge --ff-only origin/#{branch} 2>&1 && #{subm})", name, :update, nil
|
bt.call "#{cd} #{dir} && git fetch #{progress} 2>&1 && git checkout -q #{checkout} 2>&1 && git merge --ff-only #{merge} 2>&1 && #{subm}", name, :update, nil
|
||||||
else
|
else
|
||||||
[true, skip]
|
[true, skip]
|
||||||
end
|
end
|
||||||
@ -1162,7 +1575,7 @@ function! s:update_ruby()
|
|||||||
else
|
else
|
||||||
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", name, :install, proc {
|
bt.call "git clone #{progress} --recursive #{uri} -b #{checkout} #{d} 2>&1", name, :install, proc {
|
||||||
FileUtils.rm_rf dir
|
FileUtils.rm_rf dir
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
@ -1180,7 +1593,7 @@ EOF
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:shellesc(arg)
|
function! s:shellesc(arg)
|
||||||
return '"'.substitute(a:arg, '"', '\\"', 'g').'"'
|
return '"'.escape(a:arg, '"').'"'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:glob_dir(path)
|
function! s:glob_dir(path)
|
||||||
@ -1207,7 +1620,7 @@ function! s:format_message(bullet, name, message)
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:with_cd(cmd, dir)
|
function! s:with_cd(cmd, dir)
|
||||||
return (s:is_win ? 'cd /d ' : 'cd ').s:esc(a:dir).' && '.a:cmd
|
return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:system(cmd, ...)
|
function! s:system(cmd, ...)
|
||||||
@ -1244,13 +1657,19 @@ function! s:git_valid(spec, check_branch)
|
|||||||
let ret = 0
|
let ret = 0
|
||||||
elseif a:check_branch
|
elseif a:check_branch
|
||||||
let branch = result[0]
|
let branch = result[0]
|
||||||
if a:spec.branch !=# branch
|
" Check tag
|
||||||
|
if has_key(a:spec, 'tag')
|
||||||
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
|
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
|
||||||
if a:spec.branch !=# tag
|
if a:spec.tag !=# tag
|
||||||
let msg = printf('Invalid branch/tag: %s (expected: %s). Try PlugUpdate.',
|
let msg = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.',
|
||||||
\ (empty(tag) ? branch : tag), a:spec.branch)
|
\ (empty(tag) ? 'N/A' : tag), a:spec.tag)
|
||||||
let ret = 0
|
let ret = 0
|
||||||
endif
|
endif
|
||||||
|
" Check branch
|
||||||
|
elseif a:spec.branch !=# branch
|
||||||
|
let msg = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.',
|
||||||
|
\ branch, a:spec.branch)
|
||||||
|
let ret = 0
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
@ -1332,8 +1751,10 @@ function! s:upgrade()
|
|||||||
endif
|
endif
|
||||||
elseif s:ruby
|
elseif s:ruby
|
||||||
call s:upgrade_using_ruby(new)
|
call s:upgrade_using_ruby(new)
|
||||||
|
elseif s:py2
|
||||||
|
call s:upgrade_using_python(new)
|
||||||
else
|
else
|
||||||
return s:err('curl executable or ruby support not found')
|
return s:err('Missing: curl executable, ruby support or python support')
|
||||||
endif
|
endif
|
||||||
catch
|
catch
|
||||||
return s:err('Error upgrading vim-plug: '. v:exception)
|
return s:err('Error upgrading vim-plug: '. v:exception)
|
||||||
@ -1361,6 +1782,15 @@ function! s:upgrade_using_ruby(new)
|
|||||||
EOF
|
EOF
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:upgrade_using_python(new)
|
||||||
|
python << EOF
|
||||||
|
import urllib
|
||||||
|
import vim
|
||||||
|
psrc, dest = vim.eval('s:plug_src'), vim.eval('a:new')
|
||||||
|
urllib.urlretrieve(psrc, dest)
|
||||||
|
EOF
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:upgrade_specs()
|
function! s:upgrade_specs()
|
||||||
for spec in values(g:plugs)
|
for spec in values(g:plugs)
|
||||||
let spec.frozen = get(spec, 'frozen', 0)
|
let spec.frozen = get(spec, 'frozen', 0)
|
||||||
@ -1476,7 +1906,7 @@ function! s:preview_commit()
|
|||||||
execute 'pedit' sha
|
execute 'pedit' sha
|
||||||
wincmd P
|
wincmd P
|
||||||
setlocal filetype=git buftype=nofile nobuflisted
|
setlocal filetype=git buftype=nofile nobuflisted
|
||||||
execute 'silent read !cd' s:esc(g:plugs[name].dir) '&& git show' sha
|
execute 'silent read !cd' s:shellesc(g:plugs[name].dir) '&& git show' sha
|
||||||
normal! gg"_dd
|
normal! gg"_dd
|
||||||
wincmd p
|
wincmd p
|
||||||
endfunction
|
endfunction
|
||||||
@ -1510,6 +1940,7 @@ function! s:diff()
|
|||||||
|
|
||||||
call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
|
call setline(1, cnt == 0 ? 'No updates.' : 'Last update:')
|
||||||
nnoremap <silent> <buffer> <cr> :silent! call <SID>preview_commit()<cr>
|
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>
|
nnoremap <silent> <buffer> X :call <SID>revert()<cr>
|
||||||
normal! gg
|
normal! gg
|
||||||
setlocal nomodifiable
|
setlocal nomodifiable
|
||||||
@ -1537,7 +1968,7 @@ function! s:snapshot(...) abort
|
|||||||
let [type, var, header] = s:is_win ?
|
let [type, var, header] = s:is_win ?
|
||||||
\ ['dosbatch', '%PLUG_HOME%',
|
\ ['dosbatch', '%PLUG_HOME%',
|
||||||
\ ['@echo off', ':: Generated by vim-plug', ':: '.strftime("%c"), '',
|
\ ['@echo off', ':: Generated by vim-plug', ':: '.strftime("%c"), '',
|
||||||
\ ':: Make sure to PlugUpdate first', '', 'set PLUG_HOME='.s:esc(home)]] :
|
\ ':: Make sure to PlugUpdate first', '', 'set PLUG_HOME='.home]] :
|
||||||
\ ['sh', '$PLUG_HOME',
|
\ ['sh', '$PLUG_HOME',
|
||||||
\ ['#!/bin/sh', '# Generated by vim-plug', '# '.strftime("%c"), '',
|
\ ['#!/bin/sh', '# Generated by vim-plug', '# '.strftime("%c"), '',
|
||||||
\ 'vim +PlugUpdate +qa', '', 'PLUG_HOME='.s:esc(home)]]
|
\ 'vim +PlugUpdate +qa', '', 'PLUG_HOME='.s:esc(home)]]
|
||||||
@ -1556,7 +1987,7 @@ function! s:snapshot(...) abort
|
|||||||
let sha = s:system_chomp('git rev-parse --short HEAD', dir)
|
let sha = s:system_chomp('git rev-parse --short HEAD', dir)
|
||||||
if !empty(sha)
|
if !empty(sha)
|
||||||
call append(anchor, printf('cd %s && git reset --hard %s',
|
call append(anchor, printf('cd %s && git reset --hard %s',
|
||||||
\ substitute(dir, '^'.g:plug_home, var, ''), sha))
|
\ substitute(dir, '^\V'.escape(g:plug_home, '\'), var, ''), sha))
|
||||||
redraw
|
redraw
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
Loading…
Reference in New Issue
Block a user