1 /// Generates a D module for package version info. 2 module genPackageVersion.genDModule; 3 4 import std.array; 5 import scriptlike.only; 6 7 import genPackageVersion.util; 8 import genPackageVersion.packageVersion; 9 10 /// Returns path to the output file that was (or would've been) written. 11 string generateDModule(string packageName, string moduleName, 12 string ver, string timestamp, string timestampIso, string dubExtras) 13 { 14 // Generate D source code 15 auto dModule = 16 `/++ 17 Generated at `~timestamp~` 18 by gen-package-version `~packageVersion~`: 19 $(LINK https://github.com/Abscissa/gen-package-version) 20 +/ 21 module `~outPackageName~`.`~outModuleName~`; 22 23 /++ 24 Version of this package. 25 +/ 26 enum packageVersion = "`~ver~`"; 27 28 /++ 29 Human-readable timestamp of when this module was generated. 30 +/ 31 enum packageTimestamp = "`~timestamp~`"; 32 33 /++ 34 Timestamp of when this module was generated, as an ISO Ext string. 35 Get a SysTime from this via: 36 37 ------ 38 std.datetime.fromISOExtString(packageTimestampISO) 39 ------ 40 +/ 41 enum packageTimestampISO = "`~timestampIso~`"; 42 `~dubExtras; 43 //logTrace("--------------------------------------"); 44 //logTrace(dModule); 45 //logTrace("--------------------------------------"); 46 47 import std.path : stdBuildPath = buildPath, stdDirName = dirName, dirSeparator; 48 import scriptlike.file : scriptlikeRead = read, scriptlikeWrite = write; 49 50 // Determine output filepath 51 auto packagePath = outPackageName.replace(".", dirSeparator); 52 auto outPath = stdBuildPath(projectSourcePath, packagePath, outModuleName) ~ ".d"; 53 logTrace("outPath: ", outPath); 54 55 // Ensure directory for output file exits 56 auto outDir = stdDirName(outPath); 57 failEnforce(exists(Path(outDir)), "Output directory doesn't exist: ", outDir); 58 failEnforce(isDir(Path(outDir)), "Output directory isn't a directory: ", outDir); 59 60 // Check whether output file should be updated 61 if(force) 62 logVerbose(`--force used, skipping "up-to-date" check`); 63 else 64 { 65 if(existsAsFile(outPath)) 66 { 67 import std.regex; 68 69 auto existingModule = cast(string) scriptlikeRead(Path(outPath)); 70 auto adjustedExistingModule = existingModule 71 .replaceFirst(regex(`Generated at [^\n]*\n`), `Generated at `~timestamp~"\n") 72 .replaceFirst(regex(`packageTimestamp = "[^"]*";`), `packageTimestamp = "`~timestamp~`";`) 73 .replaceFirst(regex(`packageTimestampISO = "[^"]*";`), `packageTimestampISO = "`~timestampIso~`";`); 74 75 if(adjustedExistingModule == dModule) 76 { 77 logVerbose("Existing version file is up-to-date, skipping overwrite of ", outPath); 78 return outPath; 79 } 80 } 81 } 82 83 // Write the file 84 logVerbose("Saving to ", outPath); 85 if(!dryRun) 86 { 87 try 88 scriptlikeWrite(outPath, dModule); 89 catch(FileException e) 90 fail(e.msg); 91 } 92 93 return outPath; 94 }