Skip to content

Commit 1998411

Browse files
test: remove duplicated code
1 parent 10366f7 commit 1998411

File tree

1 file changed

+47
-51
lines changed

1 file changed

+47
-51
lines changed

automation/utils/bin/rui-update-screenshots.ts

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { pipeline } from "stream/promises";
1010
import fetch from "node-fetch";
1111
import { createLogger, format, transports } from "winston";
1212
import * as crossZip from "cross-zip";
13+
import { GitHub } from "../../utils/src/github";
14+
import { getPackageFileContent } from "../../utils/src/package-info";
1315

1416
const execAsync = promisify(exec);
1517

@@ -46,9 +48,9 @@ interface TestProject {
4648
branchName: string;
4749
}
4850

49-
interface WidgetPackage {
50-
name: string;
51-
version: string;
51+
interface WidgetPackageJson {
52+
name?: string;
53+
version?: string;
5254
scripts?: {
5355
[key: string]: string;
5456
};
@@ -109,51 +111,42 @@ class DockerError extends SnapshotUpdaterError {
109111
}
110112
}
111113

112-
// Utility classes
113-
class FileSystem {
114-
static async ensureDir(dirPath: string): Promise<void> {
114+
// Utility functions
115+
const FileSystem = {
116+
async ensureDir(dirPath: string): Promise<void> {
115117
try {
116118
await fs.mkdir(dirPath, { recursive: true });
117-
} catch (error) {
119+
} catch (_error) {
118120
throw new SnapshotUpdaterError(`Failed to create directory: ${dirPath}`, "FS_ERROR");
119121
}
120-
}
122+
},
121123

122-
static async removeDir(dirPath: string): Promise<void> {
124+
async removeDir(dirPath: string): Promise<void> {
123125
if (existsSync(dirPath)) {
124126
await fs.rm(dirPath, { recursive: true, force: true });
125127
}
126-
}
128+
},
127129

128-
static async copyFile(src: string, dest: string): Promise<void> {
130+
async copyFile(src: string, dest: string): Promise<void> {
129131
await fs.copyFile(src, dest);
130-
}
131-
132-
static async readJsonFile<T>(filePath: string): Promise<T> {
133-
try {
134-
const content = await fs.readFile(filePath, "utf8");
135-
return JSON.parse(content);
136-
} catch (error) {
137-
throw new SnapshotUpdaterError(`Failed to read JSON file: ${filePath}`, "JSON_ERROR");
138-
}
139-
}
132+
},
140133

141-
static async createTempDir(): Promise<string> {
142-
return await fs.mkdtemp(path.join(process.env.TMPDIR || "/tmp", "mx-e2e-"));
134+
async createTempDir(): Promise<string> {
135+
return fs.mkdtemp(path.join(process.env.TMPDIR || "/tmp", "mx-e2e-"));
143136
}
144-
}
137+
};
145138

146-
class DockerManager {
147-
static async isRunning(): Promise<boolean> {
139+
const DockerManager = {
140+
async isRunning(): Promise<boolean> {
148141
try {
149142
await execAsync("docker info");
150143
return true;
151144
} catch {
152145
return false;
153146
}
154-
}
147+
},
155148

156-
static async findFreePort(): Promise<number> {
149+
async findFreePort(): Promise<number> {
157150
try {
158151
const { stdout } = await execAsync(
159152
"node -e \"const net = require('net'); const server = net.createServer(); server.listen(0, () => { console.log(server.address().port); server.close(); });\""
@@ -163,9 +156,9 @@ class DockerManager {
163156
// Fallback to random port in ephemeral range
164157
return Math.floor(Math.random() * (65535 - 49152) + 49152);
165158
}
166-
}
159+
},
167160

168-
static async runContainer(options: {
161+
async runContainer(options: {
169162
image: string;
170163
name?: string;
171164
ports?: Record<number, number>;
@@ -205,50 +198,52 @@ class DockerManager {
205198
try {
206199
const { stdout } = await execAsync(`docker ${args.join(" ")}`);
207200
return stdout.trim();
208-
} catch (error) {
209-
throw new DockerError(`Failed to run container: ${error}`);
201+
} catch (_error) {
202+
throw new DockerError(`Failed to run container: ${_error}`);
210203
}
211-
}
204+
},
212205

213-
static async isContainerRunning(name: string): Promise<boolean> {
206+
async isContainerRunning(name: string): Promise<boolean> {
214207
try {
215208
const { stdout } = await execAsync(`docker ps --filter name=${name} --format "{{.Names}}"`);
216209
return stdout.trim() === name;
217210
} catch {
218211
return false;
219212
}
220-
}
213+
},
221214

222-
static async stopContainer(name: string): Promise<void> {
215+
async stopContainer(name: string): Promise<void> {
223216
try {
224217
await execAsync(`docker rm -f ${name}`);
225218
} catch {
226219
// Container might not exist or already stopped
227220
}
228-
}
221+
},
229222

230-
static async getContainerLogs(name: string): Promise<string> {
223+
async getContainerLogs(name: string): Promise<string> {
231224
try {
232225
const { stdout } = await execAsync(`docker logs ${name}`);
233226
return stdout;
234227
} catch {
235228
return "No logs available";
236229
}
237230
}
238-
}
231+
};
239232

240-
class GitHubClient {
233+
class GitHubHelper extends GitHub {
241234
private readonly baseUrl = "https://api.github.com";
242235
private readonly headers: Record<string, string>;
243236

244237
constructor(private readonly token?: string) {
238+
super();
245239
this.headers = {
246240
"User-Agent": "mx-e2e-script",
247-
Accept: "application/vnd.github+json"
241+
Accept: "application/vnd.github+json",
242+
"X-GitHub-Api-Version": "2022-11-28"
248243
};
249244

250245
if (token) {
251-
this.headers["Authorization"] = `Bearer ${token}`;
246+
this.headers.Authorization = `Bearer ${token}`;
252247
}
253248
}
254249

@@ -286,7 +281,7 @@ class GitHubClient {
286281

287282
class AtlasUpdater {
288283
constructor(
289-
private readonly githubClient: GitHubClient,
284+
private readonly githubClient: GitHubHelper,
290285
private readonly tempDir: string
291286
) {}
292287

@@ -463,7 +458,7 @@ class SnapshotUpdater {
463458
}
464459

465460
private setupCleanup(): void {
466-
const cleanup = async () => {
461+
const cleanup = async (): Promise<void> => {
467462
if (this.tempDir) {
468463
await FileSystem.removeDir(this.tempDir);
469464
}
@@ -527,7 +522,7 @@ class SnapshotUpdater {
527522
logger.info(`Setting up test project for ${widgetName}...`);
528523

529524
const widgetDir = path.join(this.rootDir, CONFIG.PATHS.PLUGGABLE_WIDGETS, widgetName);
530-
const widgetPkg = await FileSystem.readJsonFile<WidgetPackage>(path.join(widgetDir, "package.json"));
525+
const widgetPkg = (await getPackageFileContent(widgetDir)) as WidgetPackageJson;
531526

532527
if (!widgetPkg.testProject) {
533528
throw new ValidationError("No testProject field in widget package.json");
@@ -538,7 +533,7 @@ class SnapshotUpdater {
538533

539534
// Update Atlas components
540535
if (options.githubToken) {
541-
const githubClient = new GitHubClient(options.githubToken);
536+
const githubClient = new GitHubHelper(options.githubToken);
542537
const atlasUpdater = new AtlasUpdater(githubClient, this.tempDir!);
543538

544539
const testProjectDir = path.join(this.rootDir, CONFIG.PATHS.TEST_PROJECT);
@@ -554,7 +549,8 @@ class SnapshotUpdater {
554549
}
555550

556551
// Build and copy widget
557-
await this.buildAndCopyWidget(widgetName, widgetPkg.version);
552+
const version = widgetPkg.version || "0.0.0";
553+
await this.buildAndCopyWidget(widgetName, version);
558554
}
559555

560556
private async downloadTestProject(testProject: TestProject): Promise<void> {
@@ -612,7 +608,7 @@ class SnapshotUpdater {
612608
logger.info(`Building widget ${widgetName}...`);
613609

614610
const widgetDir = path.join(this.rootDir, CONFIG.PATHS.PLUGGABLE_WIDGETS, widgetName);
615-
const widgetPkg = await FileSystem.readJsonFile<WidgetPackage>(path.join(widgetDir, "package.json"));
611+
const widgetPkg = (await getPackageFileContent(widgetDir)) as WidgetPackageJson;
616612

617613
if (!widgetPkg || typeof widgetPkg.version !== "string") {
618614
throw new SnapshotUpdaterError(`Invalid package.json in widget ${widgetName}`);
@@ -759,7 +755,7 @@ class SnapshotUpdater {
759755
if (runtimeContainerId) {
760756
break;
761757
}
762-
} catch (error) {
758+
} catch (_error) {
763759
// Continue waiting
764760
}
765761
await new Promise(resolve => setTimeout(resolve, 100));
@@ -789,7 +785,7 @@ class SnapshotUpdater {
789785
logger.info("Mendix runtime is ready");
790786
return;
791787
}
792-
} catch (error) {
788+
} catch (_error) {
793789
logger.info(`Could not reach http://${ip}:${port}, trying again...`);
794790
}
795791
await new Promise(resolve => setTimeout(resolve, 3000));
@@ -801,7 +797,7 @@ class SnapshotUpdater {
801797
try {
802798
const logContent = await fs.readFile(path.join(this.rootDir, "results/runtime.log"), "utf8");
803799
logger.error(logContent);
804-
} catch (error) {
800+
} catch (_error) {
805801
logger.error("Could not read runtime.log");
806802
}
807803
throw new DockerError("Runtime didn't start in time, exiting now...");

0 commit comments

Comments
 (0)