Skip to content
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { join } from 'node:path';
import { join } from 'pathe';

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

Expand Down Expand Up @@ -637,17 +637,20 @@ describe('ChangeDetectionService', () => {
});

it('stores changed files as normalized repo-relative paths', async () => {
const buttonCss = createModuleNode(join(workingDir, 'src', 'Button.module.css'));
const buttonComponent = createModuleNode(join(workingDir, 'src', 'Button.tsx'));
const buttonStory = createModuleNode(join(workingDir, 'src', 'Button.stories.tsx'));
const buttonCssPath = join(workingDir, 'src', 'Button.module.css');
const buttonComponentPath = join(workingDir, 'src', 'Button.tsx');
const buttonStoryPath = join(workingDir, 'src', 'Button.stories.tsx');
const buttonCss = createModuleNode(buttonCssPath);
const buttonComponent = createModuleNode(buttonComponentPath);
const buttonStory = createModuleNode(buttonStoryPath);

buttonCss.importers.add(buttonComponent);
buttonComponent.importers.add(buttonStory);

const moduleGraph: ModuleGraph = new Map([
[join(workingDir, 'src', 'Button.module.css'), new Set([buttonCss])],
[join(workingDir, 'src', 'Button.tsx'), new Set([buttonComponent])],
[join(workingDir, 'src', 'Button.stories.tsx'), new Set([buttonStory])],
[buttonCssPath, new Set([buttonCss])],
[buttonComponentPath, new Set([buttonComponent])],
[buttonStoryPath, new Set([buttonStory])],
]);
const storyIndex = createStoryIndex([
{ storyId: 'button--primary', importPath: './src/Button.stories.tsx', title: 'Button' },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { relative, resolve } from 'node:path';
import { join, relative } from 'pathe';

import { logger } from 'storybook/internal/node-logger';
import type {
Expand Down Expand Up @@ -41,23 +41,14 @@ function getStoryIdsByAbsolutePath(
workingDir: string
): Map<string, Set<string>> {
const storyIdsByFile = new Map<string, Set<string>>();
const addStoryId = (filePath: string, storyId: string) => {
const storyIds = storyIdsByFile.get(filePath) ?? new Set<string>();
storyIds.add(storyId);
storyIdsByFile.set(filePath, storyIds);
};

Object.values(storyIndex.entries).forEach((entry) => {
if (entry.type !== 'story' || entry.importPath.startsWith('virtual:')) {
return;
if (entry.type === 'story' && !entry.importPath.startsWith('virtual:')) {
const filePath = join(workingDir, entry.importPath);
const storyIds = storyIdsByFile.get(filePath) ?? new Set<string>();
storyIds.add(entry.id);
storyIdsByFile.set(filePath, storyIds);
}

const absolutePath = resolve(workingDir, entry.importPath);
const normalizedAbsolutePath = normalizePath(absolutePath);
addStoryId(absolutePath, entry.id);
addStoryId(normalizedAbsolutePath, entry.id);
});

return storyIdsByFile;
}

Expand All @@ -80,11 +71,6 @@ function mergeStatusValues(
return nextValue;
}

function toRepoRelativePath(repoRoot: string, filePath: string): string {
const relativePath = relative(repoRoot, filePath);
return relativePath.startsWith('\\\\?\\') ? relativePath : relativePath.replace(/\\/g, '/');
}

/**
* Coordinates change detection by listening to builder module-graph updates, resolving changed
* files from git, mapping those changes to affected stories, and publishing the resulting story
Expand Down Expand Up @@ -255,12 +241,8 @@ export class ChangeDetectionService {
this.options.storyIndexGeneratorPromise,
]);

const changedFiles = new Set(
Array.from(changes.changed).map((filePath) => normalizePath(resolve(repoRoot, filePath)))
);
const newFiles = new Set(
Array.from(changes.new).map((filePath) => normalizePath(resolve(repoRoot, filePath)))
);
const changedFiles = new Set(Array.from(changes.changed).map((path) => join(repoRoot, path)));
const newFiles = new Set(Array.from(changes.new).map((path) => join(repoRoot, path)));
const scannedFiles = new Set([...changedFiles, ...newFiles]);
const normalizedModuleGraph = new Map<string, Set<ModuleNode>>();
moduleGraph.forEach((nodes, filePath) => {
Expand Down Expand Up @@ -302,7 +284,7 @@ export class ChangeDetectionService {
storyIds.forEach((storyId) => {
const existingStatus = statuses.get(storyId);
const changedStoryFiles = new Set<string>(existingStatus?.data?.changedFiles ?? []);
changedStoryFiles.add(toRepoRelativePath(repoRoot, changedFile));
changedStoryFiles.add(relative(repoRoot, changedFile));

statuses.set(storyId, {
storyId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { watch, type FSWatcher } from 'node:fs';
import { readFile, stat } from 'node:fs/promises';
import { dirname, join, resolve as resolvePath } from 'node:path';
import { dirname, join, resolve as resolvePath } from 'pathe';

// eslint-disable-next-line depend/ban-dependencies
import { execa, type ExecaError } from 'execa';
Expand Down
Loading