Cascade.Template behaviour (Cascade v0.3.0)

View Source

The template generation logic.

Every Cascade template must implement this behaviour. It provides callbacks which affect the template generation logic.

Summary

Callbacks

The CLI arguments (if any) schema of the template.

The absolute path to the template.

Returns the destination path for the given template file.

Returns the name of template.

Optional callback to be invoked after the template generation has finished.

Optional callback to be invoked before the template generation.

Used for custom validation and post-processing of cli arguments.

Functions

Gets the moduledoc for the given template module.

Gets the shortdoc for the given template module.

Callbacks

args_schema()

@callback args_schema() :: keyword()

The CLI arguments (if any) schema of the template.

It should return a valid CliOptions arguments schema. These CLI options will be automatically parsed and assigned to the template's bindings when invoked from the cascade mix task.

Examples

defmodule MyTemplate do
  @behaviour Cascade.Template

  @impl true
  def args_schema do
    [
      path: [
        type: :string,
        doc: "The path to store the template to",
        required: true
      ],
      auth: [
        type: :boolean,
        doc: "Whether to generate authentication logic",
        default: false
      ]
    ]
  end
end

assets_path()

@callback assets_path() :: String.t()

The absolute path to the template.

destination_path(asset_path, output_path, opts)

@callback destination_path(
  asset_path :: String.t(),
  output_path :: String.t(),
  opts :: keyword()
) ::
  Path.t()

Returns the destination path for the given template file.

It expects a file path, the template's config and the user provided CLI arguments and is expected to return the destination path for this specific asset. The asset_path is the template file's path with respect to the assets.

This will be called for all template files. For example for the following foo template:

templates/foo

  ├── README.md   ├── lib   │   └── foo.ex   └── mix.exs

it will be called for the following asset paths:

  • README.md
  • mix.exs
  • lib/foo.ex

name()

@callback name() :: atom()

Returns the name of template.

The names must be unique, it is advised to use a prefix in order to avoid collisions with other packages.

post_generate(output_path, opts)

(optional)
@callback post_generate(output_path :: Path.t(), opts :: keyword()) :: :ok

Optional callback to be invoked after the template generation has finished.

You can use it to perform post-generation clean up, log a message to the user or perform any custom logic after the template generation completion (e.g. format the generated code).

pre_generate(output_path, opts)

(optional)
@callback pre_generate(output_path :: Path.t(), opts :: keyword()) :: :ok

Optional callback to be invoked before the template generation.

You can use it to perform setup before the actual template invocation.

validate_cli_opts(opts)

@callback validate_cli_opts(opts :: keyword()) :: {:ok, keyword()} | {:error, String.t()}

Used for custom validation and post-processing of cli arguments.

This can be used for performing custom validations/casting of cli arguments and optionally augment them. It expects the parsed cli arguments and is expected to return {:ok, opts} in case of success or {:error, reason} in case of failure.

All templates are required to define the expected cli arguments under their config.exs. The callback will be called in order to validate the user provided arguments.

Examples

Assuming that you have a template that expects a --path argument. Since generator works with absolute paths you can override this callback in order to expand the path if it is relative.

def validate_cli_opts(opts) do
  path =
    Keyword.fetch!(opts, :path)
    |> Path.expand(File.cwd())

  opts = Keyword.put(opts, :path, path)

  {:ok, opts}
end

Functions

generate(template, output_path, opts, generate_opts \\ [])

@spec generate(
  template :: module(),
  output_path :: Path.t(),
  opts :: keyword(),
  generate_opts :: keyword()
) :: :ok

Generates a template

The opts are the template's options, used as bindings for its assets.

Generate options

  • :force - if set existing files are overwritten without asking, defaults to false.

moduledoc(module)

@spec moduledoc(module :: module()) :: String.t() | false

Gets the moduledoc for the given template module.

Returns the moduledoc or nil.

shortdoc(module)

@spec shortdoc(module :: module()) :: String.t() | nil

Gets the shortdoc for the given template module.

Returns the shortdoc or nil.