From 9dc04b37c6b131ce054515dcfb9cd7907849a18f Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Wed, 6 Jun 2012 06:06:20 +1100 Subject: [PATCH 1/7] refactored config for git tree-ish support --- autoload/vundle/config.vim | 42 +++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/autoload/vundle/config.vim b/autoload/vundle/config.vim index 55c7d7d0..a1e891b8 100644 --- a/autoload/vundle/config.vim +++ b/autoload/vundle/config.vim @@ -1,15 +1,16 @@ 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[bundle.name] = bundle call s:rtp_add_a() return bundle endf func! vundle#config#init() - if !exists('g:bundles') | let g:bundles = [] | endif + if !exists('g:bundles') | let g:bundles = {} | endif call s:rtp_rm_a() - let g:bundles = [] + let g:bundles = {} endf func! vundle#config#require(bundles) abort @@ -24,25 +25,32 @@ 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 + if(has_key(b, "as")) + let b.original_name = a:name + let b.name = b.as + endif + let b.rtpath = s:rtpath(a:opts) 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' if arg =~? '^\s*\(gh\|github\):\S\+' @@ -66,16 +74,16 @@ 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' + let prepends = join(values(paths), ',') + let appends = join(values(paths), '/after,').'/after' exec 'set rtp-='.fnameescape(prepends) exec 'set rtp-='.fnameescape(appends) 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' + let prepends = join(values(paths), ',') + let appends = join(values(paths), '/after,').'/after' exec 'set rtp^='.fnameescape(prepends) exec 'set rtp+='.fnameescape(appends) endf @@ -98,7 +106,7 @@ 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 = {} +let s:bundle = {'local': 0} func! s:bundle.path() return s:expand_path(g:bundle_dir.'/'.self.name) From 0cd9ab90bb5c55f0c16cb6a3cb65d57129eb535d Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Fri, 8 Jun 2012 23:03:06 +1100 Subject: [PATCH 2/7] further refactored config for git tree-ish support alternate install name can be specified now in name_specs string function vundle#config#require() can now accept both list and dict --- autoload/vundle/config.vim | 62 ++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/autoload/vundle/config.vim b/autoload/vundle/config.vim index a1e891b8..e710a2d6 100644 --- a/autoload/vundle/config.vim +++ b/autoload/vundle/config.vim @@ -1,21 +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 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() - let g:bundles[bundle.name] = 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' @@ -27,16 +36,13 @@ endf func! vundle#config#init_bundle(name, opts) let b = extend(a:opts, copy(s:bundle)) let b.name = a:name - if(has_key(b, "as")) - let b.original_name = a:name - let b.name = b.as - endif - let b.rtpath = s:rtpath(a:opts) + "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 type(a:opts[0]) == type({}) @@ -53,6 +59,13 @@ 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] @@ -69,23 +82,15 @@ func! s:parse_name_spec(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(values(paths), ',') - let appends = join(values(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(values(paths), ',') - let appends = join(values(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 @@ -102,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 = {'local': 0} +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 From b992871153352f728eebcc9ea226e4913d88c027 Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Sat, 9 Jun 2012 01:41:39 +1100 Subject: [PATCH 3/7] Refactored installer for git tree-ish support --- autoload/vundle/installer.vim | 53 +++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index 38a24367..f4309f5e 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -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')) @@ -39,7 +39,7 @@ func! s:process(bang, cmd) setl nomodified endfor - redraw + redraw echo 'Done! '.msg endf @@ -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 @@ -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('') @@ -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)') @@ -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 @@ -203,10 +213,16 @@ 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', '') if isdirectory(git_dir) if !(a:bang) | return 'todate' | endif - let cmd = 'cd '.shellescape(a:bundle.path()).' && git pull' + let cmd = 'cd '.shellescape(a:bundle.path()).' && git checkout master && git pull --ff-only --all' if (has('win32') || has('win64')) let cmd = substitute(cmd, '^cd ','cd /d ','') " add /d switch to change drives @@ -215,6 +231,8 @@ func! s:sync(bang, bundle) abort 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 initial_sha = '' @@ -230,6 +248,19 @@ func! s:sync(bang, bundle) abort return 'error' end + if (!empty(target_treeish)) + let checkout_cmd = 'cd '.shellescape(a:bundle.path()).' && git checkout '.shellescape(target_treeish) + let out = s:system(checkout_cmd) + call s:log('') + call s:log('Checkout tree-ish: '. target_treeish) + call s:log('$ '.checkout_cmd) + call s:log('> '.out) + + if 0 != v:shell_error + return 'error' + end + endif + if empty(initial_sha) return 'new' endif From 96d0734edddbadccb74e76391606f8b0eb69c976 Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Sat, 9 Jun 2012 09:38:09 +1100 Subject: [PATCH 4/7] Update git commands Update git commands for bundle install and upgrade for better git tree-ish support --- autoload/vundle/installer.vim | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index f4309f5e..10f0e78b 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -219,25 +219,29 @@ func! s:sync(bang, bundle) abort return 'todate' endif let git_dir = expand(a:bundle.path().'/.git/', 1) - let target_treeish = get(a:bundle, 'tree-ish', '') + 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 checkout master && git pull --ff-only --all' - - 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 fetch --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) @@ -248,19 +252,6 @@ func! s:sync(bang, bundle) abort return 'error' end - if (!empty(target_treeish)) - let checkout_cmd = 'cd '.shellescape(a:bundle.path()).' && git checkout '.shellescape(target_treeish) - let out = s:system(checkout_cmd) - call s:log('') - call s:log('Checkout tree-ish: '. target_treeish) - call s:log('$ '.checkout_cmd) - call s:log('> '.out) - - if 0 != v:shell_error - return 'error' - end - endif - if empty(initial_sha) return 'new' endif From 65f5edd5dcc00b515268905bf4d19ee8e29111da Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Sun, 10 Jun 2012 23:07:39 +1100 Subject: [PATCH 5/7] Revert changes to git commands for bundle update. Update README --- README.md | 9 ++++++--- autoload/vundle/installer.vim | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9de30cee..17be37f8 100644 --- a/README.md +++ b/README.md @@ -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' @@ -32,13 +33,15 @@ " 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' " ... filetype plugin indent on " required! @@ -131,7 +134,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 diff --git a/autoload/vundle/installer.vim b/autoload/vundle/installer.vim index 10f0e78b..ee2d23ae 100644 --- a/autoload/vundle/installer.vim +++ b/autoload/vundle/installer.vim @@ -226,7 +226,7 @@ func! s:sync(bang, bundle) abort endif if isdirectory(git_dir) if !(a:bang) | return 'todate' | endif - let cmd = cd . shellescape(a:bundle.path()).' && git fetch --all && git checkout '.shellescape(target_treeish) + 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 initial_sha = s:system(get_current_sha)[0:15] From d09f6bb017b485f4406a56c814f146b1a5cd530c Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Sat, 16 Jun 2012 06:24:38 +1100 Subject: [PATCH 6/7] add example of 'local' flag to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 17be37f8..6d599f84 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,8 @@ " 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! " From 900bc9ae43a192093780e7ae5badbcd842aa4ffd Mon Sep 17 00:00:00 2001 From: Aleksey 'Xerkus' Khudyakov Date: Sun, 1 Jul 2012 03:07:39 +1100 Subject: [PATCH 7/7] Added function to check if bundle registered with vundle --- autoload/vundle.vim | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/autoload/vundle.vim b/autoload/vundle.vim index 1ac74e1d..b763f4c6 100644 --- a/autoload/vundle.vim +++ b/autoload/vundle.vim @@ -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