Skip to content

Commit

Permalink
feat: Exit with code 1 on empty migration:generate (#6978)
Browse files Browse the repository at this point in the history
This makes the `migration:generate` cli command exit with code 1 if no changes were found between the database and the schema from the code.
  • Loading branch information
holm committed Oct 30, 2020
1 parent a5eb946 commit 8244ea1
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 33 deletions.
2 changes: 2 additions & 0 deletions docs/using-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ Learn more about [Migrations](./migrations.md).
Automatic migration generation creates a new migration file
and writes all sql queries that must be executed to update the database.

If no there were no changes generated, the command will exit with code 1.

```
typeorm migration:generate -n UserMigration
```
Expand Down
66 changes: 33 additions & 33 deletions src/commands/MigrationGenerateCommand.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {ConnectionOptionsReader} from "../connection/ConnectionOptionsReader";
import {CommandUtils} from "./CommandUtils";
import {Connection} from "../connection/Connection";
import {createConnection} from "../index";
import {MysqlDriver} from "../driver/mysql/MysqlDriver";
import {camelCase} from "../util/StringUtils";
Expand Down Expand Up @@ -69,7 +68,6 @@ export class MigrationGenerateCommand implements yargs.CommandModule {
} catch (err) { }
}

let connection: Connection|undefined = undefined;
try {
const connectionOptionsReader = new ConnectionOptionsReader({
root: process.cwd(),
Expand All @@ -82,36 +80,41 @@ export class MigrationGenerateCommand implements yargs.CommandModule {
dropSchema: false,
logging: false
});
connection = await createConnection(connectionOptions);
const sqlInMemory = await connection.driver.createSchemaBuilder().log();

if (args.pretty) {
sqlInMemory.upQueries.forEach(upQuery => {
upQuery.query = MigrationGenerateCommand.prettifyQuery(upQuery.query);
});
sqlInMemory.downQueries.forEach(downQuery => {
downQuery.query = MigrationGenerateCommand.prettifyQuery(downQuery.query);
});
}

const upSqls: string[] = [], downSqls: string[] = [];

// mysql is exceptional here because it uses ` character in to escape names in queries, that's why for mysql
// we are using simple quoted string instead of template string syntax
if (connection.driver instanceof MysqlDriver || connection.driver instanceof AuroraDataApiDriver) {
sqlInMemory.upQueries.forEach(upQuery => {
upSqls.push(" await queryRunner.query(\"" + upQuery.query.replace(new RegExp(`"`, "g"), `\\"`) + "\"" + MigrationGenerateCommand.queryParams(upQuery.parameters) + ");");
});
sqlInMemory.downQueries.forEach(downQuery => {
downSqls.push(" await queryRunner.query(\"" + downQuery.query.replace(new RegExp(`"`, "g"), `\\"`) + "\"" + MigrationGenerateCommand.queryParams(downQuery.parameters) + ");");
});
} else {
sqlInMemory.upQueries.forEach(upQuery => {
upSqls.push(" await queryRunner.query(`" + upQuery.query.replace(new RegExp("`", "g"), "\\`") + "`" + MigrationGenerateCommand.queryParams(upQuery.parameters) + ");");
});
sqlInMemory.downQueries.forEach(downQuery => {
downSqls.push(" await queryRunner.query(`" + downQuery.query.replace(new RegExp("`", "g"), "\\`") + "`" + MigrationGenerateCommand.queryParams(downQuery.parameters) + ");");
});
const connection = await createConnection(connectionOptions);
try {
const sqlInMemory = await connection.driver.createSchemaBuilder().log();

if (args.pretty) {
sqlInMemory.upQueries.forEach(upQuery => {
upQuery.query = MigrationGenerateCommand.prettifyQuery(upQuery.query);
});
sqlInMemory.downQueries.forEach(downQuery => {
downQuery.query = MigrationGenerateCommand.prettifyQuery(downQuery.query);
});
}

// mysql is exceptional here because it uses ` character in to escape names in queries, that's why for mysql
// we are using simple quoted string instead of template string syntax
if (connection.driver instanceof MysqlDriver || connection.driver instanceof AuroraDataApiDriver) {
sqlInMemory.upQueries.forEach(upQuery => {
upSqls.push(" await queryRunner.query(\"" + upQuery.query.replace(new RegExp(`"`, "g"), `\\"`) + "\"" + MigrationGenerateCommand.queryParams(upQuery.parameters) + ");");
});
sqlInMemory.downQueries.forEach(downQuery => {
downSqls.push(" await queryRunner.query(\"" + downQuery.query.replace(new RegExp(`"`, "g"), `\\"`) + "\"" + MigrationGenerateCommand.queryParams(downQuery.parameters) + ");");
});
} else {
sqlInMemory.upQueries.forEach(upQuery => {
upSqls.push(" await queryRunner.query(`" + upQuery.query.replace(new RegExp("`", "g"), "\\`") + "`" + MigrationGenerateCommand.queryParams(upQuery.parameters) + ");");
});
sqlInMemory.downQueries.forEach(downQuery => {
downSqls.push(" await queryRunner.query(`" + downQuery.query.replace(new RegExp("`", "g"), "\\`") + "`" + MigrationGenerateCommand.queryParams(downQuery.parameters) + ");");
});
}
} finally {
await connection.close();
}

if (upSqls.length) {
Expand All @@ -126,12 +129,9 @@ export class MigrationGenerateCommand implements yargs.CommandModule {
}
} else {
console.log(chalk.yellow(`No changes in database schema were found - cannot generate a migration. To create a new empty migration use "typeorm migration:create" command`));
process.exit(1);
}
await connection.close();

} catch (err) {
if (connection) await (connection as Connection).close();

console.log(chalk.black.bgRed("Error during migration generation:"));
console.error(err);
process.exit(1);
Expand Down

0 comments on commit 8244ea1

Please sign in to comment.