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.process : execute;
32 import std.experimental.logger;
33 
34 enum MIRROR = "./.mirror";
35 
36 string getFolderName(string name, string v) {
37    import std.path : buildPath;
38 
39    return buildPath(MIRROR, name ~ "-" ~ v);
40 }
41 
42 unittest {
43    string f = getFolderName("cul", "0.1.0");
44    assert(f == "./.mirror/cul-0.1.0", f);
45 }
46 
47 string[] getCloneCmd(string url, string branch, string folder) {
48    string[] a = ["git", "clone", "--depth", "1"];
49    a ~= "--branch";
50    a ~= "v" ~ branch;
51    a ~= url;
52    a ~= folder;
53 
54    return a;
55 }
56 
57 unittest {
58    string[] x = getCloneCmd("git@o30", "0.13.0", "cul");
59    assert(x[0] == "git");
60    assert(x[5] == "v0.13.0");
61 }
62 
63 void run(bool clean) {
64    import std.array : join;
65    import std.file : readText, exists, mkdirRecurse, rmdirRecurse;
66    import std..string : startsWith;
67    import std.json : parseJSON, JSONValue;
68 
69    string depJ = readText("localdep.json");
70    JSONValue dubConfig = parseJSON(depJ);
71 
72    foreach (dep; dubConfig.array) {
73       writeln(dep["name"].get!string);
74       string v = dep["version"].get!string;
75       if (v.startsWith("v")) {
76          v = v[1 .. $];
77       }
78 
79       string f = getFolderName(dep["name"].get!string, v);
80       if (clean) {
81          tracef("Remove %s dir", f);
82          f.rmdirRecurse;
83          return;
84       }
85 
86       if (!exists(f)) {
87          f.mkdirRecurse;
88 
89          string[] cmd = getCloneCmd(dep["url"].get!string, v, f);
90          trace(cmd.join(" "));
91          auto reply = execute(cmd);
92          if (reply.status != 0) {
93             errorf("Failed\n", reply.output);
94          } else {
95             info("Successful");
96          }
97       }
98    }
99 }
100 
101 void main(string[] args) {
102    import std.getopt;
103 
104    bool verbose;
105    bool clean;
106 
107    auto opt = getopt(args, "verbose|v", "Verbose", &verbose, "clean|c", "Delete package directory", &clean);
108    if (verbose) {
109       globalLogLevel(LogLevel.trace);
110    } else {
111       globalLogLevel(LogLevel.error);
112    }
113    if (opt.helpWanted) {
114       defaultGetoptPrinter("dirimere", opt.options);
115       help;
116    } else {
117       run(clean);
118    }
119 }
120 
121 void help() {
122    import std.stdio : writefln;
123    enum VERSION = "0.1.0";
124    writefln("Version %s", VERSION);
125 }