Skip to content

Commit 40a424e

Browse files
authored
NPM Global Modules Ownership and macOS Tests (#2)
1 parent 7855289 commit 40a424e

File tree

3 files changed

+66
-14
lines changed

3 files changed

+66
-14
lines changed

.github/workflows/test.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test-macos:
11+
runs-on: macos-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-node@v4
15+
with:
16+
node-version: 24.x
17+
- run: npm install -g matterbridge
18+
- run: npm ci
19+
- run: npm link matterbridge
20+
- run: npm run build
21+
- run: npm link
22+
- run: sudo chown -R root:wheel "$(npm prefix -g --silent)/lib/node_modules"
23+
- run: sudo mb-service install
24+
- run: mb-service pid
25+
- run: launchctl print system/com.matterbridge
26+
- run: sleep 10 && curl http://localhost:8283/
27+
- run: test -w "$(npm prefix -g --silent)/lib/node_modules"
28+
- run: sudo mb-service uninstall

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ A service management command-line utility for [Matterbridge](https://github.com/
55
_This is currently experimental and only supports macOS with a default configuration at the moment!_
66

77
```
8-
% npm -g install matterbridge
8+
% npm install -g matterbridge
99
% git clone https://github.com/michaelahern/mb-service.git
1010
% cd mb-service
1111
% npm install

src/mac.ts

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,41 @@ export class MacPlatform extends PlatformCommands {
1313
this.#checkRoot();
1414
const userInfo = this.#getUserInfo();
1515

16-
const pluginPath = resolve(userInfo.homedir, 'Matterbridge');
17-
const storagePath = resolve(userInfo.homedir, '.matterbridge');
18-
19-
mkdirSync(pluginPath, { recursive: true });
20-
mkdirSync(storagePath, { recursive: true });
21-
22-
chownSync(pluginPath, userInfo.uid, userInfo.gid);
23-
chownSync(storagePath, userInfo.uid, userInfo.gid);
24-
16+
// Check if Matterbridge is installed globally
2517
const matterbridgePath = execSync('eval echo "$(npm prefix -g --silent)/bin/matterbridge"').toString().trim();
2618
if (!existsSync(matterbridgePath)) {
2719
console.error('Matterbridge is not installed globally!');
2820
console.error('npm install -g matterbridge');
2921
process.exit(1);
3022
}
3123

24+
// Create Matterbridge Plugin and Storage directories
25+
const matterbridgePluginPath = resolve(userInfo.homedir, 'Matterbridge');
26+
this.#mkdirPath(matterbridgePluginPath, userInfo);
27+
28+
const matterbridgeStoragePath = resolve(userInfo.homedir, '.matterbridge');
29+
this.#mkdirPath(matterbridgeStoragePath, userInfo);
30+
31+
// Check NPM global modules path permissions and change if necessary
32+
const npmGlobalModulesPath = execSync('eval echo "$(npm prefix -g --silent)/lib/node_modules"').toString().trim();
33+
try {
34+
execSync(`eval test -w "${npmGlobalModulesPath}"`, {
35+
uid: userInfo.uid,
36+
gid: userInfo.gid
37+
});
38+
}
39+
catch {
40+
try {
41+
execSync(`chown -R ${userInfo.uid}:${userInfo.gid} "${npmGlobalModulesPath}"`);
42+
}
43+
catch {
44+
console.error('User not able to write to the NPM Global Modules Path!');
45+
console.error(`sudo chown -R ${userInfo.uid}:${userInfo.gid} "${npmGlobalModulesPath}"`);
46+
process.exit(1);
47+
}
48+
}
49+
50+
// Create the launchd plist file
3251
const plistFileContents = [
3352
'<?xml version="1.0" encoding="UTF-8"?>',
3453
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
@@ -55,9 +74,9 @@ export class MacPlatform extends PlatformCommands {
5574
` <string>${process.env.PATH}</string>`,
5675
' </dict>',
5776
' <key>StandardOutPath</key>',
58-
` <string>${storagePath}/matterbridge.log</string>`,
77+
` <string>${matterbridgeStoragePath}/matterbridge.log</string>`,
5978
' <key>StandardErrorPath</key>',
60-
` <string>${storagePath}/matterbridge.log</string>`,
79+
` <string>${matterbridgeStoragePath}/matterbridge.log</string>`,
6180
'</dict>',
6281
'</plist>'
6382
].filter(x => x).join('\n');
@@ -123,8 +142,8 @@ export class MacPlatform extends PlatformCommands {
123142
}
124143

125144
tail(): void {
126-
const storagePath = resolve(this.#getUserInfo().homedir, '.matterbridge');
127-
execFileSync('tail', ['-f', '-n', '32', `${storagePath}/matterbridge.log`], { stdio: 'inherit' });
145+
const matterbridgeStoragePath = resolve(this.#getUserInfo().homedir, '.matterbridge');
146+
execFileSync('tail', ['-f', '-n', '32', `${matterbridgeStoragePath}/matterbridge.log`], { stdio: 'inherit' });
128147
}
129148

130149
#checkRoot() {
@@ -152,4 +171,9 @@ export class MacPlatform extends PlatformCommands {
152171
#isInstalled(): boolean {
153172
return existsSync(this.#plist);
154173
}
174+
175+
#mkdirPath(path: string, userInfo: UserInfo<string>): void {
176+
mkdirSync(path, { recursive: true });
177+
chownSync(path, userInfo.uid, userInfo.gid);
178+
}
155179
}

0 commit comments

Comments
 (0)