Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit verbose binary backend output #308

Merged
merged 2 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions payload/reggae/backend/binary.d
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,25 @@ private struct BinaryOptions {
bool list;
bool norerun;
bool singleThreaded;
bool verbose;
private bool _earlyReturn;
string[] args;

this(string[] args) @trusted {

auto optInfo = getopt(
args,
"list|l", "List available build targets", &list,
"norerun|n", "Don't check for rerun", &norerun,
"single|s", "Use only one thread", &singleThreaded,
);
"verbose|v", "Verbose output", &verbose,
);

if(optInfo.helpWanted) {
defaultGetoptPrinter("Usage: build <targets>", optInfo.options);
_earlyReturn = true;
}

if(list) {
_earlyReturn = true;
}
Expand Down Expand Up @@ -70,6 +75,7 @@ auto Binary(T)(Build build, in Options options, ref T output) {
struct BinaryT(T) {
Build build;
const(Options) options;
BinaryOptions binaryOptions;
T* output;
private string[] _srcDirs;

Expand All @@ -96,7 +102,7 @@ struct BinaryT(T) {
}
}

auto binaryOptions = BinaryOptions(args);
binaryOptions = BinaryOptions(args);

handleOptions(binaryOptions);
if(binaryOptions.earlyReturn) return;
Expand All @@ -112,7 +118,7 @@ struct BinaryT(T) {
else
didAnything = mainLoop(topTargets.parallel, binaryOptions, didAnything);

if(!didAnything) output.writeln("[build] Nothing to do");
if(!didAnything) log("Nothing to do");
}

Target[] topLevelTargets(string[] args) @trusted pure {
Expand Down Expand Up @@ -197,7 +203,7 @@ private:

immutable myPath = thisExePath;
if(deps.any!(a => a.newerThan(myPath))) {
output.writeln("[build] " ~ options.rerunArgs.join(" "));
log(options.rerunArgs.join(" "));
immutable reggaeRes = execute(options.rerunArgs);
enforce(reggaeRes.status == 0,
text("Could not run ", options.rerunArgs.join(" "), " to regenerate build:\n",
Expand Down Expand Up @@ -268,7 +274,10 @@ private:
}

void executeCommand(Target target) @trusted {
output.writeln("[build] ", target.shellCommand(options));
if(binaryOptions.verbose)
log(target.shellCommand(options));
else
log(target.describe(options));

mkDir(target);
auto targetOutput = target.execute(options);
Expand All @@ -287,6 +296,11 @@ private:
mkdirRecurse(output.dirName);
}
}

private void log(A...)(auto ref A args) {
import std.functional: forward;
output.writeln("[build] ", forward!args);
}
}


Expand Down
41 changes: 40 additions & 1 deletion payload/reggae/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,10 @@ struct Target {
return _command.shellCommand(options, getLanguage(), _outputs, inputs(options.projectPath), deps);
}

string describe(in Options options) {
return _command.describe(options, getLanguage(), _outputs, inputs(options.projectPath), Yes.dependencies);
}

// not const because the code commands take inputs and outputs as non-const strings
const(string)[] execute(in Options options) @safe const {
return _command.execute(options, getLanguage(), _outputs, inputs(options.projectPath));
Expand All @@ -371,7 +375,9 @@ struct Target {
return _command.getType;
}

string[] getCommandParams(in string projectPath, in string key, string[] ifNotFound) @safe pure const return scope {
string[] getCommandParams(in string projectPath, in string key, string[] ifNotFound)
@safe pure const return scope
{
return _command.getParams(projectPath, key, ifNotFound);
}

Expand Down Expand Up @@ -708,6 +714,39 @@ struct Command {
.join(" ");
}

/// Describes what the command does, like "compiling", "linking", etc.
string describe(in Options options,
in Language language,
in string[] outputs,
in string[] inputs,
Flag!"dependencies" deps = Yes.dependencies)
{
import std.array: join;
import std.algorithm: map;

const outputsStr = outputs
.map!(a => expandOutput(a, options.projectPath))
.join(", ");

final switch(type) with(CommandType) {
case shell:
case phony:
return "Shell command generating " ~ outputsStr;

case code:
return "D code generating " ~ outputsStr;

case compile:
return "Compiling " ~ outputsStr;

case link:
return "Linking " ~ outputsStr;

case compileAndLink:
return "Compiling and linking " ~ outputsStr;
}
}

///returns a command string to be run by the shell
private auto shellCommandRange(
in Options options,
Expand Down
77 changes: 73 additions & 4 deletions tests/it/runtime/backend/binary.d
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,70 @@ version(DigitalMars) {

runReggae(["-b", "ninja"]);
writelnUt(gCurrentFakeFile.lines);
gCurrentFakeFile.lines.shouldHaveCompiledBuildgen;
gCurrentFakeFile.lines.shouldHaveCompiledQuiet;
gCurrentFakeFile.reset;

runReggae(["-b", "ninja"]); // should not build reggaefile again
writelnUt(gCurrentFakeFile.lines);
gCurrentFakeFile.lines.shouldNotHaveCompiledBuildgen;
gCurrentFakeFile.lines.shouldNotHaveCompiledQuiet;
}
}
}
}

void shouldHaveCompiledBuildgen(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
version(DigitalMars) {
version(linux) {

@("output.quiet")
@Tags("binary")
unittest {
with(immutable ReggaeSandbox()) {
writeFile(
"reggaefile.d",
q{
import reggae;
alias lib = staticLibrary!("mylib", Sources!"src");
mixin build!lib;
}
);

writeFile(
"src/foo.d",
q{
module foo;
import bar;

void main() {

}

int foo(int i) {
return bar(i) * 2;
}
}
);

writeFile(
"src/foo.d",
q{
module bar;
int bar(int i) {
return i + 1;
}
}
);

runReggae(["-b", "binary"]);
binary.shouldExecuteOk; // build the 1st time
gCurrentFakeFile.lines.shouldNotHaveCompiledVerbose;
("[build] Linking " ~ inSandboxPath("build")).should.be in gCurrentFakeFile.lines;
}
}
}
}


void shouldHaveCompiledVerbose(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
import std.algorithm: filter, canFind;
lines
.filter!(l => l.canFind("[build]"))
Expand All @@ -119,11 +171,28 @@ void shouldHaveCompiledBuildgen(in string[] lines, in string file = __FILE__, in
}


void shouldNotHaveCompiledBuildgen(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
void shouldNotHaveCompiledVerbose(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
import std.algorithm: filter, canFind;
lines
.filter!(l => l.canFind("[build]"))
.filter!(l => l.canFind("dmd "))
.filter!(l => l.canFind("-of"))
.shouldBeEmpty(file, line);
}

void shouldHaveCompiledQuiet(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
import std.algorithm: filter, canFind;
lines
.filter!(l => l.canFind("[build]"))
.filter!(l => l.canFind("Compiling "))
.shouldNotBeEmpty(file, line);
}


void shouldNotHaveCompiledQuiet(in string[] lines, in string file = __FILE__, in size_t line = __LINE__) {
import std.algorithm: filter, canFind;
lines
.filter!(l => l.canFind("[build]"))
.filter!(l => l.canFind("Compiling "))
.shouldBeEmpty(file, line);
}
Loading