2020-11-14 01:38:56 +00:00
|
|
|
|
2020-11-14 14:53:13 +00:00
|
|
|
require('colors');
|
2020-11-14 01:38:56 +00:00
|
|
|
const getopts = require('getopts');
|
|
|
|
const package = require('./package.json');
|
2020-11-14 14:53:13 +00:00
|
|
|
const fs = require('fs-extra');
|
2020-11-15 18:24:25 +00:00
|
|
|
const ini = require('ini');
|
2020-11-16 13:23:28 +00:00
|
|
|
const path = require('path');
|
|
|
|
const dockerRun = require('./docker-run');
|
2020-11-14 14:53:13 +00:00
|
|
|
|
2020-11-15 18:24:25 +00:00
|
|
|
console.log('MyVC (MySQL Version Control)'.green, `v${package.version}`.magenta);
|
2020-11-14 01:38:56 +00:00
|
|
|
|
2020-11-15 18:24:25 +00:00
|
|
|
const argv = process.argv.slice(2);
|
2020-11-16 13:23:28 +00:00
|
|
|
const cliOpts = getopts(argv, {
|
2020-11-14 01:38:56 +00:00
|
|
|
alias: {
|
|
|
|
env: 'e',
|
2020-11-17 10:53:31 +00:00
|
|
|
workspace: 'w',
|
2020-11-14 14:53:13 +00:00
|
|
|
help: 'h',
|
|
|
|
version: 'v'
|
2020-11-14 01:38:56 +00:00
|
|
|
},
|
2020-11-15 18:24:25 +00:00
|
|
|
default: {
|
2020-11-17 10:53:31 +00:00
|
|
|
workspace: process.cwd(),
|
2020-11-15 18:24:25 +00:00
|
|
|
env: 'production'
|
|
|
|
}
|
2020-11-14 01:38:56 +00:00
|
|
|
})
|
|
|
|
|
2020-11-16 13:23:28 +00:00
|
|
|
if (cliOpts.version)
|
2020-11-15 18:24:25 +00:00
|
|
|
process.exit(0);
|
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
const command = cliOpts._[0];
|
|
|
|
if (!command) {
|
|
|
|
console.log('Usage:'.gray, '[npx] myvc [-w|--workspace] [-e|--env] [-h|--help] command'.blue);
|
2020-11-14 14:53:13 +00:00
|
|
|
process.exit(0);
|
2020-11-14 01:38:56 +00:00
|
|
|
}
|
2020-11-15 18:24:25 +00:00
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
const commandArgs = {
|
|
|
|
push: {
|
2020-11-15 18:24:25 +00:00
|
|
|
alias: {
|
2020-11-17 17:15:09 +00:00
|
|
|
env: 'e',
|
2020-11-15 18:24:25 +00:00
|
|
|
force: 'f',
|
2020-11-17 17:15:09 +00:00
|
|
|
user: 'u',
|
|
|
|
applyUncommited: 'a'
|
2020-11-15 18:24:25 +00:00
|
|
|
},
|
|
|
|
default: {
|
|
|
|
env: 'test'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2020-11-17 10:53:31 +00:00
|
|
|
const commandOpts = getopts(argv, commandArgs[command]);
|
|
|
|
Object.assign(cliOpts, commandOpts);
|
2020-11-16 13:23:28 +00:00
|
|
|
|
|
|
|
const opts = {};
|
|
|
|
for (let opt in cliOpts) {
|
|
|
|
if (opt.length > 1 || opt == '_')
|
|
|
|
opts[opt] = cliOpts[opt];
|
|
|
|
}
|
|
|
|
|
|
|
|
function parameter(parameter, value) {
|
|
|
|
console.log(parameter.gray, value.blue);
|
|
|
|
}
|
2020-11-15 18:24:25 +00:00
|
|
|
|
|
|
|
parameter('Environment:', opts.env);
|
2020-11-17 10:53:31 +00:00
|
|
|
parameter('Workspace:', opts.workspace);
|
|
|
|
parameter('Command:', command);
|
2020-11-14 01:38:56 +00:00
|
|
|
|
2020-11-16 13:23:28 +00:00
|
|
|
class MyVC {
|
2020-11-19 12:51:27 +00:00
|
|
|
async load(opts) {
|
2020-11-16 13:23:28 +00:00
|
|
|
// Configuration file
|
|
|
|
|
|
|
|
const configFile = 'myvc.config.json';
|
2020-11-17 10:53:31 +00:00
|
|
|
const configPath = path.join(opts.workspace, configFile);
|
2020-11-16 13:23:28 +00:00
|
|
|
if (!await fs.pathExists(configPath))
|
|
|
|
throw new Error(`Config file not found: ${configFile}`);
|
|
|
|
const config = require(configPath);
|
|
|
|
|
|
|
|
Object.assign(opts, config);
|
|
|
|
opts.configFile = configFile;
|
|
|
|
|
|
|
|
// Database configuration
|
|
|
|
|
|
|
|
let iniFile = 'db.ini';
|
|
|
|
let iniDir = __dirname;
|
|
|
|
if (opts.env) {
|
2020-11-19 12:51:27 +00:00
|
|
|
iniFile = `remotes/${opts.env}.ini`;
|
2020-11-17 10:53:31 +00:00
|
|
|
iniDir = opts.workspace;
|
2020-11-16 13:23:28 +00:00
|
|
|
}
|
|
|
|
const iniPath = path.join(iniDir, iniFile);
|
|
|
|
|
|
|
|
if (!await fs.pathExists(iniPath))
|
|
|
|
throw new Error(`Database config file not found: ${iniFile}`);
|
|
|
|
|
|
|
|
const iniConfig = ini.parse(await fs.readFile(iniPath, 'utf8')).client;
|
|
|
|
const dbConfig = {
|
|
|
|
host: !opts.env ? 'localhost' : iniConfig.host,
|
|
|
|
port: iniConfig.port,
|
|
|
|
user: iniConfig.user,
|
|
|
|
password: iniConfig.password,
|
|
|
|
authPlugins: {
|
|
|
|
mysql_clear_password() {
|
|
|
|
return () => iniConfig.password + '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if (iniConfig.ssl_ca) {
|
|
|
|
dbConfig.ssl = {
|
2020-11-17 10:53:31 +00:00
|
|
|
ca: await fs.readFile(`${opts.workspace}/${iniConfig.ssl_ca}`),
|
2020-11-16 13:23:28 +00:00
|
|
|
rejectUnauthorized: iniConfig.ssl_verify_server_cert != undefined
|
|
|
|
}
|
|
|
|
}
|
2020-11-14 14:53:13 +00:00
|
|
|
|
2020-11-16 13:23:28 +00:00
|
|
|
Object.assign(opts, {
|
|
|
|
iniFile,
|
|
|
|
dbConfig
|
|
|
|
});
|
|
|
|
}
|
2020-11-14 14:53:13 +00:00
|
|
|
|
2020-11-19 12:51:27 +00:00
|
|
|
async init(opts) {
|
|
|
|
const templateDir = `${__dirname}/workspace`;
|
|
|
|
const templates = await fs.readdir(templateDir);
|
|
|
|
for (let template of templates){
|
|
|
|
const dst = `${opts.workspace}/${template}`;
|
|
|
|
if (!await fs.pathExists(dst))
|
|
|
|
await fs.copy(`${templateDir}/${template}`, dst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
async pull(opts) {
|
|
|
|
const pull = require('./myvc-pull');
|
|
|
|
await pull(
|
|
|
|
opts.workspace,
|
2020-11-16 13:23:28 +00:00
|
|
|
opts.schemas,
|
|
|
|
opts.dbConfig
|
|
|
|
);
|
2020-11-15 18:24:25 +00:00
|
|
|
}
|
2020-11-14 01:38:56 +00:00
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
async push(opts) {
|
2020-11-16 13:23:28 +00:00
|
|
|
let args = [];
|
|
|
|
if (opts.force) args.push('-f');
|
|
|
|
if (opts.user) args.push('-u');
|
2020-11-17 17:15:09 +00:00
|
|
|
if (opts.applyUncommited) args.push('-a');
|
2020-11-16 13:23:28 +00:00
|
|
|
if (opts.env) args = args.concat(['-e', opts.env]);
|
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
await dockerRun('myvc-push.sh',
|
|
|
|
opts.workspace,
|
2020-11-16 13:23:28 +00:00
|
|
|
...args
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-11-17 10:53:31 +00:00
|
|
|
async dump (opts) {
|
|
|
|
await dockerRun('myvc-dump.sh',
|
|
|
|
opts.workspace,
|
|
|
|
opts.configFile,
|
|
|
|
opts.iniFile
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-11-16 13:23:28 +00:00
|
|
|
async run(opts) {
|
2020-11-14 14:53:13 +00:00
|
|
|
const Docker = require('./docker');
|
2020-11-17 10:53:31 +00:00
|
|
|
const container = new Docker(opts.code, opts.workspace);
|
2020-11-16 13:23:28 +00:00
|
|
|
await container.run();
|
2020-11-14 14:53:13 +00:00
|
|
|
}
|
2020-11-16 13:23:28 +00:00
|
|
|
|
|
|
|
async start(opts) {
|
2020-11-14 14:53:13 +00:00
|
|
|
const Docker = require('./docker');
|
2020-11-17 10:53:31 +00:00
|
|
|
const container = new Docker(opts.code, opts.workspace);
|
2020-11-16 13:23:28 +00:00
|
|
|
await container.start();
|
2020-11-14 14:53:13 +00:00
|
|
|
}
|
2020-11-14 01:38:56 +00:00
|
|
|
}
|
2020-11-16 13:23:28 +00:00
|
|
|
|
|
|
|
(async function() {
|
|
|
|
try {
|
|
|
|
const myvc = new MyVC();
|
|
|
|
|
2020-11-19 12:51:27 +00:00
|
|
|
if (command != 'load' && myvc[command]) {
|
|
|
|
await myvc.load(opts);
|
2020-11-17 10:53:31 +00:00
|
|
|
await myvc[command](opts);
|
2020-11-16 13:23:28 +00:00
|
|
|
} else
|
2020-11-17 10:53:31 +00:00
|
|
|
throw new Error (`Unknown command '${command}'`);
|
2020-11-16 13:23:28 +00:00
|
|
|
} catch (err) {
|
|
|
|
if (err.name == 'Error')
|
|
|
|
console.error('Error:'.gray, err.message.red);
|
|
|
|
else
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
})();
|
|
|
|
|
|
|
|
module.exports = MyVC;
|