1 import * as fs from 'fs';
2 import * as md5File from 'md5-file';
3 import * as path from 'path';
4 import { promisify } from 'util';
6 const copyFile = promisify(fs.copyFile);
7 const exists = promisify(fs.exists);
8 const stat = promisify(fs.stat);
10 if (process.argv.length !== 3) {
11 throw new Error('Expected the path to the repository root as the only argument.');
14 const repository = process.argv[2];
15 if (!fs.existsSync(repository)) {
16 throw new Error(`The path '${repository}' does not exist.`);
18 process.chdir(repository);
20 const 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);
26 checksum: md5File.sync(file),
27 lastModified: stats.mtime,
34 (async (): Promise<void> => {
35 fs.readFile('syncTemplates.json', 'utf8', async (err: NodeJS.ErrnoException, content: string): Promise<void> => {
37 const data: SyncTemplateConfiguration = JSON.parse(content);
39 if ((<any>data).__proto__ === Object.prototype) {
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]),
49 if (status[0] === null && status[1] === null) {
50 throw new Error(`Unknown file ${template}.`);
54 if (status[0] === null) {
56 } else if (status[1] === null) {
58 } else if (status[0].checksum !== status[1].checksum) {
59 copyTo = (status[0].lastModified > status[1].lastModified) ? 1 : 0;
63 const source = (copyTo === 0) ? 1 : 0;
65 path.join(data.directories[source], template),
66 path.join(data.directories[copyTo], template),
73 if (filesCopied === 0) {
74 console.log("All files are in sync.");
76 console.log(`Copied ${filesCopied} of ${data.templates.length} files.`);
79 throw new Error("Expected an object at the JSON root.");
85 interface SyncTemplateConfiguration {
86 directories: string[];
90 interface FileStatus {