add system_with_error for handling v:shell_error using job

This commit is contained in:
Yasuhiro Matsumoto 2017-02-21 13:24:18 +09:00
parent 90ad03408e
commit ed4c8611d3

View File

@ -865,8 +865,8 @@ endfunction
function! s:checkout(spec) function! s:checkout(spec)
let sha = a:spec.commit let sha = a:spec.commit
let output = s:system('git rev-parse HEAD', a:spec.dir) let [output, shellerror] = s:system_with_error('git rev-parse HEAD', a:spec.dir)
if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) if !shellerror && !s:hash_match(sha, s:lines(output)[0])
let output = s:system( let output = s:system(
\ 'git fetch --depth 999999 && git checkout '.s:esc(sha), a:spec.dir) \ 'git fetch --depth 999999 && git checkout '.s:esc(sha), a:spec.dir)
endif endif
@ -1053,14 +1053,16 @@ function! s:update_finish()
if !pos if !pos
continue continue
endif endif
let shellerror = 0
if has_key(spec, 'commit') if has_key(spec, 'commit')
call s:log4(name, 'Checking out '.spec.commit) call s:log4(name, 'Checking out '.spec.commit)
let out = s:checkout(spec) let out = s:checkout(spec)
elseif has_key(spec, 'tag') elseif has_key(spec, 'tag')
let tag = spec.tag let tag = spec.tag
if tag =~ '\*' if tag =~ '\*'
let tags = s:lines(s:system('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir)) let [output, shellerror] = s:system_with_error('git tag --list '.string(tag).' --sort -version:refname 2>&1', spec.dir)
if !v:shell_error && !empty(tags) let tags = s:lines(output)
if !shellerror && !empty(tags)
let tag = tags[0] let tag = tags[0]
call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
call append(3, '') call append(3, '')
@ -1074,13 +1076,13 @@ function! s:update_finish()
let out = s:system('git checkout -q '.branch.' 2>&1' let out = s:system('git checkout -q '.branch.' 2>&1'
\. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir)
endif endif
if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && if !shellerror && filereadable(spec.dir.'/.gitmodules') &&
\ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
call s:log4(name, 'Updating submodules. This may take a while.') call s:log4(name, 'Updating submodules. This may take a while.')
let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir) let out .= s:bang('git submodule update --init --recursive 2>&1', spec.dir)
endif endif
let msg = s:format_message(v:shell_error ? 'x': '-', name, out) let msg = s:format_message(shellerror ? 'x': '-', name, out)
if v:shell_error if shellerror
call add(s:update.errors, name) call add(s:update.errors, name)
call s:regress_bar() call s:regress_bar()
silent execute pos 'd _' silent execute pos 'd _'
@ -1203,8 +1205,9 @@ function! s:spawn(name, cmd, opts)
endif endif
else else
let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd] let params = has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]
let job.lines = s:lines(call('s:system', params)) let [output, shellerror] = call('s:system_with_error', params)
let job.error = v:shell_error != 0 let job.lines = s:lines(output)
let job.error = shellerror != 0
let job.running = 0 let job.running = 0
endif endif
endfunction endfunction
@ -1997,26 +2000,52 @@ function! s:system(cmd, ...)
endtry endtry
endfunction endfunction
function! s:system_with_error(cmd, ...)
try
let maxfuncdepth = &maxfuncdepth
set maxfuncdepth=99999
let [sh, shrd] = s:chsh(1)
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
if s:vim8
let [out, exit_code] = ['', 0]
let job = job_start([&shell, &shellcmdflag, cmd], {
\ 'out_cb': {ch,msg->[execute("let out .= msg"), out]},
\ 'err_cb': {ch,msg->[execute("let out .= msg"), out]},
\ 'exit_cb': {job,code->[execute("let exit_code=code"), exit_code]},
\ 'out_mode': 'raw'})
while job_status(job) == 'run'
sleep 10m
endwhile
return [out, exit_code]
endif
return [system(s:is_win ? '('.cmd.')' : cmd), v:shell_error]
finally
let [&shell, &shellredir, &maxfuncdepth] = [sh, shrd, maxfuncdepth]
endtry
endfunction
function! s:system_chomp(...) function! s:system_chomp(...)
let ret = call('s:system', a:000) let [ret, shellerror] = call('s:system_with_error', a:000)
return v:shell_error ? '' : substitute(ret, '\n$', '', '') return shellerror ? '' : substitute(ret, '\n$', '', '')
endfunction endfunction
function! s:git_validate(spec, check_branch) function! s:git_validate(spec, check_branch)
let err = '' let err = ''
if isdirectory(a:spec.dir) if isdirectory(a:spec.dir)
let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) let [output, shellerror] = s:system_with_error('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)
let result = s:lines(output)
let remote = result[-1] let remote = result[-1]
if v:shell_error if shellerror
let err = join([remote, 'PlugClean required.'], "\n") let err = join([remote, 'PlugClean required.'], "\n")
elseif !s:compare_git_uri(remote, a:spec.uri) elseif !s:compare_git_uri(remote, a:spec.uri)
let err = join(['Invalid URI: '.remote, let err = join(['Invalid URI: '.remote,
\ 'Expected: '.a:spec.uri, \ 'Expected: '.a:spec.uri,
\ 'PlugClean required.'], "\n") \ 'PlugClean required.'], "\n")
elseif a:check_branch && has_key(a:spec, 'commit') elseif a:check_branch && has_key(a:spec, 'commit')
let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) let [output, shellerror] = s:system_with_error('git rev-parse HEAD 2>&1', a:spec.dir)
let result = s:lines(output)
let sha = result[-1] let sha = result[-1]
if v:shell_error if shellerror
let err = join(add(result, 'PlugClean required.'), "\n") let err = join(add(result, 'PlugClean required.'), "\n")
elseif !s:hash_match(sha, a:spec.commit) elseif !s:hash_match(sha, a:spec.commit)
let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', let err = join([printf('Invalid HEAD (expected: %s, actual: %s)',
@ -2038,10 +2067,11 @@ function! s:git_validate(spec, check_branch)
\ branch, a:spec.branch) \ branch, a:spec.branch)
endif endif
if empty(err) if empty(err)
let [ahead, behind] = split(s:lastline(s:system(printf( let [output, shellerror] = s:system_with_error(printf(
\ 'git rev-list --count --left-right HEAD...origin/%s', \ 'git rev-list --count --left-right HEAD...origin/%s',
\ a:spec.branch), a:spec.dir)), '\t') \ a:spec.branch), a:spec.dir)
if !v:shell_error && ahead let [ahead, behind] = split(s:lastline(output), '\t')
if !shellerror && ahead
if behind if behind
" Only mention PlugClean if diverged, otherwise it's likely to be " Only mention PlugClean if diverged, otherwise it's likely to be
" pushable (and probably not that messed up). " pushable (and probably not that messed up).
@ -2173,8 +2203,8 @@ function! s:upgrade()
let new = tmp . '/plug.vim' let new = tmp . '/plug.vim'
try try
let out = s:system(printf('git clone --depth 1 %s %s', s:plug_src, tmp)) let [out, shellerror] = s:system_with_error(printf('git clone --depth 1 %s %s', s:plug_src, tmp))
if v:shell_error if shellerror
return s:err('Error upgrading vim-plug: '. out) return s:err('Error upgrading vim-plug: '. out)
endif endif