Skip to content

Commit

Permalink
Merge pull request #6 from Come2Daddy/feat/cli-debug-option
Browse files Browse the repository at this point in the history
feat: adds cli debug option
  • Loading branch information
Come2Daddy authored Dec 17, 2020
2 parents e12222c + e68f5b1 commit 1a93d86
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 35 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Either use environment variables
UPMIG_PATH=./migrations
UPMIG_TABLE=pg_upmig
UPMIG_REJECT=false
UPMIG_DEBUG=false
```
or use `.upmigrc.js` to set global options:
```javascript
Expand All @@ -48,7 +49,8 @@ try {
module.exports = {
migrations: "./migrations", // Where to store migrations files
table: "pg_upmig", // Table name where migrations history is stored
reject: false
reject: false,
debug: false
};
```
## Migrations folder tree view
Expand Down Expand Up @@ -89,6 +91,7 @@ Options:
-m, --migrations <path> specify migrations path (default: "./migrations")
-p, --pgtable <table> specify migration table name (default: "pg_upmig")
-r, --reject dont ignore unauthorized ssl rejection
-d, --debug print debug informations

Commands:
up [options] perform all pending migrations
Expand Down Expand Up @@ -312,4 +315,4 @@ Returns an array of objects representing migration file:
|name|string|Migration name excluding timestamp.|
## Todo
- [ ] Custom logger implementation
- [ ] Remove dispensable dependencies
- [x] Remove dispensable dependencies
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pg-upmig",
"version": "0.0.27",
"version": "0.0.28",
"description": "Postgresql migration tool",
"keywords": [
"database",
Expand Down
29 changes: 21 additions & 8 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ const path = require("path");
let migrationsPath = process.env.UPMIG_PATH||"./migrations";
let pgTable = process.env.UPMIG_TABLE||"pg_upmig";
let reject = Boolean(process.env.UPMIG_REJECT)||false;
let debug = Boolean(process.env.UPMIG_DEBUG)||false;

try {
const dotConfig = require(path.join(process.cwd(), ".upmigrc.js"));
migrationsPath = dotConfig.migrations?dotConfig.migrations:migrationsPath;
pgTable = dotConfig.table?dotConfig.table:pgTable;
reject = dotConfig.reject?dotConfig.reject:reject;
debug = dotConfig.debug?dotConfig.debug:debug;
} catch (error) {}

function steps (s) {
Expand Down Expand Up @@ -47,6 +49,9 @@ function setOpt (namespace) {
break;
case "reject":
reject = option;
break;
case "debug":
debug = option;
}
}
}
Expand All @@ -56,20 +61,24 @@ exports.setOpt = setOpt;
exports._env = () => {
return {
migrationsPath,
pgTable
pgTable,
reject,
debug
};
}

program.on("option:migrations", setOpt("migrations"));
program.on("option:pgtable", setOpt("pgtable"));
program.on("option:reject", setOpt("reject"));
program.on("option:debug", setOpt("debug"));

program.version(pkg.version)
.arguments("<cmd> [opt]")
.usage("<command> [options]")
.option("-m, --migrations <path>", "specify migrations path", "./migrations")
.option("-p, --pgtable <table>", "specify migration table name", "pg-upmig", migTable)
.option("-r, --reject", "dont ignore unauthorized ssl rejection");
.option("-r, --reject", "dont ignore unauthorized ssl rejection")
.option("-d, --debug", "print debug informations");

async function up (cmd) {
const mig = new migration({
Expand All @@ -83,7 +92,8 @@ async function up (cmd) {
table: pgTable,
migrations: migrationsPath,
to: cmd.to,
steps: cmd.steps
steps: cmd.steps,
debug
});
const done = await mig.up();
mig.release();
Expand All @@ -102,7 +112,7 @@ program

const len = done.reduce((accu, file) => Math.max(accu, file.name.length), 21);
for (let file of done) {
process.stdout.write(`\n\x1b[32m⇈")}\t\x1b[33m${file.name}\x1b[0m${" ".repeat(Math.ceil(len-file.name.length))}\t\x1b[35;1m${file.ts}\x1b[0m`);
process.stdout.write(`\n\x1b[32m⇈\t\x1b[33m${file.name}\x1b[0m${" ".repeat(Math.ceil(len-file.name.length))}\t\x1b[35;1m${file.ts}\x1b[0m`);
}
process.stdout.write(`\n\x1b[32m✓\x1b[0m\tMigrations completed:${" ".repeat(Math.ceil(len-21))}\t\x1b[35;1m${done.length}\x1b[0m`);
process.stdout.write("\n\n");
Expand All @@ -116,7 +126,7 @@ async function create (cmd, name){
}
}
});
await mig.init({migrations: migrationsPath, table: pgTable});
await mig.init({migrations: migrationsPath, table: pgTable, debug});
const file = await mig.create(name?name.join("-"):"", cmd.nosql);
mig.release();
return file;
Expand All @@ -143,7 +153,7 @@ async function pending (cmd) {
}
}
});
await mig.init({migrations: migrationsPath, table: pgTable, history: cmd.history});
await mig.init({migrations: migrationsPath, table: pgTable, history: cmd.history, debug});
const list = await mig.pending();
mig.release();
return list;
Expand All @@ -157,9 +167,12 @@ program
.option("-H, --history", "show history about migrations")
.action(async (cmd) => {
const list = await pending(cmd);
const len = list.pending.reduce((accu, file) => Math.max(accu, file.name.length), 19);
const len = list.pending.reduce((accu, file) => Math.max(accu, file.name.length, (list.last||{}).name||0), 19);
if (list.last && cmd.history) {
process.stdout.write(`\n\x1b[32m✓ Last\t\t\x1b[32m${list.last.name}\x1b[0m${" ".repeat(Math.ceil(len-list.last.name.length))}\t\x1b[35m${list.last.ts}\x1b[0m\n`);
}
for (let file of list.pending) {
process.stdout.write(`\n\x1b[34m⇉\t\x1b[33;1m${file.name}\x1b[0m${" ".repeat(Math.ceil(len-file.name.length))}\t\x1b[35;1m${file.ts}\x1b[0m`);
process.stdout.write(`\n\x1b[34m⇉ Pending\t\x1b[33;1m${file.name}\x1b[0m${" ".repeat(Math.ceil(len-file.name.length))}\t\x1b[35;1m${file.ts}\x1b[0m`);
}
process.stdout.write(`\n\x1b[36mⓘ\x1b[0m\tPending migrations:${" ".repeat(Math.ceil(len-19))}\t\x1b[35;1m${list.pending.length}\x1b[0m${cmd.history?`/\x1b[35;1m${list.history+list.pending.length}\x1b[0m \x1b[32;1m(${list.history}\x1b[0m done)`:""}`);
process.stdout.write("\n\n");
Expand Down
20 changes: 14 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ class migration {
const dotConfig = require(path.join(process.cwd(),".upmigrc.js"));
this.options.migrations = dotConfig.migrations?dotConfig.migrations:this.options.migrations;
this.options.table = dotConfig.table?dotConfig.table:this.options.table;
} catch (error) { }
} catch (error) {
this._debug(error, 3);
}

if ((params||{}).options) {
Object.assign(this.options, params.options);
Expand All @@ -73,9 +75,9 @@ class migration {
if (!this.client) {
if ((params||{}).connection) {
if (!params.connection.hasOwnProperty("ssl")) {
params.connection.ssl= { rejectUnauthorized: process.env.UPMIG_REJECT||false };
params.connection.ssl= { rejectUnauthorized: Boolean(process.env.UPMIG_REJECT||0) };
} else if (!params.connection.ssl.hasOwnProperty("rejectUnauthorized")) {
params.connection.ssl["rejectUnauthorized"] = process.env.UPMIG_REJECT||false;
params.connection.ssl["rejectUnauthorized"] = Boolean(process.env.UPMIG_REJECT||0);
}
// Uses connection params
this.client = new Client(params.connection);
Expand All @@ -84,7 +86,7 @@ class migration {
// At this point, if nothing is provided we let PG client rise errors
this.client = new Client({
ssl{
rejectUnauthorized: process.env.UPMIG_REJECT||false
rejectUnauthorized: Boolean(process.env.UPMIG_REJECT||0)
}
});
}
Expand Down Expand Up @@ -276,7 +278,7 @@ module.exports = async (client, method) => {
await this.init();

const files = await this._files();
const latest = this._pluck(await this._query(`SELECT ts FROM ${this.options.table} ORDER BY ts DESC;`));
const latest = this._pluck(await this._query(`SELECT ts, name FROM ${this.options.table} ORDER BY ts DESC;`));
let idx = 0;

// Find the first file with a timestamp greater than the last successful migration
Expand All @@ -286,7 +288,13 @@ module.exports = async (client, method) => {

const pending = idx >= 0 ? files.slice(idx, files.length) : [];

return {pending, history: latest.length};
let last = null;
// Find the last migration
if (latest.length) {
last = latest[0];
}

return {pending, history: latest.length, last};
}

/**
Expand Down
7 changes: 5 additions & 2 deletions tests/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ describe("Core logic", () => {
};
expect(pending).toEqual({
history: 0,
last: null,
pending: [file]
});
});
Expand Down Expand Up @@ -304,13 +305,15 @@ describe("List pending migrations", () => {
}
const containing = [];

containing.push(expect.stringMatching(new RegExp(`Last\\s+${fixtures.migrationFile}\\s+\[0\-9\]+`)))

for (let i = 0; i < details.length; i++) {
containing.push(expect.stringMatching(new RegExp(`${details[i][2]}\\s+${details[i][1]}$`, "i")));
containing.push(expect.stringMatching(new RegExp(`Pending\\s+${details[i][2]}\\s+${details[i][1]}$`, "i")));
}
containing.push(expect.stringMatching(new RegExp(`Pending migrations:\\s+${details.length}/\[0\-9\]\+\\s\\(\[0\-9\]\+\\sdone\\)$`, "i")));

const response = await proc.execute(["-m", fixtures.migrations, "-p", fixtures.pgTable, fixtures.cli._cmds.list, "-H"], [], {env});
expect(response.trim().replace(/\x1b[[0-9;]+m/g, "").split(EOL)).toEqual(containing);
expect(response.trim().replace(/\x1b[[0-9;]+m/g, "").split(EOL).filter(item => item)).toEqual(containing);
});
});

Expand Down
32 changes: 16 additions & 16 deletions tests/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe("Migration using environment variables", () => {

test("Should list empty pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 0});
expect(files).toEqual({pending: [], last: null, history: 0});
});

test("Should create migration files", async () => {
Expand All @@ -105,7 +105,7 @@ describe("Migration using environment variables", () => {

test("Should list pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
expect(files).toEqual({last: null, pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
});

test("Should perform pending migrations", async () => {
Expand All @@ -117,7 +117,7 @@ describe("Migration using environment variables", () => {

test("Should list empty pending migrations with history", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 1});
expect(files).toEqual({pending: [], history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should create 4 migration files with SQL", async () => {
Expand Down Expand Up @@ -147,7 +147,7 @@ describe("Migration using environment variables", () => {
ts: parseInt(item.match(/^([0-9]+)_/)[1], 10)
};
});
expect(files).toEqual({pending, history: 1});
expect(files).toEqual({pending, history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should perform 2 pending migrations over 3 steps", async () => {
Expand Down Expand Up @@ -213,7 +213,7 @@ describe("Migration using custom PG database client", () => {

test("Should list empty pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 0});
expect(files).toEqual({pending: [], history: 0, last: null});
});

test("Should create migration files", async () => {
Expand All @@ -224,7 +224,7 @@ describe("Migration using custom PG database client", () => {

test("Should list pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
expect(files).toEqual({last: null, pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
});

test("Should perform pending migrations", async () => {
Expand All @@ -236,7 +236,7 @@ describe("Migration using custom PG database client", () => {

test("Should list empty pending migrations with history", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 1});
expect(files).toEqual({pending: [], history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should create 4 migration files with SQL", async () => {
Expand Down Expand Up @@ -266,7 +266,7 @@ describe("Migration using custom PG database client", () => {
ts: parseInt(item.match(/^([0-9]+)_/)[1], 10)
};
});
expect(files).toEqual({pending, history: 1});
expect(files).toEqual({pending, history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should perform 2 pending migrations over 3 steps", async () => {
Expand Down Expand Up @@ -334,7 +334,7 @@ describe("Migration using custom Knex database client", () => {

test("Should list empty pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 0});
expect(files).toEqual({pending: [], history: 0, last: null});
});

test("Should create migration files", async () => {
Expand All @@ -345,7 +345,7 @@ describe("Migration using custom Knex database client", () => {

test("Should list pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
expect(files).toEqual({last: null, pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
});

test("Should perform pending migrations", async () => {
Expand All @@ -357,7 +357,7 @@ describe("Migration using custom Knex database client", () => {

test("Should list empty pending migrations with history", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 1});
expect(files).toEqual({pending: [], history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should create 4 migration files with SQL", async () => {
Expand Down Expand Up @@ -387,7 +387,7 @@ describe("Migration using custom Knex database client", () => {
ts: parseInt(item.match(/^([0-9]+)_/)[1], 10)
};
});
expect(files).toEqual({pending, history: 1});
expect(files).toEqual({pending, history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should perform 2 pending migrations over 3 steps", async () => {
Expand Down Expand Up @@ -448,7 +448,7 @@ describe("Migration using default database client with connection parameters", (

test("Should list empty pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 0});
expect(files).toEqual({pending: [], history: 0, last: null});
});

test("Should create migration files", async () => {
Expand All @@ -459,7 +459,7 @@ describe("Migration using default database client with connection parameters", (

test("Should list pending migrations", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
expect(files).toEqual({last: null, pending: [{filename: jestmig, name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}], history: 0});
});

test("Should perform pending migrations", async () => {
Expand All @@ -471,7 +471,7 @@ describe("Migration using default database client with connection parameters", (

test("Should list empty pending migrations with history", async () => {
const files = await mig.pending();
expect(files).toEqual({pending: [], history: 1});
expect(files).toEqual({pending: [], history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should create 4 migration files with SQL", async () => {
Expand Down Expand Up @@ -501,7 +501,7 @@ describe("Migration using default database client with connection parameters", (
ts: parseInt(item.match(/^([0-9]+)_/)[1], 10)
};
});
expect(files).toEqual({pending, history: 1});
expect(files).toEqual({pending, history: 1, last: {name: jestmig.replace(/^([0-9]+)_/, ""), ts: parseInt(jestmig.match(/^([0-9]+)_/)[1], 10)}});
});

test("Should perform 2 pending migrations over 3 steps", async () => {
Expand Down

0 comments on commit 1a93d86

Please sign in to comment.