forked from PreMiD/Presences
-
Notifications
You must be signed in to change notification settings - Fork 0
/
syntaxEnforcer.ts
178 lines (156 loc) · 5.27 KB
/
syntaxEnforcer.ts
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
171
172
173
174
175
176
177
178
import "source-map-support/register";
import { green, yellow } from "chalk";
import { readFileSync, writeFileSync } from "fs";
import { sync as glob } from "glob";
import { join, normalize, relative, resolve, sep } from "path";
import { format as prettier, resolveConfig } from "prettier";
import { coerce, inc } from "semver";
import execa = require("execa");
/**
* Helper function to read any file as string
* @param path Path to the file
*/
const readFile = (path: string): string =>
readFileSync(path, { encoding: "utf8" }),
/**
* Helper function to write any data to disk
* @param data Data to write
* @param path Path to write the data to
*/
writeFile = (path: string, data: string): void =>
writeFileSync(path, data, { encoding: "utf8" }),
/**
* Helper function to read a JSON file into memory
* @param jsonPath Path to the JSON file
*/
readJson = <T>(jsonPath: string): T => JSON.parse(readFile(jsonPath)) as T,
/**
* Helper function to write a JSON file to disk
* @param data The data to write to the JSON file
* @param jsonPath The path to write the JSON file to
*/
writeJson = <T>(data: T, jsonPath: string): void =>
writeFileSync(jsonPath, JSON.stringify(data, null, 2), {
encoding: "utf8"
}),
prettify = async (): Promise<void> => {
console.time("pretty_time");
// Grab all TS files and JSON files
const tsFiles = glob("./{websites,programs}/*/*/*.ts", {
ignore: ["**/node_modules/**", "**/@types/**"],
absolute: true
});
for (const fileToPrettify of tsFiles) {
// Get the raw data from the file
const fileContent = readFile(fileToPrettify),
// Format the file using Prettier
formatted = prettier(fileContent, {
...(await resolveConfig(fileToPrettify)),
filepath: fileToPrettify
});
// If the file content is not the same as the formatted content
if (formatted !== fileContent) {
// Write the file to the system
writeFile(fileToPrettify, formatted);
// And log the name with a green colour to indicate it did change
console.log(green(relative(__dirname, fileToPrettify)));
}
}
console.timeEnd("pretty_time");
},
increaseSemver = async (filesToBump: string[]): Promise<void> => {
console.time("semver_bump_time");
if (filesToBump.length === 0) return;
for (const [i, dir] of filesToBump.entries()) {
// Normalize the path and seperate it on OS specific seperator
const normalizedPath = normalize(dir).split(sep);
// Pop off the presence/iframe.ts
normalizedPath.pop();
filesToBump[i] = normalizedPath.join(sep);
}
const directory = [...new Set(filesToBump)];
for (const path of directory) {
console.log(path);
// Normalize the path and seperate it on OS specific seperator
const normalizedPath = resolve(normalize(path)).split(sep),
metadataPath = join(normalizedPath.join(sep), "dist", "metadata.json"),
metadata = readJson<Metadata>(metadataPath);
if (metadata && metadata.version) {
const newVersion = inc(coerce(metadata.version), "patch");
writeJson({ ...metadata, version: newVersion }, metadataPath);
}
}
console.timeEnd("semver_bump_time");
},
// Main function that calls the other functions above
main = async (): Promise<void> => {
if (!process.env.GITHUB_ACTIONS)
console.log(
"\nPlease note that this script is ONLY supposed to run on a CI environment\n"
);
// A clear splitter before prettify
console.log(
yellow(
[
"|--------------------------------|",
"| PROCEEDING TO PRETTIFY SOURCES |",
"|--------------------------------|"
].join("\n")
)
);
await prettify();
// A clear splitter between TypeScript compilation and semver bumps
console.log(
yellow(
[
"|----------------------------|",
"| PROCEEDING TO SEMVER BUMPS |",
"|----------------------------|"
].join("\n")
)
);
// Use Git to check what files have changed after TypeScript compilation
const { stdout: listOfChangedFiles } = await execa("git", [
"--no-pager",
"diff",
"--name-only"
]),
changedPresenceFiles = listOfChangedFiles
.split("\n")
.filter(
(file) => file.includes("presence.ts") || file.includes("iframe.ts")
);
await increaseSemver(changedPresenceFiles);
// Exit with the designated exit code to ensure the CI action fails or succeeds
process.exit();
};
// Call main
main();
/** Typings for the Metadata JSON file */
interface Metadata {
author: { name: string; id: string };
contributors?: Array<{ name: string; id: string }>;
service: string;
description: Record<string, string>;
url: string;
version: string;
logo: string;
thumbnail: string;
color: string;
tags: string | Array<string>;
category: string;
iframe?: boolean;
regExp?: RegExp;
iframeRegExp?: RegExp;
button?: boolean;
warning?: boolean;
settings?: Array<{
id: string;
title: string;
icon: string;
if?: Record<string, string>;
placeholder?: string;
value?: string | number | boolean;
values?: Array<string | number | boolean>;
}>;
}