Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit c7d8718

Browse files
authored
Merge pull request #10 from codeoverflow-org/fix/sub-package-upgrade
Redownload dashboard when upgrading core
2 parents c631349 + 67ee171 commit c7d8718

File tree

8 files changed

+54
-12
lines changed

8 files changed

+54
-12
lines changed

src/install/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import * as os from "os";
1010
import { logger } from "../log";
1111
import { requireNpmV7 } from "../npm";
1212

13-
// TODO: remove nodecg-io directory if initial installation was aborted?
14-
1513
export const installModule: CommandModule<unknown, { concurrency: number }> = {
1614
command: "install",
1715
describe: "installs nodecg-io to your local nodecg installation",

src/install/production.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
buildNpmPackagePath,
88
downloadNpmPackage,
99
createNpmSymlinks,
10+
getSubPackages,
1011
} from "../npm";
1112
import { directoryExists, ensureDirectory } from "../fsUtils";
1213
import { logger } from "../log";
@@ -53,14 +54,25 @@ export function diffPackages(
5354
requested: NpmPackage[],
5455
current: NpmPackage[],
5556
): { pkgInstall: NpmPackage[]; pkgRemove: NpmPackage[] } {
57+
// currently installed but not requested exactly anymore
58+
const pkgRemove = current.filter((a) => !requested.find((b) => isPackageEquals(a, b)));
59+
60+
// requested and not already exactly installed (e.g. version change)
61+
const pkgInstall = requested.filter((a) => !current.find((b) => isPackageEquals(a, b)));
62+
63+
// Gets sub-packages of packages in pkgInstall that might not be in there.
64+
// E.g. core got upgraded => nodecg-io-core will be removed and reinstalled
65+
// nodecg-io-dashboard will also be removed because it is in nodecg-io-core and
66+
// contained in the directory of the core package. This ensures that the dashboard will
67+
// also be reinstalled, even though it got no upgrade.
68+
const installAdditional = pkgInstall.map((pkg) => getSubPackages(requested, pkg)).flat();
69+
5670
return {
57-
pkgInstall: requested.filter((a) => !current.find((b) => isPackageEquals(a, b))), // requested and not already exactly installed (e.g. version change)
58-
pkgRemove: current.filter((a) => !requested.find((b) => isPackageEquals(a, b))), // currently installed but not requested exactly anymore
71+
pkgRemove,
72+
pkgInstall: [...new Set(pkgInstall.concat(installAdditional))],
5973
};
6074
}
6175

62-
// TODO: handle when e.g. core upgrades and removes nodecg-io-core directory. Need to re-download dashboard because it got deleted (or don't delete it).
63-
6476
/**
6577
* Removes a list of packages from a production nodecg-io install.
6678
* @param pkgs the packages that should be removed

src/install/prompt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function getPackagePath(pkgName: string) {
151151
async function getPackageVersion(pkgName: string, minorVersion: string) {
152152
const version = await getHighestPatchVersion(pkgName, minorVersion);
153153
// if patch part could be found out we will use .0 as it should always exist if the minor version also does.
154-
return version ?? `${version}.0`;
154+
return version ?? `${minorVersion}.0`;
155155
}
156156

157157
function getPackageSymlinks(pkgName: string) {

src/npm.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ export async function removeNpmPackage(pkg: NpmPackage, nodecgIODir: string): Pr
191191
await removeDirectory(buildNpmPackagePath(pkg, nodecgIODir));
192192
}
193193

194+
/**
195+
* Returns you all packages that are in a sub-path of rootPkg.
196+
* This is helpful if you have reinstalled rootPkg and now also need to reinstall all packages
197+
* that were in the directory of rootPkg because they also got removed in {@link removeNpmPackage}.
198+
* @returns the packages that are contained in rootPkg
199+
*/
200+
export function getSubPackages(allPackages: NpmPackage[], rootPkg: NpmPackage): NpmPackage[] {
201+
return allPackages.filter((pkg) => pkg !== rootPkg && pkg.path.startsWith(rootPkg.path));
202+
}
203+
194204
/**
195205
* Gets version of the installed npm by running "npm --version".
196206
* @returns the npm version or undefined if npm is not installed/not in $PATH.

test/install/production.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { vol } from "memfs";
22
import * as path from "path";
3-
import { corePkg, nodecgIODir, twitchChatPkg, validProdInstall } from "../testUtils";
3+
import { corePkg, dashboardPkg, nodecgIODir, twitchChatPkg, validProdInstall } from "../testUtils";
44
import { diffPackages, installPackages, removePackages, validateInstall } from "../../src/install/production";
55
import * as installation from "../../src/installation";
66
import * as fsUtils from "../../src/fsUtils";
@@ -45,6 +45,13 @@ describe("diffPackages", () => {
4545
expect(pkgRemove).toStrictEqual([]);
4646
expect(pkgInstall).toStrictEqual([]);
4747
});
48+
49+
test("should install dashboard (sub pkg) if upgrading core", async () => {
50+
// dashboard not modified, but should still be installed because it is in core and core gets upgraded
51+
const { pkgInstall, pkgRemove } = diffPackages([corePkg2, dashboardPkg], [corePkg, dashboardPkg]);
52+
expect(pkgRemove).toStrictEqual([corePkg]);
53+
expect(pkgInstall).toStrictEqual([corePkg2, dashboardPkg]);
54+
});
4855
});
4956

5057
describe("removePackages", () => {

test/install/prompt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe("getCompatibleVersions", () => {
2525
});
2626

2727
describe("buildPackageList", () => {
28-
const ver = "0.1.0";
28+
const ver = "0.1";
2929
const testSvcName = "testSvc";
3030
const testSvcPkgName = `nodecg-io-${testSvcName}`;
3131
const mock = jest.spyOn(npm, "getHighestPatchVersion").mockResolvedValue("0.1.1");

test/npm/pkgManagement.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createFsFromVolume, vol } from "memfs";
2-
import { createNpmSymlinks, removeNpmPackage, runNpmInstall } from "../../src/npm";
3-
import { tempDir, corePkg, fsRoot } from "../testUtils";
2+
import { createNpmSymlinks, getSubPackages, removeNpmPackage, runNpmInstall } from "../../src/npm";
3+
import { tempDir, corePkg, fsRoot, twitchChatPkg, dashboardPkg } from "../testUtils";
44
import * as fsUtils from "../../src/fsUtils";
55
import * as path from "path";
66

@@ -45,3 +45,13 @@ describe("removeNpmPackage", () => {
4545
expect(spy).toHaveBeenCalled();
4646
});
4747
});
48+
49+
describe("getSubPackages", () => {
50+
test("should return empty list if no packages are inside the passed package", async () => {
51+
expect(getSubPackages([corePkg, twitchChatPkg], corePkg)).toStrictEqual([]);
52+
});
53+
54+
test("should return dashboard to be inside core", async () => {
55+
expect(getSubPackages([corePkg, dashboardPkg], corePkg)).toStrictEqual([dashboardPkg]);
56+
});
57+
});

test/testUtils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as temp from "temp";
2-
import { corePackage } from "../src/install/nodecgIOVersions";
2+
import { corePackage, dashboardPackage, dashboardPath } from "../src/install/nodecgIOVersions";
33
import * as path from "path";
44
import { DevelopmentInstallation, ProductionInstallation } from "../src/installation";
55

@@ -21,6 +21,11 @@ export const twitchChatPkg = {
2121
path: "nodecg-io-twitch-chat",
2222
version: "0.1.0",
2323
};
24+
export const dashboardPkg = {
25+
name: dashboardPackage,
26+
path: dashboardPath,
27+
version: "0.1.0",
28+
};
2429
export const nodecgExampleConfig = {
2530
bundles: {
2631
paths: ["some-custom-bundle-dir"],

0 commit comments

Comments
 (0)