commit a3ce0eca32d2c5570034530fe2f7d5c49b8c1c8f
parent 0cf6503998baa3f68b9d680f2f4d448bf291f7f9
Author: Sebastian <sebastian@sebsite.pw>
Date: Sun, 29 Jan 2023 01:27:40 -0500
haredoc: get default tags from `hare version`
If hare isn't found in PATH, haredoc falls back to just setting the
platform and architecture as tags, like it already used to.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
4 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/cmd/hare/subcmds.ha b/cmd/hare/subcmds.ha
@@ -553,7 +553,6 @@ fn version(args: []str) void = {
fmt::printfln("Hare {}", VERSION)!;
if (verbose) {
- fmt::errorln()!;
fmt::printf("Build tags\t")!;
const build_target = default_target();
const tags = build_target.tags;
diff --git a/cmd/haredoc/env.ha b/cmd/haredoc/env.ha
@@ -1,23 +1,66 @@
// License: GPL-3.0
// (c) 2021 Drew DeVault <sir@cmpwn.com>
// (c) 2022 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
+use bufio;
+use fmt;
use hare::module;
+use io;
use os::exec;
use os;
use strings;
def PLATFORM: str = "unknown";
-fn default_tags() []module::tag = {
- // TODO: Once os::exec can handle pipes, we should read the default tags
- // from $(hare version).
- return alloc([module::tag {
- name = strings::dup(PLATFORM),
- mode = module::tag_mode::INCLUSIVE,
- }, module::tag {
- name = strings::dup(os::machine()),
- mode = module::tag_mode::INCLUSIVE,
- }]);
+fn default_tags() ([]module::tag | error) = {
+ let cmd = match (exec::cmd("hare", "version", "-v")) {
+ case let cmd: exec::command =>
+ yield cmd;
+ case exec::nocmd =>
+ let platform = strings::dup(PLATFORM);
+ let machine = strings::dup(os::machine());
+ fmt::errorln("Couldn't find hare binary in PATH")?;
+ fmt::errorfln("Build tags defaulting to +{}+{}",
+ platform, machine)?;
+
+ return alloc([module::tag {
+ name = platform,
+ mode = module::tag_mode::INCLUSIVE,
+ }, module::tag {
+ name = machine,
+ mode = module::tag_mode::INCLUSIVE,
+ }]);
+ case let err: exec::error =>
+ return err;
+ };
+
+ let pipe = exec::pipe();
+ exec::addfile(&cmd, os::stdout_file, pipe.1);
+ let proc = exec::start(&cmd)?;
+ io::close(pipe.1)?;
+
+ let tags: []module::tag = [];
+ for (true) match (bufio::scanline(pipe.0)?) {
+ case let b: []u8 =>
+ defer free(b);
+ const (k, v) = strings::cut(strings::fromutf8(b)!, "\t");
+ if (k == "Build tags") {
+ tags = module::parsetags(v) as []module::tag;
+ break;
+ };
+ case io::EOF =>
+ // process exited with failure; handled below
+ break;
+ };
+
+ io::close(pipe.0)?;
+ let status = exec::wait(&proc)?;
+ match (exec::check(&status)) {
+ case void =>
+ assert(len(tags) > 0);
+ case let status: !exec::exit_status =>
+ fmt::fatal("Error: hare:", exec::exitstr(status));
+ };
+ return tags;
};
fn addtags(tags: []module::tag, in: str) ([]module::tag | void) = {
diff --git a/cmd/haredoc/errors.ha b/cmd/haredoc/errors.ha
@@ -5,8 +5,10 @@ use hare::lex;
use hare::module;
use hare::parse;
use io;
+use os::exec;
-type error = !(lex::error | parse::error | io::error | module::error);
+type error = !(lex::error | parse::error | io::error | module::error |
+ exec::error);
fn strerror(err: error) str = {
match (err) {
@@ -18,5 +20,7 @@ fn strerror(err: error) str = {
return io::strerror(err);
case let err: module::error =>
return module::strerror(err);
+ case let err: exec::error =>
+ return exec::strerror(err);
};
};
diff --git a/cmd/haredoc/main.ha b/cmd/haredoc/main.ha
@@ -48,7 +48,12 @@ export fn main() void = {
};
let template = true;
let show_undocumented = false;
- let tags = default_tags();
+ let tags = match (default_tags()) {
+ case let t: []module::tag =>
+ yield t;
+ case let err: exec::error =>
+ fmt::fatal(strerror(err));
+ };
defer module::tags_free(tags);
const help: [_]getopt::help = [