1 module more.repos; 2 3 import std.array; 4 import std.path; 5 import std.file; 6 7 import core.stdc.stdlib : alloca; 8 9 import more.fields; 10 import more.path; 11 12 immutable gitDir = ".git"; 13 14 /** 15 Checks to see if the given path is inside a git repo. 16 It does this by checking for the '.git' directory in the given directory and every 17 parent directory. 18 Returns: The path to the root of the git repo, or null if not inside a git repo. 19 */ 20 string insideGitRepo(string path = getcwd()) nothrow @nogc 21 { 22 auto pathBuffer = cast(char*)alloca(path.length + 1 + gitDir.length); 23 24 char[] addGitDir(size_t s) nothrow @nogc 25 { 26 if(pathBuffer[s-1] == dirSeparator[0]) { 27 pathBuffer[s..s+gitDir.length] = gitDir; 28 return pathBuffer[0..s+gitDir.length]; 29 } else { 30 pathBuffer[s] = dirSeparator[0]; 31 pathBuffer[s+1..s+1+gitDir.length] = gitDir; 32 return pathBuffer[0..s+1+gitDir.length]; 33 } 34 } 35 36 pathBuffer[0..path.length] = path; 37 auto gitPath = addGitDir(path.length); 38 39 while(true) { 40 auto currentDir = gitPath[0..$-gitDir.length-1]; 41 42 if(exists(gitPath)) { 43 return path[0..currentDir.length]; 44 } 45 46 auto newCheckPath = parentDir(currentDir); 47 if(newCheckPath.length == currentDir.length) { 48 return null; 49 } 50 51 gitPath = addGitDir(newCheckPath.length); 52 } 53 } 54 55 struct Repo 56 { 57 string localPath; 58 //string keyPath; // 59 60 string globMatcher; 61 62 void setupGlobMatcher() 63 { 64 this.globMatcher = localPath; 65 } 66 bool contains(string file) { 67 if(globMatcher is null) { 68 setupGlobMatcher(); 69 } 70 return globMatch(globMatcher, file); 71 } 72 } 73 74 struct RepoSet 75 { 76 Appender!(Repo[]) repos; 77 78 bool pathBelongsToKnownRepo(string path, ref Repo foundRepo) { 79 foreach(repo; repos.data) { 80 if(repo.contains(path)) { 81 foundRepo = repo; 82 return true; 83 } 84 } 85 return false; 86 } 87 } 88 RepoSet knownRepos; 89 90 91 /** 92 Find Repo Algorithm: 93 1. Check if you are inside a git repository, if you are get out. 94 2. search the given directory for sub directories with the same name as the repo. 95 If the repo name matches, it checks if it is a repo, if it is, then the repo is found. 96 3. It checks for a file named "repos". If it exists it reads the file and searches to 97 see if it contains the definition for the repo. 98 4. It goes through every parent directory checking the sub directories again for the repo name. 99 */ 100 Repo findRepo(string repoName, string path = null) 101 { 102 if(path.length <= 0) { 103 path = getcwd(); 104 } else { 105 106 } 107 108 Repo currentRepo; 109 110 111 112 if(knownRepos.pathBelongsToKnownRepo(path, currentRepo)) { 113 path = currentRepo.localPath; 114 } 115 116 117 118 return Repo(); 119 /+ 120 121 122 foreach(entry; dirEntries(path, SpanMode.shallow)) { 123 if( 124 } 125 +/ 126 }