-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirstrun.js
113 lines (104 loc) · 3.92 KB
/
firstrun.js
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
/**
* Provides methods for performing a first-run module install.
*
* When there are no modules installed, this code will download a known set of
* defaults using known install list locations.
*
* Written By:
* Matthew Knox
*
* License:
* MIT License. All code unless otherwise specified is
* Copyright (c) Matthew Knox and Contributors 2017.
*/
const path = require('path'),
util = require('util'),
client = require('scoped-http-client'),
git = require('concierge/git'),
files = require('concierge/files');
class FirstRun {
async _getJsonFile (file) {
try {
return await files.readJson(file);
}
catch (e) {
return null;
}
}
_getJson (data) {
try {
return JSON.parse(data.replace(/^\uFEFF/, ''));
}
catch (e) {
return null;
}
}
async _getRemoteDefaults (globalConfig) {
const potentialDefaultUrls = [
globalConfig.url || null,
this.config.url || null,
this._getJson(process.env.CONCIERGE_DEFAULTS_URL),
'https://raw.githubusercontent.com/wiki/concierge/Concierge/Defaults.md'
];
const url = potentialDefaultUrls.find(p => !!p);
try {
const response = await util.promisify((u, c) => client.create(u).get()((e, r, b) => c(e, b)))(url);
const tableArea = response.substring(response.indexOf('***') + 3, response.lastIndexOf('***')),
relevantArea = tableArea.substring(tableArea.indexOf('--|\n') + 4),
defaults = relevantArea.split(/\r?\n/)
.map(r => r.split('|').map(s => s.trim()).filter(s => !!s)
.slice(0, 2).reverse()).filter(r => r.length === 2);
return defaults;
}
catch (e) {
LOG.critical(e);
return null;
}
}
async _getInstalledVersion (installPath) {
const descriptor = await this._getJsonFile(path.join(installPath, 'kassy.json')) ||
await this._getJsonFile(path.join(installPath, 'hubot.json')) ||
await this._getJsonFile(path.join(installPath, 'package.json'));
if (typeof(descriptor.version) === 'string') {
return descriptor.version;
}
// convert to semver
const spl = descriptor.version.toString().split('.');
return spl.concat(Array(3 - spl.length).fill('0')).join('.');
}
async _installModule (def) {
LOG.warn($$`Attempting to install module from "${def[0]}"`);
const installPath = path.join(global.__modulesPath, def[1]);
try {
await git.clone(def[0], installPath);
const installedVersion = await this._getInstalledVersion(installPath);
LOG.warn($$`"${def[1]}" (${installedVersion}) is now installed.`);
}
catch (err) {
LOG.critical(err);
LOG.error($$`Failed to install module from "${def[0]}"`);
}
return true;
}
async load (platform) {
const globalConfig = platform.config.getSystemConfig('defaults');
const potentialDefaults = [
await this._getJsonFile(global.rootPathJoin('defaults.json')),
globalConfig.list || null,
this.config.list || null,
this._getJson(process.env.CONCIERGE_DEFAULTS),
await this._getRemoteDefaults(globalConfig)
];
const defaultModules = potentialDefaults.find(p => !!p);
if (!defaultModules) {
return LOG.error('No defaults list is available to install.');
}
await Promise.all(defaultModules.map(def => this._installModule(def)));
await files.deleteDirectory(this.__descriptor.folderPath);
platform.modulesLoader.unloadModule(this);
}
async unload (platform) {
await platform.modulesLoader.loadAllModules();
}
}
module.exports = new FirstRun();