AshOps - Expose actions as mix tasks on the command-line

@jimsynz just launched an epic new extension for Ash! It allows you to create rich mix tasks for calling your resource actions directly from the command line.

Its only just had its first release, so there will probably be bugs here and there, but honestly this think slaps and so far it has Just Worked™ in my usage.

Check out the docs for more: README — ash_ops v0.2.3

Here is a teaser image:

Which would give you:

mix tunez.music.create_album and mix tunez.music.list_albums mix tasks. If you really want your mind blown, try out the --filter option on list tasks, and the --format option on any of them :exploding_head:

And there is a demo video in the latest Ash Weekly newsletter: Ash Weekly: Issue #8 - Ash Weekly

10 Likes

This :point_up: is awesome! I have a CLI/REPL utility that I have been hacking around with for a while now, and I have an idea for an Ash-compatible extension for it at the back of my mind. I will see if I can quickly connect the two …

BTW: This might not be to everyone’s taste. It’s potentially very ropey Elixir code, so don’t expect too much! The motivation for it was twofold: a) to help me learn Elixir, and b) to have a simple way to implement the command pattern from a CLI/REPL so that I could test my code as I was building it. As they say, #ymmv. :pray:

1 Like

This is absolute fire and @jimsynz is the MVP.

1 Like

Ok, I must be being really dumb. Where does the mix_tasks... bit go? I ran the install via mix igniter.install ash_ops and then I have tried to put that inside the Ash Domain, the Ash Resource, in mix.exs. This looks so simple from the docs, what am I doing wrong?

This seemed the most obvious place to put it given the instructions said “Example: Defining the following action in your domain”

So I did this:

defmodule Myapp.Accounts do
  use Ash.Domain, otp_app: :myapp, extensions: [AshAdmin.Domain]
  ...
  mix_tasks do
    list Myapp.Accounts.User, :list_users, :read
  end
end

But that generates a compile error. :thinking_face:

Aha. I worked it out. I needed to add AshOps to :extensions like this:

defmodule Myapp.Accounts do
  use Ash.Domain, otp_app: :myapp, extensions: [AshAdmin.Domain, AshOps]

Now the mix task is available:

mix help | grep myapp
mix myapp.accounts.list_users     # Query for `Myapp.Accounts.User` records using the `read` action

Cool!

Ok, the next question is how to map these resource actions onto the mix tasks? For example, consider this:

defmodule Myapp.Accounts do
  use Ash.Domain, otp_app: :icpzero, extensions: [AshAdmin.Domain, AshOps]

  admin do
    show? true
  end

  resources do
    resource Myapp.Accounts.Token

    resource Myapp.Accounts.User do
      define :add_user_to_team, action: :add_to_team
      define :get_user_by_email, action: :read, get_by: :email
      define :get_user_by_id, action: :read, get_by: :id

      define :register_with_password, action: :register_with_password
      define :set_role, action: :set_role
      define :set_name, action: :set_name
    end

    resource Myapp.Accounts.Team do
      define :create_team, action: :create
    end
  end

  mix_tasks do
    list Myapp.Accounts.User, :list_users, :read
  end
end

What’s the syntax for mapping those Resource commands that take a parameter onto mix tasks?

More here: Slack

1 Like