Skip to content

Commit 8775ceb

Browse files
authored
fix: General cleanup (#26595)
1 parent 11fb858 commit 8775ceb

File tree

6 files changed

+85
-64
lines changed

6 files changed

+85
-64
lines changed

index.js

+38-32
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const fs = require('fs');
44
const os = require('os');
55
const path = require('path');
66
const {exec} = require('child_process');
7-
const {rimrafSync} = require('rimraf');
87
require('source-map-support').install();
98

109
let controller;
@@ -16,7 +15,7 @@ let unsolicitedStop = false;
1615
let watchdogDelays = [2000, 60000, 300000, 900000, 1800000, 3600000];
1716

1817
if (watchdog && process.env.Z2M_WATCHDOG !== 'default') {
19-
if (/^(?:(?:[0-9]*[.])?[0-9]+)+(?:,?(?:[0-9]*[.])?[0-9]+)*$/.test(process.env.Z2M_WATCHDOG)) {
18+
if (/^\d+(.\d+)?(,\d+(.\d+)?)*$/.test(process.env.Z2M_WATCHDOG)) {
2019
watchdogDelays = process.env.Z2M_WATCHDOG.split(',').map((v) => parseFloat(v) * 60000);
2120
} else {
2221
console.log(`Invalid watchdog delays (must use number-only CSV format representing minutes, example: 'Z2M_WATCHDOG=1,5,15,30,60'.`);
@@ -58,10 +57,16 @@ async function exit(code, restart = false) {
5857
}
5958

6059
async function currentHash() {
61-
const git = require('git-last-commit');
60+
return await new Promise((resolve) => {
61+
exec('git rev-parse --short=8 HEAD', (error, stdout) => {
62+
const commitHash = stdout.trim();
6263

63-
return new Promise((resolve) => {
64-
git.getLastCommit((err, commit) => (err ? resolve('unknown') : resolve(commit.shortHash)));
64+
if (error || commitHash === '') {
65+
resolve('unknown');
66+
} else {
67+
resolve(commitHash);
68+
}
69+
});
6570
});
6671
}
6772

@@ -72,10 +77,9 @@ async function writeHash() {
7277
}
7378

7479
async function build(reason) {
75-
return new Promise((resolve, reject) => {
76-
process.stdout.write(`Building Zigbee2MQTT... (${reason})`);
77-
rimrafSync('dist');
80+
process.stdout.write(`Building Zigbee2MQTT... (${reason})`);
7881

82+
return await new Promise((resolve, reject) => {
7983
const env = {...process.env};
8084
const _600mb = 629145600;
8185

@@ -85,7 +89,8 @@ async function build(reason) {
8589
env.NODE_OPTIONS = '--max_old_space_size=256';
8690
}
8791

88-
exec('pnpm run build', {env, cwd: __dirname}, async (err, stdout, stderr) => {
92+
// clean build, prevent failures due to tsc incremental building
93+
exec('pnpm run prepack', {env, cwd: __dirname}, async (err, stdout, stderr) => {
8994
if (err) {
9095
process.stdout.write(', failed\n');
9196

@@ -107,8 +112,9 @@ async function checkDist() {
107112
await build('initial build');
108113
}
109114

110-
const distHash = fs.readFileSync(hashFile, 'utf-8');
115+
const distHash = fs.readFileSync(hashFile, 'utf8');
111116
const hash = await currentHash();
117+
112118
if (hash !== 'unknown' && distHash !== hash) {
113119
await build('hash changed');
114120
}
@@ -118,41 +124,41 @@ async function start() {
118124
console.log(`Starting Zigbee2MQTT ${watchdog ? `with watchdog (${watchdogDelays})` : `without watchdog`}.`);
119125
await checkDist();
120126

121-
const version = engines.node;
127+
// gc
128+
{
129+
const version = engines.node;
122130

123-
if (!semver.satisfies(process.version, version)) {
124-
console.log(`\t\tZigbee2MQTT requires node version ${version}, you are running ${process.version}!\n`);
125-
}
131+
if (!semver.satisfies(process.version, version)) {
132+
console.log(`\t\tZigbee2MQTT requires node version ${version}, you are running ${process.version}!\n`);
133+
}
126134

127-
// Validate settings
128-
const settings = require('./dist/util/settings');
135+
// Validate settings
136+
const settings = require('./dist/util/settings');
129137

130-
settings.reRead();
138+
settings.reRead();
131139

132-
// gc
133-
{
134140
const settingsMigration = require('./dist/util/settingsMigration');
135141

136142
settingsMigration.migrateIfNecessary();
137-
}
138143

139-
const errors = settings.validate();
144+
const errors = settings.validate();
140145

141-
if (errors.length > 0) {
142-
unsolicitedStop = false;
146+
if (errors.length > 0) {
147+
unsolicitedStop = false;
143148

144-
console.log(`\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
145-
console.log(' READ THIS CAREFULLY\n');
146-
console.log(`Refusing to start because configuration is not valid, found the following errors:`);
149+
console.log(`\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
150+
console.log(' READ THIS CAREFULLY\n');
151+
console.log(`Refusing to start because configuration is not valid, found the following errors:`);
147152

148-
for (const error of errors) {
149-
console.log(`- ${error}`);
150-
}
153+
for (const error of errors) {
154+
console.log(`- ${error}`);
155+
}
151156

152-
console.log(`\nIf you don't know how to solve this, read https://www.zigbee2mqtt.io/guide/configuration`);
153-
console.log(`\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n`);
157+
console.log(`\nIf you don't know how to solve this, read https://www.zigbee2mqtt.io/guide/configuration`);
158+
console.log(`\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n`);
154159

155-
return exit(1);
160+
return await exit(1);
161+
}
156162
}
157163

158164
const {Controller} = require('./dist/controller');

lib/types/types.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ declare global {
120120
serial: {
121121
disable_led: boolean;
122122
port?: string;
123-
adapter?: 'deconz' | 'zstack' | 'ezsp' | 'zigate' | 'ember';
123+
adapter?: 'deconz' | 'zstack' | 'ezsp' | 'zigate' | 'ember' | 'zboss';
124124
baudrate?: number;
125125
rtscts?: boolean;
126126
};

lib/util/utils.ts

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {Zigbee2MQTTAPI, Zigbee2MQTTResponse, Zigbee2MQTTResponseEndpoints, Zigbee2MQTTScene} from 'lib/types/api';
22
import type * as zhc from 'zigbee-herdsman-converters';
33

4+
import {exec} from 'child_process';
45
import assert from 'node:assert';
56
import crypto from 'node:crypto';
67
import fs from 'node:fs';
@@ -50,32 +51,26 @@ function capitalize(s: string): string {
5051
}
5152

5253
async function getZigbee2MQTTVersion(includeCommitHash = true): Promise<{commitHash?: string; version: string}> {
53-
const git = await import('git-last-commit');
54-
const packageJSON = await import('../..' + '/package.json');
54+
const packageJSON = await import('../../package.json');
55+
const version = packageJSON.version;
56+
let commitHash: string | undefined;
5557

5658
if (!includeCommitHash) {
57-
return {version: packageJSON.version, commitHash: undefined};
59+
return {version, commitHash};
5860
}
5961

6062
return await new Promise((resolve) => {
61-
const version = packageJSON.version;
63+
exec('git rev-parse --short=8 HEAD', (error, stdout) => {
64+
commitHash = stdout.trim();
6265

63-
git.getLastCommit((err: Error, commit: {shortHash: string}) => {
64-
let commitHash = undefined;
65-
66-
if (err) {
66+
if (error || commitHash === '') {
6767
try {
6868
commitHash = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', '.hash'), 'utf-8');
69-
/* v8 ignore start */
7069
} catch {
7170
commitHash = 'unknown';
7271
}
73-
/* v8 ignore stop */
74-
} else {
75-
commitHash = commit.shortHash;
7672
}
7773

78-
commitHash = commitHash.trim();
7974
resolve({commitHash, version});
8075
});
8176
});

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
"express-static-gzip": "^2.2.0",
4747
"fast-deep-equal": "^3.1.3",
4848
"finalhandler": "^1.3.1",
49-
"git-last-commit": "^1.0.1",
5049
"humanize-duration": "^3.32.1",
5150
"js-yaml": "^4.1.0",
5251
"json-stable-stringify-without-jsonify": "^1.0.1",

pnpm-lock.yaml

-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/utils.test.ts

+38-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1+
import {exec} from 'node:child_process';
12
import fs from 'node:fs';
23
import path from 'node:path';
34

45
import utils from '../lib/util/utils';
56

6-
const mockGetLastCommit = vi.fn<() => [boolean, {shortHash: string} | null]>(() => [false, {shortHash: '123'}]);
7-
8-
vi.mock('git-last-commit', () => ({
9-
getLastCommit: vi.fn((cb) => cb(...mockGetLastCommit())),
10-
}));
7+
// keep the implementations, just spy
8+
vi.mock('node:child_process', {spy: true});
119

1210
describe('Utils', () => {
1311
it('Object is empty', () => {
@@ -20,13 +18,44 @@ describe('Utils', () => {
2018
expect(utils.objectHasProperties({a: 1, b: 2, c: 3}, ['a', 'b', 'd'])).toBeFalsy();
2119
});
2220

23-
it('git last commit', async () => {
21+
it('get Z2M version', async () => {
22+
const readFileSyncSpy = vi.spyOn(fs, 'readFileSync');
2423
const version = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')).version;
2524

26-
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: '123', version: version});
25+
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: expect.stringMatching(/^(?!unknown)[a-z0-9]{8}$/), version});
26+
expect(exec).toHaveBeenCalledTimes(1);
27+
28+
// @ts-expect-error mock spy
29+
exec.mockImplementationOnce((cmd, cb) => {
30+
cb(null, 'abcd1234');
31+
});
32+
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: 'abcd1234', version});
33+
34+
// @ts-expect-error mock spy
35+
exec.mockImplementationOnce((cmd, cb) => {
36+
cb(null, '');
37+
});
38+
// hash file may or may not be present during testing, don't failing matching if not
39+
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: expect.stringMatching(/^(unknown|([a-z0-9]{8}))$/), version});
40+
41+
readFileSyncSpy.mockImplementationOnce(() => {
42+
throw new Error('no hash file');
43+
});
44+
// @ts-expect-error mock spy
45+
exec.mockImplementationOnce((cmd, cb) => {
46+
cb(null, '');
47+
});
48+
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: 'unknown', version});
2749

28-
mockGetLastCommit.mockReturnValueOnce([true, null]);
29-
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: expect.any(String), version: version});
50+
readFileSyncSpy.mockImplementationOnce(() => {
51+
throw new Error('no hash file');
52+
});
53+
// @ts-expect-error mock spy
54+
exec.mockImplementationOnce((cmd, cb) => {
55+
cb(new Error('invalid'), '');
56+
});
57+
expect(await utils.getZigbee2MQTTVersion()).toStrictEqual({commitHash: 'unknown', version});
58+
expect(exec).toHaveBeenCalledTimes(5);
3059
});
3160

3261
it('Check dependency version', async () => {

0 commit comments

Comments
 (0)