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

ci: more robust handling of directories in shell.zig #1275

Merged
merged 2 commits into from
Nov 8, 2023
Merged

Conversation

matklad
Copy link
Member

@matklad matklad commented Nov 7, 2023

We use shell.zig for various "scripting" tasks. One problem there is
managing environment --- current directory and environmental variables.

So far, the strategy was to avoid doing anything special about it and
just use std API to mutate global process state. That's not great, for
two reasons:

  • First, mutating process state is inherently fragile. For example,
    calling setenv in a multithreaded program is almost always UB

  • Second, mutating global state might lead to logical errors. For
    example, we had a bug recently where foo called bar, bar changed
    process working directory, and, upon return, foo ended up in an
    unexpected state. (ci: fix wrong working directory when unmarking release as a draft #1272)

To fix the issues, this PR phases our global API in favor of Shell.cwd
field.

Trivia: in most other languages, adding a second cwd would be quite
confusing, as that would make the std API behave in unexpected ways.
However in Zig the cwd is not ambient, but rather passed explicitly to
almost all APIs:

std.fs.cwd().readFle("Readme.me")

So there's no confusion!

We use shell.zig for various "scripting" tasks. One problem there is
managing environment --- current directory and environmental variables.

So far, the strategy was to avoid doing anything special about it and
just use std API to mutate global process state. That's not great, for
two reasons:

- First, mutating process state is inherently fragile. For example,
  calling setenv in a multithreaded program is almost always UB

- Second, mutating global state might lead to logical errors. For
  example, we had a bug recently where `foo` called `bar`, `bar` changed
  process working directory, and, upon return, `foo` ended up in an
  unexpected state. (#1272)

To fix the issues, this PR phases our global API in favor of `Shell.cwd`
field.

Trivia: in most other languages, adding a second cwd would be quite
confusing, as that would make the `std` API behave in unexpected ways.
However in Zig the cwd is not ambient, but rather passed explicitly to
almost all APIs:

    std.fs.cwd().readFle("Readme.me")

So there's no confusion!
@@ -9,6 +9,7 @@ const Shell = @import("../../shell.zig");
const TmpTigerBeetle = @import("../../testing/tmp_tigerbeetle.zig");

pub fn tests(shell: *Shell, gpa: std.mem.Allocator) !void {
assert(shell.file_exists("TigerBeetle.sln"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fun fact: I've added these asserts as a drive by change, because why not, and they've already caught a bug in this PR!

@@ -132,8 +132,6 @@ fn build_tigerbeetle(shell: *Shell, info: VersionInfo, dist_dir: std.fs.Dir) !vo
var section = try shell.open_section("build tigerbeetle");
defer section.close();

try shell.project_root.setAsCwd();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, we were defensively setting up cwd, because it could have been changed from under our feet. With pushd/popd we can rather assume that the cwd is reasonable, and just assert that when appropriate.

cwd: std.fs.Dir,

// Stack of working directories backing pushd/popd.
cwd_stack: [cwd_stack_max]std.fs.Dir,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open-coded bounded array here:

  • std.BoundedArray is banned in favor of stdx.BoundedArray
  • but, as we use shell.zig in build.zig, we don't want to drag any deps here
  • and, also, std.BoundedArray doesn't really by us all that much.

// TODO(Zig): use cwd_dir once that is available https://github.com/ziglang/zig/issues/5190
var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const cwd_path = try shell.cwd.realpath(".", &buffer);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not happy about all these copy-paste here, but also not sure if its worth to try to dry it out -- it's hard to move stack-allocated bufer to a helper. Hopefully, cwd_dir will be available in the next release.

@matklad matklad added this pull request to the merge queue Nov 8, 2023
Merged via the queue into main with commit 9871760 Nov 8, 2023
27 checks passed
@matklad matklad deleted the matklad/cd branch November 8, 2023 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants