1 module more.repos; 2 3 import std.array; 4 import std.path : dirSeparator, globMatch; 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 { 28 pathBuffer[s..s+gitDir.length] = gitDir; 29 return pathBuffer[0..s+gitDir.length]; 30 } 31 else 32 { 33 pathBuffer[s] = dirSeparator[0]; 34 pathBuffer[s+1..s+1+gitDir.length] = gitDir; 35 return pathBuffer[0..s+1+gitDir.length]; 36 } 37 } 38 39 pathBuffer[0..path.length] = path; 40 auto gitPath = addGitDir(path.length); 41 42 while(true) 43 { 44 auto currentDir = gitPath[0..$-gitDir.length-1]; 45 //import core.stdc.stdio; 46 //printf("checking '%.*s'\n", gitPath.length, gitPath.ptr); 47 if(exists(gitPath)) 48 { 49 return path[0..currentDir.length]; 50 } 51 52 auto newCheckPath = parentDir(currentDir); 53 if(newCheckPath.length == currentDir.length) 54 { 55 return null; 56 } 57 58 gitPath = addGitDir(newCheckPath.length); 59 } 60 } 61 62 struct Repo 63 { 64 string localPath; 65 //string keyPath; // 66 67 string globMatcher; 68 69 void setupGlobMatcher() 70 { 71 this.globMatcher = localPath; 72 } 73 bool contains(string file) 74 { 75 if(globMatcher is null) 76 { 77 setupGlobMatcher(); 78 } 79 return globMatch(globMatcher, file); 80 } 81 } 82 83 struct RepoSet 84 { 85 Appender!(Repo[]) repos; 86 87 bool pathBelongsToKnownRepo(string path, ref Repo foundRepo) 88 { 89 foreach(repo; repos.data) 90 { 91 if(repo.contains(path)) 92 { 93 foundRepo = repo; 94 return true; 95 } 96 } 97 return false; 98 } 99 } 100 RepoSet knownRepos; 101 102 /** 103 Find Repo Algorithm: 104 1. Check if you are inside a git repository, if you are get out. 105 2. search the given directory for sub directories with the same name as the repo. 106 If the repo name matches, it checks if it is a repo, if it is, then the repo is found. 107 3. It checks for a file named "repos". If it exists it reads the file and searches to 108 see if it contains the definition for the repo. 109 4. It goes through every parent directory checking the sub directories again for the repo name. 110 */ 111 Repo findRepo(string repoName, string path = null) 112 { 113 if(path.length <= 0) 114 { 115 path = getcwd(); 116 } 117 else 118 { 119 120 } 121 122 Repo currentRepo; 123 124 if(knownRepos.pathBelongsToKnownRepo(path, currentRepo)) 125 { 126 path = currentRepo.localPath; 127 } 128 129 130 131 return Repo(); 132 /+ 133 134 135 foreach(entry; dirEntries(path, SpanMode.shallow)) { 136 if( 137 } 138 +/ 139 }