commit a34403b365af8c13f0868901ebfe31f3edbcf250
parent e7479d15649ad6693c5e33fbe6ee03b57e776b6f
Author: Sebastian <sebastian@sebsite.pw>
Date: Sat, 9 Dec 2023 21:06:29 -0500
hare build: only overwrite executable files
Fixes: https://todo.sr.ht/~sircmpwn/hare/659
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/cmd/hare/build.ha b/cmd/hare/build.ha
@@ -216,10 +216,25 @@ fn get_output(goal: build::stage, input: str) (str | error) = {
if (goal != build::stage::BIN) {
path::push_ext(&buf, build::stage_ext[goal])?;
};
- match (path::peek(&buf)) {
+
+ const output = match (path::peek(&buf)) {
case let s: str =>
- return s;
+ yield s;
case void =>
return unknown_output;
};
+ stat = match (os::stat(output)) {
+ case let s: fs::filestat =>
+ yield s;
+ case errors::noentry =>
+ return output;
+ case fs::error =>
+ // XXX: double cast here (and below) shouldn't be necessary
+ return output: output_exists: error;
+ };
+ if (!fs::isfile(stat.mode)
+ || fs::mode_perm(stat.mode) & fs::mode::USER_X == 0) {
+ return output: output_exists: error;
+ };
+ return output;
};
diff --git a/cmd/hare/error.ha b/cmd/hare/error.ha
@@ -21,6 +21,7 @@ type error = !(
unknown_arch |
unknown_output |
unknown_type |
+ output_exists |
output_failed |
invalid_namespace |
build::unknown_platform |
@@ -32,6 +33,8 @@ type unknown_output = !void;
type unknown_type = !str;
+type output_exists = !str;
+
type output_failed = !(str, fs::error);
type invalid_namespace = !str;
diff --git a/cmd/hare/main.ha b/cmd/hare/main.ha
@@ -122,6 +122,9 @@ export fn main() void = {
fmt::fatal("Error: Can't guess output in root directory");
case let e: unknown_type =>
fmt::fatalf("Error: Unknown build type: {}", e);
+ case let e: output_exists =>
+ fmt::fatalf("Error: Output path '{}' already exists, but isn't an executable file",
+ e);
case let e: output_failed =>
fmt::fatalf("Error: Could not open output '{}': {}",
e.0, fs::strerror(e.1));