Command and workspace structure refactor

This commit is contained in:
Juan Ferrer 2020-11-17 11:53:31 +01:00
parent 513862648d
commit 1b8da1f48f
12 changed files with 85 additions and 108 deletions

View File

@ -14,10 +14,9 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*
COPY \
export-fixtures.sh \
export-structure.sh \
apply-changes.sh \
myvc-dump.sh \
myvc-push.sh \
db.ini \
/usr/local/bin/
WORKDIR /workdir
WORKDIR /workspace

View File

@ -3,23 +3,22 @@ FROM myvc/server
USER root
COPY \
dump/structure.local.sql \
dump/structure.sql \
dump/fixtures.sql \
myvc.config.json \
myvc.structure.sql \
.dump.sql \
./
RUN gosu mysql docker-init.sh \
&& docker-dump.sh structure.local \
&& docker-dump.sh structure \
&& docker-dump.sh fixtures \
&& docker-dump.sh myvc.structure \
&& docker-dump.sh .dump \
&& gosu mysql docker-temp-stop.sh
COPY routines ./routines
COPY changes ./changes
COPY dump/fixtures.local.sql ./
COPY myvc.fixtures.sql ./
ARG STAMP=unknown
RUN gosu mysql docker-temp-start.sh \
&& apply-changes.sh \
&& docker-dump.sh fixtures.local \
&& myvc-push.sh \
&& docker-dump.sh myvc.fixtures \
&& gosu mysql docker-temp-stop.sh
RUN echo "[INFO] -> Import finished" \

View File

@ -20,7 +20,7 @@ COPY \
docker/docker-temp-stop.sh \
docker/docker-dump.sh \
docker/docker-start.sh \
apply-changes.sh \
myvc-push.sh \
/usr/local/bin/
RUN mkdir /mysql-data \

View File

@ -21,33 +21,33 @@ Required applications.
It's recommended to install the package globally.
```text
# npm install -g myvc
$ myvc [action]
$ myvc [command]
```
You can also install locally and use the *npx* command to execute it.
```text
$ npm install myvc
$ npx myvc [action]
$ npx myvc [command]
```
## How to use
Execute *myvc* with the desired action.
Execute *myvc* with the desired command.
```text
$ myvc [-w|--workdir] [-e|--env] [-h|--help] action
$ myvc [-w|--workspace] [-e|--env] [-h|--help] command
```
The default working directory is the current one and unless otherwise indicated,
the default environment is *production*.
Available actions are:
* **structure**: Export database structure.
* **fixtures**: Export database fixtures.
* **routines**: Export database routines.
* **apply**: Apply changes into database, uses *local* environment by default.
Available commands are:
* **pull**: Exports database routines into workspace.
* **push**: Apply changes into database, uses *test* environment by default.
* **dump**: Export database structure and fixtures.
* **run**: Builds and starts local database server container.
* **start**: Starts local database server container.
Each action can have its own specific commandline options.
Each command can have its own specific commandline options.
## Basic information
@ -56,8 +56,8 @@ includes the tables where MyVC stores information about applied versions.
Create *myvc.config.json* main configuration file at the root of your project
folder, this file should include the project codename and schemas/tables wich
are exported when you use *structure*, *fixtures* or *routines* actions. You
have an example of a configuration file in the root folder of this project.
are exported when you use *pull*or *dump* commands. You have an example of a
configuration file in the root folder of this project.
### Environments
@ -70,17 +70,11 @@ db.[environment].ini
### Dumps
Structure and fixture dumps will be created inside *dump* folder.
Structure and fixture dumps will be created into hidden file *.dump.sql*. You
can also create your local fixture and structure files.
* *structure.sql*
* *fixtures.sql*
### Local
You can also create your local fixture and structure files inside *dump* folder.
* *structure.local.sql*
* *fixtures.local.sql*
* *myvc.structure.sql*
* *myvc.fixtures.sql*
### Routines

View File

@ -3,7 +3,7 @@ const path = require('path');
const execFile = require('child_process').execFile;
const spawn = require('child_process').spawn;
module.exports = async function(command, workdir, ...args) {
module.exports = async function(command, workspace, ...args) {
const buildArgs = [
'build',
'-t', 'myvc/client',
@ -20,7 +20,7 @@ module.exports = async function(command, workdir, ...args) {
let runArgs = [
'run',
'-v', `${workdir}:/workdir`,
'-v', `${workspace}:/workspace`,
'myvc/client',
command
];

View File

@ -149,7 +149,7 @@ module.exports = class Docker {
}
if (elapsedTime >= maxInterval)
reject(new Error(`Container initialized whithin ${elapsedTime / 1000} secs`));
reject(new Error(`Container not initialized whithin ${elapsedTime / 1000} secs`));
else
setTimeout(bindedChecker, interval);
}

View File

@ -1,20 +0,0 @@
#!/bin/bash
set -e
CONFIG_FILE=$1
INI_FILE=$2
DUMP_FILE="dump/structure.sql"
echo "SELECT 1;" | mysql --defaults-file="$INI_FILE" >> /dev/null
SCHEMAS=( $(jq -r ".schemas[]" "$CONFIG_FILE") )
mysqldump \
--defaults-file="$INI_FILE" \
--default-character-set=utf8 \
--no-data \
--comments \
--triggers --routines --events \
--databases \
${SCHEMAS[@]} \
| sed 's/ AUTO_INCREMENT=[0-9]* //g' \
> "$DUMP_FILE"

View File

@ -13,12 +13,12 @@ const argv = process.argv.slice(2);
const cliOpts = getopts(argv, {
alias: {
env: 'e',
workdir: 'w',
workspace: 'w',
help: 'h',
version: 'v'
},
default: {
workdir: process.cwd(),
workspace: process.cwd(),
env: 'production'
}
})
@ -26,14 +26,14 @@ const cliOpts = getopts(argv, {
if (cliOpts.version)
process.exit(0);
const action = cliOpts._[0];
if (!action) {
console.log('Usage:'.gray, '[npx] myvc [-w|--workdir] [-e|--env] [-h|--help] action'.blue);
const command = cliOpts._[0];
if (!command) {
console.log('Usage:'.gray, '[npx] myvc [-w|--workspace] [-e|--env] [-h|--help] command'.blue);
process.exit(0);
}
const actionArgs = {
apply: {
const commandArgs = {
push: {
alias: {
force: 'f',
user: 'u'
@ -45,8 +45,8 @@ const actionArgs = {
}
}
};
const actionOpts = getopts(argv, actionArgs[action]);
Object.assign(cliOpts, actionOpts);
const commandOpts = getopts(argv, commandArgs[command]);
Object.assign(cliOpts, commandOpts);
const opts = {};
for (let opt in cliOpts) {
@ -59,15 +59,15 @@ function parameter(parameter, value) {
}
parameter('Environment:', opts.env);
parameter('Workdir:', opts.workdir);
parameter('Action:', action);
parameter('Workspace:', opts.workspace);
parameter('Command:', command);
class MyVC {
async init(opts) {
// Configuration file
const configFile = 'myvc.config.json';
const configPath = path.join(opts.workdir, configFile);
const configPath = path.join(opts.workspace, configFile);
if (!await fs.pathExists(configPath))
throw new Error(`Config file not found: ${configFile}`);
const config = require(configPath);
@ -81,7 +81,7 @@ class MyVC {
let iniDir = __dirname;
if (opts.env) {
iniFile = `db.${opts.env}.ini`;
iniDir = opts.workdir;
iniDir = opts.workspace;
}
const iniPath = path.join(iniDir, iniFile);
@ -103,7 +103,7 @@ class MyVC {
if (iniConfig.ssl_ca) {
dbConfig.ssl = {
ca: await fs.readFile(`${opts.workdir}/${iniConfig.ssl_ca}`),
ca: await fs.readFile(`${opts.workspace}/${iniConfig.ssl_ca}`),
rejectUnauthorized: iniConfig.ssl_verify_server_cert != undefined
}
}
@ -114,52 +114,44 @@ class MyVC {
});
}
async structure (opts) {
await dockerRun('export-structure.sh',
opts.workdir,
opts.configFile,
opts.iniFile
);
}
async fixtures(opts) {
await dockerRun('export-fixtures.sh',
opts.workdir,
opts.configFile,
opts.iniFile
);
}
async routines(opts) {
const exportRoutines = require('./export-routines');
await exportRoutines(
opts.workdir,
async pull(opts) {
const pull = require('./myvc-pull');
await pull(
opts.workspace,
opts.schemas,
opts.dbConfig
);
}
async apply(opts) {
async push(opts) {
let args = [];
if (opts.force) args.push('-f');
if (opts.user) args.push('-u');
if (opts.env) args = args.concat(['-e', opts.env]);
await dockerRun('apply-changes.sh',
opts.workdir,
await dockerRun('myvc-push.sh',
opts.workspace,
...args
);
}
async dump (opts) {
await dockerRun('myvc-dump.sh',
opts.workspace,
opts.configFile,
opts.iniFile
);
}
async run(opts) {
const Docker = require('./docker');
const container = new Docker(opts.code, opts.workdir);
const container = new Docker(opts.code, opts.workspace);
await container.run();
}
async start(opts) {
const Docker = require('./docker');
const container = new Docker(opts.code, opts.workdir);
const container = new Docker(opts.code, opts.workspace);
await container.start();
}
}
@ -168,11 +160,11 @@ class MyVC {
try {
const myvc = new MyVC();
if (myvc[action]) {
if (myvc[command]) {
await myvc.init(opts);
await myvc[action](opts);
await myvc[command](opts);
} else
throw new Error (`Unknown action '${action}'`);
throw new Error (`Unknown command '${command}'`);
} catch (err) {
if (err.name == 'Error')
console.error('Error:'.gray, err.message.red);

View File

@ -3,15 +3,25 @@ set -e
CONFIG_FILE=$1
INI_FILE=$2
DUMP_FILE="dump/fixtures.sql"
DUMP_FILE=".dump.sql"
echo "SELECT 1;" | mysql --defaults-file="$INI_FILE" >> /dev/null
echo "" > "$DUMP_FILE"
SCHEMAS=( $(jq -r ".schemas[]" "$CONFIG_FILE") )
mysqldump \
--defaults-file="$INI_FILE" \
--default-character-set=utf8 \
--no-data \
--comments \
--triggers --routines --events \
--databases \
${SCHEMAS[@]} \
| sed 's/ AUTO_INCREMENT=[0-9]* //g' \
> "$DUMP_FILE"
for SCHEMA in $(jq -r ".fixtures | keys[]" "$CONFIG_FILE"); do
TABLES=( $(jq -r ".fixtures.$SCHEMA[]" "$CONFIG_FILE") )
echo " -> $SCHEMA"
echo "USE \`$SCHEMA\`;" >> "$DUMP_FILE"
mysqldump \
--defaults-file="$INI_FILE" \

View File

@ -48,7 +48,7 @@ const exporters = [
// Exports objects for all schemas
module.exports = async function main(workdir, schemas, dbConf) {
module.exports = async function main(workspace, schemas, dbConf) {
const conn = await mysql.createConnection(dbConf);
conn.queryFromFile = function(file, params) {
return this.execute(
@ -58,7 +58,7 @@ module.exports = async function main(workdir, schemas, dbConf) {
}
try {
const exportDir = `${workdir}/routines`;
const exportDir = `${workspace}/routines`;
if (fs.existsSync(exportDir))
fs.removeSync(exportDir, {recursive: true});
fs.mkdirSync(exportDir);

View File

@ -1,10 +1,13 @@
{
"name": "myvc",
"version": "1.0.7",
"version": "1.0.9",
"author": "Verdnatura Levante SL",
"description": "MySQL Version Control",
"license": "GPL-3.0",
"bin": "myvc.js",
"bin": {
"myvc": "myvc.js",
"myvc-push": "myvc-push.sh"
},
"repository": {
"type": "git",
"url": "https://github.com/verdnatura/myvc.git"