Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mix task to undo latest codegen/delete latest migration #490

Open
sevenseacat opened this issue Feb 25, 2025 · 16 comments
Open

Add mix task to undo latest codegen/delete latest migration #490

sevenseacat opened this issue Feb 25, 2025 · 16 comments
Labels
enhancement New feature or request needs review

Comments

@sevenseacat
Copy link
Contributor

Is your feature request related to a problem? Please describe.

Codegen to generate a migration is really awesome, but sometimes you generate a migration and then you realize you missed something, so you want to delete that migration, make the change, and then generate it again. Currently that's a manual process - go find the migration, find the snapshots for all the relevant tables, delete them all, and do it again. It's pretty annoying!

Describe the solution you'd like

A task like ash_postgres.delete_latest_migration that will delete the last migration, and any snapshots that were created at the same time. No option to delete other migrations or anything like that - only the last one.

And it should probably confirm the name of the migration just to make sure!

Describe alternatives you've considered

You could just generate another migration with the added changes, but snapshot files are big and ugly and if you haven't even run the first migration, being able to undo/regenerate it seems like the smarter approach.

@sevenseacat sevenseacat added enhancement New feature or request needs review labels Feb 25, 2025
@zachdaniel
Copy link
Contributor

There is an example here of a script that does it based off of git status:

https://hexdocs.pm/ash_postgres/migrations-and-tasks.html#regenerating-migrations

@zachdaniel
Copy link
Contributor

I don't think we can just do "only the last one" because it is actually possible for the migration generator to produce more than one migration (concurrent index generation must be done in its own migration w/o a ddl transaction).

@sevenseacat
Copy link
Contributor Author

Oh interesting! Yeah if I don't feel like doing it manually I usually do it with git now - add, stash, drop - but that feels a bit weird.

Okay so maybe not the last one, but any with the timestamp of the last one? If more than one migration is generated, do they have the same timestamp?

@zachdaniel
Copy link
Contributor

They do not, the timestamp differentiates them. However, I think the fix here is actually to support a --dev flag for migrations, which uses numbered migrations like Dev1 and Dev2 etc. Then, when migrations are checked with mix ash.codegen --check, we error if there are dev migrations. When you run mix ash.codegen name we rollback all dev migrations, delete all dev snapshots and regenerate them fully.

The added benefit here (which is a big one) is we could then get:

  1. a watcher that auto generates migrations with --dev as you change your files
  2. a plug like Ecto's plug that says "you haven't run codegen yet, click here to run it"

@zachdaniel
Copy link
Contributor

and then mix ash.codegen --reset-dev or something would then do what you want, based on dev migrations, not named migrations. Then you just name it once at the end when you're done with your feature.

@ken-kost
Copy link
Contributor

a watcher that auto generates migrations with --dev as you change your files
a plug like Ecto's plug that says "you haven't run codegen yet, click here to run it"

could you expand on these two points, what you had in mind exactly. This sounds like the fun part. 👀

@zachdaniel
Copy link
Contributor

https://hexdocs.pm/phoenix/Phoenix.Endpoint.html#module-runtime-configuration

So we would want something that can be plugged in here that would then autogenerate dev migrations on save with mix ash.codegen --dev

Then a plug like this one: https://hexdocs.pm/phoenix_ecto/Phoenix.Ecto.CheckRepoStatus.html

That runs mix ash.codegen --check and shows you a button to run mix ash.codegen --dev

@zachdaniel
Copy link
Contributor

And I agree, these are definitely the fun part because they will make this --dev feature really sing and be a huge UX improvement.

@ken-kost
Copy link
Contributor

watchers: [dev: {Mix.Tasks.AshPostgres.GenerateMigrations, :run, [["--dev"]]}],

works, i.e. runs dev migrations on server start. 🎉

Regarding the plug, where should that go, ash_phoenix?

Also, after we finish here I'll open a PR for codegen part so that will be in watcher configuration instead of generate migrations I assume, and docs should be expanded mentioning this possible configuration.

@zachdaniel
Copy link
Contributor

Wow. That's really all that's needed? Does it run when files change too?

@zachdaniel
Copy link
Contributor

And yeah the plug would go in ash_phoenix

@ken-kost
Copy link
Contributor

Wow. That's really all that's needed? Does it run when files change too?

yea I also thought it would but I digged and it turns out it's misleading, the name watcher. 😅

https://elixirforum.com/t/phoenix-asset-management-watchers/45661/2?u=ken-kost

@ken-kost
Copy link
Contributor

not sure, will dig more. 👌

@zachdaniel
Copy link
Contributor

https://github.com/phoenixframework/phoenix_live_reload Perhaps here 😄

@ken-kost
Copy link
Contributor

Did some more digging and I couldn't figure out the live reload. I can't even figure out how to trigger rebuild when backend context is changed, only works for _web. 😅 Also, even if you do recompile the watcher above will not trigger, only on system start.

The last part in the link you gave for phoenix_live_reload states

Differences between Phoenix.CodeReloader
Phoenix.CodeReloader recompiles code in the lib directory. This means that if you change anything in the lib directory (such as a context) then the Elixir code will be reloaded and used on your next request.

If I'm understanding correctly I should be able to trigger rebuild even when in BE context with CodeReloader but I'm not sure what I'm missing (or am I missing anything).

It would be really cool to never need to exit running server no matter what you do in the codebase. 🤤

Regarding the feature itself do you think it's ready for merge? I guess I need it merged so I can continue in ash (codegen) and ash_phoenix (plug). 🤔

@zachdaniel
Copy link
Contributor

Asked a question on the feature. For the watcher we may need to do something like this: https://github.com/lpil/mix-test.watch

And have our task watch for changes using FileSystem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request needs review
Projects
None yet
Development

No branches or pull requests

3 participants