Skip to content

Commit

Permalink
fix(core): handle non-source files better (#35)
Browse files Browse the repository at this point in the history
* fix(core): handle non-source files better

* pr changes
  • Loading branch information
EladBezalel authored Sep 30, 2024
1 parent b40b9ad commit 45e8ca0
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 38 deletions.
64 changes: 55 additions & 9 deletions libs/core/src/assets.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('findNonSourceAffectedFiles', () => {

it('should return relevant files', () => {
const cwd = '/project';
const changedFilePath = '/project/src/file.ts';
const changedFilePaths = ['/project/src/file.ts'];
const excludeFolderPaths = ['node_modules', 'dist', '.git'];

(fastFindInFiles as jest.Mock).mockReturnValue([
Expand All @@ -26,14 +26,50 @@ describe('findNonSourceAffectedFiles', () => {

const result = findNonSourceAffectedFiles(
cwd,
changedFilePath,
changedFilePaths,
excludeFolderPaths
);

expect(result).toEqual([{ filePath: 'src/file.ts', changedLines: [1] }]);
expect(fastFindInFiles).toHaveBeenCalledWith({
directory: cwd,
needle: path.basename(changedFilePath),
needle: new RegExp(
changedFilePaths
.map((changedFilePath) => path.basename(changedFilePath))
.join('|')
.replaceAll('.', '\\.')
),
excludeFolderPaths: excludeFolderPaths.map((folder) =>
path.join(cwd, folder)
),
});
});

it('should aggregate changedFilePaths to regExp needle', () => {
const cwd = '/project';
const changedFilePaths = ['/project/src/file.ts', '/project/src/file2.ts'];
const excludeFolderPaths = ['node_modules', 'dist', '.git'];
(fastFindInFiles as jest.Mock).mockReturnValue([
{
filePath: '/project/src/file.ts',
queryHits: [{ lineNumber: 1, line: `"file.ts"` }],
},
]);
(existsSync as jest.Mock).mockReturnValue(true);
const result = findNonSourceAffectedFiles(
cwd,
changedFilePaths,
excludeFolderPaths
);
expect(result).toEqual([{ filePath: 'src/file.ts', changedLines: [1] }]);
expect(fastFindInFiles).toHaveBeenCalledWith({
directory: cwd,
needle: new RegExp(
changedFilePaths
.map((changedFilePath) => path.basename(changedFilePath))
.join('|')
.replaceAll('.', '\\.')
),
excludeFolderPaths: excludeFolderPaths.map((folder) =>
path.join(cwd, folder)
),
Expand All @@ -42,22 +78,27 @@ describe('findNonSourceAffectedFiles', () => {

it('should return empty array if no relevant files found', () => {
const cwd = '/project';
const changedFilePath = '/project/src/file.ts';
const changedFilePaths = ['/project/src/file.ts'];
const excludeFolderPaths = ['node_modules', 'dist', '.git'];

(fastFindInFiles as jest.Mock).mockReturnValue([]);
(existsSync as jest.Mock).mockReturnValue(true);

const result = findNonSourceAffectedFiles(
cwd,
changedFilePath,
changedFilePaths,
excludeFolderPaths
);

expect(result).toEqual([]);
expect(fastFindInFiles).toHaveBeenCalledWith({
directory: cwd,
needle: path.basename(changedFilePath),
needle: new RegExp(
changedFilePaths
.map((changedFilePath) => path.basename(changedFilePath))
.join('|')
.replaceAll('.', '\\.')
),
excludeFolderPaths: excludeFolderPaths.map((folder) =>
path.join(cwd, folder)
),
Expand All @@ -66,7 +107,7 @@ describe('findNonSourceAffectedFiles', () => {

it("should still work even if found file didn't have a match", () => {
const cwd = '/project';
const changedFilePath = '/project/src/file.ts';
const changedFilePaths = ['/project/src/file.ts'];
const excludeFolderPaths = ['node_modules', 'dist', '.git'];

(fastFindInFiles as jest.Mock).mockReturnValue([
Expand All @@ -79,14 +120,19 @@ describe('findNonSourceAffectedFiles', () => {

const result = findNonSourceAffectedFiles(
cwd,
changedFilePath,
changedFilePaths,
excludeFolderPaths
);

expect(result).toEqual([]);
expect(fastFindInFiles).toHaveBeenCalledWith({
directory: cwd,
needle: path.basename(changedFilePath),
needle: new RegExp(
changedFilePaths
.map((changedFilePath) => path.basename(changedFilePath))
.join('|')
.replaceAll('.', '\\.')
),
excludeFolderPaths: excludeFolderPaths.map((folder) =>
path.join(cwd, folder)
),
Expand Down
38 changes: 21 additions & 17 deletions libs/core/src/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,46 @@ import { existsSync } from 'fs';

export function findNonSourceAffectedFiles(
cwd: string,
changedFilePath: string,
changedFilePaths: string[],
excludeFolderPaths: (string | RegExp)[]
): ChangedFiles[] {
const fileName = basename(changedFilePath);
if (changedFilePaths.length === 0) return [];

const fileNames = changedFilePaths.map((path) => basename(path));

const files = fastFindInFiles({
directory: cwd,
needle: fileName,
needle: new RegExp(fileNames.join('|').replaceAll('.', '\\.')),
excludeFolderPaths: excludeFolderPaths.map((path) =>
typeof path === 'string' ? join(cwd, path) : path
),
});

const relevantFiles = filterRelevantFiles(cwd, files, changedFilePath);
const relevantFiles = filterRelevantFiles(cwd, files, changedFilePaths);

return relevantFiles;
}

function filterRelevantFiles(
cwd: string,
files: FastFindInFiles[],
changedFilePath: string
changedFilePaths: string[]
): ChangedFiles[] {
const fileName = basename(changedFilePath);
const regExp = new RegExp(`['"\`](?<relFilePath>.*${fileName})['"\`]`);
return changedFilePaths.flatMap((changedFilePath) => {
const fileName = basename(changedFilePath);
const regExp = new RegExp(`['"\`](?<relFilePath>.*${fileName})['"\`]`);

return files
.map(({ filePath: foundFilePath, queryHits }) => ({
filePath: relative(cwd, foundFilePath),
changedLines: queryHits
.filter(({ line }) =>
isRelevantLine(line, regExp, cwd, foundFilePath, changedFilePath)
)
.map(({ lineNumber }) => lineNumber),
}))
.filter(({ changedLines }) => changedLines.length > 0);
return files
.map(({ filePath: foundFilePath, queryHits }) => ({
filePath: relative(cwd, foundFilePath),
changedLines: queryHits
.filter(({ line }) =>
isRelevantLine(line, regExp, cwd, foundFilePath, changedFilePath)
)
.map(({ lineNumber }) => lineNumber),
}))
.filter(({ changedLines }) => changedLines.length > 0);
});
}

function isRelevantLine(
Expand Down
32 changes: 21 additions & 11 deletions libs/core/src/true-affected.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,37 @@ export const trueAffected = async ({
({ filePath }) => project.getSourceFile(resolve(cwd, filePath)) != null
);

const nonSourceChangedFiles = changedFiles
const nonSourceChangedFilesPaths = changedFiles
.filter(
({ filePath }) =>
!filePath.match(/.*\.(ts|js)x?$/g) &&
!filePath.endsWith(lockFileName) &&
project.getSourceFile(resolve(cwd, filePath)) == null
)
.flatMap(({ filePath: changedFilePath }) => {
logger.debug(
`Finding non-source affected files for ${chalk.bold(changedFilePath)}`
);
.map(({ filePath }) => filePath);

return findNonSourceAffectedFiles(cwd, changedFilePath, ignoredPaths);
});
let nonSourceChangedFiles: ChangedFiles[] = [];

if (nonSourceChangedFiles.length > 0) {
if (nonSourceChangedFilesPaths.length > 0) {
logger.debug(
`Found ${chalk.bold(
nonSourceChangedFiles.length
)} non-source affected files`
`Finding non-source affected files for ${chalk.bold(
nonSourceChangedFilesPaths.join(', ')
)}`
);

nonSourceChangedFiles = findNonSourceAffectedFiles(
cwd,
nonSourceChangedFilesPaths,
ignoredPaths
);

if (nonSourceChangedFiles.length > 0) {
logger.debug(
`Found ${chalk.bold(
nonSourceChangedFiles.length
)} non-source affected files`
);
}
}

let changedFilesByLockfile: ChangedFiles[] = [];
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"importHelpers": true,
"target": "es2015",
"module": "esnext",
"lib": ["es2020", "dom"],
"lib": ["es2023", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
Expand Down

0 comments on commit 45e8ca0

Please sign in to comment.