Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

branches/tags/commit hashes support #189

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()

" format: Bundle (git_url)|([vendor/]name)[ as alternate_install_name][, tree-ish][, {options}]
" let Vundle manage Vundle
" required!
Bundle 'gmarik/vundle'
Expand All @@ -32,14 +33,18 @@
" original repos on github
Bundle 'tpope/vim-fugitive'
Bundle 'Lokaltog/vim-easymotion'
Bundle 'rstacruz/sparkup', {'rtp': 'vim/'}
Bundle 'tpope/vim-rails.git'
" vim-scripts repos
Bundle 'L9'
Bundle 'FuzzyFinder'
" non github repos
Bundle 'git://git.wincent.com/command-t.git'
" alternate install name
Bundle 'rstacruz/sparkup as sparky', {'rtp': 'vim/'}
" specific tree-ish, in this case commit hash
Bundle 'tpope/vim-rails.git', '257bed767d589e2fcda59732d79fc871365cb0ef'
" ...
" option 'local': 1 tells Vundle not to install/update this bundle, but still register its resources.
" Bundle 'some-local-bundle', {'local': 1}

filetype plugin indent on " required!
"
Expand Down Expand Up @@ -131,7 +136,7 @@ see [wiki](/gmarik/vundle/wiki)
* √ put vundle to bundles/ too(will fix vundle help)
* √ tests
* √ improve error handling
* allow specify revision/version?
* allow specify git tree-ish (commit/branch/tag)
* handle dependencies
* show description in search results
* search by description as well
Expand Down
4 changes: 4 additions & 0 deletions autoload/vundle.vim
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ func! vundle#rc(...) abort
let g:vundle_changelog = ['Updated Bundles:']
call vundle#config#init()
endf

func! vundle#hasBundle(bundle_install_name)
return exists('g:bundles') && has_key(g:bundles, a:bundle_install_name)
endf
76 changes: 44 additions & 32 deletions autoload/vundle/config.vim
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
func! vundle#config#init()
if !exists('g:bundles') | let g:bundles = {} | endif
call s:rtp_rm_a()
let g:bundles = {}
endf

func! vundle#config#bundle(arg, ...)
let bundle = vundle#config#init_bundle(a:arg, a:000)
let opts = extend(s:parse_options(a:000), s:parse_name_spec(a:arg))
let bundle = vundle#config#init_bundle(opts.name,opts)
call s:rtp_rm_a()
call add(g:bundles, bundle)
let g:bundles[opts.name] = bundle
call s:rtp_add_a()
return bundle
endf

func! vundle#config#init()
if !exists('g:bundles') | let g:bundles = [] | endif
call s:rtp_rm_a()
let g:bundles = []
func! vundle#config#parse_name_spec(arg)
return s:parse_name_spec(a:arg)
endf

func! vundle#config#require(bundles) abort
for b in a:bundles
call s:rtp_add(b.rtpath)
if type(a:bundles) == type({})
let bundles = values(a:bundles)
else
let bundles = a:bundles
endif
for b in bundles
call s:rtp_add(b.rtpath())
call s:rtp_add(g:bundle_dir)
" TODO: it has to be relative rtpath, not bundle.name
exec 'runtime! '.b.name.'/plugin/*.vim'
Expand All @@ -24,27 +34,38 @@ func! vundle#config#require(bundles) abort
endf

func! vundle#config#init_bundle(name, opts)
let opts = extend(s:parse_options(a:opts), s:parse_name(substitute(a:name,"['".'"]\+','','g')))
let b = extend(opts, copy(s:bundle))
let b.rtpath = s:rtpath(opts)
let b = extend(a:opts, copy(s:bundle))
let b.name = a:name
"make sure keys for these options exist
let b.name_spec = get(b, 'name_spec', a:name)
let b.uri = get(b, 'uri', '')
return b
endf

func! s:parse_options(opts)
" TODO: improve this
if len(a:opts) != 1 | return {} | endif
if len(a:opts) < 1 | return {} | endif

if type(a:opts[0]) == type({})
return a:opts[0]
else
return {'rev': a:opts[0]}
endif
let opts = {'tree-ish': a:opts[0]}
if len(a:opts) >= 2 && type(a:opts[1]) == type({})
let opts = extend(a:opts[1], opts)
endif
return opts
endf

func! s:parse_name(arg)
let arg = a:arg
func! s:parse_name_spec(arg)
let arg = substitute(a:arg,"['".'"]\+','','g')
let git_proto = exists('g:vundle_default_git_proto') ? g:vundle_default_git_proto : 'https'

let altname = ''
let name_spec = arg
if arg =~? ' as '
let altname = split(arg, ' as ')[-1]
let arg = split(arg, ' as ')[0]
endif

if arg =~? '^\s*\(gh\|github\):\S\+'
\ || arg =~? '^[a-z0-9][a-z0-9-]*/[^/]\+$'
let uri = git_proto.'://github.com/'.split(arg, ':')[-1]
Expand All @@ -61,23 +82,15 @@ func! s:parse_name(arg)
let name = arg
let uri = git_proto.'://github.com/vim-scripts/'.name.'.git'
endif
return {'name': name, 'uri': uri, 'name_spec': arg }
return {'name': empty(altname) ? name : altname, 'uri': uri, 'name_spec': name_spec }
endf

func! s:rtp_rm_a()
let paths = map(copy(g:bundles), 'v:val.rtpath')
let prepends = join(paths, ',')
let appends = join(paths, '/after,').'/after'
exec 'set rtp-='.fnameescape(prepends)
exec 'set rtp-='.fnameescape(appends)
call filter(values(g:bundles), 's:rtp_rm(v:val.rtpath())')
endf

func! s:rtp_add_a()
let paths = map(copy(g:bundles), 'v:val.rtpath')
let prepends = join(paths, ',')
let appends = join(paths, '/after,').'/after'
exec 'set rtp^='.fnameescape(prepends)
exec 'set rtp+='.fnameescape(appends)
call filter(reverse(values(g:bundles)), 's:rtp_add(v:val.rtpath())')
endf

func! s:rtp_rm(dir) abort
Expand All @@ -94,13 +107,12 @@ func! s:expand_path(path) abort
return simplify(expand(a:path, 1))
endf

func! s:rtpath(opts)
return has_key(a:opts, 'rtp') ? s:expand_path(a:opts.path().'/'.a:opts.rtp) : a:opts.path()
endf

let s:bundle = {}

func! s:bundle.path()
return s:expand_path(g:bundle_dir.'/'.self.name)
endf

func! s:bundle.rtpath()
return has_key(self, 'rtp') ? s:expand_path(self.path().'/'.self.rtp) : self.path()
endf
56 changes: 39 additions & 17 deletions autoload/vundle/installer.vim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ func! vundle#installer#new(bang, ...) abort
\ g:bundles :
\ map(copy(a:000), 'vundle#config#bundle(v:val, {})')

let names = vundle#scripts#bundle_names(map(copy(bundles), 'v:val.name_spec'))
let names = vundle#scripts#bundle_names(map(values(bundles), 'v:val.name_spec'))
call vundle#scripts#view('Installer',['" Installing bundles to '.expand(g:bundle_dir, 1)], names + ['Helptags'])

call s:process(a:bang, (a:bang ? 'add!' : 'add'))
Expand Down Expand Up @@ -39,7 +39,7 @@ func! s:process(bang, cmd)
setl nomodified
endfor

redraw
redraw
echo 'Done! '.msg
endf

Expand Down Expand Up @@ -89,18 +89,27 @@ func! s:sign(status)
exe ":sign place ".line('.')." line=".line('.')." name=Vu_". a:status ." buffer=" . bufnr("%")
endf

func! vundle#installer#install_and_require(bang, name) abort
let result = vundle#installer#install(a:bang, a:name)
let b = vundle#config#bundle(a:name, {})
func! vundle#installer#install_and_require(bang, name_spec) abort
let result = vundle#installer#install(a:bang, a:name_spec)
let opts = vundle#config#parse_name_spec(a:name_spec)
if !has_key(g:bundles, opts.name)
\ || g:bundles[opts.name].name_spec != opts.name_spec
let b = vundle#config#bundle(opts.name, opts)
endif
call vundle#installer#helptags([b])
call vundle#config#require([b])
return result
endf

func! vundle#installer#install(bang, name) abort
func! vundle#installer#install(bang, name_spec) abort
if !isdirectory(g:bundle_dir) | call mkdir(g:bundle_dir, 'p') | endif

let b = vundle#config#init_bundle(a:name, {})
let opts = vundle#config#parse_name_spec(a:name_spec)
if has_key(g:bundles, opts.name)
\ && g:bundles[opts.name].name_spec == opts.name_spec
let b = g:bundles[opts.name]
else
let b = vundle#config#init_bundle(opts.name, opts)
endif

return s:sync(a:bang, b)
endf
Expand All @@ -111,7 +120,7 @@ func! vundle#installer#docs() abort
endf

func! vundle#installer#helptags(bundles) abort
let bundle_dirs = map(copy(a:bundles),'v:val.rtpath')
let bundle_dirs = map(values(a:bundles),'v:val.rtpath()')
let help_dirs = filter(bundle_dirs, 's:has_doc(v:val)')

call s:log('')
Expand All @@ -133,7 +142,7 @@ endf


func! vundle#installer#clean(bang) abort
let bundle_dirs = map(copy(g:bundles), 'v:val.path()')
let bundle_dirs = map(values(g:bundles), 'v:val.path()')
let all_dirs = v:version >= 702 ? split(globpath(g:bundle_dir, '*', 1), "\n") : split(globpath(g:bundle_dir, '*'), "\n")
let x_dirs = filter(all_dirs, '0 > index(bundle_dirs, v:val)')

Expand All @@ -158,6 +167,7 @@ func! vundle#installer#clean(bang) abort
call s:process(a:bang, 'D')
endif
endif
"TODO add checks to ensure bundle's remote origin is same as specified uri
endf


Expand Down Expand Up @@ -203,23 +213,35 @@ func! s:helptags(rtp) abort
endf

func! s:sync(bang, bundle) abort
"bundle dev friendly:
"if bundle has local flag - skip it as it's files is not managed by vundle
if get(a:bundle, 'local', 0) == 1
return 'todate'
endif
let git_dir = expand(a:bundle.path().'/.git/', 1)
let target_treeish = get(a:bundle, 'tree-ish', 'master')
let cd = 'cd '
if (has('win32') || has('win64'))
let cd = 'cd /d ' " add /d switch to change drives
endif
if isdirectory(git_dir)
if !(a:bang) | return 'todate' | endif
let cmd = 'cd '.shellescape(a:bundle.path()).' && git pull'

if (has('win32') || has('win64'))
let cmd = substitute(cmd, '^cd ','cd /d ','') " add /d switch to change drives
let cmd = '"'.cmd.'"' " enclose in quotes
endif
let cmd = cd . shellescape(a:bundle.path()).' && git checkout master && git pull --ff-only --all && git checkout '.shellescape(target_treeish)

let get_current_sha = 'cd '.shellescape(a:bundle.path()).' && git rev-parse HEAD'
let get_current_sha = cd . shellescape(a:bundle.path()).' && git rev-parse HEAD'
let initial_sha = s:system(get_current_sha)[0:15]
"make sure non-hash will not be accidentally matched
if (len(target_treeish) > 5 && stridx(initial_sha, target_treeish) == 0) | return 'todate' | endif
else
let cmd = 'git clone '.a:bundle.uri.' '.shellescape(a:bundle.path())
let cmd .= ' && '. cd . shellescape(a:bundle.path()).' && git checkout '.shellescape(target_treeish)
let initial_sha = ''
endif

if (has('win32') || has('win64'))
let cmd = '"'.cmd.'"' " enclose in quotesi
endif

let out = s:system(cmd)
call s:log('')
call s:log('Bundle '.a:bundle.name_spec)
Expand Down