From fd722cae61171eb05d08a4996342dd96cd53333d Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 13:53:08 -0400 Subject: [PATCH 1/7] Bump minor version --- Tasks/UsePythonVersion/task.json | 4 ++-- Tasks/UsePythonVersion/task.loc.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tasks/UsePythonVersion/task.json b/Tasks/UsePythonVersion/task.json index 93ffc894f3e1..70400b8c8d1f 100644 --- a/Tasks/UsePythonVersion/task.json +++ b/Tasks/UsePythonVersion/task.json @@ -12,8 +12,8 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 133, - "Patch": 2 + "Minor": 134, + "Patch": 0 }, "preview": true, "demands": [], diff --git a/Tasks/UsePythonVersion/task.loc.json b/Tasks/UsePythonVersion/task.loc.json index 2b670216f5ac..d5f2f8586a6d 100644 --- a/Tasks/UsePythonVersion/task.loc.json +++ b/Tasks/UsePythonVersion/task.loc.json @@ -12,8 +12,8 @@ "author": "Microsoft Corporation", "version": { "Major": 0, - "Minor": 133, - "Patch": 2 + "Minor": 134, + "Patch": 0 }, "preview": true, "demands": [], From 8d4a7b95e27a98ca5661940021a5a9111b5ccb1c Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 14:03:25 -0400 Subject: [PATCH 2/7] add failing tests --- Tasks/UsePythonVersion/Tests/L0.ts | 41 +++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/Tasks/UsePythonVersion/Tests/L0.ts b/Tasks/UsePythonVersion/Tests/L0.ts index 086ddf6295c5..4881a595b240 100644 --- a/Tasks/UsePythonVersion/Tests/L0.ts +++ b/Tasks/UsePythonVersion/Tests/L0.ts @@ -82,7 +82,7 @@ describe('UsePythonVersion L0 Suite', function () { }; mockery.registerMock('vsts-task-lib/task', Object.assign({}, mockTask, mockBuildVariables)); - const toolPath = path.join('/', 'Python', '3.6.4'); + const toolPath = path.join('/', 'Python', '3.6.4', 'x64'); mockery.registerMock('vsts-task-tool-lib/tool', { findLocalTool: () => toolPath }); @@ -119,7 +119,8 @@ describe('UsePythonVersion L0 Suite', function () { const expectedMessage = [ 'loc_mock_VersionNotFound 3.x', 'loc_mock_ListAvailableVersions', - '2.7.13' + '2.7.13 (x86)', + '2.7.13 (x64)' ].join(EOL); assert.strictEqual(e.message, expectedMessage); @@ -127,6 +128,41 @@ describe('UsePythonVersion L0 Suite', function () { } }); + it('selects architecture passed as input', async function () { + let buildVariables: { [key: string]: string } = {}; + const mockBuildVariables = { + setVariable: (variable: string, value: string) => { + buildVariables[variable] = value; + }, + getVariable: (variable: string) => buildVariables[variable] + }; + mockery.registerMock('vsts-task-lib/task', Object.assign({}, mockTask, mockBuildVariables)); + + const toolPathx86 = path.join('/', 'Python', '3.6.4', 'x86'); + const toolPathx64 = path.join('/', 'Python', '3.6.4', 'x64'); + mockery.registerMock('vsts-task-tool-lib/tool', { + findLocalTool: (toolName: string, versionSpec: string, arch?: string) => { + if (arch === 'x86') { + return toolPathx86; + } else { + return toolPathx64; + } + } + }); + + const uut = reload(); + const parameters = { + versionSpec: '3.6', + addToPath: false, + architecture: 'x86' + }; + + assert.strictEqual(buildVariables['pythonLocation'], undefined); + + await uut.usePythonVersion(parameters, Platform.Linux); + assert.strictEqual(buildVariables['pythonLocation'], toolPathx86); + }); + it('sets PATH correctly on Linux', async function () { mockery.registerMock('vsts-task-lib/task', mockTask); @@ -145,7 +181,6 @@ describe('UsePythonVersion L0 Suite', function () { const uut = reload(); const parameters = { versionSpec: '3.6', - outputVariable: 'Python', addToPath: true }; From 34092ddf7a443bc075a4aa920c821b563088c6f4 Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 14:16:22 -0400 Subject: [PATCH 3/7] expose another bug --- Tasks/UsePythonVersion/Tests/L0.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Tasks/UsePythonVersion/Tests/L0.ts b/Tasks/UsePythonVersion/Tests/L0.ts index 4881a595b240..c7e9b313b538 100644 --- a/Tasks/UsePythonVersion/Tests/L0.ts +++ b/Tasks/UsePythonVersion/Tests/L0.ts @@ -103,7 +103,7 @@ describe('UsePythonVersion L0 Suite', function () { mockery.registerMock('vsts-task-lib/task', mockTask); mockery.registerMock('vsts-task-tool-lib/tool', { findLocalTool: () => null, - findLocalToolVersions: () => ['2.7.13'] + findLocalToolVersions: () => ['2.6.0', '2.7.13'] }); const uut = reload(); @@ -119,7 +119,9 @@ describe('UsePythonVersion L0 Suite', function () { const expectedMessage = [ 'loc_mock_VersionNotFound 3.x', 'loc_mock_ListAvailableVersions', + '2.6.0 (x86)', '2.7.13 (x86)', + '2.6.0 (x64)', '2.7.13 (x64)' ].join(EOL); @@ -138,14 +140,14 @@ describe('UsePythonVersion L0 Suite', function () { }; mockery.registerMock('vsts-task-lib/task', Object.assign({}, mockTask, mockBuildVariables)); - const toolPathx86 = path.join('/', 'Python', '3.6.4', 'x86'); - const toolPathx64 = path.join('/', 'Python', '3.6.4', 'x64'); + const x86ToolPath = path.join('/', 'Python', '3.6.4', 'x86'); + const x64ToolPath = path.join('/', 'Python', '3.6.4', 'x64'); mockery.registerMock('vsts-task-tool-lib/tool', { findLocalTool: (toolName: string, versionSpec: string, arch?: string) => { if (arch === 'x86') { - return toolPathx86; + return x86ToolPath; } else { - return toolPathx64; + return x64ToolPath; } } }); @@ -160,7 +162,7 @@ describe('UsePythonVersion L0 Suite', function () { assert.strictEqual(buildVariables['pythonLocation'], undefined); await uut.usePythonVersion(parameters, Platform.Linux); - assert.strictEqual(buildVariables['pythonLocation'], toolPathx86); + assert.strictEqual(buildVariables['pythonLocation'], x86ToolPath); }); it('sets PATH correctly on Linux', async function () { From 2642272ca384831184e6fb987a70da81784d55a6 Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 14:17:47 -0400 Subject: [PATCH 4/7] List versions with architecture when a match can't be found --- Tasks/UsePythonVersion/usepythonversion.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Tasks/UsePythonVersion/usepythonversion.ts b/Tasks/UsePythonVersion/usepythonversion.ts index e470f295e3a8..3ac5ef9456dd 100644 --- a/Tasks/UsePythonVersion/usepythonversion.ts +++ b/Tasks/UsePythonVersion/usepythonversion.ts @@ -30,10 +30,19 @@ export async function usePythonVersion(parameters: TaskParameters, platform: Pla const installDir: string | null = tool.findLocalTool('Python', semanticVersionSpec); if (!installDir) { // Fail and list available versions + const x86Versions = tool.findLocalToolVersions('Python', 'x86') + .map(s => `${s} (x86)`) + .join(os.EOL); + + const x64Versions = tool.findLocalToolVersions('Python', 'x64') + .map(s => `${s} (x64)`) + .join(os.EOL); + throw new Error([ task.loc('VersionNotFound', parameters.versionSpec), task.loc('ListAvailableVersions'), - tool.findLocalToolVersions('Python') + x86Versions, + x64Versions ].join(os.EOL)); } From da860979458abefed23c8dac4b83ae06194fff24 Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 15:00:29 -0400 Subject: [PATCH 5/7] Add "architecture" parameter under "Advanced" --- .../resources.resjson/en-US/resources.resjson | 2 ++ Tasks/UsePythonVersion/Tests/L0.ts | 12 ++++++++---- Tasks/UsePythonVersion/main.ts | 3 ++- Tasks/UsePythonVersion/task.json | 13 +++++++++++++ Tasks/UsePythonVersion/task.loc.json | 13 +++++++++++++ Tasks/UsePythonVersion/usepythonversion.ts | 9 +++++---- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson b/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson index 9420b7bfbd05..e342d8258cdc 100644 --- a/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson @@ -7,6 +7,8 @@ "loc.input.help.versionSpec": "Version range or exact version of a Python version to use.", "loc.input.label.addToPath": "Add to PATH", "loc.input.help.addToPath": "Whether to prepend the retrieved Python version to the PATH environment variable to make it available in subsequent tasks or scripts without using the output variable.", + "loc.input.label.architecture": "Architecture", + "loc.input.help.architecture": "The target architecture (x86, x64) of the Python interpeter.", "loc.messages.ListAvailableVersions": "Available versions:", "loc.messages.PlatformNotRecognized": "Platform not recognized", "loc.messages.PrependPath": "Prepending PATH environment variable with directory: %s", diff --git a/Tasks/UsePythonVersion/Tests/L0.ts b/Tasks/UsePythonVersion/Tests/L0.ts index c7e9b313b538..cc21a7d7bbaa 100644 --- a/Tasks/UsePythonVersion/Tests/L0.ts +++ b/Tasks/UsePythonVersion/Tests/L0.ts @@ -90,7 +90,8 @@ describe('UsePythonVersion L0 Suite', function () { const uut = reload(); const parameters = { versionSpec: '3.6', - addToPath: false + addToPath: false, + architecture: 'x64' }; assert.strictEqual(buildVariables['pythonLocation'], undefined); @@ -109,7 +110,8 @@ describe('UsePythonVersion L0 Suite', function () { const uut = reload(); const parameters = { versionSpec: '3.x', - addToPath: false + addToPath: false, + architecture: 'x64' }; try { @@ -183,7 +185,8 @@ describe('UsePythonVersion L0 Suite', function () { const uut = reload(); const parameters = { versionSpec: '3.6', - addToPath: true + addToPath: true, + architecture: 'x64' }; await uut.usePythonVersion(parameters, Platform.Linux); @@ -210,7 +213,8 @@ describe('UsePythonVersion L0 Suite', function () { const uut = reload(); const parameters = { versionSpec: '3.6', - addToPath: true + addToPath: true, + architecture: 'x64' }; await uut.usePythonVersion(parameters, Platform.Windows); diff --git a/Tasks/UsePythonVersion/main.ts b/Tasks/UsePythonVersion/main.ts index 4f6910a65c62..4a488ae9cff8 100644 --- a/Tasks/UsePythonVersion/main.ts +++ b/Tasks/UsePythonVersion/main.ts @@ -8,7 +8,8 @@ import { usePythonVersion } from './usepythonversion'; task.setResourcePath(path.join(__dirname, 'task.json')); await usePythonVersion({ versionSpec: task.getInput('versionSpec', true), - addToPath: task.getBoolInput('addToPath', true) + addToPath: task.getBoolInput('addToPath', true), + architecture: task.getInput('architecture', true) }, getPlatform()); task.setResult(task.TaskResult.Succeeded, ""); diff --git a/Tasks/UsePythonVersion/task.json b/Tasks/UsePythonVersion/task.json index 70400b8c8d1f..35a4fda7a0b9 100644 --- a/Tasks/UsePythonVersion/task.json +++ b/Tasks/UsePythonVersion/task.json @@ -34,6 +34,19 @@ "required": true, "defaultValue": "true", "helpMarkDown": "Whether to prepend the retrieved Python version to the PATH environment variable to make it available in subsequent tasks or scripts without using the output variable." + }, + { + "name": "architecture", + "type": "pickList", + "label": "Architecture", + "defaultValue": "x64", + "required": false, + "helpMarkDown": "The target architecture (x86, x64) of the Python interpeter.", + "groupName": "advanced", + "options": { + "x86": "x86", + "x64": "x64" + } } ], "outputVariables": [ diff --git a/Tasks/UsePythonVersion/task.loc.json b/Tasks/UsePythonVersion/task.loc.json index d5f2f8586a6d..4c3f7129a8bc 100644 --- a/Tasks/UsePythonVersion/task.loc.json +++ b/Tasks/UsePythonVersion/task.loc.json @@ -34,6 +34,19 @@ "required": true, "defaultValue": "true", "helpMarkDown": "ms-resource:loc.input.help.addToPath" + }, + { + "name": "architecture", + "type": "pickList", + "label": "ms-resource:loc.input.label.architecture", + "defaultValue": "x64", + "required": false, + "helpMarkDown": "ms-resource:loc.input.help.architecture", + "groupName": "advanced", + "options": { + "x86": "x86", + "x64": "x64" + } } ], "outputVariables": [ diff --git a/Tasks/UsePythonVersion/usepythonversion.ts b/Tasks/UsePythonVersion/usepythonversion.ts index 3ac5ef9456dd..5175b4270fb3 100644 --- a/Tasks/UsePythonVersion/usepythonversion.ts +++ b/Tasks/UsePythonVersion/usepythonversion.ts @@ -11,8 +11,9 @@ import { Platform } from './taskutil'; import * as toolUtil from './toolutil'; interface TaskParameters { - readonly versionSpec: string, - readonly addToPath: boolean + versionSpec: string, + addToPath: boolean, + architecture: string } export function pythonVersionToSemantic(versionSpec: string) { @@ -20,14 +21,14 @@ export function pythonVersionToSemantic(versionSpec: string) { return versionSpec.replace(prereleaseVersion, '$1-$2'); } -export async function usePythonVersion(parameters: TaskParameters, platform: Platform): Promise { +export async function usePythonVersion(parameters: Readonly, platform: Platform): Promise { // Python's prelease versions look like `3.7.0b2`. // This is the one part of Python versioning that does not look like semantic versioning, which specifies `3.7.0-b2`. // If the version spec contains prerelease versions, we need to convert them to the semantic version equivalent const semanticVersionSpec = pythonVersionToSemantic(parameters.versionSpec); task.debug(`Semantic version spec of ${parameters.versionSpec} is ${semanticVersionSpec}`); - const installDir: string | null = tool.findLocalTool('Python', semanticVersionSpec); + const installDir: string | null = tool.findLocalTool('Python', semanticVersionSpec, parameters.architecture); if (!installDir) { // Fail and list available versions const x86Versions = tool.findLocalToolVersions('Python', 'x86') From 6a2ad3b78b5f1b7f73960ba55fa9023e2ec3a905 Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 15:35:58 -0400 Subject: [PATCH 6/7] Add "Advanced" tab --- .../Strings/resources.resjson/en-US/resources.resjson | 1 + Tasks/UsePythonVersion/task.json | 7 +++++++ Tasks/UsePythonVersion/task.loc.json | 7 +++++++ 3 files changed, 15 insertions(+) diff --git a/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson b/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson index e342d8258cdc..468cf531ec44 100644 --- a/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson +++ b/Tasks/UsePythonVersion/Strings/resources.resjson/en-US/resources.resjson @@ -3,6 +3,7 @@ "loc.helpMarkDown": "[More Information](https://go.microsoft.com/fwlink/?linkid=871498)", "loc.description": "Retrieves the specified version of Python from the tool cache. Optionally add it to PATH.", "loc.instanceNameFormat": "Use Python $(versionSpec)", + "loc.group.displayName.advanced": "Advanced", "loc.input.label.versionSpec": "Version spec", "loc.input.help.versionSpec": "Version range or exact version of a Python version to use.", "loc.input.label.addToPath": "Add to PATH", diff --git a/Tasks/UsePythonVersion/task.json b/Tasks/UsePythonVersion/task.json index 35a4fda7a0b9..0998d0e3da58 100644 --- a/Tasks/UsePythonVersion/task.json +++ b/Tasks/UsePythonVersion/task.json @@ -18,6 +18,13 @@ "preview": true, "demands": [], "instanceNameFormat": "Use Python $(versionSpec)", + "groups": [ + { + "name": "advanced", + "displayName": "Advanced", + "isExpanded": false + } + ], "inputs": [ { "name": "versionSpec", diff --git a/Tasks/UsePythonVersion/task.loc.json b/Tasks/UsePythonVersion/task.loc.json index 4c3f7129a8bc..ccc891220bb0 100644 --- a/Tasks/UsePythonVersion/task.loc.json +++ b/Tasks/UsePythonVersion/task.loc.json @@ -18,6 +18,13 @@ "preview": true, "demands": [], "instanceNameFormat": "ms-resource:loc.instanceNameFormat", + "groups": [ + { + "name": "advanced", + "displayName": "ms-resource:loc.group.displayName.advanced", + "isExpanded": false + } + ], "inputs": [ { "name": "versionSpec", From 020e8368b9541d87e1b58d864bbe1ba054fd2ae6 Mon Sep 17 00:00:00 2001 From: Brian Cristante Date: Tue, 10 Apr 2018 16:20:00 -0400 Subject: [PATCH 7/7] Architecture parameter is required --- Tasks/UsePythonVersion/task.json | 2 +- Tasks/UsePythonVersion/task.loc.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tasks/UsePythonVersion/task.json b/Tasks/UsePythonVersion/task.json index 0998d0e3da58..8ff86e5e1782 100644 --- a/Tasks/UsePythonVersion/task.json +++ b/Tasks/UsePythonVersion/task.json @@ -47,7 +47,7 @@ "type": "pickList", "label": "Architecture", "defaultValue": "x64", - "required": false, + "required": true, "helpMarkDown": "The target architecture (x86, x64) of the Python interpeter.", "groupName": "advanced", "options": { diff --git a/Tasks/UsePythonVersion/task.loc.json b/Tasks/UsePythonVersion/task.loc.json index ccc891220bb0..9b1b42e607ab 100644 --- a/Tasks/UsePythonVersion/task.loc.json +++ b/Tasks/UsePythonVersion/task.loc.json @@ -47,7 +47,7 @@ "type": "pickList", "label": "ms-resource:loc.input.label.architecture", "defaultValue": "x64", - "required": false, + "required": true, "helpMarkDown": "ms-resource:loc.input.help.architecture", "groupName": "advanced", "options": {