App-Sqitch

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

     - Added support for ClickHouse. It relies on the `clickhouse` (or
       `clickhouse-client`) CLI and ODBC driver. Like MySQL, it uses a
       database for the registry schema, where the tables use the `MergeTree`
       engine. It supports client certificate authentication and the
       ClickHouse client configuration file format.

1.5.2  2025-04-29T15:13:35Z
     - Added missing German translations, thanks to @0xflotus for the PR
       (#873)!
     - Fixed bug where the location of reworked script files did not respect
       the `deploy_dir`, `revert_dir`, or `verify_dir` options. Thanks to Neil
       Freeman for the report (#875)!
     - Updated the MySQL engine's installation of the `checkit()` function so
       that it no longer depends on permission-checking, since the current
       user may not have such permission. It instead attempts to create the
       function and ignores a failure due to a lack of permission. Thanks to
       Alastair Douglas for the report and solution (#874)!
     - Added missing CockroachDB templates. Thanks to @Peterbyte for the
       report (#878)!
     - Removed support for the `SNOWSQL_PORT` environment variable, which has
       long been deprecated by Snowflake and likely never did anything.

Changes  view on Meta::CPAN

       but not created. Thanks to @jfeaver for the report (#686).
     - Output the list of changes to be deployed or reverted when `--verbose`
       is specified at least twice. Thanks to @vectro for the PR (#702).
     - Fixed the formatting of the log and plan commands to allow empty or `0`
       separators in lists of things (such as `%{0}t` for a list of tags).
       Thanks to @web-vertalo for the pull request (#703).
     - Updated the MySQL Tutorial to use 5.7 features. Thanks to Vlad
       Safronov for the PR (#705).
     - Deprecated the `no_prompt` and `no_prompt` attributes of
       App::Sqitch::Engine in favor of passing booleans to the `revert` and
       `verify` methods. The attributes still exist for reverse compatibility,
       but now emit warnings and will be removed in the future. Thanks to
       Thanks to @vectro for the PR (#704).
     - Added a warning for a double extension on the file names created
       by the `add` command. Thanks to @blairjordan for the PR (#724)!
     - Added the `revert.strict` boolean configuration variable which, when
       set to true, requires the specification of a change to revert to. It
       also disables the `rebase` and `checkout` commands, though the
       `rebase.strict` and `checkout.strict` variables, respectively, may
       override it. Use `revert.strict` to prevent accidental reverts in
       sensitive environments. Thanks to @vectro for the PR (#719; revised in

Changes  view on Meta::CPAN

       change such as `foo:greeble`, Sqitch would raise an error if
       `foo:greeble` was reworked, suggesting that the dependency be
       tag-qualified to eliminate ambiguity. Now reworked dependencies may be
       required without tag-qualification, though tag-qualification should still
       be specified if functionality as of a particular tag is required.
     - Added a workaround for the shell quoting issue on Windows. Applies to
       IPC::System::Simple 1.29 and lower. See
       [pjf/ipc-system-simple#29](https://github.com/pjf/ipc-system-simple/pull/29)
       for details (#413).
     - Fixed an issue with the MariaDB client where a deploy, revert, or
       verify failure was not properly propagated to Sqitch. Sqitch now passes
       `--abort-source-on-error` to the Maria `mysql` client to ensure that
       SQL errors cause the client to abort with an error so that Sqitch can
       properly handle it. Thanks to @mvgrimes for the original report and,
       years later, the fix (#209).
     - Fixed an issue with command argument parsing so that it truly never
       returns a target without an engine specified, as documented.
     - Removed documentation for methods that don't exist.
     - Fixed test failures due to a change in Encode v2.99 that's stricter
       about `undef` arguments that should be defined.

Changes  view on Meta::CPAN

       lets engines be determined strictly from command-line arguments --
       derived from targets, or just listed on their own -- whether or not
       `core.engine` is set. This change eliminates the need for the
       `no_default` parameter to the `parse_args()` method of App::Sqitch
       Command. It also greatly reduces the need for the core `--engine`
       option, which was previously required to work around this issue (see
       below for its removal).
     - Refactored config handling in tests to use a custom subclass of
       App::Sqitch::Config instead of various mocks, temporary files, and the
       like.
     - Added advice to use the PL/pgSQL `ASSERT()` function for verify scripts
       to the Postgres tutorial. Thanks to Sergii Tkachenko for the PR (#425).

     [Target Variables]
     - The `verify` command now reads `deploy.variables`, and individual
       `verify.variables override `deploy.variables`, on the assumption that
       the verify variables in general ought to be the same as the deploy
       variables. This makes `verify` variable configuration consistent with
       `revert` variable configuration.
     - Variables set via the `--set-deploy` option on the `rebase` and
       `checkout` commands no longer apply to both reverts and deploys, but
       only deploys. Use the `--set` option to apply a variable to both
       reverts and deploys.
     - Added support for core, engine, and target variable configuration. The
       simplest way to use them is via the `--set` option on the `init`,
       `engine`, and `target` commands. These commands allow the configuration
       of database client variables for specific engines and targets, as well
       as defaults that apply to all change execution commands (`deploy`,
       `revert`, `verify`, `rebase`, and `checkout`). The commands merge the
       variables from each level in this priority order:
       * `--set-deploy` and `--set-revert` options on `rebase` and `checkout`
       * `--set` option
       * `target.$target.variables`
       * `engine.$engine.variables`
       * `deploy.variables`, `revert.variables`, and `verify.variables`
       * `core.variables`
       See `sqitch-configuration` for general documentation of of the
       hierarchy for merging variables and the documentation for each command
       for specifics.

     [Options Unification]
     - Added the `--chdir`/`--cd`/`-C` option to specify a directory to change
       to before executing any Sqitch commands. Thanks to Thomas Sibley for
       the suggestion (#411).
     - Added the `--no-pager` option to disable the pager (#414).

Changes  view on Meta::CPAN

       has been added as an alias for `--version`, although `-v` remains for
       now, undocumented. It may be removed in the future should a compelling
       use for `-v` in a command be discovered.
     - All other options have been moved to the commands they affect. Their
       use should remain mostly unchanged now that command options are parsed
       from anywhere on the command-line, although we recommend that all
       options come after commands. The options were moved as follows:
       * `--registry`, `--client`, `--db-name`, `--db-user`, `--db-host`, and
         `--db-port` (and their aliases) have been moved to the `checkout`,
         `deploy`, `log`, `rebase`, `revert`, `status`, `upgrade`, and
         `verify` commands.
       * `--plan-file` and `--top-dir` (deprecated; see below) have been moved
         to the `add`, `bundle`, `checkout`, `deploy`, `rebase`, `revert`,
         `rework`, `show`, `status`, `tag`, and `verify` commands. They were
         already supported by the `init`, `engine`, and `target` commands
         (where `--top-dir` is not deprecated).
     - Because some command options conflicted with core options, a few
       options have been removed altogether, including:
       * The `--verbose` option on the `--engine` and `--target` commands has
         been removed, but no visible change should be apparent, since those
         commands now read the core `--verbose` option.
       * The undocumented `--dir` alias for `--top-dir` has been removed, as
         it conflicted with the option of the same name but different meaning
         in the `init`, `engine`, and `target` commands.
       * The `-d` alias for `--set-deploy` in the `rebase` and `checkout`
         commands has been changed to `-e` so as not to conflict with the `-d`
         alias for `--db-name`.
       * Added tests for all commands to ensure none of their options conflict
         with core options. Will help prevent conflicts in the future.

     [Deprecations & Removals]
     - Deprecated the `--top-dir` option in favor of `--chdir` with a warning
       except when used for configuration in the `init`, `engine`, and
       `target` commands.
     - Removed the core `--deploy-dir`, `--revert-dir`, and `--verify-dir`
       options, which have been deprecated and triggering warnings since
       v0.9993 (August 2015). The `--dir` option to the `init`, `engine`, and
       `target` commands remains the favored interface for specifying script
       directories.
     - Removed the deprecated core `--engine` option. The `init` command still
       supports it, while other commands are able to parse the engine name as
       an argument --- e.g., `sqitch deploy mysql` --- or implicitly as part
       of a target, as in `sqitch revert db:pg:tryme`. When Sqitch is unable
       to determine the engine for a command, the error message no longer
       mentions `--engine` and instead suggests specifying the engine via the
       target. This option never triggered an error, but demonstration of its
       use has been limited to `init` examples.
     - Removed support for reading the `core.$engine` configuration, which has
       been deprecated with warnings in favor of `engine.$engine` since 0.997
       (November 2014). The `sqitch engine update-config` action remains
       available to update old configurations, but may be removed in the
       future.
     - Removed the `--deploy`, `--revert`, and `--verify` options on the `add`
       command, as well as their `--no-*` variants. They have been deprecated
       with warnings in favor of the `--with` and `--without` options since
       v0.990 (January 2014).
     - Removed the `--deploy-template`, `--revert-template`, and
       `--verify-template` options to the `add` command. They have been
       deprecated with warnings in favor of the `--use` option since v0.990
       (January 2014).
     - Removed the `add.deploy_template`, `add.revert_template`, and
	   `add.verify_template` configuration settings. They have been deprecated
	   with warnings in favor of the `add.templates` configuration section
       since v0.990 (January 2014).
     - Removed the `@FIRST` and `@LAST` symbolic tags, which have been
       deprecated with warnings in favor of `@ROOT` and `@HEAD`, respectively,
       since 0.997 (November 2014).
     - Removed the command-specific options with the string "target" in them,
       such as `--to-target`, `--upto-target`, which have been deprecated with
       warnings in in favor of options containing the string "change", such as
       `--to-change` and `--upto-change`, since v0.997 (November 2014).
     - Remove the `engine` and `target` command `set-*` actions and their

Changes  view on Meta::CPAN

     - Documented all supported engine-specific environment variables in the
       sqitch-environment guide.
     - Renamed the sqitch-passwords guide to sqitch-authentication and added a
       section on username specification.
     - Updated all URLs to use the https scheme. Only exceptions are tt2.org,
       which doesn't support TLS, and conferences.embarcadero.com, which
       appears to be down.

0.9997 2018-03-15T21:13:52Z
     - Fixed the Firebird engine to properly detect multiple instances of a
       change specified to `revert` and `verify`, matching the behavior of
       displaying tag-qualified alternates added to the other engines in
       v0.9996.
     - Fixed test failure on Windows.
     - Updated the MySQL and PostgreSQL tests to use process-specific database
       names, to try to avoid conflicts when tests are being run by multiple
       processes on the same box, as happens with CPAN smoke testing boxes.
     - Fixed an issue where Sqitch would sometimes truncate the registry
       version number fetched from Postgres, most likely because the Perl
       runtime was using 32-bit integers. Fixed by casting the version to text
       in the query, before Perl ever see it. Thanks to Malte Legenhausen for

Changes  view on Meta::CPAN

     - Removed `no Moo::sification`, to allow modules to be used by Moose
       applications. Replaced with tests to make sure Sqitch itself never uses
       Moose. Thanks to @perigrin for the PR (#332).
     - Specifying a change before a target name on the command-line no longer
       ignores the target (#281).
     - The `--db-*` options are now more consistently applied to a target,
       including when the target is specified as a URI (#293).
     - `HEAD` and `ROOT` are now properly recognized as aliases for `@HEAD`
       and `@ROOT`, when querying the database. This was supposedly done in
       v0.991, but due to a bug, it wasn't really. Sorry about that.
     - The `revert` and `verify` commands will now fail if a change is
       specified and matches multiple changes. This happens when referencing a
       reworked change only by its name. In this case, Sqitch will emit an
       error listing properly tag-qualified changes to use. Suggested by Jay
       Hannah (#312).
     - Sqitch no longer returns an error when a target name is passed to a
       command and the default target's plan file does not exist (#324).
     - Added missing options to the `rework` usage statement. Thanks to Jay
       Hannah for the PR (#342).
     - Passing an engine name or plan file as the `<database>` parameter to
       the `log`, `status`, and `upgrade` commands now works correctly,

Changes  view on Meta::CPAN

     - Added the `--target` option to the `plan` and `show` commands.
     - Added the `<database>` parameter to the `plan` command.
     - Sqitch now loads targets from all config files, not just the local
       file, when trying to determine if a `<database>` parameter is a plan
       file name.
     - Improved the error message when a change is found more than once in a
       plan, typically a reworked changed referenced only by name. The error
       will no longer be "Key at multiple indexes", but "Change is ambiguous.
       Please specify a tag-qualified change:", followed by a list of
       tag-qualified variants of the change.
     - Fixed a bug where the verify command would return a database error when
       it finds no registry. Now it reports that the registry wasn't found in
       the database.

0.9995 2016-07-27T09:23:55Z
     - Taught the `add` command not to ignore the `--change` option.
     - The `add` command now emits a usage statement when no change name is
       passed to it.
     - The `add` command now helpfully suggests using the --change option when
       attempting to add a change with the same name as a target. Thanks to
       Ivan Nunes for the report!

Changes  view on Meta::CPAN

       (#265).
     - Added missing dash to `-engine` in sample calls to `sqitch init` in the
       tutorials. Thanks to Andrew Dunstan for the spot (Issue #268).
     - Fixed broken Vertica documentation links.
     - Attempting to revert a database with no associated registry no longer
       reports the registry as version 0, but correctly reports that no
       registry can be found. Thanks to Arnaldo Piccinelli for the spot (Issue
       #271).
     - Fixed the search for change IDs in engines to match the search for
       changes. Specifically, change ID search now properly handles the
       offset characters `~` and `^`. This bug mainly affected the `verify`
       command, but it's good to address the inconsistency, done mainly by
       adding the `find_change_id` and `change_id_offset_from_id` methods to
       complement the `find_change` and `change_offset_from_id` methods.
       Thanks to Andrew Dunstan for the spot (Issue #272).
     - Fixed the `flips` table example in the MySQL tutorial. It was
       inappropriately copied from the PostgreSQL tutorial at some point.
       Thanks to Jeff Carpenter for the spot (Issue #254)!

0.9993  2015-08-17T17:55:26Z
     [Bug Fixes]

Changes  view on Meta::CPAN

       been reworked two or more times. Was fixed for the other engines in
       v0.9991.
     - Fixed the `--all` option used to apply a command to all known targets
       so that it loads only targets specified by the local configuration.
       Otherwise, user and system configuration can get in the way when they
       specify engines and targets not used by the current project.
     [Improvements]
     - Added support for the `--set` option when deploying to MySQL. Thanks to
       Chris Bandy for figuring out how to do it!
     - Added support for a "reworked directory". By default, reworked change
       scripts live in the deploy, revert, and verify directories along with
       all the other change scripts. But if that starts to get too messy, or
       you simply don't want to see them, add a `reworked_dir` setting to the
       core, engine, or target config and reworked scripts will be stored
       there, instead. Also supported are `reworked_deploy_dir`,
       `reworked_revert_dir`, and `reworked_verify_dir`.
     - Added the `--dir` option to the `init`, `engine`, and `target`
       commands.
     - Copied the core configuration options (`--engine`, `--target`,
       `--plan-file`, `--registry`, etc.) to the `init`, `engine`, and
       `target` commands. This means that they can be specified after the
       command, which is a bit more natural. It also means that the
       `--registry` and `--client` options of the `target` are no longer
       deprecated.
     - The `init` command no longer writes out commented values for the
       `deploy_dir`, `revert_dir`, or `verify_dir` settings. I think these
       settings are not commonly used, and it would start to get crowded if we
       also added their "reworked" variants, which will be used still less.
     - Added the `alter` action to the `engine` and `target` commands to set
       engine and target properties.
     - Added support for setting reworked directories to the `engine` and
       `target` commands.
     - Reformatted the output of the `engine` and `target` command `show`
       actions to include reworked directories, and to bit a bit less flat.
     - Attempting to add or alter an engine with a target URI that connects to
       a different engine now triggers an error. For example, you can't set
       the target for engine `pg` to `db:sqlite:`.
     - The `add` and `alter` actions of the `engine` and `target` commands
       now create script directories if they don't already exist.
     - The `add` action of the `engine` and `target` commands now creates a
       plan file if one does not exist in the specified location for the
       engine or target.
     - Added the `deploy_dir`, `revert_dir`, and `verify_dir` methods to
       App::Sqitch::Plan::Change. Each points to the proper directory for the
       target depending on whether or not the change has been reworked.
     - In the MySQL engine, the following URI query params will be converted
       to options passed to the command-line client, if they're present:
       * mysql_compression=1   => --compress
       * mysql_ssl=1           => --ssl
       * mysql_connect_timeout => --connect_timeout
       * mysql_init_command    => --init-command
       * mysql_socket          => --socket
       * mysql_ssl_client_key  => --ssl-key
       * mysql_ssl_client_cert => --ssl-cert
       * mysql_ssl_ca_file     => --ssl-ca
       * mysql_ssl_ca_path     => --ssl-capath
       * mysql_ssl_cipher      => --ssl-cipher
     [Documentation]
     - Added the "Overworked" section to sqitch-configuration guide with an
       example of how to move reworked change scripts into a `reworked_dir`.
     [Deprecations]
     - Deprecated the `set-*` actions in the `engine` and `target` commands in
       favor of the new `alter` action.
     - The core `--deployed-dir`, `--revert-dir`, and `--verify-dir` options
       are deprecated in favor of the `--dir` option on the `init`, `engine`,
       and `target` command.

0.9992 2015-05-20T23:51:41Z
     - On PostgreSQL, Sqitch now sets the `client_encoding` parameter to
       `UTF8` for its own connection to the database. This ensures that data
       sent to and from the database should always be properly encoded and
       decoded. Users should still set the proper encodings for change scripts
       as appropriate.
     - Fixed test failures due to path differences on Windows.

Changes  view on Meta::CPAN

     - Reduced minimum required MySQL engine from 5.6.4 to 5.1.0. Versions
       prior to 5.6.4 lose the following features:
       * Versions earlier than 5.6.4 is fractional second precision on
         registry `DATETIME` columns. Since the ordering of those timestamps
         is so important to the functioning of Sqitch, it will sleep in 100 ms
         increments between logging changes to the registry until the time has
         ticked over to the next second. Naturally, reverts and deploys will
         be a little slower on versions of MySQL before 5.6.4, but accurate.
       * Versions earlier than 5.5.0 lose the `checkit()` functions, which
         would otherwise be used to emulate CHECK constraints in the registry,
         as well as in user-created verify scripts, as recommended in the
         MySQL tutorial, `sqitchtutorial-mysql`.
     - Added a script to update the `DATETIME` columns in a MySQL Sqitch
       registry that was upgraded to MySQL 5.6.4 or higher. It will be
       installed as `tools/upgrade-registry-to-mysql-5.6.4.sql` in the
       directory returned by `sqitch --etc`.
     - Added a script to add the `checkit()` function and registry triggers to
       emulate CHECK constraints to a MySQL Sqitch registry that was upgraded
       to MySQL 5.5.0 or higher. It will be installed as
       `tools/upgrade-registry-to-mysql-5.5.0.sql` in the directory returned
       by `sqitch --etc`.

Changes  view on Meta::CPAN

     - Made the registry upgrade more transparent when deploying. Sqitch is
       now is a little more vigilant in checking for things being out-of-date
       and updating them.
     - Fixed an issue where the `status` command would return an error when
       run against a an older version of the registry.
     - Fixed a Postgres test failure when DBD::Pg is installed but psql is not
       in the path.
     - Now require Config::GitLike 1.15 to build on Windows in order to avoid
       test failures when Cwd::abs_path dies on non-existent paths.
     - Clarified the behavior of each `deploy` reversion mode with regard to
       deploy script vs. verify script failures, and with the expectation that
       deploy scripts are atomic.
     - Target passwords can now be set via a single environment variable,
       `$SQITCH_PASSWORD`. Its value will override URI-specified password.
     - Added the sqitch-passwords and sqitch-environment guides.

0.998  2015-01-15T22:17:44Z
     - Fixed a bug in `sqitch engine update-config` where it would add data to
       config files that did not previously have them, or report that data was
       present in nonexistent config files.
     - Added the `releases` table to the databases. This table will keep track

Changes  view on Meta::CPAN

     [New Features]
     - Added support for new target properties. In addition to the existing
       `uri`, `client`, and `registry` properties, targets may also configure
       these properties via the new `--set` option to and `set-*` actions on
       the `target` command:
       * `top_dir`
       * `plan_file`
       * `extension`
       * `deploy_dir`
       * `revert_dir`
       * `verify_dir`
     - Added support for new engine configuration variables. In addition to
       the existing `target`, `client`, and `registry` variables, engine
       configuration may also include these variables:
       * `top_dir`
       * `plan_file`
       * `extension`
       * `deploy_dir`
       * `revert_dir`
       * `verify_dir`
     - Rationalized the hierarchical configuration of deployment targets. The
       properties of any given target will now be determined by examining
       values in the following order:
       * Command-line options
       * Target configuration
       * Engine configuration
       * Core configuration
       * Reasonable engine-specific defaults
     - Added the `engine` command to simplify engine configuration. This
       complements the newly-improved `target` command. Run `sqitch engine

Changes  view on Meta::CPAN

       * `core.$engine.db_name`
     - Deprecated the `--registry` and `--client` options of the `target`
       command. All target properties should now be set via the new `--set`
       option, such as `--set registry=reg`.
     - Formally deprecated the following options of the `add` command. They
       have been replaced with the `--with`, `--without`, and `--use` options
       since v0.991. Their use will emit a warning, and they will be removed
       in v1.0:
       * `--deploy-template`
       * `--revert-template`
       * `--verify-template`
       * `--deploy`
       * `--no-deploy`
       * `--revert`
       * `--no-revert`
       * `--verify`
       * `--no-verify`
     - Dropped support for the long-deprecated (and likely never used outside
       ancient tests long deleted) engine configuration variables
       `core.sqlite.sqitch_db` and `core.pg.sqitch_schema`. Both have been
       replaced with `engine.$engine.registry`, which applies to all engines.
     - Formally deprecated the `@FIRST` and `@LAST` symbolic tags. Their use
       will trigger a warning to use `@ROOT` and `@HEAD`, instead. They will
       be removed in v1.0.
     [Internals]
     - Moved target and engine configuration from App::Sqitch and
       App::Sqitch::Engine to a new class, App::Sqitch::Target. This class is

Changes  view on Meta::CPAN

         `target` is not passed or configured, or if it has no registry
         associated with it, the `config.$engine.registry` configuration
         variable is used. If no value is found there, it defaults to an
         engine-specific value, usually "sqitch".

     [Bug Fixes]
     - Fixed a bug when installing under local::lib. Thanks to Thomas Sibley
       for the pull request!
     - Eliminated "Wide character in print" warnings when piping the `log`
       command.
     - Documented that reworked changes do not have their verify tests run by
       the `verify` command. They do run when using the `--verify` deploy
       option.
     - Removed the documentation for the `add.with_deploy`, `add.with_revert`,
       and `add.with_verify` configuration variables, which were never
       implemented.

     [Deprecations]
     - Deprecated engine-specific connection attributes and configuration
       variables. See the "Internals" section for their replacements. The
       deprecated options are:
       * `core.$engine.username`
       * `core.$engine.password`
       * `core.$engine.db_name`
       * `core.$engine.host`
       * `core.$engine.port`
       * `core.$engine.sqitch_schema`
       * `core.$engine.sqitch_db`
     - Deprecated all command-specific options with the string "target" in
       them, such as `--to-target`, `--upto-target`, etc. They have been
       replaced with options containing the string "change", instead, such as
       `--to-change` and `--upto-change`. Few people used these options,
       preferring their shorter aliases (`--to`, `--upto`, etc.).
     - Deprecated the `--deploy-template`, `--revert-template`, and
       `--verify-template` options to the `add` command. They are replaced
       with a single option, `--use` which takes a key/value pair for the
       script name and template path. This makes it useful for arbitrary
       script generation, as well.
     - Deprecated the `--deploy`, `--revert`, and `--verify` options to the
       `add` command, as well as their `--no-*` variants. They are replaced
       with two new options, `--with` and `--without`, to which a script name
       is passed. These are useful for arbitrary script generation, as well.
     - Deprecated the `add.deploy_template`, `add.revert_template`, and
       `add.verify_template` configuration settings. They have been replaced
       with a section, `add.templates`, which is more general, and supports
       arbitrary script generation, as well.

     [Incompatibilities]
     - Removed the undocumented `--test` option to the `add` command.
     - Changed the meaning of `--target` from specifying a change to
       specifying a deployment target. Use the new `--change` option to
       specify a change.

0.983  2013-11-21T21:50:12Z

Changes  view on Meta::CPAN

       "changes" table is missing. This should catch the case where the
       database has its own "changes" table unrelated to Sqitch.

0.982  2013-09-11T18:26:07Z
     - Errors thrown by Template toolkit are no longer silently ignored.
     - Variables passed to change templates are now cloned before the
       execution of each template. This prevents one template from deleting
       variable values another template might also need.
     - Fixed "The getpwnam function is unimplemented" errors on Win32.
     - No longer runs revert scripts when deploying with `--log-only` and a
       verify script fails, as that could lead to data loss (yikes!). Thanks
       to BryLo for the report (issue #112).

0.981  2013-09-06T00:22:26Z
     - Now use Encode::Locale to try to decode the user's full name from the
       system encoding when fetched from the system on all OSes. Note that
       this is not necessary if the `user.name` config is explicitly set, as
       recommended. Issue #107.
     - Removed the special-case handling of the user's full name fetched from
       the system on OS X.
     - Added call to `sleep` to test in an attempt to fix SQLite failures.

Changes  view on Meta::CPAN

       rather than just vertical white space. Thanks to Ronan Dunklau for the
       report (issue #106).
     - The `status` command now notices if the specified database is
       uninitialized and says as much, rather than dying with an SQL error
       (issue #109).
     - When reading the user's username from the system Sqitch now uses
       Encode::Locale to try to decode the value from the system encoding.
       Issue #107.
     - Compatibility change: Changed the location and name of script template
       files. Previously they were called `deploy.tmpl`, `revert.tmpl`, and
       `verify.tmpl`, and they lived in the `templates` subdirectory of the
       system-wide and user-specific configuration directories. They now live
       in subdirectories of the `templates` directory named for each action
       (deploy, revert, and verify), and with file names matching engine names
       (`pg.tmpl`, `sqlite.tmpl`, `oracle.tmpl`, and `mysql.tmpl`). The
       installer will move old files from the system-wide config directory
       (`sqitch --etc-path`) to their new homes, named `pg.tmpl` and
       `sqlite.tmpl`. It assumes no customizations exist for Oracle. If that's
       not true in your case, simply copy the `pg.tmpl` files to
       `oracle.tmpl`.
     - Added the `--template-name` option to the `add` command. By default, it
       looks for templates named for the current engine. The option allows for
       the user of task-specific templates. For example, if you create
       templates named `createtable.tmpl` in the `deploy`, `revert`, and
       `verify` subdirectories of `~/.sqitch/templates`, You can specify
       `--template-name createtable` to use those templates when adding a
       change.
     - Added the `--exists` option to the `show` command.
     - Fixed the `--set` option to the `add` command so that duplicate keys
       have their values passed to the template as an array, as documented.
     - If Template::Toolkit is installed, the `add` command will use it for
       processing templates instead of Template::Tiny. This makes it easy to
       upgrade the templating environment just by installing a module.

0.973  2013-07-03T13:47:22Z

Changes  view on Meta::CPAN

       DBI-based engines can use this module to do all or most of the live
       testing.
     - Added the SQLite engine. The Sqitch metadata is stored in a separate
       file from a database, by default in the same directory as the database
       file.
     - Added `sqitchtutorial-sqlite.pod`, a SQLite-specific variant of
       `sqitchtutorial.pod`.

0.953  2013-02-21T23:37:57Z
     - Fixed test failure in `t/engine.t` triggered by a clock tick.
     - Changed the verify template to end with `ROLLBACK` rather than
       `COMMIT`. This it to encourage folks to make no lasting changes in
       verify tests.
     - Fixed exception triggered on an attempt to revert or rebase `--to` a
       change that does not exist in the database.
     - Added recommendation for Pod::Simple to the build process.
     - Added the `--etcdir` build option to specify the directory in which
       configuration and template files should be installed. Defaults to the
       `etc/sqitch` subdirectory of the `--prefix`, `--install_base`, or
       Perl's prefix.
     - Added the `--installed_etcdir` build option. This is used to set
       the location of the system etc directory. Defaults to the value of
       `--etcdir`.

Changes  view on Meta::CPAN

       converted to Sqitch, and you need to log changes as deployed because
       they have been deployed by other means in the past.
     - Now check that dependencies are required for all changes to be deployed
       or reverted before deploying or reverting anything, rather than
       checking dependencies for each change just before deploying or reverting
       it. This allows a or revert deploy to fail sooner, with no database
       changes, when dependencies are not met.
     - The `deploy` command now checks that no changes its about to deploy are
       already deployed.
     - Added `--mode` to the `rebase` command.
     - Added the `--verify` option to `deploy` and `rebase`. Specify this
       option to run the verify script, if it exists, for each change after it
       is deployed. If the verify script dies, the deploy will be considered a
       failure and the requisite reversion (as specified for `--mode`) will
       begin.
     - Added the `verify` command, which verifies that a database is valid
       relative to the plan and each deployed change's verification scripts.
     - Changed the format of the list of changes output by `deploy` and
       `revert` so that each now gets "ok" or "not ok" printed on success or
       failure.
     - Added short aliases for commonly-used core options:
       * -f for --plan-file
       * -v for --verbose
       * -h for --db-host
       * -p for --db-port

Changes  view on Meta::CPAN

     - The `add` command now throws an exception if `--template-directory` is
       passed or specified in the configuration file, and the specified
       directory does not exist or is not a directory. Thanks to Ronan Dunklau
       for the report! (Issue #52).
     - The `revert` command now prompts for confirmation before reverting
       anything. The prompt can be skipped via the `-y` option or setting the
       `revert.no_prompt` configuration variable. Works for rebase, too, which
       reads `rebase.no_prompt` before `revert.no_prompt`.' (Issue #49.)
     - Added the `show` command, which show information about changes or tags,
       or the contents of change script files. (Issue #57.)
     - Renamed the `test` scripts and planned command to `verify`.

0.938 2012-10-12T19:16:57Z
     - Added a primary key to the PostgreSQL `events` table, which should make
       it easier to support replication.

0.937 2012-10-09T21:54:36Z
     - Fixed the `--to` option to `deploy` and `revert`, which was ignored
       starting in v0.936.

0.936 2012-10-09T19:11:5Z2

MANIFEST  view on Meta::CPAN

etc/templates/revert/clickhouse.tmpl
etc/templates/revert/cockroach.tmpl
etc/templates/revert/exasol.tmpl
etc/templates/revert/firebird.tmpl
etc/templates/revert/mysql.tmpl
etc/templates/revert/oracle.tmpl
etc/templates/revert/pg.tmpl
etc/templates/revert/snowflake.tmpl
etc/templates/revert/sqlite.tmpl
etc/templates/revert/vertica.tmpl
etc/templates/verify/clickhouse.tmpl
etc/templates/verify/cockroach.tmpl
etc/templates/verify/exasol.tmpl
etc/templates/verify/firebird.tmpl
etc/templates/verify/mysql.tmpl
etc/templates/verify/oracle.tmpl
etc/templates/verify/pg.tmpl
etc/templates/verify/snowflake.tmpl
etc/templates/verify/sqlite.tmpl
etc/templates/verify/vertica.tmpl
etc/tools/upgrade-registry-to-mysql-5.5.0.sql
etc/tools/upgrade-registry-to-mysql-5.6.4.sql
inc/Menlo/Sqitch.pm
inc/Module/Build/Sqitch.pm
lib/App/Sqitch.pm
lib/App/Sqitch/Command.pm
lib/App/Sqitch/Command/add.pm
lib/App/Sqitch/Command/bundle.pm
lib/App/Sqitch/Command/check.pm
lib/App/Sqitch/Command/checkout.pm

MANIFEST  view on Meta::CPAN

lib/App/Sqitch/Command/log.pm
lib/App/Sqitch/Command/plan.pm
lib/App/Sqitch/Command/rebase.pm
lib/App/Sqitch/Command/revert.pm
lib/App/Sqitch/Command/rework.pm
lib/App/Sqitch/Command/show.pm
lib/App/Sqitch/Command/status.pm
lib/App/Sqitch/Command/tag.pm
lib/App/Sqitch/Command/target.pm
lib/App/Sqitch/Command/upgrade.pm
lib/App/Sqitch/Command/verify.pm
lib/App/Sqitch/Config.pm
lib/App/Sqitch/DateTime.pm
lib/App/Sqitch/Engine.pm
lib/App/Sqitch/Engine/Upgrade/clickhouse-1.0.sql
lib/App/Sqitch/Engine/Upgrade/clickhouse-1.1.sql
lib/App/Sqitch/Engine/Upgrade/cockroach-1.0.sql
lib/App/Sqitch/Engine/Upgrade/cockroach-1.1.sql
lib/App/Sqitch/Engine/Upgrade/exasol-1.0.sql
lib/App/Sqitch/Engine/Upgrade/exasol-1.1.sql
lib/App/Sqitch/Engine/Upgrade/firebird-1.0.sql

MANIFEST  view on Meta::CPAN

lib/sqitch-show-usage.pod
lib/sqitch-show.pod
lib/sqitch-status-usage.pod
lib/sqitch-status.pod
lib/sqitch-tag-usage.pod
lib/sqitch-tag.pod
lib/sqitch-target-usage.pod
lib/sqitch-target.pod
lib/sqitch-upgrade-usage.pod
lib/sqitch-upgrade.pod
lib/sqitch-verify-usage.pod
lib/sqitch-verify.pod
lib/sqitch.pod
lib/sqitchchanges.pod
lib/sqitchcommands.pod
lib/sqitchguides.pod
lib/sqitchtutorial-clickhouse.pod
lib/sqitchtutorial-exasol.pod
lib/sqitchtutorial-firebird.pod
lib/sqitchtutorial-mysql.pod
lib/sqitchtutorial-oracle.pod
lib/sqitchtutorial-snowflake.pod

MANIFEST  view on Meta::CPAN

t/sql/deploy/users.sql
t/sql/deploy/widgets.sql
t/sql/revert/curry.sql
t/sql/revert/dr_evil.sql
t/sql/revert/lolz.sql
t/sql/revert/roles.sql
t/sql/revert/tacos.sql
t/sql/revert/users.sql
t/sql/revert/widgets.sql
t/sql/sqitch.plan
t/sql/verify/users.sql
t/sqlite.t
t/status.t
t/tag.t
t/tag_cmd.t
t/target.conf
t/target.t
t/target_cmd.t
t/templates.conf
t/upgrade.t
t/user.conf
t/verify.t
t/vertica.t
t/win32.t
t/x.t

inc/Module/Build/Sqitch.pm  view on Meta::CPAN

    my $notify = 0;
    my $tmpl_dir = File::Spec->catdir(
        ( $self->destdir ? $self->destdir : ()),
        $self->_getetc,
        'templates'
    );
    if (-e $tmpl_dir && -d _) {
        # Scan for old templates, but only if we can read the directory.
        if (opendir my $dh, $tmpl_dir) {
            while (my $bn = readdir $dh) {
                next unless $bn =~ /^(deploy|verify|revert)[.]tmpl([.]default)?$/;
                my ($action, $default) = ($1, $2);
                my $file = File::Spec->catfile($tmpl_dir, $bn);
                if ($default) {
                    $self->log_verbose("Unlinking $file\n");
                    # Just unlink default files.
                    unlink $file;
                    next;
                }
                # Move action templates to $action/pg.tmpl and $action/sqlite.tmpl.
                my $action_dir = File::Spec->catdir($tmpl_dir, $action);

inc/Module/Build/Sqitch.pm  view on Meta::CPAN

            # locations as described above. However, user-specific          #
            # templates have not been moved.                                #
            #                                                               #
            # Please inform all users that any custom Sqitch templates in   #
            # their ~/.sqitch/templates directories must be moved into      #
            # subdirectories using the appropriate engine name (pg, sqlite, #
            # or oracle) as follows:                                        #
            #                                                               #
            #             deploy.tmpl -> deploy/$engine.tmpl                #
            #             revert.tmpl -> revert/$engine.tmpl                #
            #             verify.tmpl -> verify/$engine.tmpl                #
            #                                                               #
            #################################################################
        } . "\n");
    }
}

sub ACTION_install {
    my ($self, @params) = @_;
    $self->depends_on('move_old_templates');
    $self->SUPER::ACTION_install(@_);

lib/App/Sqitch/Command/add.pm  view on Meta::CPAN

        for my $subdir($dir->children) {
            next unless $subdir->is_dir;
            next if $tmpl->{my $script = $subdir->basename};
            my $file = $subdir->file("$name.tmpl");
            $tmpl->{$script} = $file if -f $file
        }
    }

    # Make sure we have core templates.
    my $with = $self->with_scripts;
    for my $script (qw(deploy revert verify)) {
        hurl add => __x(
            'Cannot find {script} template',
            script => $script,
        ) if !$tmpl->{$script} && ($with->{$script} || !exists $with->{$script});
    }

    return $tmpl;
}

sub options {

lib/App/Sqitch/Command/add.pm  view on Meta::CPAN

    $opts{set} = \%vars if %vars;

    # Convert dashes to underscores.
    for my $k (keys %opts) {
        next unless ( my $nk = $k ) =~ s/-/_/g;
        $opts{$nk} = delete $opts{$k};
    }

    # Merge with and without.
    $opts{with_scripts} = {
        ( map { $_ => 1 } qw(deploy revert verify) ),
        ( map { $_ => 1 } @{ delete $opts{with}    || [] } ),
        ( map { $_ => 0 } @{ delete $opts{without} || [] } ),
    };
    return \%opts;
}

sub configure {
    my ( $class, $config, $opt ) = @_;

    my %params = (

lib/App/Sqitch/Command/add.pm  view on Meta::CPAN

App::Sqitch::Command::add - Add a new change to Sqitch plans

=head1 Synopsis

  my $cmd = App::Sqitch::Command::add->new(%params);
  $cmd->execute;

=head1 Description

Adds a new deployment change. This will result in the creation of a scripts in
the deploy, revert, and verify directories. The scripts are based on
L<Template::Tiny> templates in F<~/.sqitch/templates/> or
C<$(prefix)/etc/sqitch/templates> (call C<sqitch --etc-path> to find out
where, exactly (e.g., C<$(sqitch --etc-path)/sqitch.conf>).

=head1 Interface

=head2 Class Methods

=head3 C<options>

lib/App/Sqitch/Command/bundle.pm  view on Meta::CPAN

    my $self = shift;
    dir $self->dest_dir, shift->top_dir->relative;
}

sub dest_dirs_for {
    my ($self, $target) = @_;
    my $dest = $self->dest_dir;
    return {
        deploy          => dir($dest, $target->deploy_dir->relative),
        revert          => dir($dest, $target->revert_dir->relative),
        verify          => dir($dest, $target->verify_dir->relative),
        reworked_deploy => dir($dest, $target->reworked_deploy_dir->relative),
        reworked_revert => dir($dest, $target->reworked_revert_dir->relative),
        reworked_verify => dir($dest, $target->reworked_verify_dir->relative),
    };
}

sub options {
    return qw(
        dest-dir|dir=s
        all|a!
        from=s
        to=s
    );

lib/App/Sqitch/Command/bundle.pm  view on Meta::CPAN

                $file,
                $dir_for->{"${prefix}deploy"}->file(@path)
            );
        }
        if (-e ( my $file = $change->revert_file )) {
            $self->_copy_if_modified(
                $file,
                $dir_for->{"${prefix}revert"}->file(@path)
            );
        }
        if (-e ( my $file = $change->verify_file )) {
            $self->_copy_if_modified(
                $file,
                $dir_for->{"${prefix}verify"}->file(@path)
            );
        }
        $plan->next;
    }

    return $self;
}

1;

lib/App/Sqitch/Command/bundle.pm  view on Meta::CPAN

=head3 C<bundle_plan>

 $bundle->bundle_plan($target);

Copies the plan file for the specified target to the bundle directory.

=head3 C<bundle_scripts>

 $bundle->bundle_scripts($target);

Copies the deploy, revert, and verify scripts for each step in the plan for
the specified target to the bundle directory. Files in the script directories
that do not correspond to changes in the plan will not be copied.

=head3 C<dest_top_dir>

  my $top_dir = $bundle->top_dir($target);

Returns the destination top directory for the specified target.

=head3 C<dest_dirs_for>

lib/App/Sqitch/Command/checkout.pm  view on Meta::CPAN

    my $target = shift @{ $targets };
    $self->warn(__x(
        'Too many targets specified; connecting to {target}',
        target => $target->name,
    )) if @{ $targets };

    # Now get to work.
    my $sqitch = $self->sqitch;
    my $git    = $self->client;
    my $engine = $target->engine;
    $engine->with_verify( $self->verify );
    $engine->log_only( $self->log_only );
    $engine->lock_timeout( $self->lock_timeout );

    # What branch are we on?
    my $current_branch = $sqitch->probe($git, qw(rev-parse --abbrev-ref HEAD));
    hurl {
        ident   => 'checkout',
        message => __x('Already on branch {branch}', branch => $branch),
        exitval => 1,
    } if $current_branch eq $branch;

lib/App/Sqitch/Command/deploy.pm  view on Meta::CPAN

    default  => 0,
);

has lock_timeout => (
    is      => 'ro',
    isa     => Int,
    lazy    => 1,
    default => sub { App::Sqitch::Engine::default_lock_timeout() },
);

has verify => (
    is       => 'ro',
    isa      => Bool,
    default  => 0,
);

has variables => (
    is       => 'ro',
    isa      => HashRef,
    lazy     => 1,
    default  => sub { {} },
);

sub options {
    return qw(
        target|t=s
        to-change|to|change=s
        mode=s
        set|s=s%
        log-only
        lock-timeout=i
        verify!
    );
}

sub configure {
    my ( $class, $config, $opt ) = @_;

    my %params = (
        mode     => $opt->{mode}   || $config->get( key => 'deploy.mode' )   || 'all',
        verify   => $opt->{verify} // $config->get( key => 'deploy.verify', as => 'boolean' ) // 0,
        log_only => $opt->{log_only} || 0,
    );
    for my $key (qw(to_change target lock_timeout)) {
        $params{$key} = $opt->{$key} if exists $opt->{$key};
    }
    if ( my $vars = $opt->{set} ) {
        $params{variables} = $vars;
    }

    return \%params;

lib/App/Sqitch/Command/deploy.pm  view on Meta::CPAN


    # Warn on too many changes.
    my $change = $self->to_change // shift @{ $changes };
    $self->warn(__x(
        'Too many changes specified; deploying to "{change}"',
        change => $change,
    )) if @{ $changes };

    # Now get to work.
    my $engine = $target->engine;
    $engine->with_verify( $self->verify );
    $engine->log_only( $self->log_only );
    $engine->lock_timeout( $self->lock_timeout );
    $engine->set_variables( $self->_collect_vars($target) );
    $engine->deploy( $change, $self->mode );
    return $self;
}

1;

__END__

lib/App/Sqitch/Command/deploy.pm  view on Meta::CPAN

Deploy mode, one of "change", "tag", or "all".

=head3 C<target>

The deployment target URI.

=head3 C<to_change>

Change up to which to deploy.

=head3 C<verify>

Boolean indicating whether or not to run verify scripts after each change.

=head2 Instance Methods

=head3 C<execute>

  $deploy->execute;

Executes the deploy command.

=head1 See Also

lib/App/Sqitch/Command/engine.pm  view on Meta::CPAN

    # Set up labels.
    my %label_for = (
        target       => __ 'Target',
        registry     => __ 'Registry',
        client       => __ 'Client',
        top_dir      => __ 'Top Directory',
        plan_file    => __ 'Plan File',
        extension    => __ 'Extension',
        revert       => '  ' . __ 'Revert',
        deploy       => '  ' . __ 'Deploy',
        verify       => '  ' . __ 'Verify',
        reworked     => '  ' . __ 'Reworked',
    );

    my $len = max map { length } values %label_for;
    $_ .= ': ' . ' ' x ($len - length $_) for values %label_for;

    # Header labels.
    $label_for{script_dirs} = __('Script Directories') . ':';
    $label_for{reworked_dirs} = __('Reworked Script Directories') . ':';
    $label_for{variables} = __('Variables') . ':';

lib/App/Sqitch/Command/engine.pm  view on Meta::CPAN

        $self->emit("* $engine");
        $self->emit('    ', $label_for{target},     $target->target);
        $self->emit('    ', $label_for{registry},   $target->registry);
        $self->emit('    ', $label_for{client},     $target->client);
        $self->emit('    ', $label_for{top_dir},    $target->top_dir);
        $self->emit('    ', $label_for{plan_file},  $target->plan_file);
        $self->emit('    ', $label_for{extension},  $target->extension);
        $self->emit('    ', $label_for{script_dirs});
        $self->emit('    ', $label_for{deploy}, $target->deploy_dir);
        $self->emit('    ', $label_for{revert}, $target->revert_dir);
        $self->emit('    ', $label_for{verify}, $target->verify_dir);
        $self->emit('    ', $label_for{reworked_dirs});
        $self->emit('    ', $label_for{reworked}, $target->reworked_dir);
        $self->emit('    ', $label_for{deploy}, $target->reworked_deploy_dir);
        $self->emit('    ', $label_for{revert}, $target->reworked_revert_dir);
        $self->emit('    ', $label_for{verify}, $target->reworked_verify_dir);
        my $vars = $target->variables;
        if (%{ $vars }) {
            my $len = max map { length } keys %{ $vars };
            $self->emit('    ', $label_for{variables});
            $self->emit("  $_: " . (' ' x ($len - length $_)) . $vars->{$_})
                for sort { lc $a cmp lc $b } keys %{ $vars };
        } else {
            $self->emit('    ', $label_for{no_variables});
        }
    }

lib/App/Sqitch/Command/init.pm  view on Meta::CPAN

            my $val //= $target->$name // '';
            push @comments => "\t$name = $val";
        }
    }

    # Add script options passed to the init command. No comments if not set.
    for my $attr (qw(
        extension
        deploy_dir
        revert_dir
        verify_dir
        reworked_dir
        reworked_deploy_dir
        reworked_revert_dir
        reworked_verify_dir
    )) {
        push @vars => { key => "core.$attr", value => $props->{$attr} }
            if defined $props->{$attr};
    }

    # Add variables.
    if (my $vars = $props->{variables}) {
        push @vars => map {{
            key   => "core.variables.$_",
            value => $vars->{$_},

lib/App/Sqitch/Command/rebase.pm  view on Meta::CPAN

        ? $engine->planned_deployed_common_ancestor_id
        : $self->onto_change // shift @{ $changes };
    my $upto = $self->upto_change // shift @{ $changes };
    $self->warn(__x(
        'Too many changes specified; rebasing onto "{onto}" up to "{upto}"',
        onto => $onto,
        upto => $upto,
    )) if @{ $changes };

    # Now get to work.
    $engine->with_verify( $self->verify );
    $engine->log_only( $self->log_only );
    $engine->lock_timeout( $self->lock_timeout );

    # Revert.
    $engine->set_variables( $self->_collect_revert_vars($target) );
    die unless defined $self->no_prompt;
    die unless defined $self->prompt_accept;
    try {
        $engine->revert( $onto, ! ($self->no_prompt), $self->prompt_accept );
    } catch {

lib/App/Sqitch/Command/rework.pm  view on Meta::CPAN


        # Record the files to be copied to the previous change name.
        push @{ $spec->{scripts} } => map {
            push @files => $_->[0] if -e $_->[0];
            $_;
        } grep {
            !$seen{ $_->[0] }++;
        } (
            [ $reworked->deploy_file, $prev->deploy_file ],
            [ $reworked->revert_file, $prev->revert_file ],
            [ $reworked->verify_file, $prev->verify_file ],
        );

        # Replace the revert file with the previous deploy file.
        push @{ $spec->{scripts} } => [
            $reworked->deploy_file,
            $reworked->revert_file,
            $prev->revert_file,
        ] unless $seen{$prev->revert_file}++;
    }

lib/App/Sqitch/Command/rework.pm  view on Meta::CPAN

App::Sqitch::Command::rework - Rework a Sqitch change

=head1 Synopsis

  my $cmd = App::Sqitch::Command::rework->new(%params);
  $cmd->execute;

=head1 Description

Reworks a change. This will result in the copying of the existing deploy,
revert, and verify scripts for the change to preserve the earlier instances of
the change.

=head1 Interface

=head2 Class Methods

=head3 C<options>

  my @opts = App::Sqitch::Command::rework->options;

lib/App/Sqitch/Command/show.pm  view on Meta::CPAN

            hurl show => __x( 'Unknown tag "{tag}"', tag => $key );
        }
        $self->emit( $tag->info ) unless $self->exists_only;
        return $self;
    }

    # Make sure we recognize the type.
    hurl show => __x(
        'Unknown object type "{type}',
        type => $type,
    ) unless first { $type eq $_ } qw(change deploy revert verify);

    # Make sure we have a change object.
    my $change = $plan->get($key) or do {
        return if $self->exists_only;
        hurl show => __x(
            'Unknown change "{change}"',
            change => $key
        );
    };

lib/App/Sqitch/Command/target.pm  view on Meta::CPAN


    my %label_for = (
        uri        => __('URI'),
        registry   => __('Registry'),
        client     => __('Client'),
        top_dir    => __('Top Directory'),
        plan_file  => __('Plan File'),
        extension  => __('Extension'),
        revert     => '  ' . __ 'Revert',
        deploy     => '  ' . __ 'Deploy',
        verify     => '  ' . __ 'Verify',
        reworked   => '  ' . __ 'Reworked',
    );

    my $len = max map { length } values %label_for;
    $_ .= ': ' . ' ' x ($len - length $_) for values %label_for;

    # Header labels.
    $label_for{script_dirs} = __('Script Directories') . ':';
    $label_for{reworked_dirs} = __('Reworked Script Directories') . ':';
    $label_for{variables} = __('Variables') . ':';

lib/App/Sqitch/Command/target.pm  view on Meta::CPAN

        $self->emit("* $name");
        $self->emit('    ', $label_for{uri},        $target->uri->as_string);
        $self->emit('    ', $label_for{registry},   $target->registry);
        $self->emit('    ', $label_for{client},     $target->client);
        $self->emit('    ', $label_for{top_dir},    $target->top_dir);
        $self->emit('    ', $label_for{plan_file},  $target->plan_file);
        $self->emit('    ', $label_for{extension},  $target->extension);
        $self->emit('    ', $label_for{script_dirs});
        $self->emit('    ', $label_for{deploy}, $target->deploy_dir);
        $self->emit('    ', $label_for{revert}, $target->revert_dir);
        $self->emit('    ', $label_for{verify}, $target->verify_dir);
        $self->emit('    ', $label_for{reworked_dirs});
        $self->emit('    ', $label_for{reworked}, $target->reworked_dir);
        $self->emit('    ', $label_for{deploy}, $target->reworked_deploy_dir);
        $self->emit('    ', $label_for{revert}, $target->reworked_revert_dir);
        $self->emit('    ', $label_for{verify}, $target->reworked_verify_dir);
        my $vars = $target->variables;
        if (%{ $vars }) {
            my $len = max map { length } keys %{ $vars };
            $self->emit('    ', $label_for{variables});
            $self->emit("  $_: " . (' ' x ($len - length $_)) . $vars->{$_})
                for sort { lc $a cmp lc $b } keys %{ $vars };
        } else {
            $self->emit('    ', $label_for{no_variables});
        }
    }

lib/App/Sqitch/Command/verify.pm  view on Meta::CPAN

package App::Sqitch::Command::verify;

use 5.010;
use strict;
use warnings;
use utf8;
use Moo;
use Types::Standard qw(Str HashRef);
use App::Sqitch::X qw(hurl);
use Locale::TextDomain qw(App-Sqitch);
use List::Util qw(first);

lib/App/Sqitch/Command/verify.pm  view on Meta::CPAN


    return \%params;
}

sub _collect_vars {
    my ($self, $target) = @_;
    my $cfg = $self->sqitch->config;
    return (
        %{ $cfg->get_section(section => 'core.variables') },
        %{ $cfg->get_section(section => 'deploy.variables') },
        %{ $cfg->get_section(section => 'verify.variables') },
        %{ $target->variables }, # includes engine
        %{ $self->variables },   # --set
    );
}

sub execute {
    my $self = shift;
    my ($targets, $changes) = $self->parse_args(
        target => $self->target,
        args   => \@_,

lib/App/Sqitch/Command/verify.pm  view on Meta::CPAN

    my $target = shift @{ $targets };
    $self->warn(__x(
        'Too many targets specified; connecting to {target}',
        target => $target->name,
    )) if @{ $targets };

    # Warn on too many changes.
    my $from = $self->from_change // shift @{ $changes };
    my $to   = $self->to_change   // shift @{ $changes };
    $self->warn(__x(
        'Too many changes specified; verifying from "{from}" to "{to}"',
        from => $from,
        to   => $to,
    )) if @{ $changes };

    # Now get to work.
    my $engine = $target->engine;
    $engine->set_variables( $self->_collect_vars($target) );
    $engine->verify($from, $to);
    return $self;
}

1;

__END__

=head1 Name

App::Sqitch::Command::verify - Verify deployed Sqitch changes

=head1 Synopsis

  my $cmd = App::Sqitch::Command::verify->new(%params);
  $cmd->execute;

=head1 Description

If you want to know how to use the C<verify> command, you probably want to be
reading C<sqitch-verify>. But if you really want to know how the C<verify> command
works, read on.

=head1 Interface

=head2 Class Methods

=head3 C<options>

  my @opts = App::Sqitch::Command::verify->options;

Returns a list of L<Getopt::Long> option specifications for the command-line
options for the C<verify> command.

=head2 Attributes

=head3 C<onto_change>

Change onto which to rebase the target.

=head3 C<target>

The verify target database URI.

=head3 C<from_change>

Change from which to verify changes.

=head3 C<to_change>

Change up to which to verify changes.

=head2 Instance Methods

=head3 C<execute>

  $verify->execute;

Executes the verify command.

=head1 See Also

=over

=item L<sqitch-verify>

Documentation for the C<verify> command to the Sqitch command-line client.

=item L<sqitch>

The Sqitch command-line client.

=back

=head1 Author

David E. Wheeler <david@justatheory.com>

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

        );
    }
);

has log_only => (
    is      => 'rw',
    isa     => Bool,
    default => 0,
);

has with_verify => (
    is      => 'rw',
    isa     => Bool,
    default => 0,
);

has max_name_length => (
    is      => 'rw',
    isa     => Int,
    default => 0,
    lazy    => 1,

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

    # something you generally want to recover from by deploying back to where
    # you started. But maybe I'm wrong?
    $self->max_name_length(
        max map { length $_->format_name_with_tags } @changes
    );
    $self->revert_change($_) for @changes;

    return $self;
}

sub verify {
    my ( $self, $from, $to ) = @_;
    # $from = verify changes after and including this one, or if undefined starting from the first change.
    # $to = verify changes up to but not including this one, or if undefined up to all changes.

    $self->_check_registry;
    my $sqitch   = $self->sqitch;
    my $plan     = $self->plan;
    my @changes  = $self->_load_changes( $self->deployed_changes );

    $sqitch->info(__x(
        'Verifying {destination}',
        destination => $self->destination,
    ));

    if (!@changes) {
        my $msg = $plan->count
            ? __ 'No changes deployed'
            : __ 'Nothing to verify (no planned or deployed changes)';
        $sqitch->info($msg);
        return $self;
    }

    if ($plan->count == 0) {
        # Oy, there are deployed changes, but not planned!
        hurl verify => __ 'There are deployed changes, but none planned!';
    }

    # Figure out where to start and end relative to the plan.
    my $from_idx = $self->_from_idx('verify', $from, \@changes);
    my $to_idx = $self->_to_idx('verify', $to, \@changes);

    # Run the verify tests.
    if ( my $count = $self->_verify_changes($from_idx, $to_idx, !$to, @changes) ) {
        # Emit a quick report.
        # XXX Consider coloring red.
        my $num_changes = 1 + $to_idx - $from_idx;
        $num_changes = @changes if @changes > $num_changes;
        my $msg = __ 'Verify Summary Report';
        $sqitch->emit("\n", $msg);
        $sqitch->emit('-' x length $msg);
        $sqitch->emit(__x 'Changes: {number}', number => $num_changes );
        $sqitch->emit(__x 'Errors:  {number}', number => $count );
        hurl verify => __ 'Verify failed';
    }

    # Success!
    # XXX Consider coloring green.
    $sqitch->emit(__ 'Verify successful');

    return $self;
}

sub _from_idx {

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

    if ($pop) {
        pop @{ $changes }   while $changes->[-1]->id ne $to_id;
    } else {
        shift @{ $changes } while $changes->[0]->id  ne $to_id;
    }

    # We good.
    return $to_idx;
}

sub _verify_changes {
    my $self     = shift;
    my $from_idx = shift;
    my $to_idx   = shift;
    my $pending  = shift;
    my $sqitch   = $self->sqitch;
    my $plan     = $self->plan;
    my $errcount = 0;
    my $i        = -1;
    my @seen;

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

                $sqitch->comment(__ 'Out of order');
                $errs++;
            }
            # Is it reworked?
            $reworked = $plan->change_at($plan_index)->is_reworked;
        } else {
            $sqitch->comment(__ 'Not present in the plan');
            $errs++;
        }

        # Run the verify script.
        try { $self->verify_change( $change ) } catch {
            $sqitch->comment(eval { $_->message } // $_);
            $errs++;
        } unless $reworked;

        # Emit pass/fail and add to the total error count.
        $sqitch->emit( $errs ? __ 'not ok' : __ 'ok' );
        $errcount += $errs;
    }

    # List any undeployed changes.

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

                @pending,
            ));

            $sqitch->emit( '  * ', $_->format_name_with_tags ) for @pending;
        }
    }

    return $errcount;
}

sub verify_change {
    my ( $self, $change ) = @_;
    my $file = $change->verify_file;
    if (-e $file) {
        return try { $self->run_verify($file) }
        catch {
            hurl {
                ident => 'verify',
                previous_exception => $_,
                message => __x(
                    'Verify script "{script}" failed.',
                    script => $file,
                ),
            };
        };
    }

    # The file does not exist. Complain, but don't die.
    $self->sqitch->vent(__x(
        'Verify script {file} does not exist',
        file => $file,
    ));

    return $self;
}

sub run_deploy  { shift->run_file(@_) }
sub run_revert  { shift->run_file(@_) }
sub run_verify  { shift->run_file(@_) }
sub run_upgrade { shift->run_file(@_) }

sub check_deploy_dependencies {
    my ( $self, $plan, $to_index ) = @_;
    my $from_index = $plan->position + 1;
    $to_index    //= $plan->count - 1;
    my @changes = map { $plan->change_at($_) } $from_index..$to_index;
    my (%seen, @conflicts, @required);

    for my $change (@changes) {

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

    $self->begin_work($change);

    return try {
        my $file = $change->deploy_file;
        hurl deploy => __x(
            'Deploy script {file} does not exist',
            file => $file,
        ) unless -e $file;
        $self->run_deploy($file) unless $self->log_only;
        try {
            $self->verify_change( $change ) if $self->with_verify;
            $self->log_deploy_change($change);
            $sqitch->info(__ 'ok');
        } catch {
            # Oy, logging or verify failed. Rollback.
            $sqitch->vent(eval { $_->message } // $_);
            $self->rollback_work($change);

            # Begin work and run the revert.
            try {
                # Don't bother displaying the reverting change name.
                # $self->sqitch->info('  - ', $change->format_name_with_tags);
                $self->begin_work($change);
                $self->run_revert($change->revert_file) unless $self->log_only;
            } catch {

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

=head3 C<start_at>

The point in the plan from which to start deploying changes.

=head3 C<log_only>

Boolean indicating whether or not to log changes I<without running deploy or
revert scripts>. This is useful for an existing database schema that needs to
be converted to Sqitch. False by default.

=head3 C<with_verify>

Boolean indicating whether or not to run the verification script after each
deploy script. False by default.

=head3 C<variables>

A hash of engine client variables to be set. May be set and retrieved as a
list.

=head2 Instance Methods

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

  $engine->revert;
  $engine->revert($tag);
  $engine->revert($tag);

Reverts the L<App::Sqitch::Plan::Tag> from the database, including all of its
associated changes.

Note that this method does not respect the C<$cmd.strict> configuration
variables, which therefore must be checked by the caller.

=head3 C<verify>

  $engine->verify;
  $engine->verify( $from );
  $engine->verify( $from, $to );
  $engine->verify( undef, $to );

Verifies the database against the plan. Pass in change identifiers, as
described in L<sqitchchanges>, to limit the changes to verify. For each
change, information will be emitted if:

=over

=item *

It does not appear in the plan.

=item *

It has not been deployed to the database.

=item *

It has been deployed out-of-order relative to the plan.

=item *

Its verify script fails.

=back

Changes without verify scripts will emit a warning, but not constitute a
failure. If there are any failures, an exception will be thrown once all
verifications have completed.

=head3 C<check>

  $engine->check;
  $engine->check( $from );
  $engine->check( $from, $to );
  $engine->check( undef, $to );

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

Used internally by C<deploy()> to deploy an individual change.

=head3 C<revert_change>

  $engine->revert_change($change);
  $engine->revert_change($change);

Used internally by C<revert()> (and, by C<deploy()> when a deploy fails) to
revert an individual change.

=head3 C<verify_change>

  $engine->verify_change($change);

Used internally by C<deploy_change()> to verify a just-deployed change if
C<with_verify> is true.

=head3 C<is_deployed>

  say "Tag deployed"  if $engine->is_deployed($tag);
  say "Change deployed" if $engine->is_deployed($change);

Convenience method that dispatches to C<is_deployed_tag()> or
C<is_deployed_change()> as appropriate to its argument.

=head3 C<earliest_change>

lib/App/Sqitch/Engine.pm  view on Meta::CPAN

Runs a deploy script. The implementation is just an alias for C<run_file()>;
subclasses may override as appropriate.

=head3 C<run_revert>

  $engine->run_revert($revert_file);

Runs a revert script. The implementation is just an alias for C<run_file()>;
subclasses may override as appropriate.

=head3 C<run_verify>

  $engine->run_verify($verify_file);

Runs a verify script. The implementation is just an alias for C<run_file()>;
subclasses may override as appropriate.

=head3 C<run_upgrade>

  $engine->run_upgrade($upgrade_file);

Runs an upgrade script. The implementation is just an alias for C<run_file()>;
subclasses may override as appropriate.

=head3 C<needs_upgrade>

lib/App/Sqitch/Engine/exasol.pm  view on Meta::CPAN

sub _run_with_verbosity {
    my $self = shift;
    my $file = $self->_file_for_script(shift);
    # Suppress STDOUT unless we want extra verbosity.
    #my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    my $meth = '_capture';
    $self->$meth(qq{\@"$file"});
}

sub run_upgrade { shift->_run_with_verbosity(@_) }
sub run_verify  { shift->_run_with_verbosity(@_) }

sub run_handle {
    my ($self, $fh) = @_;
    my $conn = $self->_script;
    open my $tfh, '<:utf8_strict', \$conn;
    $self->sqitch->spool( [$tfh, $fh], $self->exaplus );
}

# Exasol treats empty string as NULL; adjust accordingly..

lib/App/Sqitch/Engine/firebird.pm  view on Meta::CPAN

    my $pass   = $self->password or return $sqitch->spool( $fh, $self->isql, @_ );
    local $ENV{ISC_PASSWORD} = $pass;
    return $sqitch->spool( $fh, $self->isql, @_ );
}

sub run_file {
    my ($self, $file) = @_;
    $self->_run( '-input' => $file );
}

sub run_verify {
    my ($self, $file) = @_;
    # Suppress STDOUT unless we want extra verbosity.
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    $self->$meth( '-input' => $file );
}

sub run_upgrade {
    my ($self, $file) = @_;
    my $uri    = $self->registry_uri;
    my @cmd    = $self->isql;

lib/App/Sqitch/Engine/mysql.pm  view on Meta::CPAN

    my $pass   = $self->password or return $sqitch->spool( \@fh, $self->mysql, @_ );
    local $ENV{MYSQL_PWD} = $pass;
    return $sqitch->spool( \@fh, $self->mysql, @_ );
}

sub run_file {
    my $self = shift;
    $self->_run( $self->_source(@_) );
}

sub run_verify {
    my $self = shift;
    # Suppress STDOUT unless we want extra verbosity.
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    $self->$meth( $self->_source(@_) );
}

sub run_upgrade {
    my ($self, $file) = @_;
    my @cmd = $self->mysql;

lib/App/Sqitch/Engine/mysql.pm  view on Meta::CPAN

    require File::Temp;
    my $fh = File::Temp->new;
    print $fh $sql;
    close $fh;
    return $fh;
}

sub _create_check_function {
    # The checkit() function works sort of like a CHECK: if the first argument
    # is 0 or NULL, it throws the second argument as an exception.
    # Conveniently, verify scripts can also use it to ensure an error is
    # thrown when a change cannot be verified. Requires MySQL 5.5.0 and
    # permission to create an immutable function, so ignore failures in those
    # situations.
    my $self = shift;
    return if $self->dbh->{mariadb_serverversion} < 50500;
    try {
        $self->dbh->do(q{
            CREATE FUNCTION checkit(doit INTEGER, message VARCHAR(256)) RETURNS INTEGER DETERMINISTIC
            BEGIN
                IF doit IS NULL OR doit = 0 THEN

lib/App/Sqitch/Engine/oracle.pm  view on Meta::CPAN


sub _run_with_verbosity {
    my $self = shift;
    my $file = $self->_file_for_script(shift);
    # Suppress STDOUT unless we want extra verbosity.
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    $self->$meth(qq{\@"$file"});
}

sub run_upgrade { shift->_run_with_verbosity(@_) }
sub run_verify  { shift->_run_with_verbosity(@_) }

sub run_handle {
    my ($self, $fh) = @_;
    my $conn = $self->_script;
    open my $tfh, '<:utf8_strict', \$conn;
    $self->sqitch->spool( [$tfh, $fh], $self->sqlplus );
}

# Override to take advantage of the RETURNING expression, and to save tags as
# an array rather than a space-delimited string.

lib/App/Sqitch/Engine/pg.pm  view on Meta::CPAN

    # Timed out, cancel the query and return false.
    $dbh->pg_cancel;
    return 0;
}

sub run_file {
    my ($self, $file) = @_;
    $self->_run('--file' => $file);
}

sub run_verify {
    my $self = shift;
    # Suppress STDOUT unless we want extra verbosity.
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    return $self->$meth('--file' => @_);
}

sub run_handle {
    my ($self, $fh) = @_;
    $self->_spool($fh);
}

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN

    # https://support.snowflake.net/s/case/5000Z000010wbUSQAY
    # https://support.snowflake.net/s/question/0D50Z00008C90beSAB/
    return "regexp_substr($col, ?) IS NOT NULL", $regex;
}

sub run_file {
    my ($self, $file) = @_;
    $self->_run(_quiet_opts, '--filename' => $file);
}

sub run_verify {
    my ($self, $file) = @_;
    # Suppress STDOUT unless we want extra verbosity.
    return $self->run_file($file) unless $self->sqitch->verbosity > 1;
    $self->_run(_verbose_opts, '--filename' => $file);
}

sub run_handle {
    my ($self, $fh) = @_;
    $self->_spool($fh);
}

lib/App/Sqitch/Engine/sqlite.pm  view on Meta::CPAN

    my $self   = shift;
    my $fh     = shift;
    return $self->sqitch->spool( $fh, $self->sqlite3, @_ );
}

sub run_file {
    my ($self, $file) = @_;
    $self->_run( $self->_read($file) );
}

sub run_verify {
    my ($self, $file) = @_;
    # Suppress STDOUT unless we want extra verbosity.
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    $self->$meth( $self->_read($file) );
}

sub run_handle {
    my ($self, $fh) = @_;
    $self->_spool($fh);
}

lib/App/Sqitch/Engine/vertica.pm  view on Meta::CPAN

    $dbh->begin_work;
    $dbh->do('LOCK TABLE changes IN EXCLUSIVE MODE');
    return $self;
}

sub run_file {
    my ($self, $file) = @_;
    $self->_run('--file' => $file);
}

sub run_verify { shift->_run_with_verbosity(@_) }

sub _run_with_verbosity {
    my $self = shift;
    my $meth = $self->can($self->sqitch->verbosity > 1 ? '_run' : '_capture');
    return $self->$meth('--file' => @_);
}

sub run_handle {
    my ($self, $fh) = @_;
    $self->_spool($fh);

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN

    return $self->is_reworked
        ? $target->reworked_revert_dir
        : $target->revert_dir;
}

sub revert_file {
    my $self = shift;
    $self->revert_dir->file( $self->path_segments );
}

sub verify_dir {
    my $self = shift;
    my $target = $self->target;
    return $self->is_reworked
        ? $target->reworked_verify_dir
        : $target->verify_dir;
}

sub verify_file {
    my $self = shift;
    $self->verify_dir->file( $self->path_segments );
}

sub script_file {
    my ($self, $name) = @_;
    if ( my $meth = $self->can("$name\_file") ) {
        return $self->$meth;
    }
    return $self->target->top_dir->subdir($name)->cleanup->file(
        $self->path_segments
    );

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN

sub deploy_handle {
    my $self = shift;
    $self->plan->open_script($self->deploy_file);
}

sub revert_handle {
    my $self = shift;
    $self->plan->open_script($self->revert_file);
}

sub verify_handle {
    my $self = shift;
    $self->plan->open_script($self->verify_file);
}

sub format_content {
    my $self = shift;
    return $self->SUPER::format_content . $self->pspace . join (
        ' ',
        ($self->format_dependencies || ()),
        $self->timestamp->as_string,
        $self->format_planner
    );

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN

  my $plan = App::Sqitch::Plan->new( sqitch => $sqitch );
  for my $line ($plan->lines) {
      say $line->as_string;
  }

=head1 Description

A App::Sqitch::Plan::Change represents a change as parsed from a plan file. In
addition to the interface inherited from L<App::Sqitch::Plan::Line>, it offers
interfaces for parsing dependencies from the deploy script, as well as for
opening the deploy, revert, and verify scripts.

=head1 Interface

See L<App::Sqitch::Plan::Line> for the basics.

=head2 Accessors

=head3 C<since_tag>

An L<App::Sqitch::Plan::Tag> object representing the last tag to appear in the

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN


=head2 Instance Methods

=head3 C<path_segments>

  my @segments = $change->path_segments;

Returns the path segment for the change. For example, if the change is named
"foo", C<('foo.sql')> is returned. If the change is named "functions/bar>
C<('functions', 'bar.sql')> is returned. Internally, this data is used to
create the deploy, revert, and verify file names.

=head3 C<deploy_dir>

  my $file = $change->deploy_dir;

Returns the path to the deploy directory for the change.

=head3 C<deploy_file>

  my $file = $change->deploy_file;

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN

  my $file = $change->revert_dir;

Returns the path to the revert directory for the change.

=head3 C<revert_file>

  my $file = $change->revert_file;

Returns the path to the revert script file for the change.

=head3 C<verify_dir>

  my $file = $change->verify_dir;

Returns the path to the verify directory for the change.

=head3 C<verify_file>

  my $file = $change->verify_file;

Returns the path to the verify script file for the change.

=head3 C<script_file>

  my $file = $sqitch->script_file($script_name);

Returns the path to a script, for the change.

=head3 C<script_hash>

  my $hash = $change->script_hash;

lib/App/Sqitch/Plan/Change.pm  view on Meta::CPAN

Returns an L<IO::File> file handle, opened for reading, for the deploy script
for the change.

=head3 C<revert_handle>

  my $fh = $change->revert_handle;

Returns an L<IO::File> file handle, opened for reading, for the revert script
for the change.

=head3 C<verify_handle>

  my $fh = $change->verify_handle;

Returns an L<IO::File> file handle, opened for reading, for the verify script
for the change.

=head3 C<note_prompt>

  my $prompt = $change->note_prompt(
      for     => 'rework',
      scripts => [$change->deploy_file, $change->revert_file],
  );

Overrides the implementation from C<App::Sqitch::Plan::Line> to add the
C<files> parameter. This is a list of the files to be created for the command.
These will usually be the deploy, revert, and verify files, but the caller
might not be creating all of them, so it needs to pass the list.

=head1 See Also

=over

=item L<App::Sqitch::Plan>

Class representing a plan.

lib/App/Sqitch/Role/RevertDeployCommand.pm  view on Meta::CPAN

with 'App::Sqitch::Role::ContextCommand';
with 'App::Sqitch::Role::ConnectingCommand';

our $VERSION = 'v1.6.0'; # VERSION

has target => (
    is  => 'ro',
    isa => Str,
);

has verify => (
    is       => 'ro',
    isa      => Bool,
    default  => 0,
);

has log_only => (
    is       => 'ro',
    isa      => Bool,
    default  => 0,
);

lib/App/Sqitch/Role/RevertDeployCommand.pm  view on Meta::CPAN

        %{ $target->variables }, # includes engine
        %{ $self->revert_variables }, # --set, --set-revert
    );
}

around options => sub {
    my ($orig, $class) = @_;
    return ($class->$orig), qw(
        target|t=s
        mode=s
        verify!
        set|s=s%
        set-deploy|e=s%
        set-revert|r=s%
        log-only
        lock-timeout=i
        y
    );
};

around configure => sub {

lib/App/Sqitch/Role/RevertDeployCommand.pm  view on Meta::CPAN

        key => 'revert.strict',
        as  => 'bool',
    );

    my $params = $class->$orig($config, $opt);
    for my $key (qw(log_only target lock_timeout)) {
        $params->{$key} = $opt->{$key} if exists $opt->{$key};
    }

    # Verify?
    $params->{verify} = $opt->{verify}
                     // $config->get( key => "$cmd.verify", as => 'boolean' )
                     // $config->get( key => 'deploy.verify', as => 'boolean' )
                     // 0;
    $params->{mode} = $opt->{mode}
                   || $config->get( key => "$cmd.mode" )
                   || $config->get( key => 'deploy.mode' )
                   || 'all';

    if ( my $vars = $opt->{set} ) {
        # --set used for both revert and deploy.
        $params->{revert_variables} = $params->{deploy_variables} = $vars;
    }

lib/App/Sqitch/Role/RevertDeployCommand.pm  view on Meta::CPAN


=head3 C<strict>

Boolean value to indicate whether or not strict mode is enabled; if
so, use of these commands is prohibited.

=head3 C<target>

The deployment target URI.

=head3 C<verify>

Boolean indicating whether or not to run verify scripts after deploying
changes.

=head3 C<mode>

Deploy mode, one of "change", "tag", or "all".

=head1 See Also

=over

lib/App/Sqitch/Role/TargetConfigCommand.pm  view on Meta::CPAN

    # Convert URI.
    if ( my $uri = $props->{uri} ) {
        require URI;
        $props->{uri} = URI->new($uri);
    }

    # Convert directory properties to Class::Path::Dir objects.
    if (my $dirs = delete $props->{dir}) {
        my %ok_keys = map {; $_ => undef } (
            qw(reworked),
            map { ($_, "reworked_$_") } qw(deploy revert verify)
        );

        my @unknown;
        for my $key (keys %{ $dirs }) {
            unless (exists $ok_keys{$key}) {
                push @unknown => $key;
                next;
            }
            $props->{"$key\_dir"} = dir(delete $dirs->{$key})->cleanup
        }

lib/App/Sqitch/Role/TargetConfigCommand.pm  view on Meta::CPAN

    require App::Sqitch::Target;
    return App::Sqitch::Target->new(
        @params,
        map { $_ => $props->{$_} } grep { $props->{$_} } qw(
            top_dir
            plan_file
            registry
            client
            deploy_dir
            revert_dir
            verify_dir
            reworked_dir
            reworked_deploy_dir
            reworked_revert_dir
            reworked_verify_dir
            extension
        )
    );
}

sub directories_for {
    my $self = shift;
    my $props = $self->properties;
    my (@dirs, %seen);

    for my $target (@_) {
        # Script directories.
        if (my $top_dir = $props->{top_dir}) {
            push @dirs => grep { !$seen{$_}++ } map {
                $props->{"$_\_$_"} || $top_dir->subdir($_);
            } qw(deploy revert verify);
        } else {
            push @dirs => grep { !$seen{$_}++ } map {
                my $name = "$_\_dir";
                $props->{$name} || $target->$name;
            } qw(deploy revert verify);
        }

        # Reworked script directories.
        if (my $reworked_dir = $props->{reworked_dir} || $props->{top_dir}) {
            push @dirs => grep { !$seen{$_}++ } map {
                $props->{"reworked_$_\_dir"} || $reworked_dir->subdir($_);
            } qw(deploy revert verify);
        } else {
            push @dirs => grep { !$seen{$_}++ } map {
                my $name = "reworked_$_\_dir";
                $props->{$name} || $target->$name;
            } qw(deploy revert verify);
        }
    }

    return @dirs;
}

sub make_directories_for {
    my $self  = shift;
    $self->mkdirs( $self->directories_for(@_) );
}

lib/App/Sqitch/Role/TargetConfigCommand.pm  view on Meta::CPAN

=head3 C<properties>

A hash reference of target configurations. The keys may be as follows:

=over

=item C<deploy>

=item C<revert>

=item C<verify>

=item C<reworked>

=item C<reworked_deploy>

=item C<reworked_revert>

=item C<reworked_verify>

=item C<extension>

=back

=head2 Instance Methods

=head3 C<config_target>

  my $target = $cmd->config_target;

lib/App/Sqitch/Target.pm  view on Meta::CPAN

    lazy    => 1,
    default => sub {
        my $self = shift;
        if ( my $dir = $self->_fetch('reworked_dir') ) {
            return dir $dir;
        }
        $self->top_dir;
    },
);

for my $script (qw(deploy revert verify)) {
    has "$script\_dir" => (
        is      => 'ro',
        isa     => Dir,
        lazy    => 1,
        default => sub {
            my $self = shift;
            if ( my $dir = $self->_fetch("$script\_dir") ) {
                return dir $dir;
            }
            $self->top_dir->subdir($script)->cleanup;

lib/App/Sqitch/Target.pm  view on Meta::CPAN


=item * Engine-and-OS-specific default

=back

=head3 C<top_dir>

  my $top_dir = $target->top_dir;

The path to the top directory of the project. This directory generally
contains the plan file and subdirectories for deploy, revert, and verify
scripts. The value comes from one of these options, searched in this order:

=over

=item * C<--top-dir>

=item * C<target.$name.top_dir>

=item * C<engine.$engine.top_dir>

lib/App/Sqitch/Target.pm  view on Meta::CPAN

=item * C<target.$name.revert_dir>

=item * C<engine.$engine.revert_dir>

=item * C<core.revert_dir>

=item * F<C<$top_dir/revert>>

=back

=head3 C<verify_dir>

  my $verify_dir = $target->verify_dir;

The path to the verify directory of the project. This directory contains all
of the verify scripts referenced by changes in the C<plan_file>. The value
comes from one of these options, searched in this order:

=over

=item * C<--dir verify_dir=$verify_dir>

=item * C<target.$name.verify_dir>

=item * C<engine.$engine.verify_dir>

=item * C<core.verify_dir>

=item * F<C<$top_dir/verify>>

=back

=head3 C<reworked_dir>

  my $reworked_dir = $target->reworked_dir;

The path to the reworked directory of the project. This directory contains
subdirectories for reworked deploy, revert, and verify scripts. The value
comes from one of these options, searched in this order:

=over

=item * C<--dir reworked_dir=$reworked_dir>

=item * C<target.$name.reworked_dir>

=item * C<engine.$engine.reworked_dir>

lib/App/Sqitch/Target.pm  view on Meta::CPAN

=item * C<target.$name.reworked_revert_dir>

=item * C<engine.$engine.reworked_revert_dir>

=item * C<core.reworked_revert_dir>

=item * F<C<$reworked_dir/reworked_revert>>

=back

=head3 C<reworked_verify_dir>

  my $reworked_verify_dir = $target->reworked_verify_dir;

The path to the reworked verify directory of the project. This directory
contains all of the reworked verify scripts referenced by changes in the
C<plan_file>. The value comes from one of these options, searched in this
order:

=over

=item * C<--dir reworked_verify_dir=$reworked_verify_dir>

=item * C<target.$name.reworked_verify_dir>

=item * C<engine.$engine.reworked_verify_dir>

=item * C<core.reworked_verify_dir>

=item * F<C<$reworked_dir/reworked_verify>>

=back

=head3 C<extension>

  my $extension = $target->extension;

The file name extension to append to change names to create script file names.
The value comes from one of these options, searched in this order:

lib/sqitch-add.pod  view on Meta::CPAN

=head1 Synopsis

  sqitch add widgets [options
  sqitch add blankets --all
  sqitch add --change sprockets pg sql
  sqitch add slinkies --require sprockets --set schema=industry

=head1 Description

This command adds a database change to one or more plans. This will result in
the creation of script files in the deploy, revert, and verify directories,
and possibly others. The content of these files is determined by the
evaluation of templates. By default, system templates in
F<$(prefix)/etc/sqitch/templates> are used. These can be overridden by a
single user by creating templates in F<~/.sqitch/templates/> See L</Templates>
for details.

The paths and extensions of the generated scripts depend on the configuration
of Sqitch targets, engines, and the core. See L<sqitch-configuration> for
details.

lib/sqitch-add.pod  view on Meta::CPAN

Name of the templates to use for the scripts. When Sqitch searches the
template directory for templates, it uses this name to find them in subdirectories
named for the various types of scripts, including:

=over

=item C<deploy/$name.tmpl>

=item C<revert/$name.tmpl>

=item C<verify/$name.tmpl>

=back

Any templates found with the same name in additional subdirectories will also
be evaluated.

This option allows one to define templates for specific tasks, such as
creating a table, and then use them for changes that perform those tasks.
Defaults to the name of the database engine (C<pg>, C<sqlite>, C<mysql>,
C<oracle>, C<firebird>, C<vertica>, C<exasol>, C<snowflake>, C<cockroach>, or

lib/sqitch-add.pod  view on Meta::CPAN

  sqitch add --change logs vertica -n 'Adds the logs table to Vertica.'

Add a change to just two plans in a project, and generate the scripts only for
those plans:

  sqitch add -a coolfunctions sqlite.plan pg.plan -n 'Adds functions.'

=head1 Templates

Sqitch contains a very simple set of templates for generating the deploy,
revert, and verify scripts, and you can create more of your own. By default,
Sqitch uses system-wide templates installed in
F<$(prefix)/etc/sqitch/templates>; call C<sqitch --etc-path> to find out
where, exactly (e.g., C<$(sqitch --etc-path)/templates>). Individual templates
may be overridden on a user basis by copying templates to
F<~/.sqitch/templates> and making modifications. They may also be overridden
by using the C<--template-directory> or C<--template-name> options, as well as
the template-specific options.

=head2 Directory Layout

lib/sqitch-add.pod  view on Meta::CPAN


=item * C<--template-directory> or C<add.template_directory>

=item * F<~/.sqitch/templates/>

=item * F<$(prefix)/etc/sqitch/templates>

=back

Each should consist of subdirectories named for the types of scripts to be
generated. These should include F<deploy>, F<revert>, and F<verify>, but you
can create any number of other directories to create additional scripts that
will end up in a directory of the same name.

Each directory should include one or more files ending in F<.tmpl>. The
main part of the file name can be anything, but by default Sqitch will
look for a file named for the database engine. Use the C<--template> option
to have Sqitch use a different file.

For example, say you have this directory structure:

  templates/deploy/pg.tmpl
  templates/deploy/create_table.tmpl
  templates/revert/pg.tmpl
  templates/revert/create_table.tmpl
  templates/test/pg.tmpl
  templates/verify/pg.tmpl
  templates/verify/create_table.tmpl

Assuming that you're using the PostgreSQL engine, the code for which is C<pg>,
when you add a new change like so:

  sqitch add schema -n 'Creates schema'

Sqitch will use the C<pg.tmpl> files to create the following files in the
top directory configured for the project (See L<sqitch-configuration> for
details).

  deploy/schema.sql
  revert/schema.sql
  test/schema.sql
  verify/schema.sql

If you want to use the C<create_table> templates, instead, use the
C<--template> option, like so:

  sqitch add user_table --template create_table -n 'Create user table'

Sqitch will use the C<create_table.tmpl> files to create the following files
in the top directory configured for the project (See L<sqitch-configuration>
for details).

  deploy/user_table.sql
  revert/user_table.sql
  verify/user_table.sql

Note that the C<test> file was not created, because no
F<test/create_table.tmpl> template file exists.

=head2 Syntax

The syntax of Sqitch templates is the very simple language provided by
L<Template::Tiny>, which is limited to:

=over

lib/sqitch-add.pod  view on Meta::CPAN

=item C<[add.templates]>

Location of templates of different types. Core templates include:

=over

=item C<add.templates.deploy>

=item C<add.templates.revert>

=item C<add.templates.verify>

=back

But a custom template type can have its location specified here, as well,
such as C<add.template.unit_test>. May be overridden by C<--use>.

=item C<[add.variables]>

A section defining template variables. Useful if you've customized templates
with your own variables and want project-, user-, or system-specific defaults



( run in 0.877 second using v1.01-cache-2.11-cpan-73692580452 )