-
Notifications
You must be signed in to change notification settings - Fork 13
/
github-asset.ts
126 lines (109 loc) · 3.62 KB
/
github-asset.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import fs from 'fs-extra';
import { TSError } from '@terascope/utils';
import { downloadRelease } from '@terascope/fetch-github-release';
import { GithubAssetConfig } from '../interfaces.js';
export default class GithubAsset {
arch: string;
assetString: string;
nodeVersion: string;
platform: string;
user: string;
name: string;
version?: string;
bundle: boolean;
constructor(config: GithubAssetConfig) {
this.arch = config.arch;
this.assetString = config.assetString;
this.bundle = config.bundle;
this.nodeVersion = config.nodeVersion;
this.platform = config.platform;
const p = GithubAsset.parseAssetString(this.assetString);
this.user = p.user;
this.name = p.name;
this.version = p.version;
}
get nodeMajorVersion(): string {
return this.nodeVersion.split('.', 1)[0].substr(1);
}
async download(outDir = '/tmp', quiet = false): Promise<string> {
let assetPath;
const leaveZipped = true;
let assetName: string;
if (this.bundle) {
assetName = `node-${this.nodeMajorVersion}-bundle.zip`;
} else {
assetName = `node-${this.nodeMajorVersion}-${this.platform}-${this.arch}.zip`;
}
const version = this.version ? this.version.slice(1) : null;
let filterRelease;
if (version) {
filterRelease = (r: any) => r.tag_name.includes(version);
} else {
filterRelease = (r: any) => !r.draft && !r.prerelease;
}
const genFilterAsset = (asset: any) => asset.name.indexOf(assetName) >= 0;
try {
await fs.ensureDir(outDir);
} catch (err) {
throw new TSError(err, {
reason: `Failure creating ${outDir}`
});
}
try {
const r = await downloadRelease(
this.user,
this.name,
outDir,
// TODO: need to fix types in forked repo
filterRelease as any,
genFilterAsset,
leaveZipped,
quiet
) as any;
[assetPath] = r;
} catch (err) {
throw new Error(`Error downloading ${this.assetString}: ${err}`);
}
return assetPath;
}
/**
* @typedef {Object} AssetDescriptor
* @property {string} user The github user for the asset repository.
* @property {string} name The github repository name for the asset.
* @property {string} version The version of the asset.
*/
/**
*
* @param {String}
* A string containing the assets Github repo and name, e.g.:
* terascope/file-assets
* terascope/file-assets@v2.0.0
* @return {AssetDescriptor}
*/
static parseAssetString(assetString: string): {
user: string;
name: string;
version: string|undefined;
} {
let userAndName;
let version;
const versionSplit = assetString.split('@');
if (versionSplit.length === 1) {
[userAndName] = versionSplit;
} else if (versionSplit.length === 2) {
[userAndName, version] = versionSplit;
} else {
throw new Error('An asset string must contain zero or one \'@\'.');
}
const nameSplit = userAndName.split('/');
if (nameSplit.length !== 2) {
throw new Error('An asset string must contain exactly one \'/\'');
}
const [user, name] = nameSplit;
return {
user,
name,
version
};
}
}