1
1
const { spawnSync : baseSpawnSync } = require ( "child_process" ) ;
2
2
const { basename, dirname, resolve } = require ( "path" ) ;
3
3
const platform = require ( "os" ) . platform ( ) ;
4
+ const { safeRandomString } = require ( "../../scripts/lib/random" ) ;
5
+ const fsp = require ( "fs" ) . promises ;
6
+
7
+ const DOCKER_DOTENV_PATH = `${ __dirname } /../.env` ;
4
8
5
9
if ( platform !== "win32" && ! process . env . UID ) {
6
10
console . error (
@@ -23,28 +27,76 @@ function spawnSync(command, args, options = {}) {
23
27
}
24
28
}
25
29
26
- // The `docker-compose` project name defaults to the directory name containing
27
- // `docker-compose.yml`, which is the root folder of our project. Let's call
28
- // that 'ROOT'. We're in ROOT/docker/scripts and we want to get the name of
29
- // ROOT:
30
- const projectName = basename ( dirname ( dirname ( resolve ( __dirname ) ) ) ) ;
31
-
32
- // On Windows we must run 'yarn.cmd' rather than 'yarn'
33
- const yarnCmd = platform === "win32" ? "yarn.cmd" : "yarn" ;
34
-
35
- spawnSync ( yarnCmd , [ "down" ] ) ;
36
- spawnSync ( yarnCmd , [ "db:up" ] ) ;
37
-
38
- // Fix permissions
39
- spawnSync ( yarnCmd , [
40
- "compose" ,
41
- "run" ,
42
- "server" ,
43
- "sudo" ,
44
- "bash" ,
45
- "-c" ,
46
- "chmod o+rwx /var/run/docker.sock && chown -R node /work/node_modules /work/@app/*/node_modules" ,
47
- ] ) ;
48
-
49
- // Run setup as normal
50
- spawnSync ( yarnCmd , [ "compose" , "run" , "server" , "yarn" , "setup" , projectName ] ) ;
30
+ async function main ( ) {
31
+ // Check that docker/.env exists
32
+ try {
33
+ await fsp . access ( DOCKER_DOTENV_PATH , fs . constants . F_OK ) ;
34
+ } catch ( e ) {
35
+ // Does not exist, write it
36
+ const password = safeRandomString ( 30 ) ;
37
+ const data = `
38
+ # We'd like scripts ran through Docker to pretend they're in a normal
39
+ # interactive terminal.
40
+ FORCE_COLOR=2
41
+
42
+ # \`pg_dump\` is run from inside container, which doesn't have pg tools installed
43
+ # so it needs a way to still run it. \`docker-compose run\` would start an
44
+ # instance inside the current running container which doesn't work with volume
45
+ # mappings, so we must use \`docker-compose exec\`. \`-T\` is needed because our
46
+ # \`.gmrc\` checks for interactive TTY.
47
+ PG_DUMP=docker-compose exec -T db pg_dump
48
+
49
+ # Drops tables without asking in \`yarn setup\`. Reasoning: 1) docker-compose is
50
+ # not tty, 2) it's a dev env anyway.
51
+ CONFIRM_DROP=y
52
+
53
+ # POSTGRES_PASSWORD is the superuser password for PostgreSQL, it's required to
54
+ # initialize the Postgres docker volume.
55
+ POSTGRES_PASSWORD=${ password }
56
+
57
+ # We're accessing Postgres via Docker, so we must use the db host and the
58
+ # relevant password.
59
+ DATABASE_HOST=db
60
+ ROOT_DATABASE_URL=postgres://postgres:${ password } @db/template1
61
+ ` ;
62
+ await fsp . writeFile ( DOCKER_DOTENV_PATH , data ) ;
63
+ }
64
+
65
+ // The `docker-compose` project name defaults to the directory name containing
66
+ // `docker-compose.yml`, which is the root folder of our project. Let's call
67
+ // that 'ROOT'. We're in ROOT/docker/scripts and we want to get the name of
68
+ // ROOT:
69
+ const projectName = basename ( dirname ( dirname ( resolve ( __dirname ) ) ) ) ;
70
+
71
+ // On Windows we must run 'yarn.cmd' rather than 'yarn'
72
+ const yarnCmd = platform === "win32" ? "yarn.cmd" : "yarn" ;
73
+
74
+ spawnSync ( yarnCmd , [ "down" ] ) ;
75
+ spawnSync ( yarnCmd , [ "db:up" ] ) ;
76
+
77
+ // Fix permissions
78
+ spawnSync ( yarnCmd , [
79
+ "compose" ,
80
+ "run" ,
81
+ "server" ,
82
+ "sudo" ,
83
+ "bash" ,
84
+ "-c" ,
85
+ "chmod o+rwx /var/run/docker.sock && chown -R node /work/node_modules /work/@app/*/node_modules" ,
86
+ ] ) ;
87
+
88
+ // Run setup as normal
89
+ spawnSync ( yarnCmd , [
90
+ "compose" ,
91
+ "run" ,
92
+ "server" ,
93
+ "yarn" ,
94
+ "setup" ,
95
+ projectName ,
96
+ ] ) ;
97
+ }
98
+
99
+ main ( ) . catch ( e => {
100
+ console . error ( e ) ;
101
+ process . exit ( 1 ) ;
102
+ } ) ;
0 commit comments