Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,18 @@ public async Task<ParseResult> ParseAsync(
return result;
}

var manifestPath = componentStream.Location.Contains(' ') && !componentStream.Location.StartsWith('"')
? $"\"{componentStream.Location}\""
: componentStream.Location;

var cliResult = await this.cliService.ExecuteCommandAsync(
command: "cargo",
additionalCandidateCommands: null,
workingDirectory: null,
cancellationToken: cancellationToken,
"metadata",
"--manifest-path",
componentStream.Location,
manifestPath,
"--format-version=1",
"--locked");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,18 @@ private async Task<CargoMetadata> RunCargoMetadataAsync(string manifestPath, Can
return null;
}

var manifestPathArg = manifestPath.Contains(' ') && !manifestPath.StartsWith('"')
? $"\"{manifestPath}\""
: manifestPath;

var res = await this.cliService.ExecuteCommandAsync(
"cargo",
additionalCandidateCommands: null,
workingDirectory: null,
cancellationToken: token,
"metadata",
"--manifest-path",
manifestPath,
manifestPathArg,
"--format-version=1",
"--locked");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,37 @@ public async Task VirtualManifest_MultipleRootNodes_AllProcessed()
distinctNames.Should().Contain("pkgB");
}

[TestMethod]
public async Task ParseAsync_QuotesManifestPathWhenPathContainsSpaces()
{
var tomlPath = "C:/repo with space/AppControl Manager/Cargo.toml";
var quotedTomlPath = $"\"{tomlPath}\"";

var json = """
{
"packages": [
{ "name": "my-pkg", "version": "1.0.0", "id": "my-pkg 1.0.0 (path+file:///C:/repo)", "dependencies": [], "source": null }
],
"workspace_members": [ "my-pkg 1.0.0 (path+file:///C:/repo)" ],
"resolve": {
"nodes": [
{ "id": "my-pkg 1.0.0 (path+file:///C:/repo)", "deps": [] }
]
}
}
""";

this.cli.Setup(c => c.CanCommandBeLocatedAsync("cargo", null)).ReturnsAsync(true);
this.cli.Setup(c => c.ExecuteCommandAsync("cargo", null, null, It.IsAny<CancellationToken>(), "metadata", "--manifest-path", quotedTomlPath, "--format-version=1", "--locked"))
.ReturnsAsync(new CommandLineExecutionResult { ExitCode = 0, StdOut = json });

var recorder = new Mock<ISingleFileComponentRecorder>(MockBehavior.Loose);
var result = await this.parser.ParseAsync(MakeTomlStream(tomlPath), recorder.Object);

result.Success.Should().BeTrue();
this.cli.Verify(c => c.ExecuteCommandAsync("cargo", null, null, It.IsAny<CancellationToken>(), "metadata", "--manifest-path", quotedTomlPath, "--format-version=1", "--locked"), Times.Once());
}

private async Task<ParseResult> InvokeProcessMetadataAsync(string manifestLocation, ISingleFileComponentRecorder fallbackRecorder, CargoMetadata metadata) =>
await this.parser.ParseFromMetadataAsync(
new ComponentStream { Location = manifestLocation, Pattern = "Cargo.toml", Stream = new MemoryStream([]) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,57 @@ public async Task BuildPackageOwnershipMapAsync_CargoMetadataFails_AddsToFailedM
result.ManifestToMetadata.Should().BeEmpty();
}

[TestMethod]
public async Task BuildPackageOwnershipMapAsync_QuotesManifestPathWhenPathContainsSpaces()
{
var tomlPath = "C:/repo with space/AppControl Manager/Cargo.toml";
var quotedTomlPath = $"\"{tomlPath}\"";

var json = """
{
"packages": [
{ "name": "my-pkg", "version": "1.0.0", "id": "my-pkg 1.0.0 (path+file:///C:/repo)", "dependencies": [], "source": null }
],
"workspace_members": [ "my-pkg 1.0.0 (path+file:///C:/repo)" ],
"resolve": {
"nodes": [
{ "id": "my-pkg 1.0.0 (path+file:///C:/repo)", "deps": [] }
]
}
}
""";

this.envVarService.Setup(e => e.IsEnvironmentVariableValueTrue("DisableRustCliScan")).Returns(false);
this.cliService.Setup(c => c.CanCommandBeLocatedAsync("cargo", null)).ReturnsAsync(true);
this.cliService.Setup(c => c.ExecuteCommandAsync(
"cargo",
null,
null,
It.IsAny<CancellationToken>(),
"metadata",
"--manifest-path",
quotedTomlPath,
"--format-version=1",
"--locked"))
.ReturnsAsync(new CommandLineExecutionResult { ExitCode = 0, StdOut = json });

var result = await this.builder.BuildPackageOwnershipMapAsync([tomlPath]);

result.FailedManifests.Should().BeEmpty();
this.cliService.Verify(
c => c.ExecuteCommandAsync(
"cargo",
null,
null,
It.IsAny<CancellationToken>(),
"metadata",
"--manifest-path",
quotedTomlPath,
"--format-version=1",
"--locked"),
Times.Once());
}

[TestMethod]
public async Task BuildPackageOwnershipMapAsync_SimpleDependency_BuildsOwnershipMap()
{
Expand Down