-
Notifications
You must be signed in to change notification settings - Fork 18
/
yarnToolInstallerTask.ts
107 lines (82 loc) · 3.29 KB
/
yarnToolInstallerTask.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import fs = require("fs");
import q = require("q");
import * as tl from "vsts-task-lib/task";
import * as path from "path";
import * as toolLib from "vsts-task-tool-lib/tool";
import { downloadFile, getTempPath, detar } from "./util";
let yarnVersionsFile = path.join(getTempPath(), "yarnVersions.json");
async function queryLatestMatch(versionSpec: string): Promise<{ version: string, url: string }> {
await downloadFile("https://geeklearningassets.blob.core.windows.net/yarn/tarballs.json", yarnVersionsFile);
let yarnVersions = <{ [key: string]: string }>JSON.parse(fs.readFileSync(yarnVersionsFile, { encoding: "utf8" }));
let version: string = toolLib.evaluateVersions(Object.keys(yarnVersions), versionSpec);
if (!version) {
return undefined;
}
return { version: version, url: yarnVersions[version] };
}
async function downloadYarn(version: { version: string, url: string }) {
let cleanVersion = toolLib.cleanVersion(version.version);
let downloadPath: string = path.join(getTempPath(), `yarn-${cleanVersion}.tar.gz`);
await downloadFile(version.url, downloadPath);
let detarLocation = path.join(getTempPath(), "output");
await detar(downloadPath, detarLocation);
return await toolLib.cacheDir(detarLocation, "yarn", cleanVersion);
}
async function getYarn(versionSpec: string, checkLatest: boolean) {
if (toolLib.isExplicitVersion(versionSpec)) {
checkLatest = false; // check latest doesn't make sense when explicit version
}
// check cache
let toolPath: string;
if (!checkLatest) {
toolPath = toolLib.findLocalTool("yarn", versionSpec);
}
if (!toolPath) {
let version: { version: string, url: string };
if (toolLib.isExplicitVersion(versionSpec)) {
// version to download
version = await queryLatestMatch(versionSpec);
} else {
// query nodejs.org for a matching version
version = await queryLatestMatch(versionSpec);
if (!version) {
throw new Error(`Unable to find Yarn version '${versionSpec}'.`);
}
// check cache
toolPath = toolLib.findLocalTool("yarn", version.version);
}
if (!toolPath) {
// download, extract, cache
toolPath = await downloadYarn(version);
}
toolLib.prependPath(toolPath);
}
//
// a tool installer initimately knows details about the layout of that tool
// for example, node binary is in the bin folder after the extract on Mac/Linux.
// layouts could change by version, by platform etc... but that's the tool installers job
//
let matches = tl.findMatch(toolPath, [
"**/bin/yarn.cmd",
]);
if (matches.length) {
toolPath = path.dirname(matches[0]);
} else {
throw new Error("Yarn package layout unexpected.");
}
//
// prepend the tools path. instructs the agent to prepend for future tasks
//
toolLib.prependPath(toolPath);
}
async function run() {
try {
let versionSpec = tl.getInput("versionSpec", true);
let checkLatest: boolean = tl.getBoolInput("checkLatest", false);
await getYarn(versionSpec, checkLatest);
}
catch (error) {
tl.setResult(tl.TaskResult.Failed, error.message);
}
}
run();