on main help sign in
Update docs and error messages with new CLI commands
df938fafabianlindfors
README.md+24−22
@@ -35,10 +35,10 @@ Designed for Postgres 12 and later.
35 - [Remove enum](#remove-enum)
35 - [Remove enum](#remove-enum)
36 - [Custom](#custom)
36 - [Custom](#custom)
37- [Commands and options](#commands-and-options)
37- [Commands and options](#commands-and-options)
38− - [`reshape migrate`](#reshape-migrate)
38+ - [`reshape migration start`](#reshape-migration-start)
39− - [`reshape complete`](#reshape-complete)
39+ - [`reshape migration complete`](#reshape-migration-complete)
40− - [`reshape abort`](#reshape-abort)
40+ - [`reshape migration abort`](#reshape-migration-abort)
41− - [`reshape generate-schema-query`](#reshape-generate-schema-query)
41+ - [`reshape schema-query`](#reshape-schema-query)
42 - [Connection options](#connection-options)
42 - [Connection options](#connection-options)
43- [License](#license)
43- [License](#license)
44
44
@@ -47,11 +47,11 @@ Designed for Postgres 12 and later.
47
47
48Reshape works by creating views that encapsulate the underlying tables, which your application will interact with. During a migration, Reshape will automatically create a new set of views and set up triggers to translate inserts and updates between the old and new schema. This means that every deployment is a three-phase process:
48Reshape works by creating views that encapsulate the underlying tables, which your application will interact with. During a migration, Reshape will automatically create a new set of views and set up triggers to translate inserts and updates between the old and new schema. This means that every deployment is a three-phase process:
49
49
50−1. **Start migration** (`reshape migrate`): Sets up views and triggers to ensure both the new and old schema are usable at the same time.
50+1. **Start migration** (`reshape migration start`): Sets up views and triggers to ensure both the new and old schema are usable at the same time.
512. **Roll out application**: Your application can be gradually rolled out without downtime. The existing deployment will continue using the old schema whilst the new deployment uses the new schema.
512. **Roll out application**: Your application can be gradually rolled out without downtime. The existing deployment will continue using the old schema whilst the new deployment uses the new schema.
52−3. **Complete migration** (`reshape complete`): Removes the old schema and any intermediate data and triggers.
52+3. **Complete migration** (`reshape migration complete`): Removes the old schema and any intermediate data and triggers.
53
53
54−If the application deployment fails, you should run `reshape abort` which will roll back any changes made by `reshape migrate` without losing data.
54+If the application deployment fails, you should run `reshape migration abort` which will roll back any changes made by `reshape migration start` without losing data.
55
55
56## Getting started
56## Getting started
57
57
@@ -74,7 +74,7 @@ cargo install reshape
74Reshape is available as a Docker image on [Docker Hub](https://hub.docker.com/repository/docker/fabianlindfors/reshape).
74Reshape is available as a Docker image on [Docker Hub](https://hub.docker.com/repository/docker/fabianlindfors/reshape).
75
75
76```shell
76```shell
77−docker run -v $(pwd):/usr/share/app fabianlindfors/reshape reshape migrate
77+docker run -v $(pwd):/usr/share/app fabianlindfors/reshape reshape migration start
78```
78```
79
79
80### Creating your first migration
80### Creating your first migration
@@ -103,9 +103,9 @@ This is the equivalent of running `CREATE TABLE users (id INTEGER GENERATED ALWA
103
103
104### Preparing your application
104### Preparing your application
105
105
106−Reshape relies on your application using a specific schema. When establishing the connection to Postgres in your application, you need to run a query to select the most recent schema. This query can be generated using: `reshape generate-schema-query`.
106+Reshape relies on your application using a specific schema. When establishing the connection to Postgres in your application, you need to run a query to select the most recent schema. This query can be generated using: `reshape schema-query`.
107
107
108−To pass it along to your application, you can for example use an environment variable in your run script: `RESHAPE_SCHEMA_QUERY=$(reshape generate-schema-query)`. Then in your application:
108+To pass it along to your application, you can for example use an environment variable in your run script: `RESHAPE_SCHEMA_QUERY=$(reshape schema-query)`. Then in your application:
109
109
110```python
110```python
111# Example for Python
111# Example for Python
@@ -120,16 +120,16 @@ If your application is written in Rust, you might prefer the [Rust helper librar
120To create your new `users` table, run:
120To create your new `users` table, run:
121
121
122```bash
122```bash
123−reshape migrate --complete
123+reshape migration start --complete
124```
124```
125
125
126−We use the `--complete` flag to automatically complete the migration. During a production deployment, you should first run `reshape migrate` followed by `reshape complete` once your application has been fully rolled out.
126+We use the `--complete` flag to automatically complete the migration. During a production deployment, you should first run `reshape migration start` followed by `reshape migration complete` once your application has been fully rolled out.
127
127
128If nothing else is specified, Reshape will try to connect to a Postgres database running on `localhost` using `postgres` as both username and password. See [Connection options](#connection-options) for details on how to change the connection settings.
128If nothing else is specified, Reshape will try to connect to a Postgres database running on `localhost` using `postgres` as both username and password. See [Connection options](#connection-options) for details on how to change the connection settings.
129
129
130### Using during development
130### Using during development
131
131
132−When adding new migrations during development, we recommend running `reshape migrate` but skipping `reshape complete`. This way, the new migrations can be iterated on by updating the migration file and running `reshape abort` followed by `reshape migrate`.
132+When adding new migrations during development, we recommend running `reshape migration start` but skipping `reshape migration complete`. This way, the new migrations can be iterated on by updating the migration file and running `reshape migration abort` followed by `reshape migration start`.
133
133
134## Writing migrations
134## Writing migrations
135
135
@@ -538,9 +538,9 @@ The `custom` action lets you create a migration which runs custom SQL. It should
538
538
539There are three optional settings available which all accept SQL queries. All queries need to be idempotent, for example by using `IF NOT EXISTS` wherever available.
539There are three optional settings available which all accept SQL queries. All queries need to be idempotent, for example by using `IF NOT EXISTS` wherever available.
540
540
541−- `start`: run when a migration is started using `reshape migrate`
541+- `start`: run when a migration is started using `reshape migration start`
542−- `complete`: run when a migration is completed using `reshape complete`
542+- `complete`: run when a migration is completed using `reshape migration complete`
543−- `abort`: run when a migration is aborted using `reshape abort`
543+- `abort`: run when a migration is aborted using `reshape migration abort`
544
544
545*Example: enable PostGIS and pg_stat_statements extensions*
545*Example: enable PostGIS and pg_stat_statements extensions*
546
546
@@ -561,9 +561,9 @@ abort = """
561
561
562## Commands and options
562## Commands and options
563
563
564−### `reshape migrate`
564+### `reshape migration start`
565
565
566−Starts a new migration, applying all migrations under `migrations/` that haven't yet been applied. After the command has completed, both the old and new schema will be usable at the same time. When you have rolled out the new version of your application which uses the new schema, you should run `reshape complete`.
566+Starts a new migration, applying all migrations under `migrations/` that haven't yet been applied. After the command has completed, both the old and new schema will be usable at the same time. When you have rolled out the new version of your application which uses the new schema, you should run `reshape migration complete`.
567
567
568#### Options
568#### Options
569
569
@@ -574,15 +574,15 @@ Starts a new migration, applying all migrations under `migrations/` that haven't
574| `--complete`, `-c` | `false` | Automatically complete migration after applying it. |
574| `--complete`, `-c` | `false` | Automatically complete migration after applying it. |
575| `--dirs` | `migrations/` | Directories to search for migration files. Multiple directories can be specified using `--dirs dir1 dir2 dir3`. |
575| `--dirs` | `migrations/` | Directories to search for migration files. Multiple directories can be specified using `--dirs dir1 dir2 dir3`. |
576
576
577−### `reshape complete`
577+### `reshape migration complete`
578
578
579−Completes migrations previously started with `reshape complete`.
579+Completes migrations previously started with `reshape migration complete`.
580
580
581#### Options
581#### Options
582
582
583See [Connection options](#connection-options)
583See [Connection options](#connection-options)
584
584
585−### `reshape abort`
585+### `reshape migration abort`
586
586
587Aborts any migrations which haven't yet been completed.
587Aborts any migrations which haven't yet been completed.
588
588
@@ -590,10 +590,12 @@ Aborts any migrations which haven't yet been completed.
590
590
591See [Connection options](#connection-options)
591See [Connection options](#connection-options)
592
592
593−### `reshape generate-schema-query`
593+### `reshape schema-query`
594
594
595Generates the SQL query you need to run in your application before using the database. This command does not require a database connection. Instead it will generate the query based on the latest migration in the `migrations/` directory (or the directories specified by `--dirs`).
595Generates the SQL query you need to run in your application before using the database. This command does not require a database connection. Instead it will generate the query based on the latest migration in the `migrations/` directory (or the directories specified by `--dirs`).
596
596
597+If your application is written in Rust, we recommend using the [Rust helper library](https://github.com/fabianlindfors/reshape-helper/) instead.
598+
597The query should look something like `SET search_path TO migration_1_initial_migration`.
599The query should look something like `SET search_path TO migration_1_initial_migration`.
598
600
599#### Options
601#### Options
src/lib.rs+9−7
@@ -147,13 +147,15 @@ fn migrate(
147) -> anyhow::Result<()> {
147) -> anyhow::Result<()> {
148 // Make sure no migration is in progress
148 // Make sure no migration is in progress
149 if let State::InProgress { .. } = &state {
149 if let State::InProgress { .. } = &state {
150+ println!(
150− println!("Migration already in progress, please complete using 'reshape complete'");
151+ "Migration already in progress, please complete using 'reshape migration complete'"
152+ );
151 return Ok(());
153 return Ok(());
152 }
154 }
153
155
154 if let State::Completing { .. } = &state {
156 if let State::Completing { .. } = &state {
155 println!(
157 println!(
156− "Migration already in progress and has started completion, please finish using 'reshape complete'"
158+ "Migration already in progress and has started completion, please finish using 'reshape migration complete'"
157 );
159 );
158 return Ok(());
160 return Ok(());
159 }
161 }
@@ -176,7 +178,7 @@ fn migrate(
176 {
178 {
177 if existing_migrations != &remaining_migrations {
179 if existing_migrations != &remaining_migrations {
178 return Err(anyhow!(
180 return Err(anyhow!(
179− "a previous migration seems to have failed without cleaning up. Please run `reshape abort` and then run migrate again."
181+ "a previous migration seems to have failed without cleaning up. Please run `reshape migration abort` and then run migrate again."
180 ));
182 ));
181 }
183 }
182 }
184 }
@@ -232,7 +234,7 @@ fn migrate(
232 // Set to the Aborting state. This is to ensure that the failed
234 // Set to the Aborting state. This is to ensure that the failed
233 // migration is fully aborted and nothing is left dangling.
235 // migration is fully aborted and nothing is left dangling.
234 // If the abort is interrupted for any reason, the user can try again
236 // If the abort is interrupted for any reason, the user can try again
235− // by running `reshape abort`.
237+ // by running `reshape migration abort`.
236 state.aborting(
238 state.aborting(
237 remaining_migrations.clone(),
239 remaining_migrations.clone(),
238 last_migration_index + 1,
240 last_migration_index + 1,
@@ -259,7 +261,7 @@ fn migrate(
259 schema_query_for_migration(&target_migration)
261 schema_query_for_migration(&target_migration)
260 );
262 );
261 println!(
263 println!(
262− " - Run 'reshape complete' once your application has been updated and the previous schema is no longer in use"
264+ " - Run 'reshape migration complete' once your application has been updated and the previous schema is no longer in use"
263 );
265 );
264 Ok(())
266 Ok(())
265}
267}
@@ -281,7 +283,7 @@ fn complete(db: &mut DbConn, state: &mut State) -> anyhow::Result<()> {
281 current_action_index
283 current_action_index
282 } => (migrations, current_migration_index, current_action_index),
284 } => (migrations, current_migration_index, current_action_index),
283 State::Aborting { .. } => {
285 State::Aborting { .. } => {
284− return Err(anyhow!("migration been aborted and can't be completed. Please finish using `reshape abort`."))
286+ return Err(anyhow!("migration been aborted and can't be completed. Please finish using `reshape migration abort`."))
285 }
287 }
286 State::Applying { .. } => {
288 State::Applying { .. } => {
287 return Err(anyhow!("a previous migration unexpectedly failed. Please run `reshape migrate` to try applying the migration again."))
289 return Err(anyhow!("a previous migration unexpectedly failed. Please run `reshape migrate` to try applying the migration again."))
@@ -409,7 +411,7 @@ fn abort(db: &mut DbConn, state: &mut State) -> anyhow::Result<()> {
409 last_action_index,
411 last_action_index,
410 } => (migrations, last_migration_index, last_action_index),
412 } => (migrations, last_migration_index, last_action_index),
411 State::Completing { .. } => {
413 State::Completing { .. } => {
412− return Err(anyhow!("Migration completion has already been started. Please run `reshape complete` again to finish it."));
414+ return Err(anyhow!("migration completion has already been started. Please run `reshape migration complete` again to finish it."));
413 }
415 }
414 State::Idle => {
416 State::Idle => {
415 println!("No migration is in progress");
417 println!("No migration is in progress");