-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReactScanner.js
170 lines (145 loc) · 5.65 KB
/
ReactScanner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
const fs = require('fs');
const path = require('path');
// === Configuration: Set parameters ===
const DESTINATION_DIRECTORY = path.resolve(
'C:/Users/md8w7/OneDrive University of Missouri/Desktop/ImportantFiles/Milestone4/src'
);
const MODULE_NAMES = ["repaymentPercentageOfRevenueAmount2", "KeyAmount2", "KeyAmount3"]; // Search phrases
const EXCLUDED_PHRASES = ['ReactScanner', 'ID_Replace_React', 'ID_Replace_React_Final']; // Excluded files
const SKIP_FOLDERS = ['node_modules', 'dist', 'build']; // List of folders to skip
// === New Configuration: Specific targets ===
const SPECIFIC = false; // Set this to true to enable specific file matching
const SPECIFIC_TARGET_FILES = ["example1.js", "example2.js"]; // List of specific files to search
// === Log file path inside the destination directory ===
const logFilePath = path.join(DESTINATION_DIRECTORY, 'ID_Scan_React.log');
// Store matches and tracking found phrases
const matches = [];
const foundPhrases = new Set(); // Track found phrases for summary
// Generate regex patterns for each search term (case-insensitive matching)
const generateRegexPatterns = (moduleNames) => {
return moduleNames.map((name) => new RegExp(name, 'i')); // Case-insensitive
};
// Initialize the log file by clearing old content
const initializeLogFile = () => {
try {
fs.writeFileSync(logFilePath, '', 'utf-8'); // Clear previous content
console.log(`Log file initialized: ${logFilePath}`);
} catch (error) {
console.error(`Failed to initialize log file: ${error.message}`);
process.exit(1);
}
};
// Helper function to log a match with details
const logMatch = (moduleName, file, lineNumber, lineContent) => {
const relativePath = path.relative(DESTINATION_DIRECTORY, file);
matches.push({
component: moduleName,
file: relativePath,
line: lineNumber,
content: lineContent.trim(),
});
foundPhrases.add(moduleName); // Track found phrase
};
// Helper function to exclude files based on excluded phrases
const isExcludedFile = (filename) => {
return EXCLUDED_PHRASES.some((phrase) =>
filename.toLowerCase().includes(phrase.toLowerCase())
);
};
// Helper function to skip certain folders
const shouldSkipFolder = (folderName) => {
return SKIP_FOLDERS.includes(folderName);
};
// Recursive function to walk through directories and search .js files
const walkDirectory = (dir, patterns) => {
const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stat = fs.statSync(fullPath);
if (stat.isDirectory()) {
if (shouldSkipFolder(file)) {
console.log(`Skipping folder: ${file}`);
continue; // Skip this folder
}
walkDirectory(fullPath, patterns); // Recursively search subdirectories
} else if (file.endsWith('.js') && !isExcludedFile(file)) {
try {
const content = fs.readFileSync(fullPath, 'utf-8');
const lines = content.split('\n');
// Search each line for each pattern
lines.forEach((line, index) => {
patterns.forEach((pattern, i) => {
if (pattern.test(line)) {
logMatch(MODULE_NAMES[i], fullPath, index + 1, line); // Log match details
}
});
});
} catch (error) {
console.error(`Could not read ${fullPath}: ${error.message}`);
}
}
}
};
// Function to scan specific files only
const scanSpecificFiles = (files, patterns) => {
files.forEach((specificFile) => {
const fullPath = path.join(DESTINATION_DIRECTORY, specificFile);
if (fs.existsSync(fullPath)) {
try {
const content = fs.readFileSync(fullPath, 'utf-8');
const lines = content.split('\n');
// Search each line for each pattern
lines.forEach((line, index) => {
patterns.forEach((pattern, i) => {
if (pattern.test(line)) {
logMatch(MODULE_NAMES[i], fullPath, index + 1, line); // Log match details
}
});
});
} catch (error) {
console.error(`Could not read ${fullPath}: ${error.message}`);
}
} else {
console.log(`File not found: ${specificFile}`);
}
});
};
// Main function to execute the search and log results
const findReactMatches = () => {
initializeLogFile(); // Clear previous content from the log file
const patterns = generateRegexPatterns(MODULE_NAMES); // Generate regex patterns
if (SPECIFIC) {
scanSpecificFiles(SPECIFIC_TARGET_FILES, patterns); // Scan specific files only
} else {
walkDirectory(DESTINATION_DIRECTORY, patterns); // Start the recursive search
}
// Prepare the brief summary on missing phrases
const notFoundPhrases = MODULE_NAMES.filter(
(name) => !foundPhrases.has(name)
);
const summaryHeader = `=== Summary of Matches ===\n\n`;
const missingPhrasesInfo = notFoundPhrases.length
? `The following phrases were not found: ${notFoundPhrases.join(', ')}.\n\n`
: 'All target phrases were found.\n\n';
// Prepare the tabulated results
const tableHeader =
`| # | Component/Phrase | File Path | Line | Content |\n` +
`|---|-----------------|-----------|------|---------|\n`;
const tableRows = matches
.map(
(match, index) =>
`| ${index + 1} | ${match.component} | ${match.file} | ${match.line} | ${match.content} |`
)
.join('\n');
const summaryContent =
matches.length > 0 ? tableHeader + tableRows : 'No matches found.\n';
// Write the full summary and results to the log file
fs.writeFileSync(
logFilePath,
summaryHeader + missingPhrasesInfo + summaryContent,
'utf-8'
);
console.log(`Search completed. Results are logged in: ${logFilePath}`);
};
// Execute the search
findReactMatches();