mirror of
https://github.com/AventurasTeam/Aventuras.git
synced 2026-11-13 17:55:55 +00:00
## Summary - Adds `scripts/package-manager.js`, which detects whether `aube` or `npm` owns the current `node_modules` (by checking for `node_modules/.aube-state`, then confirming `aube` is still on `PATH`) and builds the right `[cmd, args]` pair for `spawnSync`/`execFileSync`, including the Windows `npm.cmd` workaround. - Adds `scripts/pm.js`, a thin CLI (`node scripts/pm.js <args...>`) that runs that detected package manager with the given arguments and forwards its exit status. - Routes `lefthook.yml`'s `pre-push` `lint`/`check` commands and `tauri.conf.json`'s `beforeDevCommand`/`beforeBuildCommand` through `scripts/pm.js`, so they use aube wherever aube did the install and npm otherwise. - `scripts/release.js` keeps the version bump on npm (npm owns `package-lock.json`), but now runs its `format`/`lint:fix` steps through the detected package manager. When that manager is aube, it adds `--no-install --frozen-lockfile` so aube doesn't re-resolve the lockfile npm just rewrote. - Documents the new detection/routing behavior in `docs/development/release.md`. ## Test plan - [ ] `npm test` / `aube test` passes, including the new `scripts/package-manager.test.js` coverage for `detectPackageManager` and `commandFor` on both platforms. - [ ] `npm run lint` / `aubr lint` and `npm run check` / `aubr check` pass. - [ ] Manually verify `npx tauri dev` still launches correctly on a checkout with only npm installed, and on one where aube performed the install. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01YHkuCEJRUTBnsZaUnhfR9N <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Development, build, pre-push checks, and release tasks now use the package manager detected for the project, supporting both npm and Aube. * Command execution accounts for platform differences, including Windows, and the existing lint memory limit is preserved. * These changes apply to development and release workflows; they do not change application features or behavior for end users. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
81 lines
2.6 KiB
JavaScript
81 lines
2.6 KiB
JavaScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import fs from 'fs'
|
|
import os from 'os'
|
|
import path from 'path'
|
|
import { spawnSync } from 'child_process'
|
|
import { commandFor, detectPackageManager } from './package-manager.js'
|
|
|
|
vi.mock('child_process', async (importOriginal) => ({
|
|
...(await importOriginal()),
|
|
spawnSync: vi.fn(),
|
|
}))
|
|
|
|
describe('commandFor', () => {
|
|
it.each([
|
|
['npm', 'win32', ['cmd.exe', ['/c', 'npm', 'run', 'lint']]],
|
|
['npm', 'linux', ['npm', ['run', 'lint']]],
|
|
['aube', 'win32', ['cmd.exe', ['/c', 'aube', 'run', 'lint']]],
|
|
['aube', 'linux', ['aube', ['run', 'lint']]],
|
|
])('builds the command for %s on %s', (pm, platform, expected) => {
|
|
expect(commandFor(pm, ['run', 'lint'], platform)).toEqual(expected)
|
|
})
|
|
|
|
it.each([
|
|
['win32', ['cmd.exe', ['/c', 'npm', 'run', 'lint']]],
|
|
['linux', ['npm', ['run', 'lint']]],
|
|
])('defaults the platform to process.platform (%s)', (platform, expected) => {
|
|
const original = Object.getOwnPropertyDescriptor(process, 'platform')
|
|
Object.defineProperty(process, 'platform', { value: platform, configurable: true })
|
|
try {
|
|
expect(commandFor('npm', ['run', 'lint'])).toEqual(expected)
|
|
} finally {
|
|
Object.defineProperty(process, 'platform', original)
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('detectPackageManager', () => {
|
|
beforeEach(() => {
|
|
vi.mocked(spawnSync).mockReset()
|
|
})
|
|
|
|
function withRootDir(hasAubeState, fn) {
|
|
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pm-test-'))
|
|
try {
|
|
if (hasAubeState)
|
|
fs.mkdirSync(path.join(rootDir, 'node_modules', '.aube-state'), { recursive: true })
|
|
fn(rootDir)
|
|
} finally {
|
|
fs.rmSync(rootDir, { recursive: true, force: true })
|
|
}
|
|
}
|
|
|
|
it('picks npm when the install marker is absent, without probing aube', () => {
|
|
withRootDir(false, (rootDir) => {
|
|
expect(detectPackageManager(rootDir)).toBe('npm')
|
|
expect(spawnSync).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
it.each([
|
|
['aube', { status: 0 }],
|
|
['npm', { error: new Error('ENOENT') }],
|
|
['npm', { status: 1 }],
|
|
])('picks %s when the marker is present and the probe returns %o', (expected, probeResult) => {
|
|
vi.mocked(spawnSync).mockReturnValue(probeResult)
|
|
withRootDir(true, (rootDir) => {
|
|
expect(detectPackageManager(rootDir)).toBe(expected)
|
|
})
|
|
})
|
|
|
|
it('probes aube through commandFor', () => {
|
|
vi.mocked(spawnSync).mockReturnValue({ status: 0 })
|
|
withRootDir(true, (rootDir) => {
|
|
detectPackageManager(rootDir)
|
|
expect(spawnSync).toHaveBeenCalledWith(
|
|
...commandFor('aube', ['--version']),
|
|
expect.anything(),
|
|
)
|
|
})
|
|
})
|
|
})
|