Skip to content

[ACIX-1353] Improve dda info owners code behavior when running out of repo root#244

Open
Ishirui wants to merge 10 commits intomainfrom
pierrelouis.veyrenc/ACIX-1353-fix-info-owners-code
Open

[ACIX-1353] Improve dda info owners code behavior when running out of repo root#244
Ishirui wants to merge 10 commits intomainfrom
pierrelouis.veyrenc/ACIX-1353-fix-info-owners-code

Conversation

@Ishirui
Copy link
Copy Markdown
Contributor

@Ishirui Ishirui commented Mar 4, 2026

Currently, dda info owners code only works properly when running from the repo root:

  • The default codeowners filepath (.github/CODEOWNERS) only resolves to a correct path if we are running from the repo root. Running from within a subdir fails within an error:
datadog-agent/bazel on  main on ☁️  pierrelouis.veyrenc@datadoghq.com
❯ dda info owners code BUILD.bazel

 Usage: dda info owners code [OPTIONS] PATHS...

 Try 'dda info owners code -h' for help
╭─ Error ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Invalid value for '--owners' / '-f': File '.github/CODEOWNERS' does not exist.                                                                                                 │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

  • Even if we manually specify the CODEOWNERS file, the resolution logic expects all paths to be passed as paths relative to the repo root - this is not done currently, so the resolution returns the wrong result (it queries the CODEOWNERS file as if the cwd was the repo root):
datadog-agent/bazel on  main on ☁️  pierrelouis.veyrenc@datadoghq.com
❯ dda info owners code patches --owners ../.github/CODEOWNERS
┌──────────┬──┐
│ patches/ │  │
└──────────┴──┘

(We would expect @DataDog/agent-build here)

This PR fixes this behavior by dynamically getting the git repo root and transparently rewriting all paths to be relative to that root before passing it to the codeowners resolver.

@Ishirui Ishirui force-pushed the pierrelouis.veyrenc/ACIX-1353-fix-info-owners-code branch from f99e3c7 to cfa4c0a Compare March 31, 2026 12:25
Ishirui and others added 6 commits March 31, 2026 15:13
…epo root

Input paths are now resolved from CWD to absolute, then converted to
repo-root-relative using dynamic `git rev-parse --show-toplevel` detection
per file. The CODEOWNERS file is auto-detected from each file's repo root
when not explicitly provided. This fixes the command failing when run from
a subdirectory or when referencing files in other repos.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…wners code`

Tests cover the behavior matrix: file from subdirectory, directory
resolution with trailing slash, parent traversal with '..', non-existent
path error, explicit --owners from subdirectory, and multiple mixed paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Ishirui Ishirui marked this pull request as ready for review April 1, 2026 11:53
@Ishirui Ishirui requested a review from a team as a code owner April 1, 2026 11:53
Copilot AI review requested due to automatic review settings April 1, 2026 11:54
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8e108cb801

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/dda/cli/info/owners/code/__init__.py Outdated
Comment thread src/dda/cli/info/owners/code/__init__.py Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the dda info owners code command so it works correctly when invoked from subdirectories by determining the Git repository root dynamically and resolving input paths relative to that root before querying CODEOWNERS.

Changes:

  • Added Git.get_repo_root() helper to locate a repo’s top-level directory from a given path (or CWD).
  • Reworked dda info owners code to resolve CODEOWNERS relative to the detected repo root and to convert input paths into repo-root-relative paths before lookup.
  • Expanded test coverage for repo-root detection and for subdirectory invocation/path resolution behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/dda/tools/git.py Introduces get_repo_root() used by CLI logic to find the repo root from various starting paths.
src/dda/cli/info/owners/code/__init__.py Updates CODEOWNERS loading/path rewriting to behave correctly outside the repo root.
tests/tools/git/test_git.py Adds tests validating get_repo_root() behavior across different call locations and error cases.
tests/cli/info/owners/test_code.py Adds tests ensuring path resolution works from subdirectories and with explicit --owners.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +111 to +115
with repo_root.as_cwd():
formatted_path = format_path_for_codeowners(repo_relative)
resolved_owners = owners.of(formatted_path)
res[formatted_path] = [owner[1] for owner in resolved_owners] if resolved_owners else [None]

Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

owners.of() returning no matches is currently encoded as [None], which changes the command’s previous behavior (empty list) and will display the literal string None in human output. Prefer keeping [] for “no owners” and let the table display an empty cell (or handle the fallback explicitly in display code) to avoid breaking JSON consumers and CLI output expectations.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this is better and less confusing - happy to discuss though :)

Maybe we should leave the JSON output as [] and only show None for human output.

Comment thread src/dda/cli/info/owners/code/__init__.py
Comment thread src/dda/tools/git.py Outdated
Comment thread src/dda/cli/info/owners/code/__init__.py
Copy link
Copy Markdown
Member

@chouetz chouetz left a comment

Choose a reason for hiding this comment

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

Can you elaborate on the owners cache? Thanks in advance!

app.display_table(display_res, stderr=False)
# Process each path with dynamic repo root detection
res: dict[str, list[str | None]] = {}
owners_cache: dict[Path, codeowners.CodeOwners] = {}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't really get the point of this cache: do we expect several CODEOWNERS files on a single git repo? Otherwise if it's just to limit opening twice the same file because the repo_root is only retrieved within the paths loops from any path, the implementation is probably quite complex. Do you agree we could make is simpler, or do I misunderstand something?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fundamentally yes it's about avoiding opening the same file and instantiating the CodeOwners object multiple times.

I didn't find a simpler way because nothing prevents you from querying multiple files in different repos, i.e. dda info owners code repo1/file repo2/file, so the logic for opening the codeowners file has to go in the loop.

I guess we could prevent that but I wanted the CLI to be as flexible and intuitive as possible

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ok if you want to support repo1 and repo2, even if I'm unsure of the use case criticality, you need a dict. This is quite a bit complex for what we need but let's go like that

@Ishirui Ishirui requested a review from chouetz April 13, 2026 13:57
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.

3 participants