1 module repo; 2 3 import std.array; 4 import std.algorithm; 5 import std.exception; 6 import std.file; 7 import std.parallelism : parallel; 8 import std.path; 9 import std.process; 10 import std.range; 11 import std.regex; 12 import std..string; 13 14 import ae.sys.file; 15 import ae.sys.d.manager; 16 17 import common; 18 import config : config, opts; 19 import custom : parseSpec; 20 21 //alias BuildConfig = DManager.Config.Build; 22 23 final class DiggerManager : DManager 24 { 25 this() 26 { 27 this.config.build = cast().config.build; 28 this.config.local = cast().config.local; 29 this.verifyWorkTree = true; 30 } 31 32 override void log(string s) 33 { 34 common.log(s); 35 } 36 37 void logProgress(string s) 38 { 39 log((" " ~ s ~ " ").center(70, '-')); 40 } 41 42 override SubmoduleState parseSpec(string spec) 43 { 44 return .parseSpec(spec); 45 } 46 47 override MetaRepository getMetaRepo() 48 { 49 if (!repoDir.exists) 50 log("First run detected.\nPlease be patient, " ~ 51 "cloning everything might take a few minutes...\n"); 52 return super.getMetaRepo(); 53 } 54 55 override string getCallbackCommand() 56 { 57 return escapeShellFileName(thisExePath) ~ " do callback"; 58 } 59 60 string[string] getBaseEnvironment() 61 { 62 return d.baseEnvironment.vars; 63 } 64 65 bool haveUpdate; 66 67 void needUpdate() 68 { 69 if (!haveUpdate) 70 { 71 d.update(); 72 haveUpdate = true; 73 } 74 } 75 } 76 77 DiggerManager d; 78 79 static this() 80 { 81 d = new DiggerManager(); 82 } 83 84 string parseRev(string rev) 85 { 86 auto args = ["log", "--pretty=format:%H"]; 87 88 // git's approxidate accepts anything, so a disambiguating prefix is required 89 if (rev.canFind('@') && !rev.canFind("@{")) 90 { 91 auto parts = rev.findSplit("@"); 92 auto at = parts[2].strip(); 93 if (at.startsWith("#")) // For the build-all command - skip this many commits 94 args ~= ["--skip", at[1..$]]; 95 else 96 args ~= ["--until", at]; 97 rev = parts[0].strip(); 98 } 99 100 if (rev.empty) 101 rev = "origin/master"; 102 103 d.needUpdate(); 104 105 auto metaRepo = d.getMetaRepo(); 106 metaRepo.needRepo(); 107 auto repo = &metaRepo.git; 108 109 try 110 return repo.query(args ~ ["-n", "1", "origin/" ~ rev]); 111 catch (Exception e) 112 try 113 return repo.query(args ~ ["-n", "1", rev]); 114 catch (Exception e) 115 {} 116 117 auto grep = repo.query("log", "-n", "2", "--pretty=format:%H", "--grep", rev, "origin/master").splitLines(); 118 if (grep.length == 1) 119 return grep[0]; 120 121 auto pickaxe = repo.query("log", "-n", "3", "--pretty=format:%H", "-S" ~ rev, "origin/master").splitLines(); 122 if (pickaxe.length && pickaxe.length <= 2) // removed <- added 123 return pickaxe[$-1]; // the one where it was added 124 125 throw new Exception("Unknown/ambiguous revision: " ~ rev); 126 }