mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 06:20:05 +08:00
893 lines
26 KiB
VimL
Vendored
893 lines
26 KiB
VimL
Vendored
"=============================================================================
|
|
" FILE: installer.vim
|
|
" AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
|
|
" License: MIT license {{{
|
|
" Permission is hereby granted, free of charge, to any person obtaining
|
|
" a copy of this software and associated documentation files (the
|
|
" "Software"), to deal in the Software without restriction, including
|
|
" without limitation the rights to use, copy, modify, merge, publish,
|
|
" distribute, sublicense, and/or sell copies of the Software, and to
|
|
" permit persons to whom the Software is furnished to do so, subject to
|
|
" the following conditions:
|
|
"
|
|
" The above copyright notice and this permission notice shall be included
|
|
" in all copies or substantial portions of the Software.
|
|
"
|
|
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
" }}}
|
|
"=============================================================================
|
|
|
|
let s:save_cpo = &cpo
|
|
set cpo&vim
|
|
|
|
let s:install_info_version = '3.0'
|
|
|
|
let s:log = []
|
|
let s:updates_log = []
|
|
|
|
function! neobundle#installer#update(bundles) abort "{{{
|
|
if neobundle#util#is_sudo()
|
|
call neobundle#util#print_error(
|
|
\ '"sudo vim" is detected. This feature is disabled.')
|
|
return
|
|
endif
|
|
|
|
let all_bundles = neobundle#config#get_enabled_bundles()
|
|
|
|
call neobundle#commands#helptags(all_bundles)
|
|
call s:reload(filter(copy(a:bundles),
|
|
\ "v:val.sourced && !v:val.disabled && v:val.rtp != ''"))
|
|
|
|
call s:save_install_info(all_bundles)
|
|
|
|
let lazy_bundles = filter(copy(all_bundles), 'v:val.lazy')
|
|
call neobundle#util#merge_bundle_files(
|
|
\ lazy_bundles, 'ftdetect')
|
|
call neobundle#util#merge_bundle_files(
|
|
\ lazy_bundles, 'after/ftdetect')
|
|
|
|
" For neovim remote plugins
|
|
NeoBundleRemotePlugins
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#build(bundle) abort "{{{
|
|
if !empty(a:bundle.build_commands)
|
|
\ && neobundle#config#check_commands(a:bundle.build_commands)
|
|
call neobundle#installer#log(
|
|
\ printf('|%s| ' .
|
|
\ 'Build dependencies not met. Skipped', a:bundle.name))
|
|
return 0
|
|
endif
|
|
|
|
" Environment check.
|
|
let build = get(a:bundle, 'build', {})
|
|
if type(build) == type('')
|
|
let cmd = build
|
|
elseif neobundle#util#is_windows() && has_key(build, 'windows')
|
|
let cmd = build.windows
|
|
elseif neobundle#util#is_mac() && has_key(build, 'mac')
|
|
let cmd = build.mac
|
|
elseif neobundle#util#is_cygwin() && has_key(build, 'cygwin')
|
|
let cmd = build.cygwin
|
|
elseif !neobundle#util#is_windows() && has_key(build, 'linux')
|
|
\ && !executable('gmake')
|
|
let cmd = build.linux
|
|
elseif !neobundle#util#is_windows() && has_key(build, 'unix')
|
|
let cmd = build.unix
|
|
elseif has_key(build, 'others')
|
|
let cmd = build.others
|
|
else
|
|
return 0
|
|
endif
|
|
|
|
call neobundle#installer#log('Building...')
|
|
|
|
let cwd = getcwd()
|
|
try
|
|
call neobundle#util#cd(a:bundle.path)
|
|
|
|
if !neobundle#util#has_vimproc()
|
|
let result = neobundle#util#system(cmd)
|
|
|
|
if neobundle#util#get_last_status()
|
|
call neobundle#installer#error(result)
|
|
else
|
|
call neobundle#installer#log(result)
|
|
endif
|
|
else
|
|
call s:async_system(cmd)
|
|
endif
|
|
catch
|
|
" Build error from vimproc.
|
|
let message = (v:exception !~# '^Vim:')?
|
|
\ v:exception : v:exception . ' ' . v:throwpoint
|
|
call neobundle#installer#error(message)
|
|
|
|
return 1
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
|
|
return neobundle#util#get_last_status()
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#reinstall(bundles) abort "{{{
|
|
let bundles = neobundle#util#uniq(a:bundles)
|
|
|
|
for bundle in bundles
|
|
if bundle.type ==# 'none'
|
|
\ || bundle.local
|
|
\ || bundle.normalized_name ==# 'neobundle'
|
|
\ || (bundle.sourced &&
|
|
\ index(['vimproc', 'unite'], bundle.normalized_name) >= 0)
|
|
call neobundle#installer#error(
|
|
\ printf('|%s| Cannot reinstall the plugin!', bundle.name))
|
|
continue
|
|
endif
|
|
|
|
" Reinstall.
|
|
call neobundle#installer#log(
|
|
\ printf('|%s| Reinstalling...', bundle.name))
|
|
|
|
" Save info.
|
|
let arg = copy(bundle.orig_arg)
|
|
|
|
" Remove.
|
|
call neobundle#commands#clean(1, bundle.name)
|
|
|
|
call call('neobundle#parser#bundle', [arg])
|
|
endfor
|
|
|
|
call s:save_install_info(neobundle#config#get_neobundles())
|
|
|
|
" Install.
|
|
call neobundle#commands#install(0,
|
|
\ join(map(copy(bundles), 'v:val.name')))
|
|
|
|
call neobundle#installer#update(bundles)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_reinstall_bundles(bundles) abort "{{{
|
|
call neobundle#installer#_load_install_info(a:bundles)
|
|
|
|
let reinstall_bundles = filter(copy(a:bundles),
|
|
\ "neobundle#config#is_installed(v:val.name)
|
|
\ && v:val.type !=# 'none'
|
|
\ && !v:val.local
|
|
\ && v:val.path ==# v:val.installed_path
|
|
\ && v:val.uri !=# v:val.installed_uri")
|
|
if !empty(reinstall_bundles)
|
|
call neobundle#util#print_error(
|
|
\ 'Reinstall bundles are detected!')
|
|
|
|
for bundle in reinstall_bundles
|
|
echomsg printf('%s: %s -> %s',
|
|
\ bundle.name, bundle.installed_uri, bundle.uri)
|
|
endfor
|
|
|
|
let cwd = neobundle#util#substitute_path_separator(getcwd())
|
|
let warning_bundles = map(filter(copy(reinstall_bundles),
|
|
\ 'v:val.path ==# cwd'), 'v:val.path')
|
|
if !empty(warning_bundles)
|
|
call neobundle#util#print_error(
|
|
\ 'Warning: current directory is the
|
|
\ reinstall bundles directory! ' . string(warning_bundles))
|
|
endif
|
|
let ret = confirm('Reinstall bundles now?', "yes\nNo", 2)
|
|
redraw
|
|
if ret != 1
|
|
return []
|
|
endif
|
|
endif
|
|
|
|
return reinstall_bundles
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_updated_bundles_message(bundles) abort "{{{
|
|
let msg = ''
|
|
|
|
let installed_bundles = filter(copy(a:bundles),
|
|
\ "v:val.old_rev == ''")
|
|
if !empty(installed_bundles)
|
|
let msg .= "\nInstalled bundles:\n".
|
|
\ join(map(copy(installed_bundles),
|
|
\ "' ' . v:val.name"), "\n")
|
|
endif
|
|
|
|
let updated_bundles = filter(copy(a:bundles),
|
|
\ "v:val.old_rev != ''")
|
|
if !empty(updated_bundles)
|
|
let msg .= "\nUpdated bundles:\n".
|
|
\ join(map(updated_bundles,
|
|
\ "' ' . v:val.name . (v:val.commit_count == 0 ? ''
|
|
\ : printf('(%d change%s)',
|
|
\ v:val.commit_count,
|
|
\ (v:val.commit_count == 1 ? '' : 's')))
|
|
\ . (v:val.uri =~ '^\\h\\w*://github.com/' ? \"\\n\"
|
|
\ . printf(' %s/compare/%s...%s',
|
|
\ substitute(substitute(v:val.uri, '\\.git$', '', ''),
|
|
\ '^\\h\\w*:', 'https:', ''),
|
|
\ v:val.old_rev, v:val.new_rev) : '')")
|
|
\ , "\n")
|
|
endif
|
|
|
|
return msg
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_errored_bundles_message(bundles) abort "{{{
|
|
if empty(a:bundles)
|
|
return ''
|
|
endif
|
|
|
|
let msg = "\nError installing bundles:\n".join(
|
|
\ map(copy(a:bundles), "' ' . v:val.name"), "\n")
|
|
let msg .= "\n"
|
|
let msg .= "Please read the error message log with the :message command.\n"
|
|
|
|
return msg
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_sync_command(bang, bundle, number, max) abort "{{{
|
|
let type = neobundle#config#get_types(a:bundle.type)
|
|
if empty(type)
|
|
return ['E: Unknown Type', '']
|
|
endif
|
|
|
|
let is_directory = isdirectory(a:bundle.path)
|
|
|
|
let cmd = type.get_sync_command(a:bundle)
|
|
|
|
if cmd == ''
|
|
return ['', 'Not supported sync action.']
|
|
elseif (is_directory && !a:bang
|
|
\ && a:bundle.install_rev ==#
|
|
\ neobundle#installer#get_revision_number(a:bundle))
|
|
return ['', 'Already installed.']
|
|
endif
|
|
|
|
let message = printf('(%'.len(a:max).'d/%d): |%s| %s',
|
|
\ a:number, a:max, a:bundle.name, cmd)
|
|
|
|
return [cmd, message]
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_revision_lock_command(bang, bundle, number, max) abort "{{{
|
|
let type = neobundle#config#get_types(a:bundle.type)
|
|
if empty(type)
|
|
return ['E: Unknown Type', '']
|
|
endif
|
|
|
|
let cmd = type.get_revision_lock_command(a:bundle)
|
|
|
|
if cmd == ''
|
|
return ['', '']
|
|
endif
|
|
|
|
return [cmd, '']
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_revision_number(bundle) abort "{{{
|
|
let cwd = getcwd()
|
|
let type = neobundle#config#get_types(a:bundle.type)
|
|
|
|
if !isdirectory(a:bundle.path)
|
|
\ || !has_key(type, 'get_revision_number_command')
|
|
return ''
|
|
endif
|
|
|
|
let cmd = type.get_revision_number_command(a:bundle)
|
|
if cmd == ''
|
|
return ''
|
|
endif
|
|
|
|
try
|
|
call neobundle#util#cd(a:bundle.path)
|
|
|
|
let rev = neobundle#util#system(cmd)
|
|
|
|
if type.name ==# 'vba' || type.name ==# 'raw'
|
|
" If rev is ok, the output is the checksum followed by the filename
|
|
" separated by two spaces.
|
|
let pat = '^[0-9a-f]\+ ' . a:bundle.path . '/' .
|
|
\ fnamemodify(a:bundle.uri, ':t') . '$'
|
|
return (rev =~# pat) ? matchstr(rev, '^[0-9a-f]\+') : ''
|
|
else
|
|
" If rev contains spaces, it is error message
|
|
return (rev !~ '\s') ? rev : ''
|
|
endif
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
endfunction"}}}
|
|
|
|
function! s:get_commit_date(bundle) abort "{{{
|
|
let cwd = getcwd()
|
|
try
|
|
let type = neobundle#config#get_types(a:bundle.type)
|
|
|
|
if !isdirectory(a:bundle.path) ||
|
|
\ !has_key(type, 'get_commit_date_command')
|
|
return 0
|
|
endif
|
|
|
|
call neobundle#util#cd(a:bundle.path)
|
|
|
|
return neobundle#util#system(
|
|
\ type.get_commit_date_command(a:bundle))
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_updated_log_message(bundle, new_rev, old_rev) abort "{{{
|
|
let cwd = getcwd()
|
|
try
|
|
let type = neobundle#config#get_types(a:bundle.type)
|
|
|
|
call neobundle#util#cd(a:bundle.path)
|
|
|
|
let log_command = has_key(type, 'get_log_command') ?
|
|
\ type.get_log_command(a:bundle, a:new_rev, a:old_rev) : ''
|
|
let log = (log_command != '' ?
|
|
\ neobundle#util#system(log_command) : '')
|
|
return log != '' ? log :
|
|
\ (a:old_rev == a:new_rev) ? ''
|
|
\ : printf('%s -> %s', a:old_rev, a:new_rev)
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#sync(bundle, context, is_unite) abort "{{{
|
|
let a:context.source__number += 1
|
|
|
|
let num = a:context.source__number
|
|
let max = a:context.source__max_bundles
|
|
|
|
let before_one_day = localtime() - 60 * 60 * 24
|
|
let before_one_week = localtime() - 60 * 60 * 24 * 7
|
|
|
|
if a:context.source__bang == 1 &&
|
|
\ a:bundle.frozen
|
|
let [cmd, message] = ['', 'is frozen.']
|
|
elseif a:context.source__bang == 1 &&
|
|
\ a:bundle.uri ==# a:bundle.installed_uri &&
|
|
\ a:bundle.updated_time < before_one_week
|
|
\ && a:bundle.checked_time >= before_one_day
|
|
let [cmd, message] = ['', 'Outdated plugin.']
|
|
else
|
|
let [cmd, message] =
|
|
\ neobundle#installer#get_sync_command(
|
|
\ a:context.source__bang, a:bundle,
|
|
\ a:context.source__number, a:context.source__max_bundles)
|
|
endif
|
|
|
|
if cmd == ''
|
|
" Skipped.
|
|
call neobundle#installer#log(s:get_skipped_message(
|
|
\ num, max, a:bundle, '', message), a:is_unite)
|
|
return
|
|
elseif cmd =~# '^E: '
|
|
" Errored.
|
|
|
|
call neobundle#installer#update_log(
|
|
\ printf('(%'.len(max).'d/%d): |%s| %s',
|
|
\ num, max, a:bundle.name, 'Error'), a:is_unite)
|
|
call neobundle#installer#error(cmd[3:])
|
|
call add(a:context.source__errored_bundles,
|
|
\ a:bundle)
|
|
return
|
|
endif
|
|
|
|
call neobundle#installer#log(message, a:is_unite)
|
|
|
|
let cwd = getcwd()
|
|
try
|
|
let lang_save = $LANG
|
|
let $LANG = 'C'
|
|
|
|
" Cd to bundle path.
|
|
call neobundle#util#cd(a:bundle.path)
|
|
|
|
let rev = neobundle#installer#get_revision_number(a:bundle)
|
|
|
|
let process = {
|
|
\ 'number' : num,
|
|
\ 'rev' : rev,
|
|
\ 'bundle' : a:bundle,
|
|
\ 'output' : '',
|
|
\ 'status' : -1,
|
|
\ 'eof' : 0,
|
|
\ 'start_time' : localtime(),
|
|
\ }
|
|
|
|
if isdirectory(a:bundle.path) && !a:bundle.local
|
|
let rev_save = a:bundle.rev
|
|
try
|
|
" Force checkout HEAD revision.
|
|
" The repository may be checked out.
|
|
let a:bundle.rev = ''
|
|
|
|
call neobundle#installer#lock_revision(
|
|
\ process, a:context, a:is_unite)
|
|
finally
|
|
let a:bundle.rev = rev_save
|
|
endtry
|
|
endif
|
|
|
|
if has('nvim') && a:is_unite
|
|
" Use neovim async jobs
|
|
let process.proc = jobstart(
|
|
\ iconv(cmd, &encoding, 'char'), {
|
|
\ 'on_stdout' : function('s:job_handler'),
|
|
\ 'on_stderr' : function('s:job_handler'),
|
|
\ 'on_exit' : function('s:job_handler'),
|
|
\ })
|
|
elseif neobundle#util#has_vimproc()
|
|
let process.proc = vimproc#pgroup_open(vimproc#util#iconv(
|
|
\ cmd, &encoding, 'char'), 0, 2)
|
|
|
|
" Close handles.
|
|
call process.proc.stdin.close()
|
|
call process.proc.stderr.close()
|
|
else
|
|
let process.output = neobundle#util#system(cmd)
|
|
let process.status = neobundle#util#get_last_status()
|
|
endif
|
|
finally
|
|
let $LANG = lang_save
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
|
|
call add(a:context.source__processes, process)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#check_output(context, process, is_unite) abort "{{{
|
|
if has('nvim') && a:is_unite && has_key(a:process, 'proc')
|
|
let is_timeout = (localtime() - a:process.start_time)
|
|
\ >= a:process.bundle.install_process_timeout
|
|
|
|
if !has_key(s:job_info, a:process.proc)
|
|
return
|
|
endif
|
|
|
|
let job = s:job_info[a:process.proc]
|
|
|
|
if !job.eof && !is_timeout
|
|
let output = join(job.candidates[: -2], "\n")
|
|
if output != ''
|
|
let a:process.output .= output
|
|
call neobundle#util#redraw_echo(output)
|
|
endif
|
|
let job.candidates = job.candidates[-1:]
|
|
return
|
|
else
|
|
if is_timeout
|
|
call jobstop(a:process.proc)
|
|
endif
|
|
let output = join(job.candidates, "\n")
|
|
if output != ''
|
|
let a:process.output .= output
|
|
call neobundle#util#redraw_echo(output)
|
|
endif
|
|
let job.candidates = []
|
|
endif
|
|
|
|
let status = job.status
|
|
elseif neobundle#util#has_vimproc() && has_key(a:process, 'proc')
|
|
let is_timeout = (localtime() - a:process.start_time)
|
|
\ >= a:process.bundle.install_process_timeout
|
|
let output = vimproc#util#iconv(
|
|
\ a:process.proc.stdout.read(-1, 300), 'char', &encoding)
|
|
if output != ''
|
|
let a:process.output .= output
|
|
call neobundle#util#redraw_echo(output)
|
|
endif
|
|
if !a:process.proc.stdout.eof && !is_timeout
|
|
return
|
|
endif
|
|
call a:process.proc.stdout.close()
|
|
|
|
let status = a:process.proc.waitpid()[1]
|
|
else
|
|
let is_timeout = 0
|
|
let status = a:process.status
|
|
endif
|
|
|
|
let num = a:process.number
|
|
let max = a:context.source__max_bundles
|
|
let bundle = a:process.bundle
|
|
|
|
if bundle.rev != '' || !a:context.source__bang
|
|
" Restore revision.
|
|
let rev_save = bundle.rev
|
|
try
|
|
if !a:context.source__bang && bundle.rev == ''
|
|
" Checkout install_rev revision.
|
|
let bundle.rev = bundle.install_rev
|
|
endif
|
|
|
|
call neobundle#installer#lock_revision(
|
|
\ a:process, a:context, a:is_unite)
|
|
finally
|
|
let bundle.rev = rev_save
|
|
endtry
|
|
endif
|
|
|
|
let rev = neobundle#installer#get_revision_number(bundle)
|
|
|
|
let updated_time = s:get_commit_date(bundle)
|
|
let bundle.checked_time = localtime()
|
|
|
|
if is_timeout || status
|
|
let message = printf('(%'.len(max).'d/%d): |%s| %s',
|
|
\ num, max, bundle.name, 'Error')
|
|
call neobundle#installer#update_log(message, a:is_unite)
|
|
call neobundle#installer#error(bundle.path)
|
|
|
|
call neobundle#installer#error(
|
|
\ (is_timeout ? 'Process timeout.' :
|
|
\ split(a:process.output, '\n')))
|
|
|
|
call add(a:context.source__errored_bundles,
|
|
\ bundle)
|
|
elseif a:process.rev ==# rev
|
|
if updated_time != 0
|
|
let bundle.updated_time = updated_time
|
|
endif
|
|
|
|
call neobundle#installer#log(s:get_skipped_message(
|
|
\ num, max, bundle, '', 'Same revision.'), a:is_unite)
|
|
else
|
|
call neobundle#installer#update_log(
|
|
\ printf('(%'.len(max).'d/%d): |%s| %s',
|
|
\ num, max, bundle.name, 'Updated'), a:is_unite)
|
|
if a:process.rev != ''
|
|
let log_messages = split(
|
|
\ neobundle#installer#get_updated_log_message(
|
|
\ bundle, rev, a:process.rev), '\n')
|
|
let bundle.commit_count = len(log_messages)
|
|
call call((!has('vim_starting') ? 'neobundle#installer#update_log'
|
|
\ : 'neobundle#installer#log'), [
|
|
\ map(log_messages, "printf('|%s| ' .
|
|
\ substitute(v:val, '%', '%%', 'g'), bundle.name)"),
|
|
\ a:is_unite
|
|
\ ])
|
|
else
|
|
let bundle.commit_count = 0
|
|
endif
|
|
|
|
if updated_time == 0
|
|
let updated_time = bundle.checked_time
|
|
endif
|
|
let bundle.updated_time = updated_time
|
|
let bundle.installed_uri = bundle.uri
|
|
let bundle.revisions[updated_time] = rev
|
|
let bundle.old_rev = a:process.rev
|
|
let bundle.new_rev = rev
|
|
if neobundle#installer#build(bundle)
|
|
\ && confirm('Build failed. Uninstall "'
|
|
\ .bundle.name.'" now?', "yes\nNo", 2) == 1
|
|
" Remove.
|
|
call neobundle#commands#clean(1, bundle.name)
|
|
else
|
|
call add(a:context.source__synced_bundles, bundle)
|
|
endif
|
|
endif
|
|
|
|
let bundle.install_rev = rev
|
|
|
|
let a:process.eof = 1
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#lock_revision(process, context, is_unite) abort "{{{
|
|
let num = a:process.number
|
|
let max = a:context.source__max_bundles
|
|
let bundle = a:process.bundle
|
|
|
|
let bundle.new_rev = neobundle#installer#get_revision_number(bundle)
|
|
|
|
let [cmd, message] =
|
|
\ neobundle#installer#get_revision_lock_command(
|
|
\ a:context.source__bang, bundle, num, max)
|
|
|
|
if cmd == '' || bundle.new_rev ==# bundle.rev
|
|
" Skipped.
|
|
return 0
|
|
elseif cmd =~# '^E: '
|
|
" Errored.
|
|
call neobundle#installer#error(bundle.path)
|
|
call neobundle#installer#error(cmd[3:])
|
|
return -1
|
|
endif
|
|
|
|
if bundle.rev != ''
|
|
call neobundle#installer#log(
|
|
\ printf('(%'.len(max).'d/%d): |%s| %s',
|
|
\ num, max, bundle.name, 'Locked'), a:is_unite)
|
|
|
|
call neobundle#installer#log(message, a:is_unite)
|
|
endif
|
|
|
|
let cwd = getcwd()
|
|
try
|
|
" Cd to bundle path.
|
|
call neobundle#util#cd(bundle.path)
|
|
|
|
let result = neobundle#util#system(cmd)
|
|
let status = neobundle#util#get_last_status()
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
|
|
if status
|
|
call neobundle#installer#error(bundle.path)
|
|
call neobundle#installer#error(result)
|
|
return -1
|
|
endif
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_release_revision(bundle, command) abort "{{{
|
|
let cwd = getcwd()
|
|
let rev = ''
|
|
try
|
|
call neobundle#util#cd(a:bundle.path)
|
|
let rev = get(neobundle#util#sort_human(
|
|
\ split(neobundle#util#system(a:command), '\n')), -1, '')
|
|
finally
|
|
call neobundle#util#cd(cwd)
|
|
endtry
|
|
|
|
return rev
|
|
endfunction"}}}
|
|
|
|
function! s:save_install_info(bundles) abort "{{{
|
|
let s:install_info = {}
|
|
for bundle in filter(copy(a:bundles),
|
|
\ "!v:val.local && has_key(v:val, 'updated_time')")
|
|
" Note: Don't save local repository.
|
|
let s:install_info[bundle.name] = {
|
|
\ 'checked_time' : bundle.checked_time,
|
|
\ 'updated_time' : bundle.updated_time,
|
|
\ 'installed_uri' : bundle.installed_uri,
|
|
\ 'installed_path' : bundle.path,
|
|
\ 'revisions' : bundle.revisions,
|
|
\ }
|
|
endfor
|
|
|
|
call neobundle#util#writefile('install_info',
|
|
\ [s:install_info_version, string(s:install_info)])
|
|
|
|
" Save lock file
|
|
call s:save_lockfile(a:bundles)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#_load_install_info(bundles) abort "{{{
|
|
let install_info_path =
|
|
\ neobundle#get_neobundle_dir() . '/.neobundle/install_info'
|
|
if !exists('s:install_info')
|
|
call s:source_lockfile()
|
|
|
|
let s:install_info = {}
|
|
|
|
if filereadable(install_info_path)
|
|
try
|
|
let list = readfile(install_info_path)
|
|
let ver = list[0]
|
|
sandbox let s:install_info = eval(list[1])
|
|
if ver !=# s:install_info_version
|
|
\ || type(s:install_info) != type({})
|
|
let s:install_info = {}
|
|
endif
|
|
catch
|
|
endtry
|
|
endif
|
|
endif
|
|
|
|
call map(a:bundles, "extend(v:val, get(s:install_info, v:val.name, {
|
|
\ 'checked_time' : localtime(),
|
|
\ 'updated_time' : localtime(),
|
|
\ 'installed_uri' : v:val.uri,
|
|
\ 'installed_path' : v:val.path,
|
|
\ 'revisions' : {},
|
|
\}))")
|
|
|
|
return s:install_info
|
|
endfunction"}}}
|
|
|
|
function! s:get_skipped_message(number, max, bundle, prefix, message) abort "{{{
|
|
let messages = [a:prefix . printf('(%'.len(a:max).'d/%d): |%s| %s',
|
|
\ a:number, a:max, a:bundle.name, 'Skipped')]
|
|
if a:message != ''
|
|
call add(messages, a:prefix . a:message)
|
|
endif
|
|
return messages
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#log(msg, ...) abort "{{{
|
|
let msg = neobundle#util#convert2list(a:msg)
|
|
if empty(msg)
|
|
return
|
|
endif
|
|
call extend(s:log, msg)
|
|
|
|
call s:append_log_file(msg)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#update_log(msg, ...) abort "{{{
|
|
let is_unite = get(a:000, 0, 0)
|
|
|
|
if !(&filetype == 'unite' || is_unite)
|
|
call neobundle#util#redraw_echo(a:msg)
|
|
endif
|
|
|
|
call neobundle#installer#log(a:msg)
|
|
|
|
let s:updates_log += neobundle#util#convert2list(a:msg)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#echomsg(msg) abort "{{{
|
|
call neobundle#util#redraw_echomsg(a:msg)
|
|
|
|
call neobundle#installer#log(a:msg)
|
|
|
|
let s:updates_log += neobundle#util#convert2list(a:msg)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#error(msg) abort "{{{
|
|
let msgs = neobundle#util#convert2list(a:msg)
|
|
if empty(msgs)
|
|
return
|
|
endif
|
|
call extend(s:log, msgs)
|
|
call extend(s:updates_log, msgs)
|
|
|
|
call neobundle#util#print_error(msgs)
|
|
call s:append_log_file(msgs)
|
|
endfunction"}}}
|
|
|
|
function! s:append_log_file(msg) abort "{{{
|
|
if g:neobundle#log_filename == ''
|
|
return
|
|
endif
|
|
|
|
let msg = a:msg
|
|
" Appends to log file.
|
|
if filereadable(g:neobundle#log_filename)
|
|
let msg = readfile(g:neobundle#log_filename) + msg
|
|
endif
|
|
|
|
let dir = fnamemodify(g:neobundle#log_filename, ':h')
|
|
if !isdirectory(dir)
|
|
call mkdir(dir, 'p')
|
|
endif
|
|
call writefile(msg, g:neobundle#log_filename)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_log() abort "{{{
|
|
return s:log
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_updates_log() abort "{{{
|
|
return s:updates_log
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#clear_log() abort "{{{
|
|
let s:log = []
|
|
let s:updates_log = []
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_progress_message(bundle, number, max) abort "{{{
|
|
return printf('(%'.len(a:max).'d/%d) [%-20s] %s',
|
|
\ a:number, a:max,
|
|
\ repeat('=', (a:number*20/a:max)), a:bundle.name)
|
|
endfunction"}}}
|
|
|
|
function! neobundle#installer#get_tags_info() abort "{{{
|
|
let path = neobundle#get_neobundle_dir() . '/.neobundle/tags_info'
|
|
if !filereadable(path)
|
|
return []
|
|
endif
|
|
|
|
return readfile(path)
|
|
endfunction"}}}
|
|
|
|
function! s:save_lockfile(bundles) abort "{{{
|
|
let path = neobundle#get_neobundle_dir() . '/NeoBundle.lock'
|
|
let dir = fnamemodify(path, ':h')
|
|
if !isdirectory(dir)
|
|
call mkdir(dir, 'p')
|
|
endif
|
|
|
|
return writefile(sort(map(filter(map(copy(a:bundles),
|
|
\ '[v:val.name, neobundle#installer#get_revision_number(v:val)]'),
|
|
\ "v:val[1] != '' && v:val[1] !~ '\s'"),
|
|
\ "printf('NeoBundleLock %s %s',
|
|
\ escape(v:val[0], ' \'), v:val[1])")), path)
|
|
endfunction"}}}
|
|
|
|
function! s:source_lockfile() abort "{{{
|
|
let path = neobundle#get_neobundle_dir() . '/NeoBundle.lock'
|
|
if filereadable(path)
|
|
execute 'source' fnameescape(path)
|
|
endif
|
|
endfunction"}}}
|
|
|
|
function! s:reload(bundles) abort "{{{
|
|
if empty(a:bundles)
|
|
return
|
|
endif
|
|
|
|
call filter(copy(a:bundles), 'neobundle#config#rtp_add(v:val)')
|
|
|
|
silent! runtime! ftdetect/**/*.vim
|
|
silent! runtime! after/ftdetect/**/*.vim
|
|
silent! runtime! plugin/**/*.vim
|
|
silent! runtime! after/plugin/**/*.vim
|
|
|
|
" Call hooks.
|
|
call neobundle#call_hook('on_post_source', a:bundles)
|
|
endfunction"}}}
|
|
|
|
let s:job_info = {}
|
|
function! s:job_handler(job_id, data, event) abort "{{{
|
|
if !has_key(s:job_info, a:job_id)
|
|
let s:job_info[a:job_id] = {
|
|
\ 'candidates' : [],
|
|
\ 'eof' : 0,
|
|
\ 'status' : -1,
|
|
\ }
|
|
endif
|
|
|
|
let job = s:job_info[a:job_id]
|
|
|
|
if a:event ==# 'exit'
|
|
let job.eof = 1
|
|
let job.status = a:data
|
|
return
|
|
endif
|
|
|
|
let lines = a:data
|
|
|
|
let candidates = job.candidates
|
|
if !empty(lines) && lines[0] != "\n" && !empty(job.candidates)
|
|
" Join to the previous line
|
|
let candidates[-1] .= lines[0]
|
|
call remove(lines, 0)
|
|
endif
|
|
|
|
let candidates += map(lines, "iconv(v:val, 'char', &encoding)")
|
|
endfunction"}}}
|
|
|
|
function! s:async_system(cmd) abort "{{{
|
|
let proc = vimproc#pgroup_open(a:cmd)
|
|
|
|
" Close handles.
|
|
call proc.stdin.close()
|
|
|
|
while !proc.stdout.eof
|
|
if !proc.stderr.eof
|
|
" Print error.
|
|
call neobundle#installer#error(proc.stderr.read_lines(-1, 100))
|
|
endif
|
|
|
|
call neobundle#util#redraw_echo(proc.stdout.read_lines(-1, 100))
|
|
endwhile
|
|
|
|
if !proc.stderr.eof
|
|
" Print error.
|
|
call neobundle#installer#error(proc.stderr.read_lines(-1, 100))
|
|
endif
|
|
|
|
call proc.waitpid()
|
|
endfunction"}}}
|
|
|
|
let &cpo = s:save_cpo
|
|
unlet s:save_cpo
|