Skip to content

Commit 83adf80

Browse files
authored
Merge pull request #2136 from jmyersmsft/nugetFindUncFix
Fix regressions in NuGet tasks (M103)
2 parents ef46a5b + 044913e commit 83adf80

File tree

9 files changed

+74
-35
lines changed

9 files changed

+74
-35
lines changed

Tasks/Common/nuget-task-common/NuGetToolRunner.ts

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,29 +91,53 @@ export function createNuGetToolRunner(nuGetExePath: string, settings: NuGetEnvir
9191
return runner;
9292
}
9393

94-
export function locateTool(tool: string, userPath?: string, optional?: boolean) {
95-
tl.debug("looking for tool " + tool);
96-
if (userPath) {
97-
tl.debug("using user-supplied path " + userPath)
98-
tl.checkPath(userPath, 'nuget');
99-
return userPath;
100-
}
94+
export interface LocateOptions {
95+
optional?: boolean;
96+
userPath?: string;
97+
fallbackToSystemPath?: boolean;
98+
}
10199

100+
export function locateTool(tool: string | string[], opts?: LocateOptions) {
101+
let toolVariants: string[] = typeof tool === 'string' ? [tool] : tool;
102102
let searchPath = ["externals/nuget", "agent/Worker/Tools/NuGetCredentialProvider", "agent/Worker/Tools"];
103-
104103
let agentRoot = tl.getVariable("Agent.HomeDirectory");
105-
for (let possibleLocation of searchPath) {
106-
let fullPath = path.join(agentRoot, possibleLocation, tool);
107-
tl.debug("checking " + fullPath);
108-
if (tl.exist(fullPath)) {
109-
return fullPath;
110-
}
104+
105+
opts = opts || {};
106+
107+
tl.debug(`looking for tool ${tool}`)
108+
109+
if (opts.userPath) {
110+
tl.debug(`using user-supplied path ${opts.userPath}`)
111+
tl.checkPath(opts.userPath, toolVariants[0]);
112+
return opts.userPath;
111113
}
112114

113-
tl.debug("not found");
115+
for (let thisVariant of toolVariants)
116+
{
117+
tl.debug(`looking for tool variant ${thisVariant}`);
118+
119+
for (let possibleLocation of searchPath) {
120+
let fullPath = path.join(agentRoot, possibleLocation, thisVariant);
121+
tl.debug(`checking ${fullPath}`);
122+
if (tl.exist(fullPath)) {
123+
return fullPath;
124+
}
125+
}
126+
127+
if (opts.fallbackToSystemPath) {
128+
tl.debug('Checking system path');
129+
let whichResult = tl.which(thisVariant);
130+
if (whichResult) {
131+
tl.debug(`found ${whichResult}`);
132+
return whichResult;
133+
}
134+
}
135+
136+
tl.debug("not found");
137+
}
114138

115-
if (!optional) {
116-
throw new Error(tl.loc("NGCommon_UnableToFindTool", tool));
139+
if (!opts.optional) {
140+
throw new Error(tl.loc("NGCommon_UnableToFindTool", toolVariants[0]));
117141
}
118142

119143
return null;

Tasks/Common/nuget-task-common/Utility.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,23 @@ export function resolveFilterSpec(filterSpec: string, basePath?: string, allowEm
4343
}
4444

4545
export function resolveWildcardPath(pattern: string, allowEmptyWildcardMatch?: boolean): string[] {
46+
let isWindows = os.platform() === 'win32';
47+
let toPosixPath = (path: string) => path;
48+
let toNativePath = (path: string) => path;
49+
if (isWindows) {
50+
// minimatch assumes paths use /, so on Windows, make paths use /
51+
// This needs to be done both to the pattern and to the filenames.
52+
toPosixPath = (path: string) => path.replace(/\\/g, "/");
53+
54+
// tl.find always returns forward slashes. This is problematic with UNC paths because NuGet
55+
// interprets that as a switch argument instead of a path.
56+
toNativePath = (path: string) => path.replace(/\//g, "\\");
57+
}
58+
4659
// Resolve files for the specified value or pattern
4760
var filesList: string[];
4861
if (pattern.indexOf('*') == -1 && pattern.indexOf('?') == -1) {
62+
4963
// No pattern found, check literal path to a single file
5064
tl.checkPath(pattern, 'files');
5165

@@ -78,14 +92,6 @@ export function resolveWildcardPath(pattern: string, allowEmptyWildcardMatch?: b
7892
// Now we get a list of all files under this root
7993
var allFiles = tl.find(findPathRoot);
8094

81-
let isWindows = os.platform() === 'win32';
82-
let toPosixPath: (string) => string = _ => _;
83-
if (isWindows) {
84-
// minimatch assumes paths use /, so on Windows, make paths use /
85-
// This needs to be done both to the pattern and to the filenames.
86-
toPosixPath = (path: string) => path.replace("\\", "/");
87-
}
88-
8995
// Now matching the pattern against all files
9096
// Turn off a bunch of minimatch features to replicate the be
9197
let patternFilter = tl.filter(
@@ -107,5 +113,5 @@ export function resolveWildcardPath(pattern: string, allowEmptyWildcardMatch?: b
107113
}
108114
}
109115

110-
return filesList;
116+
return filesList.map(toNativePath);
111117
}

Tasks/NuGetInstaller/nugetinstaller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import * as ngToolRunner from 'nuget-task-common/NuGetToolRunner';
1414
import * as nutil from 'nuget-task-common/Utility';
1515
import * as auth from 'nuget-task-common/Authentication'
1616
import {NuGetConfigHelper} from 'nuget-task-common/NuGetConfigHelper'
17+
import * as os from 'os';
1718

1819
class RestoreOptions {
1920
constructor(
@@ -65,8 +66,9 @@ if (!tl.filePathSupplied('nuGetPath')) {
6566
var serviceUri = tl.getEndpointUrl("SYSTEMVSSCONNECTION", false);
6667

6768
//find nuget location to use
68-
var nuGetPathToUse = ngToolRunner.locateTool('nuget.exe', userNuGetPath);
69-
var credProviderPath = ngToolRunner.locateTool('CredentialProvider.TeamBuild.exe', null, true);
69+
var nuGetExeVariants = ['nuget.exe', 'NuGet.exe', 'nuget', 'NuGet']
70+
var nuGetPathToUse = ngToolRunner.locateTool(nuGetExeVariants, {userPath: userNuGetPath, fallbackToSystemPath: os.platform() !== 'win32'});
71+
var credProviderPath = ngToolRunner.locateTool('CredentialProvider.TeamBuild.exe', {optional: true});
7072

7173
var credProviderDir: string = null;
7274
if (credProviderPath) {

Tasks/NuGetInstaller/task.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"version": {
1010
"Major": 0,
1111
"Minor": 2,
12-
"Patch": 0
12+
"Patch": 1
1313
},
1414
"minimumAgentVersion": "1.83.0",
1515
"groups": [

Tasks/NuGetInstaller/task.loc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"version": {
1010
"Major": 0,
1111
"Minor": 2,
12-
"Patch": 0
12+
"Patch": 1
1313
},
1414
"minimumAgentVersion": "1.83.0",
1515
"groups": [

Tasks/NugetPublisher/nugetpublisher.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import * as nutil from 'nuget-task-common/Utility';
1515
import * as auth from 'nuget-task-common/Authentication';
1616
import {NuGetConfigHelper} from 'nuget-task-common/NuGetConfigHelper';
1717
import * as locationApi from 'nuget-task-common/LocationApi';
18+
import * as os from 'os';
1819

1920
class PublishOptions {
2021
constructor(
@@ -62,8 +63,9 @@ if (!tl.filePathSupplied('nuGetPath')) {
6263
var serviceUri = tl.getEndpointUrl("SYSTEMVSSCONNECTION", false);
6364

6465
//find nuget location to use
65-
var nuGetPathToUse = ngToolRunner.locateTool('nuget.exe', userNuGetPath);
66-
var credProviderPath = ngToolRunner.locateTool('CredentialProvider.TeamBuild.exe', null, true);
66+
var nuGetExeVariants = ['nuget.exe', 'NuGet.exe', 'nuget', 'NuGet']
67+
var nuGetPathToUse = ngToolRunner.locateTool(nuGetExeVariants, {userPath: userNuGetPath, fallbackToSystemPath: os.platform() !== 'win32'});
68+
var credProviderPath = ngToolRunner.locateTool('CredentialProvider.TeamBuild.exe', {optional: true});
6769

6870
var credProviderDir: string = null;
6971
if (credProviderPath) {

Tasks/NugetPublisher/task.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"version": {
1010
"Major": 0,
1111
"Minor": 2,
12-
"Patch": 0
12+
"Patch": 1
1313
},
1414
"demands": [
1515
"Cmd"

Tasks/NugetPublisher/task.loc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"version": {
1010
"Major": 0,
1111
"Minor": 2,
12-
"Patch": 0
12+
"Patch": 1
1313
},
1414
"demands": [
1515
"Cmd"

definitions/nuget-task-common.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,12 @@ declare module 'nuget-task-common/NuGetToolRunner' {
101101
exec(options?: IExecOptions): Q.Promise<number>;
102102
}
103103
export function createNuGetToolRunner(nuGetExePath: string, settings: NuGetEnvironmentSettings): NuGetToolRunner;
104-
export function locateTool(tool: string, userPath?: string, optional?: boolean): string;
104+
export interface LocateOptions {
105+
optional?: boolean;
106+
userPath?: string;
107+
fallbackToSystemPath?: boolean;
108+
}
109+
export function locateTool(tool: string | string[], opts?: LocateOptions): string;
105110

106111
}
107112
declare module 'nuget-task-common/NuGetConfigHelper' {

0 commit comments

Comments
 (0)