Skip to content

Commit 31608ec

Browse files
committed
Remove unused functions in fileUtils, move things around, use fs/promises more, and other refactors
1 parent 62f49d0 commit 31608ec

File tree

5 files changed

+43
-126
lines changed

5 files changed

+43
-126
lines changed
Lines changed: 16 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,8 @@
11
'use strict';
22

3-
import * as fs from 'fs';
4-
import { rename } from 'fs/promises';
3+
import { readFile, writeFile } from 'fs/promises';
54
import * as path from 'path';
65
import { logger } from '../logger';
7-
import { ncpAsync } from '../utilities';
8-
import { updateFileContents } from './pathUtils';
9-
10-
/**
11-
* A copy files wrapper function that also returns all copied files. Can throw exceptions.
12-
*/
13-
export async function copyAndReturnFiles(
14-
sourceFolder: string,
15-
destinationFolder: string,
16-
filter?: (sourcePath: string) => boolean
17-
): Promise<string[]> {
18-
const copiedFiles: string[] = [];
19-
await ncpAsync(sourceFolder, destinationFolder, {
20-
filter: (filePath: string): boolean => {
21-
// Apply custom filter if provided
22-
if (filter) {
23-
// Track copied files if requested
24-
if (filter(filePath) && fs.lstatSync(filePath).isFile()) {
25-
copiedFiles.push(path.relative(sourceFolder, filePath));
26-
}
27-
return filter(filePath);
28-
}
29-
if (fs.lstatSync(filePath).isFile()) {
30-
copiedFiles.push(path.relative(sourceFolder, filePath));
31-
}
32-
33-
return true;
34-
},
35-
});
36-
37-
return copiedFiles;
38-
}
396

407
export async function processFile(
418
file: string,
@@ -52,54 +19,22 @@ export async function processFile(
5219
}
5320

5421
/**
55-
* Rename files based on pattern replacement
22+
* Safely updates file contents by reading and writing atomically
5623
*/
57-
export async function renameFiles(
58-
files: string[],
59-
basePath: string,
60-
pattern: string | RegExp,
61-
replacement: string
62-
): Promise<string[]> {
63-
const renamePromises: Promise<string>[] = [];
64-
const regex = typeof pattern === 'string' ? new RegExp(pattern, 'g') : pattern;
65-
66-
for (const filePath of files) {
67-
const fullPath = path.join(basePath, filePath);
68-
const filename = path.basename(fullPath);
69-
70-
// Only rename files matching the pattern
71-
if (filename.match(regex)) {
72-
const directory = path.dirname(fullPath);
73-
const newName = filename.replace(regex, replacement);
74-
const newPath = path.join(directory, newName);
75-
76-
renamePromises.push(
77-
(async () => {
78-
await rename(fullPath, newPath);
79-
return newPath;
80-
})()
81-
);
82-
}
83-
}
84-
24+
export async function updateFileContents(
25+
filePath: string,
26+
replacer: (content: string) => string
27+
): Promise<boolean> {
8528
try {
86-
return await Promise.all(renamePromises);
87-
} catch (error) {
88-
logger.error('Error renaming files:', error);
89-
throw error;
90-
}
91-
}
92-
93-
/**
94-
* Create a filter function that takes in a path to a file and checks if the file names matches a list of file names
95-
*/
96-
export function createFileNameFilter(fileNames: string[]) {
97-
return (sourcePath: string): boolean => {
98-
if (!fs.lstatSync(sourcePath).isFile()) {
99-
return true; // Always include directories
29+
const fileContent = await readFile(filePath, 'utf8');
30+
const updatedContent = replacer(fileContent);
31+
if (fileContent !== updatedContent) {
32+
await writeFile(filePath, updatedContent, 'utf8');
33+
return true;
10034
}
101-
102-
const basename = path.basename(sourcePath);
103-
return fileNames.includes(basename);
104-
};
35+
return false;
36+
} catch (err) {
37+
logger.error('Failed to update file contents', err);
38+
return false;
39+
}
10540
}

vscode-wpilib/src/shared/generator.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import * as path from 'path';
44
import { logger } from '../logger';
5+
import { ncpAsync } from '../utilities';
6+
import * as fileUtils from './fileUtils';
57
import * as pathUtils from './pathUtils';
68
import * as genUtils from './projectGeneratorUtils';
7-
import { ncpAsync } from '../utilities';
8-
import { processFile } from './fileUtils';
99

1010
export async function generateCopyCpp(
1111
resourcesFolder: string,
@@ -105,19 +105,23 @@ export async function generateCopyJava(
105105
}
106106

107107
// Process template files
108-
await Promise.all(files.map((testFile) => processFile(testFile, codePath, replacements)));
108+
await Promise.all(
109+
files.map((testFile) => fileUtils.processFile(testFile, codePath, replacements))
110+
);
109111

110112
// Process test files if they exist
111113
if (fromTemplateTestFolder !== undefined) {
112114
const testFiles = await genUtils.findMatchingFiles(testPath);
113-
await Promise.all(testFiles.map((testFile) => processFile(testFile, testPath, replacements)));
115+
await Promise.all(
116+
testFiles.map((testFile) => fileUtils.processFile(testFile, testPath, replacements))
117+
);
114118
}
115119

116120
// Setup project structure
117121
await genUtils.setupProjectStructure(fromGradleFolder, toFolder, grRoot);
118122

119123
// Update gradle file with correct version and robot class
120-
await pathUtils.updateFileContents(path.join(toFolder, 'build.gradle'), (content) =>
124+
await fileUtils.updateFileContents(path.join(toFolder, 'build.gradle'), (content) =>
121125
content
122126
.replace(new RegExp(genUtils.ReplacementPatterns.ROBOT_CLASS_MARKER, 'g'), robotClassTo)
123127
.replace(new RegExp(genUtils.ReplacementPatterns.GRADLE_RIO_MARKER, 'g'), gradleRioVersion)
@@ -137,7 +141,7 @@ export async function generateCopyJava(
137141
}
138142

139143
export async function setDesktopEnabled(buildgradle: string, setting: boolean): Promise<void> {
140-
await pathUtils.updateFileContents(buildgradle, (content) =>
144+
await fileUtils.updateFileContents(buildgradle, (content) =>
141145
content.replace(
142146
/def\s+includeDesktopSupport\s*=\s*(true|false)/gm,
143147
`def includeDesktopSupport = ${setting ? 'true' : 'false'}`

vscode-wpilib/src/shared/importupdater.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as jsonc from 'jsonc-parser';
44
import path from 'path';
55
import { logger } from '../logger';
66
import { readFileAsync } from '../utilities';
7-
import { updateFileContents } from './pathUtils';
7+
import { updateFileContents } from './fileUtils';
88
import glob = require('glob');
99

1010
interface IReplaceGroup {

vscode-wpilib/src/shared/pathUtils.ts

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
'use strict';
22

3-
import { readdir } from 'fs/promises';
3+
import { cp, readdir } from 'fs/promises';
44
import * as path from 'path';
55
import { logger } from '../logger';
6-
import { copyFileAsync, readFileAsync, writeFileAsync } from '../utilities';
76

87
/**
98
* Creates source and test paths based on project type and import mode
@@ -37,27 +36,6 @@ export function getProjectPaths(
3736
return { codePath, testPath };
3837
}
3938

40-
/**
41-
* Safely updates file contents by reading and writing atomically
42-
*/
43-
export async function updateFileContents(
44-
filePath: string,
45-
replacer: (content: string) => string
46-
): Promise<boolean> {
47-
try {
48-
const fileContent = await readFileAsync(filePath, 'utf8');
49-
const updatedContent = replacer(fileContent);
50-
if (fileContent !== updatedContent) {
51-
await writeFileAsync(filePath, updatedContent, 'utf8');
52-
return true;
53-
}
54-
return false;
55-
} catch (err) {
56-
logger.error('Failed to update file contents', err);
57-
return false;
58-
}
59-
}
60-
6139
/**
6240
* Copies a vendordep file to the project
6341
*/
@@ -69,7 +47,7 @@ export async function copyVendorDep(
6947
try {
7048
const sourcePath = path.join(path.dirname(resourcesFolder), 'vendordeps', vendorDepName);
7149
const targetPath = path.join(targetDir, vendorDepName);
72-
await copyFileAsync(sourcePath, targetPath);
50+
await cp(sourcePath, targetPath);
7351
return true;
7452
} catch (err) {
7553
logger.error(`Failed to copy vendor dependency: ${vendorDepName}`, err);

vscode-wpilib/src/shared/projectGeneratorUtils.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
'use strict';
22

3+
import { cp, mkdir, readFile, writeFile } from 'fs/promises';
34
import * as path from 'path';
4-
import glob = require('glob');
55
import { localize as i18n } from '../locale';
66
import { logger } from '../logger';
7-
import { mkdirpAsync, ncpAsync, readFileAsync, writeFileAsync } from '../utilities';
8-
import { setExecutePermissions } from './permissions';
7+
import * as fileUtils from './fileUtils';
98
import * as pathUtils from './pathUtils';
9+
import { setExecutePermissions } from './permissions';
10+
import glob = require('glob');
1011

1112
/**
1213
* Common patterns used in text replacements
@@ -29,7 +30,7 @@ export const VendorDepFiles = {
2930
/**
3031
* Filter function for excluding files from gradle copy operations
3132
*/
32-
export function gradleCopyFilter(sourcePath: string, fromGradleFolder: string): boolean {
33+
function gradleCopyFilter(sourcePath: string, fromGradleFolder: string): boolean {
3334
const rooted = path.relative(fromGradleFolder, sourcePath);
3435
if (rooted.startsWith('bin') || rooted.indexOf('.project') >= 0) {
3536
return false;
@@ -73,13 +74,15 @@ export async function setupProjectStructure(
7374
): Promise<boolean> {
7475
try {
7576
// Copy gradle files
76-
await ncpAsync(fromGradleFolder, toFolder, {
77+
await cp(fromGradleFolder, toFolder, {
7778
filter: (cf) => gradleCopyFilter(cf, fromGradleFolder),
79+
recursive: true,
7880
});
7981

8082
// Copy shared gradle files
81-
await ncpAsync(path.join(grRoot, 'shared'), toFolder, {
83+
await cp(path.join(grRoot, 'shared'), toFolder, {
8284
filter: (cf) => gradleCopyFilter(cf, fromGradleFolder),
85+
recursive: true,
8386
});
8487

8588
// Set execute permissions on gradlew
@@ -100,7 +103,7 @@ export async function updateGradleRioVersion(
100103
gradleRioVersion: string
101104
): Promise<boolean> {
102105
try {
103-
return await pathUtils.updateFileContents(buildGradlePath, (content) =>
106+
return await fileUtils.updateFileContents(buildGradlePath, (content) =>
104107
content.replace(new RegExp(ReplacementPatterns.GRADLE_RIO_MARKER, 'g'), gradleRioVersion)
105108
);
106109
} catch (error) {
@@ -123,7 +126,7 @@ export async function setupDeployDirectory(
123126
}
124127

125128
const deployDir = path.join(toFolder, 'src', 'main', 'deploy');
126-
await mkdirpAsync(deployDir);
129+
await mkdir(deployDir, { recursive: true });
127130

128131
const hintKey = isJava ? 'generateJavaDeployHint' : 'generateCppDeployHint';
129132
const hintText = isJava
@@ -135,10 +138,7 @@ to get a proper path relative to the deploy directory.`
135138
function from the 'frc/Filesystem.h' header to get a proper path relative to the deploy
136139
directory.`;
137140

138-
await writeFileAsync(
139-
path.join(deployDir, 'example.txt'),
140-
i18n('generator', [hintKey, hintText])
141-
);
141+
await writeFile(path.join(deployDir, 'example.txt'), i18n('generator', [hintKey, hintText]));
142142

143143
return true;
144144
} catch (error) {
@@ -157,7 +157,7 @@ export async function setupVendorDeps(
157157
): Promise<boolean> {
158158
try {
159159
const vendorDir = path.join(toFolder, 'vendordeps');
160-
await mkdirpAsync(vendorDir);
160+
await mkdir(vendorDir, { recursive: true });
161161

162162
// Add WPILib New Commands
163163
await pathUtils.copyVendorDep(resourcesFolder, VendorDepFiles.COMMANDS, vendorDir);
@@ -183,5 +183,5 @@ export async function setupVendorDeps(
183183
*/
184184
export async function getGradleRioVersion(grRoot: string): Promise<string> {
185185
const grVersionFile = path.join(grRoot, 'version.txt');
186-
return (await readFileAsync(grVersionFile, 'utf8')).trim();
186+
return (await readFile(grVersionFile, 'utf8')).trim();
187187
}

0 commit comments

Comments
 (0)