@verdnatura/myt 1.8.6 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +80 -52
  2. package/assets/myt.default.yml +7 -0
  3. package/assets/structure.sql +1 -1
  4. package/{server/Dockerfile.client → docker/client/Dockerfile} +3 -3
  5. package/docker/server/Dockerfile +37 -0
  6. package/docker/server/Dockerfile.base +6 -0
  7. package/docker/server/Dockerfile.myt +35 -0
  8. package/docker/server/docker-init.sh +36 -0
  9. package/{server → docker/server}/docker-start.sh +1 -1
  10. package/lib/command.js +14 -6
  11. package/lib/docker.js +60 -34
  12. package/lib/dumper.js +11 -9
  13. package/lib/exporter-engine.js +4 -4
  14. package/lib/server.js +2 -8
  15. package/myt-apply.js +203 -0
  16. package/myt-build.js +283 -0
  17. package/myt-clean.js +15 -11
  18. package/myt-create.js +19 -11
  19. package/myt-dump.js +41 -36
  20. package/myt-fixtures.js +6 -6
  21. package/myt-init.js +5 -3
  22. package/myt-pull.js +12 -11
  23. package/myt-push.js +99 -96
  24. package/myt-run.js +28 -144
  25. package/myt-start.js +4 -4
  26. package/myt-version.js +13 -13
  27. package/myt.js +285 -149
  28. package/package.json +4 -3
  29. package/prebuilts/README.md +15 -0
  30. package/prebuilts/nodegit-v0.28.0-alpha.36-node-v127-linux-x64.tar.gz +0 -0
  31. package/template/.dockerignore +5 -0
  32. package/template/myt.config.yml +1 -4
  33. package/template/package.json +1 -1
  34. package/template/realms/.keep +0 -0
  35. package/template/remotes/docker.ini +1 -1
  36. package/template/remotes/local.ini +1 -1
  37. package/template/remotes/socket.ini +3 -0
  38. package/template/structure/.dump/structure.sql +32 -0
  39. package/server/Dockerfile.base +0 -1
  40. package/server/Dockerfile.dump +0 -16
  41. package/server/Dockerfile.server +0 -16
  42. package/server/docker-import.sh +0 -10
  43. package/server/docker-init.sh +0 -24
  44. /package/{server → docker/client}/docker-dump.sh +0 -0
  45. /package/{server → docker/client}/docker-fixtures.sh +0 -0
  46. /package/{server → docker/server}/docker.cnf +0 -0
  47. /package/template/{dump/Dockerfile.base → docker/Dockerfile} +0 -0
  48. /package/template/{dump/fixtures.after.sql → fixtures/after.sql} +0 -0
  49. /package/template/{dump/fixtures.before.sql → fixtures/before.sql} +0 -0
  50. /package/template/{dump/dump.after.sql → structure/after.sql} +0 -0
  51. /package/template/{dump/dump.before.sql → structure/before.sql} +0 -0
package/myt-run.js CHANGED
@@ -1,12 +1,8 @@
1
1
  const Myt = require('./myt');
2
2
  const Command = require('./lib/command');
3
- const Push = require('./myt-push');
4
3
  const docker = require('./lib/docker');
5
- const fs = require('fs-extra');
6
- const path = require('path');
7
4
  const Server = require('./lib/server');
8
- const connExt = require('./lib/conn');
9
- const SqlString = require('sqlstring');
5
+ const Build = require('./myt-build');
10
6
 
11
7
  /**
12
8
  * Builds the database image and runs a container. It only rebuilds the image
@@ -23,12 +19,12 @@ class Run extends Command {
23
19
  persist: 'Whether to not use tmpfs mount for MySQL data',
24
20
  keep: 'Keep container on failure',
25
21
  realm: 'Name of fixture realm to use',
26
- realm: 'Use container IP instead of localhost'
22
+ ip: 'Bind to container IP instead of localhost'
27
23
  },
28
24
  operand: 'realm'
29
25
  };
30
26
 
31
- static opts = {
27
+ static args = {
32
28
  alias: {
33
29
  network: 'n',
34
30
  random: 'r',
@@ -37,84 +33,48 @@ class Run extends Command {
37
33
  realm: 'm',
38
34
  ip: 'i'
39
35
  },
36
+ string: [
37
+ 'network',
38
+ 'realm'
39
+ ],
40
40
  boolean: [
41
41
  'ci',
42
42
  'random',
43
43
  'persist',
44
- 'keep'
44
+ 'keep',
45
+ 'ip'
45
46
  ]
46
47
  };
47
48
 
48
49
  static reporter = {
49
50
  buildingImage: 'Building container image.',
50
51
  runningContainer: 'Running container.',
51
- mockingDate: 'Mocking date functions.',
52
- applyingFixtures: 'Applying fixtures.',
53
- applyingRealms: 'Applying realm fixtures.',
54
- creatingTriggers: 'Creating triggers.',
55
52
  waitingDb: function(dbConfig) {
56
- console.log(`Waiting for MySQL: ${dbConfig.host}:${dbConfig.port}`);
53
+ console.log(`Waiting for database: ${dbConfig.host}:${dbConfig.port}`);
57
54
  }
58
55
  };
59
56
 
60
- async run(myt, opts) {
61
- const dumpDir = opts.dumpDir;
62
- const dumpDataDir = path.join(dumpDir, '.dump');
63
- const serverDir = path.join(__dirname, 'server');
64
-
65
- if (!await fs.pathExists(`${dumpDataDir}/structure.sql`))
66
- throw new Error('To run local database you have to create a dump first');
67
-
68
- // Build base image
69
-
70
- this.emit('buildingImage');
71
-
72
- let basePath = dumpDir;
73
- let baseDockerfile = path.join(dumpDir, 'Dockerfile');
74
-
75
- if (!await fs.pathExists(baseDockerfile)) {
76
- basePath = serverDir;
77
- baseDockerfile = path.join(serverDir, 'Dockerfile.base');
78
- }
79
-
80
- await docker.build(basePath, {
81
- tag: 'myt/base',
82
- file: baseDockerfile
83
- }, opts.debug);
84
-
85
- // Build server image
86
-
87
- await docker.build(serverDir, {
88
- tag: 'myt/server',
89
- file: path.join(serverDir, 'Dockerfile.server')
90
- }, opts.debug);
91
-
92
- // Build dump image
93
-
94
- const dumpContext = path.join(opts.mytDir, 'dump');
95
- await docker.build(dumpContext, {
96
- tag: opts.code,
97
- file: path.join(serverDir, 'Dockerfile.dump')
98
- }, opts.debug);
99
-
100
- // Run container
57
+ async _run(myt, ctx, cfg, opts) {
58
+ const tag = await myt.run(Build, {
59
+ realm: opts.realm
60
+ });
101
61
 
102
62
  this.emit('runningContainer');
103
63
 
104
64
  const isRandom = opts.random;
105
- const dbConfig = opts.dbConfig;
65
+ const dbConfig = ctx.dbConfig;
106
66
 
107
- let runOptions;
67
+ const runOptions = {};
108
68
 
109
69
  if (isRandom)
110
- runOptions = {publish: '3306'};
70
+ Object.assign(runOptions, {publish: '3306'});
111
71
  else {
112
- runOptions = {
113
- name: opts.code,
72
+ Object.assign(runOptions, {
73
+ name: cfg.code,
114
74
  publish: `3306:${dbConfig.port}`
115
- };
75
+ });
116
76
  try {
117
- const server = new Server(new docker.Container(opts.code));
77
+ const server = new Server(new docker.Container(cfg.code));
118
78
  await server.rm();
119
79
  } catch (e) {}
120
80
  }
@@ -122,13 +82,15 @@ class Run extends Command {
122
82
  const {network} = opts;
123
83
  if (opts.network)
124
84
  runOptions.network = network;
85
+
125
86
  if (!opts.persist)
126
87
  runOptions.tmpfs = '/var/lib/mysql';
127
88
 
128
- Object.assign(runOptions, null, {
89
+ Object.assign(runOptions, {
129
90
  detach: true
130
91
  });
131
- const ct = await docker.run(opts.code, null, runOptions);
92
+
93
+ const ct = await docker.run(tag, null, runOptions, undefined, cfg.debug);
132
94
 
133
95
  try {
134
96
  const server = new Server(ct, dbConfig);
@@ -146,15 +108,15 @@ class Run extends Command {
146
108
  if (network) {
147
109
  host = network != 'host'
148
110
  ? ctNetworks[network].IPAddress
149
- : localhost
111
+ : localhost;
150
112
  } else {
151
113
  host = netSettings.IPAddress
152
- ?? ctNetworks.bridge?.IPAddress
114
+ ?? ctNetworks.bridge?.IPAddress;
153
115
  }
154
116
  port = 3306;
155
117
  } else {
156
118
  host = localhost;
157
- port = netSettings.Ports['3306/tcp'][0].HostPort
119
+ port = netSettings.Ports['3306/tcp'][0].HostPort;
158
120
  }
159
121
 
160
122
  if (!host)
@@ -168,76 +130,6 @@ class Run extends Command {
168
130
 
169
131
  this.emit('waitingDb', dbConfig);
170
132
  await server.wait();
171
- const conn = await myt.createConnection();
172
-
173
- // Mock date functions
174
-
175
- this.emit('mockingDate');
176
- const mockDateScript = path.join(dumpDir, 'mockDate.sql');
177
-
178
- if (opts.mockDate) {
179
- if (!await fs.pathExists(mockDateScript))
180
- throw new Error(`Date mock enabled but mock script does not exist: ${mockDateScript}`);
181
-
182
- let sql = await fs.readFile(mockDateScript, 'utf8');
183
- sql = sql.replace(/@mockDate/g, SqlString.escape(opts.mockDate));
184
- await connExt.multiQuery(conn, sql);
185
- }
186
-
187
- // Apply changes
188
-
189
- const hasTriggers = await fs.exists(`${dumpDataDir}/triggers.sql`);
190
-
191
- Object.assign(opts, {
192
- triggers: !hasTriggers,
193
- commit: true,
194
- dbConfig
195
- });
196
- await myt.run(Push, opts);
197
-
198
- // Apply fixtures
199
-
200
- this.emit('applyingFixtures');
201
- const fixturesFiles = [
202
- 'fixtures.before',
203
- '.fixtures',
204
- 'fixtures.after',
205
- 'fixtures.local'
206
- ]
207
- for (const file of fixturesFiles) {
208
- if (!await fs.exists(`${dumpDir}/${file}.sql`)) continue;
209
- await execFile(`dump/${file}`)
210
- }
211
-
212
- // Apply realms
213
-
214
- if(opts.realm) {
215
- this.emit('applyingRealms');
216
- const realmDir = `realms/${opts.realm}`;
217
- let realmFiles = await fs.readdir(`${dumpDir}/${realmDir}`);
218
- realmFiles = realmFiles.map(file => path.parse(file).name);
219
- for (const file of realmFiles) {
220
- await execFile(`${realmDir}/${file}`)
221
- }
222
- }
223
-
224
- // Create triggers
225
-
226
- if (!hasTriggers) {
227
- this.emit('creatingTriggers');
228
-
229
- for (const schema of opts.schemas) {
230
- const triggersPath = `${opts.routinesDir}/${schema}/triggers`;
231
- if (!await fs.pathExists(triggersPath))
232
- continue;
233
-
234
- const triggersDir = await fs.readdir(triggersPath);
235
- for (const triggerFile of triggersDir)
236
- await connExt.queryFromFile(conn, `${triggersPath}/${triggerFile}`);
237
- }
238
- }
239
-
240
- await conn.end();
241
133
  return server;
242
134
  } catch (err) {
243
135
  try {
@@ -245,14 +137,6 @@ class Run extends Command {
245
137
  } catch (e) {}
246
138
  throw err;
247
139
  }
248
-
249
- async function execFile(path){
250
- await ct.exec(null, 'docker-import.sh',
251
- [`/workspace/${path}` ],
252
- 'spawn',
253
- true
254
- );
255
- }
256
140
  }
257
141
  }
258
142
 
package/myt-start.js CHANGED
@@ -19,8 +19,8 @@ class Start extends Command {
19
19
  startingContainer: 'Starting container.'
20
20
  };
21
21
 
22
- async run(myt, opts) {
23
- const ct = new Container(opts.code);
22
+ async _run(myt, ctx, cfg, opts) {
23
+ const ct = new Container(cfg.code);
24
24
  let status;
25
25
  let exists;
26
26
  let server;
@@ -31,7 +31,7 @@ class Start extends Command {
31
31
  });
32
32
  exists = true;
33
33
  } catch (err) {
34
- server = await myt.run(Run, opts);
34
+ server = await myt.run(Run);
35
35
  }
36
36
 
37
37
  if (exists) {
@@ -41,7 +41,7 @@ class Start extends Command {
41
41
  case 'exited':
42
42
  this.emit('startingContainer');
43
43
  await ct.start();
44
- server = new Server(ct, opts.dbConfig);
44
+ server = new Server(ct, ctx.dbConfig);
45
45
  await server.wait();
46
46
  break;
47
47
  default:
package/myt-version.js CHANGED
@@ -16,7 +16,7 @@ class Version extends Command {
16
16
  operand: 'name'
17
17
  };
18
18
 
19
- static opts = {
19
+ static args = {
20
20
  alias: {
21
21
  name: 'n',
22
22
  deprecate: 'p'
@@ -46,7 +46,7 @@ class Version extends Command {
46
46
  deprecate: 'Generating SQL for deprecated objects deletion.'
47
47
  };
48
48
 
49
- async run(myt, opts) {
49
+ async _run(myt, ctx, cfg, opts) {
50
50
  let newVersionDir;
51
51
 
52
52
  // Fetch last version number
@@ -61,7 +61,7 @@ class Version extends Command {
61
61
  FROM version
62
62
  WHERE code = ?
63
63
  FOR UPDATE`,
64
- [opts.code]
64
+ [cfg.code]
65
65
  );
66
66
  const number = row && row.number;
67
67
  const lastNumber = row && row.lastNumber;
@@ -78,7 +78,7 @@ class Version extends Command {
78
78
 
79
79
  const versionDigits = number
80
80
  ? number.length
81
- : opts.versionDigits;
81
+ : cfg.versionDigits;
82
82
 
83
83
  newVersion = String(newVersion).padStart(versionDigits, '0');
84
84
 
@@ -87,7 +87,7 @@ class Version extends Command {
87
87
  let versionName = opts.name;
88
88
 
89
89
  const versionNames = new Set();
90
- const versionDirs = await fs.readdir(opts.versionsDir);
90
+ const versionDirs = await fs.readdir(ctx.versionsDir);
91
91
  for (const versionDir of versionDirs) {
92
92
  const version = myt.parseVersionDir(versionDir);
93
93
  if (!version) continue;
@@ -117,7 +117,7 @@ class Version extends Command {
117
117
  // Create version
118
118
 
119
119
  const versionFolder = `${newVersion}-${versionName}`;
120
- newVersionDir = `${opts.versionsDir}/${versionFolder}`;
120
+ newVersionDir = `${ctx.versionsDir}/${versionFolder}`;
121
121
 
122
122
  await conn.query(
123
123
  `INSERT INTO version
@@ -125,13 +125,13 @@ class Version extends Command {
125
125
  lastNumber = ?
126
126
  ON DUPLICATE KEY UPDATE
127
127
  lastNumber = VALUES(lastNumber)`,
128
- [opts.code, newVersion]
128
+ [cfg.code, newVersion]
129
129
  );
130
130
  await fs.mkdir(newVersionDir);
131
131
 
132
132
  if (opts.deprecate) {
133
133
  this.emit('deprecate');
134
- await deprecate(conn, opts, newVersionDir);
134
+ await deprecate(conn, cfg, newVersionDir);
135
135
  } else
136
136
  await fs.writeFile(
137
137
  `${newVersionDir}/00-firstScript.sql`,
@@ -150,12 +150,12 @@ class Version extends Command {
150
150
  }
151
151
  }
152
152
 
153
- async function deprecate(conn, opts, newVersionDir) {
153
+ async function deprecate(conn, cfg, newVersionDir) {
154
154
  const now = new Date();
155
- const minDeprecDate = new Date(now.getTime() - opts.deprecRetentionPeriod * 24 * 60 * 60 * 1000);
156
- const deprecMarkRegex = opts.deprecMarkRegex;
157
- const deprecCommentRegex = opts.deprecCommentRegex;
158
- const deprecDateRegex = opts.deprecDateRegex;
155
+ const minDeprecDate = new Date(now.getTime() - cfg.deprecRetentionPeriod * 24 * 60 * 60 * 1000);
156
+ const deprecMarkRegex = cfg.deprecMarkRegex;
157
+ const deprecCommentRegex = cfg.deprecCommentRegex;
158
+ const deprecDateRegex = cfg.deprecDateRegex;
159
159
  const filePath = `${newVersionDir}/00-deprecate.sql`;
160
160
 
161
161
  // Generate the drops of the primary keys