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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"@cypress/request": "^3.0.1",
"strip-ansi": "^6.0.1",
"winston-transport": "^4.5.0",
"uuid": "^9.0.0"
"uuid": "^9.0.0",
"glob": "^7.2.0"
},
"devDependencies": {
"chai": "^4.3.7",
Expand Down
119 changes: 12 additions & 107 deletions src/utils/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const os = require('os');
const fs = require('fs');
const fsPromises = fs.promises;
const path = require('path');
const glob = require('glob');
const {promisify} = require('util');
const gitRepoInfo = require('git-repo-info');
const gitconfig = require('gitconfiglocal');
Expand Down Expand Up @@ -853,84 +854,7 @@ exports.truncateString = (field, truncateSizeInBytes) => {

// Helper function to check if a pattern contains glob characters
exports.isGlobPattern = (pattern) => {
return pattern.includes('*') || pattern.includes('?') || pattern.includes('[');
};

// Helper function to recursively find files matching a pattern
exports.findFilesRecursively = (dir, pattern) => {
const files = [];
try {
if (!fs.existsSync(dir)) {
return files;
}

const entries = fs.readdirSync(dir, {withFileTypes: true});

for (const entry of entries) {
const fullPath = path.join(dir, entry.name);

if (entry.isDirectory()) {
// Recursively search subdirectories
files.push(...exports.findFilesRecursively(fullPath, pattern));
} else if (entry.isFile()) {
const relativePath = path.relative(process.cwd(), fullPath);

// Enhanced pattern matching for glob patterns
if (exports.matchesGlobPattern(relativePath, pattern)) {
files.push(relativePath);
}
}
}
} catch (err) {
Logger.debug(`Error reading directory ${dir}: ${err.message}`);
}

return files;
};

// Helper function to match a file path against a glob pattern
exports.matchesGlobPattern = (filePath, pattern) => {
// Normalize paths to use forward slashes
const normalizedPath = filePath.replace(/\\/g, '/');
const normalizedPattern = pattern.replace(/\\/g, '/');

// Convert glob pattern to regex step by step
let regexPattern = normalizedPattern;

// First, handle ** patterns (must be done before single *)
// ** should match zero or more directories
regexPattern = regexPattern.replace(/\*\*/g, '§DOUBLESTAR§');

// Escape regex special characters except the placeholders
regexPattern = regexPattern.replace(/[.+^${}()|[\]\\]/g, '\\$&');

// Now handle single * and ? patterns
regexPattern = regexPattern.replace(/\*/g, '[^/]*'); // * matches anything except path separators
regexPattern = regexPattern.replace(/\?/g, '[^/]'); // ? matches single character except path separator

// Finally, replace ** placeholder with regex for any path (including zero directories)
regexPattern = regexPattern.replace(/§DOUBLESTAR§/g, '.*?');

// Special case: if pattern ends with /**/* we need to handle direct files in the base directory
// Convert patterns like "dir/**/*" to also match "dir/*"
if (normalizedPattern.includes('/**/')) {
const baseRegex = regexPattern;
const alternativeRegex = regexPattern.replace(/\/\.\*\?\//g, '/');
regexPattern = `(?:${baseRegex}|${alternativeRegex})`;
}

// Ensure pattern matches from start to end
regexPattern = '^' + regexPattern + '$';

try {
const regex = new RegExp(regexPattern);

return regex.test(normalizedPath);
} catch (err) {
Logger.debug(`Error in glob pattern matching: ${err.message}`);

return false;
}
return glob.hasMagic(pattern);
};

// Helper function to resolve and collect test files from a path/pattern
Expand Down Expand Up @@ -1004,36 +928,17 @@ exports.findTestFilesInDirectory = (dir) => {
exports.expandGlobPattern = (pattern) => {
Logger.debug(`Expanding glob pattern: ${pattern}`);

// Extract the base directory from the pattern
const parts = pattern.split(/[/\\]/);
let baseDir = '.';
let patternStart = 0;

// Find the first part that contains glob characters
for (let i = 0; i < parts.length; i++) {
if (exports.isGlobPattern(parts[i])) {
patternStart = i;
break;
}
if (i === 0 && parts[i] !== '.') {
baseDir = parts[i];
} else if (i > 0) {
baseDir = path.join(baseDir, parts[i]);
}
}

// If baseDir doesn't exist, try current directory
if (!fs.existsSync(baseDir)) {
Logger.debug(`Base directory ${baseDir} doesn't exist, using current directory`);
baseDir = '.';
try {
const files = glob.sync(pattern);

Logger.debug(`Found ${files.length} files matching pattern: ${pattern}`);

return files;
} catch (err) {
Logger.debug(`Error expanding glob pattern: ${err.message}`);

return [];
}

Logger.debug(`Base directory: ${baseDir}, Pattern: ${pattern}`);

const files = exports.findFilesRecursively(baseDir, pattern);
Logger.debug(`Found ${files.length} files matching pattern: ${pattern}`);

return files;
};

/**
Expand Down