1 /++ 2 + Copyright: Copyright © 2018, Christian Köstlin 3 + License: MIT 4 + Authors: Christian Koestlin 5 +/ 6 module app; 7 8 import std.stdio; 9 import std..string; 10 import std.process; 11 import std.file; 12 import std.path; 13 import std.file; 14 import std.regex; 15 import std.experimental.logger; 16 17 void writeContent(string file, string content) 18 { 19 file.dirName.mkdirRecurse; 20 std.file.write(file, content); 21 } 22 23 auto getFromDubSdl(string path, string what) 24 { 25 try 26 { 27 auto pattern = "^%1$s \"(?P<%1$s>.*)\"$".format(what); 28 auto text = readText(path); 29 auto match = matchFirst(text, regex(pattern, "m")); 30 if (match.empty) 31 { 32 return null; 33 } 34 return match[what]; 35 } 36 catch (FileException e) 37 { 38 trace(e); 39 return null; 40 } 41 } 42 43 auto getFromDubJson(string path, string what) 44 { 45 try 46 { 47 import std.json; 48 49 auto json = parseJSON(readText(path)); 50 return json[what].str; 51 } 52 catch (FileException e) 53 { 54 trace(e); 55 return null; 56 } 57 } 58 59 auto packageDir() 60 { 61 import std.process; 62 63 auto e = std.process.environment.toAA; 64 if ("DUB_PACKAGE_DIR" !in e) 65 { 66 return null; 67 } 68 return e["DUB_PACKAGE_DIR"]; 69 } 70 71 auto getFromDubJsonFromPackageDir() 72 { 73 if (string pd = packageDir) 74 { 75 return getFromDubJson(pd ~ "/dub.json", "version"); 76 } 77 return null; 78 } 79 80 string getFromDubSdlFromPackageDir() 81 { 82 if (string pd = packageDir) 83 { 84 return getFromDubSdl(pd ~ "/dub.sdl", "version"); 85 } 86 return null; 87 } 88 89 string getFromGit() 90 { 91 auto gitCommand = ["git", "describe", "--dirty"].execute(null, Config.none, 92 size_t.max, packageDir); 93 if (gitCommand.status != 0) 94 { 95 "Cannot get version with git describe --dirty, make sure you have at least one annotated tag" 96 .info; 97 return null; 98 } 99 100 return gitCommand.output.strip; 101 } 102 103 string getVersion() 104 { 105 if (string res = getFromDubJsonFromPackageDir) 106 { 107 "Using version from dub.json '%s'".format(res).warning; 108 return res; 109 } 110 if (string res = getFromDubSdlFromPackageDir) 111 { 112 "Using version from dub.sdl '%s'".format(res).warning; 113 return res; 114 } 115 if (string res = getFromGit) 116 { 117 "Using version from git '%s'".format(res).warning; 118 return res; 119 } 120 throw new Exception("Cannot determine version"); 121 } 122 123 int main(string[] args) 124 { 125 import std.getopt; 126 127 string packageName; 128 auto info = getopt(args, "packageName", &packageName); 129 if (info.helpWanted) 130 { 131 defaultGetoptPrinter("packageversion %s. Generate or update a simple packageversion module.".format("v0.0.11"), 132 info.options); 133 return 0; 134 } 135 if (packageName == null) 136 { 137 defaultGetoptPrinter("Packagename required.", info.options); 138 return 1; 139 } 140 141 auto versionText = getVersion(); 142 143 auto file = "out/generated/packageversion/" ~ packageName.replace(".", 144 "/") ~ "/packageversion.d"; 145 auto moduleText = "module %s.packageversion;\n".format(packageName); 146 auto packageVersionText = "const PACKAGE_VERSION = \"%s\";\n".format(versionText); 147 auto registerVersionText = "static this()\n{\n import packageversion;\n packageversion.registerPackageVersion(\"%s\", \"%s\");\n}\n" 148 .format(packageName, versionText); 149 auto totalText = moduleText ~ packageVersionText ~ registerVersionText; 150 151 if (exists(file)) 152 { 153 auto content = file.readText; 154 if (content != totalText) 155 { 156 "Updating packageversion module".warning; 157 file.writeContent(totalText); 158 } 159 } 160 else 161 { 162 "Writing packageversion module".warning; 163 file.writeContent(totalText); 164 } 165 return 0; 166 }