Fix dtest -f relative paths under bazel run - #330
Conversation
Literal paths like hands/list1.txt were only checked against the runfiles cwd; resolve them via BUILD_WORKING_DIRECTORY / BUILD_WORKSPACE_DIRECTORY and relative to the binary, matching the numeric list shorthand. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Updates dtest argument handling so literal relative -f paths resolve correctly when running under bazelisk run, using Bazel-provided environment directories and an argv0-based fallback to locate the workspace hands/ files.
Changes:
- Extends
-f/--fileresolution to retry literal relative paths underBUILD_WORKING_DIRECTORY/BUILD_WORKSPACE_DIRECTORY, then relative to the inferred workspace root fromargv0. - Updates usage/docs/error output to describe the new resolution behavior.
- Adds unit tests covering Bazel env-dir resolution for literal relative paths and binary-relative fallback.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
library/tests/args.hpp |
Updates documentation for -f input-file resolution order. |
library/tests/args.cpp |
Implements Bazel env-dir + binary-relative fallback for literal relative -f paths; updates help/error text. |
library/tests/args_test.cpp |
Adds tests verifying literal relative path resolution via Bazel env dirs and argv0 fallback. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Spell out that list shorthand is for numeric ids, that absolute paths only try the literal path, and avoid inventing hands/list<path>.txt in the error text when -f is already a path. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed both Copilot review notes:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
library/tests/args.cpp:333
- Absolute
-fvalues that don't exist still fall through to the list-shorthand/env/binary-relative search (e.g., potentially resolving to an unrelated hands/list*.txt file). This contradicts the updated contract in args.hpp (“Absolute paths only attempt the literal path as given.”) and can produce surprising results.
return cwd_candidate;
A missing absolute path must fail rather than searching hands/list{arg}.txt
under cwd, bazel env dirs, or the dtest binary, matching the documented
contract.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the follow-up Copilot note on absolute |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
library/tests/args.hpp:41
- The header comment says the final fallback is "relative to the directory of argv0", but the implementation actually infers the workspace root by climbing four parents from argv0 (bazel-bin/.../dtest) and then resolves relative paths from that root. This is a documentation mismatch that could confuse callers.
/// `bazel run`); then those same two forms relative to the directory of
/// `argv0` (the usual `bazel-bin/library/tests/dtest` layout). Absolute
/// paths only attempt the literal path as given.
library/tests/args_test.cpp:402
- This test assumes the OS path
/no_such_dtest_absdoes not exist. If it happens to exist on a developer machine or CI image, the test will fail even though the resolver logic is correct. Consider choosing a missing absolute path dynamically and creating the corresponding "trap" file based on that chosen path.
EXPECT_TRUE(
resolve_dtest_input_file("/no_such_dtest_abs", binary_path_).empty());
Document that binary-relative lookup climbs four parents from argv0 to the workspace root, and build the absolute-path regression trap from a unique missing path so the test does not depend on a hardcoded absolute name. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the latest Copilot notes:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
library/tests/args_test.cpp:272
- The comment references
-f hands/list1.txt, but this test resolveshands/list42.txt. This is misleading when debugging bazel path resolution behavior; update the comment to match the test input.
// bazelisk run //library/tests:dtest -- -f hands/list1.txt must find the
// path relative to the invoke-time shell cwd, not the runfiles tree.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the latest Copilot note: the |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
library/tests/args.cpp:399
- Similarly for the binary-relative fallback:
root/argis tried beforeroot/hands/list{arg}.txt. This can cause numeric-f 42to resolve to a workspace-root file named42instead of the documentedhands/list42.txtif both exist. To keep numeric shorthand semantics stable, prefer the list-shorthand candidate under the inferred workspace root before the literal candidate.
const string bin_literal =
normalize_logical_path((root / arg).string());
if (path_exists(bin_literal))
return bin_literal;
library/tests/args.cpp:389
resolve_dtest_input_file()now checksBUILD_WORKING_DIRECTORY/argandBUILD_WORKSPACE_DIRECTORY/argbefore the numeric shorthandhands/list{arg}.txtunder those env dirs. This changes numeric-f 42resolution if a file named42exists in the workspace (contradicting the PR description that numeric shorthand behavior is unchanged). Consider trying the list-shorthand candidate under the Bazel env dirs before the literalargcandidate.
This issue also appears on line 395 of the same file.
if (const string found =
from_env_dir("BUILD_WORKING_DIRECTORY", arg); !found.empty())
{
return found;
}
Under BUILD_* dirs and the argv0 workspace root, try hands/listN.txt before a literal relative arg so numeric -f N is not shadowed by a workspace-root file named N. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the latest Copilot notes on resolution order:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
library/tests/args.cpp:345
from_env_dir()joinsdir / releven whenrelhas a root-name (e.g. Windows drive-relativeC:foo). In that casestd::filesystem::operator/can discarddir, so BUILD_* / argv0-root fallback can be bypassed unexpectedly. Consider rejecting such inputs (treat them as non-relative) so the join behaves consistently.
const char* dir = std::getenv(env_name);
if (dir == nullptr || dir[0] == '\0')
return string();
const string candidate =
normalize_logical_path((fs::path(dir) / rel).string());
library/tests/args.cpp:473
- The “Also tried …” message is misleading for absolute
-farguments:resolve_dtest_input_file()returns early for missing absolute paths and does not try BUILD_* or argv0-root fallbacks. Consider wording this as conditional (only for relative paths).
cout << "Also tried that path under the current directory, "
"BUILD_WORKING_DIRECTORY, BUILD_WORKSPACE_DIRECTORY, "
"and under the workspace root inferred from the dtest binary; "
"for numeric -f N, also hands/listN.txt\n";
Windows drive-relative paths like C:foo are not joined under BUILD_* or argv0 (operator/ can discard the base). The "Also tried" hint is only printed for portable relative -f values. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the latest Copilot notes:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (1)
library/tests/args.cpp:338
resolve_dtest_input_file()still applies the list-shorthand transformation (list{arg}.txt) even whenargis already a relative path containing directory separators (e.g.hands/list42.txt), producing nonsense candidates likehands/listhands/list42.txt.txt. This can lead to surprising resolution if such a path happens to exist, and it also means the resolver is trying paths that the updated docs/error text no longer describe. Consider disabling list-shorthand when the argument already looks like a path (contains/or\\), and (optionally) only enabling shorthand for purely numeric tokens.
const string list_name = "list" + arg + ".txt";
// Keep generic separators so cwd hits match the documented hands/listN.txt form.
const string cwd_candidate =
(fs::path("hands") / list_name).generic_string();
if (path_exists(cwd_candidate))
zzcgumn
left a comment
There was a problem hiding this comment.
I just wish that there was an easier way to handle file paths :(.
Path-like -f values no longer probe hands/list{arg}.txt candidates that
concatenate directory components into nonsense paths.
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the latest Copilot note on list shorthand for path-like
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.
Suppressed comments (2)
library/tests/args.cpp:321
is_dtest_list_shorthand_arg()is a TU-local helper but is currently emitted with external linkage, unlike the other helper functions in this file (kept in the unnamed namespace). Making itstaticavoids exporting an unnecessary symbol and prevents potential name collisions at link time.
bool is_dtest_list_shorthand_arg(const string& arg)
library/tests/args_test.cpp:303
- This test uses the throwing overload of
std::filesystem::remove(). If the remove fails unexpectedly (permissions, transient FS issues), it will throw and abort the test binary instead of producing a clear assertion failure. Prefer theerror_codeoverload here (and assert success).
std::filesystem::remove(root_ + "hands/list42.txt");
Summary
-fpaths (e.g.hands/list1.txt) viaBUILD_WORKING_DIRECTORY/BUILD_WORKSPACE_DIRECTORYand relative to the dtest binary, sobazelisk run //library/tests:dtest -- -f hands/list1.txtworks.-f 1→hands/list1.txt) behavior is unchanged; docs and error text updated to match.Fixes #328
Test plan
bazelisk test //library/tests:args_testbazelisk run //library/tests:dtest -- -f hands/list1.txt -s calcbazel-bin/library/tests/dtest -f hands/list1.txtstill works from the repo rootMade with Cursor