NAME
    Perinci::Sub::Gen::Undoable - Generate undoable (transactional,
    dry-runnable, idempotent) function

VERSION
    version 0.25

SYNOPSIS
     # See an example, like in Setup::File::Symlink

DESCRIPTION
    This module helps you write undoable/transactional functions (as well as
    functions that support dry-run and are idempotent).

SEE ALSO
    Rinci::function::Undo, Rinci::function::Transaction, Rinci

    Setup.

DESCRIPTION
    This module has Rinci metadata.

FUNCTIONS
    None are exported by default, but they are exportable.

  gen_undoable_func(%args) -> [status, msg, result, meta]
    Generate undoable (transactional, dry-runnable, idempotent) function.

    This function (hereby called generator, or helper) is a helper for
    writing undoable (as well as transactional, dry-runnable, and
    idempotent) function (hereby called generated function). Undo and
    transaction features are as described in Rinci::function::Undo and
    Rinci::function::Transaction. Generator will create the generated
    function with the basic flow and structure; you just need to supply the
    necessary "business logics" bits like the "check_state" and "fix_state"
    hooks.

    Here is the flow of the generated function:

    1.  Execute "check_args" hook if supplied. Hook will be passed ($args).
        The task of the this hook is to check arguments (and possibly supply
        defaults). It should return enveloped result. If response is not
        success, exit with this response. Otherwise, continue.

    1.  If we are called in do mode (-undo_action => 'do' or undefined):

           2a. Execute C<check_state> hook, to check state. Hook will be passed ($args).
           Hook must return enveloped result, status 304 if checking succeeds and
           fixed state (final, desired state) has been reached so nothing needs to
           be done, status 200 if checking succeeds and we are in a fixable state (a
           non-final state but fixable into the final state, also called an
           acceptable initial state), status 412 if checking succeeds but we are in
           an unfixable state (non-final state which is not fixable into the final
           state, also called an unacceptable initial state). Other status means
           checking has failed. Function should return with this result unless
           status is 200.

           If status is 200, hook must also return undo data (a list of calls that
           can be used to I<undo> the 'fix_state' routine back to the initial state)
           in its result metadata, in C<undo_data> key. This means, if we fail during
           fixing, we can rollback to initial state using this information.

           The undo data looks like this: C. C
           is the fully-qualified function name to call (required), C is a
           hashref containing arguments for the function (optional, defaults to {}).

           2b. If function is called in dry run mode (-dry_run => 1), we return 200
           (along undo data from step 2a in the result metadata).

           2c. We execute C<fix_state> hook to fix state to final/fixed state. Hook will
           be passed ($args, $undoI<data), where $undo>data was retrieved from
           C<check_state> hook. Hook must return enveloped result. Function returns
           with this result. Failure will trigger a rollback by TM.

    1.  If we are called in undo mode (-undo*action =* 'undo', -undo>data =>
        $calls): then we simply invoke TM's call() to process the undo
        calls.

    For examples, see Setup::* Perl modules.

    Arguments ('*' denotes required arguments):

    *   args => *hash* (default: {})

        Specification for generated function's arguments.

        This is just like the metadata property 'args'.

    *   check_args => *code*

        Code to check function's arguments.

        See generator's documentation on how this hook should do and return.

    *   check_or_fix_state => *code*

        Code to check or fix state.

        An alternative to combine check*state and fix*state in one code.
        Code will be called with either ('check', $args) or ('fix', $args,
        $undo_data), depending on whether check/fix is wanted.

    *   check_state* => *code*

        Code to check state.

        See generator's documentation on how this hook should do and return.

    *   description => *str*

        Generated function's description.

    *   fix_state => *code*

        Code to fix state.

        See generator's documentation on how this hook should do and return.

    *   install => *bool* (default: 1)

        Whether to install generated function (and metadata).

        By default, generated function will be installed to the specified
        (or caller's) package, as well as its generated metadata into %SPEC.
        Set this argument to false to skip installing.

    *   name* => *str*

        Generated function's name, e.g. `myfunc`.

    *   package => *str*

        Generated function's package, e.g. `My::Package`.

        This is needed mostly for installing the function. You usually don't
        need to supply this if you set "install" to false.

        If not specified, caller's package will be used by default.

    *   summary => *str*

        Generated function's summary.

    *   trash_dir => *bool* (default: 0)

        Whether function needs undo trash directory.

        If set to true, generator will put "-undo_trash_dir" in function
        arguments.

    *   v => *int* (default: 1)

        Interface version.

        When Perinci::Sub::Gen::Undoable 0.22 broke backward-compatibility,
        v was introduced at v=2 (previous interface at v=1).

        For new interface, must be set to 2.

    Return value:

    Returns an enveloped result (an array). First element (status) is an
    integer containing HTTP status code (200 means OK, 4xx caller error, 5xx
    function error). Second element (msg) is a string containing error
    message, or 'OK' if status is 200. Third element (result) is optional,
    the actual result. Fourth element (meta) is called result metadata and
    is optional, a hash that contains extra information.

AUTHOR
    Steven Haryanto <stevenharyanto@gmail.com>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2012 by Steven Haryanto.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

POD ERRORS
    Hey! The above document had some coding errors, which are explained
    below:

    Around line 341:
        You have '=item 1' instead of the expected '=item 2'

    Around line 375:
        You have '=item 1' instead of the expected '=item 3'

