Skip to content

Commit 395fa5d

Browse files
committed
opend cmd line improvements
1 parent 84e0458 commit 395fa5d

File tree

1 file changed

+76
-38
lines changed

1 file changed

+76
-38
lines changed

opend/opend.d

Lines changed: 76 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,37 +50,62 @@ string[] testRunnerBuildArgs(string[] userArgs) {
5050
return args;
5151
}
5252

53+
string preferredCompiler;
54+
5355
int main(string[] args) {
5456
// maybe override the normal config files
5557
// --opend-config-file
5658
// --opend-project-file
5759
try {
5860
import std.algorithm;
5961
string[] buildSpecificArgs;
62+
string[] otherOpendArgs;
6063
string[] allOtherArgs;
61-
foreach(arg; args)
64+
foreach(arg; args) {
6265
if(arg.startsWith("--opend-to-build="))
6366
buildSpecificArgs ~= arg["--opend-to-build=".length .. $];
67+
else
68+
if(arg.startsWith("--opend-"))
69+
otherOpendArgs ~= arg["--opend-".length .. $];
6470
else
6571
allOtherArgs ~= arg;
72+
}
73+
foreach(arg; otherOpendArgs) {
74+
import std.string;
75+
auto equal = arg.indexOf("=");
76+
if(equal == -1)
77+
throw new Exception("opend arg without param: " ~ arg);
78+
auto name = arg[0 .. equal];
79+
auto value = arg[equal + 1 .. $];
80+
81+
switch(name) {
82+
case "compiler":
83+
preferredCompiler = value;
84+
break;
85+
default:
86+
throw new Exception("unknown opend arg: " ~ name);
87+
}
88+
}
89+
6690

6791
if(allOtherArgs.length == 0) {
6892
return 1; // should never happen...
6993
} if(allOtherArgs.length == 1) {
70-
return Commands.run(null);
94+
return Commands.run(null, buildSpecificArgs);
7195
} else switch(auto a = allOtherArgs[1]) {
7296
foreach(memberName; __traits(allMembers, Commands))
97+
static if(__traits(getProtection, __traits(getMember, Commands, memberName)) == "public")
7398
case memberName: {
7499
string[] argsToSend = allOtherArgs[2 .. $];
75-
if(a == "build" /*|| a == "test"*/ || a == "publish" || a == "testOnly" || a == "check" || a == "run")
76-
argsToSend = buildSpecificArgs ~ allOtherArgs[2 .. $];
77-
return __traits(getMember, Commands, memberName)(argsToSend);
100+
if(a == "build" || a == "test" || a == "publish" || a == "testOnly" || a == "check" || a == "run")
101+
argsToSend = allOtherArgs[2 .. $];
102+
return __traits(getMember, Commands, memberName)(argsToSend, buildSpecificArgs);
78103
}
79104
case "-h", "--help":
80-
Commands.help(null);
105+
Commands.help(null, null);
81106
return 0;
82107
default:
83-
return Commands.build(buildSpecificArgs ~ allOtherArgs[1 .. $]);
108+
return Commands.build(allOtherArgs[1 .. $], buildSpecificArgs);
84109
}
85110
} catch (Throwable e) {
86111
import std.stdio;
@@ -108,12 +133,19 @@ struct Commands {
108133
static:
109134

110135
/// Displays this information
111-
int help(string[] args) {
136+
int help(string[] args, string[] extraBuildArgs) {
112137
import std.stdio, std.string;
113138

114-
writeln("`opend command_or_filename [args...]` where commands include:");
139+
writeln("`opend [--opend-args...] command_or_filename [args...]` where commands include:");
140+
141+
writeln("Where opend-args include:");
142+
writeln("\t--opend-compiler=ldmd2 prefer the ldc-based compiler in all cases");
143+
writeln("\t--opend-to-build=flag passes the given flag to the compiler when building");
144+
145+
writeln("Commands include:");
115146

116147
foreach(memberName; __traits(allMembers, Commands))
148+
static if(__traits(getProtection, __traits(getMember, Commands, memberName)) == "public")
117149
static if(memberName != "sendToCompilerDriver")
118150
writefln("%9s\t%s", memberName, strip(__traits(docComment, __traits(getMember, Commands, memberName))));
119151

@@ -122,16 +154,18 @@ struct Commands {
122154
}
123155

124156
/// Does a debug build and immediately runs the program
125-
int run(string[] args) {
157+
int run(string[] args, string[] extraBuildArgs) {
126158
import std.stdio, std.string;
127159
if(args.length == 0) {
128-
help(null);
160+
help(null, null);
129161
return 1;
130162
}
131163

164+
args = extraBuildArgs ~ args;
165+
132166
auto oe = getOutputExecutable(args);
133167

134-
if(auto err = build(oe.buildArgs))
168+
if(auto err = build(oe.buildArgs, null))
135169
return err;
136170

137171
return spawnProcess([oe.exe] ~ oe.args, [
@@ -140,7 +174,7 @@ struct Commands {
140174
}
141175

142176
/// Builds the code and runs its unittests
143-
int test(string[] args) {
177+
int test(string[] args, string[] extraBuildArgs) {
144178
// Check if user wants advanced test runner features
145179
if(args.length > 0) {
146180
switch(args[0]) {
@@ -154,7 +188,7 @@ struct Commands {
154188
// Delegate to test runner's help system to avoid duplication
155189
auto oe = getOutputExecutable(testRunnerBuildArgs([]));
156190

157-
if(auto err = build(oe.buildArgs))
191+
if(auto err = build(oe.buildArgs, extraBuildArgs))
158192
return err;
159193

160194
return spawnProcess([oe.exe, "help"], [
@@ -170,14 +204,14 @@ struct Commands {
170204
}
171205

172206
// Original test behavior - run all tests
173-
return run(["-g", "-unittest", "-main", "-checkaction=context"] ~ args);
207+
return run(["-g", "-unittest", "-main", "-checkaction=context"] ~ extraBuildArgs ~ args, null);
174208
}
175209

176210
private int testList(string[] args) {
177211
// Build executable with test runner embedded (no -main since test_runner.d has its own)
178212
auto oe = getOutputExecutable(testRunnerBuildArgs(args));
179213

180-
if(auto err = build(oe.buildArgs))
214+
if(auto err = build(oe.buildArgs, null))
181215
return err;
182216

183217
return spawnProcess([oe.exe, "list"] ~ oe.args, [
@@ -197,7 +231,7 @@ struct Commands {
197231
// Build executable with test runner embedded (no -main since test_runner.d has its own)
198232
auto oe = getOutputExecutable(testRunnerBuildArgs(args[1..$]));
199233

200-
if(auto err = build(oe.buildArgs))
234+
if(auto err = build(oe.buildArgs, null))
201235
return err;
202236

203237
return spawnProcess([oe.exe, "filter", args[0]] ~ oe.args, [
@@ -216,7 +250,7 @@ struct Commands {
216250
// Build executable with test runner embedded (no -main since test_runner.d has its own)
217251
auto oe = getOutputExecutable(testRunnerBuildArgs(args[1..$]));
218252

219-
if(auto err = build(oe.buildArgs))
253+
if(auto err = build(oe.buildArgs, null))
220254
return err;
221255

222256
return spawnProcess([oe.exe, "run", args[0]] ~ oe.args, [
@@ -225,28 +259,30 @@ struct Commands {
225259
}
226260

227261
/// Builds the code and runs unittests but only for files explicitly listed, not auto-imported files
228-
int testOnly(string[] args) {
229-
return run(["-g", "-unittest=explicit", "-main", "-checkaction=context"] ~ args);
262+
int testOnly(string[] args, string[] extraBuildArgs) {
263+
return run(["-g", "-unittest=explicit", "-main", "-checkaction=context"] ~ extraBuildArgs ~ args, null);
230264
}
231265

232266
/// Performs quick syntax and semantic tests, without performing code generation
233-
int check(string[] args) {
234-
return build(args ~ ["-o-"]);
267+
int check(string[] args, string[] extraBuildArgs) {
268+
return build(args ~ ["-o-"], extraBuildArgs);
235269
}
236270

237271
/// Does a debug build with the given arguments
238-
int build(string[] args) {
272+
int build(string[] args, string[] extraBuildArgs) {
239273
// FIXME: support -gnone?
240274
// FIXME: pull info out of the cache to get the right libs and -i modifiers out
241-
return sendToCompilerDriver(["-g", "-i"] ~ args, "dmd");
275+
return sendToCompilerDriver(["-g", "-i"] ~ extraBuildArgs ~ args, "dmd");
242276
}
243277

244278
/// Does a release build with the given arguments
245-
int publish(string[] args) {
279+
int publish(string[] args, string[] extraBuildArgs) {
246280
return sendToCompilerDriver(["-i", "-O2"] ~ args, "ldmd2");
247281
}
248282

249283
private int sendToCompilerDriver(string[] args, string preferredCompiler = null) {
284+
if(.preferredCompiler !is null)
285+
preferredCompiler = .preferredCompiler;
250286
version(OSX) version(AArch64) if(preferredCompiler == "dmd") preferredCompiler = "ldmd2";
251287

252288
// extract --target
@@ -413,11 +449,11 @@ struct Commands {
413449
}
414450
switch(preferredCompiler) {
415451
case "dmd":
416-
return dmd(args);
452+
return dmd(args, null);
417453
case "ldmd2":
418-
return ldmd2(args);
454+
return ldmd2(args, null);
419455
case "ldc2":
420-
return ldc2(args);
456+
return ldc2(args, null);
421457
default:
422458
goto case "ldmd2";
423459
}
@@ -432,50 +468,50 @@ struct Commands {
432468

433469
/// Pre-compiles with the given arguments so future calls to `build` can use the cached library
434470
version(none)
435-
int precompile(string[] args) {
471+
int precompile(string[] args, string[] extraBuildArgs) {
436472
// any modules present in the precompile need to be written to the cache, knowing which output file they went into
437473
// FIXME
438474
return 1;
439475
}
440476

441477
/// Watches for changes to its source and attempts to automatically recompile and restart the application (if compatible)
442478
version(none)
443-
int watch(string[] args) {
479+
int watch(string[] args, string[] extraBuildArgs) {
444480
// FIXME
445481
return 1;
446482
}
447483

448484
/// Passes args to the compiler, then opens a debugger to run the generated file.
449485
version(none)
450-
int dbg(string[] args) {
486+
int dbg(string[] args, string[] extraBuildArgs) {
451487
// FIXME
452488
return 1;
453489
}
454490

455491
/// Allows for updating the OpenD compiler or libraries
456492
version(none)
457-
int update(string[] args) {
493+
int update(string[] args, string[] extraBuildArgs) {
458494
// FIXME
459495
return 1;
460496
}
461497

462498
/// Forwards arguments directly to the OpenD dmd driver
463-
int dmd(string[] args) {
499+
int dmd(string[] args, string[] extraBuildArgs) {
464500
return spawnProcess([getCompilerPath("dmd")] ~ args, null).wait.checkForCrash("dmd");
465501
}
466502

467503
/// Forwards arguments directly to the OpenD ldmd2 driver
468-
int ldmd2(string[] args) {
504+
int ldmd2(string[] args, string[] extraBuildArgs) {
469505
return spawnProcess([getCompilerPath("ldmd2")] ~ args, null).wait.checkForCrash("ldmd2");
470506
}
471507

472508
/// Forwards arguments directly to the OpenD ldc2 driver
473-
int ldc2(string[] args) {
509+
int ldc2(string[] args, string[] extraBuildArgs) {
474510
return spawnProcess([getCompilerPath("ldc2")] ~ args, null).wait.checkForCrash("ldc2");
475511
}
476512

477513
/// Installs optional components or updates to opend
478-
int install(string[] args) {
514+
int install(string[] args, string[] extraBuildArgs) {
479515

480516
// FIXME: remove any --opend-to-build= stuff before args[0]
481517

@@ -575,7 +611,7 @@ string getCompilerPath(string compiler) {
575611

576612
string getBundledModulePath(string moduleName) {
577613
import std.file, std.path;
578-
import std.string;
614+
import std.string;
579615
return buildPath([dirName(thisExePath()), "../import/" ~ moduleName.replace(".", "/") ~ ".d"]);
580616

581617
}
@@ -608,6 +644,8 @@ OutputExecutable getOutputExecutable(string[] args) {
608644
version(Windows)
609645
extension = ".exe";
610646

647+
import std.path;
648+
611649
foreach(idx, arg; args) {
612650
if(arg == "--") {
613651
buildArgsSplitter = idx;
@@ -616,7 +654,7 @@ OutputExecutable getOutputExecutable(string[] args) {
616654
}
617655
if(arg.length > 1 && arg[0] == '-') {
618656
if(arg.length > 3 && arg[0 .. 3] == "-of") {
619-
name = arg[3 .. $];
657+
name = baseName(arg[3 .. $]);
620658
extension = null;
621659
nameExplicitlyGiven = true;
622660
break;

0 commit comments

Comments
 (0)