@verdnatura/myt 1.5.26 → 1.5.28
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.
- package/README.md +2 -2
- package/cli.js +1 -1
- package/lib/command.js +23 -5
- package/lib/server.js +1 -6
- package/myt-clean.js +35 -11
- package/myt-create.js +6 -3
- package/myt-dump.js +2 -3
- package/myt-fixtures.js +1 -1
- package/myt-init.js +1 -1
- package/myt-pull.js +10 -3
- package/myt-push.js +133 -93
- package/myt-run.js +22 -7
- package/myt-start.js +7 -2
- package/myt-version.js +16 -8
- package/myt.js +15 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -275,8 +275,8 @@ $ myt fixtures [<remote>]
|
|
|
275
275
|
|
|
276
276
|
### run
|
|
277
277
|
|
|
278
|
-
Builds and starts local database server container. It only rebuilds the image
|
|
279
|
-
dump
|
|
278
|
+
Builds and starts local database server container. It only rebuilds the image
|
|
279
|
+
when dump have been modified.
|
|
280
280
|
|
|
281
281
|
```text
|
|
282
282
|
$ myt run [-c|--ci] [-r|--random]
|
package/cli.js
CHANGED
package/lib/command.js
CHANGED
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base class for Myt commands.
|
|
3
3
|
*/
|
|
4
|
-
module.exports = class MytCommand
|
|
4
|
+
module.exports = class MytCommand{
|
|
5
5
|
constructor(myt, opts) {
|
|
6
6
|
this.myt = myt;
|
|
7
7
|
this.opts = opts;
|
|
8
|
+
this.handlers = {};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async cli(myt, opts) {
|
|
12
|
+
const reporter = this.constructor.reporter;
|
|
13
|
+
if (reporter)
|
|
14
|
+
for (const event in reporter) {
|
|
15
|
+
const handler = reporter[event];
|
|
16
|
+
if (typeof handler == 'string') {
|
|
17
|
+
this.on(event, () => console.log(handler));
|
|
18
|
+
} else if (handler instanceof Function)
|
|
19
|
+
this.on(event, handler);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await this.run(myt, opts);
|
|
8
23
|
}
|
|
9
24
|
|
|
10
25
|
async run(myt, opts) {
|
|
11
26
|
throw new Error('run command not defined');
|
|
12
27
|
}
|
|
13
28
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
29
|
+
on(event, handler) {
|
|
30
|
+
this.handlers[event] = handler;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
emit(event, ...args) {
|
|
34
|
+
const handler = this.handlers[event];
|
|
35
|
+
if (handler) handler (...args);
|
|
18
36
|
}
|
|
19
37
|
}
|
package/lib/server.js
CHANGED
|
@@ -25,8 +25,6 @@ module.exports = class Server {
|
|
|
25
25
|
port: dbConfig.port
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
console.log('Waiting for MySQL init process...');
|
|
29
|
-
|
|
30
28
|
async function checker() {
|
|
31
29
|
elapsedTime += interval;
|
|
32
30
|
let status;
|
|
@@ -46,10 +44,7 @@ module.exports = class Server {
|
|
|
46
44
|
conn.on('error', () => {});
|
|
47
45
|
conn.connect(err => {
|
|
48
46
|
conn.destroy();
|
|
49
|
-
if (!err)
|
|
50
|
-
console.log('MySQL process ready.');
|
|
51
|
-
return resolve();
|
|
52
|
-
}
|
|
47
|
+
if (!err) return resolve();
|
|
53
48
|
|
|
54
49
|
if (elapsedTime >= maxInterval)
|
|
55
50
|
reject(new Error(`MySQL not initialized whithin ${elapsedTime / 1000} secs`));
|
package/myt-clean.js
CHANGED
|
@@ -26,15 +26,30 @@ class Clean extends Command {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
static reporter = {
|
|
30
|
+
versionsArchived: function(nVersions) {
|
|
31
|
+
if (nVersions)
|
|
32
|
+
console.log(` -> ${oldVersions.length} versions archived.`);
|
|
33
|
+
else
|
|
34
|
+
console.log(` -> No versions archived.`);
|
|
35
|
+
},
|
|
36
|
+
versionLogPurged: function(nPurged) {
|
|
37
|
+
if (nPurged)
|
|
38
|
+
console.log(` -> ${nPurged} changes purged from log.`);
|
|
39
|
+
else
|
|
40
|
+
console.log(` -> No logs purged.`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
29
44
|
async run(myt, opts) {
|
|
30
45
|
const conn = await myt.dbConnect();
|
|
31
|
-
const versionDirs = await fs.readdir(opts.versionsDir);
|
|
32
46
|
const archiveDir = path.join(opts.versionsDir, '.archive');
|
|
33
47
|
|
|
34
48
|
const dbVersion = await myt.fetchDbVersion() || {};
|
|
35
49
|
const number = parseInt(dbVersion.number);
|
|
36
50
|
|
|
37
51
|
const oldVersions = [];
|
|
52
|
+
const versionDirs = await fs.readdir(opts.versionsDir);
|
|
38
53
|
for (const versionDir of versionDirs) {
|
|
39
54
|
const version = await myt.loadVersion(versionDir);
|
|
40
55
|
const shouldArchive = version
|
|
@@ -71,9 +86,9 @@ class Clean extends Command {
|
|
|
71
86
|
await fs.rmdir(srcDir);
|
|
72
87
|
}
|
|
73
88
|
|
|
74
|
-
|
|
89
|
+
this.emit('versionsArchived', oldVersions.length);
|
|
75
90
|
} else
|
|
76
|
-
|
|
91
|
+
this.emit('versionsArchived');
|
|
77
92
|
|
|
78
93
|
if (opts.purge) {
|
|
79
94
|
const versionDb = new VersionDb(myt, opts.versionsDir);
|
|
@@ -89,6 +104,7 @@ class Clean extends Command {
|
|
|
89
104
|
[opts.code]
|
|
90
105
|
);
|
|
91
106
|
|
|
107
|
+
let nPurged = 0;
|
|
92
108
|
for (const script of res) {
|
|
93
109
|
const hasVersion = await versionDb.hasScript(script);
|
|
94
110
|
const hasArchive = await archiveDb.hasScript(script);
|
|
@@ -99,8 +115,11 @@ class Clean extends Command {
|
|
|
99
115
|
WHERE code = ? AND number = ? AND file = ?`,
|
|
100
116
|
[opts.code, script.number, script.file]
|
|
101
117
|
);
|
|
118
|
+
nPurged++;
|
|
102
119
|
}
|
|
103
120
|
}
|
|
121
|
+
|
|
122
|
+
this.emit('versionLogPurged', nPurged);
|
|
104
123
|
}
|
|
105
124
|
}
|
|
106
125
|
}
|
|
@@ -111,27 +130,32 @@ class VersionDb {
|
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
async load() {
|
|
114
|
-
const
|
|
133
|
+
const map = this.map = new Map();
|
|
115
134
|
if (await fs.pathExists(this.baseDir)) {
|
|
116
135
|
const dirs = await fs.readdir(this.baseDir);
|
|
117
136
|
for (const dir of dirs) {
|
|
118
137
|
const version = this.myt.parseVersionDir(dir);
|
|
119
138
|
if (!version) continue;
|
|
120
|
-
|
|
139
|
+
let subdirs = map.get(version.number);
|
|
140
|
+
if (!subdirs) map.set(version.number, subdirs = []);
|
|
141
|
+
subdirs.push(dir);
|
|
121
142
|
}
|
|
122
143
|
}
|
|
123
|
-
return
|
|
144
|
+
return map;
|
|
124
145
|
}
|
|
125
146
|
|
|
126
147
|
async hasScript(script) {
|
|
127
|
-
const
|
|
128
|
-
if (
|
|
129
|
-
|
|
130
|
-
|
|
148
|
+
const dirs = this.map.get(script.number);
|
|
149
|
+
if (dirs)
|
|
150
|
+
for (const dir of dirs) {
|
|
151
|
+
const scriptPath = path.join(this.baseDir, dir, script.file);
|
|
152
|
+
if (await fs.pathExists(scriptPath)) return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
131
155
|
}
|
|
132
156
|
}
|
|
133
157
|
|
|
134
158
|
module.exports = Clean;
|
|
135
159
|
|
|
136
160
|
if (require.main === module)
|
|
137
|
-
new Myt().
|
|
161
|
+
new Myt().cli(Clean);
|
package/myt-create.js
CHANGED
|
@@ -27,6 +27,11 @@ class Create extends Command {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
+
async cli(myt, opts) {
|
|
31
|
+
await super.cli(myt, opts);
|
|
32
|
+
console.log('Routine created.');
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
async run(myt, opts) {
|
|
31
36
|
const match = opts.name.match(/^(\w+)\.(\w+)$/);
|
|
32
37
|
if (!match)
|
|
@@ -63,12 +68,10 @@ class Create extends Command {
|
|
|
63
68
|
|
|
64
69
|
const routineFile = `${routineDir}/${name}.sql`;
|
|
65
70
|
await fs.writeFile(routineFile, sql);
|
|
66
|
-
|
|
67
|
-
console.log('Routine created.');
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
module.exports = Create;
|
|
72
75
|
|
|
73
76
|
if (require.main === module)
|
|
74
|
-
new Myt().
|
|
77
|
+
new Myt().cli(Create);
|
package/myt-dump.js
CHANGED
|
@@ -28,7 +28,7 @@ class Dump extends Command {
|
|
|
28
28
|
]
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
static
|
|
31
|
+
static reporter = {
|
|
32
32
|
dumpStructure: 'Dumping structure.',
|
|
33
33
|
dumpData: 'Dumping data.',
|
|
34
34
|
dumpPrivileges: 'Dumping privileges.',
|
|
@@ -128,5 +128,4 @@ class Dump extends Command {
|
|
|
128
128
|
module.exports = Dump;
|
|
129
129
|
|
|
130
130
|
if (require.main === module)
|
|
131
|
-
new Myt().
|
|
132
|
-
|
|
131
|
+
new Myt().cli(Dump);
|
package/myt-fixtures.js
CHANGED
package/myt-init.js
CHANGED
package/myt-pull.js
CHANGED
|
@@ -32,6 +32,13 @@ class Pull extends Command {
|
|
|
32
32
|
]
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
static reporter = {
|
|
36
|
+
creatingBranch: function(branchName) {
|
|
37
|
+
console.log(`Creating branch '${branchName}' from database commit.`);
|
|
38
|
+
},
|
|
39
|
+
routineChanges: 'Incorporating routine changes.'
|
|
40
|
+
};
|
|
41
|
+
|
|
35
42
|
async run(myt, opts) {
|
|
36
43
|
const conn = await myt.dbConnect();
|
|
37
44
|
const repo = await myt.openRepo();
|
|
@@ -73,7 +80,7 @@ class Pull extends Command {
|
|
|
73
80
|
if (version && version.gitCommit) {
|
|
74
81
|
const now = parseInt(new Date().toJSON());
|
|
75
82
|
const branchName = `myt-pull_${now}`;
|
|
76
|
-
|
|
83
|
+
this.emit('creatingBranch', branchName);
|
|
77
84
|
const commit = await repo.getCommit(version.gitCommit);
|
|
78
85
|
const branch = await nodegit.Branch.create(repo,
|
|
79
86
|
`myt-pull_${now}`, commit, () => {});
|
|
@@ -83,7 +90,7 @@ class Pull extends Command {
|
|
|
83
90
|
|
|
84
91
|
// Export routines to SQL files
|
|
85
92
|
|
|
86
|
-
|
|
93
|
+
this.emit('routineChanges', branchName);
|
|
87
94
|
|
|
88
95
|
const engine = new ExporterEngine(conn, opts);
|
|
89
96
|
await engine.init();
|
|
@@ -180,4 +187,4 @@ class Pull extends Command {
|
|
|
180
187
|
module.exports = Pull;
|
|
181
188
|
|
|
182
189
|
if (require.main === module)
|
|
183
|
-
new Myt().
|
|
190
|
+
new Myt().cli(Pull);
|
package/myt-push.js
CHANGED
|
@@ -37,6 +37,95 @@ class Push extends Command {
|
|
|
37
37
|
]
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
static reporter = {
|
|
41
|
+
applyingVersions: 'Applying versions.',
|
|
42
|
+
applyingRoutines: 'Applying changed routines.',
|
|
43
|
+
dbInfo: function(version) {
|
|
44
|
+
console.log(
|
|
45
|
+
`Database information:`
|
|
46
|
+
+ `\n -> Version: ${version.number}`
|
|
47
|
+
+ `\n -> Commit: ${version.gitCommit}`
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
version(version, error) {
|
|
51
|
+
let actionMsg;
|
|
52
|
+
let number, color;
|
|
53
|
+
|
|
54
|
+
if (!error) {
|
|
55
|
+
actionMsg = version.apply
|
|
56
|
+
? '[A]'.green
|
|
57
|
+
: '[I]'.blue;
|
|
58
|
+
number = version.number;
|
|
59
|
+
color = 'cyan';
|
|
60
|
+
} else {
|
|
61
|
+
actionMsg = '[W]'.yellow;
|
|
62
|
+
switch(action) {
|
|
63
|
+
case 'badVersion':
|
|
64
|
+
number = '?????';
|
|
65
|
+
color = 'yellow';
|
|
66
|
+
break;
|
|
67
|
+
case 'wrongDirectory':
|
|
68
|
+
number = '*****';
|
|
69
|
+
color = 'gray';
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const numberMsg = `[${number}]`[color];
|
|
75
|
+
console.log('', `${actionMsg}${numberMsg}`.bold, version.name);
|
|
76
|
+
},
|
|
77
|
+
logScript(script) {
|
|
78
|
+
let actionMsg;
|
|
79
|
+
if (script.apply)
|
|
80
|
+
actionMsg = '[+]'.green;
|
|
81
|
+
else if (!script.matchRegex)
|
|
82
|
+
actionMsg = '[W]'.yellow;
|
|
83
|
+
else
|
|
84
|
+
actionMsg = '[I]'.blue;
|
|
85
|
+
|
|
86
|
+
console.log(' ', actionMsg.bold, script.file);
|
|
87
|
+
},
|
|
88
|
+
change(status, ignore, change) {
|
|
89
|
+
let actionMsg;
|
|
90
|
+
if (ignore)
|
|
91
|
+
actionMsg = '[I]'.blue;
|
|
92
|
+
else
|
|
93
|
+
actionMsg = '[A]'.green;
|
|
94
|
+
|
|
95
|
+
let statusMsg;
|
|
96
|
+
switch(status) {
|
|
97
|
+
case 'added':
|
|
98
|
+
statusMsg = '[+]'.green;
|
|
99
|
+
break;
|
|
100
|
+
case 'deleted':
|
|
101
|
+
statusMsg = '[-]'.red;
|
|
102
|
+
break;
|
|
103
|
+
case 'modified':
|
|
104
|
+
statusMsg = '[·]'.yellow;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const typeMsg = `[${change.type.abbr}]`[change.type.color];
|
|
109
|
+
console.log('',
|
|
110
|
+
(actionMsg + statusMsg).bold,
|
|
111
|
+
typeMsg.bold,
|
|
112
|
+
change.fullName
|
|
113
|
+
);
|
|
114
|
+
},
|
|
115
|
+
versionsApplied: function(nVersions, nChanges) {
|
|
116
|
+
if (nVersions) {
|
|
117
|
+
console.log(` -> ${nVersions} versions with ${nChanges} changes applied.`);
|
|
118
|
+
} else
|
|
119
|
+
console.log(` -> No versions applied.`);
|
|
120
|
+
},
|
|
121
|
+
routinesApplied: function(nRoutines) {
|
|
122
|
+
if (nRoutines) {
|
|
123
|
+
console.log(` -> ${nRoutines} routines changed.`);
|
|
124
|
+
} else
|
|
125
|
+
console.log(` -> No routines changed.`);
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
40
129
|
async run(myt, opts) {
|
|
41
130
|
const conn = await myt.dbConnect();
|
|
42
131
|
this.conn = conn;
|
|
@@ -85,24 +174,7 @@ class Push extends Command {
|
|
|
85
174
|
await releaseLock();
|
|
86
175
|
}
|
|
87
176
|
|
|
88
|
-
async
|
|
89
|
-
const pushConn = await myt.createConnection();
|
|
90
|
-
|
|
91
|
-
// Get database version
|
|
92
|
-
|
|
93
|
-
const dbVersion = await myt.fetchDbVersion() || {};
|
|
94
|
-
|
|
95
|
-
console.log(
|
|
96
|
-
`Database information:`
|
|
97
|
-
+ `\n -> Version: ${dbVersion.number}`
|
|
98
|
-
+ `\n -> Commit: ${dbVersion.gitCommit}`
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
if (!dbVersion.number)
|
|
102
|
-
dbVersion.number = String('0').padStart(opts.versionDigits, '0');
|
|
103
|
-
if (!/^[0-9]*$/.test(dbVersion.number))
|
|
104
|
-
throw new Error('Wrong database version');
|
|
105
|
-
|
|
177
|
+
async cli(myt, opts) {
|
|
106
178
|
// Prevent push to production by mistake
|
|
107
179
|
|
|
108
180
|
if (opts.remote == 'production') {
|
|
@@ -134,33 +206,31 @@ class Push extends Command {
|
|
|
134
206
|
}
|
|
135
207
|
}
|
|
136
208
|
|
|
209
|
+
await super.cli(myt, opts);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async push(myt, opts, conn) {
|
|
213
|
+
const pushConn = await myt.createConnection();
|
|
214
|
+
|
|
215
|
+
// Get database version
|
|
216
|
+
|
|
217
|
+
const dbVersion = await myt.fetchDbVersion() || {};
|
|
218
|
+
this.emit('dbInfo', dbVersion);
|
|
219
|
+
|
|
220
|
+
if (!dbVersion.number)
|
|
221
|
+
dbVersion.number = String('0').padStart(opts.versionDigits, '0');
|
|
222
|
+
if (!/^[0-9]*$/.test(dbVersion.number))
|
|
223
|
+
throw new Error('Wrong database version');
|
|
224
|
+
|
|
137
225
|
// Apply versions
|
|
138
226
|
|
|
139
|
-
|
|
227
|
+
this.emit('applyingVersions');
|
|
140
228
|
|
|
229
|
+
let nVersions = 0;
|
|
141
230
|
let nChanges = 0;
|
|
142
|
-
let
|
|
231
|
+
let showLog = false;
|
|
143
232
|
const versionsDir = opts.versionsDir;
|
|
144
233
|
|
|
145
|
-
function logVersion(version, name, action, error) {
|
|
146
|
-
let actionMsg;
|
|
147
|
-
switch(action) {
|
|
148
|
-
case 'apply':
|
|
149
|
-
actionMsg = '[A]'.green;
|
|
150
|
-
break;
|
|
151
|
-
case 'ignore':
|
|
152
|
-
actionMsg = '[I]'.blue;
|
|
153
|
-
break;
|
|
154
|
-
default:
|
|
155
|
-
actionMsg = '[W]'.yellow;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
console.log('', (actionMsg + version).bold, name);
|
|
159
|
-
}
|
|
160
|
-
function logScript(type, message, error) {
|
|
161
|
-
console.log(' ', type.bold, message);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
234
|
const skipFiles = new Set([
|
|
165
235
|
'README.md',
|
|
166
236
|
'.archive'
|
|
@@ -172,45 +242,27 @@ class Push extends Command {
|
|
|
172
242
|
if (skipFiles.has(versionDir)) continue;
|
|
173
243
|
const version = await myt.loadVersion(versionDir);
|
|
174
244
|
|
|
175
|
-
|
|
176
|
-
logVersion('[?????]'.yellow, versionDir, 'warn',
|
|
177
|
-
`Wrong directory name.`
|
|
178
|
-
);
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (version.number.length != dbVersion.number.length) {
|
|
182
|
-
logVersion('[*****]'.gray, versionDir, 'warn'
|
|
183
|
-
`Bad version length, should have ${dbVersion.number.length} characters.`
|
|
184
|
-
);
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const {apply} = version;
|
|
189
|
-
if (apply) silent = false;
|
|
190
|
-
if (silent) continue;
|
|
245
|
+
let apply = false;
|
|
191
246
|
|
|
192
|
-
|
|
193
|
-
|
|
247
|
+
if (!version)
|
|
248
|
+
this.emit('version', version, 'wrongDirectory');
|
|
249
|
+
else if (version.number.length != dbVersion.number.length)
|
|
250
|
+
this.emit('version', version, 'badVersion');
|
|
251
|
+
else
|
|
252
|
+
apply = version.apply;
|
|
194
253
|
|
|
254
|
+
if (apply) showLog = true;
|
|
255
|
+
if (showLog) this.emit('version', version);
|
|
195
256
|
if (!apply) continue;
|
|
196
257
|
|
|
197
258
|
for (const script of version.scripts) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (!script.matchRegex) {
|
|
201
|
-
logScript('[W]'.yellow, scriptFile, `Wrong file name.`);
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const actionMsg = script.apply ? '[+]'.green : '[I]'.blue;
|
|
206
|
-
logScript(actionMsg, scriptFile);
|
|
207
|
-
|
|
259
|
+
this.emit('logScript', script);
|
|
208
260
|
if (!script.apply) continue;
|
|
209
261
|
|
|
210
262
|
let err;
|
|
211
263
|
try {
|
|
212
264
|
await connExt.queryFromFile(pushConn,
|
|
213
|
-
`${versionsDir}/${versionDir}/${
|
|
265
|
+
`${versionsDir}/${versionDir}/${script.file}`);
|
|
214
266
|
} catch (e) {
|
|
215
267
|
err = e;
|
|
216
268
|
}
|
|
@@ -232,7 +284,7 @@ class Push extends Command {
|
|
|
232
284
|
[
|
|
233
285
|
opts.code,
|
|
234
286
|
version.number,
|
|
235
|
-
|
|
287
|
+
script.file,
|
|
236
288
|
err && err.errno,
|
|
237
289
|
err && err.message
|
|
238
290
|
]
|
|
@@ -243,14 +295,15 @@ class Push extends Command {
|
|
|
243
295
|
}
|
|
244
296
|
|
|
245
297
|
await this.updateVersion('number', version.number);
|
|
298
|
+
nVersions++;
|
|
246
299
|
}
|
|
247
300
|
}
|
|
248
301
|
|
|
302
|
+
this.emit('versionsApplied', nVersions, nChanges);
|
|
303
|
+
|
|
249
304
|
// Apply routines
|
|
250
305
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const gitExists = await fs.pathExists(`${opts.workspace}/.git`);
|
|
306
|
+
this.emit('applyingRoutines');
|
|
254
307
|
|
|
255
308
|
let nRoutines = 0;
|
|
256
309
|
const changes = await this.changedRoutines(dbVersion.gitCommit);
|
|
@@ -314,26 +367,15 @@ class Push extends Command {
|
|
|
314
367
|
&& opts.mockFunctions.indexOf(name) !== -1;
|
|
315
368
|
const ignore = newSql == oldSql || isMockFn;
|
|
316
369
|
|
|
317
|
-
let
|
|
370
|
+
let status;
|
|
318
371
|
if (exists && !oldSql)
|
|
319
|
-
|
|
372
|
+
status = 'added';
|
|
320
373
|
else if (!exists)
|
|
321
|
-
|
|
322
|
-
else
|
|
323
|
-
statusMsg = '[·]'.yellow;
|
|
324
|
-
|
|
325
|
-
let actionMsg;
|
|
326
|
-
if (ignore)
|
|
327
|
-
actionMsg = '[I]'.blue;
|
|
374
|
+
status = 'deleted';
|
|
328
375
|
else
|
|
329
|
-
|
|
376
|
+
status = 'modified';
|
|
330
377
|
|
|
331
|
-
|
|
332
|
-
console.log('',
|
|
333
|
-
(actionMsg + statusMsg).bold,
|
|
334
|
-
typeMsg.bold,
|
|
335
|
-
change.fullName
|
|
336
|
-
);
|
|
378
|
+
this.emit('change', status, ignore, change);
|
|
337
379
|
|
|
338
380
|
if (!ignore) {
|
|
339
381
|
const scapedSchema = SqlString.escapeId(schema, true);
|
|
@@ -381,11 +423,9 @@ class Push extends Command {
|
|
|
381
423
|
|
|
382
424
|
await finalize();
|
|
383
425
|
|
|
384
|
-
|
|
385
|
-
console.log(` -> ${nRoutines} routines have changed.`);
|
|
386
|
-
} else
|
|
387
|
-
console.log(` -> No routines changed.`);
|
|
426
|
+
this.emit('routinesApplied', nRoutines);
|
|
388
427
|
|
|
428
|
+
const gitExists = await fs.pathExists(`${opts.workspace}/.git`);
|
|
389
429
|
if (gitExists && opts.commit) {
|
|
390
430
|
const repo = await nodegit.Repository.open(this.opts.workspace);
|
|
391
431
|
const head = await repo.getHeadCommit();
|
|
@@ -552,4 +592,4 @@ class Routine {
|
|
|
552
592
|
module.exports = Push;
|
|
553
593
|
|
|
554
594
|
if (require.main === module)
|
|
555
|
-
new Myt().
|
|
595
|
+
new Myt().cli(Push);
|
package/myt-run.js
CHANGED
|
@@ -10,7 +10,7 @@ const SqlString = require('sqlstring');
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Builds the database image and runs a container. It only rebuilds the image
|
|
13
|
-
* when dump
|
|
13
|
+
* when dump have been modified. Some workarounds have been used to avoid a bug
|
|
14
14
|
* with OverlayFS driver on MacOS.
|
|
15
15
|
*/
|
|
16
16
|
class Run extends Command {
|
|
@@ -33,6 +33,15 @@ class Run extends Command {
|
|
|
33
33
|
]
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
static reporter = {
|
|
37
|
+
buildingImage: 'Building container image.',
|
|
38
|
+
runningContainer: 'Running container.',
|
|
39
|
+
waitingDb: 'Waiting for MySQL init process.',
|
|
40
|
+
mockingDate: 'Mocking date functions.',
|
|
41
|
+
applyingFixtures: 'Applying fixtures.',
|
|
42
|
+
creatingTriggers: 'Creating triggers.'
|
|
43
|
+
};
|
|
44
|
+
|
|
36
45
|
async run(myt, opts) {
|
|
37
46
|
const dumpDir = opts.dumpDir;
|
|
38
47
|
const dumpDataDir = path.join(dumpDir, '.dump');
|
|
@@ -43,6 +52,8 @@ class Run extends Command {
|
|
|
43
52
|
|
|
44
53
|
// Build base image
|
|
45
54
|
|
|
55
|
+
this.emit('buildingImage');
|
|
56
|
+
|
|
46
57
|
let basePath = dumpDir;
|
|
47
58
|
let baseDockerfile = path.join(dumpDir, 'Dockerfile');
|
|
48
59
|
|
|
@@ -73,8 +84,10 @@ class Run extends Command {
|
|
|
73
84
|
|
|
74
85
|
// Run container
|
|
75
86
|
|
|
87
|
+
this.emit('runningContainer');
|
|
88
|
+
|
|
76
89
|
const isRandom = opts.random;
|
|
77
|
-
const dbConfig =
|
|
90
|
+
const dbConfig = opts.dbConfig;
|
|
78
91
|
|
|
79
92
|
let runOptions;
|
|
80
93
|
|
|
@@ -117,12 +130,13 @@ class Run extends Command {
|
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
|
|
133
|
+
this.emit('waitingDb');
|
|
120
134
|
await server.wait();
|
|
121
135
|
const conn = await myt.createConnection();
|
|
122
136
|
|
|
123
137
|
// Mock date functions
|
|
124
138
|
|
|
125
|
-
|
|
139
|
+
this.emit('mockingDate');
|
|
126
140
|
const mockDateScript = path.join(dumpDir, 'mockDate.sql');
|
|
127
141
|
|
|
128
142
|
if (opts.mockDate) {
|
|
@@ -143,11 +157,11 @@ class Run extends Command {
|
|
|
143
157
|
commit: true,
|
|
144
158
|
dbConfig
|
|
145
159
|
});
|
|
146
|
-
await myt.
|
|
160
|
+
await myt.run(Push, opts);
|
|
147
161
|
|
|
148
162
|
// Apply fixtures
|
|
149
163
|
|
|
150
|
-
|
|
164
|
+
this.emit('applyingFixtures');
|
|
151
165
|
const fixturesFiles = [
|
|
152
166
|
'fixtures.before',
|
|
153
167
|
'.fixtures',
|
|
@@ -166,7 +180,7 @@ class Run extends Command {
|
|
|
166
180
|
// Create triggers
|
|
167
181
|
|
|
168
182
|
if (!hasTriggers) {
|
|
169
|
-
|
|
183
|
+
this.emit('creatingTriggers');
|
|
170
184
|
|
|
171
185
|
for (const schema of opts.schemas) {
|
|
172
186
|
const triggersPath = `${opts.routinesDir}/${schema}/triggers`;
|
|
@@ -179,6 +193,7 @@ class Run extends Command {
|
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
195
|
|
|
196
|
+
await conn.end();
|
|
182
197
|
return server;
|
|
183
198
|
}
|
|
184
199
|
}
|
|
@@ -186,4 +201,4 @@ class Run extends Command {
|
|
|
186
201
|
module.exports = Run;
|
|
187
202
|
|
|
188
203
|
if (require.main === module)
|
|
189
|
-
new Myt().
|
|
204
|
+
new Myt().cli(Run);
|
package/myt-start.js
CHANGED
|
@@ -15,6 +15,10 @@ class Start extends Command {
|
|
|
15
15
|
description: 'Start local database server container'
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
static reporter = {
|
|
19
|
+
startingContainer: 'Starting container.'
|
|
20
|
+
};
|
|
21
|
+
|
|
18
22
|
async run(myt, opts) {
|
|
19
23
|
const ct = new Container(opts.code);
|
|
20
24
|
let status;
|
|
@@ -27,7 +31,7 @@ class Start extends Command {
|
|
|
27
31
|
});
|
|
28
32
|
exists = true;
|
|
29
33
|
} catch (err) {
|
|
30
|
-
server = await myt.
|
|
34
|
+
server = await myt.run(Run, opts);
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
if (exists) {
|
|
@@ -35,6 +39,7 @@ class Start extends Command {
|
|
|
35
39
|
case 'running':
|
|
36
40
|
break;
|
|
37
41
|
case 'exited':
|
|
42
|
+
this.emit('startingContainer');
|
|
38
43
|
await ct.start();
|
|
39
44
|
server = new Server(ct, opts.dbConfig);
|
|
40
45
|
await server.wait();
|
|
@@ -51,4 +56,4 @@ class Start extends Command {
|
|
|
51
56
|
module.exports = Start;
|
|
52
57
|
|
|
53
58
|
if (require.main === module)
|
|
54
|
-
new Myt().
|
|
59
|
+
new Myt().cli(Start);
|
package/myt-version.js
CHANGED
|
@@ -26,6 +26,19 @@ class Version extends Command {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
static reporter = {
|
|
30
|
+
dbInfo: function(number, lastNumber) {
|
|
31
|
+
console.log(
|
|
32
|
+
`Database information:`
|
|
33
|
+
+ `\n -> Version: ${number}`
|
|
34
|
+
+ `\n -> Last version: ${lastNumber}`
|
|
35
|
+
);
|
|
36
|
+
},
|
|
37
|
+
versionCreated: function(versionName) {
|
|
38
|
+
console.log(`New version created: ${versionName}`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
29
42
|
async run(myt, opts) {
|
|
30
43
|
let newVersionDir;
|
|
31
44
|
|
|
@@ -45,12 +58,7 @@ class Version extends Command {
|
|
|
45
58
|
);
|
|
46
59
|
const number = row && row.number;
|
|
47
60
|
const lastNumber = row && row.lastNumber;
|
|
48
|
-
|
|
49
|
-
console.log(
|
|
50
|
-
`Database information:`
|
|
51
|
-
+ `\n -> Version: ${number}`
|
|
52
|
-
+ `\n -> Last version: ${lastNumber}`
|
|
53
|
-
);
|
|
61
|
+
this.emit('dbInfo', number, lastNumber);
|
|
54
62
|
|
|
55
63
|
let newVersion;
|
|
56
64
|
if (lastNumber)
|
|
@@ -117,7 +125,7 @@ class Version extends Command {
|
|
|
117
125
|
`${newVersionDir}/00-firstScript.sql`,
|
|
118
126
|
'-- Place your SQL code here\n'
|
|
119
127
|
);
|
|
120
|
-
|
|
128
|
+
this.emit('versionCreated', versionFolder);
|
|
121
129
|
|
|
122
130
|
await conn.query('COMMIT');
|
|
123
131
|
} catch (err) {
|
|
@@ -215,4 +223,4 @@ const plants = [
|
|
|
215
223
|
module.exports = Version;
|
|
216
224
|
|
|
217
225
|
if (require.main === module)
|
|
218
|
-
new Myt().
|
|
226
|
+
new Myt().cli(Version);
|
package/myt.js
CHANGED
|
@@ -40,7 +40,9 @@ class Myt {
|
|
|
40
40
|
]
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
async
|
|
43
|
+
async cli(Command) {
|
|
44
|
+
this.cliMode = true;
|
|
45
|
+
|
|
44
46
|
console.log(
|
|
45
47
|
'Myt'.green,
|
|
46
48
|
`v${packageJson.version}`.magenta
|
|
@@ -144,9 +146,9 @@ class Myt {
|
|
|
144
146
|
parameter('Workspace:', opts.workspace);
|
|
145
147
|
parameter('Remote:', opts.remote || 'local');
|
|
146
148
|
|
|
147
|
-
await this.
|
|
148
|
-
await this.
|
|
149
|
-
await this.
|
|
149
|
+
await this.init(opts);
|
|
150
|
+
await this.run(Command, opts);
|
|
151
|
+
await this.deinit();
|
|
150
152
|
} catch (err) {
|
|
151
153
|
if (err.name == 'Error' && !opts.debug) {
|
|
152
154
|
console.error('Error:'.gray, err.message.red);
|
|
@@ -164,12 +166,16 @@ class Myt {
|
|
|
164
166
|
process.exit();
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
async
|
|
169
|
+
async run(Command, opts) {
|
|
170
|
+
if (!opts) opts = this.opts;
|
|
168
171
|
const command = new Command(this, opts);
|
|
169
|
-
|
|
172
|
+
if (this.cliMode)
|
|
173
|
+
return await command.cli(this, opts);
|
|
174
|
+
else
|
|
175
|
+
return await command.run(this, opts);
|
|
170
176
|
}
|
|
171
177
|
|
|
172
|
-
async
|
|
178
|
+
async init(opts) {
|
|
173
179
|
// Configuration file
|
|
174
180
|
|
|
175
181
|
const defaultConfig = require(`${__dirname}/assets/myt.default.yml`);
|
|
@@ -265,7 +271,7 @@ class Myt {
|
|
|
265
271
|
this.opts = opts;
|
|
266
272
|
}
|
|
267
273
|
|
|
268
|
-
async
|
|
274
|
+
async deinit() {
|
|
269
275
|
if (this.conn)
|
|
270
276
|
await this.conn.end();
|
|
271
277
|
}
|
|
@@ -434,4 +440,4 @@ class Myt {
|
|
|
434
440
|
module.exports = Myt;
|
|
435
441
|
|
|
436
442
|
if (require.main === module)
|
|
437
|
-
new Myt().
|
|
443
|
+
new Myt().cli();
|