@shazhou/proman-core 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/LICENSE +18 -0
- package/dist/commands/bump.d.ts +13 -0
- package/dist/commands/bump.d.ts.map +1 -0
- package/dist/commands/bump.js +115 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +42 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +175 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +262 -0
- package/dist/commands/link.d.ts +19 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +155 -0
- package/dist/commands/publish.d.ts +18 -0
- package/dist/commands/publish.d.ts.map +1 -0
- package/dist/commands/publish.js +125 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/load-config.d.ts +6 -0
- package/dist/config/load-config.d.ts.map +1 -0
- package/dist/config/load-config.js +29 -0
- package/dist/config/types.d.ts +17 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +1 -0
- package/dist/config/validate-config.d.ts +7 -0
- package/dist/config/validate-config.d.ts.map +1 -0
- package/dist/config/validate-config.js +72 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/utils/changeset.d.ts +16 -0
- package/dist/utils/changeset.d.ts.map +1 -0
- package/dist/utils/changeset.js +80 -0
- package/dist/utils/fingerprint.d.ts +38 -0
- package/dist/utils/fingerprint.d.ts.map +1 -0
- package/dist/utils/fingerprint.js +182 -0
- package/dist/utils/git.d.ts +23 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +105 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/npm.d.ts +30 -0
- package/dist/utils/npm.d.ts.map +1 -0
- package/dist/utils/npm.js +85 -0
- package/dist/utils/smoke-test.d.ts +7 -0
- package/dist/utils/smoke-test.d.ts.map +1 -0
- package/dist/utils/smoke-test.js +59 -0
- package/dist/utils/version.d.ts +5 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +36 -0
- package/dist/utils/workspace.d.ts +21 -0
- package/dist/utils/workspace.d.ts.map +1 -0
- package/dist/utils/workspace.js +73 -0
- package/package.json +45 -0
- package/src/commands/bump.ts +131 -0
- package/src/commands/deploy.ts +52 -0
- package/src/commands/dev.ts +214 -0
- package/src/commands/index.ts +7 -0
- package/src/commands/init.integration.test.ts +59 -0
- package/src/commands/init.test.ts +179 -0
- package/src/commands/init.ts +290 -0
- package/src/commands/link.ts +195 -0
- package/src/commands/publish.ts +168 -0
- package/src/config/index.ts +8 -0
- package/src/config/load-config.ts +33 -0
- package/src/config/types.ts +19 -0
- package/src/config/validate-config.ts +81 -0
- package/src/index.ts +29 -0
- package/src/utils/changeset.ts +98 -0
- package/src/utils/fingerprint.ts +199 -0
- package/src/utils/git.ts +119 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/npm.ts +110 -0
- package/src/utils/smoke-test.ts +79 -0
- package/src/utils/version.ts +41 -0
- package/src/utils/workspace.ts +94 -0
- package/tests/build-fingerprint-integration.test.ts +403 -0
- package/tests/bump.test.ts +261 -0
- package/tests/changeset.test.ts +147 -0
- package/tests/deploy.test.ts +98 -0
- package/tests/dev.test.ts +756 -0
- package/tests/fingerprint.test.ts +316 -0
- package/tests/fixtures/api-only/packages/api/.gitkeep +0 -0
- package/tests/fixtures/api-only/proman.yaml +4 -0
- package/tests/fixtures/bad-packages/proman.yaml +1 -0
- package/tests/fixtures/bun-project/packages/a/.gitkeep +0 -0
- package/tests/fixtures/bun-project/proman.yaml +4 -0
- package/tests/fixtures/defaults/proman.yaml +3 -0
- package/tests/fixtures/no-deployable/packages/core/.gitkeep +0 -0
- package/tests/fixtures/no-deployable/packages/mycli/.gitkeep +0 -0
- package/tests/fixtures/no-deployable/proman.yaml +7 -0
- package/tests/fixtures/node-runtime/packages/a/package.json +5 -0
- package/tests/fixtures/node-runtime/proman.yaml +3 -0
- package/tests/fixtures/pnpm-project/packages/a/package.json +1 -0
- package/tests/fixtures/pnpm-project/pnpm-lock.yaml +0 -0
- package/tests/fixtures/pnpm-project/proman.yaml +3 -0
- package/tests/fixtures/typed/packages/api/.gitkeep +0 -0
- package/tests/fixtures/typed/packages/core/.gitkeep +0 -0
- package/tests/fixtures/typed/packages/dashboard/.gitkeep +0 -0
- package/tests/fixtures/typed/packages/mycli/.gitkeep +0 -0
- package/tests/fixtures/typed/proman.yaml +13 -0
- package/tests/fixtures/valid/packages/cli/package.json +5 -0
- package/tests/fixtures/valid/packages/core/package.json +5 -0
- package/tests/fixtures/valid/packages/fs/package.json +5 -0
- package/tests/fixtures/valid/proman.yaml +13 -0
- package/tests/fixtures/webui-only/packages/dashboard/.gitkeep +0 -0
- package/tests/fixtures/webui-only/proman.yaml +4 -0
- package/tests/link.test.ts +419 -0
- package/tests/load-config.test.ts +44 -0
- package/tests/npm.test.ts +199 -0
- package/tests/publish.test.ts +599 -0
- package/tests/smoke-test.test.ts +211 -0
- package/tests/validate-config.test.ts +67 -0
- package/tests/version.test.ts +86 -0
- package/tests/workflow-schema.test.ts +72 -0
- package/tests/workspace.test.ts +160 -0
- package/tsconfig.build.json +14 -0
- package/tsconfig.json +8 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, rmSync, utimesSync, writeFileSync } from 'node:fs'
|
|
2
|
+
import { tmpdir } from 'node:os'
|
|
3
|
+
import { join, resolve } from 'node:path'
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
|
|
5
|
+
import {
|
|
6
|
+
computeBuildFingerprints,
|
|
7
|
+
computeRootFingerprint,
|
|
8
|
+
fingerprintPath,
|
|
9
|
+
hashFiles,
|
|
10
|
+
pkgNameToFilename,
|
|
11
|
+
readFingerprint,
|
|
12
|
+
writeFingerprint,
|
|
13
|
+
} from '../src/utils/fingerprint.ts'
|
|
14
|
+
|
|
15
|
+
let tmpDir: string
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
tmpDir = resolve(tmpdir(), `proman-fp-test-${Date.now()}-${Math.random().toString(36).slice(2)}`)
|
|
19
|
+
mkdirSync(tmpDir, { recursive: true })
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
rmSync(tmpDir, { recursive: true, force: true })
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('hashFiles', () => {
|
|
27
|
+
test('F1: deterministic — same content → same hash', () => {
|
|
28
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
29
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const x = 1')
|
|
30
|
+
|
|
31
|
+
const hash1 = hashFiles(tmpDir, ['**/*.ts'])
|
|
32
|
+
const hash2 = hashFiles(tmpDir, ['**/*.ts'])
|
|
33
|
+
|
|
34
|
+
expect(hash1).toBeTruthy()
|
|
35
|
+
expect(hash1).toBe(hash2)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('F2: content-sensitive — different content → different hash', () => {
|
|
39
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
40
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const x = 1')
|
|
41
|
+
const hash1 = hashFiles(tmpDir, ['**/*.ts'])
|
|
42
|
+
|
|
43
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const x = 2')
|
|
44
|
+
const hash2 = hashFiles(tmpDir, ['**/*.ts'])
|
|
45
|
+
|
|
46
|
+
expect(hash1).not.toBe(hash2)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('F3: order-independent — file discovery order does not matter', () => {
|
|
50
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
51
|
+
writeFileSync(join(tmpDir, 'src', 'b.ts'), 'export const b = 2')
|
|
52
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const a = 1')
|
|
53
|
+
|
|
54
|
+
const hash1 = hashFiles(tmpDir, ['**/*.ts'])
|
|
55
|
+
const hash2 = hashFiles(tmpDir, ['**/*.ts'])
|
|
56
|
+
|
|
57
|
+
expect(hash1).toBe(hash2)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
test('F4: content-based, not mtime-based — touch without change keeps same hash', () => {
|
|
61
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
62
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const x = 1')
|
|
63
|
+
|
|
64
|
+
const hash1 = hashFiles(tmpDir, ['**/*.ts'])
|
|
65
|
+
|
|
66
|
+
// Touch the file (update mtime but not content)
|
|
67
|
+
const future = new Date(Date.now() + 60000)
|
|
68
|
+
utimesSync(join(tmpDir, 'src', 'a.ts'), future, future)
|
|
69
|
+
|
|
70
|
+
const hash2 = hashFiles(tmpDir, ['**/*.ts'])
|
|
71
|
+
|
|
72
|
+
expect(hash1).toBe(hash2)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('F5: ignores non-matching files', () => {
|
|
76
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
77
|
+
writeFileSync(join(tmpDir, 'src', 'a.ts'), 'export const x = 1')
|
|
78
|
+
writeFileSync(join(tmpDir, 'readme.md'), '# README')
|
|
79
|
+
|
|
80
|
+
const hash1 = hashFiles(tmpDir, ['**/*.ts'])
|
|
81
|
+
|
|
82
|
+
writeFileSync(join(tmpDir, 'another.md'), '# Another')
|
|
83
|
+
|
|
84
|
+
const hash2 = hashFiles(tmpDir, ['**/*.ts'])
|
|
85
|
+
|
|
86
|
+
expect(hash1).toBe(hash2)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
describe('readFingerprint / writeFingerprint', () => {
|
|
91
|
+
test('F6: readFingerprint returns null when file missing', () => {
|
|
92
|
+
expect(readFingerprint(join(tmpDir, 'nonexistent', 'fp'))).toBeNull()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('F7: round-trip — write then read returns same value', () => {
|
|
96
|
+
const fpPath = join(tmpDir, 'test.fingerprint')
|
|
97
|
+
writeFingerprint(fpPath, 'abc123')
|
|
98
|
+
expect(readFingerprint(fpPath)).toBe('abc123')
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
test('F8: writeFingerprint creates parent directories', () => {
|
|
102
|
+
const fpPath = join(tmpDir, 'deep', 'nested', 'dir', 'fp')
|
|
103
|
+
writeFingerprint(fpPath, 'hash')
|
|
104
|
+
expect(existsSync(fpPath)).toBe(true)
|
|
105
|
+
expect(readFingerprint(fpPath)).toBe('hash')
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
describe('pkgNameToFilename / fingerprintPath', () => {
|
|
110
|
+
test('F-san1: pkgNameToFilename converts @scope/name → @scope-name', () => {
|
|
111
|
+
expect(pkgNameToFilename('@ocas/core')).toBe('@ocas-core')
|
|
112
|
+
expect(pkgNameToFilename('@test/cli')).toBe('@test-cli')
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
test('F-san2: fingerprintPath round-trip for scoped package names (non-build commands)', () => {
|
|
116
|
+
// Test with deploy command (non-build command should still use old .proman path)
|
|
117
|
+
const fpPath = fingerprintPath(tmpDir, 'deploy', '@ocas/core')
|
|
118
|
+
writeFingerprint(fpPath, 'x')
|
|
119
|
+
expect(readFingerprint(fpPath)).toBe('x')
|
|
120
|
+
expect(fpPath).toContain('@ocas-core.fingerprint')
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('F-san3: fingerprintPath with no pkgName uses root.fingerprint', () => {
|
|
124
|
+
const fpPath = fingerprintPath(tmpDir, 'test')
|
|
125
|
+
expect(fpPath).toContain('root.fingerprint')
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('F-san4: fingerprintPath for build command returns path inside package dist folder', () => {
|
|
129
|
+
const pkgDir = join(tmpDir, 'packages/pkg')
|
|
130
|
+
const fpPath = fingerprintPath(pkgDir, 'build', '@test/pkg')
|
|
131
|
+
expect(fpPath).toBe(join(pkgDir, 'dist/.build-fingerprint'))
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test('F-san5: fingerprintPath for test/check commands returns path in .proman', () => {
|
|
135
|
+
const testFpPath = fingerprintPath(tmpDir, 'test')
|
|
136
|
+
expect(testFpPath).toBe(join(tmpDir, '.proman/test/root.fingerprint'))
|
|
137
|
+
|
|
138
|
+
const checkFpPath = fingerprintPath(tmpDir, 'check')
|
|
139
|
+
expect(checkFpPath).toBe(join(tmpDir, '.proman/check/root.fingerprint'))
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
describe('computeBuildFingerprints', () => {
|
|
144
|
+
function writeMonorepo(root: string): void {
|
|
145
|
+
// core — no workspace deps
|
|
146
|
+
mkdirSync(join(root, 'packages/core/src'), { recursive: true })
|
|
147
|
+
writeFileSync(join(root, 'packages/core/src/index.ts'), 'export const x = 1')
|
|
148
|
+
writeFileSync(
|
|
149
|
+
join(root, 'packages/core/package.json'),
|
|
150
|
+
JSON.stringify({ name: '@test/core', version: '1.0.0' }),
|
|
151
|
+
)
|
|
152
|
+
writeFileSync(join(root, 'packages/core/tsconfig.json'), '{}')
|
|
153
|
+
|
|
154
|
+
// fs — depends on core
|
|
155
|
+
mkdirSync(join(root, 'packages/fs/src'), { recursive: true })
|
|
156
|
+
writeFileSync(join(root, 'packages/fs/src/index.ts'), 'export const y = 2')
|
|
157
|
+
writeFileSync(
|
|
158
|
+
join(root, 'packages/fs/package.json'),
|
|
159
|
+
JSON.stringify({
|
|
160
|
+
name: '@test/fs',
|
|
161
|
+
version: '1.0.0',
|
|
162
|
+
dependencies: { '@test/core': 'workspace:*' },
|
|
163
|
+
}),
|
|
164
|
+
)
|
|
165
|
+
writeFileSync(join(root, 'packages/fs/tsconfig.json'), '{}')
|
|
166
|
+
|
|
167
|
+
// cli — depends on fs
|
|
168
|
+
mkdirSync(join(root, 'packages/cli/src'), { recursive: true })
|
|
169
|
+
writeFileSync(join(root, 'packages/cli/src/index.ts'), 'export const z = 3')
|
|
170
|
+
writeFileSync(
|
|
171
|
+
join(root, 'packages/cli/package.json'),
|
|
172
|
+
JSON.stringify({
|
|
173
|
+
name: '@test/cli',
|
|
174
|
+
version: '1.0.0',
|
|
175
|
+
dependencies: { '@test/fs': 'workspace:*' },
|
|
176
|
+
}),
|
|
177
|
+
)
|
|
178
|
+
writeFileSync(join(root, 'packages/cli/tsconfig.json'), '{}')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
test('F9: returns per-package fingerprints', () => {
|
|
182
|
+
writeMonorepo(tmpDir)
|
|
183
|
+
const packages = [
|
|
184
|
+
{ name: '@test/core', path: 'packages/core', type: 'lib' as const },
|
|
185
|
+
{ name: '@test/fs', path: 'packages/fs', type: 'lib' as const },
|
|
186
|
+
{ name: '@test/cli', path: 'packages/cli', type: 'cli' as const },
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
const fps = computeBuildFingerprints(tmpDir, packages)
|
|
190
|
+
|
|
191
|
+
expect(fps.size).toBe(3)
|
|
192
|
+
expect(fps.get('@test/core')).toBeTruthy()
|
|
193
|
+
expect(fps.get('@test/fs')).toBeTruthy()
|
|
194
|
+
expect(fps.get('@test/cli')).toBeTruthy()
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
test('F10: dependency propagation — changing leaf invalidates dependents', () => {
|
|
198
|
+
writeMonorepo(tmpDir)
|
|
199
|
+
const packages = [
|
|
200
|
+
{ name: '@test/core', path: 'packages/core', type: 'lib' as const },
|
|
201
|
+
{ name: '@test/fs', path: 'packages/fs', type: 'lib' as const },
|
|
202
|
+
{ name: '@test/cli', path: 'packages/cli', type: 'cli' as const },
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
const before = computeBuildFingerprints(tmpDir, packages)
|
|
206
|
+
|
|
207
|
+
// Modify core's source
|
|
208
|
+
writeFileSync(join(tmpDir, 'packages/core/src/index.ts'), 'export const x = 999')
|
|
209
|
+
|
|
210
|
+
const after = computeBuildFingerprints(tmpDir, packages)
|
|
211
|
+
|
|
212
|
+
// core changed directly
|
|
213
|
+
expect(before.get('@test/core')).not.toBe(after.get('@test/core'))
|
|
214
|
+
// fs changed transitively (depends on core)
|
|
215
|
+
expect(before.get('@test/fs')).not.toBe(after.get('@test/fs'))
|
|
216
|
+
// cli changed transitively (depends on fs → core)
|
|
217
|
+
expect(before.get('@test/cli')).not.toBe(after.get('@test/cli'))
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
test('F11: changing leaf does NOT invalidate unrelated packages', () => {
|
|
221
|
+
writeMonorepo(tmpDir)
|
|
222
|
+
|
|
223
|
+
// Add an unrelated package (util, no deps)
|
|
224
|
+
mkdirSync(join(tmpDir, 'packages/util/src'), { recursive: true })
|
|
225
|
+
writeFileSync(join(tmpDir, 'packages/util/src/index.ts'), 'export const u = 0')
|
|
226
|
+
writeFileSync(
|
|
227
|
+
join(tmpDir, 'packages/util/package.json'),
|
|
228
|
+
JSON.stringify({ name: '@test/util', version: '1.0.0' }),
|
|
229
|
+
)
|
|
230
|
+
writeFileSync(join(tmpDir, 'packages/util/tsconfig.json'), '{}')
|
|
231
|
+
|
|
232
|
+
const packages = [
|
|
233
|
+
{ name: '@test/core', path: 'packages/core', type: 'lib' as const },
|
|
234
|
+
{ name: '@test/fs', path: 'packages/fs', type: 'lib' as const },
|
|
235
|
+
{ name: '@test/cli', path: 'packages/cli', type: 'cli' as const },
|
|
236
|
+
{ name: '@test/util', path: 'packages/util', type: 'lib' as const },
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
const before = computeBuildFingerprints(tmpDir, packages)
|
|
240
|
+
|
|
241
|
+
// Modify core's source
|
|
242
|
+
writeFileSync(join(tmpDir, 'packages/core/src/index.ts'), 'export const x = 888')
|
|
243
|
+
|
|
244
|
+
const after = computeBuildFingerprints(tmpDir, packages)
|
|
245
|
+
|
|
246
|
+
// core changed
|
|
247
|
+
expect(before.get('@test/core')).not.toBe(after.get('@test/core'))
|
|
248
|
+
// util unchanged (no dep on core)
|
|
249
|
+
expect(before.get('@test/util')).toBe(after.get('@test/util'))
|
|
250
|
+
})
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
describe('computeRootFingerprint', () => {
|
|
254
|
+
test('F12: test fingerprint includes src and tests', () => {
|
|
255
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
256
|
+
mkdirSync(join(tmpDir, 'tests'), { recursive: true })
|
|
257
|
+
writeFileSync(join(tmpDir, 'src/a.ts'), 'export const x = 1')
|
|
258
|
+
writeFileSync(join(tmpDir, 'tests/a.test.ts'), 'test("a", () => {})')
|
|
259
|
+
writeFileSync(join(tmpDir, 'package.json'), '{}')
|
|
260
|
+
|
|
261
|
+
const hash1 = computeRootFingerprint(tmpDir, 'test')
|
|
262
|
+
|
|
263
|
+
writeFileSync(join(tmpDir, 'tests/a.test.ts'), 'test("b", () => {})')
|
|
264
|
+
|
|
265
|
+
const hash2 = computeRootFingerprint(tmpDir, 'test')
|
|
266
|
+
|
|
267
|
+
expect(hash1).not.toBe(hash2)
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
test('F13: check fingerprint includes biome.json', () => {
|
|
271
|
+
mkdirSync(join(tmpDir, 'src'), { recursive: true })
|
|
272
|
+
writeFileSync(join(tmpDir, 'src/a.ts'), 'export const x = 1')
|
|
273
|
+
writeFileSync(join(tmpDir, 'package.json'), '{}')
|
|
274
|
+
writeFileSync(join(tmpDir, 'biome.json'), '{ "linter": {} }')
|
|
275
|
+
|
|
276
|
+
const hash1 = computeRootFingerprint(tmpDir, 'check')
|
|
277
|
+
|
|
278
|
+
writeFileSync(join(tmpDir, 'biome.json'), '{ "linter": { "enabled": false } }')
|
|
279
|
+
|
|
280
|
+
const hash2 = computeRootFingerprint(tmpDir, 'check')
|
|
281
|
+
|
|
282
|
+
expect(hash1).not.toBe(hash2)
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
describe('Fingerprint storage inside build output (Issue #135)', () => {
|
|
287
|
+
test('T1: Fingerprint stored inside dist folder', () => {
|
|
288
|
+
const pkgDir = join(tmpDir, 'packages/pkg')
|
|
289
|
+
mkdirSync(join(pkgDir, 'src'), { recursive: true })
|
|
290
|
+
mkdirSync(join(pkgDir, 'dist'), { recursive: true })
|
|
291
|
+
writeFileSync(join(pkgDir, 'src/index.ts'), 'export const x = 1')
|
|
292
|
+
writeFileSync(join(pkgDir, 'package.json'), JSON.stringify({ name: '@test/pkg' }))
|
|
293
|
+
|
|
294
|
+
// Write fingerprint using new location
|
|
295
|
+
const fpPath = fingerprintPath(pkgDir, 'build', '@test/pkg')
|
|
296
|
+
writeFingerprint(fpPath, 'abc123')
|
|
297
|
+
|
|
298
|
+
// Verify it's inside dist folder
|
|
299
|
+
expect(fpPath).toBe(join(pkgDir, 'dist/.build-fingerprint'))
|
|
300
|
+
expect(existsSync(fpPath)).toBe(true)
|
|
301
|
+
|
|
302
|
+
// Verify old location is NOT used
|
|
303
|
+
const oldPath = join(tmpDir, '.proman/build/@test-pkg.fingerprint')
|
|
304
|
+
expect(existsSync(oldPath)).toBe(false)
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
test('T2: Test and check fingerprints still use .proman directory', () => {
|
|
308
|
+
// Test command fingerprint
|
|
309
|
+
const testFpPath = fingerprintPath(tmpDir, 'test')
|
|
310
|
+
expect(testFpPath).toBe(join(tmpDir, '.proman/test/root.fingerprint'))
|
|
311
|
+
|
|
312
|
+
// Check command fingerprint
|
|
313
|
+
const checkFpPath = fingerprintPath(tmpDir, 'check')
|
|
314
|
+
expect(checkFpPath).toBe(join(tmpDir, '.proman/check/root.fingerprint'))
|
|
315
|
+
})
|
|
316
|
+
})
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
packages: []
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"@test/a","version":"0.1.0"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|