Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/scripts/__tests__/upgrade-deps.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/// <reference types="node" />

import { copyFileSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { dirname, join, resolve } from 'node:path';

import { expect, test, vi } from 'vitest';

test('upgrades lint-staged across major versions and includes it in upgrade metadata', async ({
onTestFinished,
}) => {
const root = resolve(import.meta.dirname, '../../..');
const tempDir = mkdtempSync(join(tmpdir(), 'vite-plus-upgrade-deps-'));
const metaDir = join(tempDir, 'meta');
onTestFinished(() => {
vi.restoreAllMocks();
vi.unstubAllGlobals();
vi.unstubAllEnvs();
vi.resetModules();
rmSync(tempDir, { recursive: true, force: true });
});

for (const file of [
'pnpm-workspace.yaml',
'packages/tools/.upstream-versions.json',
'packages/cli/src/utils/constants.ts',
]) {
mkdirSync(dirname(join(tempDir, file)), { recursive: true });
copyFileSync(join(root, file), join(tempDir, file));
}
const workspacePath = join(tempDir, 'pnpm-workspace.yaml');
writeFileSync(
workspacePath,
readFileSync(workspacePath, 'utf8').replace(/ lint-staged: .+/, ' lint-staged: ^16.2.6'),
);

vi.spyOn(process, 'cwd').mockReturnValue(tempDir);
vi.spyOn(console, 'log').mockImplementation(() => {});
vi.stubEnv('UPGRADE_DEPS_META_DIR', metaDir);
vi.stubGlobal('fetch', async (url: string) => {
if (url.startsWith('https://api.github.com/repos/')) {
return Response.json([{ name: 'v1.2.3', commit: { sha: 'a'.repeat(40) } }]);
}
if (url === 'https://registry.npmjs.org/vitest') {
return Response.json({ versions: { '4.1.11': {}, '5.0.0': {} } });
}
if (url === 'https://registry.npmjs.org/@tsdown/css/latest') {
return Response.json({ dependencies: { lightningcss: '^1.33.0' } });
}
if (url === 'https://registry.npmjs.org/lint-staged/latest') {
return Response.json({ version: '17.5.1' });
}
if (url.startsWith('https://registry.npmjs.org/') && url.endsWith('/latest')) {
return Response.json({ version: '1.2.3' });
}
throw new Error(`Unexpected request: ${url}`);
});

vi.resetModules();
await import('../upgrade-deps.ts');

expect(readFileSync(workspacePath, 'utf8')).toContain('\n lint-staged: ^17.5.1\n');
const versions = JSON.parse(readFileSync(join(metaDir, 'versions.json'), 'utf8'));
expect(versions['lint-staged']).toEqual({ old: '16.2.6', new: '17.5.1' });
expect(readFileSync(join(metaDir, 'commit-message.txt'), 'utf8')).toContain(
'- lint-staged: 16.2.6 -> 17.5.1',
);
expect(readFileSync(join(metaDir, 'pr-body.md'), 'utf8')).toContain(
'| `lint-staged` | `16.2.6` | `17.5.1` |',
);
});
11 changes: 11 additions & 0 deletions .github/scripts/upgrade-deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type PnpmWorkspaceVersions = {
vitest: string;
tsdown: string;
lightningcss: string;
lintStaged: string;
oxcNodeCli: string;
oxcNodeCore: string;
oxfmt: string;
Expand Down Expand Up @@ -278,6 +279,12 @@ async function updatePnpmWorkspace(versions: PnpmWorkspaceVersions): Promise<voi
replacement: `\n lightningcss: ${versions.lightningcss}\n`,
newVersion: versions.lightningcss,
},
{
name: 'lint-staged',
pattern: /\n {2}lint-staged: \^([\d.]+(?:-[\w.]+)?)\n/,
replacement: `\n lint-staged: ^${versions.lintStaged}\n`,
newVersion: versions.lintStaged,
},
{
name: '@oxc-node/cli',
pattern: /'@oxc-node\/cli': \^([\d.]+(?:-[\w.]+)?)/,
Expand Down Expand Up @@ -524,6 +531,7 @@ const [
vitestVersion,
tsdownVersion,
lightningcssVersion,
lintStagedVersion,
oxcNodeCliVersion,
oxcNodeCoreVersion,
oxfmtVersion,
Expand All @@ -539,6 +547,7 @@ const [
getLatestNpmVersion('tsdown'),
// Mirror exactly what the bundled @tsdown/css depends on.
getNpmDependencyRange('@tsdown/css', 'lightningcss'),
getLatestNpmVersion('lint-staged'),
getLatestNpmVersion('@oxc-node/cli'),
getLatestNpmVersion('@oxc-node/core'),
getLatestNpmVersion('oxfmt'),
Expand All @@ -554,6 +563,7 @@ const [
console.log(`vitest: ${vitestVersion}`);
console.log(`tsdown: ${tsdownVersion}`);
console.log(`lightningcss (from @tsdown/css): ${lightningcssVersion}`);
console.log(`lint-staged: ${lintStagedVersion}`);
console.log(`@oxc-node/cli: ${oxcNodeCliVersion}`);
console.log(`@oxc-node/core: ${oxcNodeCoreVersion}`);
console.log(`oxfmt: ${oxfmtVersion}`);
Expand All @@ -570,6 +580,7 @@ await updatePnpmWorkspace({
vitest: vitestVersion,
tsdown: tsdownVersion,
lightningcss: lightningcssVersion,
lintStaged: lintStagedVersion,
oxcNodeCli: oxcNodeCliVersion,
oxcNodeCore: oxcNodeCoreVersion,
oxfmt: oxfmtVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@
--no-concurrent runs staged tasks and does not stall

```
✔ Backed up original state in git stash (<hash>)
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
⋯ Backing up original state…
✔ Done backing up original state (<hash>)!
⋯ Running tasks for staged files…
*.txt — 1 file
⋯ vpt print linted

✔ vpt print linted

✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✔ Done staging changes from tasks!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!

→ vpt print linted:
linted <workspace>/a.txt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
process.exit(1);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
original
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "command-staged-no-stash-restore",
"private": true,
"type": "module"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[[case]]
name = "command_staged_no_stash_restore"
vp = ["local", "global"]
comment = "A failed task with --no-stash must restore the unstaged part of a partially staged file."
steps = [
{ argv = ["git", "init"], snapshot = false },
{ argv = ["git", "add", "-A"], snapshot = false },
{ argv = ["git", "-c", "user.name=Vite Plus", "-c", "user.email=vite-plus@example.com", "commit", "-m", "init"], snapshot = false },
{ argv = ["vpt", "write-file", "file.txt", "staged\n"], snapshot = false },
{ argv = ["git", "add", "file.txt"], snapshot = false },
{ argv = ["vpt", "write-file", "file.txt", "staged\nunstaged\n"], snapshot = false },
{ argv = ["vp", "staged", "--no-stash", "--quiet"], continue-on-failure = true },
{ argv = ["vpt", "print-file", "file.txt"], comment = "The working tree retains both staged and unstaged changes.", continue-on-failure = true },
{ argv = ["git", "show", ":file.txt"], comment = "The index retains only the staged change." },
{ argv = ["git", "stash", "list"], comment = "No backup stash is created." },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# command_staged_no_stash_restore

A failed task with --no-stash must restore the unstaged part of a partially staged file.

## `git init`


## `git add -A`


## `git -c 'user.name=Vite Plus' -c user.email=vite-plus@example.com commit -m init`


## `vpt write-file file.txt 'staged
'`


## `git add file.txt`


## `vpt write-file file.txt 'staged
unstaged
'`


## `vp staged --no-stash --quiet`

**Exit code:** 1

```
✖ node fail.cjs
```

## `vpt print-file file.txt`

The working tree retains both staged and unstaged changes.

```
staged
unstaged
```

## `git show :file.txt`

The index retains only the staged change.

```
staged
```

## `git stash list`

No backup stash is created.

```
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# command_staged_no_stash_restore

A failed task with --no-stash must restore the unstaged part of a partially staged file.

## `git init`


## `git add -A`


## `git -c 'user.name=Vite Plus' -c user.email=vite-plus@example.com commit -m init`


## `vpt write-file file.txt 'staged
'`


## `git add file.txt`


## `vpt write-file file.txt 'staged
unstaged
'`


## `vp staged --no-stash --quiet`

**Exit code:** 1

```
✖ node fail.cjs
```

## `vpt print-file file.txt`

The working tree retains both staged and unstaged changes.

```
staged
unstaged
```

## `git show :file.txt`

The index retains only the staged change.

```
staged
```

## `git stash list`

No backup stash is created.

```
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default {
staged: {
'*.txt': 'node fail.cjs',
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ append foo (write-file with the full appended content)
should succeed with staged .ts files

```
✔ Backed up original state in git stash (<hash>)
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
⋯ Backing up original state…
✔ Done backing up original state (<hash>)!
⋯ Running tasks for staged files…
*.ts — 1 file
⋯ vp check --fix

✔ vp check --fix

✔ Done running tasks for staged files!
⋯ Staging changes from tasks…
✔ Done staging changes from tasks!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!
```

## `git add -A`
Expand Down Expand Up @@ -72,15 +81,20 @@ should fail when staged .js file has lint errors
**Exit code:** 1

```
✔ Backed up original state in git stash (<hash>)
⚠ Running tasks for staged files...
❯ Config object — 1 file
↓ *.ts — no files
❯ *.js — 1 file
✖ vp lint [FAILED]
↓ Skipped because of errors from tasks.
✔ Reverting to original state because of errors...
✔ Cleaning up temporary files...
⋯ Backing up original state…
✔ Done backing up original state (<hash>)!
⋯ Running tasks for staged files…
*.js — 1 file
⋯ vp lint

✖ vp lint

✖ Failed to run tasks for staged files!
↓ Skipped staging changes from tasks…
⋯ Reverting to original state because of errors…
✔ Done reverting to original state!
⋯ Cleaning up temporary files…
✔ Done cleaning up temporary files!

✖ vp lint:

Expand Down
5 changes: 3 additions & 2 deletions crates/vp_cli_snapshots/tests/cli_snapshots/redact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,9 @@ static YARN_TELEMETRY_RE: LazyLock<regex::Regex> =
LazyLock::new(|| regex::Regex::new(r"(?m)^\u{27A4} YN0065: [^\n]*\n(?:[ \t]*\n)*").unwrap());
// `vp staged` reports the backup stash it created; the short hash covers a
// commit of the working tree at run time, so it can never be stable.
static STASH_HASH_RE: LazyLock<regex::Regex> =
LazyLock::new(|| regex::Regex::new(r"(git stash \()[0-9a-f]+(\))").unwrap());
static STASH_HASH_RE: LazyLock<regex::Regex> = LazyLock::new(|| {
regex::Regex::new(r"((?:git stash|Done backing up original state) \()[0-9a-f]+(\))").unwrap()
});
// Package managers emit blank separator lines whose count races their own
// progress rendering under a PTY; collapse runs so spacing is stable.
static BLANK_RUN_RE: LazyLock<regex::Regex> =
Expand Down
18 changes: 18 additions & 0 deletions crates/vp_cli_snapshots/tests/redact_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,24 @@ fn masks_bun_build_hash_only_in_bun_banners() {
assert_eq!(redact_output(unrelated.clone(), &[], true), unrelated);
}

#[test]
fn masks_lint_staged_backup_hashes() {
let input = concat!(
"✔ Backed up original state in git stash (a1b2c3d)\n",
"✔ Done backing up original state (d4e5f6a)!\n",
"commit (deadbeef1) applied\n",
)
.to_owned();
assert_eq!(
redact_output(input, &[], true),
concat!(
"✔ Backed up original state in git stash (<hash>)\n",
"✔ Done backing up original state (<hash>)!\n",
"commit (deadbeef1) applied\n",
)
);
}

#[test]
fn normalizes_managed_executable_paths_and_missing_commands() {
let input = concat!(
Expand Down
Loading
Loading