forked from Koenkk/zigbee2mqtt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
121 lines (105 loc) · 3.51 KB
/
index.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
114
115
116
117
118
119
120
121
require('core-js/features/object/from-entries');
require('core-js/features/array/flat');
const semver = require('semver');
const engines = require('./package.json').engines;
const indexJsRestart = 'indexjs.restart';
const fs = require('fs');
const path = require('path');
const {exec} = require('child_process');
const rimraf = require('rimraf');
require('source-map-support').install();
let controller;
let stopping = false;
const hashFile = path.join(__dirname, 'dist', '.hash');
async function restart() {
await stop(indexJsRestart);
await start();
}
async function exit(code, reason) {
if (reason !== indexJsRestart) {
process.exit(code);
}
}
async function currentHash() {
const git = require('git-last-commit');
return new Promise((resolve) => {
git.getLastCommit((err, commit) => {
if (err) resolve('unknown');
else resolve(commit.shortHash);
});
});
}
async function writeHash() {
const hash = await currentHash();
fs.writeFileSync(hashFile, hash);
}
async function build(reason) {
return new Promise((resolve, reject) => {
process.stdout.write(`Building Zigbee2MQTT... (${reason})`);
rimraf.sync('dist');
exec('npm run build', {cwd: __dirname}, async (err, stdout, stderr) => {
if (err) {
process.stdout.write(', failed\n');
if (err.code === 134) {
process.stderr.write(
'\n\nBuild failed; ran out-of-memory, free some memory (RAM) and start again\n\n');
}
reject(err);
} else {
process.stdout.write(', finished\n');
resolve();
}
});
});
}
async function checkDist() {
if (!fs.existsSync(hashFile)) {
await build('initial build');
}
const distHash = fs.readFileSync(hashFile, 'utf-8');
const hash = await currentHash();
if (hash !== 'unknown' && distHash !== hash) {
await build('hash changed');
}
}
async function start() {
await checkDist();
const version = engines.node;
if (!semver.satisfies(process.version, version)) {
console.log(`\t\tZigbee2MQTT requires node version ${version}, you are running ${process.version}!\n`); // eslint-disable-line
}
// Validate settings
const settings = require('./dist/util/settings');
settings.reRead();
const errors = settings.validate();
if (errors.length > 0) {
console.log(`\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
console.log(' READ THIS CAREFULLY\n');
console.log(`Refusing to start because configuration is not valid, found the following errors:`);
for (const error of errors) {
console.log(`- ${error}`);
}
console.log(`\nIf you don't know how to solve this, read https://www.zigbee2mqtt.io/guide/configuration`); // eslint-disable-line
console.log(`\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n`);
exit(1);
}
const Controller = require('./dist/controller');
controller = new Controller(restart, exit);
await controller.start();
}
async function stop(reason=null) {
await controller.stop(reason);
}
async function handleQuit() {
if (!stopping && controller) {
stopping = true;
await stop();
}
}
if (process.argv.length === 3 && process.argv[2] === 'writehash') {
writeHash();
} else {
process.on('SIGINT', handleQuit);
process.on('SIGTERM', handleQuit);
start();
}