Merge branch '5.3'
[GitHub/WoltLab/WCF.git] / extra / syncTemplates.ts
CommitLineData
3f4a49f8
AE
1import * as fs from 'fs';
2import * as md5File from 'md5-file';
3import * as path from 'path';
4import { promisify } from 'util';
5
6const copyFile = promisify(fs.copyFile);
7const exists = promisify(fs.exists);
8const stat = promisify(fs.stat);
9
10if (process.argv.length !== 3) {
11 throw new Error('Expected the path to the repository root as the only argument.');
12}
13
14const repository = process.argv[2];
15if (!fs.existsSync(repository)) {
16 throw new Error(`The path '${repository}' does not exist.`);
17}
18process.chdir(repository);
19
20const getFileStatus = async (filename: string, directory: string): Promise<FileStatus> => {
21 const file = path.join(directory, filename);
22 if (await exists(file)) {
23 const stats = await stat(file);
24
25 return {
26 checksum: md5File.sync(file),
27 lastModified: stats.mtime,
28 };
29 }
30
31 return null;
32};
33
34(async (): Promise<void> => {
35 fs.readFile('syncTemplates.json', 'utf8', async (err: NodeJS.ErrnoException, content: string): Promise<void> => {
36 if (!err) {
37 const data: SyncTemplateConfiguration = JSON.parse(content);
38
39 if ((<any>data).__proto__ === Object.prototype) {
40 let filesCopied = 0;
41
42 await Promise.all(data.templates.map(async (template: string): Promise<void> => {
43 template = `${template}.tpl`;
44 const status = await Promise.all([
45 getFileStatus(template, data.directories[0]),
46 getFileStatus(template, data.directories[1]),
47 ]);
48
49 if (status[0] === null && status[1] === null) {
50 throw new Error(`Unknown file ${template}.`);
51 }
52
53 let copyTo = -1;
54 if (status[0] === null) {
55 copyTo = 0;
56 } else if (status[1] === null) {
57 copyTo = 1;
58 } else if (status[0].checksum !== status[1].checksum) {
59 copyTo = (status[0].lastModified > status[1].lastModified) ? 1 : 0;
60 }
61
62 if (copyTo !== -1) {
63 const source = (copyTo === 0) ? 1 : 0;
64 await copyFile(
65 path.join(data.directories[source], template),
66 path.join(data.directories[copyTo], template),
67 );
68
69 filesCopied++;
70 }
71 }));
72
73 if (filesCopied === 0) {
74 console.log("All files are in sync.");
75 } else {
76 console.log(`Copied ${filesCopied} of ${data.templates.length} files.`);
77 }
78 } else {
79 throw new Error("Expected an object at the JSON root.");
80 }
81 }
82 });
83})();
84
85interface SyncTemplateConfiguration {
86 directories: string[];
87 templates: string[];
88}
89
90interface FileStatus {
91 checksum: string;
92 lastModified: Date;
93}