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 }