Skip to content

Commit cdb7593

Browse files
authored
Merge pull request #1439 from cgay/exit-status
Console compiler: exit with error status for serious warnings
2 parents bc0b57d + 626a2be commit cdb7593

File tree

11 files changed

+99
-34
lines changed

11 files changed

+99
-34
lines changed

documentation/release-notes/source/2022.1.rst

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Compiler
3232
the :file:`sbin` (static executables binary) directory of the
3333
personal-root.
3434

35+
* To aid with automation tasks the ``dylan-compiler`` and ``dylan-environment``
36+
executables now return exit code ``3`` if any serious warnings are
37+
generated. Use the new ``-allow-serious-warnings`` flag to return to the old
38+
behavior of returning exit code ``0``.
39+
3540
Tooling
3641
=======
3742

sources/common-dylan/tests/common-extensions-tests.dylan

+8-2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ define test test-find-element ()
150150
skip: 2), #f);
151151
end test;
152152

153+
/*
154+
Commenting these two out for now because they cause serious warnings. We want
155+
to be able to run libraries-test-suite from the GitHub CI and have serious
156+
warnings cause a failure. --cgay 2022
157+
153158
define test test-ignorable ()
154159
assert-signals(<error>, ignorable(this-is-undefined),
155160
"ignorable crashes on undefined variables");
@@ -159,6 +164,7 @@ define test test-ignore ()
159164
assert-signals(<error>, ignore(this-is-undefined),
160165
"ignore crashes on undefined variables");
161166
end;
167+
*/
162168

163169
define test test-one-of ()
164170
let new-type = #f;
@@ -503,8 +509,8 @@ define suite common-extensions-test-suite ()
503509
test test-difference;
504510
test test-false-or;
505511
test test-find-element;
506-
test test-ignorable;
507-
test test-ignore;
512+
//test test-ignorable;
513+
//test test-ignore;
508514
test test-one-of;
509515
test test-position;
510516
test test-split;

sources/dylan/tests/control.dylan

+9-3
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,26 @@ define test test-conditionals ()
7373
#(9, 8, 7));
7474
end test;
7575

76-
define function no-param-function () 1 end;
77-
define function one-param-function (x) x end;
78-
7976
define test test-required-calls (expected-failure?: #t)
8077
check-equal("no param call",
8178
(method () 1 end)(), 1);
8279
check-equal("one param call one arg",
8380
(method (x) x end)(1), 1);
81+
82+
// Defeat compiler warnings. We want to check runtime errors.
83+
local method fun0 () 1 end;
84+
let no-param-function = list(fun0)[0];
8485
check-condition("no param call one arg", <error>,
8586
apply(no-param-function, #[1]));
87+
88+
// Defeat compiler warnings. We want to check runtime errors.
89+
local method fun1 (x) x end;
90+
let one-param-function = list(fun1)[0];
8691
check-condition("one param call no args", <error>,
8792
apply(one-param-function, #[]));
8893
check-condition("one param call two args", <error>,
8994
apply(one-param-function, #[1, 2]));
95+
9096
check-equal("two args call",
9197
(method (x, y) x + y end)(1, 2), 3);
9298
check-equal("lots args call",

sources/dylan/tests/module.dylan

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ define module dylan-test-suite
1616
limited-integer-max };
1717
use common-dylan;
1818
use format;
19+
use simple-random;
1920
use table-extensions,
2021
import: { case-insensitive-equal };
2122
use testworks;

sources/environment/commands/build.dylan

+27-5
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,17 @@ define class <build-project-command> (<abstract-link-command>)
182182
init-keyword: dispatch-coloring:;
183183
constant slot %release? :: <boolean> = #f,
184184
init-keyword: release?:;
185+
// When #t serious warnings DO NOT cause an error exit status to be returned
186+
// to the shell.
187+
constant slot %allow-serious-warnings? :: <boolean> = #f,
188+
init-keyword: allow-serious-warnings?:;
185189
end class <build-project-command>;
186190

191+
// This defines the interactive version of the "build" command. See also
192+
// sources/environment/console/compiler-command-line.dylan for the
193+
// <main-command>, which duplicates some of these options so that the command
194+
// can also be invoked non-interactively.
195+
187196
define command-line build => <build-project-command>
188197
(summary: "builds a project's executable",
189198
documentation: "Builds the executable for a project.")
@@ -205,7 +214,7 @@ end command-line build;
205214

206215
define method do-execute-command
207216
(context :: <environment-context>, command :: <build-project-command>)
208-
=> ()
217+
=> (exit-code :: <integer>)
209218
let project = command.%project | context.context-project;
210219
let messages = if (command.%verbose?) #"internal" else #"external" end;
211220
let stream = context.context-server.server-output-stream;
@@ -217,7 +226,14 @@ define method do-execute-command
217226
else
218227
curry(note-build-progress, context, #f)
219228
end;
229+
let serious-warnings? = #f;
220230
block ()
231+
local method warning-callback (warning)
232+
note-compiler-warning(context, warning);
233+
if (instance?(warning, <serious-compiler-warning-object>))
234+
serious-warnings? := #t;
235+
end;
236+
end;
221237
if (build-project
222238
(project,
223239
process-subprojects?: command.%subprojects?,
@@ -228,7 +244,7 @@ define method do-execute-command
228244
output: command.%output,
229245
dispatch-coloring: command.%dispatch-coloring,
230246
progress-callback: progress-callback,
231-
warning-callback: curry(note-compiler-warning, context),
247+
warning-callback: warning-callback,
232248
error-handler: curry(compiler-condition-handler, context)))
233249
if (command.%link?)
234250
let project-context = context.context-project-context;
@@ -247,10 +263,16 @@ define method do-execute-command
247263
progress-callback: progress-callback,
248264
error-handler: curry(compiler-condition-handler, context))
249265
end;
250-
message(context, "Build of '%s' completed", project.project-name)
266+
message(context, "Build of '%s' completed", project.project-name);
267+
if (serious-warnings? & ~command.%allow-serious-warnings?)
268+
$serious-warnings-exit-code
269+
else
270+
$success-exit-code
271+
end
251272
else
252-
message(context, "Build of '%s' aborted", project.project-name)
253-
end;
273+
message(context, "Build of '%s' aborted", project.project-name);
274+
$unexpected-error-exit-code
275+
end
254276
exception (error :: <file-system-error>)
255277
command-error("%s", error)
256278
end

sources/environment/commands/command-line.dylan

+8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ Warranty: Distributed WITHOUT WARRANTY OF ANY KIND
88

99
/// Useful constants
1010

11+
// These are sorted by severity so that Windows scripts can use IF ERRORLEVEL.
12+
// https://devblogs.microsoft.com/oldnewthing/20080926-00/?p=20743
13+
define constant $success-exit-code = 0;
14+
define constant $usage-error-exit-code = 1;
15+
// space for potential $warnings-exit-code = 2;
16+
define constant $serious-warnings-exit-code = 3;
17+
define constant $unexpected-error-exit-code = 9;
18+
1119
define constant $whitespace = #[' ', '\t', '\n'];
1220
define constant $quote-characters = #['\'', '"'];
1321

sources/environment/commands/module.dylan

+5-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ define module command-lines
8686
command-line-loop,
8787
display-command-prompt,
8888
execute-command-line,
89-
execute-server-command;
89+
execute-server-command,
90+
$success-exit-code,
91+
$unexpected-error-exit-code,
92+
$serious-warnings-exit-code,
93+
$usage-error-exit-code;
9094

9195
// Command line user interface
9296
export command-line-choose-file,

sources/environment/console/command-line.dylan

+31-20
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ define abstract class <basic-main-command> (<basic-command>)
6666
init-keyword: dfm?:;
6767
constant slot %dispatch-coloring :: false-or(<symbol>) = #f,
6868
init-keyword: dispatch-coloring:;
69+
// When #t serious warnings DO NOT cause an error exit status to be returned
70+
// to the shell.
71+
constant slot %allow-serious-warnings? :: <boolean> = #f,
72+
init-keyword: allow-serious-warnings?:;
6973
/*---*** fill this in later.
7074
constant slot %exports? :: <boolean> = #f,
7175
init-keyword: exports?:;
@@ -77,9 +81,9 @@ end class <basic-main-command>;
7781

7882
define method execute-main-command
7983
(context :: <server-context>, command :: <basic-main-command>)
80-
=> (status-code :: <integer>)
81-
local method run
82-
(class :: subclass(<command>), #rest arguments) => ()
84+
=> (exit-code :: <integer>)
85+
local method run (class :: subclass(<command>), #rest arguments)
86+
=> (#rest values)
8387
let command = apply(make, class, server: context, arguments);
8488
execute-command(command)
8589
end method run;
@@ -96,21 +100,27 @@ define method execute-main-command
96100
run(<open-project-command>, file: filename)
97101
end;
98102
let build? = command.%build?;
103+
let exit-code = #f;
99104
if (build? | command.%compile?)
100-
run(<build-project-command>,
101-
clean?: command.%clean?,
102-
link?: #f,
103-
release?: command.%release?,
104-
verbose?: command.%verbose?,
105-
subprojects: command.%subprojects?,
106-
output: begin
107-
let output = make(<stretchy-object-vector>);
108-
if (command.%assemble?) add!(output, #"assembler") end;
109-
if (command.%dfm?) add!(output, #"dfm") end;
110-
if (command.%harp?) add!(output, #"harp") end;
111-
output
112-
end,
113-
dispatch-coloring: command.%dispatch-coloring)
105+
// By default the build command returns an error status for serious
106+
// warnings. This makes it possible for scripting to abort on serious
107+
// warnings.
108+
exit-code
109+
:= run(<build-project-command>,
110+
clean?: command.%clean?,
111+
link?: #f,
112+
release?: command.%release?,
113+
verbose?: command.%verbose?,
114+
subprojects: command.%subprojects?,
115+
output: begin
116+
let output = make(<stretchy-object-vector>);
117+
if (command.%assemble?) add!(output, #"assembler") end;
118+
if (command.%dfm?) add!(output, #"dfm") end;
119+
if (command.%harp?) add!(output, #"harp") end;
120+
output
121+
end,
122+
dispatch-coloring: command.%dispatch-coloring,
123+
allow-serious-warnings?: command.%allow-serious-warnings?);
114124
end;
115125
if (build? | command.%link?)
116126
let target = command.%target;
@@ -123,7 +133,7 @@ define method execute-main-command
123133
subprojects: command.%subprojects?,
124134
unify?: command.%unify?)
125135
end;
126-
$success-exit-code;
136+
exit-code | $success-exit-code
127137
end method execute-main-command;
128138

129139
define method execute-main-loop
@@ -150,8 +160,9 @@ define method do-execute-command
150160
next-handler()
151161
else
152162
display-condition(context, condition);
153-
message(context, "Exiting with return code %d", $error-exit-code);
154-
return($error-exit-code)
163+
message(context, "Exiting with return code %d",
164+
$unexpected-error-exit-code);
165+
return($unexpected-error-exit-code)
155166
end
156167
end;
157168
local method run

sources/environment/console/compiler-command-line.dylan

+2
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,6 @@ define command-line main => <main-command>
4949
flag harp = "generate HARP output";
5050
flag assemble = "generate assembly-language output";
5151
flag dfm = "generate Dylan Flow Machine output";
52+
flag allow-serious-warnings
53+
= "exit with success status if there are serious warnings [off by default]";
5254
end command-line main;

sources/environment/console/environment-command-line.dylan

+2
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,6 @@ define command-line main => <main-command>
132132
flag harp = "generate HARP output";
133133
flag assemble = "generate assembly-language output";
134134
flag dfm = "generate Dylan Flow Machine output";
135+
flag allow-serious-warnings
136+
= "exit with success status if there are serious warnings [off by default]";
135137
end command-line main;

sources/environment/console/start.dylan

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc.
66
License: See License.txt in this distribution for details.
77
Warranty: Distributed WITHOUT WARRANTY OF ANY KIND
88

9-
define constant $success-exit-code = 0;
10-
define constant $error-exit-code = -1;
119

1210
define function main
1311
(arguments :: <string>)
@@ -23,7 +21,7 @@ define function main
2321
parse-command-line(server, arguments, class: class)
2422
exception (error :: <parse-error>)
2523
format(output-stream, "%s\n", error);
26-
exit-application($error-exit-code)
24+
exit-application($usage-error-exit-code)
2725
end;
2826
let status-code :: <integer> = execute-command(command);
2927
exit-application(status-code)

0 commit comments

Comments
 (0)