Skip to content

Simplify LocateRepository relative-path test (follow-up to #1734)#1737

Closed
jankratochvilcz wants to merge 10 commits into
dotnet:mainfrom
jankratochvilcz:mt/locate-repository-test-simplify
Closed

Simplify LocateRepository relative-path test (follow-up to #1734)#1737
jankratochvilcz wants to merge 10 commits into
dotnet:mainfrom
jankratochvilcz:mt/locate-repository-test-simplify

Conversation

@jankratochvilcz

Copy link
Copy Markdown
Contributor

Follow-up to #1734 addressing review comment https://github.com/dotnet/sourcelink/pull/1734/changes#r3537777727.

The reviewer noted we don't need to set the process CWD in the relative-path test — it is sufficient to validate that a non-fully-qualified argument is rejected.

This change (src/Microsoft.Build.Tasks.Git.UnitTests/LocateRepositoryTests.cs):

  • Removes the Directory.SetCurrentDirectory manipulation (and the try/finally restore) from the relative-path test.
  • Renames RelativePath_IsRejected_IndependentOfProcessCwd to RelativePath_IsRejected; it now just passes a relative path (".") and asserts the missing-repository warning.
  • Drops the now-unused System.IO using.

Note

This PR is stacked on #1734. Until #1734 merges, the diff here also shows #1734's commits; it will narrow to just the test simplification once #1734 is in main.

Verified: RelativePath_IsRejected and AbsolutePath_LocatesRepository pass on net11.0.

jankratochvilcz and others added 10 commits June 30, 2026 15:51
Migrates the shared abstract base RepositoryTask and the concrete
LocateRepository task to the MSBuild multithreaded (MT) task model.

Base RepositoryTask:
- Implements IMultiThreadableTask with a TaskEnvironment property that
  defaults to TaskEnvironment.Fallback so existing call paths and unit
  tests keep single-process (CWD) semantics with no setup.
- Absolutizes the initial path at the GetInitialPath() boundary:
  GetOrCreateRepositoryInstance now computes
  TaskEnvironment.GetAbsolutePath(initialPath) and passes the resolved
  AbsolutePath.Value to GitRepository.TryFindRepository. This removes the
  process-CWD dependency (TryFindRepository internally calls
  Path.GetFullPath, which only consults the CWD for relative inputs;
  feeding it an absolute path is MT-safe).
  Note: the implicit AbsolutePath->string conversion returns the original
  (possibly relative) input, so .Value is used explicitly.
- Sin 2: both ReportMissingRepositoryWarning call sites keep the ORIGINAL
  initialPath so warnings show the user's input, not the absolutized path.
- Edge case: GetAbsolutePath throws ArgumentException on null/empty,
  matching the previous Path.GetFullPath("") behavior.

Concrete LocateRepository:
- Annotated with [MSBuildMultiThreadableTask].

Call-chain audit: GitOperations.GetRepositoryUrl / GetSourceRoots and the
downstream GitRepository path operations combine paths with the absolute
git/working directories of the located repository, so they become MT-safe
once the initial path is absolute. No remaining
Directory.GetCurrentDirectory / Environment.CurrentDirectory /
Environment.Get/SetEnvironmentVariable / CWD-relative Path.GetFullPath in
the LocateRepository chain.

Test:
- Adds LocateRepositoryTests.RelativePath_ResolvesAgainstTaskEnvironment-
  ProjectDirectory_NotProcessCwd (Pattern A decoy CWD): creates a real
  minimal git repo, sets the process CWD to a repo-less decoy, sets the
  task's TaskEnvironment project directory to the repo, passes a relative
  Path, and asserts WorkingDirectory/RepositoryId resolve to the project
  repo. Fails if the migration is reverted.
- Extends MockEngine to IBuildEngine4 (in-memory registered task object
  store) so the cached success path can run.
- Disables assembly test parallelization to keep the CWD mutation safe.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The implicit string conversion returns the absolute Value, not the
original input; correct the comment while keeping the explicit .Value.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Wrap GetAbsolutePath + TryFindRepository so an empty/null initial path
  reports a missing-repository warning and returns gracefully instead of
  throwing an unhandled ArgumentException (preserves pre-migration behavior;
  ExecuteImpl's catch does not handle ArgumentException).
- Rewrite the parity comment to describe the control-flow (not just exception
  type) equivalence with the old TryFindRepository path.
- Add EmptyPath_DegradesGracefully regression test (dual-fault verified: fails
  when the catch is reverted).
- Make AssemblyInfo.cs parallelization comment test-agnostic.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…itory)

Make the MT migration attribute-only: rather than resolving the initial
path via TaskEnvironment.GetAbsolutePath, RepositoryTask now rejects any
path that is not fully qualified. A relative/drive-relative/root-relative
path depends on the shared process CWD/drive, which is unsafe under the
multithreaded task model, so it degrades to the standard "missing
repository" warning.

- Add IsPathFullyQualified polyfill to PathUtilities (net472 lacks the BCL
  API) with a dedicated test suite (Windows/Unix/relative cases).
- Drop IMultiThreadableTask/TaskEnvironment from RepositoryTask; keep
  [MSBuildMultiThreadableTask] on the concrete LocateRepository.
- Simplify tests: revert shared MockEngine to IBuildEngine; localize a
  minimal IBuildEngine4 to LocateRepositoryTests. Cover historical
  behavior (absolute path locates repo) and CWD-independence (relative
  path rejected even when CWD is a repo).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move the inline IBuildEngine4 test engine into a shared TestUtilities.MockEngine4
next to the existing MockEngine so other tests can reuse it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…f new MockEngine4

Per review feedback, the existing MockEngine in TestUtilities now implements
IBuildEngine4 (adding the IBuildEngine2/3/4 members and an in-memory
registered-task-object store) rather than introducing a separate MockEngine4
test double. IBuildEngine4 derives from IBuildEngine, so all existing
MockEngine usages remain source-compatible.

- Extend MockEngine : IBuildEngine -> IBuildEngine4
- Delete MockEngine4.cs
- Update LocateRepositoryTests to use MockEngine

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per review feedback, the RelativePath test no longer sets the process
current working directory. It is sufficient to validate that a
non-fully-qualified path is rejected, so the test just passes a relative
path (".") and asserts the missing-repository warning.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@jankratochvilcz jankratochvilcz requested a review from tmat as a code owner July 8, 2026 10:58
@jankratochvilcz

Copy link
Copy Markdown
Contributor Author

Closing as redundant. #1734 merged with the test simplification (commit 8e9e319) as its final commit, so this change is already in main. The review comment https://github.com/dotnet/sourcelink/pull/1734/changes#r3537777727 is fully addressed there. The diff here only appeared large because it was computed against the pre-#1734 merge-base.

@jankratochvilcz jankratochvilcz deleted the mt/locate-repository-test-simplify branch July 8, 2026 13:26
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.

1 participant