" Tools for use with the mkbuild build environment. " Return the results of a command without the ending newline function! s:chompsys(cmd) return substitute(system(a:cmd), '\n$', '', '') endfunction " Return a list directories contained within an extrefs file at 'dir'. Use " '.' as dir if wanting to find extrefs in the current directory. The " returned list may be empty. Directories returned are not validated. function! s:extrefs(dir) let extdirs = [] let extrefs = a:dir . '/extrefs' if filereadable(extrefs) for e in split(s:chompsys( \ "grep ^git " . extrefs . "| awk '{ print $3 }'")) if !empty(e) call add(extdirs, a:dir . '/' . e) endif endfor endif return extdirs endfunction " Return a list of files found using 'find', recursively, starting at 'dir' function s:filesFromFind(dir) return split(s:chompsys("cd " . a:dir . " 2>/dev/null && find . -type f"), \ '\n') endfunction " If 'dir' is empty, assume the current directory. Assume 'dir' is within a " Git checkout. If true, return a list of tracked files from the Get " repository. Otherwise, return an empty string. function! s:gitTopLevel(dir) return s:chompsys("cd " . a:dir . \ " && git rev-parse --show-toplevel 2>/dev/null") endfunction " 'dir' must either be an empty string or a directory within a Git checkout, " generally its top level directory. Return a list of all tracked files " within the repository starting at 'dir'. function! s:filesFromGit(dir) if empty(a:dir) return [] else return split(s:chompsys("git --git-dir=" . a:dir . "/.git ls-files | " \ . "sed -e s'|^|" . a:dir . "/|'"), '\n') endif endfunction " Return a list of files contained within the directory 'dir'. If 'dir' " belongs to a Git working directory, return all tracked files in the " repository. Otherwise, use find to return the files at the filesystem " subtree starting at 'dir'. " " Additionally, if 'dir' (or instead the Git top-level working directory), " contains an extrefs file, recursively include files from each of its listed " directories. function! s:filesFromDir(dir) let dir = s:gitTopLevel(a:dir) if !empty(dir) let files = s:filesFromGit(dir) else let dir = a:dir let files = s:filesFromFind(dir) endif if !empty(files) let extrefs = dir . '/extrefs' if filereadable(extrefs) for e in split(s:chompsys( \ "grep ^git " . extrefs . "| awk '{ print $3 }'")) if !empty(e) call extend(files, s:filesFromDir(dir . '/' . e)) endif endfor endif endif return files endfunction " Return a list of readable tag files, as present in &tags. This function " doesn't handle the sometimes-default 'tags:/' value I've seen. function! s:tagfiles() let tags = [] for t in split(&tags, ',') if filereadable(t) call add(tags, t) endif endfor return tags endfunction " Return a list of files with full paths, parsed from the named tags (ctags) " file. function! s:filesFromTagsFile(tagfile) return split(s:chompsys("grep -v \"!\" " . a:tagfile . \ " | awk -F\\\t '{ print $2 }' | sort -u"), '\n') endfunction " Return a list of readable filelist files, which are looked for in the same " directories where &tags has vim looking for tags files. function! s:filelistfiles() let files = [] for t in s:tagfiles() let f = substitute(t, '\c\(\.\/\)*tags.*$', 'filelist', '') if filereadable(f) call add(files, f) endif endfor return files endfunction " Return a list of files with full paths, parsed from the named filelist file. function! s:filesFromFilelistFile(filelist) return split(s:chompsys("cat " . a:filelist), '\n') endfunction " Return a list of all project files. Where possible, use tracked files from " the project Git repository, else collect all files. Also follow 'extrefs' " files to additional, external sources. function! mkbuild#allFiles() return s:filesFromDir('.') endfunction " Return the subset of project files used in the build referenced by the " directory defined in the 'tags' variable. Use the mkbuild filelist, if " available, or fall back to extracting files from the tags file. If no " source of filelist or tags files are available, revert to returning all " proejct files. function! mkbuild#buildFiles() let files = [] let flfiles = s:filelistfiles() if !empty(flfiles) for f in flfiles call extend(files, s:filesFromFilelistFile(f)) endfor else let tagfiles = s:tagfiles() if !empty(tagfiles) for t in tags call extend(files, s:filesFromTagsFile(t)) endfor else call extend(files, s:filesFromDir('.')) endif endif return files endfunction