1 /* 2 * Copyright (c) 2020 Orfeo Da Vià 3 * 4 * Boost Software License - Version 1.0 - August 17th, 2003 5 * 6 * Permission is hereby granted, free of charge, to any person or organization 7 * obtaining a copy of the software and accompanying documentation covered by 8 * this license (the "Software") to use, reproduce, display, distribute, 9 * execute, and transmit the Software, and to prepare derivative works of the 10 * Software, and to permit third-parties to whom the Software is furnished to 11 * do so, all subject to the following: 12 * 13 * The copyright notices in the Software and this entire statement, including 14 * the above license grant, this restriction and the following disclaimer, 15 * must be included in all copies of the Software, in whole or in part, and 16 * all derivative works of the Software, unless such copies or derivative 17 * works are solely in the form of machine-executable object code generated by 18 * a source language processor. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 23 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 24 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28 29 module app; 30 31 import std.stdio : writefln, writeln; 32 import std.experimental.logger; 33 import std.json : JSONValue; 34 35 enum MIRROR = "./.dirimere"; 36 37 void main(string[] args) { 38 import std.getopt; 39 40 bool verbose; 41 bool clean; 42 string proxyFile = "dirimere.json"; 43 44 auto opt = getopt(args, "verbose|v", "Verbose", &verbose, 45 "clean|c", "Delete package directory", &clean, 46 "proxyFile|i", "The filename of the file to search packages in", &proxyFile, 47 ); 48 if (verbose) { 49 globalLogLevel(LogLevel.trace); 50 } else { 51 globalLogLevel(LogLevel.info); 52 } 53 if (opt.helpWanted) { 54 defaultGetoptPrinter("dirimere", opt.options); 55 help; 56 } else { 57 JSONValue j = makeJson(proxyFile); 58 trace(j); 59 run(j, clean); 60 } 61 } 62 63 JSONValue makeJson(string fn) { 64 import std.file : readText; 65 import std.json : parseJSON; 66 string depJ = readText(fn); 67 return parseJSON(depJ); 68 } 69 70 void run(JSONValue dubConfig, bool clean) { 71 import std.array : join; 72 import std.file : exists, mkdirRecurse, rmdirRecurse; 73 import std.process : execute; 74 75 foreach (dep; dubConfig.array) { 76 string v = dep["version"].get!string.getVersion; 77 string name = dep["name"].get!string; 78 string f = getFolderName(name, v); 79 if (clean) { 80 writefln("Remove %s", f); 81 f.rmdirRecurse; 82 } 83 84 if (!exists(f)) { 85 f.mkdirRecurse; 86 87 string[] cmd = getCloneCmd(dep["url"].get!string, v, f); 88 trace(cmd.join(" ")); 89 writefln("Clone %s version %s", name, v); 90 91 auto reply = execute(cmd); 92 if (reply.status != 0) { 93 writeln("Failed\n", reply.output); 94 } else { 95 writeln("Successful"); 96 } 97 } else { 98 writeln("None to do"); 99 } 100 } 101 } 102 103 string getVersion(string v) { 104 import std..string : startsWith; 105 if (v.startsWith("v")) { 106 return v[1 .. $]; 107 } else { 108 return v; 109 } 110 } 111 112 unittest { 113 assert("v1.2.3".getVersion == "1.2.3"); 114 assert("2.2.3".getVersion == "2.2.3"); 115 } 116 117 string getFolderName(string name, string v) { 118 import std.path : buildPath; 119 120 return buildPath(MIRROR, name ~ "-" ~ v); 121 } 122 123 unittest { 124 string f = getFolderName("cul", "0.1.0"); 125 assert(f == "./.mirror/cul-0.1.0", f); 126 } 127 128 string[] getCloneCmd(string url, string branch, string folder) { 129 string[] a = ["git", "clone", "--depth", "1"]; 130 a ~= "--branch"; 131 a ~= "v" ~ branch; 132 a ~= url; 133 a ~= folder; 134 135 return a; 136 } 137 138 unittest { 139 string[] x = getCloneCmd("git@o30", "0.13.0", "cul"); 140 assert(x[0] == "git"); 141 assert(x[5] == "v0.13.0"); 142 } 143 144 145 bool isValidCsFile(in string fn) { 146 import std.algorithm.searching : canFind; 147 enum ASSEMBLY = "Assembly"; 148 enum TEST = "test"; 149 enum APP = "App"; 150 return !(canFind(fn, ASSEMBLY) || canFind(fn, TEST) || canFind(fn, APP)); 151 } 152 unittest { 153 assert(isValidCsFile(".mirror/Uns/src/Cul.cs")); 154 assert(!isValidCsFile(".mirror/Uns/src/App.cs")); 155 assert(!isValidCsFile(".mirror/Uns/src/AssemblyInfo.cs")); 156 assert(!isValidCsFile(".mirror/Uns/src/IAssemblyInfo.cs")); 157 assert(!isValidCsFile(".mirror/Uns/test/Cul.cs")); 158 assert(!isValidCsFile(".mirror/Uns/tests/Cul.cs")); 159 } 160 161 void help() { 162 enum VERSION = "0.5.0"; 163 writefln("Version %s", VERSION); 164 }