Split reading/parsing tar file and writing results to the disk in two
separate steps. So we can later test parsing part without need to write
everyting to the disk.
* Specifically recognize stderr as a different concept than an error
message in Step results.
* Display it differently when only stderr occurs but the build proceeds
successfully.
closes#18473
Co-authored-by: Motiejus Jakštys <motiejus@jakstys.lt>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Samuel Cantero <scanterog@gmail.com>
Co-authored-by: Giorgos Georgiou <giorgos.georgiou@datadoghq.com>
Co-authored-by: Carl Åstholm <carl@astholm.se>
std.fs.dir.makePath silently failed if one of the items in the path already exists. For example:
cwd.makePath("foo/bar/baz")
Silently failing is OK if "bar" is already a directory - this is the intended use of makePath (like mkdir -p). But if bar is a file then the subdirectory baz cannot be created - the end result is that makePath doesn't do anything which should be a detectable error because baz is never created.
The existing code had a TODO comment that did not specifically cover this error, but the solution for this silent failure also accomplishes the TODO task - the code now stats "foo" and returns an appropriate error. The new code also handles potential race condition if "bar" is deleted/permissions changed/etc in between the initial makeDir and statFile calls.
This mainly replaces ChunkIterator with std.mem.window and also
prints \n, \r, \t using Unicode symbols instead of periods because
they're common non-printable characters.
This same code exists in std.debug.hexdump.
At some point maybe this code could be exposed through a public
function. Then we could reuse the code in both places.
Recently, when I've been working with structures of data that is not
directly in RAM but rather laid out in bytes somewhere else,
it was always very useful to print out maybe the next 50 bytes or the
previous 50 bytes or so to see what's ahead or before me.
I would usually do this with a quick
`std.debug.print("{any}\n", .{bytes});` or something but the output is
not as nice obviously.
Changes the types of `std.builtin.Type` `name` fields from `[]const u8`
to `[:0]const u8`, which should make them easier to pass to C APIs
expecting null-terminated strings.
This will break code that reifies types using `[]const u8` strings, such
as code that uses `std.mem.tokenize()` to construct types from strings
at comptime. Luckily, the fix is simple: simply concatenate the
`[]const u8` string with an empty string literal (`name ++ ""`) to
explicitly coerce it to `[:0]const u8`.
Co-authored-by: Krzysztof Wolicki <der.teufel.mail@gmail.com>
Adds a variant to the LazyPath union representing a parent directory
of a generated path.
```zig
const LazyPath = union(enum) {
generated_dirname: struct {
generated: *const GeneratedFile,
up: usize,
},
// ...
}
```
These can be constructed with the new method:
```zig
pub fn dirname(self: LazyPath) LazyPath
```
For the cases where the LazyPath is already known
(`.path`, `.cwd_relative`, and `dependency`)
this is evaluated right away.
For dirnames of generated files and their dirnames,
this is evaluated at getPath time.
dirname calls can be chained, but for safety,
they are not allowed to escape outside a root
defined for each case:
- path: This is relative to the build root,
so dirname can't escape outside the build root.
- generated: Can't escape the zig-cache.
- cwd_relative: This can be a relative or absolute path.
If relative, can't escape the current directory,
and if absolute, can't go beyond root (/).
- dependency: Can't escape the dependency's root directory.
Testing:
I've included a standalone case for many of the happy cases.
I couldn't find an easy way to test the negatives, though,
because tests cannot yet expect panics.
When depending on a module that depends on a static library, there was a
missing step dependency on the static library, which caused a compile
error due to missing header file.
This fixes the problem by adding the proper step dependencies.
Reviewing this code, I'm starting to wonder if it might be simpler to
have Module instances create dummy Step objects to better model
dependencies and dependees, rather than trying to maintain this graph
without an actual node. That would be an improvement for a future
commit.