Automatic output tracking misses files a task renames into place, so a cache hit restores nothing
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 48/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Stack technique
- node.js, rust
- Domaine
- build-system, tooling
Piste de recherche
Start with crates/fspy_preload_unix/src/interceptions/mod.rs to see how filesystem calls are intercepted, then read crates/vt/src/session/cache/archive.rs to understand how recorded outputs are archived. The issue calls out Linux rename, renameat, and renameat2, plus macOS rename and renameat; done means those renames record the destination so a cache hit restores the renamed file or folder contents.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Written by an AI agent (Claude) on behalf of @jasonkuhrt.
Problem
With automatic output tracking, the default when cache.output is omitted or holds { auto: true }, a task that writes its output somewhere else and then renames it into place gets a cache entry without that output. A cache hit then restores nothing.
Writing to a temporary path and renaming is the standard way to replace a file or a folder atomically. TanStack Router's generator writes its route tree this way: a temp file, then rename (safeFileWrite, router-generator/src/generator.ts L1203-L1277). Our own code generators stage a whole folder and rename it over the old one.
Reproduction on vite-plus 1.4.0, with no remote cache:
// vite.config.ts
import { defineConfig } from 'vite-plus';
export default defineConfig({
run: {
tasks: {
generate: {
command: 'node generate.mjs',
cache: { input: ['generate.mjs'] },
},
},
},
});
// generate.mjs: stages the output, then renames it into place
import { mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
rmSync('.staging', { recursive: true, force: true });
mkdirSync('.staging');
writeFileSync('.staging/a.ts', 'export const a = 1;\n');
rmSync('generated', { recursive: true, force: true });
renameSync('.staging', 'generated');
$ vp run generate
$ node generate.mjs
$ ls generated
a.ts
$ rm -rf generated
$ vp run generate
vp run: cache hit, 39ms saved.
$ ls generated
ls: generated: No such file or directory # the hit restored nothing
Replacing the renameSync line with a direct writeFileSync('generated/a.ts', …) makes the same hit restore generated/a.ts.
Cause
fspy records the write to .staging/a.ts. It has no rename interception (fspy_preload_unix/src/interceptions/mod.rs covers access, dirent, open, spawn and stat), so generated/a.ts is never recorded. When outputs are archived, the recorded .staging/a.ts no longer exists and is skipped (archive.rs L29-L34), which leaves the entry empty.
The workaround today is a positive cache.output glob for the destination. But a glob archives whatever matches on disk, including files a previous run left there, so it gives up what automatic tracking gets right.
Proposal: cover the common case, leave the long tail to explicit config
Record a rename's destination as a write:
- A file renamed to
dst:dstis written. - A folder renamed to
dst: every file underdstis written. These can be collected by walkingdstwhen outputs are archived, instead of tracking each file inside.
Covering rename, renameat and renameat2 on Linux and rename and renameat on macOS should catch nearly every atomic-write tool, since that is how Node's fs.rename and most tools' atomic writers move files.
Deliberately out of scope, where users keep declaring cache.output:
RENAME_EXCHANGE;- moving files into place with
link; - platforms or syscalls the interception layer doesn't reach yet.
Cross-filesystem moves need nothing, since they copy and so are already recorded as writes.
Related: #904 covers the cache-hit side, where a hit leaves behind files the cached run did not write.
- Langage dominant
- Rust
- Étoiles
- 480
- Forks
- 50
- Merge moyen
- 1 j 5 h
- PR mergées (30 j)
- 63
Préparer son environnement
Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de voidzero-dev/vite-task
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
voidzero-dev/vite-task#921 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 56/100
voidzero-dev/vite-task#910 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Export OpenTelemetry client spans for the native remote cachePeut-être pris @jasonkuhrt l’a pris aujourd’hui. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 25/100
voidzero-dev/vite-task#906 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 56/100
voidzero-dev/vite-task#905 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 55/100
voidzero-dev/vite-task#904 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de voidzero-dev/vite-task
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
Les mainteneurs répondent en général sous 1 jour
-
compiler P4 perf
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
HerringtonDarkholme/hd-lang#1044 ·
Les mainteneurs répondent en général sous 1 jour
-
good first issue help wanted r-docs
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
servo/rust-smallvec#824 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 90/100
akitaonrails/ai-usagebar#552 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100