Skip to content

Commit

Permalink
cache the generated test main file: dub_test_root.d
Browse files Browse the repository at this point in the history
these changes prevent dub from rebuilding a project every time it runs a unittest.
  • Loading branch information
foerdi authored and lange-tci committed Aug 31, 2020
1 parent 3288bbb commit 2b5a180
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 29 deletions.
4 changes: 4 additions & 0 deletions changelog/cache-generated-test-config.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Caching of generated unittest runner (dub test)

For projects without a user-defined unittest configuration `dub test` generates a main file automatically.
This main file is now being cached and won't be regenerated won subsequent runs without file changes.
17 changes: 15 additions & 2 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ class Dub {
}

// prepare the list of tested modules

string[] import_modules;
foreach (file; lbuildsettings.sourceFiles) {
if (file.endsWith(".d")) {
Expand All @@ -679,11 +680,23 @@ class Dub {
}
}

NativePath mainfile;
if (settings.tempBuild)
mainfile = getTempFile("dub_test_root", ".d");
else {
import dub.generators.build : computeBuildName;
mainfile = m_project.rootPackage.path ~ format(".dub/code/%s_dub_test_root.d", computeBuildName(test_config, settings, import_modules));
}

mkdirRecurse(mainfile.parentPath.toNativeString());

bool regenerateMainFile = settings.force || !existsFile(mainfile);

// generate main file
NativePath mainfile = getTempFile("dub_test_root", ".d");
tcinfo.sourceFiles[""] ~= mainfile.toNativeString();
tcinfo.mainSourceFile = mainfile.toNativeString();
if (!m_dryRun) {

if (!m_dryRun && regenerateMainFile) {
auto fil = openFile(mainfile, FileMode.createTrunc);
scope(exit) fil.close();
fil.write("module dub_test_root;\n");
Expand Down
62 changes: 35 additions & 27 deletions source/dub/generators/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ string getObjSuffix(const scope ref BuildPlatform platform)
return platform.platform.canFind("windows") ? ".obj" : ".o";
}

string computeBuildName(string config, GeneratorSettings settings, const string[][] hashing...)
{
import std.digest;
import std.digest.md;

MD5 hash;
hash.start();
void addHash(in string[] strings...) { foreach (s; strings) { hash.put(cast(ubyte[])s); hash.put(0); } hash.put(0); }
foreach(strings; hashing)
addHash(strings);
auto hashstr = hash.finish().toHexString().idup;

return format("%s-%s-%s-%s-%s_%s-%s", config, settings.buildType,
settings.platform.platform.join("."),
settings.platform.architecture.join("."),
settings.platform.compiler, settings.platform.frontendVersion, hashstr);
}

class BuildGenerator : ProjectGenerator {
private {
PackageManager m_packageMan;
Expand Down Expand Up @@ -329,33 +347,23 @@ class BuildGenerator : ProjectGenerator {

private string computeBuildID(string config, in BuildSettings buildsettings, GeneratorSettings settings)
{
import std.digest;
import std.digest.md;
import std.bitmanip;

MD5 hash;
hash.start();
void addHash(in string[] strings...) { foreach (s; strings) { hash.put(cast(ubyte[])s); hash.put(0); } hash.put(0); }
void addHashI(int value) { hash.put(nativeToLittleEndian(value)); }
addHash(buildsettings.versions);
addHash(buildsettings.debugVersions);
//addHash(buildsettings.versionLevel);
//addHash(buildsettings.debugLevel);
addHash(buildsettings.dflags);
addHash(buildsettings.lflags);
addHash((cast(uint)buildsettings.options).to!string);
addHash(buildsettings.stringImportPaths);
addHash(buildsettings.importPaths);
addHash(settings.platform.architecture);
addHash(settings.platform.compilerBinary);
addHash(settings.platform.compiler);
addHashI(settings.platform.frontendVersion);
auto hashstr = hash.finish().toHexString().idup;

return format("%s-%s-%s-%s-%s_%s-%s", config, settings.buildType,
settings.platform.platform.join("."),
settings.platform.architecture.join("."),
settings.platform.compiler, settings.platform.frontendVersion, hashstr);
const(string[])[] hashing = [
buildsettings.versions,
buildsettings.debugVersions,
buildsettings.dflags,
buildsettings.lflags,
buildsettings.stringImportPaths,
buildsettings.importPaths,
settings.platform.architecture,
[
(cast(uint)buildsettings.options).to!string,
settings.platform.compilerBinary,
settings.platform.compiler,
settings.platform.frontendVersion.to!string,
],
];

return computeBuildName(config, settings, hashing);
}

private void copyTargetFile(NativePath build_path, BuildSettings buildsettings, GeneratorSettings settings)
Expand Down
24 changes: 24 additions & 0 deletions test/cache-generated-test-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

. $(dirname "${BASH_SOURCE[0]}")/common.sh
cd ${CURR_DIR}/cache-generated-test-config
rm -rf .dub

${DUB} test --compiler=${DC}

STAT="stat -c '%Y'"
[[ "$OSTYPE" == "darwin"* ]] && STAT="stat -f '%m' -t '%Y'"

EXECUTABLE_TIME="$(${STAT} cache-generated-test-config-test-library)"
[ -z "$EXECUTABLE_TIME" ] && die $LINENO 'no EXECUTABLE_TIME was found'
MAIN_TIME="$(${STAT} "$(ls .dub/code/*dub_test_root.d)")"
[ -z "$MAIN_TIME" ] && die $LINENO 'no MAIN_TIME was found'

${DUB} test --compiler=${DC}
MAIN_FILES_COUNT=$(ls .dub/code/*dub_test_root.d | wc -l)

[ $MAIN_FILES_COUNT -ne 1 ] && die $LINENO 'DUB generated more then one main file'
[ "$EXECUTABLE_TIME" != "$(${STAT} cache-generated-test-config-test-library)" ] && die $LINENO 'The executable has been rebuilt'
[ "$MAIN_TIME" != "$(${STAT} "$(ls .dub/code/*dub_test_root.d | head -n1)")" ] && die $LINENO 'The test main file has been rebuilt'

exit 0
Empty file.
Empty file.
Empty file.
3 changes: 3 additions & 0 deletions test/cache-generated-test-config/dub.sdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name "cache-generated-test-config"

targetType "staticLibrary"
6 changes: 6 additions & 0 deletions test/cache-generated-test-config/source/test.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module test;

unittest
{
assert(true);
}

0 comments on commit 2b5a180

Please sign in to comment.