Repository navigation
Expand file tree
/
Copy pathsetup.ts
More file actions
124 lines (106 loc) · 2.93 KB
/
Copy pathsetup.ts
File metadata and controls
124 lines (106 loc) · 2.93 KB
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
import { exists } from "@std/fs";
import { dirname, join } from "@std/path";
import {
fail,
getReposDir,
loadEnv,
ok,
readYaml,
ROOT,
type Service,
SERVICES,
warn,
} from "./utils.ts";
const run = async (cmd: string, ...args: string[]): Promise<boolean> => {
try {
const { success } = await new Deno.Command(cmd, {
args,
stdout: "null",
stderr: "inherit",
}).output();
return success;
} catch {
return false;
}
};
const checkRequirements = async () => {
if (!(await run("git", "--version"))) fail("git not found");
if (!(await run("docker", "compose", "version"))) {
warn("docker compose not found, you will need it to run the stack");
}
};
const cloneRepos = async (reposDir: string) => {
for (const { repo } of SERVICES) {
const repoPath = join(reposDir, repo);
if (await exists(repoPath)) {
ok(`${repo} already exists`);
continue;
}
console.log(`Cloning ${repo}...`);
const cloned = await run(
"git",
"clone",
`https://github.com/openhotel/${repo}.git`,
repoPath,
);
if (cloned) ok(`${repo} cloned`);
else warn(`${repo} could not be cloned!`);
}
};
const flatten = (
object: Record<string, unknown>,
prefix = "",
): Record<string, unknown> =>
Object.entries(object).reduce((flat, [key, value]) => {
const path = prefix ? `${prefix}.${key}` : key;
return typeof value === "object" && value !== null && !Array.isArray(value)
? { ...flat, ...flatten(value as Record<string, unknown>, path) }
: { ...flat, [path]: value };
}, {});
const checkConfig = async (
service: Service,
configPath: string,
templatePath: string,
) => {
let config: Record<string, unknown>;
try {
config = flatten(await readYaml(configPath));
} catch {
warn(`${service.name}: ${configPath} is not valid yaml`);
return;
}
const template = flatten(await readYaml(templatePath));
for (const [key, value] of Object.entries(template)) {
if (config[key] !== value) {
warn(
`${service.name}: '${key}' should be '${value}' (is '${config[key]}')`,
);
}
}
};
const copyConfigs = async (reposDir: string) => {
for (const service of SERVICES) {
const repoPath = join(reposDir, service.repo);
if (!(await exists(repoPath))) continue;
const configPath = join(repoPath, service.config);
const templatePath = join(ROOT, "configs", `${service.name}.yml`);
if (await exists(configPath)) {
await checkConfig(service, configPath, templatePath);
continue;
}
await Deno.mkdir(dirname(configPath), { recursive: true });
await Deno.copyFile(templatePath, configPath);
ok(`${service.name}: config created`);
}
};
await checkRequirements();
const env = await loadEnv();
const reposDir = getReposDir(env);
await cloneRepos(reposDir);
await copyConfigs(reposDir);
console.log(`
Ready! Next steps:
1. deno task up auth
2. deno task seed
3. deno task up
`);