diff --git a/Tasks/DotNetCoreInstallerV0/Strings/resources.resjson/en-US/resources.resjson b/Tasks/DotNetCoreInstallerV0/Strings/resources.resjson/en-US/resources.resjson
index 95e966847425..7b24abe4fd1a 100644
--- a/Tasks/DotNetCoreInstallerV0/Strings/resources.resjson/en-US/resources.resjson
+++ b/Tasks/DotNetCoreInstallerV0/Strings/resources.resjson/en-US/resources.resjson
@@ -6,22 +6,24 @@
"loc.input.label.packageType": "Package to install",
"loc.input.help.packageType": "Please select whether to install only runtime or full SDK.",
"loc.input.label.version": "Version",
- "loc.input.help.version": "Specify exact version of .NET Core SDK or runtime to install.
Examples:
1. To install 1.0.4 SDK, use 1.0.4
2. To install 1.1.2 runtime, use 1.1.2
2. To install 2.0 preview 2 runtime, use 2.0.0-preview2-25407-01
For getting more details about exact version, refer [here](https://github.com/dotnet/core/blob/master/release-notes/releases.csv)",
+ "loc.input.help.version": "Specify exact version of .NET Core SDK or runtime to install.
Find the value of `version-sdk` for installing SDK, or `version-runtime` for installing Runtime from any releases [here](https://github.com/dotnet/core/blob/master/release-notes/releases.json)",
"loc.messages.ToolFailed": "Tool install failed: %s",
"loc.messages.ImplicitVersionNotSupported": "Version should be a valid and explicit version: %s",
- "loc.messages.PrimaryUrlDownloadFailed": "Failed to download .NET Core package using primary URL. Error: %s.",
- "loc.messages.LegacyUrlDownloadFailed": "Failed to download .NET Core package using legacy URL as well. Error: %s.",
- "loc.messages.DownloadFailed": "Failed to download .NET Core package. Please ensure that .NET Core %s of version %s exists. Check out: https://github.com/dotnet/core/blob/master/release-notes/releases.csv",
- "loc.messages.getDownloadUrlsFailed": "Failed to get download urls. Error: %s.",
+ "loc.messages.getMachinePlatformFailed": "Failed to get machine platform details. Error: %s.",
"loc.messages.UsingCachedTool": "Cached copy of .NET Core exists. No need to install afresh. Cached tool location: %s.",
"loc.messages.CheckingToolCache": "Checking if a cached copy exists for this version...",
"loc.messages.InstallingAfresh": "Cache does not contains this particular .NET Core. Will be downloaded and installed.",
- "loc.messages.GettingDownloadUrls": "Getting URLs to download .NET Core %s version: %s.",
- "loc.messages.NullDownloadUrls": "Could not construct download Urls. Please ensure that specified version is valid.",
- "loc.messages.DownloadingPrimaryUrl": "Downloading .NET Core package from primary URL: %s",
- "loc.messages.DownloadingSecondaryUrl": "Downloading .NET Core package from legacy URL: %s",
+ "loc.messages.GettingDownloadUrl": "Getting URL to download .NET Core %s version: %s.",
+ "loc.messages.CouldNotDetectPlatform": "Could not detect the machine's OS",
+ "loc.messages.NullDownloadUrls": "Could not construct download Url. Please ensure that specified version %s is valid.",
+ "loc.messages.DownloadingUrl": "Downloading .NET Core package from URL: %s",
"loc.messages.ExtractingPackage": "Extracting downloaded package %s.",
"loc.messages.CachingTool": "Caching this installed tool.",
"loc.messages.SuccessfullyInstalled": "Successfully installed .NET Core %s version %s.",
- "loc.messages.ToolToInstall": "Tool to install: .NET Core %s version %s."
+ "loc.messages.ToolToInstall": "Tool to install: .NET Core %s version %s.",
+ "loc.messages.PrimaryPlatform": "Detected platform (Primary): %s",
+ "loc.messages.LegacyPlatform": "Detected platform (Legacy): %s",
+ "loc.messages.VersionNotFound": "Could not fetch download information for version %s. Please check if the version specified is correct. You can refer https://github.com/dotnet/core/blob/master/release-notes/releases.json",
+ "loc.messages.CouldNotDownload": "Could not download installation package from this URL: %s Error: %s",
+ "loc.messages.FailedToDownloadPackage": "Failed to download package for installation"
}
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/Tests/InstallNix.ts b/Tasks/DotNetCoreInstallerV0/Tests/InstallNix.ts
index f334175007bb..cf6c8ea310e2 100644
--- a/Tasks/DotNetCoreInstallerV0/Tests/InstallNix.ts
+++ b/Tasks/DotNetCoreInstallerV0/Tests/InstallNix.ts
@@ -14,33 +14,27 @@ process.env["AGENT_TEMPDIRECTORY"] = "/agent/_temp";
let a: ma.TaskLibAnswers = {
"exec": {
- "/somedir/currdir/externals/install-dotnet.sh --version 1.0.4 --dry-run": {
- "code": process.env["__get_dlurls_failed__"] === "true" ? -1 : 0,
- "stdout": process.env["__get_dlurls_failed__"] === "true" ? "" : "dotnet-install: Payload URLs:" + os.EOL + "dotnet-install: Payload URL: https://primary-url" + os.EOL + "dotnet-install: Legacy payload URL: https://legacy-url" + os.EOL + "dotnet-install: Repeatable invocation:",
- "stderr": process.env["__get_dlurls_failed__"] === "true" ? "install-script failed to get donwload urls" : ""
- },
- "/somedir/currdir/externals/install-dotnet.sh --version 1.0.4 --dry-run --shared-runtime": {
+ "/somedir/currdir/externals/get-os-distro.sh": {
"code": 0,
- "stdout": "dotnet-install: Payload URLs:" + os.EOL + "dotnet-install: Payload URL: https://primary-runtime-url" + os.EOL + "dotnet-install: Legacy payload URL: https://legacy-runtime-url" + os.EOL + "dotnet-install: Repeatable invocation:"
+ "stdout": "Primary: linux" + os.EOL,
}
},
"osType": {
"osType": "Linux"
},
"which": {
- "/somedir/currdir/externals/install-dotnet.sh": "/somedir/currdir/externals/install-dotnet.sh"
+ "/somedir/currdir/externals/get-os-distro.sh": "/somedir/currdir/externals/get-os-distro.sh"
},
"checkPath": {
- "/somedir/currdir/externals/install-dotnet.sh": true
+ "/somedir/currdir/externals/get-os-distro.sh": true
}
};
-var ut = require('../utilities');
tr.registerMock('./utilities', {
- getCurrentDir : function() {
+ getCurrentDir: function () {
return "/somedir/currdir";
},
- setFileAttribute: function(file, mode) {
+ setFileAttribute: function (file, mode) {
console.log("Changing attribute for file " + file + " to " + mode);
}
});
@@ -50,4 +44,5 @@ tr.setAnswers(a);
tr.registerMock('vsts-task-lib/toolrunner', require('vsts-task-lib/mock-toolrunner'));
tr.registerMock('vsts-task-tool-lib/tool', require('./mock_node_modules/tool'));
+tr.registerMock('./releasesfetcher', require("./mock_node_modules/releasesfetcher"));
tr.run();
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/Tests/InstallWindows.ts b/Tasks/DotNetCoreInstallerV0/Tests/InstallWindows.ts
index 80171fbc428f..0873feb6cf69 100644
--- a/Tasks/DotNetCoreInstallerV0/Tests/InstallWindows.ts
+++ b/Tasks/DotNetCoreInstallerV0/Tests/InstallWindows.ts
@@ -48,4 +48,5 @@ tr.setAnswers(a);
tr.registerMock('vsts-task-lib/toolrunner', require('vsts-task-lib/mock-toolrunner'));
tr.registerMock('vsts-task-tool-lib/tool', require('./mock_node_modules/tool'));
+tr.registerMock('./releasesfetcher', require("./mock_node_modules/releasesfetcher"));
tr.run();
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/Tests/L0.ts b/Tasks/DotNetCoreInstallerV0/Tests/L0.ts
index 9109eec428c7..3536d14823bb 100644
--- a/Tasks/DotNetCoreInstallerV0/Tests/L0.ts
+++ b/Tasks/DotNetCoreInstallerV0/Tests/L0.ts
@@ -40,7 +40,7 @@ describe('DotNetCoreInstaller', function() {
assert(tr.stdout.indexOf("Checking local tool for dncs and version 1.0.4") > -1, "should check for local cached tool");
assert(tr.stdout.indexOf("loc_mock_InstallingAfresh") > -1, "should install fresh if cache miss");
assert(tr.stdout.indexOf("Downloading tool from https://primary-url") > -1, "should download from correct url");
- assert(tr.stdout.indexOf("Extracting zip archieve from C:\\agent\\_temp\\someArchieve") > -1, "Should extract downloaded archieve corectly");
+ assert(tr.stdout.indexOf("Extracting zip archive from C:\\agent\\_temp\\someArchive.zip") > -1, "Should extract downloaded archive corectly");
assert(tr.stdout.indexOf("Caching dir C:\\agent\\_temp\\someDir for tool dncs version 1.0.4") > -1, "should cache correctly");
assert(tr.stdout.indexOf("loc_mock_SuccessfullyInstalled sdk 1.0.4") > -1, "should print installed tool info");
assert(tr.stdout.indexOf("prepending path: C:\\agent\\_tools\\cacheDir") > -1, "should pre-prend to PATH");
@@ -60,7 +60,7 @@ describe('DotNetCoreInstaller', function() {
assert(tr.stdout.indexOf("Checking local tool for dncr and version 1.0.4") > -1, "should check for local cached tool");
assert(tr.stdout.indexOf("loc_mock_InstallingAfresh") > -1, "should install fresh if cache miss");
assert(tr.stdout.indexOf("Downloading tool from https://primary-runtime-url") > -1, "should download from correct url");
- assert(tr.stdout.indexOf("Extracting zip archieve from C:\\agent\\_temp\\someArchieve") > -1, "Should extract downloaded archieve corectly");
+ assert(tr.stdout.indexOf("Extracting zip archive from C:\\agent\\_temp\\someArchive.zip") > -1, "Should extract downloaded archive corectly");
assert(tr.stdout.indexOf("Caching dir C:\\agent\\_temp\\someDir for tool dncr version 1.0.4") > -1, "should cache correctly");
assert(tr.stdout.indexOf("loc_mock_SuccessfullyInstalled runtime 1.0.4") > -1, "should print installed tool info");
assert(tr.stdout.indexOf("prepending path: C:\\agent\\_tools\\cacheDir") > -1, "should pre-prend to PATH");
@@ -96,7 +96,7 @@ describe('DotNetCoreInstaller', function() {
runValidations(() => {
assert(tr.succeeded, "Should have succeeded");
- assert(tr.stdout.indexOf("loc_mock_PrimaryUrlDownloadFailed 404 not found https://primary-url") >= -1, "should print primary url failure error")
+ assert(tr.stdout.indexOf("404 not found https://primary-url") > -1, "should print primary url failure error")
assert(tr.stdout.indexOf("Downloading tool from https://legacy-url") > -1, "should download from legacy url");
}, tr, done);
});
@@ -137,9 +137,9 @@ describe('DotNetCoreInstaller', function() {
assert(tr.stdout.indexOf("loc_mock_ToolToInstall sdk 1.0.4") > -1, "should print to-be-installed info");
assert(tr.stdout.indexOf("Checking local tool for dncs and version 1.0.4") > -1, "should check for local cached tool");
assert(tr.stdout.indexOf("loc_mock_InstallingAfresh") > -1, "should install fresh if cache miss");
- assert(tr.stdout.indexOf("Changing attribute for file /somedir/currdir/externals/install-dotnet.sh to 777") > -1, "should iset executable attribute for install script");
+ assert(tr.stdout.indexOf("Changing attribute for file /somedir/currdir/externals/get-os-distro.sh to 777") > -1, "should iset executable attribute for install script");
assert(tr.stdout.indexOf("Downloading tool from https://primary-url") > -1, "should download from correct url");
- assert(tr.stdout.indexOf("Extracting tar archieve from /agent/_temp/someArchieve") > -1, "Should extract downloaded archieve corectly");
+ assert(tr.stdout.indexOf("Extracting tar archive from /agent/_temp/someArchive.tar") > -1, "Should extract downloaded archive corectly");
assert(tr.stdout.indexOf("Caching dir /agent/_temp/someDir for tool dncs version 1.0.4") > -1, "should cache correctly");
assert(tr.stdout.indexOf("loc_mock_SuccessfullyInstalled sdk 1.0.4") > -1, "should print installed tool info");
assert(tr.stdout.indexOf("prepending path: /agent/_tools/cacheDir") > -1, "should pre-prend to PATH");
@@ -159,7 +159,7 @@ describe('DotNetCoreInstaller', function() {
assert(tr.stdout.indexOf("Checking local tool for dncr and version 1.0.4") > -1, "should check for local cached tool");
assert(tr.stdout.indexOf("loc_mock_InstallingAfresh") > -1, "should install fresh if cache miss");
assert(tr.stdout.indexOf("Downloading tool from https://primary-runtime-url") > -1, "should download from correct url");
- assert(tr.stdout.indexOf("Extracting tar archieve from /agent/_temp/someArchieve") > -1, "Should extract downloaded archieve corectly");
+ assert(tr.stdout.indexOf("Extracting tar archive from /agent/_temp/someArchive.tar") > -1, "Should extract downloaded archive corectly");
assert(tr.stdout.indexOf("Caching dir /agent/_temp/someDir for tool dncr version 1.0.4") > -1, "should cache correctly");
assert(tr.stdout.indexOf("loc_mock_SuccessfullyInstalled runtime 1.0.4") > -1, "should print installed tool info");
assert(tr.stdout.indexOf("prepending path: /agent/_tools/cacheDir") > -1, "should pre-prend to PATH");
@@ -184,5 +184,19 @@ describe('DotNetCoreInstaller', function() {
assert(tr.stdout.indexOf("prepending path: /agent/_tools/oldCacheDir") > -1, "should pre-prend to PATH");
}, tr, done);
});
+
+ it("[nix]Should download using DLC url if primary url does not work", (done) => {
+ process.env["__primary_url_failed__"] = "true";
+ let tp = path.join(__dirname, "InstallNix.js");
+ let tr = new ttm.MockTestRunner(tp);
+ tr.run();
+ delete process.env["__primary_url_failed__"];
+
+ runValidations(() => {
+ assert(tr.succeeded, "Should have succeeded");
+ assert(tr.stdout.indexOf("404 not found https://primary-url") > -1, "should print primary url failure error")
+ assert(tr.stdout.indexOf("Downloading tool from https://legacy-url") > -1, "should download from legacy url");
+ }, tr, done);
+ });
}
});
diff --git a/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/releasesfetcher.ts b/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/releasesfetcher.ts
new file mode 100644
index 000000000000..8306a103f2fd
--- /dev/null
+++ b/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/releasesfetcher.ts
@@ -0,0 +1,18 @@
+export class DotNetCoreReleaseFetcher {
+
+ public static async getDownloadUrls(osSuffixes: string[], version: string, type: string) {
+ if (process.env["__get_dlurls_failed__"] == "true") {
+ throw "loc_mock_getDownloadUrlsFailed install-script failed to get donwload urls";
+ }
+ if (process.env["__primary_url_failed__"] == "true") {
+ return ["https://primary-url", "https://legacy-url"];
+ }
+
+ if (type == "sdk" && version == "1.0.4") {
+ return ["https://primary-url"];
+ }
+ if (type == "runtime") {
+ return ["https://primary-runtime-url"];
+ }
+ }
+}
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/tool.js b/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/tool.js
index 73ec3a955e47..2d3d418a97bd 100644
--- a/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/tool.js
+++ b/Tasks/DotNetCoreInstallerV0/Tests/mock_node_modules/tool.js
@@ -1,8 +1,9 @@
var tl = require('vsts-task-lib/task');
var path = require('path');
+var os = require('os');
function isExplicitVersion(versionSpec) {
- if(process.env["__implicit_version__"] === "true") {
+ if (process.env["__implicit_version__"] === "true") {
return false;
}
@@ -17,7 +18,7 @@ exports.prependPath = prependPath;
function findLocalTool(toolName, versionSpec, arch) {
console.log("Checking local tool for " + toolName + " and version " + versionSpec);
- if(process.env["__cache_hit__"] === "true") {
+ if (process.env["__cache_hit__"] === "true") {
return path.join(tl.getVariable('Agent.ToolsDirectory'), "oldCacheDir");
}
return null;
@@ -25,27 +26,27 @@ function findLocalTool(toolName, versionSpec, arch) {
exports.findLocalTool = findLocalTool;
function downloadTool(url, fileName) {
- if( process.env["__primary_url_failed__"] === "true" && url === "https://primary-url") {
+ if (process.env["__primary_url_failed__"] === "true" && url === "https://primary-url") {
throw "404 not found " + url;
}
console.log("Downloading tool from " + url);
- return path.join(tl.getVariable('Agent.TempDirectory'), "someArchieve");
+ return path.join(tl.getVariable('Agent.TempDirectory'), "someArchive" + (os.type().match(/^Win/) ? ".zip" : ".tar"));
}
exports.downloadTool = downloadTool;
function extractZip(file) {
- if( process.env["__extract_failed__"] === "true") {
+ if (process.env["__extract_failed__"] === "true") {
throw "unzip failed with some error";
}
- console.log("Extracting zip archieve from " + file);
+ console.log("Extracting zip archive from " + file);
return path.join(tl.getVariable('Agent.TempDirectory'), "someDir");
}
exports.extractZip = extractZip;
function extractTar(file) {
- console.log("Extracting tar archieve from " + file);
+ console.log("Extracting tar archive from " + file);
return path.join(tl.getVariable('Agent.TempDirectory'), "someDir");
}
exports.extractTar = extractTar;
diff --git a/Tasks/DotNetCoreInstallerV0/dotnetcoreinstaller.ts b/Tasks/DotNetCoreInstallerV0/dotnetcoreinstaller.ts
index 34bb110e577e..e5c1fd4677a9 100644
--- a/Tasks/DotNetCoreInstallerV0/dotnetcoreinstaller.ts
+++ b/Tasks/DotNetCoreInstallerV0/dotnetcoreinstaller.ts
@@ -1,171 +1,136 @@
-import * as taskLib from 'vsts-task-lib/task';
+import * as tl from 'vsts-task-lib/task';
import * as toolLib from 'vsts-task-tool-lib/tool';
import * as trm from 'vsts-task-lib/toolrunner';
-import * as utils from "./utilities";
+import { DotNetCoreReleaseFetcher } from "./releasesfetcher";
+import * as utilities from "./utilities";
import * as os from 'os';
import * as path from 'path';
-async function run() {
- let packageType = taskLib.getInput('packageType', true);
- let version = taskLib.getInput('version', true).trim();
- console.log(taskLib.loc("ToolToInstall", packageType, version));
- await getDotnetCore(packageType, version);
-}
-
-async function getDotnetCore(packageType: string, version: string): Promise {
- if (!toolLib.isExplicitVersion(version)) {
- throw taskLib.loc("ImplicitVersionNotSupported", version);
+class DotnetCoreInstaller {
+ constructor(packageType, version) {
+ this.packageType = packageType;
+ if (!toolLib.isExplicitVersion(version)) {
+ throw tl.loc("ImplicitVersionNotSupported", version);
+ }
+ this.version = version;
+ this.cachedToolName = this.packageType === 'runtime' ? 'dncr' : 'dncs';;
}
- // check cache
- let toolPath: string;
- toolPath = getLocalTool(packageType, version);
+ public async install() {
+ // Check cache
+ let toolPath: string;
+ toolPath = this.getLocalTool();
+
+ if (!toolPath) {
+ // download, extract, cache
+ console.log(tl.loc("InstallingAfresh"));
+ let osSuffixes = this.detectMachineOS();
+ console.log(tl.loc("GettingDownloadUrl", this.packageType, this.version));
+ let downloadUrls = await DotNetCoreReleaseFetcher.getDownloadUrls(osSuffixes, this.version, this.packageType);
+ toolPath = await this.downloadAndInstall(downloadUrls);
+ } else {
+ console.log(tl.loc("UsingCachedTool", toolPath));
+ }
+
+ // Prepend the tools path. instructs the agent to prepend for future tasks
+ toolLib.prependPath(toolPath);
- if (!toolPath) {
- // download, extract, cache
- console.log(taskLib.loc("InstallingAfresh"));
- toolPath = await acquireDotNetCore(packageType, version);
- } else {
- console.log(taskLib.loc("UsingCachedTool", toolPath));
+ // Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
+ tl.setVariable('DOTNET_ROOT', toolPath);
}
- // prepend the tools path. instructs the agent to prepend for future tasks
- toolLib.prependPath(toolPath);
- // set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
- taskLib.setVariable('DOTNET_ROOT', toolPath);
-}
+ private getLocalTool(): string {
+ console.log(tl.loc("CheckingToolCache"));
+ return toolLib.findLocalTool(this.cachedToolName, this.version);
+ }
-function getCachedToolName(packageType: string): string {
- // use short names to not unnecessarily run into path limit issues
- return packageType === 'runtime' ? 'dncr' : 'dncs';
-}
+ private detectMachineOS(): string[] {
+ let osSuffix = [];
-function getLocalTool(packageType: string, version:string): string {
- console.log(taskLib.loc("CheckingToolCache"));
- let cachedToolName = getCachedToolName(packageType);
- return toolLib.findLocalTool(cachedToolName, version);
-}
+ if (tl.osType().match(/^Win/)) {
+ let primary = "win-" + os.arch();
+ osSuffix.push(primary);
+ console.log(tl.loc("PrimaryPlatform", primary));
+ }
+ else {
+ let scriptPath = path.join(utilities.getCurrentDir(), 'externals', 'get-os-distro.sh');
+ utilities.setFileAttribute(scriptPath, "777");
-async function acquireDotNetCore(packageType: string, version: string): Promise {
- let downloadUrls = getDownloadUrls(packageType, version);
- let downloadPath: string;
+ let scriptRunner: trm.ToolRunner = tl.tool(tl.which(scriptPath, true));
+ let result: trm.IExecSyncResult = scriptRunner.execSync();
- try {
- // try primary url
- if (!!downloadUrls[0]) {
- console.log(taskLib.loc("DownloadingPrimaryUrl", downloadUrls[0]));
- downloadPath = await toolLib.downloadTool(downloadUrls[0]);
- }
- } catch (error1) {
- console.log(taskLib.loc("PrimaryUrlDownloadFailed", error1));
- try {
- // try secondary url
- if (!!downloadUrls[1]) {
- console.log(taskLib.loc("DownloadingSecondaryUrl", downloadUrls[1]));
- downloadPath = await toolLib.downloadTool(downloadUrls[1]);
+ if (result.code != 0) {
+ throw tl.loc("getMachinePlatformFailed", result.error ? result.error.message : result.stderr);
}
- } catch (error2) {
- console.log(taskLib.loc("LegacyUrlDownloadFailed", error2));
- throw taskLib.loc("DownloadFailed", packageType, version);
- }
- }
- // extract
- let extPath: string;
- console.log(taskLib.loc("ExtractingPackage", downloadPath));
- if (taskLib.osType().match(/^Win/)) {
- extPath = await toolLib.extractZip(downloadPath);
- }
- else {
- extPath = await toolLib.extractTar(downloadPath);
- }
+ let output: string = result.stdout;
- // cache tool
- let cachedToolName = getCachedToolName(packageType);
- console.log(taskLib.loc("CachingTool"));
- let cachedDir = await toolLib.cacheDir(extPath, cachedToolName, version);
- console.log(taskLib.loc("SuccessfullyInstalled", packageType, version));
- return cachedDir;
-}
+ let index;
+ if ((index = output.indexOf("Primary:")) >= 0) {
+ let primary = output.substr(index + "Primary:".length).split(os.EOL)[0];
+ osSuffix.push(primary);
+ console.log(tl.loc("PrimaryPlatform", primary));
+ }
-function getDownloadUrls(packageType: string, version: string): string[] {
- let scriptRunner: trm.ToolRunner;
- let primaryUrlSearchString: string;
- let legacyUrlSearchString: string;
-
- console.log(taskLib.loc("GettingDownloadUrls", packageType, version));
- if(taskLib.osType().match(/^Win/)) {
- let escapedScript = path.join(utils.getCurrentDir(), 'externals', 'install-dotnet.ps1').replace(/'/g, "''");
- let command = `& '${escapedScript}' -Version ${version} -DryRun`
- if(packageType === 'runtime') {
- command = command.concat(" -SharedRuntime");
- }
+ if (index = output.indexOf("Legacy:") >= 0) {
+ let legacy = output.substr(index + "Legacy:".length).split(os.EOL)[0];
+ osSuffix.push(legacy);
+ console.log(tl.loc("LegacyPlatform", legacy));
+ }
- let powershellPath = taskLib.which('powershell', true);
- scriptRunner = taskLib.tool(powershellPath)
- .line('-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command')
- .arg(command);
-
- primaryUrlSearchString = "dotnet-install: Primary - ";
- legacyUrlSearchString = "dotnet-install: Legacy - ";
- } else {
- let escapedScript = path.join(utils.getCurrentDir(), 'externals', 'install-dotnet.sh').replace(/'/g, "''");
- utils.setFileAttribute(escapedScript, "777");
- scriptRunner = taskLib.tool(taskLib.which(escapedScript, true));
- scriptRunner.arg('--version');
- scriptRunner.arg(version);
- scriptRunner.arg('--dry-run');
- if(packageType === 'runtime') {
- scriptRunner.arg('--shared-runtime');
+ if (osSuffix.length == 0) {
+ throw tl.loc("CouldNotDetectPlatform");
+ }
}
- primaryUrlSearchString = "dotnet-install: Payload URL: ";
- legacyUrlSearchString = "dotnet-install: Legacy payload URL: ";
+ return osSuffix;
}
- let result: trm.IExecSyncResult = scriptRunner.execSync();
- if(result.code != 0) {
- throw taskLib.loc("getDownloadUrlsFailed", result.error ? result.error.message : result.stderr);
- }
+ private async downloadAndInstall(downloadUrls: string[]) {
+ let downloaded = false;
+ let downloadPath = "";
+ for (var i = 0; i < downloadUrls.length; i++) {
+ try {
+ downloadPath = await toolLib.downloadTool(downloadUrls[i]);
+ downloaded = true;
+ break;
+ } catch (error) {
+ tl.warning(tl.loc("CouldNotDownload", downloadUrls[i], JSON.stringify(error)));
+ }
+ }
- let output: string = result.stdout;
-
- let primaryUrl: string = null;
- let legacyUrl: string = null;
- if(!!output && output.length > 0) {
- let lines: string[] = output.split(os.EOL);
- if(!!lines && lines.length > 0) {
- lines.forEach((line: string) => {
- if(!line) { return; }
- var primarySearchStringIndex = line.indexOf(primaryUrlSearchString);
- if(primarySearchStringIndex > -1) {
- primaryUrl = line.substring(primarySearchStringIndex + primaryUrlSearchString.length);
- return;
- }
-
- var legacySearchStringIndex = line.indexOf(legacyUrlSearchString);
- if(legacySearchStringIndex > -1) {
- legacyUrl = line.substring(legacySearchStringIndex + legacyUrlSearchString.length);
- return;
- }
- });
+ if (!downloaded) {
+ throw tl.loc("FailedToDownloadPackage");
}
- }
- if(!primaryUrl && !legacyUrl) {
- throw taskLib.loc("NullDownloadUrls");
+ // extract
+ console.log(tl.loc("ExtractingPackage", downloadPath));
+ let extPath: string = downloadPath.endsWith(".zip") ? await toolLib.extractZip(downloadPath) : await toolLib.extractTar(downloadPath);
+
+ // cache tool
+ console.log(tl.loc("CachingTool"));
+ let cachedDir = await toolLib.cacheDir(extPath, this.cachedToolName, this.version);
+ console.log(tl.loc("SuccessfullyInstalled", this.packageType, this.version));
+ return cachedDir;
}
- return [primaryUrl, legacyUrl];
+ private packageType: string;
+ private version: string;
+ private cachedToolName: string;
+}
+
+async function run() {
+ let packageType = tl.getInput('packageType', true);
+ let version = tl.getInput('version', true).trim();
+ console.log(tl.loc("ToolToInstall", packageType, version));
+ await new DotnetCoreInstaller(packageType, version).install();
}
var taskManifestPath = path.join(__dirname, "task.json");
-taskLib.debug("Setting resource path to " + taskManifestPath);
-taskLib.setResourcePath(taskManifestPath);
-
-run().then((result) =>
- taskLib.setResult(taskLib.TaskResult.Succeeded, "")
-).catch((error) =>
- taskLib.setResult(taskLib.TaskResult.Failed, !!error.message ? error.message : error)
-);
+tl.debug("Setting resource path to " + taskManifestPath);
+tl.setResourcePath(taskManifestPath);
+
+run()
+ .then(() => tl.setResult(tl.TaskResult.Succeeded, ""))
+ .catch((error) => tl.setResult(tl.TaskResult.Failed, !!error.message ? error.message : error));
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/externals/get-os-distro.sh b/Tasks/DotNetCoreInstallerV0/externals/get-os-distro.sh
new file mode 100644
index 000000000000..af2a48025bce
--- /dev/null
+++ b/Tasks/DotNetCoreInstallerV0/externals/get-os-distro.sh
@@ -0,0 +1,167 @@
+#!/usr/bin/env bash
+# Copyright (c) .NET Foundation and contributors. All rights reserved.
+# Licensed under the MIT license. See LICENSE file in the project root for full license information.
+#
+
+# Stop script on NZEC
+set -e
+# Stop script if unbound variable found (use ${var:-} if intentional)
+set -u
+# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
+# This is causing it to fail
+set -o pipefail
+
+# Use in the the functions: eval $invocation
+invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
+
+# standard output may be used as a return value in the functions
+# we need a way to write text on the screen in the functions so that
+# it won't interfere with the return value.
+# Exposing stream 3 as a pipe to standard output of the script itself
+exec 3>&1
+
+say_err() {
+ printf "%b\n" "get-os-distro: Error: $1" >&2
+}
+
+# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
+# then and only then should the Linux distribution appear in this list.
+# Adding a Linux distribution to this list does not imply distribution-specific support.
+get_legacy_os_name_from_platform() {
+
+ platform="$1"
+ case "$platform" in
+ "centos.7")
+ echo "centos"
+ return 0
+ ;;
+ "debian.8")
+ echo "debian"
+ return 0
+ ;;
+ "fedora.23")
+ echo "fedora.23"
+ return 0
+ ;;
+ "fedora.27")
+ echo "fedora.27"
+ return 0
+ ;;
+ "fedora.24")
+ echo "fedora.24"
+ return 0
+ ;;
+ "opensuse.13.2")
+ echo "opensuse.13.2"
+ return 0
+ ;;
+ "opensuse.42.1")
+ echo "opensuse.42.1"
+ return 0
+ ;;
+ "opensuse.42.3")
+ echo "opensuse.42.3"
+ return 0
+ ;;
+ "rhel.7"*)
+ echo "rhel"
+ return 0
+ ;;
+ "ubuntu.14.04")
+ echo "ubuntu"
+ return 0
+ ;;
+ "ubuntu.16.04")
+ echo "ubuntu.16.04"
+ return 0
+ ;;
+ "ubuntu.16.10")
+ echo "ubuntu.16.10"
+ return 0
+ ;;
+ "ubuntu.18.04")
+ echo "ubuntu.18.04"
+ return 0
+ ;;
+ "alpine.3.4.3")
+ echo "alpine"
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+get_linux_platform_name() {
+
+ if [ -e /etc/os-release ]; then
+ . /etc/os-release
+ echo "$ID.$VERSION_ID"
+ return 0
+ elif [ -e /etc/redhat-release ]; then
+ local redhatRelease=$(&1
-
-# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors.
-# See if stdout is a terminal
-if [ -t 1 ]; then
- # see if it supports colors
- ncolors=$(tput colors)
- if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
- bold="$(tput bold || echo)"
- normal="$(tput sgr0 || echo)"
- black="$(tput setaf 0 || echo)"
- red="$(tput setaf 1 || echo)"
- green="$(tput setaf 2 || echo)"
- yellow="$(tput setaf 3 || echo)"
- blue="$(tput setaf 4 || echo)"
- magenta="$(tput setaf 5 || echo)"
- cyan="$(tput setaf 6 || echo)"
- white="$(tput setaf 7 || echo)"
- fi
-fi
-
-say_err() {
- printf "%b\n" "${red:-}dotnet_install: Error: $1${normal:-}" >&2
-}
-
-say() {
- # using stream 3 (defined in the beginning) to not interfere with stdout of functions
- # which may be used as return value
- printf "%b\n" "${cyan:-}dotnet-install:${normal:-} $1" >&3
-}
-
-say_verbose() {
- if [ "$verbose" = true ]; then
- say "$1"
- fi
-}
-
-get_os_download_name_from_platform() {
- eval $invocation
-
- platform="$1"
- case "$platform" in
- "centos.7")
- echo "centos"
- return 0
- ;;
- "debian.8")
- echo "debian"
- return 0
- ;;
- "fedora.23")
- echo "fedora.23"
- return 0
- ;;
- "fedora.24")
- echo "fedora.24"
- return 0
- ;;
- "opensuse.13.2")
- echo "opensuse.13.2"
- return 0
- ;;
- "opensuse.42.1")
- echo "opensuse.42.1"
- return 0
- ;;
- "rhel.7"*)
- echo "rhel"
- return 0
- ;;
- "ubuntu.14.04")
- echo "ubuntu"
- return 0
- ;;
- "ubuntu.16.04")
- echo "ubuntu.16.04"
- return 0
- ;;
- "ubuntu.16.10")
- echo "ubuntu.16.10"
- return 0
- ;;
- "alpine.3.4.3")
- echo "alpine"
- return 0
- ;;
- esac
- return 1
-}
-
-get_current_os_name() {
- eval $invocation
-
- local uname=$(uname)
- if [ "$uname" = "Darwin" ]; then
- echo "osx"
- return 0
- else
- if [ "$uname" = "Linux" ]; then
- echo "linux"
- return 0
- fi
- fi
-
- say_err "OS name could not be detected: $ID.$VERSION_ID"
- return 1
-}
-
-get_distro_specific_os_name() {
- eval $invocation
-
- local uname=$(uname)
- if [ "$uname" = "Darwin" ]; then
- echo "osx"
- return 0
- elif [ -n "$runtime_id" ]; then
- echo $(get_os_download_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}")
- return 0
- else
- if [ -e /etc/os-release ]; then
- . /etc/os-release
- os=$(get_os_download_name_from_platform "$ID.$VERSION_ID" || echo "")
- if [ -n "$os" ]; then
- echo "$os"
- return 0
- fi
- fi
- fi
-
- say_verbose "Distribution specific OS name and version could not be detected: $ID.$VERSION_ID"
- return 1
-}
-
-machine_has() {
- eval $invocation
-
- hash "$1" > /dev/null 2>&1
- return $?
-}
-
-
-check_min_reqs() {
- local hasMinimum=false
- if machine_has "curl"; then
- hasMinimum=true
- elif machine_has "wget"; then
- hasMinimum=true
- fi
-
- if [ "$hasMinimum" = "false" ]; then
- say_err "curl (recommended) or wget are required to download dotnet. Install missing prerequisite to proceed."
- return 1
- fi
- return 0
-}
-
-check_pre_reqs() {
- eval $invocation
-
- local failing=false;
-
- if [ "${DOTNET_INSTALL_SKIP_PREREQS:-}" = "1" ]; then
- return 0
- fi
-
- if [ "$(uname)" = "Linux" ]; then
- if ! [ -x "$(command -v ldconfig)" ]; then
- echo "ldconfig is not in PATH, trying /sbin/ldconfig."
- LDCONFIG_COMMAND="/sbin/ldconfig"
- else
- LDCONFIG_COMMAND="ldconfig"
- fi
-
- [ -z "$($LDCONFIG_COMMAND -p | grep libunwind)" ] && say_err "Unable to locate libunwind. Install libunwind to continue" && failing=true
- [ -z "$($LDCONFIG_COMMAND -p | grep libssl)" ] && say_err "Unable to locate libssl. Install libssl to continue" && failing=true
- [ -z "$($LDCONFIG_COMMAND -p | grep libicu)" ] && say_err "Unable to locate libicu. Install libicu to continue" && failing=true
- fi
-
- if [ "$failing" = true ]; then
- return 1
- fi
-
- return 0
-}
-
-# args:
-# input - $1
-to_lowercase() {
- #eval $invocation
-
- echo "$1" | tr '[:upper:]' '[:lower:]'
- return 0
-}
-
-# args:
-# input - $1
-remove_trailing_slash() {
- #eval $invocation
-
- local input=${1:-}
- echo "${input%/}"
- return 0
-}
-
-# args:
-# input - $1
-remove_beginning_slash() {
- #eval $invocation
-
- local input=${1:-}
- echo "${input#/}"
- return 0
-}
-
-# args:
-# root_path - $1
-# child_path - $2 - this parameter can be empty
-combine_paths() {
- eval $invocation
-
- # TODO: Consider making it work with any number of paths. For now:
- if [ ! -z "${3:-}" ]; then
- say_err "combine_paths: Function takes two parameters."
- return 1
- fi
-
- local root_path=$(remove_trailing_slash $1)
- local child_path=$(remove_beginning_slash ${2:-})
- say_verbose "combine_paths: root_path=$root_path"
- say_verbose "combine_paths: child_path=$child_path"
- echo "$root_path/$child_path"
- return 0
-}
-
-get_machine_architecture() {
- eval $invocation
-
- # Currently the only one supported
- echo "x64"
- return 0
-}
-
-# args:
-# architecture - $1
-get_normalized_architecture_from_architecture() {
- eval $invocation
-
- local architecture=$(to_lowercase $1)
- case $architecture in
- \)
- echo "$(get_normalized_architecture_from_architecture $(get_machine_architecture))"
- return 0
- ;;
- amd64|x64)
- echo "x64"
- return 0
- ;;
- x86)
- say_err "Architecture \`x86\` currently not supported"
- return 1
- ;;
- esac
-
- say_err "Architecture \`$architecture\` not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues"
- return 1
-}
-
-# version_info is a conceptual two line string representing commit hash and 4-part version
-# format:
-# Line 1: # commit_hash
-# Line 2: # 4-part version
-
-# args:
-# version_text - stdin
-get_version_from_version_info() {
- eval $invocation
-
- cat | tail -n 1
- return 0
-}
-
-# args:
-# version_text - stdin
-get_commit_hash_from_version_info() {
- eval $invocation
-
- cat | head -n 1
- return 0
-}
-
-# args:
-# install_root - $1
-# relative_path_to_package - $2
-# specific_version - $3
-is_dotnet_package_installed() {
- eval $invocation
-
- local install_root=$1
- local relative_path_to_package=$2
- local specific_version=${3//[$'\t\r\n']}
-
- local dotnet_package_path=$(combine_paths $(combine_paths $install_root $relative_path_to_package) $specific_version)
- say_verbose "is_dotnet_package_installed: dotnet_package_path=$dotnet_package_path"
-
- if [ -d "$dotnet_package_path" ]; then
- return 0
- else
- return 1
- fi
-}
-
-# args:
-# azure_feed - $1
-# channel - $2
-# normalized_architecture - $3
-get_latest_version_info() {
- eval $invocation
-
- local azure_feed=$1
- local channel=$2
- local normalized_architecture=$3
- local coherent=$4
-
- local version_file_url=null
- if [ "$shared_runtime" = true ]; then
- version_file_url="$uncached_feed/Runtime/$channel/latest.version"
- else
- if [ "$coherent" = true ]; then
- version_file_url="$uncached_feed/Sdk/$channel/latest.coherent.version"
- else
- version_file_url="$uncached_feed/Sdk/$channel/latest.version"
- fi
- fi
- say_verbose "get_latest_version_info: latest url: $version_file_url"
-
- download $version_file_url
- return $?
-}
-
-# args:
-# azure_feed - $1
-# channel - $2
-# normalized_architecture - $3
-# version - $4
-get_specific_version_from_version() {
- eval $invocation
-
- local azure_feed=$1
- local channel=$2
- local normalized_architecture=$3
- local version=$(to_lowercase $4)
-
- case $version in
- latest)
- local version_info
- version_info="$(get_latest_version_info $azure_feed $channel $normalized_architecture false)" || return 1
- say_verbose "get_specific_version_from_version: version_info=$version_info"
- echo "$version_info" | get_version_from_version_info
- return 0
- ;;
- coherent)
- local version_info
- version_info="$(get_latest_version_info $azure_feed $channel $normalized_architecture true)" || return 1
- say_verbose "get_specific_version_from_version: version_info=$version_info"
- echo "$version_info" | get_version_from_version_info
- return 0
- ;;
- *)
- echo $version
- return 0
- ;;
- esac
-}
-
-# args:
-# azure_feed - $1
-# channel - $2
-# normalized_architecture - $3
-# specific_version - $4
-construct_download_link() {
- eval $invocation
-
- local azure_feed=$1
- local channel=$2
- local normalized_architecture=$3
- local specific_version=${4//[$'\t\r\n']}
-
- local osname
- osname=$(get_current_os_name) || return 1
-
- local download_link=null
- if [ "$shared_runtime" = true ]; then
- download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_version-$osname-$normalized_architecture.tar.gz"
- else
- download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_version-$osname-$normalized_architecture.tar.gz"
- fi
-
- echo "$download_link"
- return 0
-}
-
-# args:
-# azure_feed - $1
-# channel - $2
-# normalized_architecture - $3
-# specific_version - $4
-construct_legacy_download_link() {
- eval $invocation
-
- local azure_feed=$1
- local channel=$2
- local normalized_architecture=$3
- local specific_version=${4//[$'\t\r\n']}
-
- local distro_specific_osname
- distro_specific_osname=$(get_distro_specific_os_name) || return 1
-
- local legacy_download_link=null
- if [ "$shared_runtime" = true ]; then
- legacy_download_link="$azure_feed/Runtime/$specific_version/dotnet-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz"
- else
- legacy_download_link="$azure_feed/Sdk/$specific_version/dotnet-dev-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz"
- fi
-
- echo "$legacy_download_link"
- return 0
-}
-
-get_user_install_path() {
- eval $invocation
-
- if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then
- echo $DOTNET_INSTALL_DIR
- else
- echo "$HOME/.dotnet"
- fi
- return 0
-}
-
-# args:
-# install_dir - $1
-resolve_installation_path() {
- eval $invocation
-
- local install_dir=$1
- if [ "$install_dir" = "" ]; then
- local user_install_path=$(get_user_install_path)
- say_verbose "resolve_installation_path: user_install_path=$user_install_path"
- echo "$user_install_path"
- return 0
- fi
-
- echo "$install_dir"
- return 0
-}
-
-# args:
-# install_root - $1
-get_installed_version_info() {
- eval $invocation
-
- local install_root=$1
- local version_file=$(combine_paths "$install_root" "$local_version_file_relative_path")
- say_verbose "Local version file: $version_file"
- if [ ! -z "$version_file" ] | [ -r "$version_file" ]; then
- local version_info="$(cat $version_file)"
- echo "$version_info"
- return 0
- fi
-
- say_verbose "Local version file not found."
- return 0
-}
-
-# args:
-# relative_or_absolute_path - $1
-get_absolute_path() {
- eval $invocation
-
- local relative_or_absolute_path=$1
- echo $(cd $(dirname "$1") && pwd -P)/$(basename "$1")
- return 0
-}
-
-# args:
-# input_files - stdin
-# root_path - $1
-# out_path - $2
-# override - $3
-copy_files_or_dirs_from_list() {
- eval $invocation
-
- local root_path=$(remove_trailing_slash $1)
- local out_path=$(remove_trailing_slash $2)
- local override=$3
- local override_switch=$(if [ "$override" = false ]; then printf -- "-n"; fi)
-
- cat | uniq | while read -r file_path; do
- local path=$(remove_beginning_slash ${file_path#$root_path})
- local target=$out_path/$path
- if [ "$override" = true ] || (! ([ -d "$target" ] || [ -e "$target" ])); then
- mkdir -p $out_path/$(dirname $path)
- cp -R $override_switch $root_path/$path $target
- fi
- done
-}
-
-# args:
-# zip_path - $1
-# out_path - $2
-extract_dotnet_package() {
- eval $invocation
-
- local zip_path=$1
- local out_path=$2
-
- local temp_out_path=$(mktemp -d $temporary_file_template)
-
- local failed=false
- tar -xzf "$zip_path" -C "$temp_out_path" > /dev/null || failed=true
-
- local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/'
- find $temp_out_path -type f | grep -Eo $folders_with_version_regex | copy_files_or_dirs_from_list $temp_out_path $out_path false
- find $temp_out_path -type f | grep -Ev $folders_with_version_regex | copy_files_or_dirs_from_list $temp_out_path $out_path true
-
- rm -rf $temp_out_path
-
- if [ "$failed" = true ]; then
- say_err "Extraction failed"
- return 1
- fi
-}
-
-# args:
-# remote_path - $1
-# [out_path] - $2 - stdout if not provided
-download() {
- eval $invocation
-
- local remote_path=$1
- local out_path=${2:-}
-
- local failed=false
- if machine_has "curl"; then
- downloadcurl $remote_path $out_path || failed=true
- elif machine_has "wget"; then
- downloadwget $remote_path $out_path || failed=true
- else
- failed=true
- fi
- if [ "$failed" = true ]; then
- say_verbose "Download failed: $remote_path"
- return 1
- fi
- return 0
-}
-
-downloadcurl() {
- eval $invocation
- local remote_path=$1
- local out_path=${2:-}
-
- local failed=false
- if [ -z "$out_path" ]; then
- curl --retry 10 -sSL -f --create-dirs $remote_path || failed=true
- else
- curl --retry 10 -sSL -f --create-dirs -o $out_path $remote_path || failed=true
- fi
- if [ "$failed" = true ]; then
- say_verbose "Curl download failed"
- return 1
- fi
- return 0
-}
-
-downloadwget() {
- eval $invocation
- local remote_path=$1
- local out_path=${2:-}
-
- local failed=false
- if [ -z "$out_path" ]; then
- wget -q --tries 10 $remote_path || failed=true
- else
- wget -v --tries 10 -O $out_path $remote_path || failed=true
- fi
- if [ "$failed" = true ]; then
- say_verbose "Wget download failed"
- return 1
- fi
- return 0
-}
-
-calculate_vars() {
- eval $invocation
- valid_legacy_download_link=true
-
- normalized_architecture=$(get_normalized_architecture_from_architecture "$architecture")
- say_verbose "normalized_architecture=$normalized_architecture"
-
- specific_version=$(get_specific_version_from_version $azure_feed $channel $normalized_architecture $version)
- say_verbose "specific_version=$specific_version"
- if [ -z "$specific_version" ]; then
- say_err "Could not get version information."
- return 1
- fi
-
- download_link=$(construct_download_link $azure_feed $channel $normalized_architecture $specific_version)
- say_verbose "download_link=$download_link"
-
- legacy_download_link=$(construct_legacy_download_link $azure_feed $channel $normalized_architecture $specific_version) || valid_legacy_download_link=false
-
- if [ "$valid_legacy_download_link" = true ]; then
- say_verbose "legacy_download_link=$legacy_download_link"
- else
- say_verbose "Cound not construct a legacy_download_link; omitting..."
- fi
-
- install_root=$(resolve_installation_path $install_dir)
- say_verbose "install_root=$install_root"
-}
-
-install_dotnet() {
- eval $invocation
- local download_failed=false
-
- if is_dotnet_package_installed $install_root "sdk" $specific_version; then
- say ".NET SDK version $specific_version is already installed."
- return 0
- fi
-
- mkdir -p $install_root
- zip_path=$(mktemp $temporary_file_template)
- say_verbose "Zip path: $zip_path"
-
- say "Downloading link: $download_link"
- download "$download_link" $zip_path || download_failed=true
-
- # if the download fails, download the legacy_download_link
- if [ "$download_failed" = true ] && [ "$valid_legacy_download_link" = true ]; then
- say "Cannot download: $download_link"
- download_link=$legacy_download_link
- zip_path=$(mktemp $temporary_file_template)
- say_verbose "Legacy zip path: $zip_path"
- say "Downloading legacy link: $download_link"
- download "$download_link" $zip_path
- fi
-
- say "Extracting zip from $download_link"
- extract_dotnet_package $zip_path $install_root
-
- return 0
-}
-
-local_version_file_relative_path="/.version"
-bin_folder_relative_path=""
-temporary_file_template="${TMPDIR:-/tmp}/dotnet.XXXXXXXXX"
-
-channel="LTS"
-version="Latest"
-install_dir=""
-architecture=""
-dry_run=false
-no_path=false
-azure_feed="https://dotnetcli.azureedge.net/dotnet"
-uncached_feed="https://dotnetcli.blob.core.windows.net/dotnet"
-verbose=false
-shared_runtime=false
-runtime_id=""
-
-while [ $# -ne 0 ]
-do
- name=$1
- case $name in
- -c|--channel|-[Cc]hannel)
- shift
- channel=$1
- ;;
- -v|--version|-[Vv]ersion)
- shift
- version="$1"
- ;;
- -i|--install-dir|-[Ii]nstall[Dd]ir)
- shift
- install_dir="$1"
- ;;
- --arch|--architecture|-[Aa]rch|-[Aa]rchitecture)
- shift
- architecture="$1"
- ;;
- --shared-runtime|-[Ss]hared[Rr]untime)
- shared_runtime=true
- ;;
- --dry-run|-[Dd]ry[Rr]un)
- dry_run=true
- ;;
- --no-path|-[Nn]o[Pp]ath)
- no_path=true
- ;;
- --verbose|-[Vv]erbose)
- verbose=true
- ;;
- --azure-feed|-[Aa]zure[Ff]eed)
- shift
- azure_feed="$1"
- ;;
- --uncached-feed|-[Uu]ncached[Ff]eed)
- shift
- uncached_feed="$1"
- ;;
- --runtime-id|-[Rr]untime[Ii]d)
- shift
- runtime_id="$1"
- ;;
- -?|--?|-h|--help|-[Hh]elp)
- script_name="$(basename $0)"
- echo ".NET Tools Installer"
- echo "Usage: $script_name [-c|--channel ] [-v|--version ] [-p|--prefix ]"
- echo " $script_name -h|-?|--help"
- echo ""
- echo "$script_name is a simple command line interface for obtaining dotnet cli."
- echo ""
- echo "Options:"
- echo " -c,--channel Download from the CHANNEL specified, Defaults to \`$channel\`."
- echo " -Channel"
- echo " Possible values:"
- echo " - Current - most current release"
- echo " - LTS - most current supported release"
- echo " - 2-part version in a format A.B - represents a specific release"
- echo " examples: 2.0; 1.0"
- echo " - Branch name"
- echo " examples: release/2.0.0; Master"
- echo " -v,--version Use specific VERSION, Defaults to \`$version\`."
- echo " -Version"
- echo " Possible values:"
- echo " - latest - most latest build on specific channel"
- echo " - coherent - most latest coherent build on specific channel"
- echo " coherent applies only to SDK downloads"
- echo " - 3-part version in a format A.B.C - represents specific version of build"
- echo " examples: 2.0.0-preview2-006120; 1.1.0"
- echo " -i,--install-dir Install under specified location (see Install Location below)"
- echo " -InstallDir"
- echo " --architecture Architecture of .NET Tools. Currently only x64 is supported."
- echo " --arch,-Architecture,-Arch"
- echo " --shared-runtime Installs just the shared runtime bits, not the entire SDK."
- echo " -SharedRuntime"
- echo " --dry-run,-DryRun Do not perform installation. Display download link."
- echo " --no-path, -NoPath Do not set PATH for the current process."
- echo " --verbose,-Verbose Display diagnostics information."
- echo " --azure-feed,-AzureFeed Azure feed location. Defaults to $azure_feed, This parameter typically is not changed by the user."
- echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user."
- echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
- echo " -RuntimeId"
- echo " -?,--?,-h,--help,-Help Shows this help message"
- echo ""
- echo "Install Location:"
- echo " Location is chosen in following order:"
- echo " - --install-dir option"
- echo " - Environmental variable DOTNET_INSTALL_DIR"
- echo " - $HOME/.dotnet"
- exit 0
- ;;
- *)
- say_err "Unknown argument \`$name\`"
- exit 1
- ;;
- esac
-
- shift
-done
-
-check_min_reqs
-calculate_vars
-
-if [ "$dry_run" = true ]; then
- say "Payload URL: $download_link"
- if [ "$valid_legacy_download_link" = true ]; then
- say "Legacy payload URL: $legacy_download_link"
- fi
- say "Repeatable invocation: ./$(basename $0) --version $specific_version --channel $channel --install-dir $install_dir"
- exit 0
-fi
-
-check_pre_reqs
-install_dotnet
-
-bin_path=$(get_absolute_path $(combine_paths $install_root $bin_folder_relative_path))
-if [ "$no_path" = false ]; then
- say "Adding to current process PATH: \`$bin_path\`. Note: This change will be visible only when sourcing script."
- export PATH=$bin_path:$PATH
-else
- say "Binaries of dotnet can be found in $bin_path"
-fi
-
-say "Installation finished successfully."
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/package.json b/Tasks/DotNetCoreInstallerV0/package.json
index 5f07104cd850..9e2da38d84cb 100644
--- a/Tasks/DotNetCoreInstallerV0/package.json
+++ b/Tasks/DotNetCoreInstallerV0/package.json
@@ -23,6 +23,7 @@
"homepage": "https://github.com/microsoft/vsts-tasks#readme",
"dependencies": {
"vsts-task-lib": "2.0.6",
- "vsts-task-tool-lib": "0.4.1"
+ "vsts-task-tool-lib": "0.4.1",
+ "typed-rest-client": "0.11.0"
}
}
diff --git a/Tasks/DotNetCoreInstallerV0/releasesfetcher.ts b/Tasks/DotNetCoreInstallerV0/releasesfetcher.ts
new file mode 100644
index 000000000000..40d927b28b55
--- /dev/null
+++ b/Tasks/DotNetCoreInstallerV0/releasesfetcher.ts
@@ -0,0 +1,64 @@
+import * as util from 'util';
+import * as taskLib from 'vsts-task-lib/task';
+
+import httpClient = require("typed-rest-client/HttpClient");
+import httpInterfaces = require("typed-rest-client/Interfaces");
+import { HttpClientResponse } from 'typed-rest-client/HttpClient';
+
+export class DotNetCoreReleaseFetcher {
+
+ // OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
+ // Type - SDK / Runtime
+ // Version - Version of the SDK/Runtime
+ public static async getDownloadUrls(osSuffixes: string[], version: string, type: string): Promise {
+ let downloadUrls = [];
+ let releasesJSON = await this.getReleasesJson();
+
+ let releasesInfo = JSON.parse(await releasesJSON.readBody());
+ releasesInfo = releasesInfo.filter(releaseInfo => {
+ return releaseInfo['version-' + type] === version || releaseInfo['version-' + type + '-display'] === version;
+ });
+
+ if (releasesInfo.length == 0) {
+ throw taskLib.loc("VersionNotFound", version);
+ }
+
+ let release = releasesInfo[0];
+ let blobUrl: string = release['blob-' + type];
+ let dlcUrl: string = release['dlc-' + type];
+ let fileName: string = release[type + '-' + osSuffixes[0]] ? release[type + '-' + osSuffixes[0]] : release[type + '-' + osSuffixes[1]];
+
+ if (!!fileName) {
+ if (!!blobUrl) {
+ downloadUrls.push(util.format("%s%s", blobUrl.trim(), fileName.trim()));
+ }
+
+ if (!!dlcUrl) {
+ downloadUrls.push(util.format("%s%s", dlcUrl.trim(), fileName.trim()));
+ }
+ }
+
+ if (downloadUrls.length == 0) {
+ throw taskLib.loc("NullDownloadUrls", version);
+ }
+
+ return downloadUrls;
+ }
+
+ private static getReleasesJson(): Promise {
+ let proxyUrl: string = taskLib.getVariable("agent.proxyurl");
+ var requestOptions: httpInterfaces.IRequestOptions = proxyUrl ? {
+ proxy: {
+ proxyUrl: proxyUrl,
+ proxyUsername: taskLib.getVariable("agent.proxyusername"),
+ proxyPassword: taskLib.getVariable("agent.proxypassword"),
+ proxyBypassHosts: taskLib.getVariable("agent.proxybypasslist") ? JSON.parse(taskLib.getVariable("agent.proxybypasslist")) : null
+ }
+ } : {};
+
+ var httpCallbackClient = new httpClient.HttpClient(taskLib.getVariable("AZURE_HTTP_USER_AGENT"), null, requestOptions);
+ return httpCallbackClient.get(DotNetCoreReleasesUrl);
+ }
+}
+
+const DotNetCoreReleasesUrl: string = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json";
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/task.json b/Tasks/DotNetCoreInstallerV0/task.json
index d2076762d2bf..4cd14daff3c7 100644
--- a/Tasks/DotNetCoreInstallerV0/task.json
+++ b/Tasks/DotNetCoreInstallerV0/task.json
@@ -13,12 +13,15 @@
"version": {
"Major": 0,
"Minor": 1,
- "Patch": 8
+ "Patch": 9
},
- "satisfies": ["DotNetCore"],
+ "satisfies": [
+ "DotNetCore"
+ ],
"demands": [],
"instanceNameFormat": "Use .NET Core $(packageType) $(version)",
- "inputs": [{
+ "inputs": [
+ {
"name": "packageType",
"type": "pickList",
"label": "Package to install",
@@ -36,7 +39,7 @@
"label": "Version",
"defaultValue": "1.0.4",
"required": true,
- "helpMarkDown": "Specify exact version of .NET Core SDK or runtime to install.
Examples:
1. To install 1.0.4 SDK, use 1.0.4
2. To install 1.1.2 runtime, use 1.1.2
2. To install 2.0 preview 2 runtime, use 2.0.0-preview2-25407-01
For getting more details about exact version, refer [here](https://github.com/dotnet/core/blob/master/release-notes/releases.csv)"
+ "helpMarkDown": "Specify exact version of .NET Core SDK or runtime to install.
Find the value of `version-sdk` for installing SDK, or `version-runtime` for installing Runtime from any releases [here](https://github.com/dotnet/core/blob/master/release-notes/releases.json)"
}
],
"execution": {
@@ -47,20 +50,22 @@
"messages": {
"ToolFailed": "Tool install failed: %s",
"ImplicitVersionNotSupported": "Version should be a valid and explicit version: %s",
- "PrimaryUrlDownloadFailed": "Failed to download .NET Core package using primary URL. Error: %s.",
- "LegacyUrlDownloadFailed": "Failed to download .NET Core package using legacy URL as well. Error: %s.",
- "DownloadFailed": "Failed to download .NET Core package. Please ensure that .NET Core %s of version %s exists. Check out: https://github.com/dotnet/core/blob/master/release-notes/releases.csv",
- "getDownloadUrlsFailed": "Failed to get download urls. Error: %s.",
+ "getMachinePlatformFailed": "Failed to get machine platform details. Error: %s.",
"UsingCachedTool": "Cached copy of .NET Core exists. No need to install afresh. Cached tool location: %s.",
"CheckingToolCache": "Checking if a cached copy exists for this version...",
"InstallingAfresh": "Cache does not contains this particular .NET Core. Will be downloaded and installed.",
- "GettingDownloadUrls": "Getting URLs to download .NET Core %s version: %s.",
- "NullDownloadUrls": "Could not construct download Urls. Please ensure that specified version is valid.",
- "DownloadingPrimaryUrl": "Downloading .NET Core package from primary URL: %s",
- "DownloadingSecondaryUrl": "Downloading .NET Core package from legacy URL: %s",
+ "GettingDownloadUrl": "Getting URL to download .NET Core %s version: %s.",
+ "CouldNotDetectPlatform": "Could not detect the machine's OS",
+ "NullDownloadUrls": "Could not construct download Url. Please ensure that specified version %s is valid.",
+ "DownloadingUrl": "Downloading .NET Core package from URL: %s",
"ExtractingPackage": "Extracting downloaded package %s.",
"CachingTool": "Caching this installed tool.",
"SuccessfullyInstalled": "Successfully installed .NET Core %s version %s.",
- "ToolToInstall": "Tool to install: .NET Core %s version %s."
+ "ToolToInstall": "Tool to install: .NET Core %s version %s.",
+ "PrimaryPlatform": "Detected platform (Primary): %s",
+ "LegacyPlatform": "Detected platform (Legacy): %s",
+ "VersionNotFound": "Could not fetch download information for version %s. Please check if the version specified is correct. You can refer https://github.com/dotnet/core/blob/master/release-notes/releases.json",
+ "CouldNotDownload": "Could not download installation package from this URL: %s Error: %s",
+ "FailedToDownloadPackage": "Failed to download package for installation"
}
}
\ No newline at end of file
diff --git a/Tasks/DotNetCoreInstallerV0/task.loc.json b/Tasks/DotNetCoreInstallerV0/task.loc.json
index d250f13a7201..8fec155a4a83 100644
--- a/Tasks/DotNetCoreInstallerV0/task.loc.json
+++ b/Tasks/DotNetCoreInstallerV0/task.loc.json
@@ -13,7 +13,7 @@
"version": {
"Major": 0,
"Minor": 1,
- "Patch": 8
+ "Patch": 9
},
"satisfies": [
"DotNetCore"
@@ -50,20 +50,22 @@
"messages": {
"ToolFailed": "ms-resource:loc.messages.ToolFailed",
"ImplicitVersionNotSupported": "ms-resource:loc.messages.ImplicitVersionNotSupported",
- "PrimaryUrlDownloadFailed": "ms-resource:loc.messages.PrimaryUrlDownloadFailed",
- "LegacyUrlDownloadFailed": "ms-resource:loc.messages.LegacyUrlDownloadFailed",
- "DownloadFailed": "ms-resource:loc.messages.DownloadFailed",
- "getDownloadUrlsFailed": "ms-resource:loc.messages.getDownloadUrlsFailed",
+ "getMachinePlatformFailed": "ms-resource:loc.messages.getMachinePlatformFailed",
"UsingCachedTool": "ms-resource:loc.messages.UsingCachedTool",
"CheckingToolCache": "ms-resource:loc.messages.CheckingToolCache",
"InstallingAfresh": "ms-resource:loc.messages.InstallingAfresh",
- "GettingDownloadUrls": "ms-resource:loc.messages.GettingDownloadUrls",
+ "GettingDownloadUrl": "ms-resource:loc.messages.GettingDownloadUrl",
+ "CouldNotDetectPlatform": "ms-resource:loc.messages.CouldNotDetectPlatform",
"NullDownloadUrls": "ms-resource:loc.messages.NullDownloadUrls",
- "DownloadingPrimaryUrl": "ms-resource:loc.messages.DownloadingPrimaryUrl",
- "DownloadingSecondaryUrl": "ms-resource:loc.messages.DownloadingSecondaryUrl",
+ "DownloadingUrl": "ms-resource:loc.messages.DownloadingUrl",
"ExtractingPackage": "ms-resource:loc.messages.ExtractingPackage",
"CachingTool": "ms-resource:loc.messages.CachingTool",
"SuccessfullyInstalled": "ms-resource:loc.messages.SuccessfullyInstalled",
- "ToolToInstall": "ms-resource:loc.messages.ToolToInstall"
+ "ToolToInstall": "ms-resource:loc.messages.ToolToInstall",
+ "PrimaryPlatform": "ms-resource:loc.messages.PrimaryPlatform",
+ "LegacyPlatform": "ms-resource:loc.messages.LegacyPlatform",
+ "VersionNotFound": "ms-resource:loc.messages.VersionNotFound",
+ "CouldNotDownload": "ms-resource:loc.messages.CouldNotDownload",
+ "FailedToDownloadPackage": "ms-resource:loc.messages.FailedToDownloadPackage"
}
}
\ No newline at end of file