Skip to content

Commit bd72968

Browse files
committed
update version sync script, update and add tests
1 parent ccf3793 commit bd72968

7 files changed

Lines changed: 358 additions & 38 deletions

File tree

scripts/sync-manifest-version.cjs

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,114 @@
1-
// Sync manifest.json version with package.json
1+
// Sync manifest.json and server.json versions with package.json
22
const fs = require('node:fs');
33
const path = require('node:path');
44

5-
function syncManifestVersion() {
5+
/**
6+
* Pure function that syncs versions across config objects
7+
* @param {Object} packageJson - The package.json object
8+
* @param {Object} manifestJson - The manifest.json object
9+
* @param {Object} serverJson - The server.json object
10+
* @returns {Object} Result containing updated configs and change information
11+
*/
12+
function syncVersionsCore(packageJson, manifestJson, serverJson) {
13+
const packageVersion = packageJson.version;
14+
const result = {
15+
packageVersion,
16+
updatedManifest: null,
17+
updatedServer: null,
18+
changes: {
19+
manifest: false,
20+
server: false,
21+
serverPackage: false
22+
},
23+
oldVersions: {
24+
manifest: manifestJson.version,
25+
server: serverJson.version,
26+
serverPackage: serverJson.packages?.[0]?.version
27+
}
28+
};
29+
30+
// Check and update manifest.json
31+
if (manifestJson.version !== packageVersion) {
32+
result.updatedManifest = { ...manifestJson, version: packageVersion };
33+
result.changes.manifest = true;
34+
}
35+
36+
// Check and update server.json
37+
const serverNeedsUpdate = serverJson.version !== packageVersion;
38+
const packageNeedsUpdate = serverJson.packages?.[0] &&
39+
serverJson.packages[0].version !== packageVersion;
40+
41+
if (serverNeedsUpdate || packageNeedsUpdate) {
42+
result.updatedServer = JSON.parse(JSON.stringify(serverJson)); // Deep clone
43+
44+
if (serverNeedsUpdate) {
45+
result.updatedServer.version = packageVersion;
46+
result.changes.server = true;
47+
}
48+
49+
if (packageNeedsUpdate) {
50+
result.updatedServer.packages[0].version = packageVersion;
51+
result.changes.serverPackage = true;
52+
}
53+
}
54+
55+
return result;
56+
}
57+
58+
function syncVersions() {
659
const packageJsonPath = path.join(process.cwd(), 'package.json');
760
const manifestJsonPath = path.join(process.cwd(), 'manifest.json');
61+
const serverJsonPath = path.join(process.cwd(), 'server.json');
862

9-
// Read package.json
63+
// Read files
1064
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
11-
const packageVersion = packageJson.version;
12-
13-
// Read manifest.json
1465
const manifestJson = JSON.parse(fs.readFileSync(manifestJsonPath, 'utf-8'));
15-
const manifestVersion = manifestJson.version;
66+
const serverJson = JSON.parse(fs.readFileSync(serverJsonPath, 'utf-8'));
67+
68+
// Sync versions using pure function
69+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
70+
71+
let updatedFiles = [];
1672

17-
// Check if versions are already in sync
18-
if (manifestVersion === packageVersion) {
19-
console.log(`✓ Versions already in sync: ${packageVersion}`);
20-
return;
73+
// Write updated manifest if needed
74+
if (result.updatedManifest) {
75+
fs.writeFileSync(
76+
manifestJsonPath,
77+
JSON.stringify(result.updatedManifest, null, 2) + '\n',
78+
'utf-8'
79+
);
80+
console.log(
81+
`✓ Updated manifest.json version: ${result.oldVersions.manifest}${result.packageVersion}`
82+
);
83+
updatedFiles.push('manifest.json');
2184
}
2285

23-
// Update manifest.json version
24-
manifestJson.version = packageVersion;
25-
fs.writeFileSync(
26-
manifestJsonPath,
27-
JSON.stringify(manifestJson, null, 2) + '\n',
28-
'utf-8'
29-
);
30-
31-
console.log(
32-
`✓ Updated manifest.json version: ${manifestVersion}${packageVersion}`
33-
);
86+
// Write updated server if needed
87+
if (result.updatedServer) {
88+
fs.writeFileSync(
89+
serverJsonPath,
90+
JSON.stringify(result.updatedServer, null, 2) + '\n',
91+
'utf-8'
92+
);
93+
console.log(
94+
`✓ Updated server.json versions: ${result.oldVersions.server}${result.packageVersion}`
95+
);
96+
updatedFiles.push('server.json');
97+
}
98+
99+
if (updatedFiles.length === 0) {
100+
console.log(`✓ All versions already in sync: ${result.packageVersion}`);
101+
} else {
102+
console.log(`✓ Synced ${updatedFiles.join(', ')} with package.json version: ${result.packageVersion}`);
103+
}
104+
}
105+
106+
// Export for testing
107+
if (typeof module !== 'undefined' && module.exports) {
108+
module.exports = { syncVersionsCore, syncVersions };
34109
}
35110

36-
syncManifestVersion();
111+
// Run if called directly
112+
if (require.main === module) {
113+
syncVersions();
114+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"dxt_version": "0.1",
3+
"name": "test-manifest",
4+
"version": "1.0.0",
5+
"description": "Test manifest",
6+
"author": {
7+
"name": "Test Author"
8+
}
9+
}

test/project/fixtures/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "test-package",
3+
"version": "2.0.0",
4+
"description": "Test package for sync script"
5+
}

test/project/fixtures/server.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"$schema": "test-schema",
3+
"name": "test-server",
4+
"version": "1.5.0",
5+
"packages": [
6+
{
7+
"identifier": "test-package",
8+
"version": "1.2.0",
9+
"registryType": "npm"
10+
}
11+
]
12+
}
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { readFileSync } from 'node:fs';
3+
import { join, dirname } from 'node:path';
4+
import { fileURLToPath } from 'node:url';
5+
import { createRequire } from 'node:module';
6+
7+
const __dirname = dirname(fileURLToPath(import.meta.url));
8+
const require = createRequire(import.meta.url);
9+
10+
// Import the pure function from the sync script
11+
const { syncVersionsCore } = require('../../scripts/sync-manifest-version.cjs');
12+
13+
describe('sync-manifest-version.cjs - syncVersionsCore', () => {
14+
// Load fixtures
15+
const fixturesDir = join(__dirname, 'fixtures');
16+
const packageJsonFixture = JSON.parse(
17+
readFileSync(join(fixturesDir, 'package.json'), 'utf-8')
18+
);
19+
const manifestJsonFixture = JSON.parse(
20+
readFileSync(join(fixturesDir, 'manifest.json'), 'utf-8')
21+
);
22+
const serverJsonFixture = JSON.parse(
23+
readFileSync(join(fixturesDir, 'server.json'), 'utf-8')
24+
);
25+
26+
it('should update manifest.json when version differs from package.json', () => {
27+
const packageJson = { ...packageJsonFixture, version: '3.0.0' };
28+
const manifestJson = { ...manifestJsonFixture, version: '1.0.0' };
29+
const serverJson = {
30+
...serverJsonFixture,
31+
version: '3.0.0',
32+
packages: [{ ...serverJsonFixture.packages[0], version: '3.0.0' }]
33+
};
34+
35+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
36+
37+
expect(result.updatedManifest).toBeDefined();
38+
expect(result.updatedManifest.version).toBe('3.0.0');
39+
expect(result.updatedManifest.name).toBe('test-manifest'); // Other fields preserved
40+
expect(result.changes.manifest).toBe(true);
41+
expect(result.changes.server).toBe(false);
42+
expect(result.changes.serverPackage).toBe(false);
43+
expect(result.updatedServer).toBeNull();
44+
});
45+
46+
it('should update server.json top-level version when it differs', () => {
47+
const packageJson = { ...packageJsonFixture, version: '4.0.0' };
48+
const manifestJson = { ...manifestJsonFixture, version: '4.0.0' };
49+
const serverJson = {
50+
...serverJsonFixture,
51+
version: '2.0.0',
52+
packages: [{ ...serverJsonFixture.packages[0], version: '4.0.0' }]
53+
};
54+
55+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
56+
57+
expect(result.updatedServer).toBeDefined();
58+
expect(result.updatedServer.version).toBe('4.0.0');
59+
expect(result.updatedServer.name).toBe('test-server'); // Other fields preserved
60+
expect(result.changes.server).toBe(true);
61+
expect(result.changes.serverPackage).toBe(false);
62+
expect(result.changes.manifest).toBe(false);
63+
expect(result.updatedManifest).toBeNull();
64+
});
65+
66+
it('should update server.json packages[0].version when it differs', () => {
67+
const packageJson = { ...packageJsonFixture, version: '5.0.0' };
68+
const manifestJson = { ...manifestJsonFixture, version: '5.0.0' };
69+
const serverJson = {
70+
...serverJsonFixture,
71+
version: '5.0.0',
72+
packages: [{ ...serverJsonFixture.packages[0], version: '3.0.0' }]
73+
};
74+
75+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
76+
77+
expect(result.updatedServer).toBeDefined();
78+
expect(result.updatedServer.packages[0].version).toBe('5.0.0');
79+
expect(result.updatedServer.packages[0].identifier).toBe('test-package'); // Other fields preserved
80+
expect(result.changes.serverPackage).toBe(true);
81+
expect(result.changes.server).toBe(false);
82+
expect(result.changes.manifest).toBe(false);
83+
});
84+
85+
it('should update all versions when all differ', () => {
86+
const packageJson = { ...packageJsonFixture, version: '6.0.0' };
87+
const manifestJson = { ...manifestJsonFixture, version: '1.0.0' };
88+
const serverJson = {
89+
...serverJsonFixture,
90+
version: '2.0.0',
91+
packages: [{ ...serverJsonFixture.packages[0], version: '3.0.0' }]
92+
};
93+
94+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
95+
96+
expect(result.updatedManifest).toBeDefined();
97+
expect(result.updatedManifest.version).toBe('6.0.0');
98+
expect(result.updatedServer).toBeDefined();
99+
expect(result.updatedServer.version).toBe('6.0.0');
100+
expect(result.updatedServer.packages[0].version).toBe('6.0.0');
101+
expect(result.changes.manifest).toBe(true);
102+
expect(result.changes.server).toBe(true);
103+
expect(result.changes.serverPackage).toBe(true);
104+
});
105+
106+
it('should return no updates when all versions are in sync', () => {
107+
const packageJson = { ...packageJsonFixture, version: '7.0.0' };
108+
const manifestJson = { ...manifestJsonFixture, version: '7.0.0' };
109+
const serverJson = {
110+
...serverJsonFixture,
111+
version: '7.0.0',
112+
packages: [{ ...serverJsonFixture.packages[0], version: '7.0.0' }]
113+
};
114+
115+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
116+
117+
expect(result.updatedManifest).toBeNull();
118+
expect(result.updatedServer).toBeNull();
119+
expect(result.changes.manifest).toBe(false);
120+
expect(result.changes.server).toBe(false);
121+
expect(result.changes.serverPackage).toBe(false);
122+
expect(result.packageVersion).toBe('7.0.0');
123+
});
124+
125+
it('should handle server.json without packages array', () => {
126+
const packageJson = { ...packageJsonFixture, version: '8.0.0' };
127+
const manifestJson = { ...manifestJsonFixture, version: '8.0.0' };
128+
const serverJson = {
129+
name: 'test-server',
130+
version: '1.0.0'
131+
// No packages array
132+
};
133+
134+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
135+
136+
expect(result.updatedServer).toBeDefined();
137+
expect(result.updatedServer.version).toBe('8.0.0');
138+
expect(result.updatedServer.packages).toBeUndefined(); // Should not add packages
139+
expect(result.changes.server).toBe(true);
140+
expect(result.changes.serverPackage).toBe(false);
141+
});
142+
143+
it('should handle server.json with empty packages array', () => {
144+
const packageJson = { ...packageJsonFixture, version: '9.0.0' };
145+
const manifestJson = { ...manifestJsonFixture, version: '9.0.0' };
146+
const serverJson = {
147+
...serverJsonFixture,
148+
version: '9.0.0',
149+
packages: []
150+
};
151+
152+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
153+
154+
expect(result.updatedServer).toBeNull();
155+
expect(result.changes.server).toBe(false);
156+
expect(result.changes.serverPackage).toBe(false);
157+
});
158+
159+
it('should track old versions for reporting', () => {
160+
const packageJson = { ...packageJsonFixture, version: '10.0.0' };
161+
const manifestJson = { ...manifestJsonFixture, version: '1.1.0' };
162+
const serverJson = {
163+
...serverJsonFixture,
164+
version: '2.2.0',
165+
packages: [{ ...serverJsonFixture.packages[0], version: '3.3.0' }]
166+
};
167+
168+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
169+
170+
expect(result.oldVersions.manifest).toBe('1.1.0');
171+
expect(result.oldVersions.server).toBe('2.2.0');
172+
expect(result.oldVersions.serverPackage).toBe('3.3.0');
173+
expect(result.packageVersion).toBe('10.0.0');
174+
});
175+
176+
it('should preserve all non-version fields in updated objects', () => {
177+
const packageJson = { ...packageJsonFixture, version: '11.0.0' };
178+
const manifestJson = {
179+
...manifestJsonFixture,
180+
version: '1.0.0',
181+
customField: 'should-be-preserved',
182+
nested: { data: 'also-preserved' }
183+
};
184+
const serverJson = {
185+
...serverJsonFixture,
186+
version: '2.0.0',
187+
packages: [
188+
{
189+
...serverJsonFixture.packages[0],
190+
version: '3.0.0',
191+
extraData: 'keep-this'
192+
}
193+
],
194+
metadata: 'preserve-me'
195+
};
196+
197+
const result = syncVersionsCore(packageJson, manifestJson, serverJson);
198+
199+
expect(result.updatedManifest.customField).toBe('should-be-preserved');
200+
expect(result.updatedManifest.nested).toEqual({ data: 'also-preserved' });
201+
expect(result.updatedServer.metadata).toBe('preserve-me');
202+
expect(result.updatedServer.packages[0].extraData).toBe('keep-this');
203+
});
204+
});

0 commit comments

Comments
 (0)