diff --git a/.github/ubuntu/exasol.sh b/.github/ubuntu/exasol.sh index 2ca0d2d6..ed304b3c 100755 --- a/.github/ubuntu/exasol.sh +++ b/.github/ubuntu/exasol.sh @@ -14,10 +14,10 @@ mkdir -p /opt/exasol # Download and unpack Exasol ODBC Driver & EXAplus. # https://www.exasol.com/portal/display/DOWNLOAD/ -curl -sSLO https://www.exasol.com/support/secure/attachment/186326/EXASOL_ODBC-7.1.5.tar.gz -curl -sSLO https://www.exasol.com/support/secure/attachment/179176/EXAplus-7.1.4.tar.gz -sudo tar -xzf EXASOL_ODBC-7.1.5.tar.gz -C /opt/exasol --strip-components 1 -sudo tar -xzf EXAplus-7.1.4.tar.gz -C /opt/exasol --strip-components 1 +curl -sSLO https://x-up.s3.amazonaws.com/7.x/7.1.17/EXASOL_ODBC-7.1.17.tar.gz +curl -sSLO https://x-up.s3.amazonaws.com/7.x/7.1.17/EXAplus-7.1.17.tar.gz +sudo tar -xzf EXASOL_ODBC-7.1.17.tar.gz -C /opt/exasol --strip-components 1 +sudo tar -xzf EXAplus-7.1.17.tar.gz -C /opt/exasol --strip-components 1 # Add to the path. if [[ ! -z "$GITHUB_PATH" ]]; then diff --git a/.github/ubuntu/oracle.sh b/.github/ubuntu/oracle.sh index 2a0e695e..96d9dc37 100755 --- a/.github/ubuntu/oracle.sh +++ b/.github/ubuntu/oracle.sh @@ -2,8 +2,8 @@ set -e -version=21.3.0.0.0 -icdr=213000 +version=21.9.0.0.0dbru +icdr=219000 # Install bsdtar, required to get --strip-components for a zip file. if [ -z "$SKIP_DEPENDS" ]; then diff --git a/.github/ubuntu/pg.sh b/.github/ubuntu/pg.sh index ed59ce84..8f35bd05 100755 --- a/.github/ubuntu/pg.sh +++ b/.github/ubuntu/pg.sh @@ -6,7 +6,7 @@ PGVERSION=${PGVERSION:=${1:-14}} [[ $PGVERSION =~ ^[0-9]$ ]] && PGVERSION+=.0 curl -O https://salsa.debian.org/postgresql/postgresql-common/-/raw/master/pgdg/apt.postgresql.org.sh -sudo sh apt.postgresql.org.sh -i -v $PGVERSION +sudo sh apt.postgresql.org.sh -i -t -v $PGVERSION sudo pg_createcluster --start $PGVERSION test -p 5432 --locale=C -- -A trust -E UTF8 if [[ ! -z "$GITHUB_PATH" ]]; then diff --git a/.github/ubuntu/sqlite.sh b/.github/ubuntu/sqlite.sh index a0e07e50..7b547134 100755 --- a/.github/ubuntu/sqlite.sh +++ b/.github/ubuntu/sqlite.sh @@ -2,7 +2,8 @@ set -e -SQLITE=${SQLITE:=${1:-3.36.0}} +SQLITE=${SQLITE:=${1:-3.40.1}} +echo "Instaling SQLite $SQLITE" # Convert to the SQLITE_VERSION_NUMBER format https://sqlite.org/c3ref/c_source_id.html SQLITE=$(perl -e 'my @v = split /[.]/, shift; printf "%d%02d%02d%02d\n", @v[0..3]' $SQLITE) @@ -11,7 +12,9 @@ SQLITE=$(perl -e 'my @v = split /[.]/, shift; printf "%d%02d%02d%02d\n", @v[0..3 # 3.18.2, 3.18.1, 3.9.3, and 3.7.11 missing. # https://sqlite.org/chronology.html # https://stackoverflow.com/a/37712117/79202 -if (( $SQLITE >= 3340100 )); then YEAR=2021 +if (( $SQLITE >= 3400200 )); then YEAR=2023 +elif (( $SQLITE >= 3370200 )); then YEAR=2022 +elif (( $SQLITE >= 3340100 )); then YEAR=2021 elif (( $SQLITE >= 3310000 )); then YEAR=2020 elif (( $SQLITE >= 3270000 )); then YEAR=2019 elif (( $SQLITE >= 3220000 )); then YEAR=2018 diff --git a/.github/ubuntu/vertica.sh b/.github/ubuntu/vertica.sh index 43a88ca1..caafa380 100755 --- a/.github/ubuntu/vertica.sh +++ b/.github/ubuntu/vertica.sh @@ -11,8 +11,8 @@ fi cat t/odbc/vertica.ini | sudo tee -a /etc/vertica.ini # https://www.vertica.com/download/vertica/client-drivers/ -curl -sSLO https://www.vertica.com/client_drivers/11.0.x/11.0.1-0/vertica-client-11.0.1-0.x86_64.tar.gz -sudo tar -xzf vertica-client-11.0.1-0.x86_64.tar.gz -C / +curl -sSLO https://www.vertica.com/client_drivers/12.0.x/12.0.3-0/vertica-client-12.0.3-0.x86_64.tar.gz +sudo tar -xzf vertica-client-12.0.3-0.x86_64.tar.gz -C / if [[ ! -z "$GITHUB_PATH" ]]; then echo "/opt/vertica/bin" >> $GITHUB_PATH diff --git a/.github/workflows/cockroach.yml b/.github/workflows/cockroach.yml index 4ef056f9..a6087cac 100644 --- a/.github/workflows/cockroach.yml +++ b/.github/workflows/cockroach.yml @@ -11,19 +11,20 @@ jobs: Cockroach: strategy: matrix: - version: ['22.1', '21.2'] + # curl https://registry.hub.docker.com/v2/repositories/cockroachdb/cockroach/tags\?page_size\=10000 | jq '.results[].name + version: ['23.1', '22.2', '21.2'] name: πŸͺ³ Cockroach ${{ matrix.version }} runs-on: ubuntu-latest steps: - name: Start CockroachDB run: docker run -d -p 26257:26257 cockroachdb/cockroach:latest-v${{ matrix.version }} start-single-node --insecure - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 7a68ef0b..b433912a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -44,9 +44,24 @@ jobs: image: vertica/vertica-ce:latest ports: [ 5433 ] steps: + # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 + - name: Free Disk Space + run: rm -rf /opt/hostedtoolcache - name: Start CockroachDB run: docker run -d -p 26257:26257 cockroachdb/cockroach:latest start-single-node --insecure - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Setup Perl + id: perl + uses: shogo82148/actions-setup-perl@v1 + with: { perl-version: latest } + - name: Cache CPAN Modules + uses: actions/cache@v3 + with: + path: local + key: perl-${{ steps.perl.outputs.perl-hash }} + - name: Install SQLite + env: { PERL5LIB: "${{ github.workspace }}/local/lib/perl5" } + run: .github/ubuntu/sqlite.sh - name: Setup Clients env: SKIP_DEPENDS: true @@ -59,20 +74,8 @@ jobs: .github/ubuntu/pg.sh .github/ubuntu/snowflake.sh .github/ubuntu/vertica.sh - - name: Setup Perl - id: perl - uses: shogo82148/actions-setup-perl@v1 - with: { perl-version: latest } - - name: Cache CPAN Modules - uses: actions/cache@v2 - with: - path: local - key: perl-${{ steps.perl.outputs.perl-hash }} - run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends --cpanfile dist/cpanfile - run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends DBI DBD::ODBC DBD::Firebird DBD::Oracle DBD::mysql DBD::Pg Devel::Cover Devel::Cover::Report::Coveralls - - name: Install SQLite - env: { PERL5LIB: "${{ github.workspace }}/local/lib/perl5" } - run: .github/ubuntu/sqlite.sh - name: Run Tests env: PERL5LIB: "${{ github.workspace }}/local/lib/perl5" diff --git a/.github/workflows/exasol.yml b/.github/workflows/exasol.yml index da0cedb6..d10db9d2 100644 --- a/.github/workflows/exasol.yml +++ b/.github/workflows/exasol.yml @@ -20,7 +20,7 @@ jobs: ports: [ 8563 ] options: --privileged steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/exasol.sh - name: Setup Perl @@ -28,7 +28,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/firebird.yml b/.github/workflows/firebird.yml index 85c959ce..36a5541a 100644 --- a/.github/workflows/firebird.yml +++ b/.github/workflows/firebird.yml @@ -29,7 +29,7 @@ jobs: ISC_PASSWORD: nix FIREBIRD_DATABASE: sqitchtest.db steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/firebird.sh - name: Setup Perl @@ -37,7 +37,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 989fc2d6..14cb78ac 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -12,10 +12,14 @@ jobs: strategy: matrix: include: + # curl https://registry.hub.docker.com/v2/repositories/library/mysql/tags\?page_size\=10000 | jq '.results[].name - { version: '8.0', icon: 🐬, name: MySQL, image: mysql } - { version: '5.7', icon: 🐬, name: MySQL, image: mysql } - { version: '5.6', icon: 🐬, name: MySQL, image: mysql } - { version: '5.5', icon: 🐬, name: MySQL, image: mysql } + # https://registry.hub.docker.com/v2/repositories/library/mariadb/tags\?page_size\=10000 | jq '.results[].name' + - { version: '11.0', icon: 🦭, name: MariaDB, image: mariadb } + - { version: '10.9', icon: 🦭, name: MariaDB, image: mariadb } - { version: '10.6', icon: 🦭, name: MariaDB, image: mariadb } - { version: '10.5', icon: 🦭, name: MariaDB, image: mariadb } - { version: '10.4', icon: 🦭, name: MariaDB, image: mariadb } @@ -33,9 +37,9 @@ jobs: image: "${{ matrix.image }}:${{ matrix.version }}" env: { MYSQL_ALLOW_EMPTY_PASSWORD: yes } ports: [ 3306 ] - options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 + options: --health-cmd="healthcheck.sh --innodb_initialized || mysqladmin ping --protocol=tcp" --health-interval=5s --health-timeout=2s --health-retries=3 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/mysql.sh - name: Setup Perl @@ -43,7 +47,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/oracle.yml b/.github/workflows/oracle.yml index 87ecd44f..186501eb 100644 --- a/.github/workflows/oracle.yml +++ b/.github/workflows/oracle.yml @@ -20,6 +20,7 @@ jobs: # * Image Source: https://github.com/gvenzl/oci-oracle-xe/ # * Image Issue: https://github.com/gvenzl/oci-oracle-xe/issues/46 # * DBD::Oracle Issue: https://github.com/perl5-dbi/DBD-Oracle/issues/131 + # https://registry.hub.docker.com/v2/repositories/gvenzl/oracle-xe/tags\?page_size\=10000 | jq '.results[].name - { version: 21c, tag: 21, service: XE, altUser: dbsnmp } - { version: 18c, tag: 18-slim, service: XE, altUser: gsmuser } - { version: 11g, tag: 11-slim, service: XE, altuser: sqitchtest } @@ -39,7 +40,7 @@ jobs: --health-timeout 10s --health-retries 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/oracle.sh - name: Setup Perl @@ -47,7 +48,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/os.yml b/.github/workflows/os.yml index cdefac14..ead19a06 100644 --- a/.github/workflows/os.yml +++ b/.github/workflows/os.yml @@ -18,14 +18,14 @@ jobs: name: ${{ matrix.icon }} ${{ matrix.name }} runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - run: perl -V - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/perl.yml b/.github/workflows/perl.yml index 1b40fa15..22ddac38 100644 --- a/.github/workflows/perl.yml +++ b/.github/workflows/perl.yml @@ -4,29 +4,29 @@ name: πŸ§… Perl on: push: - branches: [main, develop] + branches: [main, develop, "**perl**"] pull_request: - branches: [main, develop] + branches: [main, develop, "**perl**"] jobs: Perl: strategy: matrix: os: [[🐧, ubuntu], [🍎, macos], [πŸͺŸ, windows]] - perl: [ '5.36', '5.34', '5.32', '5.30', '5.28', '5.26', '5.24', '5.22', '5.20', '5.18', '5.16', '5.14', '5.12' ] + perl: [ '5.38', '5.36', '5.34', '5.32', '5.30', '5.28', '5.26', '5.24', '5.22', '5.20', '5.18', '5.16', '5.14', '5.12' ] exclude: - { os: [πŸͺŸ, windows], perl: '5.12' } # https://github.com/shogo82148/actions-setup-perl/issues/876 - { os: [πŸͺŸ, windows], perl: '5.14' } # https://github.com/shogo82148/actions-setup-perl/issues/881 name: πŸ§… Perl ${{ matrix.perl }} on ${{ matrix.os[0] }} ${{ matrix.os[1] }} runs-on: ${{ matrix.os[1] }}-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: "${{ matrix.perl }}" } - run: perl -V - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/pg.yml b/.github/workflows/pg.yml index b14cb62c..c97c11ba 100644 --- a/.github/workflows/pg.yml +++ b/.github/workflows/pg.yml @@ -11,17 +11,17 @@ jobs: Postgres: strategy: matrix: - pg: [14, 13, 12, 11, 10, 9.6, 9.5, 9.4, 9.3] #, 9.2, 9.1, 9.0, 8.4] https://github.com/bucardo/dbdpg/issues/84 + pg: [16, 15, 14, 13, 12, 11, 10, 9.6, 9.5, 9.4, 9.3, 9.2, 9.1, '9.0', 8.4] name: 🐘 Postgres ${{ matrix.pg }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 02dbb4bd..9f5a1c1a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,13 +10,13 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Check out the repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} @@ -47,7 +47,7 @@ jobs: DZIL_CONFIRMRELEASE_DEFAULT: "yes" run: | local/bin/dzil release - echo "::set-output name=tarball::$( ls App-Sqitch-*.tar.gz )" + echo "tarball=$( ls App-Sqitch-*.tar.gz )" >> $GITHUB_OUTPUT - name: Generate Release Changes run: xt/gen_release_changes - name: Create GitHub Release diff --git a/.github/workflows/snowflake.yml b/.github/workflows/snowflake.yml index dff7f6b3..7dc089c5 100644 --- a/.github/workflows/snowflake.yml +++ b/.github/workflows/snowflake.yml @@ -11,7 +11,7 @@ jobs: name: ❄️ Snowflake runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/snowflake.sh - name: Setup Perl @@ -19,7 +19,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/sqlite.yml b/.github/workflows/sqlite.yml index 6ea9f1d7..4c0b758d 100644 --- a/.github/workflows/sqlite.yml +++ b/.github/workflows/sqlite.yml @@ -12,17 +12,17 @@ jobs: strategy: matrix: # https://sqlite.org/chronology.html - sqlite: [3.36.0, 3.35.5, 3.34.1, 3.33.0, 3.32.3, 3.31.1, 3.30.1, 3.29.0, 3.28.0, 3.27.2, 3.26.0, 3.25.3, 3.24.0, 3.23.1, 3.22.0, 3.21.0, 3.20.1, 3.19.3, 3.18.0, 3.17.0, 3.16.2, 3.15.2, 3.14.2, 3.13.0, 3.12.2, 3.11.1, 3.10.2, 3.9.2, 3.8.11.1, 3.7.17] + sqlite: [3.42.0, 3.41.2, 3.40.1, 3.39.4, 3.38.5, 3.37.2, 3.36.0, 3.35.5, 3.34.1, 3.33.0, 3.32.3, 3.31.1, 3.30.1, 3.29.0, 3.28.0, 3.27.2, 3.26.0, 3.25.3, 3.24.0, 3.23.1, 3.22.0, 3.21.0, 3.20.1, 3.19.3, 3.18.0, 3.17.0, 3.16.2, 3.15.2, 3.14.2, 3.13.0, 3.12.2, 3.11.1, 3.10.2, 3.9.2, 3.8.11.1, 3.8.6] name: πŸ’‘ SQLite ${{ matrix.sqlite }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/vertica.yml b/.github/workflows/vertica.yml index 1aa26da2..b524bbd3 100644 --- a/.github/workflows/vertica.yml +++ b/.github/workflows/vertica.yml @@ -12,14 +12,14 @@ jobs: strategy: matrix: include: - - { label: '11.0', version: 11.0.0-0, image: vertica/vertica-ce, db: VMart } + - { label: '12.0', version: 12.0.4-0, image: vertica/vertica-ce, db: VMart } + - { label: '11.0', version: 11.1.1-0, image: vertica/vertica-ce, db: VMart } - { label: '10.1', version: 10.1.1-0, image: vertica/vertica-ce, db: VMart } - { label: '9.2', version: 9.2.1-0, image: cjonesy/docker-vertica, db: docker } - { label: '9.1', version: 9.1.1-0, image: cjonesy/docker-vertica, db: docker } - { label: '8.1', version: 8.1.1-0, image: cjonesy/docker-vertica, db: docker } - { label: '8.0', version: 8.0.0-0, image: cjonesy/docker-vertica, db: docker } - { label: '7.2', version: 7.2.3-18, image: cjonesy/docker-vertica, db: docker } - - { label: '7.1', version: 7.1.2-21, image: cjonesy/docker-vertica, db: docker } name: πŸ”Ί Vertica ${{ matrix.label }} runs-on: ubuntu-latest services: @@ -27,7 +27,7 @@ jobs: image: ${{ matrix.image }}:${{ matrix.version }} ports: [ 5433 ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Clients run: .github/ubuntu/vertica.sh - name: Setup Perl @@ -35,7 +35,7 @@ jobs: uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/.github/workflows/yugabyte.yml b/.github/workflows/yugabyte.yml index e1c75f4c..9524be9c 100644 --- a/.github/workflows/yugabyte.yml +++ b/.github/workflows/yugabyte.yml @@ -12,25 +12,35 @@ jobs: strategy: matrix: include: + # curl https://registry.hub.docker.com/v2/repositories/yugabytedb/yugabyte/tags\?page_size\=10000 | jq '.results[].name' | sort + - { version: '2.19', tag: 2.19.0.0-b190 } + - { version: '2.18', tag: 2.18.1.0-b84 } + - { version: '2.17', tag: 2.17.3.0-b152 } + - { version: '2.16', tag: 2.16.6.0-b43 } + - { version: '2.15', tag: 2.15.3.2-b1 } + - { version: '2.14', tag: 2.14.11.0-b35 } - { version: '2.13', tag: 2.13.2.0-b135 } - - { version: '2.12', tag: 2.12.5.0-b24 } - - { version: '2.8', tag: 2.8.6.0-b12 } - - { version: '2.6', tag: 2.6.18.0-b3 } + - { version: '2.12', tag: 2.12.12.0-b12 } + - { version: '2.11', tag: 2.11.2.0-b89 } + - { version: '2.8', tag: 2.8.12.0-b5 } + - { version: '2.6', tag: 2.6.20.0-b10 } name: πŸ’« Yugabyte ${{ matrix.version }} runs-on: ubuntu-latest steps: - name: Setup YugabyteDB cluster id: yugabyte - uses: yugabyte/yugabyte-db-action@master + # https://github.com/yugabyte/yugabyte-db-action/issues/5 + # uses: yugabyte/yugabyte-db-action@master + uses: jameshartig/yugabyte-db-action@master with: yb_image_tag: "${{ matrix.tag }}" - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - name: Cache CPAN Modules - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} diff --git a/Changes b/Changes index 0b3282d3..b615c0be 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,70 @@ Revision history for Perl extension App::Sqitch +1.4.0 2023-08-01T23:37:30Z + - Fixed Snowflake warehouse and role setup to properly quote identifiers + unless they're valid unquoted identifiers or already quoted. Thanks to + @marc-marketparts for the report (#685). + - Fixed a bug reworking a change when a rework directory is configured + 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 + #735)! + - Fixed test failures due to a bug fix in the Perl URI module + (libwww-perl/URI#13). Thanks to @bobfang for the report (#744)! + - Fixed test failures due to a change in the generation of DBI DSN by + URI::Oracle introduced by libwww-perl/URI-db#23. + - Added a format option `%F` to `sqitch plan` that prints the path for + the deploy file for each migration in the plan. + - Changed the default location for the Oracle `sqlplus` client when the + `ORACLE_HOME` environment variable is set. It now returns either + `$ORACLE_HOME/bin/sqlplus` or `$ORACLE_HOME/sqlplus` if it exists + and is executable (and ends in `.exe` on Windows). Otherwise it simply + returns `sqlplus` as before, assuming it will be found in the path. + Thanks to @vectro for the suggestion (#747). + - Increased the required version of DBI to 1.631 or higher and removed + a MySQL engine workaround for older versions. + - Added detection of a missing registry schema on connect and conditions + to avoid querying it when it does not exist. Fixes an issue where + Sqitch might find a project record in the current schema instead of the + expected registry schema. Thanks to @vectro for the report and + investigation (#668)! + - Fixed Snowflake and MySQL to properly raise errors on session query + failures immediately after connection. + - Fixed the handling of unique violations for deploy script hash + uniqueness so that it no longer returns a database error but properly + reports the issue in a more human-friendly error message. Thanks to + Stefan Badenhorst for the reminder (#630). + - Updated the registry SQL scripts for Vertica to always enable primary + key and unique constraints. Unique constraints are now enabled for + all database engines except Exasol and Snowflake. + - Dropped support for Vertica 7.1, as unique constraint enforcement was + not added until Vertica 7.2. + - Increased minimum SQLite versions to 3.8.6, when unique constraint + enforcement was added. + - Removed remaining uses of the smartmatch operator, thus eliminating + the Perl 5.38 warnings about its deprecation. (#769) + - Added Cockroach to the list of valid engines recognized in command-line + arguments (and a test to ensure new engines won't be omitted in the + future). Thanks to @NOBLES5E for the spot (#772)! + 1.3.1 2022-10-01T18:49:30Z - Fixed a bug introduced in v1.3.0 where the Postgres engine would always pass the port to `psql`, thus ignoring the `PGPORT` environment @@ -37,7 +102,7 @@ Revision history for Perl extension App::Sqitch - Now require URI::db v0.20 for Cockroach and Yugabyte URI support. - Dropped support for MySQL 5.0. - Added explicit sorting for aggregated lists (such as the tags associated - with a commit) to the MySQL, Exasol, Snowflake, and Postgres (8.4 and + with a commit) to the MySQL, Exasol, Snowflake, and Postgres (9.0 and higher) engines. - Fixed slow deploys on MariaDB thanks to fractional timestamp support added in 5.03.05. Thanks to @rbrigot for the PR (#658)! diff --git a/LICENSE.md b/LICENSE.md index 196d15ce..4caa6933 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2012-2022 iovation, Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation, Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index c293d173..cb465fbf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -App/Sqitch version v1.3.1 +App/Sqitch version v1.4.0 ========================= | Release | Coverage | Database || @@ -14,12 +14,12 @@ App/Sqitch version v1.3.1 * [PostgreSQL] 8.4+ * [YugabyteDB] 2.6+ * [CockroachDB] 21+ -* [SQLite][lite] 3.7.11+ +* [SQLite][lite] 3.8.6+ * [MySQL][my] 5.1+ * [MariaDB] 10.0+ * [Oracle][orcl] 10g+, * [Firebird][bird] 2.0+ -* [Vertica][vert] 6.0+ +* [Vertica][vert] 7.2+ * [Exasol][exa] 6.0+ * [Snowflake][flake] @@ -138,7 +138,7 @@ Linux distributions and Windows, see the [Installation documentation]. License ------- -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -169,7 +169,7 @@ SOFTWARE. [Docker]: https://img.shields.io/docker/v/sqitch/sqitch?label=%F0%9F%90%B3%20Docker&sort=semver [🐳]: https://hub.docker.com/r/sqitch/sqitch "Latest version on Docker Hub" [Perl]: https://github.com/sqitchers/sqitch/actions/workflows/perl.yml/badge.svg - [πŸ§…]: https://github.com/sqitchers/sqitch/actions/workflows/perl.yml "Tested with Perl 5.12–5.34" + [πŸ§…]: https://github.com/sqitchers/sqitch/actions/workflows/perl.yml "Tested with Perl 5.12–5.38" [Firebird]: https://github.com/sqitchers/sqitch/actions/workflows/firebird.yml/badge.svg [πŸ”₯]: https://github.com/sqitchers/sqitch/actions/workflows/firebird.yml "Tested with Firebird 2.5, 3, and 4" [Snowflake]: https://github.com/sqitchers/sqitch/actions/workflows/snowflake.yml/badge.svg @@ -179,19 +179,19 @@ SOFTWARE. [Coverage]: https://img.shields.io/coveralls/github/sqitchers/sqitch?label=%F0%9F%93%88%20Coverage [πŸ“ˆ]: https://coveralls.io/r/sqitchers/sqitch "Test Coverage" [MySQL]: https://github.com/sqitchers/sqitch/actions/workflows/mysql.yml/badge.svg - [🐬]: https://github.com/sqitchers/sqitch/actions/workflows/mysql.yml "Tested with MySQL 5.5–8 and MariaDB 10.0–10.6" + [🐬]: https://github.com/sqitchers/sqitch/actions/workflows/mysql.yml "Tested with MySQL 5.5–8 and MariaDB 10.0–11.0" [SQLite]: https://github.com/sqitchers/sqitch/actions/workflows/sqlite.yml/badge.svg - [πŸ’‘]: https://github.com/sqitchers/sqitch/actions/workflows/sqlite.yml "Tested with SQLite 3.7–3.36" + [πŸ’‘]: https://github.com/sqitchers/sqitch/actions/workflows/sqlite.yml "Tested with SQLite 3.8–3.42" [Debian]: https://img.shields.io/debian/v/sqitch?label=%F0%9F%8D%A5%20Debian [πŸ₯]: https://packages.debian.org/stable/sqitch "Latest version on Debian" [Postgres]: https://github.com/sqitchers/sqitch/actions/workflows/pg.yml/badge.svg - [🐘]: https://github.com/sqitchers/sqitch/actions/workflows/pg.yml "Tested with PostgreSQL 9.3–14" + [🐘]: https://github.com/sqitchers/sqitch/actions/workflows/pg.yml "Tested with PostgreSQL 8.4–16" [Yugabyte]: https://github.com/sqitchers/sqitch/actions/workflows/yugabyte.yml/badge.svg - [πŸ’«]: https://github.com/sqitchers/sqitch/actions/workflows/yugabyte.yml "Tested with YugabyteDB 2.6–2.13" + [πŸ’«]: https://github.com/sqitchers/sqitch/actions/workflows/yugabyte.yml "Tested with YugabyteDB 2.6–2.19" [Vertica]: https://github.com/sqitchers/sqitch/actions/workflows/vertica.yml/badge.svg - [πŸ”Ί]: https://github.com/sqitchers/sqitch/actions/workflows/vertica.yml "Tested with Vertica 7.1–11.0" - [Cockroach]: https://github.com/sqitchers/sqitch/actions/workflows/cockroach.yml/badge.svg - [πŸͺ³]: https://github.com/sqitchers/sqitch/actions/workflows/cockroach.yml "Tested with CockroachDB v21-22" + [πŸ”Ί]: https://github.com/sqitchers/sqitch/actions/workflows/vertica.yml "Tested with Vertica 7.2–12.0" +[Cockroach]: https://github.com/sqitchers/sqitch/actions/workflows/cockroach.yml/badge.svg + [πŸͺ³]: https://github.com/sqitchers/sqitch/actions/workflows/cockroach.yml "Tested with CockroachDB v21-23" [Sqitch]: https://sqitch.org/ [PostgreSQL]: https://postgresql.org/ diff --git a/dist.ini b/dist.ini index 86435d7d..6f61eeb4 100644 --- a/dist.ini +++ b/dist.ini @@ -1,8 +1,8 @@ name = App-Sqitch license = MIT copyright_holder = "iovation Inc., David E. Wheeler" -copyright_year = 2012-2022 -version = v1.3.1 +copyright_year = 2012-2023 +version = v1.4.0 [GatherDir] exclude_filename = dist/cpanfile diff --git a/dist/cpanfile b/dist/cpanfile index 60bd9915..4e19f017 100644 --- a/dist/cpanfile +++ b/dist/cpanfile @@ -1,10 +1,10 @@ -# This file is generated by Dist::Zilla::Plugin::CPANFile v6.025 +# This file is generated by Dist::Zilla::Plugin::CPANFile v6.030 # Do not edit this file directly. To change prereqs, edit the `dist.ini` file. requires "Algorithm::Backoff::Exponential" => "0.006"; requires "Clone" => "0"; requires "Config::GitLike" => "1.15"; -requires "DBI" => "0"; +requires "DBI" => "1.631"; requires "DateTime" => "1.04"; requires "DateTime::TimeZone" => "0"; requires "Devel::StackTrace" => "1.30"; @@ -54,7 +54,6 @@ requires "URI::QueryParam" => "0"; requires "URI::db" => "0.20"; requires "User::pwent" => "0"; requires "constant" => "0"; -requires "if" => "0"; requires "namespace::autoclean" => "0.16"; requires "overload" => "0"; requires "parent" => "0"; diff --git a/dist/sqitch.spec b/dist/sqitch.spec index e16df9e4..dc40f81d 100644 --- a/dist/sqitch.spec +++ b/dist/sqitch.spec @@ -1,5 +1,5 @@ Name: sqitch -Version: 1.3.1 +Version: 1.4.0 Release: 1%{?dist} Summary: Sensible database change management License: MIT @@ -19,7 +19,7 @@ BuildRequires: perl(Config::GitLike) >= 1.15 BuildRequires: perl(constant) BuildRequires: perl(DateTime) >= 1.04 BuildRequires: perl(DateTime::TimeZone) -BuildRequires: perl(DBI) +BuildRequires: perl(DBI) >= 1.631 BuildRequires: perl(Devel::StackTrace) >= 1.30 BuildRequires: perl(Digest::SHA) BuildRequires: perl(Encode) @@ -188,7 +188,7 @@ Summary: Sensible database change management for PostgreSQL, YugabyteDB, Group: Development/Libraries Requires: sqitch >= %{version} Requires: postgresql >= 8.4.0 -Requires: perl(DBI) +Requires: perl(DBI) >= 1.631 Requires: perl(DBD::Pg) >= 2.0.0 Provides: sqitch-pg @@ -205,7 +205,7 @@ Summary: Sensible database change management for SQLite Group: Development/Libraries Requires: sqitch >= %{version} Requires: sqlite -Requires: perl(DBI) +Requires: perl(DBI) >= 1.631 Requires: perl(DBD::SQLite) >= 1.37 Provides: sqitch-sqlite @@ -222,7 +222,7 @@ Summary: Sensible database change management for Oracle Group: Development/Libraries Requires: sqitch >= %{version} Requires: oracle-instantclient11.2-sqlplus -Requires: perl(DBI) +Requires: perl(DBI) => 1.631 Requires: perl(DBD::Oracle) >= 1.23 Provides: sqitch-oracle @@ -239,7 +239,7 @@ Summary: Sensible database change management for MySQL Group: Development/Libraries Requires: sqitch >= %{version} Requires: mysql >= 5.1.0 -Requires: perl(DBI) +Requires: perl(DBI) >= 1.631 Requires: perl(DBD::mysql) >= 4.018 Requires: perl(MySQL::Config) Provides: sqitch-mysql @@ -257,7 +257,7 @@ Summary: Sensible database change management for Firebird Group: Development/Libraries Requires: sqitch >= %{version} Requires: firebird >= 2.5.0 -Requires: perl(DBI) +Requires: perl(DBI) >= 1.631 Requires: perl(DBD::Firebird) >= 1.11 Requires: perl(Time::HiRes) Requires: perl(Time::Local) @@ -278,7 +278,7 @@ Group: Development/Libraries Requires: sqitch >= %{version} Requires: libverticaodbc.so Requires: /opt/vertica/bin/vsql -Requires: perl(DBI) +Requires: perl(DBI) >= 1.631 Requires: perl(DBD::ODBC) >= 1.59 Provides: sqitch-vertica @@ -295,7 +295,7 @@ Summary: Sensible database change management for Snowflake Group: Development/Libraries Requires: sqitch >= %{version} Requires: snowflake-odbc -Requires: perl(DBI) +Requires: perl(DBI) => 1.631 Requires: perl(DBD::ODBC) >= 1.59 Provides: sqitch-snowflake @@ -309,6 +309,10 @@ also be installed. # No additional files required. %changelog +* Mon Aug 1 2023 David E. Wheeler 1.4.0-1 +- Upgrade to v1.4.0. +- Incrmented minimal DBI to 1.631. + * Sat Oct 1 2022 David E. Wheeler 1.3.1-1 - Upgrade to v1.3.1. diff --git a/inc/Menlo/Sqitch.pm b/inc/Menlo/Sqitch.pm index d4843ed1..9541f1d3 100644 --- a/inc/Menlo/Sqitch.pm +++ b/inc/Menlo/Sqitch.pm @@ -5,10 +5,20 @@ use warnings; use base 'Menlo::CLI::Compat'; sub new { + my %deps; + while () { + last if /^Build-only dependencies/; + } + while () { + chomp; + last unless s/^\s+//; + $deps{$_} = 1; + } + use Data::Dump; ddx \%deps; exit; shift->SUPER::new( @_, _remove => [], - _bld_deps => { map { chomp; $_ => 1 } }, + _bld_deps => \%deps, ); } @@ -62,132 +72,248 @@ sub remove_build_dependencies { # Data pasted from the report of build-only dependencies by # dev/dependency_report. __DATA__ -AppConfig -Archive-Tar -CPAN -CPAN-Common-Index -CPAN-DistnameInfo -CPAN-Meta -CPAN-Meta-Check -CPAN-Meta-Requirements -CPAN-Meta-YAML -CPAN-Perl-Releases -Capture-Tiny -Class-Tiny -Compress-Bzip2 -Compress-Raw-Bzip2 -Compress-Raw-Lzma -Compress-Raw-Zlib -Config-AutoConf -DBD-CSV -Date-Manip -Devel-CheckLib -Devel-GlobalDestruction -Devel-PPPort -Devel-Symdump -Digest -Digest-MD5 -Dist-CheckConflicts -Dumpvalue -ExtUtils-CBuilder -ExtUtils-Config -ExtUtils-Constant -ExtUtils-Helpers -ExtUtils-Install -ExtUtils-InstallPaths -ExtUtils-MakeMaker -ExtUtils-MakeMaker-CPANfile -ExtUtils-ParseXS -File-Fetch -File-Find-Rule -File-Find-Rule-Perl -File-HomeDir -File-Listing -File-ShareDir-Install -File-Slurper -File-pushd -FindBin -HTML-Parser -HTML-Tagset -HTTP-CookieJar -HTTP-Cookies -HTTP-Date -HTTP-Message -HTTP-Negotiate -HTTP-Tiny -HTTP-Tinyish -IO-Compress -IO-Compress-Brotli -IO-Compress-Lzma -IO-HTML -IO-Socket-IP -IO-Socket-SSL -IO-Zlib -IPC-Cmd -JSON-PP -LWP-MediaTypes -Locale-Maketext-Simple -Log-Dispatch -Log-Dispatch-FileRotate -Log-Log4perl -Math-Base-Convert -Math-BigInt -Math-BigRat -Math-Complex -Menlo -Menlo-Legacy -Module-Build -Module-CPANfile -Module-CoreList -Module-Load -Module-Load-Conditional -Module-Metadata -Module-Signature -Mozilla-CA -Mozilla-PublicSuffix -Net-HTTP -Net-Ping -Net-SSLeay -Number-Compare -Params-Check -Parse-PMFile -Perl-Tidy -Pod-Coverage -SQL-Statement -Safe -Search-Dict -Sub-Uplevel -Sys-Syslog -Test -Test-Exception -Test-Fatal -Test-Harness -Test-LeakTrace -Test-NoWarnings -Test-Pod -Test-Pod-Coverage -Test-Simple -Test-Version -Text-Balanced -Text-CSV_XS -Text-Glob -Text-Soundex -Thread-Semaphore -Tie-File -Tie-Handle-Offset -TimeDate -WWW-RobotRules -Win32-ShellQuote -XML-DOM -XML-Parser -XML-RegExp -YAML -YAML-Syck -bignum -inc-latest -lib -libwww-perl -libxml-perl -local-lib -threads -threads-shared +Build-only dependencies + Archive-Tar + Archive-Zip + CPAN + CPAN-Checksums + CPAN-Common-Index + CPAN-DistnameInfo + CPAN-Meta + CPAN-Meta-Check + CPAN-Meta-Requirements + CPAN-Meta-YAML + CPAN-Perl-Releases + Capture-Tiny + Class-Tiny + Compress-Bzip2 + Compress-Raw-Bzip2 + Compress-Raw-Lzma + Compress-Raw-Zlib + Config-AutoConf + DBD-CSV + Data-Compare + Date-Manip + Devel-CheckLib + Devel-GlobalDestruction + Devel-Symdump + Digest + Digest-MD5 + Dist-CheckConflicts + Dumpvalue + Expect + ExtUtils-CBuilder + ExtUtils-Config + ExtUtils-Constant + ExtUtils-Helpers + ExtUtils-Install + ExtUtils-InstallPaths + ExtUtils-MakeMaker + ExtUtils-MakeMaker-CPANfile + ExtUtils-ParseXS + File-Fetch + File-Find-Rule + File-Find-Rule-Perl + File-HomeDir + File-Listing + File-ShareDir-Install + File-Slurper + File-pushd + HTML-Parser + HTML-Tagset + HTTP-CookieJar + HTTP-Cookies + HTTP-Date + HTTP-Message + HTTP-Negotiate + HTTP-Tiny + HTTP-Tinyish + IO-Compress + IO-Compress-Brotli + IO-Compress-Lzma + IO-HTML + IO-Socket-IP + IO-Socket-SSL + IO-Tty + IO-Zlib + IPC-Cmd + JSON-PP + LWP-MediaTypes + Locale-Maketext-Simple + Log-Dispatch + Log-Dispatch-FileRotate + Log-Log4perl + Math-Base-Convert + Math-BigInt + Math-BigRat + Math-Complex + Menlo + Menlo-Legacy + Module-Build + Module-CPANfile + Module-CoreList + Module-Load + Module-Load-Conditional + Module-Metadata + Module-Signature + Mozilla-CA + Mozilla-PublicSuffix + Net-HTTP + Net-Ping + Net-SSLeay + Number-Compare + Params-Check + Parse-PMFile + Perl-Tidy + Pod-Coverage + SQL-Statement + Safe + Search-Dict + Sub-Uplevel + Sys-Syslog + Test + Test-Exception + Test-Fatal + Test-Harness + Test-NoWarnings + Test-Pod + Test-Pod-Coverage + Test-Simple + Test-Version + Text-Balanced + Text-CSV_XS + Text-Glob + Text-Soundex + Thread-Semaphore + Tie-File + Tie-Handle-Offset + TimeDate + WWW-RobotRules + Win32-ShellQuote + XML-DOM + XML-Parser + XML-RegExp + YAML + YAML-LibYAML + YAML-Syck + bignum + inc-latest + lib + libwww-perl + libxml-perl + local-lib + threads + threads-shared + +Runtime-only dependencies + Algorithm-Backoff + Class-Inspector + Class-Singleton + Clone-Choose + Config-GitLike + DBD-Firebird + DBD-ODBC + DBD-Oracle + DBD-Pg + DBD-mysql + Data-OptList + DateTime + DateTime-Locale + DateTime-TimeZone + Exporter-Tiny + File-ShareDir + Hash-Merge + IO-Pager + IPC-System-Simple + List-MoreUtils + List-MoreUtils-XS + Moo + MooX-Types-MooseLike + MySQL-Config + Path-Class + Ref-Util-XS + Regexp-Util + String-Formatter + Sub-Exporter + Sub-Install + Template-Tiny + Template-Toolkit + Term-ANSIColor + Throwable + Type-Tiny + Type-Tiny-XS + URI-Nested + URI-db + libintl-perl + strictures + +Overlapping dependencies + B-Hooks-EndOfScope + Carp + Class-Data-Inheritable + Class-Method-Modifiers + Class-XSAccessor + Clone + DBD-SQLite + DBI + Data-Dumper + Devel-Caller + Devel-LexAlias + Devel-StackTrace + Digest-SHA + Encode + Encode-Locale + Env + Eval-Closure + Exception-Class + Exporter + File-Path + File-Temp + File-Which + Getopt-Long + IO + IPC-Run3 + MIME-Base64 + MRO-Compat + Module-Implementation + Module-Runtime + Package-Stash + Package-Stash-XS + PadWalker + Params-Util + Params-ValidationCompiler + PathTools + Perl-OSType + PerlIO-utf8_strict + Pod-Escapes + Pod-Parser + Pod-Perldoc + Pod-Simple + Pod-Usage + Ref-Util + Role-Tiny + Scalar-List-Utils + Socket + Specio + Storable + String-ShellQuote + Sub-Exporter-Progressive + Sub-Identify + Sub-Quote + TermReadKey + Text-ParseWords + Text-Tabs+Wrap + Time-HiRes + Time-Local + Try-Tiny + URI + XSLoader + base + constant + if + libnet + namespace-autoclean + namespace-clean + parent + podlators + version diff --git a/lib/App/Sqitch.pm b/lib/App/Sqitch.pm index a8d4b643..79b50884 100644 --- a/lib/App/Sqitch.pm +++ b/lib/App/Sqitch.pm @@ -904,7 +904,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command.pm b/lib/App/Sqitch/Command.pm index ff4ebfab..555325ee 100644 --- a/lib/App/Sqitch/Command.pm +++ b/lib/App/Sqitch/Command.pm @@ -23,6 +23,7 @@ use constant ENGINES => qw( vertica exasol snowflake + cockroach ); has sqitch => ( @@ -369,6 +370,8 @@ Returns the list of supported engines, currently: =item * C +=item * C + =back =head2 Class Methods @@ -768,7 +771,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/add.pm b/lib/App/Sqitch/Command/add.pm index 703c5893..ccba27dc 100644 --- a/lib/App/Sqitch/Command/add.pm +++ b/lib/App/Sqitch/Command/add.pm @@ -407,6 +407,17 @@ sub _add { file => $file, error => $! ); + + # Warn if the file name has a double extension + if ($file =~ m/\.(\w+)\.\1+$/) { + my $ext = $1; + $self->warn(__x( + 'File {file} has a double extension of {ext}', + file => $file, + ext => $ext, + )); + } + $self->info(__x 'Created {file}', file => $file); } @@ -532,7 +543,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/bundle.pm b/lib/App/Sqitch/Command/bundle.pm index aff0966a..2a90da87 100644 --- a/lib/App/Sqitch/Command/bundle.pm +++ b/lib/App/Sqitch/Command/bundle.pm @@ -359,7 +359,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/check.pm b/lib/App/Sqitch/Command/check.pm index 1fbb5339..983eb64c 100644 --- a/lib/App/Sqitch/Command/check.pm +++ b/lib/App/Sqitch/Command/check.pm @@ -176,7 +176,7 @@ Matthieu Foucault =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler, Button Inc. +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler, Button Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/checkout.pm b/lib/App/Sqitch/Command/checkout.pm index 4b3b5811..fc975bc0 100644 --- a/lib/App/Sqitch/Command/checkout.pm +++ b/lib/App/Sqitch/Command/checkout.pm @@ -55,8 +55,6 @@ sub execute { my $git = $self->client; my $engine = $target->engine; $engine->with_verify( $self->verify ); - $engine->no_prompt( $self->no_prompt ); - $engine->prompt_accept( $self->prompt_accept ); $engine->log_only( $self->log_only ); $engine->lock_timeout( $self->lock_timeout ); @@ -114,7 +112,7 @@ sub execute { $engine->set_variables( $self->_collect_revert_vars($target) ); $engine->plan( $from_plan ); try { - $engine->revert( $last_common_change->id ); + $engine->revert( $last_common_change->id, ! $self->no_prompt, $self->prompt_accept ); } catch { # Rethrow unknown errors or errors with exitval > 1. die $_ if ! eval { $_->isa('App::Sqitch::X') } @@ -199,7 +197,7 @@ The Sqitch command-line client. =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Copyright (c) 2012-2013 Ronan Dunklau diff --git a/lib/App/Sqitch/Command/config.pm b/lib/App/Sqitch/Command/config.pm index 3f7cb0f4..d40ef4fe 100644 --- a/lib/App/Sqitch/Command/config.pm +++ b/lib/App/Sqitch/Command/config.pm @@ -642,7 +642,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/deploy.pm b/lib/App/Sqitch/Command/deploy.pm index d2f6d840..fba561e3 100644 --- a/lib/App/Sqitch/Command/deploy.pm +++ b/lib/App/Sqitch/Command/deploy.pm @@ -221,7 +221,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/engine.pm b/lib/App/Sqitch/Command/engine.pm index 630f21a4..55756c6e 100644 --- a/lib/App/Sqitch/Command/engine.pm +++ b/lib/App/Sqitch/Command/engine.pm @@ -315,7 +315,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/help.pm b/lib/App/Sqitch/Command/help.pm index ba861f40..e6064a11 100644 --- a/lib/App/Sqitch/Command/help.pm +++ b/lib/App/Sqitch/Command/help.pm @@ -119,7 +119,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/init.pm b/lib/App/Sqitch/Command/init.pm index 1e5df996..462fd95b 100644 --- a/lib/App/Sqitch/Command/init.pm +++ b/lib/App/Sqitch/Command/init.pm @@ -268,7 +268,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/log.pm b/lib/App/Sqitch/Command/log.pm index 039d9171..6a6d7a69 100644 --- a/lib/App/Sqitch/Command/log.pm +++ b/lib/App/Sqitch/Command/log.pm @@ -350,7 +350,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/plan.pm b/lib/App/Sqitch/Command/plan.pm index d0d0c958..cfad0867 100644 --- a/lib/App/Sqitch/Command/plan.pm +++ b/lib/App/Sqitch/Command/plan.pm @@ -236,6 +236,7 @@ sub execute { change_id => $change->id, change => $change->name, note => $change->note, + deploy_file => $change->deploy_file, tags => [ map { $_->format_name } $change->tags ], requires => [ map { $_->as_string } $change->requires ], conflicts => [ map { $_->as_string } $change->conflicts ], @@ -331,7 +332,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/rebase.pm b/lib/App/Sqitch/Command/rebase.pm index 3ac646de..dabba7bc 100644 --- a/lib/App/Sqitch/Command/rebase.pm +++ b/lib/App/Sqitch/Command/rebase.pm @@ -78,15 +78,15 @@ sub execute { # Now get to work. $engine->with_verify( $self->verify ); - $engine->no_prompt( $self->no_prompt ); - $engine->prompt_accept( $self->prompt_accept ); $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 ); + $engine->revert( $onto, ! ($self->no_prompt), $self->prompt_accept ); } catch { # Rethrow unknown errors or errors with exitval > 1. die $_ if ! eval { $_->isa('App::Sqitch::X') } @@ -175,7 +175,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/revert.pm b/lib/App/Sqitch/Command/revert.pm index 7c54838f..22c41b47 100644 --- a/lib/App/Sqitch/Command/revert.pm +++ b/lib/App/Sqitch/Command/revert.pm @@ -43,6 +43,15 @@ has prompt_accept => ( isa => Bool ); +has strict => ( + is => 'ro', + lazy => 1, + default => sub { + my $self = shift; + return $self->sqitch->config->get( key => 'revert.strict' ) // 0; + } +); + has log_only => ( is => 'ro', isa => Bool, @@ -134,18 +143,33 @@ sub execute { my $change = $self->modified ? $engine->planned_deployed_common_ancestor_id : $self->to_change // shift @{ $changes }; - $self->warn(__x( - 'Too many changes specified; reverting to "{change}"', - change => $change, - )) if @{ $changes }; + + # Require a change to revert to in strict mode. + hurl { + ident => 'revert:strict', + message => __ 'Must specify a target revision in strict mode', + exitval => 1, + } if !defined $change && $self->strict; + + if (@{ $changes }) { + # Only one change allowed currently; fatal in strict mode. + hurl { + ident => 'revert:strict', + message => __ 'Too many changes specified', + exitval => 2, + } if $self->strict; + + $self->warn(__x( + 'Too many changes specified; reverting to "{change}"', + change => $change, + )); + } # Now get to work. - $engine->no_prompt( $self->no_prompt ); - $engine->prompt_accept( $self->prompt_accept ); $engine->log_only( $self->log_only ); $engine->lock_timeout( $self->lock_timeout ); $engine->set_variables( $self->_collect_vars($target) ); - $engine->revert( $change ); + $engine->revert( $change, ! ($self->no_prompt), $self->prompt_accept ); return $self; } @@ -205,6 +229,10 @@ the revert. Boolean value to indicate whether or not the default value for the prompt, should the user hit C, is to accept the prompt or deny it. +=head3 C + +Boolean to indicate whether or not a change to revert to is required. + =head3 C The deployment target URI. @@ -241,7 +269,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/rework.pm b/lib/App/Sqitch/Command/rework.pm index ddaa1059..10f6b3a8 100644 --- a/lib/App/Sqitch/Command/rework.pm +++ b/lib/App/Sqitch/Command/rework.pm @@ -203,6 +203,9 @@ sub _copy { return; } + # Create the directory for the file, if it does not exist. + $self->_mkpath($dest->dir->stringify); + # Stringify to work around bug in File::Copy warning on 5.10.0. File::Copy::syscopy "$src", "$dest" or hurl rework => __x( 'Cannot copy {src} to {dest}: {error}', @@ -310,7 +313,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/show.pm b/lib/App/Sqitch/Command/show.pm index 2170ae2c..11fe8f90 100644 --- a/lib/App/Sqitch/Command/show.pm +++ b/lib/App/Sqitch/Command/show.pm @@ -181,7 +181,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/status.pm b/lib/App/Sqitch/Command/status.pm index 2985008a..45a3c832 100644 --- a/lib/App/Sqitch/Command/status.pm +++ b/lib/App/Sqitch/Command/status.pm @@ -409,7 +409,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/tag.pm b/lib/App/Sqitch/Command/tag.pm index 85ea4a15..887dba00 100644 --- a/lib/App/Sqitch/Command/tag.pm +++ b/lib/App/Sqitch/Command/tag.pm @@ -183,7 +183,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/target.pm b/lib/App/Sqitch/Command/target.pm index 0ae91149..69b28c87 100644 --- a/lib/App/Sqitch/Command/target.pm +++ b/lib/App/Sqitch/Command/target.pm @@ -314,7 +314,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/upgrade.pm b/lib/App/Sqitch/Command/upgrade.pm index e264c64b..df477ce7 100644 --- a/lib/App/Sqitch/Command/upgrade.pm +++ b/lib/App/Sqitch/Command/upgrade.pm @@ -124,7 +124,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Command/verify.pm b/lib/App/Sqitch/Command/verify.pm index 9981bd20..5324987d 100644 --- a/lib/App/Sqitch/Command/verify.pm +++ b/lib/App/Sqitch/Command/verify.pm @@ -182,7 +182,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Config.pm b/lib/App/Sqitch/Config.pm index 56f38381..b039a26f 100644 --- a/lib/App/Sqitch/Config.pm +++ b/lib/App/Sqitch/Config.pm @@ -208,7 +208,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/DateTime.pm b/lib/App/Sqitch/DateTime.pm index 02cbdcba..39ce7c09 100644 --- a/lib/App/Sqitch/DateTime.pm +++ b/lib/App/Sqitch/DateTime.pm @@ -191,7 +191,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine.pm b/lib/App/Sqitch/Engine.pm index 91fe757e..89dfab35 100644 --- a/lib/App/Sqitch/Engine.pm +++ b/lib/App/Sqitch/Engine.pm @@ -70,13 +70,27 @@ has start_at => ( has no_prompt => ( is => 'rw', isa => Bool, - default => 0, + trigger => sub { + # Deprecation notice added Feb 2023 + warnings::warnif( + "deprecated", + "Engine::no_prompt is deprecated and will be removed in a future release\n" + . "Use direct arguments to revert() instead", + ); + } ); has prompt_accept => ( is => 'rw', isa => Bool, - default => 1, + trigger => sub { + # Deprecation notice added Feb 2023 + warnings::warnif( + "deprecated", + "Engine::prompt_accept is deprecated and will be removed in a future release\n" + . "Use direct arguments to revert() instead", + ); + } ); has log_only => ( @@ -131,6 +145,12 @@ has _locked => ( default => 0, ); +has _no_registry => ( + is => 'rw', + isa => Bool, + default => 0, +); + sub variables { %{ shift->_variables } } sub set_variables { shift->_variables({ @_ }) } sub clear_variables { %{ shift->_variables } = () } @@ -249,6 +269,11 @@ sub deploy { ) ); + $sqitch->debug(__ "Will deploy the following changes:"); + foreach my $will_deploy_position ($plan->position .. $to_index) { + $sqitch->debug($plan->change_at($will_deploy_position)->format_name_with_tags); + } + # Check that all dependencies will be satisfied. $self->check_deploy_dependencies($plan, $to_index); @@ -269,8 +294,34 @@ sub deploy { $self->$meth( $plan, $to_index ); } +# Do a thing similar to Sqitch::Plan::Change::format_name_with_tags, +# but for an output from $self->deployed_changes or +# $self->deployed_changes_since. +sub _format_deployed_change_name_with_tags($) { + my ( $self, $change ) = @_; + + return join ' ', $change->{name}, map { '@' . $_ } @{$change->{tags}}; +} + sub revert { - my ( $self, $to ) = @_; + # $to = revert up to (but not including) this change. May be undefined. + # $prompt = If true, we ask for confirmation; if false, we don't. + # $prompt_default = Default if the user just hits enter at the prompt. + my ( $self, $to, $prompt, $prompt_default ) = @_; + + if (defined $prompt) { + hurl revert => __('Missing required parameter $prompt_default') + unless defined $prompt_default; + } else { + warnings::warnif( + "deprecated", + "Engine::revert() requires the `prompt` and `prompt_default` arguments.\n" + . 'Omitting them will become fatal in a future release.', + ); + + $prompt = !($self->no_prompt // 0); + $prompt_default = $self->prompt_accept // 1; + } # Check the registry and, once we know it's there, lock the destination. $self->_check_registry; @@ -299,6 +350,8 @@ sub revert { ); }; + # NB this is an array of unblessed references, not of + # Sqitch::Plan::Change references. @changes = $self->deployed_changes_since( $self->_load_changes($change) ) or do { @@ -308,14 +361,20 @@ sub revert { )); return $self; }; + my @change_descriptions = + map { $self->_format_deployed_change_name_with_tags($_) } @changes; - if ($self->no_prompt) { + unless ($prompt) { $sqitch->info(__x( 'Reverting changes to {change} from {destination}', change => $change->format_name_with_tags, destination => $self->destination, )); + $sqitch->info(__ 'Will revert the following changes:'); + map { $sqitch->info($_) } @change_descriptions; } else { + $sqitch->info(__ 'Would revert the following changes:'); + map { $sqitch->info($_) } @change_descriptions; hurl { ident => 'revert:confirm', message => __ 'Nothing reverted', @@ -324,21 +383,28 @@ sub revert { 'Revert changes to {change} from {destination}?', change => $change->format_name_with_tags, destination => $self->destination, - ), $self->prompt_accept ); + ), $prompt_default ); } - } else { + # NB this is an array of unblessed references, not of + # Sqitch::Plan::Change references. @changes = $self->deployed_changes or do { $sqitch->info(__ 'Nothing to revert (nothing deployed)'); return $self; }; + my @change_descriptions = + map { $self->_format_deployed_change_name_with_tags($_) } @changes; - if ($self->no_prompt) { + unless ($prompt) { $sqitch->info(__x( 'Reverting all changes from {destination}', destination => $self->destination, )); + $sqitch->info(__ 'Will revert the following changes:'); + map { $sqitch->info($_) } @change_descriptions; } else { + $sqitch->info(__ 'Would revert the following changes:'); + map { $sqitch->info($_) } @change_descriptions; hurl { ident => 'revert', message => __ 'Nothing reverted', @@ -346,7 +412,7 @@ sub revert { } unless $sqitch->ask_yes_no(__x( 'Revert all changes from {destination}?', destination => $self->destination, - ), $self->prompt_accept ); + ), $prompt_default ); } } @@ -369,6 +435,9 @@ sub revert { 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; @@ -914,7 +983,10 @@ sub _sync_plan { my $self = shift; my $plan = $self->plan; - if (my $state = $self->current_state) { + if ($self->_no_registry) { + # No registry found on connection, so no records in the database. + $plan->reset; + } elsif (my $state = $self->current_state) { my $idx = $plan->index_of($state->{change_id}) // hurl plan => __x( 'Cannot find change {id} ({change}) in {file}', id => $state->{change_id}, @@ -1249,11 +1321,23 @@ sub check { } sub initialized { + return 0 if $_[0]->_no_registry; + return $_[0]->_initialized; +} + +sub _initialized { my $class = ref $_[0] || $_[0]; hurl "$class has not implemented initialized()"; } sub initialize { + my $self = shift; + $self->_initialize || return; + $self->_no_registry(0); + return $self; +} + +sub _initialize { my $class = ref $_[0] || $_[0]; hurl "$class has not implemented initialize()"; } @@ -1572,10 +1656,6 @@ The name of the registry schema or database. The point in the plan from which to start deploying changes. -=head3 C - -Boolean indicating whether or not to prompt for reverts. False by default. - =head3 C Boolean indicating whether or not to log changes I. Write your revert scripts carefully! Reverts the L 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 $engine->verify; @@ -2009,6 +2092,21 @@ The default implementation is effectively a no-op; consult the documentation for specific engines to determine whether they have implemented support for destination locking (by overriding C and C). +=head3 C + + $engine->initialize unless $engine->initialized; + +Returns true if the database has been initialized for Sqitch, and false if it +has not. + +=head3 C + + $engine->initialize; + +Initializes the target database for Sqitch by installing the Sqitch registry +schema and/or tables. Should be overridden by subclasses. This implementation +throws an exception + =head2 Abstract Instance Methods These methods must be overridden in subclasses. @@ -2058,20 +2156,16 @@ This method is called after a change has been deployed or reverted and the logging of that change has failed. It should rollback changes started by C. -=head3 C - - $engine->initialize unless $engine->initialized; +=head3 C<_initialized> Returns true if the database has been initialized for Sqitch, and false if it has not. -=head3 C - - $engine->initialize; +=head3 C<_initialize> Initializes the target database for Sqitch by installing the Sqitch registry schema and/or tables. Should be overridden by subclasses. This implementation -throws an exception +throws an exception. =head3 C @@ -2666,7 +2760,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/Upgrade/vertica-1.0.sql b/lib/App/Sqitch/Engine/Upgrade/vertica-1.0.sql index e636bc20..0755dfcf 100644 --- a/lib/App/Sqitch/Engine/Upgrade/vertica-1.0.sql +++ b/lib/App/Sqitch/Engine/Upgrade/vertica-1.0.sql @@ -1,5 +1,5 @@ CREATE TABLE :"registry".releases ( - version FLOAT PRIMARY KEY, + version FLOAT PRIMARY KEY ENABLED, installed_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(), installer_name VARCHAR(1024) NOT NULL, installer_email VARCHAR(1024) NOT NULL @@ -10,6 +10,6 @@ COMMENT ON TABLE :"registry".releases IS 'Sqitch registry releases.'; -- Add the script_hash column to the changes table. Copy change_id for now. ALTER TABLE :"registry".changes ADD COLUMN script_hash CHAR(40); UPDATE :"registry".changes SET script_hash = change_id; -ALTER TABLE :"registry".changes ADD UNIQUE(script_hash); +ALTER TABLE :"registry".changes ADD UNIQUE(script_hash) ENABLED; COMMENT ON SCHEMA :"registry" IS 'Sqitch database deployment metadata v1.0.'; diff --git a/lib/App/Sqitch/Engine/Upgrade/vertica-1.1.sql b/lib/App/Sqitch/Engine/Upgrade/vertica-1.1.sql index 4f05271d..2e650d2c 100644 --- a/lib/App/Sqitch/Engine/Upgrade/vertica-1.1.sql +++ b/lib/App/Sqitch/Engine/Upgrade/vertica-1.1.sql @@ -1,3 +1,3 @@ ALTER TABLE :"registry".changes DROP CONSTRAINT c_unique; -ALTER TABLE :"registry".changes ADD UNIQUE(project, script_hash); +ALTER TABLE :"registry".changes ADD UNIQUE(project, script_hash) ENABLED; COMMENT ON SCHEMA :"registry" IS 'Sqitch database deployment metadata v1.1.'; diff --git a/lib/App/Sqitch/Engine/cockroach.pm b/lib/App/Sqitch/Engine/cockroach.pm index f9afd356..4e8b4859 100644 --- a/lib/App/Sqitch/Engine/cockroach.pm +++ b/lib/App/Sqitch/Engine/cockroach.pm @@ -71,7 +71,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/exasol.pm b/lib/App/Sqitch/Engine/exasol.pm index fb41c4c6..f5d9bb7e 100644 --- a/lib/App/Sqitch/Engine/exasol.pm +++ b/lib/App/Sqitch/Engine/exasol.pm @@ -146,11 +146,8 @@ has dbh => ( ); $dbh->do("ALTER SESSION SET TIME_ZONE='UTC'"); if (my $schema = $self->registry) { - try { - $dbh->do("OPEN SCHEMA $schema"); - # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html - $dbh->set_err(undef, undef) if $dbh->err; - }; + $dbh->do("OPEN SCHEMA $schema") + or $self->_handle_no_registry($dbh); } return; }, @@ -198,7 +195,7 @@ sub _multi_values { return join "\nUNION ALL ", ("SELECT $expr FROM dual") x $count; } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT EXISTS( @@ -320,7 +317,7 @@ sub _registry_variable { return "DEFINE registry=$schema;"; } -sub initialize { +sub _initialize { my $self = shift; my $schema = $self->registry; hurl engine => __ 'Sqitch already initialized' if $self->initialized; @@ -471,6 +468,11 @@ sub _no_column_error { return $DBI::errstr && $DBI::errstr =~ /object \w+ not found/m; } +sub _unique_error { + # Unique constraints not supported by Exasol + return 0; +} + sub _script { my $self = shift; my $uri = $self->uri; @@ -570,7 +572,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/exasol.sql b/lib/App/Sqitch/Engine/exasol.sql index 3f16005e..d7731ad5 100644 --- a/lib/App/Sqitch/Engine/exasol.sql +++ b/lib/App/Sqitch/Engine/exasol.sql @@ -42,7 +42,7 @@ CREATE TABLE ®istry..changes ( planned_at TIMESTAMP WITH LOCAL TIME ZONE NOT NULL, planner_name VARCHAR2(512 CHAR) NOT NULL, planner_email VARCHAR2(512 CHAR) NOT NULL - -- UNIQUE(project, script_hash) + -- UNIQUE(project, script_hash) -- not supported in EXASOL ); COMMENT ON TABLE ®istry..changes IS 'Tracks the changes currently deployed to the database.'; diff --git a/lib/App/Sqitch/Engine/firebird.pm b/lib/App/Sqitch/Engine/firebird.pm index 015cc110..a141bf42 100644 --- a/lib/App/Sqitch/Engine/firebird.pm +++ b/lib/App/Sqitch/Engine/firebird.pm @@ -184,7 +184,7 @@ sub is_deployed_tag { }, undef, $tag->id)->[0]; } -sub initialized { +sub _initialized { my $self = shift; # Try to connect. @@ -201,7 +201,7 @@ sub initialized { }, undef, 'CHANGES')->[0]; } -sub initialize { +sub _initialize { my $self = shift; my $uri = $self->registry_uri; hurl engine => __x( @@ -294,6 +294,10 @@ sub _no_column_error { return $DBI::errstr && $DBI::errstr =~ /^-Column unknown/m; } +sub _unique_error { + return $DBI::errstr && $DBI::errstr =~ /no 2 table rows can have duplicate column values$/m; +} + sub _regex_op { 'SIMILAR TO' } # NOT good match for # REGEXP :( @@ -812,23 +816,31 @@ sub log_deploy_change { planner_email committed_at )); - $dbh->do(qq{ - INSERT INTO changes ( - $cols - ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, $ts) - }, undef, - $id, - $change->script_hash, - $name, - $proj, - $change->note, - $user, - $email, - $self->_char2ts( $change->timestamp ), - $change->planner_name, - $change->planner_email, - ); + try { + $dbh->do(qq{ + INSERT INTO changes ( + $cols + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, $ts) + }, undef, + $id, + $change->script_hash, + $name, + $proj, + $change->note, + $user, + $email, + $self->_char2ts( $change->timestamp ), + $change->planner_name, + $change->planner_email, + ); + } catch { + hurl engine => __x( + 'Cannot log change "{change}": The deploy script is not unique', + change => $name, + ) if $self->_unique_error; + die $_; + }; if ( my @deps = $change->dependencies ) { foreach my $dep (@deps) { @@ -984,7 +996,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Copyright (c) 2013 Ștefan Suciu diff --git a/lib/App/Sqitch/Engine/mysql.pm b/lib/App/Sqitch/Engine/mysql.pm index fc5e12a6..27adb6e9 100644 --- a/lib/App/Sqitch/Engine/mysql.pm +++ b/lib/App/Sqitch/Engine/mysql.pm @@ -88,7 +88,7 @@ has dbh => ( Callbacks => { connected => sub { my $dbh = shift; - $dbh->do("SET SESSION $_") for ( + $dbh->do("SET SESSION $_") or return for ( q{character_set_client = 'utf8'}, q{character_set_server = 'utf8'}, ($dbh->{mysql_serverversion} || 0 < 50500 ? () : (q{default_storage_engine = 'InnoDB'})), @@ -104,15 +104,6 @@ has dbh => ( error_for_division_by_zero )) . q{'}, ); - if (!$dbh->{mysql_serverversion} && DBI->VERSION < 1.631) { - # Prior to 1.631, callbacks were inner handles and - # mysql_* aren't set yet. So set InnoDB in a try block. - try { - $dbh->do(q{SET SESSION default_storage_engine = 'InnoDB'}); - }; - # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html - $dbh->set_err(undef, undef) if $dbh->err; - } return; }, }, @@ -277,7 +268,7 @@ has initialized => ( } ); -sub initialize { +sub _initialize { my $self = shift; hurl engine => __x( 'Sqitch database {database} already initialized', @@ -367,6 +358,10 @@ sub _no_column_error { return $DBI::state && $DBI::state eq '42S22' && $DBI::err == '1054'; # ER_BAD_FIELD_ERROR } +sub _unique_error { + return $DBI::state && $DBI::state eq '23000' && $DBI::err == '1062'; # ER_DUP_ENTRY +} + sub _regex_op { 'REGEXP' } sub _limit_default { '18446744073709551615' } @@ -571,7 +566,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/oracle.pm b/lib/App/Sqitch/Engine/oracle.pm index 00abd113..e4022949 100644 --- a/lib/App/Sqitch/Engine/oracle.pm +++ b/lib/App/Sqitch/Engine/oracle.pm @@ -75,10 +75,17 @@ has tmpdir => ( sub key { 'oracle' } sub name { 'Oracle' } sub driver { 'DBD::Oracle 1.23' } -sub default_registry { '' } +sub default_registry { $_[0]->username || '' } sub default_client { - file( ($ENV{ORACLE_HOME} || ()), 'sqlplus' )->stringify + if ($ENV{ORACLE_HOME}) { + my $bin = 'sqlplus' . (App::Sqitch::ISWIN || $^O eq 'cygwin' ? '.exe' : ''); + my $path = file $ENV{ORACLE_HOME}, 'bin', $bin; + return $path->stringify if -f $path && -x $path; + $path = file $ENV{ORACLE_HOME}, $bin; + return $path->stringify if -f $path && -x $path; + } + return 'sqlplus'; } has dbh => ( @@ -110,11 +117,8 @@ has dbh => ( nls_timestamp_tz_format ); if (my $schema = $self->registry) { - try { - $dbh->do("ALTER SESSION SET CURRENT_SCHEMA = $schema"); - # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html - $dbh->set_err(undef, undef) if $dbh->err; - }; + $dbh->do("ALTER SESSION SET CURRENT_SCHEMA = $schema") + or $self->_handle_no_registry($dbh); } return; }, @@ -258,14 +262,14 @@ sub is_deployed_change { )->[0]; } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT 1 FROM all_tables WHERE owner = UPPER(?) AND table_name = 'CHANGES' - }, undef, $self->registry || $self->username)->[0]; + }, undef, $self->registry)->[0]; } sub _log_event { @@ -452,7 +456,7 @@ sub _registry_variable { ); } -sub initialize { +sub _initialize { my $self = shift; my $schema = $self->registry; hurl engine => __ 'Sqitch already initialized' if $self->initialized; @@ -691,6 +695,10 @@ sub _no_column_error { return $DBI::err && $DBI::err == 904; # ORA-00904: invalid identifier } +sub _unique_error { + return $DBI::err && $DBI::err == 1; # ORA-00001: unique constraint violated +} + sub _script { my $self = shift; my $uri = $self->uri; @@ -814,7 +822,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/pg.pm b/lib/App/Sqitch/Engine/pg.pm index c112e78f..9a7ad2bf 100644 --- a/lib/App/Sqitch/Engine/pg.pm +++ b/lib/App/Sqitch/Engine/pg.pm @@ -137,14 +137,13 @@ has dbh => ( connected => sub { my $dbh = shift; $dbh->do('SET client_min_messages = WARNING'); - try { - $dbh->do( - 'SET search_path = ?', - undef, $self->registry - ); - # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html - $dbh->set_err(undef, undef) if $dbh->err; - }; + # Setting search currently never fails, but call + # _handle_no_registry in case that changes in the future. + $dbh->do( + 'SET search_path = ?', + undef, $self->registry + ) or $self->_handle_no_registry($dbh); + # Determine the provider. Yugabyte says this is the right way to do it. # https://yugabyte-db.slack.com/archives/CG0KQF0GG/p1653762283847589 my $v = $dbh->selectcol_arrayref( @@ -187,9 +186,9 @@ sub _listagg_format { return q{array_remove(array_agg(%1$s ORDER BY %1$s), NULL)} if $dbh->{pg_server_version} >= 90300; - # Since 8.4 we can use ORDER BY. + # Since 9.0 we can use ORDER BY. return q{ARRAY(SELECT * FROM UNNEST( array_agg(%1$s ORDER BY %1$s) ) a WHERE a IS NOT NULL)} - if $dbh->{pg_server_version} >= 80400; + if $dbh->{pg_server_version} >= 90000; return q{ARRAY(SELECT * FROM UNNEST( array_agg(%s) ) a WHERE a IS NOT NULL)}; } @@ -198,7 +197,7 @@ sub _regex_op { '~' } sub _version_query { 'SELECT MAX(version)::TEXT FROM releases' } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT EXISTS( @@ -208,7 +207,7 @@ sub initialized { }, undef, $self->registry, 'changes')->[0]; } -sub initialize { +sub _initialize { my $self = shift; hurl engine => __x( 'Sqitch schema "{schema}" already exists', @@ -463,10 +462,15 @@ sub _no_table_error { return 1; } +# https://www.postgresql.org/docs/current/errcodes-appendix.html sub _no_column_error { return $DBI::state && $DBI::state eq '42703'; # undefined_column } +sub _unique_error { + return $DBI::state && $DBI::state eq '23505'; # unique_violation +} + sub _in_expr { my ($self, $vals) = @_; return '= ANY(?)', $vals; @@ -550,7 +554,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/snowflake.pm b/lib/App/Sqitch/Engine/snowflake.pm index 7c5cc5c7..b8f45c07 100644 --- a/lib/App/Sqitch/Engine/snowflake.pm +++ b/lib/App/Sqitch/Engine/snowflake.pm @@ -192,8 +192,6 @@ has dbh => ( my $self = shift; $self->use_driver; my $uri = $self->uri; - my $wh = $self->warehouse; - my $role = $self->role; DBI->connect($uri->dbi_dsn, $self->username, $self->password, { PrintError => 0, RaiseError => 0, @@ -209,22 +207,24 @@ has dbh => ( Callbacks => { connected => sub { my $dbh = shift; - try { - $dbh->do($_) for ( - ($role ? ("USE ROLE $role") : ()), - "ALTER WAREHOUSE $wh RESUME IF SUSPENDED", - "USE WAREHOUSE $wh", - 'USE SCHEMA ' . $self->registry, - 'ALTER SESSION SET TIMESTAMP_TYPE_MAPPING=TIMESTAMP_LTZ', - "ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT='YYYY-MM-DD HH24:MI:SS'", - "ALTER SESSION SET TIMEZONE='UTC'", - ); - $dbh->set_err(undef, undef) if $dbh->err; - }; + my $wh = _quote_ident($dbh, $self->warehouse); + my $role = $self->role; + $dbh->do($_) or return for ( + ($role ? ("USE ROLE " . _quote_ident($dbh, $role)) : ()), + "ALTER WAREHOUSE $wh RESUME IF SUSPENDED", + "USE WAREHOUSE $wh", + 'ALTER SESSION SET TIMESTAMP_TYPE_MAPPING=TIMESTAMP_LTZ', + "ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT='YYYY-MM-DD HH24:MI:SS'", + "ALTER SESSION SET TIMEZONE='UTC'", + ); + $dbh->do('USE SCHEMA ' . _quote_ident($dbh, $self->registry)) + or $self->_handle_no_registry($dbh); return; }, disconnect => sub { - shift->do("ALTER WAREHOUSE $wh SUSPEND"); + my $dbh = shift; + my $wh = _quote_ident($dbh, $self->warehouse); + $dbh->do("ALTER WAREHOUSE $wh SUSPEND"); return; }, }, @@ -232,6 +232,14 @@ has dbh => ( } ); +sub _quote_ident { + my ($dbh, $ident) = @_; + # https://docs.snowflake.com/en/sql-reference/identifiers-syntax + return $ident if $ident =~ /^[_a-zA-Z][_a-zA-Z0-9\$]*$/; + return $ident if $ident =~ /^"/ && $ident =~ /"$/; + return $dbh->quote_identifier($ident); +} + # Need to wait until dbh is defined. with 'App::Sqitch::Role::DBIEngine'; @@ -284,7 +292,7 @@ sub _listagg_format { sub _ts_default { 'current_timestamp' } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT true @@ -295,7 +303,7 @@ sub initialized { }, undef, $self->registry, 'changes')->[0]; } -sub initialize { +sub _initialize { my $self = shift; my $schema = $self->registry; hurl engine => __x( @@ -316,6 +324,13 @@ sub _no_column_error { return $DBI::state && $DBI::state eq '42703'; # ERRCODE_UNDEFINED_COLUMN } +sub _unique_error { + # https://docs.snowflake.com/en/sql-reference/constraints-overview + # Snowflake supports defining and maintaining constraints, but does not + # enforce them, except for NOT NULL constraints, which are always enforced. + return 0; +} + sub _ts2char_format { # The colon has to be inside the quotation marks, because otherwise it # generates wayward single quotation marks. Bug report: @@ -710,7 +725,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/sqlite.pm b/lib/App/Sqitch/Engine/sqlite.pm index b5526b63..228fb8f4 100644 --- a/lib/App/Sqitch/Engine/sqlite.pm +++ b/lib/App/Sqitch/Engine/sqlite.pm @@ -95,9 +95,9 @@ has dbh => ( # Make sure we support this version. my @v = split /[.]/ => $dbh->{sqlite_version}; hurl sqlite => __x( - 'Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}', + 'Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}', version => $dbh->{sqlite_version} - ) unless $v[0] > 3 || ($v[0] == 3 && ($v[1] > 7 || ($v[1] == 7 && $v[2] >= 11))); + ) unless $v[0] > 3 || ($v[0] == 3 && ($v[1] > 8 || ($v[1] == 8 && $v[2] >= 6))); return $dbh; } @@ -143,7 +143,7 @@ sub sqlite3 { @{ shift->_sqlite3 } } sub _version_query { 'SELECT CAST(ROUND(MAX(version), 1) AS TEXT) FROM releases' } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT EXISTS( @@ -152,7 +152,7 @@ sub initialized { }, undef, 'changes')->[0]; } -sub initialize { +sub _initialize { my $self = shift; hurl engine => __x( 'Sqitch database {database} already initialized', @@ -175,6 +175,10 @@ sub _no_column_error { return $DBI::errstr && $DBI::errstr =~ /^\Qno such column:/; } +sub _unique_error { + return $DBI::errstr && $DBI::errstr =~ /^\QUNIQUE constraint failed:/; +} + sub _regex_op { 'REGEXP' } sub _limit_default { -1 } @@ -284,7 +288,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/vertica.pm b/lib/App/Sqitch/Engine/vertica.pm index ef0ebaa8..7ac2e485 100644 --- a/lib/App/Sqitch/Engine/vertica.pm +++ b/lib/App/Sqitch/Engine/vertica.pm @@ -98,13 +98,8 @@ has dbh => ( Callbacks => { connected => sub { my $dbh = shift; - try { - $dbh->do( - 'SET search_path = ' . $dbh->quote($self->registry) - ); - # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html - $dbh->set_err(undef, undef) if $dbh->err; - }; + $dbh->do('SET search_path = ' . $dbh->quote($self->registry)) + or $self->_handle_no_registry($dbh); return; }, }, @@ -128,7 +123,7 @@ sub _client_opts { ); } -sub initialized { +sub _initialized { my $self = shift; return $self->dbh->selectcol_arrayref(q{ SELECT EXISTS( @@ -137,7 +132,7 @@ sub initialized { }, undef, $self->registry)->[0]; } -sub initialize { +sub _initialize { my $self = shift; my $schema = $self->registry; hurl engine => __x( @@ -167,9 +162,6 @@ sub _run_registry_file { ); (my $sql = scalar $file->slurp) =~ s{:"registry"}{$schema}g; - # No LONG VARCHAR before Vertica 7. - $sql =~ s/LONG //g if $maj < 7; - # Write out the temporary file. require File::Temp; my $fh = File::Temp->new; @@ -188,6 +180,10 @@ sub _no_column_error { return $DBI::state && $DBI::state eq '42703'; # ERRCODE_UNDEFINED_COLUMN } +sub _unique_error { + return $DBI::state && $DBI::state eq '23505'; # ERRCODE_UNIQUE_VIOLATION +} + sub _dt($) { require App::Sqitch::DateTime; return App::Sqitch::DateTime->new(split /:/ => shift); @@ -563,7 +559,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Engine/vertica.sql b/lib/App/Sqitch/Engine/vertica.sql index db5f111d..a75d7242 100644 --- a/lib/App/Sqitch/Engine/vertica.sql +++ b/lib/App/Sqitch/Engine/vertica.sql @@ -3,27 +3,27 @@ CREATE SCHEMA :"registry"; COMMENT ON SCHEMA :"registry" IS 'Sqitch database deployment metadata v1.1.'; CREATE TABLE :"registry".releases ( - version FLOAT PRIMARY KEY, + version FLOAT PRIMARY KEY ENABLED, installed_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(), installer_name VARCHAR(1024) NOT NULL, installer_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".releases IS 'Sqitch registry releases.'; +COMMENT ON TABLE :"registry".releases IS 'Sqitch registry releases.'; CREATE TABLE :"registry".projects ( - project VARCHAR(1024) PRIMARY KEY ENCODING AUTO, - uri VARCHAR(1024) NULL UNIQUE, + project VARCHAR(1024) PRIMARY KEY ENABLED ENCODING AUTO, + uri VARCHAR(1024) NULL UNIQUE ENABLED, created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(), creator_name VARCHAR(1024) NOT NULL, creator_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".projects IS 'Sqitch projects deployed to this database.'; +COMMENT ON TABLE :"registry".projects IS 'Sqitch projects deployed to this database.'; CREATE TABLE :"registry".changes ( - change_id CHAR(40) PRIMARY KEY ENCODING AUTO, - script_hash CHAR(40) NULL UNIQUE, + change_id CHAR(40) PRIMARY KEY ENABLED ENCODING AUTO, + script_hash CHAR(40) NULL UNIQUE ENABLED, change VARCHAR(1024) NOT NULL, project VARCHAR(1024) NOT NULL REFERENCES :"registry".projects(project), note VARCHAR(65000) NOT NULL DEFAULT '', @@ -35,10 +35,10 @@ CREATE TABLE :"registry".changes ( planner_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".changes IS 'Tracks the changes currently deployed to the database.'; +COMMENT ON TABLE :"registry".changes IS 'Tracks the changes currently deployed to the database.'; CREATE TABLE :"registry".tags ( - tag_id CHAR(40) PRIMARY KEY ENCODING AUTO, + tag_id CHAR(40) PRIMARY KEY ENABLED ENCODING AUTO, tag VARCHAR(1024) NOT NULL, project VARCHAR(1024) NOT NULL REFERENCES :"registry".projects(project), change_id CHAR(40) NOT NULL REFERENCES :"registry".changes(change_id), @@ -49,20 +49,20 @@ CREATE TABLE :"registry".tags ( planned_at TIMESTAMPTZ NOT NULL, planner_name VARCHAR(1024) NOT NULL, planner_email VARCHAR(1024) NOT NULL, - UNIQUE(project, tag) + UNIQUE(project, tag) ENABLED ); -COMMENT ON TABLE :"registry".tags IS 'Tracks the tags currently applied to the database.'; +COMMENT ON TABLE :"registry".tags IS 'Tracks the tags currently applied to the database.'; CREATE TABLE :"registry".dependencies ( change_id CHAR(40) NOT NULL REFERENCES :"registry".changes(change_id), type VARCHAR(8) NOT NULL ENCODING AUTO, dependency VARCHAR(2048) NOT NULL, dependency_id CHAR(40) NULL REFERENCES :"registry".changes(change_id), - PRIMARY KEY (change_id, dependency) + PRIMARY KEY (change_id, dependency) ENABLED ); -COMMENT ON TABLE :"registry".dependencies IS 'Tracks the currently satisfied dependencies.'; +COMMENT ON TABLE :"registry".dependencies IS 'Tracks the currently satisfied dependencies.'; CREATE TABLE :"registry".events ( event VARCHAR(6) NOT NULL ENCODING AUTO, @@ -79,7 +79,7 @@ CREATE TABLE :"registry".events ( planned_at TIMESTAMPTZ NOT NULL, planner_name VARCHAR(1024) NOT NULL, planner_email VARCHAR(1024) NOT NULL, - PRIMARY KEY (change_id, committed_at) + PRIMARY KEY (change_id, committed_at) ENABLED ); -COMMENT ON TABLE :"registry".events IS 'Contains full history of all deployment events.'; +COMMENT ON TABLE :"registry".events IS 'Contains full history of all deployment events.'; diff --git a/lib/App/Sqitch/ItemFormatter.pm b/lib/App/Sqitch/ItemFormatter.pm index 5a9c8064..86510b24 100644 --- a/lib/App/Sqitch/ItemFormatter.pm +++ b/lib/App/Sqitch/ItemFormatter.pm @@ -50,51 +50,46 @@ has formatter => ( isa => class_type('String::Formatter'), default => sub { my $self = shift; - no if $] >= 5.017011, warnings => 'experimental::smartmatch'; String::Formatter->new({ input_processor => 'require_single_input', string_replacer => 'method_replace', codes => { e => sub { $_[0]->{event} }, L => sub { - given ($_[0]->{event}) { - when ('deploy') { return __ 'Deploy' } - when ('revert') { return __ 'Revert' } - when ('fail') { return __ 'Fail' } - } + my $e = $_[0]->{event}; + return $e eq 'deploy' ? __ 'Deploy' + : $e eq 'revert' ? __ 'Revert' + : $e eq 'fail' ? __ 'Fail' + : hurl "Unknown event type $e"; # should not happen }, l => sub { - given ($_[0]->{event}) { - when ('deploy') { return __ 'deploy' } - when ('revert') { return __ 'revert' } - when ('fail') { return __ 'fail' } - } + my $e = $_[0]->{event}; + return $e eq 'deploy' ? __ 'deploy' + : $e eq 'revert' ? __ 'revert' + : $e eq 'fail' ? __ 'fail' + : hurl "Unknown event type $e"; # should not happen }, _ => sub { - given ($_[1]) { - when ('event') { return __ 'Event: ' } - when ('change') { return __ 'Change: ' } - when ('committer') { return __ 'Committer:' } - when ('planner') { return __ 'Planner: ' } - when ('by') { return __ 'By: ' } - when ('date') { return __ 'Date: ' } - when ('committed') { return __ 'Committed:' } - when ('planned') { return __ 'Planned: ' } - when ('name') { return __ 'Name: ' } - when ('project') { return __ 'Project: ' } - when ('email') { return __ 'Email: ' } - when ('requires') { return __ 'Requires: ' } - when ('conflicts') { return __ 'Conflicts:' } - when (undef) { - hurl format => __ 'No label passed to the _ format'; - } - default { - hurl format => __x( - 'Unknown label "{label}" passed to the _ format', - label => $_[1], - ); - } - }; + my $x = $_[1]; + hurl format => __ 'No label passed to the _ format' + unless defined $x; + return $x eq 'event' ? __ 'Event: ' + : $x eq 'change' ? __ 'Change: ' + : $x eq 'committer' ? __ 'Committer:' + : $x eq 'planner' ? __ 'Planner: ' + : $x eq 'by' ? __ 'By: ' + : $x eq 'date' ? __ 'Date: ' + : $x eq 'committed' ? __ 'Committed:' + : $x eq 'planned' ? __ 'Planned: ' + : $x eq 'name' ? __ 'Name: ' + : $x eq 'project' ? __ 'Project: ' + : $x eq 'email' ? __ 'Email: ' + : $x eq 'requires' ? __ 'Requires: ' + : $x eq 'conflicts' ? __ 'Conflicts:' + : hurl format => __x( + 'Unknown label "{label}" passed to the _ format', + label => $x, + ); }, H => sub { $_[0]->{change_id} }, h => sub { @@ -105,12 +100,13 @@ has formatter => ( }, n => sub { $_[0]->{change} }, o => sub { $_[0]->{project} }, + F => sub { $_[0]->{deploy_file} }, c => sub { return "$_[0]->{committer_name} <$_[0]->{committer_email}>" unless defined $_[1]; - return $_[0]->{committer_name} if $_[1] ~~ [qw(n name)]; - return $_[0]->{committer_email} if $_[1] ~~ [qw(e email)]; + return $_[0]->{committer_name} if $_[1] =~ /\An(?:ame)?\z/; + return $_[0]->{committer_email} if $_[1] =~ /\Ae(?:mail)?\z/; return $_[0]->{committed_at}->as_string( format => $_[1] || $self->date_format ) if $_[1] =~ s/^d(?:ate)?(?::|$)//; @@ -119,8 +115,8 @@ has formatter => ( p => sub { return "$_[0]->{planner_name} <$_[0]->{planner_email}>" unless defined $_[1]; - return $_[0]->{planner_name} if $_[1] ~~ [qw(n name)]; - return $_[0]->{planner_email} if $_[1] ~~ [qw(e email)]; + return $_[0]->{planner_name} if $_[1] =~ /\An(?:ame)?\z/; + return $_[0]->{planner_email} if $_[1] =~ /\Ae(?:mail)?\z/; return $_[0]->{planned_at}->as_string( format => $_[1] || $self->date_format ) if $_[1] =~ s/^d(?:ate)?(?::|$)//; @@ -128,12 +124,12 @@ has formatter => ( t => sub { @{ $_[0]->{tags} } - ? ' ' . join $_[1] || ', ' => @{ $_[0]->{tags} } + ? ' ' . join defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{tags} } : ''; }, T => sub { @{ $_[0]->{tags} } - ? ' (' . join($_[1] || ', ' => @{ $_[0]->{tags} }) . ')' + ? ' (' . join(defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{tags} }) . ')' : ''; }, v => sub { "\n" }, @@ -168,24 +164,24 @@ has formatter => ( }, r => sub { @{ $_[0]->{requires} } - ? ' ' . join $_[1] || ', ' => @{ $_[0]->{requires} } + ? ' ' . join defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{requires} } : ''; }, R => sub { return '' unless @{ $_[0]->{requires} }; return __ ('Requires: ') . ' ' . join( - $_[1] || ', ' => @{ $_[0]->{requires} } + defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{requires} } ) . "\n"; }, x => sub { @{ $_[0]->{conflicts} } - ? ' ' . join $_[1] || ', ' => @{ $_[0]->{conflicts} } + ? ' ' . join defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{conflicts} } : ''; }, X => sub { return '' unless @{ $_[0]->{conflicts} }; return __('Conflicts:') . ' ' . join( - $_[1] || ', ' => @{ $_[0]->{conflicts} } + defined $_[1] ? $_[1] : ', ' => @{ $_[0]->{conflicts} } ) . "\n"; }, a => sub { @@ -440,6 +436,8 @@ The placeholders are: =item * C<%o>: Event change project name +=item * C<%F>: Deploy file name + =item * C<%($len)h>: abbreviated change of length C<$len> =item * C<%e>: Event type (deploy, revert, fail) @@ -584,7 +582,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan.pm b/lib/App/Sqitch/Plan.pm index 78b73dfd..ce7fb419 100644 --- a/lib/App/Sqitch/Plan.pm +++ b/lib/App/Sqitch/Plan.pm @@ -1607,7 +1607,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Blank.pm b/lib/App/Sqitch/Plan/Blank.pm index 16931e2c..0c05d274 100644 --- a/lib/App/Sqitch/Plan/Blank.pm +++ b/lib/App/Sqitch/Plan/Blank.pm @@ -39,7 +39,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Change.pm b/lib/App/Sqitch/Plan/Change.pm index d0538f4e..d3aef0b7 100644 --- a/lib/App/Sqitch/Plan/Change.pm +++ b/lib/App/Sqitch/Plan/Change.pm @@ -647,7 +647,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/ChangeList.pm b/lib/App/Sqitch/Plan/ChangeList.pm index 7f674b4d..04b93526 100644 --- a/lib/App/Sqitch/Plan/ChangeList.pm +++ b/lib/App/Sqitch/Plan/ChangeList.pm @@ -410,7 +410,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Depend.pm b/lib/App/Sqitch/Plan/Depend.pm index 336e6864..faf98646 100644 --- a/lib/App/Sqitch/Plan/Depend.pm +++ b/lib/App/Sqitch/Plan/Depend.pm @@ -366,7 +366,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Line.pm b/lib/App/Sqitch/Plan/Line.pm index b2b9409a..3a1f519b 100644 --- a/lib/App/Sqitch/Plan/Line.pm +++ b/lib/App/Sqitch/Plan/Line.pm @@ -347,7 +347,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/LineList.pm b/lib/App/Sqitch/Plan/LineList.pm index 9f22a3a4..c806fffe 100644 --- a/lib/App/Sqitch/Plan/LineList.pm +++ b/lib/App/Sqitch/Plan/LineList.pm @@ -110,7 +110,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Pragma.pm b/lib/App/Sqitch/Plan/Pragma.pm index 55c0bb70..0f9d3cd0 100644 --- a/lib/App/Sqitch/Plan/Pragma.pm +++ b/lib/App/Sqitch/Plan/Pragma.pm @@ -102,7 +102,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Plan/Tag.pm b/lib/App/Sqitch/Plan/Tag.pm index 5145f7e9..356a9e0a 100644 --- a/lib/App/Sqitch/Plan/Tag.pm +++ b/lib/App/Sqitch/Plan/Tag.pm @@ -158,7 +158,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Role/ConnectingCommand.pm b/lib/App/Sqitch/Role/ConnectingCommand.pm index 447735b5..70bff56d 100644 --- a/lib/App/Sqitch/Role/ConnectingCommand.pm +++ b/lib/App/Sqitch/Role/ConnectingCommand.pm @@ -120,7 +120,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Role/ContextCommand.pm b/lib/App/Sqitch/Role/ContextCommand.pm index 4d8d899d..a8cc523b 100644 --- a/lib/App/Sqitch/Role/ContextCommand.pm +++ b/lib/App/Sqitch/Role/ContextCommand.pm @@ -122,7 +122,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Role/DBIEngine.pm b/lib/App/Sqitch/Role/DBIEngine.pm index f63b7ca6..42bc38ad 100644 --- a/lib/App/Sqitch/Role/DBIEngine.pm +++ b/lib/App/Sqitch/Role/DBIEngine.pm @@ -4,7 +4,7 @@ use 5.010; use strict; use warnings; use utf8; -use DBI; +use DBI 1.631; use Moo::Role; use Try::Tiny; use App::Sqitch::X qw(hurl); @@ -21,7 +21,19 @@ requires '_ts2char_format'; requires '_char2ts'; requires '_listagg_format'; requires '_no_table_error'; +requires '_unique_error'; requires '_handle_lookup_index'; +requires '_no_registry'; +requires 'initialized'; + +# Called on connect if the registry schema does not exist. +sub _handle_no_registry { + my ($self, $dbh) = @_; + # https://www.nntp.perl.org/group/perl.dbi.dev/2013/11/msg7622.html + $dbh->set_err(undef, undef); + $self->_no_registry(1); + return; +} after use_driver => sub { DBI->trace(1) if $_[0]->sqitch->verbosity > 2; @@ -492,23 +504,31 @@ sub log_deploy_change { )); $self->_prepare_to_log(changes => $change); - $dbh->do(qq{ - INSERT INTO changes ( - $cols + try { + $dbh->do(qq{ + INSERT INTO changes ( + $cols + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, $ts) + }, undef, + $id, + $change->script_hash, + $name, + $proj, + $change->note, + $user, + $email, + $self->_char2ts( $change->timestamp ), + $change->planner_name, + $change->planner_email, ) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, $ts) - }, undef, - $id, - $change->script_hash, - $name, - $proj, - $change->note, - $user, - $email, - $self->_char2ts( $change->timestamp ), - $change->planner_name, - $change->planner_email, - ); + } catch { + hurl engine => __x( + 'Cannot log change "{change}": The deploy script is not unique', + change => $name, + ) if $self->_unique_error; + die $_; + }; if ( my @deps = $change->dependencies ) { $dbh->do(q{ @@ -1113,7 +1133,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Role/RevertDeployCommand.pm b/lib/App/Sqitch/Role/RevertDeployCommand.pm index 2ae01e60..b71b682b 100644 --- a/lib/App/Sqitch/Role/RevertDeployCommand.pm +++ b/lib/App/Sqitch/Role/RevertDeployCommand.pm @@ -8,6 +8,8 @@ use Moo::Role; use App::Sqitch::Types qw(Str Int Bool HashRef); use Type::Utils qw(enum); use namespace::autoclean; +use Locale::TextDomain qw(App-Sqitch); +use App::Sqitch::X qw(hurl); requires 'sqitch'; requires 'command'; @@ -119,6 +121,23 @@ around configure => sub { my ( $orig, $class, $config, $opt ) = @_; my $cmd = $class->command; + # Command disabled in strict mode. + hurl { + ident => $cmd, + exitval => 2, + message => __x( + '"{command}" cannot be used in strict mode.\n'. + 'Use explicity revert and deploy commands instead.', + command => $cmd, + ), + } if $config->get( + key => "$cmd.strict", + as => 'bool', + ) // $config->get( + 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}; @@ -228,6 +247,11 @@ the revert. Boolean value to indicate whether or not the default value for the prompt, should the user hit C, is to accept the prompt or deny it. +=head3 C + +Boolean value to indicate whether or not strict mode is enabled; if +so, use of these commands is prohibited. + =head3 C The deployment target URI. @@ -263,7 +287,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Role/TargetConfigCommand.pm b/lib/App/Sqitch/Role/TargetConfigCommand.pm index a48684a0..64acaa5f 100644 --- a/lib/App/Sqitch/Role/TargetConfigCommand.pm +++ b/lib/App/Sqitch/Role/TargetConfigCommand.pm @@ -530,7 +530,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Target.pm b/lib/App/Sqitch/Target.pm index a8e50654..c3af1912 100644 --- a/lib/App/Sqitch/Target.pm +++ b/lib/App/Sqitch/Target.pm @@ -842,7 +842,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/Types.pm b/lib/App/Sqitch/Types.pm index 6a3df691..d9cda3c4 100644 --- a/lib/App/Sqitch/Types.pm +++ b/lib/App/Sqitch/Types.pm @@ -168,7 +168,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/App/Sqitch/X.pm b/lib/App/Sqitch/X.pm index 6d412099..12172983 100644 --- a/lib/App/Sqitch/X.pm +++ b/lib/App/Sqitch/X.pm @@ -175,7 +175,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitch-checkout.pod b/lib/sqitch-checkout.pod index d479e970..6f614e7f 100644 --- a/lib/sqitch-checkout.pod +++ b/lib/sqitch-checkout.pod @@ -280,6 +280,16 @@ executing the revert should be "yes" or "no". The C variable takes precedence over C, and both default to true, meaning to accept the revert. +=item C<[checkout.strict]> + +=item C<[revert.strict]> + +A boolean value that, when true, disables the C command. The +C variable takes precedence over C. + +When the checkout command is disabled, use the C and C +commands directly. + =back =head1 Sqitch diff --git a/lib/sqitch-plan.pod b/lib/sqitch-plan.pod index 542c42b1..9b52a39b 100644 --- a/lib/sqitch-plan.pod +++ b/lib/sqitch-plan.pod @@ -294,6 +294,8 @@ The placeholders are: =item * C<%o>: Event change project name +=item * C<%F>: Deploy file name + =item * C<%($len)h>: abbreviated change of length C<$len> =item * C<%e>: Event type (deploy, revert, fail) diff --git a/lib/sqitch-rebase.pod b/lib/sqitch-rebase.pod index 979e1418..9f676b22 100644 --- a/lib/sqitch-rebase.pod +++ b/lib/sqitch-rebase.pod @@ -317,6 +317,13 @@ executing the revert should be "yes" or "no". The C variable takes precedence over C, and both default to true, meaning to accept the revert by default. +=item C<[rebase.strict]> + +=item C<[revert.strict]> + +A boolean value that, when true, disables the C command. The +C variable takes precedence over C. + =back =head1 Sqitch diff --git a/lib/sqitch-revert.pod b/lib/sqitch-revert.pod index b134b69c..c02a03b8 100644 --- a/lib/sqitch-revert.pod +++ b/lib/sqitch-revert.pod @@ -207,6 +207,11 @@ are merged in the following priority order: =back +=item C + +A boolean value indicating whether or not the change to revert to must +be specified. + =item C<[revert.no_prompt]> A boolean value indicating whether or not to disable the prompt before diff --git a/lib/sqitch.pod b/lib/sqitch.pod index 9ec4d4d9..f81bc41d 100644 --- a/lib/sqitch.pod +++ b/lib/sqitch.pod @@ -20,7 +20,7 @@ Sqitch is a database change management application. It currently supports: =item * L 21+ -=item * L 3.7.11+ +=item * L 3.8.6+ =item * L 5.1+ @@ -30,7 +30,7 @@ Sqitch is a database change management application. It currently supports: =item * L 2.0+ -=item * L 6.0+ +=item * L 7.2+ =item * L 6.0+ @@ -495,7 +495,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-exasol.pod b/lib/sqitchtutorial-exasol.pod index ee365975..17c50b77 100644 --- a/lib/sqitchtutorial-exasol.pod +++ b/lib/sqitchtutorial-exasol.pod @@ -1391,7 +1391,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-firebird.pod b/lib/sqitchtutorial-firebird.pod index 8f5859e6..31fe551d 100644 --- a/lib/sqitchtutorial-firebird.pod +++ b/lib/sqitchtutorial-firebird.pod @@ -1243,7 +1243,7 @@ is planned to make managing idempotent reworkings even easier. Stay tuned. =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-mysql.pod b/lib/sqitchtutorial-mysql.pod index d2287c95..71bae521 100644 --- a/lib/sqitchtutorial-mysql.pod +++ b/lib/sqitchtutorial-mysql.pod @@ -10,7 +10,7 @@ sqitchtutorial-mysql - A tutorial introduction to Sqitch change management on My =head1 Description -This tutorial explains how to create a sqitch-enabled MySQL project, use a VCS +This tutorial explains how to create a sqitch-enabled MySQL 5.7 project, use a VCS for deployment planning, and work with other developers to make sure changes remain in sync and in the proper order. @@ -85,7 +85,7 @@ as appropriate. By default, Sqitch will read F in the current directory for settings. But it will also read F<~/.sqitch/sqitch.conf> for user-specific settings. Since MySQL's -L client|https://dev.mysql.com/doc/refman/5.6/en/mysql.html> is not +L|https://dev.mysql.com/doc/refman/5.7/en/mysql.html> is not in the path on my system, let's go ahead an tell it where to find the client on our computer (don't bother if you're using the L because it uses the @@ -669,14 +669,14 @@ C function again: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Procedure "insert_user" does not exist') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'insert_user'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'insert_user'; ROLLBACK; We simply take advantage of the fact that the new procedure should be listed -in the C table and throw an exception if it does not exist. +in the C table and throw an exception if it does not exist. And F should look something like this: @@ -699,7 +699,7 @@ Now for C; F might look like this: nickname VARCHAR(512), oldpass VARCHAR(512), newpass VARCHAR(512) - ) RETURNS INTEGER SQL SECURITY DEFINER + ) RETURNS INTEGER DETERMINISTIC SQL SECURITY DEFINER BEGIN UPDATE users SET password = md5(newpass) @@ -719,9 +719,9 @@ Use C in F again: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Procedure "change_pass" does not exist') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'change_pass'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'change_pass'; COMMIT; And of course, its C script, F, should look @@ -742,13 +742,13 @@ Try em out! Do we have the functions? Of course we do, they were verified. Still, have a look: - > mysql -u root --execute "SELECT name FROM mysql.proc WHERE db = 'flipr_test'" - +-------------+ - | name | - +-------------+ - | change_pass | - | insert_user | - +-------------+ + > mysql -u root --execute "SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'flipr_test'" + +--------------+ + | routine_name | + +--------------+ + | change_pass | + | insert_user | + +--------------+ And what's the status? @@ -768,7 +768,7 @@ Looks good. Let's make sure revert works: Reverting changes to users from flipr_test - change_pass .. ok - insert_user .. ok - > mysql -u root --execute "SELECT name FROM mysql.proc WHERE db = 'flipr_test'" + > mysql -u root --execute "SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'flipr_test'" Note the use of C<@HEAD^^> to specify that the revert be to two changes prior the last deployed change. Looks good. Let's do the commit and re-deploy dance: @@ -1002,7 +1002,7 @@ and commit them. The C deploy script might look something like: CREATE FUNCTION insert_flip( nickname VARCHAR(512), body VARCHAR(180) - ) RETURNS BIGINT SQL SECURITY DEFINER + ) RETURNS BIGINT DETERMINISTIC SQL SECURITY DEFINER BEGIN INSERT INTO flips (nickname, body) VALUES (nickname, body); @@ -1028,7 +1028,7 @@ And the C deploy script might look something like: CREATE FUNCTION delete_flip( flip_id BIGINT - ) RETURNS INTEGER SQL SECURITY DEFINER + ) RETURNS INTEGER DETERMINISTIC SQL SECURITY DEFINER BEGIN DELETE FROM flips WHERE id = flip_id; RETURN ROW_COUNT(); @@ -1048,9 +1048,9 @@ The C scripts are: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Function "insert_flip" does not exist') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'insert_flip'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'insert_flip'; ROLLBACK; @@ -1061,9 +1061,9 @@ And: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Function "delete_flip" does not exist') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'delete_flip'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'delete_flip'; ROLLBACK; @@ -1398,7 +1398,7 @@ a great idea. So we need to modify the C and C functions to fix that. How? We can use MySQL's -L|https://dev.mysql.com/doc/refman/5.5/en/encryption-functions.html#function_encrypt> +L|https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_encrypt> function to encrypt passwords with a salt, so that they're all unique. But how to deploy the changes to C and C? @@ -1559,7 +1559,7 @@ And make this change to F: nickname VARCHAR(512), oldpass VARCHAR(512), @@ -13,9 +14,9 @@ CREATE FUNCTION change_pass( - ) RETURNS INTEGER SQL SECURITY DEFINER + ) RETURNS INTEGER DETERMINISTIC SQL SECURITY DEFINER BEGIN UPDATE users - SET password = md5(newpass) @@ -1633,7 +1633,7 @@ in the new script files that include tags. But what about the verify script? How can we verify that the functions have been modified to use C? I think the simplest thing to do is to examine the body of the function as returned by -L|https://dev.mysql.com/doc/refman/5.6/en/routines-table.html> +L|https://dev.mysql.com/doc/refman/5.7/en/information-schema-routines-table.html> So the C verify script looks like this: -- Verify flipr:insert_user on mysql @@ -1641,10 +1641,10 @@ So the C verify script looks like this: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Procedure "insert_user" does not exist or is not up-to-date') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'insert_user' - AND body_utf8 LIKE '%ENCRYPT(md5(password), md5(FLOOR(RAND() * 0xFFFFFFFF))%'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'insert_user' + AND routine_definition LIKE '%ENCRYPT(md5(password), md5(FLOOR(RAND() * 0xFFFFFFFF))%'; ROLLBACK; @@ -1655,10 +1655,10 @@ And the C verify script looks like this: BEGIN; SELECT sqitch.checkit(COUNT(*), 'Procedure "change_pass" does not exist or is not up-to-date') - FROM mysql.proc - WHERE db = database() - AND specific_name = 'change_pass' - AND body_utf8 LIKE '%ENCRYPT(md5(oldpass), password)%'; + FROM information_schema.routines + WHERE routine_schema = database() + AND routine_name = 'change_pass' + AND routine_definition LIKE '%ENCRYPT(md5(oldpass), password)%'; ROLLBACK; @@ -1703,7 +1703,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-oracle.pod b/lib/sqitchtutorial-oracle.pod index 386f856a..01bbc080 100644 --- a/lib/sqitchtutorial-oracle.pod +++ b/lib/sqitchtutorial-oracle.pod @@ -1963,7 +1963,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-snowflake.pod b/lib/sqitchtutorial-snowflake.pod index a28c1f61..4347c4b9 100644 --- a/lib/sqitchtutorial-snowflake.pod +++ b/lib/sqitchtutorial-snowflake.pod @@ -1399,7 +1399,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-sqlite.pod b/lib/sqitchtutorial-sqlite.pod index 7c878470..e59fa713 100644 --- a/lib/sqitchtutorial-sqlite.pod +++ b/lib/sqitchtutorial-sqlite.pod @@ -1220,7 +1220,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial-vertica.pod b/lib/sqitchtutorial-vertica.pod index a0aca99c..fb995ca4 100644 --- a/lib/sqitchtutorial-vertica.pod +++ b/lib/sqitchtutorial-vertica.pod @@ -1370,7 +1370,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/sqitchtutorial.pod b/lib/sqitchtutorial.pod index c1fc236a..d7ed13ac 100644 --- a/lib/sqitchtutorial.pod +++ b/lib/sqitchtutorial.pod @@ -1677,7 +1677,7 @@ David E. Wheeler =head1 License -Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +Copyright (c) 2012-2023 iovation Inc., David E. Wheeler Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/po/App-Sqitch.pot b/po/App-Sqitch.pot index 608c5dd6..d998166b 100644 --- a/po/App-Sqitch.pot +++ b/po/App-Sqitch.pot @@ -1,14 +1,14 @@ # Sqitch Localization Messages -# Copyright (c) 2012-2022 "iovation Inc., David E. Wheeler" +# Copyright (c) 2012-2023 "iovation Inc., David E. Wheeler" # This file is distributed under the same license as the App-Sqitch package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: App-Sqitch v1.3.1\n" +"Project-Id-Version: App-Sqitch v1.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 14:23-0400\n" +"POT-Creation-Date: 2023-07-30 20:02-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -33,7 +33,7 @@ msgstr "" msgid "Cannot change to directory {directory}: {error}" msgstr "" -#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:113 +#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:114 #, perl-brace-format msgid "\"{command}\" is not a valid command" msgstr "" @@ -71,23 +71,23 @@ msgstr "" msgid "Error closing pipe to {command}: {error}" msgstr "" -#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:763 +#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:771 #, perl-brace-format msgid "{command} unexpectedly returned exit value {exitval}" msgstr "" -#: lib/App/Sqitch/Command.pm:283 +#: lib/App/Sqitch/Command.pm:284 #, perl-brace-format msgid "Unknown argument \"{arg}\"" msgid_plural "Unknown arguments: {arg}" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Command.pm:295 +#: lib/App/Sqitch/Command.pm:296 msgid "Cannot specify both --all and engine, target, or plan arugments" msgstr "" -#: lib/App/Sqitch/Command.pm:315 lib/App/Sqitch/Command/add.pm:410 +#: lib/App/Sqitch/Command.pm:316 lib/App/Sqitch/Command/add.pm:421 #: lib/App/Sqitch/Command/init.pm:203 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:250 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:337 @@ -95,7 +95,7 @@ msgstr "" msgid "Created {file}" msgstr "" -#: lib/App/Sqitch/Command.pm:322 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 +#: lib/App/Sqitch/Command.pm:323 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 #, perl-brace-format msgid "Error creating {path}: {error}" msgstr "" @@ -146,7 +146,7 @@ msgstr "" msgid "Skipped {file}: already exists" msgstr "" -#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:416 +#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:427 #: lib/App/Sqitch/Plan.pm:136 lib/App/Sqitch/Plan.pm:602 #: lib/App/Sqitch/Plan.pm:982 lib/App/Sqitch/Plan/Line.pm:107 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:321 @@ -165,6 +165,11 @@ msgstr "" msgid "Error closing {file}: {error}" msgstr "" +#: lib/App/Sqitch/Command/add.pm:415 +#, perl-brace-format +msgid "File {file} has a double extension of {ext}" +msgstr "" + #: lib/App/Sqitch/Command/bundle.pm:99 msgid "" "Use of --to or --from to bundle multiple targets is not recommended.\n" @@ -220,7 +225,7 @@ msgstr "" #: lib/App/Sqitch/Command/check.pm:89 lib/App/Sqitch/Command/deploy.pm:118 #: lib/App/Sqitch/Command/log.pm:212 lib/App/Sqitch/Command/rebase.pm:63 -#: lib/App/Sqitch/Command/revert.pm:128 lib/App/Sqitch/Command/status.pm:110 +#: lib/App/Sqitch/Command/revert.pm:137 lib/App/Sqitch/Command/status.pm:110 #: lib/App/Sqitch/Command/verify.pm:89 #, perl-brace-format msgid "Too many targets specified; connecting to {target}" @@ -231,17 +236,17 @@ msgstr "" msgid "Too many changes specified; checking from \"{from}\" to \"{to}\"" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:67 +#: lib/App/Sqitch/Command/checkout.pm:65 #, perl-brace-format msgid "Already on branch {branch}" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:103 +#: lib/App/Sqitch/Command/checkout.pm:101 #, perl-brace-format msgid "Branch {branch} has no changes in common with current branch {current}" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:109 +#: lib/App/Sqitch/Command/checkout.pm:107 #, perl-brace-format msgid "Last change before the branches diverged: {last_change}" msgstr "" @@ -333,12 +338,12 @@ msgid "Extension" msgstr "" #: lib/App/Sqitch/Command/engine.pm:185 lib/App/Sqitch/Command/target.pm:177 -#: lib/App/Sqitch/ItemFormatter.pm:62 +#: lib/App/Sqitch/ItemFormatter.pm:61 msgid "Revert" msgstr "" #: lib/App/Sqitch/Command/engine.pm:186 lib/App/Sqitch/Command/target.pm:178 -#: lib/App/Sqitch/ItemFormatter.pm:61 +#: lib/App/Sqitch/ItemFormatter.pm:60 msgid "Deploy" msgstr "" @@ -429,7 +434,15 @@ msgstr "" msgid "Too many changes specified; rebasing onto \"{onto}\" up to \"{upto}\"" msgstr "" -#: lib/App/Sqitch/Command/revert.pm:138 +#: lib/App/Sqitch/Command/revert.pm:150 +msgid "Must specify a target revision in strict mode" +msgstr "" + +#: lib/App/Sqitch/Command/revert.pm:158 +msgid "Too many changes specified" +msgstr "" + +#: lib/App/Sqitch/Command/revert.pm:163 #, perl-brace-format msgid "Too many changes specified; reverting to \"{change}\"" msgstr "" @@ -454,12 +467,12 @@ msgstr[1] "" msgid "Skipped {dest}: {src} does not exist" msgstr "" -#: lib/App/Sqitch/Command/rework.pm:208 +#: lib/App/Sqitch/Command/rework.pm:211 #, perl-brace-format msgid "Cannot copy {src} to {dest}: {error}" msgstr "" -#: lib/App/Sqitch/Command/rework.pm:215 +#: lib/App/Sqitch/Command/rework.pm:218 #, perl-brace-format msgid "Copied {src} to {dest}" msgstr "" @@ -507,8 +520,8 @@ msgstr "" msgid ", " msgstr "" -#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:384 -#: lib/App/Sqitch/Engine.pm:1216 +#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:453 +#: lib/App/Sqitch/Engine.pm:1288 msgid "No changes deployed" msgstr "" @@ -574,11 +587,11 @@ msgstr "" msgid "Make sure you are connected to the proper database for this project." msgstr "" -#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:217 +#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:237 msgid "Nothing to deploy (up-to-date)" msgstr "" -#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:539 +#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:608 msgid "Undeployed change:" msgid_plural "Undeployed changes:" msgstr[0] "" @@ -643,197 +656,213 @@ msgstr "" msgid "Unknown date format \"{format}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:148 lib/App/Sqitch/Engine.pm:160 +#: lib/App/Sqitch/Engine.pm:168 lib/App/Sqitch/Engine.pm:180 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:162 lib/App/Sqitch/Target.pm:251 msgid "No engine specified; specify via target or core.engine" msgstr "" -#: lib/App/Sqitch/Engine.pm:182 +#: lib/App/Sqitch/Engine.pm:202 #, perl-brace-format msgid "{driver} required to manage {engine}" msgstr "" -#: lib/App/Sqitch/Engine.pm:197 +#: lib/App/Sqitch/Engine.pm:217 msgid "Nothing to deploy (empty plan)" msgstr "" -#: lib/App/Sqitch/Engine.pm:201 lib/App/Sqitch/Engine.pm:297 +#: lib/App/Sqitch/Engine.pm:221 lib/App/Sqitch/Engine.pm:348 #: lib/App/Sqitch/Plan.pm:749 lib/App/Sqitch/Plan/ChangeList.pm:121 #, perl-brace-format msgid "Unknown change: \"{change}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:208 +#: lib/App/Sqitch/Engine.pm:228 #, perl-brace-format msgid "Nothing to deploy (already at \"{change}\")" msgstr "" -#: lib/App/Sqitch/Engine.pm:226 +#: lib/App/Sqitch/Engine.pm:246 #, perl-brace-format msgid "Adding registry tables to {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:235 +#: lib/App/Sqitch/Engine.pm:255 msgid "Cannot deploy to an earlier change; use \"revert\" instead" msgstr "" -#: lib/App/Sqitch/Engine.pm:243 +#: lib/App/Sqitch/Engine.pm:263 #, perl-brace-format msgid "Deploying changes through {change} to {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:247 +#: lib/App/Sqitch/Engine.pm:267 #, perl-brace-format msgid "Deploying changes to {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:260 +#: lib/App/Sqitch/Engine.pm:272 +msgid "Will deploy the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:285 #, perl-brace-format msgid "Unknown deployment mode: \"{mode}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:291 +#: lib/App/Sqitch/Engine.pm:313 +msgid "Missing required parameter $prompt_default" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:342 #, perl-brace-format msgid "Change not deployed: \"{change}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:306 +#: lib/App/Sqitch/Engine.pm:359 #, perl-brace-format msgid "No changes deployed since: \"{change}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:314 +#: lib/App/Sqitch/Engine.pm:369 #, perl-brace-format msgid "Reverting changes to {change} from {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:321 lib/App/Sqitch/Engine.pm:344 +#: lib/App/Sqitch/Engine.pm:373 lib/App/Sqitch/Engine.pm:403 +msgid "Will revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:376 lib/App/Sqitch/Engine.pm:406 +msgid "Would revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:380 lib/App/Sqitch/Engine.pm:410 msgid "Nothing reverted" msgstr "" -#: lib/App/Sqitch/Engine.pm:324 +#: lib/App/Sqitch/Engine.pm:383 #, perl-brace-format msgid "Revert changes to {change} from {destination}?" msgstr "" -#: lib/App/Sqitch/Engine.pm:332 +#: lib/App/Sqitch/Engine.pm:392 msgid "Nothing to revert (nothing deployed)" msgstr "" -#: lib/App/Sqitch/Engine.pm:338 +#: lib/App/Sqitch/Engine.pm:400 #, perl-brace-format msgid "Reverting all changes from {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:347 +#: lib/App/Sqitch/Engine.pm:413 #, perl-brace-format msgid "Revert all changes from {destination}?" msgstr "" -#: lib/App/Sqitch/Engine.pm:378 +#: lib/App/Sqitch/Engine.pm:447 #, perl-brace-format msgid "Verifying {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:385 +#: lib/App/Sqitch/Engine.pm:454 msgid "Nothing to verify (no planned or deployed changes)" msgstr "" -#: lib/App/Sqitch/Engine.pm:392 +#: lib/App/Sqitch/Engine.pm:461 msgid "There are deployed changes, but none planned!" msgstr "" -#: lib/App/Sqitch/Engine.pm:405 +#: lib/App/Sqitch/Engine.pm:474 msgid "Verify Summary Report" msgstr "" -#: lib/App/Sqitch/Engine.pm:408 +#: lib/App/Sqitch/Engine.pm:477 #, perl-brace-format msgid "Changes: {number}" msgstr "" -#: lib/App/Sqitch/Engine.pm:409 +#: lib/App/Sqitch/Engine.pm:478 #, perl-brace-format msgid "Errors: {number}" msgstr "" -#: lib/App/Sqitch/Engine.pm:410 +#: lib/App/Sqitch/Engine.pm:479 msgid "Verify failed" msgstr "" -#: lib/App/Sqitch/Engine.pm:415 +#: lib/App/Sqitch/Engine.pm:484 msgid "Verify successful" msgstr "" -#: lib/App/Sqitch/Engine.pm:444 +#: lib/App/Sqitch/Engine.pm:513 #, perl-brace-format msgid "Change \"{change}\" has not been deployed" msgstr "" -#: lib/App/Sqitch/Engine.pm:447 +#: lib/App/Sqitch/Engine.pm:516 #, perl-brace-format msgid "Cannot find \"{change}\" in the database or the plan" msgstr "" -#: lib/App/Sqitch/Engine.pm:454 +#: lib/App/Sqitch/Engine.pm:523 #, perl-brace-format msgid "Change \"{change}\" is deployed, but not planned" msgstr "" -#: lib/App/Sqitch/Engine.pm:498 +#: lib/App/Sqitch/Engine.pm:567 msgid "Out of order" msgstr "" -#: lib/App/Sqitch/Engine.pm:504 +#: lib/App/Sqitch/Engine.pm:573 msgid "Not present in the plan" msgstr "" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:527 -#: lib/App/Sqitch/Engine.pm:996 lib/App/Sqitch/Engine.pm:1026 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:596 +#: lib/App/Sqitch/Engine.pm:1068 lib/App/Sqitch/Engine.pm:1098 msgid "not ok" msgstr "" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:974 -#: lib/App/Sqitch/Engine.pm:1016 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:1046 +#: lib/App/Sqitch/Engine.pm:1088 msgid "ok" msgstr "" -#: lib/App/Sqitch/Engine.pm:529 +#: lib/App/Sqitch/Engine.pm:598 msgid "Not deployed" msgstr "" -#: lib/App/Sqitch/Engine.pm:561 +#: lib/App/Sqitch/Engine.pm:630 #, perl-brace-format msgid "Verify script \"{script}\" failed." msgstr "" -#: lib/App/Sqitch/Engine.pm:570 +#: lib/App/Sqitch/Engine.pm:639 #, perl-brace-format msgid "Verify script {file} does not exist" msgstr "" -#: lib/App/Sqitch/Engine.pm:612 +#: lib/App/Sqitch/Engine.pm:681 #, perl-brace-format msgid "Conflicts with previously deployed change: {changes}" msgid_plural "Conflicts with previously deployed changes: {changes}" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:619 +#: lib/App/Sqitch/Engine.pm:688 #, perl-brace-format msgid "Missing required change: {changes}" msgid_plural "Missing required changes: {changes}" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:631 +#: lib/App/Sqitch/Engine.pm:700 #, perl-brace-format msgid "Change \"{changes}\" has already been deployed" msgid_plural "Changes have already been deployed: {changes}" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:654 +#: lib/App/Sqitch/Engine.pm:723 #, perl-brace-format msgid "Change \"{change}\" required by currently deployed change: {changes}" msgid_plural "" @@ -841,148 +870,148 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:677 +#: lib/App/Sqitch/Engine.pm:746 #, perl-brace-format msgid "Invalid dependency: {dependency}" msgstr "" -#: lib/App/Sqitch/Engine.pm:813 lib/App/Sqitch/Plan/ChangeList.pm:88 +#: lib/App/Sqitch/Engine.pm:882 lib/App/Sqitch/Plan/ChangeList.pm:88 #, perl-brace-format msgid "" "Change \"{change}\" is ambiguous. Please specify a tag-qualified change:" msgstr "" -#: lib/App/Sqitch/Engine.pm:828 +#: lib/App/Sqitch/Engine.pm:897 msgid "Change Lookup Failed" msgstr "" -#: lib/App/Sqitch/Engine.pm:849 +#: lib/App/Sqitch/Engine.pm:918 #, perl-brace-format msgid "Reverting to {change}" msgstr "" -#: lib/App/Sqitch/Engine.pm:850 +#: lib/App/Sqitch/Engine.pm:919 msgid "Reverting all changes" msgstr "" -#: lib/App/Sqitch/Engine.pm:858 +#: lib/App/Sqitch/Engine.pm:927 msgid "The schema will need to be manually repaired" msgstr "" -#: lib/App/Sqitch/Engine.pm:862 lib/App/Sqitch/Engine.pm:990 +#: lib/App/Sqitch/Engine.pm:931 lib/App/Sqitch/Engine.pm:1062 msgid "Deploy failed" msgstr "" -#: lib/App/Sqitch/Engine.pm:919 +#: lib/App/Sqitch/Engine.pm:991 #, perl-brace-format msgid "Cannot find change {id} ({change}) in {file}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1041 +#: lib/App/Sqitch/Engine.pm:1113 #, perl-brace-format msgid "" "Blocked by another instance of Sqitch working on {dest}; waiting {secs} " "seconds..." msgstr "" -#: lib/App/Sqitch/Engine.pm:1051 +#: lib/App/Sqitch/Engine.pm:1123 #, perl-brace-format msgid "" "Timed out waiting {secs} seconds for another instance of Sqitch to finish " "work on {dest}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1110 +#: lib/App/Sqitch/Engine.pm:1182 #, perl-brace-format msgid "No registry found in {destination}. Have you ever deployed?" msgstr "" -#: lib/App/Sqitch/Engine.pm:1115 +#: lib/App/Sqitch/Engine.pm:1187 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " "Sqitch" msgstr "" -#: lib/App/Sqitch/Engine.pm:1121 +#: lib/App/Sqitch/Engine.pm:1193 #, perl-brace-format msgid "" "Registry is at version {old} but latest is {new}. Please run the \"upgrade\" " "command" msgstr "" -#: lib/App/Sqitch/Engine.pm:1136 +#: lib/App/Sqitch/Engine.pm:1208 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " "Sqitch." msgstr "" -#: lib/App/Sqitch/Engine.pm:1151 +#: lib/App/Sqitch/Engine.pm:1223 #, perl-brace-format msgid "Cannot upgrade to {version}: Cannot find upgrade script \"{file}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:1158 +#: lib/App/Sqitch/Engine.pm:1230 #, perl-brace-format msgid "Upgrading the Sqitch registry from {old} to {new}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1165 +#: lib/App/Sqitch/Engine.pm:1237 #, perl-brace-format msgid "From {old} to {new}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1210 +#: lib/App/Sqitch/Engine.pm:1282 #, perl-brace-format msgid "Checking {destination}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1217 +#: lib/App/Sqitch/Engine.pm:1289 msgid "Nothing to check (no planned or deployed changes)" msgstr "" -#: lib/App/Sqitch/Engine.pm:1230 +#: lib/App/Sqitch/Engine.pm:1302 #, perl-brace-format msgid "Script signatures diverge at change {change}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1238 +#: lib/App/Sqitch/Engine.pm:1310 #, perl-brace-format msgid "Failed one check" msgid_plural "Failed {count} checks" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:1246 +#: lib/App/Sqitch/Engine.pm:1318 msgid "Check successful" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:326 lib/App/Sqitch/Engine/oracle.pm:458 +#: lib/App/Sqitch/Engine/exasol.pm:323 lib/App/Sqitch/Engine/oracle.pm:462 msgid "Sqitch already initialized" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:394 lib/App/Sqitch/Engine/oracle.pm:588 +#: lib/App/Sqitch/Engine/exasol.pm:391 lib/App/Sqitch/Engine/oracle.pm:592 #, perl-brace-format msgid "Cannot remove {file}: {error}" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:403 lib/App/Sqitch/Engine/oracle.pm:597 +#: lib/App/Sqitch/Engine/exasol.pm:400 lib/App/Sqitch/Engine/oracle.pm:601 #, perl-brace-format msgid "Cannot copy {file} to {alias}: {error}" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:412 lib/App/Sqitch/Engine/oracle.pm:606 +#: lib/App/Sqitch/Engine/exasol.pm:409 lib/App/Sqitch/Engine/oracle.pm:610 #, perl-brace-format msgid "Cannot symlink {file} to {alias}: {error}" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:520 +#: lib/App/Sqitch/Engine/exasol.pm:522 #, perl-brace-format msgid "{command} unexpectedly failed; exit value = {exitval}" msgstr "" -#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:283 +#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:274 #: lib/App/Sqitch/Engine/sqlite.pm:158 #, perl-brace-format msgid "Sqitch database {database} already initialized" @@ -998,45 +1027,50 @@ msgstr "" msgid "Database name missing in URI {uri}" msgstr "" -#: lib/App/Sqitch/Engine/firebird.pm:891 lib/App/Sqitch/Engine/firebird.pm:909 -#: lib/App/Sqitch/Engine/firebird.pm:920 +#: lib/App/Sqitch/Engine/firebird.pm:839 lib/App/Sqitch/Role/DBIEngine.pm:527 +#, perl-brace-format +msgid "Cannot log change \"{change}\": The deploy script is not unique" +msgstr "" + +#: lib/App/Sqitch/Engine/firebird.pm:903 lib/App/Sqitch/Engine/firebird.pm:921 +#: lib/App/Sqitch/Engine/firebird.pm:932 #, perl-brace-format msgid "Cannot dup STDERR: {error}" msgstr "" -#: lib/App/Sqitch/Engine/firebird.pm:895 +#: lib/App/Sqitch/Engine/firebird.pm:907 #, perl-brace-format msgid "Cannot reirect STDERR: {error}" msgstr "" -#: lib/App/Sqitch/Engine/firebird.pm:923 +#: lib/App/Sqitch/Engine/firebird.pm:935 msgid "" "Unable to locate Firebird ISQL; set \"engine.firebird.client\" via sqitch " "config" msgstr "" -#: lib/App/Sqitch/Engine/mysql.pm:126 +#: lib/App/Sqitch/Engine/mysql.pm:117 #, perl-brace-format msgid "" "Sqitch requires {rdbms} {want_version} or higher; this is {have_version}" msgstr "" -#: lib/App/Sqitch/Engine/mysql.pm:158 +#: lib/App/Sqitch/Engine/mysql.pm:149 #, perl-brace-format msgid "Database name missing in URI \"{uri}\"" msgstr "" -#: lib/App/Sqitch/Engine/pg.pm:214 lib/App/Sqitch/Engine/snowflake.pm:302 -#: lib/App/Sqitch/Engine/vertica.pm:144 +#: lib/App/Sqitch/Engine/pg.pm:213 lib/App/Sqitch/Engine/snowflake.pm:310 +#: lib/App/Sqitch/Engine/vertica.pm:139 #, perl-brace-format msgid "Sqitch schema \"{schema}\" already exists" msgstr "" -#: lib/App/Sqitch/Engine/pg.pm:454 +#: lib/App/Sqitch/Engine/pg.pm:453 msgid "Sqitch registry not initialized" msgstr "" -#: lib/App/Sqitch/Engine/pg.pm:455 +#: lib/App/Sqitch/Engine/pg.pm:454 msgid "" "Because the \"changes\" table does not exist, Sqitch will now initialize the " "database to create its registry tables." @@ -1049,7 +1083,7 @@ msgstr "" #: lib/App/Sqitch/Engine/sqlite.pm:98 #, perl-brace-format msgid "" -"Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}" +"Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}" msgstr "" #: lib/App/Sqitch/Engine/sqlite.pm:121 @@ -1057,94 +1091,94 @@ msgstr "" msgid "Sqitch requires SQLite 3.3.9 or later; {client} is {version}" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:63 +#: lib/App/Sqitch/ItemFormatter.pm:62 msgid "Fail" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:68 +#: lib/App/Sqitch/ItemFormatter.pm:67 msgid "deploy" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:69 +#: lib/App/Sqitch/ItemFormatter.pm:68 msgid "revert" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:70 +#: lib/App/Sqitch/ItemFormatter.pm:69 msgid "fail" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:75 -msgid "Event: " +#: lib/App/Sqitch/ItemFormatter.pm:74 +msgid "No label passed to the _ format" msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:76 -msgid "Change: " +msgid "Event: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:77 -msgid "Committer:" +msgid "Change: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:78 -msgid "Planner: " +msgid "Committer:" msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:79 -msgid "By: " +msgid "Planner: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:80 -msgid "Date: " +msgid "By: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:81 -msgid "Committed:" +msgid "Date: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:82 -msgid "Planned: " +msgid "Committed:" msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:83 -msgid "Name: " +msgid "Planned: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:84 -msgid "Project: " +msgid "Name: " msgstr "" #: lib/App/Sqitch/ItemFormatter.pm:85 +msgid "Project: " +msgstr "" + +#: lib/App/Sqitch/ItemFormatter.pm:86 msgid "Email: " msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:86 lib/App/Sqitch/ItemFormatter.pm:176 +#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:172 msgid "Requires: " msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:187 +#: lib/App/Sqitch/ItemFormatter.pm:88 lib/App/Sqitch/ItemFormatter.pm:183 msgid "Conflicts:" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:89 -msgid "No label passed to the _ format" -msgstr "" - -#: lib/App/Sqitch/ItemFormatter.pm:93 +#: lib/App/Sqitch/ItemFormatter.pm:90 #, perl-brace-format msgid "Unknown label \"{label}\" passed to the _ format" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:150 +#: lib/App/Sqitch/ItemFormatter.pm:146 #, perl-brace-format msgid "{color} is not a valid ANSI color" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:193 +#: lib/App/Sqitch/ItemFormatter.pm:189 #, perl-brace-format msgid "{attr} is not a valid change attribute" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:216 +#: lib/App/Sqitch/ItemFormatter.pm:212 #, perl-brace-format msgid "Unknown format code \"{code}\"" msgstr "" @@ -1328,8 +1362,8 @@ msgstr "" #: lib/App/Sqitch/Plan.pm:918 #, perl-brace-format msgid "" -"\"{name}\" is invalid: changes must not begin with punctuation, contain \"@" -"\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " +"\"{name}\" is invalid: changes must not begin with punctuation, contain " +"\"@\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " "following punctuation" msgstr "" @@ -1386,32 +1420,39 @@ msgid "" " Use --chdir instead." msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:353 +#: lib/App/Sqitch/Role/DBIEngine.pm:365 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with NULL URI" msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:359 +#: lib/App/Sqitch/Role/DBIEngine.pm:371 #, perl-brace-format msgid "" "Cannot register \"{project}\" without URI: already exists with URI {uri}" msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:365 +#: lib/App/Sqitch/Role/DBIEngine.pm:377 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with URI " "{reg_uri}" msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:383 +#: lib/App/Sqitch/Role/DBIEngine.pm:395 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: project \"{reg_proj}\" already " "using that URI" msgstr "" +#: lib/App/Sqitch/Role/RevertDeployCommand.pm:129 +#, perl-brace-format +msgid "" +"\"{command}\" cannot be used in strict mode.\\nUse explicity revert and " +"deploy commands instead." +msgstr "" + #: lib/App/Sqitch/Role/TargetConfigCommand.pm:96 #, perl-brace-format msgid "Unknown directory name: {dirs}" diff --git a/po/de_DE.po b/po/de_DE.po index 2e13a06c..6eceb8bc 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -1,5 +1,5 @@ # Sqitch German Localization Messages -# Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +# Copyright (c) 2012-2023 iovation Inc., David E. Wheeler # This file is distributed under the same license as the App-Sqitch package. # Thomas Iguchi , 2019. # @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Sqitch 0.932\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 14:23-0400\n" +"POT-Creation-Date: 2023-07-30 20:02-0400\n" "PO-Revision-Date: 2012-08-31 17:15-0700\n" "Last-Translator: Thomas Iguchi \n" "Language-Team: German \n" @@ -38,7 +38,7 @@ msgstr "" msgid "Cannot change to directory {directory}: {error}" msgstr "Konnte nicht in das folgende Verzeichnis wechseln {directory}: {error}" -#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:113 +#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:114 #, perl-brace-format msgid "\"{command}\" is not a valid command" msgstr "\"{command}\" ist ein ungΓΌltiger Befehl" @@ -78,24 +78,24 @@ msgstr "Konnte den Befehl {command} nicht ausfΓΌhren: {error}" msgid "Error closing pipe to {command}: {error}" msgstr "Fehler beim Schließen der Pipeline nach {command}: {error}" -#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:763 +#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:771 #, perl-brace-format msgid "{command} unexpectedly returned exit value {exitval}" msgstr "{command} brach unerwartet ab mit RΓΌckgabewert {exitval}" -#: lib/App/Sqitch/Command.pm:283 +#: lib/App/Sqitch/Command.pm:284 #, perl-brace-format msgid "Unknown argument \"{arg}\"" msgid_plural "Unknown arguments: {arg}" msgstr[0] "Unbekanntes Argument \"{arg}\"" msgstr[1] "Unbekannte Argumente: \"{arg}\"" -#: lib/App/Sqitch/Command.pm:295 +#: lib/App/Sqitch/Command.pm:296 msgid "Cannot specify both --all and engine, target, or plan arugments" msgstr "" "Das Argument --all kann nicht mit engine, target oder plan kombiniert werden" -#: lib/App/Sqitch/Command.pm:315 lib/App/Sqitch/Command/add.pm:410 +#: lib/App/Sqitch/Command.pm:316 lib/App/Sqitch/Command/add.pm:421 #: lib/App/Sqitch/Command/init.pm:203 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:250 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:337 @@ -103,7 +103,7 @@ msgstr "" msgid "Created {file}" msgstr "{file} erstellt" -#: lib/App/Sqitch/Command.pm:322 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 +#: lib/App/Sqitch/Command.pm:323 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 #, perl-brace-format msgid "Error creating {path}: {error}" msgstr "Fehler beim Erstellen von {path}: {error}" @@ -156,7 +156,7 @@ msgstr "\"{change}\" der Datei {file} hinzugefΓΌgt" msgid "Skipped {file}: already exists" msgstr "Überspringe {file}: existiert bereits" -#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:416 +#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:427 #: lib/App/Sqitch/Plan.pm:136 lib/App/Sqitch/Plan.pm:602 #: lib/App/Sqitch/Plan.pm:982 lib/App/Sqitch/Plan/Line.pm:107 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:321 @@ -175,6 +175,11 @@ msgstr "Fehler beim AusfΓΌhren von {template}: {error}" msgid "Error closing {file}: {error}" msgstr "Fehler beim Schließen von {file}: {error}" +#: lib/App/Sqitch/Command/add.pm:415 +#, perl-brace-format +msgid "File {file} has a double extension of {ext}" +msgstr "" + #: lib/App/Sqitch/Command/bundle.pm:99 msgid "" "Use of --to or --from to bundle multiple targets is not recommended.\n" @@ -235,7 +240,7 @@ msgstr "Schreibe Skripte" #: lib/App/Sqitch/Command/check.pm:89 lib/App/Sqitch/Command/deploy.pm:118 #: lib/App/Sqitch/Command/log.pm:212 lib/App/Sqitch/Command/rebase.pm:63 -#: lib/App/Sqitch/Command/revert.pm:128 lib/App/Sqitch/Command/status.pm:110 +#: lib/App/Sqitch/Command/revert.pm:137 lib/App/Sqitch/Command/status.pm:110 #: lib/App/Sqitch/Command/verify.pm:89 #, perl-brace-format msgid "Too many targets specified; connecting to {target}" @@ -247,19 +252,19 @@ msgid "Too many changes specified; checking from \"{from}\" to \"{to}\"" msgstr "" "Zu viele Γ„nderungen angegeben. Verifiziere von \"{from}\" nach \"{to}\"" -#: lib/App/Sqitch/Command/checkout.pm:67 +#: lib/App/Sqitch/Command/checkout.pm:65 #, perl-brace-format msgid "Already on branch {branch}" msgstr "Bereits im Entwicklungszweig {branch}" -#: lib/App/Sqitch/Command/checkout.pm:103 +#: lib/App/Sqitch/Command/checkout.pm:101 #, perl-brace-format msgid "Branch {branch} has no changes in common with current branch {current}" msgstr "" "Entwicklungszweig {branch} hat keine VerΓ€nderungen mit dem aktuellen " "Entwicklungszweig {current} gemein" -#: lib/App/Sqitch/Command/checkout.pm:109 +#: lib/App/Sqitch/Command/checkout.pm:107 #, perl-brace-format msgid "Last change before the branches diverged: {last_change}" msgstr "" @@ -355,12 +360,12 @@ msgid "Extension" msgstr "Erweiterung" #: lib/App/Sqitch/Command/engine.pm:185 lib/App/Sqitch/Command/target.pm:177 -#: lib/App/Sqitch/ItemFormatter.pm:62 +#: lib/App/Sqitch/ItemFormatter.pm:61 msgid "Revert" msgstr "RΓΌckgΓ€ngig machen" #: lib/App/Sqitch/Command/engine.pm:186 lib/App/Sqitch/Command/target.pm:178 -#: lib/App/Sqitch/ItemFormatter.pm:61 +#: lib/App/Sqitch/ItemFormatter.pm:60 msgid "Deploy" msgstr "Anwenden" @@ -456,7 +461,16 @@ msgid "Too many changes specified; rebasing onto \"{onto}\" up to \"{upto}\"" msgstr "" "Zu viele Γ„nderungen angegeben. Rebase auf \"{onto}\" bis hin \"{upto}\"" -#: lib/App/Sqitch/Command/revert.pm:138 +#: lib/App/Sqitch/Command/revert.pm:150 +msgid "Must specify a target revision in strict mode" +msgstr "" + +#: lib/App/Sqitch/Command/revert.pm:158 +#, fuzzy +msgid "Too many changes specified" +msgstr "Zu viele Ziele angegeben. Verwende {target}" + +#: lib/App/Sqitch/Command/revert.pm:163 #, perl-brace-format msgid "Too many changes specified; reverting to \"{change}\"" msgstr "Zu viele Γ„nderungen angegeben. Setze zurΓΌck nach \"{change}\"" @@ -481,12 +495,12 @@ msgstr[1] "Nimm die nΓΆtigen Γ„nderungen an diesen Dateien vor:" msgid "Skipped {dest}: {src} does not exist" msgstr "{dest} ΓΌbersprungen: {src} existiert nicht" -#: lib/App/Sqitch/Command/rework.pm:208 +#: lib/App/Sqitch/Command/rework.pm:211 #, perl-brace-format msgid "Cannot copy {src} to {dest}: {error}" msgstr "Kann {src} nicht nach {dest} kopieren: {error}" -#: lib/App/Sqitch/Command/rework.pm:215 +#: lib/App/Sqitch/Command/rework.pm:218 #, perl-brace-format msgid "Copied {src} to {dest}" msgstr "{src} nach {dest} kopiert" @@ -534,8 +548,8 @@ msgstr "Verwende --project um ein bestimmtes Projekt anzugeben: {projects}" msgid ", " msgstr ", " -#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:384 -#: lib/App/Sqitch/Engine.pm:1216 +#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:453 +#: lib/App/Sqitch/Engine.pm:1288 msgid "No changes deployed" msgstr "Keine Γ„nderungen angewendet" @@ -605,11 +619,11 @@ msgstr "" "Bitte stelle sicher dass du mit der korrekten Datenbank fΓΌr dieses Projekt " "verbunden bist." -#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:217 +#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:237 msgid "Nothing to deploy (up-to-date)" msgstr "Nichts anzuwenden (auf neuestem Stand)" -#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:539 +#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:608 msgid "Undeployed change:" msgid_plural "Undeployed changes:" msgstr[0] "RΓΌckgΓ€ngig gemachte Γ„nderung:" @@ -681,200 +695,216 @@ msgstr "Konnte Benutzerverzeichnis nicht finden" msgid "Unknown date format \"{format}\"" msgstr "Unbekanntes Datumsformat \"{format}\"" -#: lib/App/Sqitch/Engine.pm:148 lib/App/Sqitch/Engine.pm:160 +#: lib/App/Sqitch/Engine.pm:168 lib/App/Sqitch/Engine.pm:180 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:162 lib/App/Sqitch/Target.pm:251 msgid "No engine specified; specify via target or core.engine" msgstr "" "Keine Engine angegeben. Bitte gib eine via \"target\" oder \"core.engine\" an" -#: lib/App/Sqitch/Engine.pm:182 +#: lib/App/Sqitch/Engine.pm:202 #, perl-brace-format msgid "{driver} required to manage {engine}" msgstr "{driver} benΓΆtigt, um {engine} zu benutzen" -#: lib/App/Sqitch/Engine.pm:197 +#: lib/App/Sqitch/Engine.pm:217 msgid "Nothing to deploy (empty plan)" msgstr "Nichts anzuwenden (leerer Plan)" -#: lib/App/Sqitch/Engine.pm:201 lib/App/Sqitch/Engine.pm:297 +#: lib/App/Sqitch/Engine.pm:221 lib/App/Sqitch/Engine.pm:348 #: lib/App/Sqitch/Plan.pm:749 lib/App/Sqitch/Plan/ChangeList.pm:121 #, perl-brace-format msgid "Unknown change: \"{change}\"" msgstr "Unbekannte Γ„nderung: \"{change}\"" -#: lib/App/Sqitch/Engine.pm:208 +#: lib/App/Sqitch/Engine.pm:228 #, perl-brace-format msgid "Nothing to deploy (already at \"{change}\")" msgstr "Nichts anzuwenden (aktueller Stand ist bereits \"{change}\")" -#: lib/App/Sqitch/Engine.pm:226 +#: lib/App/Sqitch/Engine.pm:246 #, perl-brace-format msgid "Adding registry tables to {destination}" msgstr "Erstelle Registry-Tabellen in {destination}" -#: lib/App/Sqitch/Engine.pm:235 +#: lib/App/Sqitch/Engine.pm:255 msgid "Cannot deploy to an earlier change; use \"revert\" instead" msgstr "" "Eine vorige Γ„nderung kann nicht angewandt werden. Verwende stattdessen " "\"revert\"" -#: lib/App/Sqitch/Engine.pm:243 +#: lib/App/Sqitch/Engine.pm:263 #, perl-brace-format msgid "Deploying changes through {change} to {destination}" msgstr "Wende Γ„nderungen von {change} nach {destination} an" -#: lib/App/Sqitch/Engine.pm:247 +#: lib/App/Sqitch/Engine.pm:267 #, perl-brace-format msgid "Deploying changes to {destination}" msgstr "Wende Γ„nderungen nach {destination} an" -#: lib/App/Sqitch/Engine.pm:260 +#: lib/App/Sqitch/Engine.pm:272 +msgid "Will deploy the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:285 #, perl-brace-format msgid "Unknown deployment mode: \"{mode}\"" msgstr "Unbekannter Anwendungsmodus: \"{mode}\"" -#: lib/App/Sqitch/Engine.pm:291 +#: lib/App/Sqitch/Engine.pm:313 +msgid "Missing required parameter $prompt_default" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:342 #, perl-brace-format msgid "Change not deployed: \"{change}\"" msgstr "Γ„nderung nicht angewandt: \"{change}\"" -#: lib/App/Sqitch/Engine.pm:306 +#: lib/App/Sqitch/Engine.pm:359 #, perl-brace-format msgid "No changes deployed since: \"{change}\"" msgstr "Keine Γ„nderungen seit \"{change}\" angewandt" -#: lib/App/Sqitch/Engine.pm:314 +#: lib/App/Sqitch/Engine.pm:369 #, perl-brace-format msgid "Reverting changes to {change} from {destination}" msgstr "Kehre Γ„nderungen an {destination} um nach {change}" -#: lib/App/Sqitch/Engine.pm:321 lib/App/Sqitch/Engine.pm:344 +#: lib/App/Sqitch/Engine.pm:373 lib/App/Sqitch/Engine.pm:403 +msgid "Will revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:376 lib/App/Sqitch/Engine.pm:406 +msgid "Would revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:380 lib/App/Sqitch/Engine.pm:410 msgid "Nothing reverted" msgstr "Nichts rΓΌckgΓ€ngig gemacht" -#: lib/App/Sqitch/Engine.pm:324 +#: lib/App/Sqitch/Engine.pm:383 #, perl-brace-format msgid "Revert changes to {change} from {destination}?" msgstr "Γ„nderungen von {change} nach {destination} wieder rΓΌckgΓ€ngig machen?" -#: lib/App/Sqitch/Engine.pm:332 +#: lib/App/Sqitch/Engine.pm:392 msgid "Nothing to revert (nothing deployed)" msgstr "Nichts rΓΌckgΓ€ngig zu machen (keine Γ„nderungen angewandt)" -#: lib/App/Sqitch/Engine.pm:338 +#: lib/App/Sqitch/Engine.pm:400 #, perl-brace-format msgid "Reverting all changes from {destination}" msgstr "Kehre alle Γ„nderungen an {destination} um" -#: lib/App/Sqitch/Engine.pm:347 +#: lib/App/Sqitch/Engine.pm:413 #, perl-brace-format msgid "Revert all changes from {destination}?" msgstr "Alle Γ„nderungen an {destination} rΓΌckgΓ€ngig machen?" -#: lib/App/Sqitch/Engine.pm:378 +#: lib/App/Sqitch/Engine.pm:447 #, perl-brace-format msgid "Verifying {destination}" msgstr "Verifiziere {destination}" -#: lib/App/Sqitch/Engine.pm:385 +#: lib/App/Sqitch/Engine.pm:454 msgid "Nothing to verify (no planned or deployed changes)" msgstr "Nichts zu verifizieren (keine geplanten oder angewandten Γ„nderungen)" -#: lib/App/Sqitch/Engine.pm:392 +#: lib/App/Sqitch/Engine.pm:461 msgid "There are deployed changes, but none planned!" msgstr "Angewandte Γ„nderungen gefunden die ungeplant sind!" -#: lib/App/Sqitch/Engine.pm:405 +#: lib/App/Sqitch/Engine.pm:474 msgid "Verify Summary Report" msgstr "Verifizierungsreport" -#: lib/App/Sqitch/Engine.pm:408 +#: lib/App/Sqitch/Engine.pm:477 #, perl-brace-format msgid "Changes: {number}" msgstr "Γ„nderungen: {number}" -#: lib/App/Sqitch/Engine.pm:409 +#: lib/App/Sqitch/Engine.pm:478 #, perl-brace-format msgid "Errors: {number}" msgstr "Fehler: {number}" -#: lib/App/Sqitch/Engine.pm:410 +#: lib/App/Sqitch/Engine.pm:479 msgid "Verify failed" msgstr "Verifizierung fehlgeschlagen" -#: lib/App/Sqitch/Engine.pm:415 +#: lib/App/Sqitch/Engine.pm:484 msgid "Verify successful" msgstr "Erfolgreich verifiziert" -#: lib/App/Sqitch/Engine.pm:444 +#: lib/App/Sqitch/Engine.pm:513 #, perl-brace-format msgid "Change \"{change}\" has not been deployed" msgstr "Γ„nderung \"{change}\" wurde noch nicht angewendet" -#: lib/App/Sqitch/Engine.pm:447 +#: lib/App/Sqitch/Engine.pm:516 #, perl-brace-format msgid "Cannot find \"{change}\" in the database or the plan" msgstr "Kann \"{change}\" weder in der Datenbank noch im Plan finden" -#: lib/App/Sqitch/Engine.pm:454 +#: lib/App/Sqitch/Engine.pm:523 #, perl-brace-format msgid "Change \"{change}\" is deployed, but not planned" msgstr "Γ„nderung \"{change}\" wurde angewendet, allerdings nicht geplant" -#: lib/App/Sqitch/Engine.pm:498 +#: lib/App/Sqitch/Engine.pm:567 msgid "Out of order" msgstr "UngΓΌltige Reihenfolge" -#: lib/App/Sqitch/Engine.pm:504 +#: lib/App/Sqitch/Engine.pm:573 msgid "Not present in the plan" msgstr "Im Plan nicht vorhanden" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:527 -#: lib/App/Sqitch/Engine.pm:996 lib/App/Sqitch/Engine.pm:1026 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:596 +#: lib/App/Sqitch/Engine.pm:1068 lib/App/Sqitch/Engine.pm:1098 msgid "not ok" msgstr "nicht OK" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:974 -#: lib/App/Sqitch/Engine.pm:1016 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:1046 +#: lib/App/Sqitch/Engine.pm:1088 msgid "ok" msgstr "OK" -#: lib/App/Sqitch/Engine.pm:529 +#: lib/App/Sqitch/Engine.pm:598 msgid "Not deployed" msgstr "Nicht angewendet" -#: lib/App/Sqitch/Engine.pm:561 +#: lib/App/Sqitch/Engine.pm:630 #, perl-brace-format msgid "Verify script \"{script}\" failed." msgstr "Verifizierungsskript {script} fehlgeschlagen." -#: lib/App/Sqitch/Engine.pm:570 +#: lib/App/Sqitch/Engine.pm:639 #, perl-brace-format msgid "Verify script {file} does not exist" msgstr "Verifizierungsskript {file} existiert nicht" -#: lib/App/Sqitch/Engine.pm:612 +#: lib/App/Sqitch/Engine.pm:681 #, perl-brace-format msgid "Conflicts with previously deployed change: {changes}" msgid_plural "Conflicts with previously deployed changes: {changes}" msgstr[0] "Konflikte mit zuvor angewendeter Γ„nderung: {changes}" msgstr[1] "Konflikte mit zuvor angewendeten Γ„nderungen: {changes}" -#: lib/App/Sqitch/Engine.pm:619 +#: lib/App/Sqitch/Engine.pm:688 #, perl-brace-format msgid "Missing required change: {changes}" msgid_plural "Missing required changes: {changes}" msgstr[0] "Fehlende benΓΆtigte Γ„nderung: {changes}" msgstr[1] "Fehlende benΓΆtigte Γ„nderungen: {changes}" -#: lib/App/Sqitch/Engine.pm:631 +#: lib/App/Sqitch/Engine.pm:700 #, perl-brace-format msgid "Change \"{changes}\" has already been deployed" msgid_plural "Changes have already been deployed: {changes}" msgstr[0] "Γ„nderung \"{changes}\" wurde bereits angewendet" msgstr[1] "Γ„nderungen wurden bereits angewendet: {changes}" -#: lib/App/Sqitch/Engine.pm:654 +#: lib/App/Sqitch/Engine.pm:723 #, perl-brace-format msgid "Change \"{change}\" required by currently deployed change: {changes}" msgid_plural "" @@ -886,66 +916,66 @@ msgstr[1] "" "Γ„nderung \"{change}\" wird erfordert von gerade angewendeten Γ„nderungen: " "{changes}" -#: lib/App/Sqitch/Engine.pm:677 +#: lib/App/Sqitch/Engine.pm:746 #, perl-brace-format msgid "Invalid dependency: {dependency}" msgstr "UngΓΌltige AbhΓ€ngigkeit: {dependency}" -#: lib/App/Sqitch/Engine.pm:813 lib/App/Sqitch/Plan/ChangeList.pm:88 +#: lib/App/Sqitch/Engine.pm:882 lib/App/Sqitch/Plan/ChangeList.pm:88 #, perl-brace-format msgid "" "Change \"{change}\" is ambiguous. Please specify a tag-qualified change:" msgstr "" "Γ„nderung \"{change}\" ist mehrdeutig. Bitte gib ein Tag fΓΌr die Γ„nderung an:" -#: lib/App/Sqitch/Engine.pm:828 +#: lib/App/Sqitch/Engine.pm:897 msgid "Change Lookup Failed" msgstr "Suche nach Γ„nderung gescheitert" -#: lib/App/Sqitch/Engine.pm:849 +#: lib/App/Sqitch/Engine.pm:918 #, perl-brace-format msgid "Reverting to {change}" msgstr "Mache Γ„nderungen rΓΌckgΓ€nging bis nach {change}" -#: lib/App/Sqitch/Engine.pm:850 +#: lib/App/Sqitch/Engine.pm:919 msgid "Reverting all changes" msgstr "Kehre sΓ€mtliche Γ„nderungen um" -#: lib/App/Sqitch/Engine.pm:858 +#: lib/App/Sqitch/Engine.pm:927 msgid "The schema will need to be manually repaired" msgstr "Das Schema muss manuell repariert werden" -#: lib/App/Sqitch/Engine.pm:862 lib/App/Sqitch/Engine.pm:990 +#: lib/App/Sqitch/Engine.pm:931 lib/App/Sqitch/Engine.pm:1062 msgid "Deploy failed" msgstr "Anwendung der Γ„nderung(en) fehlgeschlagen" -#: lib/App/Sqitch/Engine.pm:919 +#: lib/App/Sqitch/Engine.pm:991 #, perl-brace-format msgid "Cannot find change {id} ({change}) in {file}" msgstr "Kann Γ„nderung {id} ({change}) in {file} nicht finden" -#: lib/App/Sqitch/Engine.pm:1041 +#: lib/App/Sqitch/Engine.pm:1113 #, perl-brace-format msgid "" "Blocked by another instance of Sqitch working on {dest}; waiting {secs} " "seconds..." msgstr "" -#: lib/App/Sqitch/Engine.pm:1051 +#: lib/App/Sqitch/Engine.pm:1123 #, perl-brace-format msgid "" "Timed out waiting {secs} seconds for another instance of Sqitch to finish " "work on {dest}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1110 +#: lib/App/Sqitch/Engine.pm:1182 #, perl-brace-format msgid "No registry found in {destination}. Have you ever deployed?" msgstr "" "Registry nicht gefunden in {destination}. Wurde Sqitch jemals darauf " "ausgefΓΌhrt?" -#: lib/App/Sqitch/Engine.pm:1115 +#: lib/App/Sqitch/Engine.pm:1187 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " @@ -954,7 +984,7 @@ msgstr "" "Aktuelle Registry-Version ist {old} allerdings ist {new} die neueste " "bekannte Version. Bitte aktualisiere Sqitch" -#: lib/App/Sqitch/Engine.pm:1121 +#: lib/App/Sqitch/Engine.pm:1193 #, perl-brace-format msgid "" "Registry is at version {old} but latest is {new}. Please run the \"upgrade\" " @@ -963,7 +993,7 @@ msgstr "" "Registry ist derzeit auf Version {old} aber neueste Version ist {new}. Bitte " "fΓΌhre den \"upgrade\"-Befehl aus" -#: lib/App/Sqitch/Engine.pm:1136 +#: lib/App/Sqitch/Engine.pm:1208 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " @@ -972,76 +1002,76 @@ msgstr "" "Aktuelle Registry-Version ist {old} allerdings ist {new} die neueste " "bekannte Version. Bitte aktualisiere Sqitch" -#: lib/App/Sqitch/Engine.pm:1151 +#: lib/App/Sqitch/Engine.pm:1223 #, perl-brace-format msgid "Cannot upgrade to {version}: Cannot find upgrade script \"{file}\"" msgstr "" "Kann nicht nach {version} aktualisieren: Upgrade-Skript \"{file}\" nicht " "gefunden" -#: lib/App/Sqitch/Engine.pm:1158 +#: lib/App/Sqitch/Engine.pm:1230 #, perl-brace-format msgid "Upgrading the Sqitch registry from {old} to {new}" msgstr "Aktualisiere die Sqitch-Registry von {old} nach {new}" -#: lib/App/Sqitch/Engine.pm:1165 +#: lib/App/Sqitch/Engine.pm:1237 #, perl-brace-format msgid "From {old} to {new}" msgstr "Von {old} nach {new}" -#: lib/App/Sqitch/Engine.pm:1210 +#: lib/App/Sqitch/Engine.pm:1282 #, fuzzy, perl-brace-format msgid "Checking {destination}" msgstr "Verifiziere {destination}" -#: lib/App/Sqitch/Engine.pm:1217 +#: lib/App/Sqitch/Engine.pm:1289 #, fuzzy msgid "Nothing to check (no planned or deployed changes)" msgstr "Nichts zu verifizieren (keine geplanten oder angewandten Γ„nderungen)" -#: lib/App/Sqitch/Engine.pm:1230 +#: lib/App/Sqitch/Engine.pm:1302 #, fuzzy, perl-brace-format msgid "Script signatures diverge at change {change}" msgstr "Fehlende benΓΆtigte Γ„nderung: {changes}" -#: lib/App/Sqitch/Engine.pm:1238 +#: lib/App/Sqitch/Engine.pm:1310 #, perl-brace-format msgid "Failed one check" msgid_plural "Failed {count} checks" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:1246 +#: lib/App/Sqitch/Engine.pm:1318 #, fuzzy msgid "Check successful" msgstr "Erfolgreich verifiziert" -#: lib/App/Sqitch/Engine/exasol.pm:326 lib/App/Sqitch/Engine/oracle.pm:458 +#: lib/App/Sqitch/Engine/exasol.pm:323 lib/App/Sqitch/Engine/oracle.pm:462 msgid "Sqitch already initialized" msgstr "Sqitch ist bereits initialisiert" -#: lib/App/Sqitch/Engine/exasol.pm:394 lib/App/Sqitch/Engine/oracle.pm:588 +#: lib/App/Sqitch/Engine/exasol.pm:391 lib/App/Sqitch/Engine/oracle.pm:592 #, perl-brace-format msgid "Cannot remove {file}: {error}" msgstr "Kann Datei {file} nicht entfernen: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:403 lib/App/Sqitch/Engine/oracle.pm:597 +#: lib/App/Sqitch/Engine/exasol.pm:400 lib/App/Sqitch/Engine/oracle.pm:601 #, perl-brace-format msgid "Cannot copy {file} to {alias}: {error}" msgstr "Kann Datei {file} nicht nach {alias} kopieren: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:412 lib/App/Sqitch/Engine/oracle.pm:606 +#: lib/App/Sqitch/Engine/exasol.pm:409 lib/App/Sqitch/Engine/oracle.pm:610 #, perl-brace-format msgid "Cannot symlink {file} to {alias}: {error}" msgstr "" "Kann symbolische VerknΓΌpfung von {file} nach {alias} nicht erstellen: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:520 +#: lib/App/Sqitch/Engine/exasol.pm:522 #, perl-brace-format msgid "{command} unexpectedly failed; exit value = {exitval}" msgstr "{command} unerwartet gescheitert. RΓΌckgabewert = {exitval}" -#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:283 +#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:274 #: lib/App/Sqitch/Engine/sqlite.pm:158 #, perl-brace-format msgid "Sqitch database {database} already initialized" @@ -1057,18 +1087,23 @@ msgstr "Kann Datenbank {database} nicht erstellen: {error}" msgid "Database name missing in URI {uri}" msgstr "Name der Datenbank fehlt in URI {uri}" -#: lib/App/Sqitch/Engine/firebird.pm:891 lib/App/Sqitch/Engine/firebird.pm:909 -#: lib/App/Sqitch/Engine/firebird.pm:920 +#: lib/App/Sqitch/Engine/firebird.pm:839 lib/App/Sqitch/Role/DBIEngine.pm:527 +#, fuzzy, perl-brace-format +msgid "Cannot log change \"{change}\": The deploy script is not unique" +msgstr "Γ„nderung \"{change}\" wurde angewendet, allerdings nicht geplant" + +#: lib/App/Sqitch/Engine/firebird.pm:903 lib/App/Sqitch/Engine/firebird.pm:921 +#: lib/App/Sqitch/Engine/firebird.pm:932 #, perl-brace-format msgid "Cannot dup STDERR: {error}" msgstr "Kann STDERR nicht ΓΆffnen: {error}" -#: lib/App/Sqitch/Engine/firebird.pm:895 +#: lib/App/Sqitch/Engine/firebird.pm:907 #, perl-brace-format msgid "Cannot reirect STDERR: {error}" msgstr "Kann nicht nach STDERR umleiten: {error}" -#: lib/App/Sqitch/Engine/firebird.pm:923 +#: lib/App/Sqitch/Engine/firebird.pm:935 msgid "" "Unable to locate Firebird ISQL; set \"engine.firebird.client\" via sqitch " "config" @@ -1076,7 +1111,7 @@ msgstr "" "Kann Firebird ISQL nicht finden. Bitte setze \"engine.firebird.client\" via " "sqitch config" -#: lib/App/Sqitch/Engine/mysql.pm:126 +#: lib/App/Sqitch/Engine/mysql.pm:117 #, perl-brace-format msgid "" "Sqitch requires {rdbms} {want_version} or higher; this is {have_version}" @@ -1084,23 +1119,23 @@ msgstr "" "Sqitch setzt {rdbms} {want_version} oder hΓΆher voraus. Die aktuelle Version " "is allerdings {have_version}" -#: lib/App/Sqitch/Engine/mysql.pm:158 +#: lib/App/Sqitch/Engine/mysql.pm:149 #, perl-brace-format msgid "Database name missing in URI \"{uri}\"" msgstr "Name der Datenbank fehlt in URI \"{uri}\"" -#: lib/App/Sqitch/Engine/pg.pm:214 lib/App/Sqitch/Engine/snowflake.pm:302 -#: lib/App/Sqitch/Engine/vertica.pm:144 +#: lib/App/Sqitch/Engine/pg.pm:213 lib/App/Sqitch/Engine/snowflake.pm:310 +#: lib/App/Sqitch/Engine/vertica.pm:139 #, perl-brace-format msgid "Sqitch schema \"{schema}\" already exists" msgstr "Sqitch-Schema \"{schema}\" existiert bereits" -#: lib/App/Sqitch/Engine/pg.pm:454 +#: lib/App/Sqitch/Engine/pg.pm:453 #, fuzzy msgid "Sqitch registry not initialized" msgstr "Sqitch ist bereits initialisiert" -#: lib/App/Sqitch/Engine/pg.pm:455 +#: lib/App/Sqitch/Engine/pg.pm:454 msgid "" "Because the \"changes\" table does not exist, Sqitch will now initialize the " "database to create its registry tables." @@ -1111,9 +1146,9 @@ msgid "Cannot determine Snowflake account name" msgstr "Kann Namen fΓΌr Snowflake-Benutzerkonto nicht herausfinden" #: lib/App/Sqitch/Engine/sqlite.pm:98 -#, perl-brace-format +#, fuzzy, perl-brace-format msgid "" -"Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}" +"Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}" msgstr "" "Sqitch erwartet SQLite 3.7.11 oder neuer. DBD::SQLite wurde fΓΌr Version " "{version} gebaut" @@ -1124,94 +1159,94 @@ msgid "Sqitch requires SQLite 3.3.9 or later; {client} is {version}" msgstr "" "Sqitch erwartet SQLite 3.3.9 oder neuer. {client} ist allerdings {version}" -#: lib/App/Sqitch/ItemFormatter.pm:63 +#: lib/App/Sqitch/ItemFormatter.pm:62 msgid "Fail" msgstr "Fehlgeschlagen" -#: lib/App/Sqitch/ItemFormatter.pm:68 +#: lib/App/Sqitch/ItemFormatter.pm:67 msgid "deploy" msgstr "anwenden" -#: lib/App/Sqitch/ItemFormatter.pm:69 +#: lib/App/Sqitch/ItemFormatter.pm:68 msgid "revert" msgstr "rΓΌckgΓ€ngig machen" -#: lib/App/Sqitch/ItemFormatter.pm:70 +#: lib/App/Sqitch/ItemFormatter.pm:69 msgid "fail" msgstr "fehlschlagen" -#: lib/App/Sqitch/ItemFormatter.pm:75 +#: lib/App/Sqitch/ItemFormatter.pm:74 +msgid "No label passed to the _ format" +msgstr "Label fehlt im _ Formatierungsplatzhalter" + +#: lib/App/Sqitch/ItemFormatter.pm:76 msgid "Event: " msgstr "Ereignis: " -#: lib/App/Sqitch/ItemFormatter.pm:76 +#: lib/App/Sqitch/ItemFormatter.pm:77 msgid "Change: " msgstr "Γ„nderung: " -#: lib/App/Sqitch/ItemFormatter.pm:77 +#: lib/App/Sqitch/ItemFormatter.pm:78 msgid "Committer:" msgstr "Committer:" -#: lib/App/Sqitch/ItemFormatter.pm:78 +#: lib/App/Sqitch/ItemFormatter.pm:79 msgid "Planner: " msgstr "Planer: " -#: lib/App/Sqitch/ItemFormatter.pm:79 +#: lib/App/Sqitch/ItemFormatter.pm:80 msgid "By: " msgstr "Von: " -#: lib/App/Sqitch/ItemFormatter.pm:80 +#: lib/App/Sqitch/ItemFormatter.pm:81 msgid "Date: " msgstr "Datum: " -#: lib/App/Sqitch/ItemFormatter.pm:81 +#: lib/App/Sqitch/ItemFormatter.pm:82 msgid "Committed:" msgstr "Commitet:" -#: lib/App/Sqitch/ItemFormatter.pm:82 +#: lib/App/Sqitch/ItemFormatter.pm:83 msgid "Planned: " msgstr "Geplant: " -#: lib/App/Sqitch/ItemFormatter.pm:83 +#: lib/App/Sqitch/ItemFormatter.pm:84 msgid "Name: " msgstr "Name: " -#: lib/App/Sqitch/ItemFormatter.pm:84 +#: lib/App/Sqitch/ItemFormatter.pm:85 msgid "Project: " msgstr "Projekt: " -#: lib/App/Sqitch/ItemFormatter.pm:85 +#: lib/App/Sqitch/ItemFormatter.pm:86 msgid "Email: " msgstr "E-Mail: " -#: lib/App/Sqitch/ItemFormatter.pm:86 lib/App/Sqitch/ItemFormatter.pm:176 +#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:172 msgid "Requires: " msgstr "BenΓΆtigt: " -#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:187 +#: lib/App/Sqitch/ItemFormatter.pm:88 lib/App/Sqitch/ItemFormatter.pm:183 msgid "Conflicts:" msgstr "Konflikte:" -#: lib/App/Sqitch/ItemFormatter.pm:89 -msgid "No label passed to the _ format" -msgstr "Label fehlt im _ Formatierungsplatzhalter" - -#: lib/App/Sqitch/ItemFormatter.pm:93 +#: lib/App/Sqitch/ItemFormatter.pm:90 #, perl-brace-format msgid "Unknown label \"{label}\" passed to the _ format" msgstr "Unbekanntes Label \"{label}\" im _ Formatierungsplatzhalter angegeben" -#: lib/App/Sqitch/ItemFormatter.pm:150 +#: lib/App/Sqitch/ItemFormatter.pm:146 #, perl-brace-format msgid "{color} is not a valid ANSI color" msgstr "{color} ist keine gΓΌltige ANSI-Farbe" -#: lib/App/Sqitch/ItemFormatter.pm:193 +#: lib/App/Sqitch/ItemFormatter.pm:189 #, perl-brace-format msgid "{attr} is not a valid change attribute" msgstr "{attr} ist kein gΓΌltiges Γ„nderungsattribut" -#: lib/App/Sqitch/ItemFormatter.pm:216 +#: lib/App/Sqitch/ItemFormatter.pm:212 #, perl-brace-format msgid "Unknown format code \"{code}\"" msgstr "Unbekannter Formatierungscode \"{code}\"" @@ -1420,8 +1455,8 @@ msgstr "" #: lib/App/Sqitch/Plan.pm:918 #, fuzzy, perl-brace-format msgid "" -"\"{name}\" is invalid: changes must not begin with punctuation, contain \"@" -"\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " +"\"{name}\" is invalid: changes must not begin with punctuation, contain " +"\"@\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " "following punctuation" msgstr "" "\"{name}\" ist ungΓΌltig. Γ„nderungen dΓΌrfen nicht mit Satzzeichen beginnen, " @@ -1491,7 +1526,7 @@ msgstr "" "veraltet.\n" " Verwende stattdessen--chdir" -#: lib/App/Sqitch/Role/DBIEngine.pm:353 +#: lib/App/Sqitch/Role/DBIEngine.pm:365 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with NULL URI" @@ -1499,7 +1534,7 @@ msgstr "" "Kann \"{project}\" mit URI {uri} nicht registrieren: existiert bereits mit " "NULL URI" -#: lib/App/Sqitch/Role/DBIEngine.pm:359 +#: lib/App/Sqitch/Role/DBIEngine.pm:371 #, perl-brace-format msgid "" "Cannot register \"{project}\" without URI: already exists with URI {uri}" @@ -1507,7 +1542,7 @@ msgstr "" "Kann \"{project}\" ohne URI nicht registrieren: existiert bereits mit URI " "{uri}" -#: lib/App/Sqitch/Role/DBIEngine.pm:365 +#: lib/App/Sqitch/Role/DBIEngine.pm:377 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with URI " @@ -1516,7 +1551,7 @@ msgstr "" "Kann \"{project}\" mit URI {uri} nicht registrieren: existert bereits mit " "URI {reg_uri}" -#: lib/App/Sqitch/Role/DBIEngine.pm:383 +#: lib/App/Sqitch/Role/DBIEngine.pm:395 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: project \"{reg_proj}\" already " @@ -1525,6 +1560,13 @@ msgstr "" "Kann \"{project}\" mit URI {uri} nicht registrieren: Projekt \"{reg_proj}\" " "verwendet bereits diese URI" +#: lib/App/Sqitch/Role/RevertDeployCommand.pm:129 +#, perl-brace-format +msgid "" +"\"{command}\" cannot be used in strict mode.\\nUse explicity revert and " +"deploy commands instead." +msgstr "" + #: lib/App/Sqitch/Role/TargetConfigCommand.pm:96 #, perl-brace-format msgid "Unknown directory name: {dirs}" diff --git a/po/fr_FR.po b/po/fr_FR.po index b57678d6..dc2502ea 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -1,5 +1,5 @@ # Sqitch French Localization Messages -# Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +# Copyright (c) 2012-2023 iovation Inc., David E. Wheeler # This file is distributed under the same license as the App-Sqitch package. # Arnaud Assad , 2012. # @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Sqitch 0.932\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 14:23-0400\n" +"POT-Creation-Date: 2023-07-30 20:02-0400\n" "PO-Revision-Date: 2012-10-12 11:28-0700\n" "Last-Translator: Arnaud Assad \n" "Language-Team: French \n" @@ -36,7 +36,7 @@ msgstr "" msgid "Cannot change to directory {directory}: {error}" msgstr "Impossible de copier {src} vers {dest} : {error}" -#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:113 +#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:114 #, perl-brace-format msgid "\"{command}\" is not a valid command" msgstr "\"{command}\" n'est pas une commande valide" @@ -74,23 +74,23 @@ msgstr "Impossible d'exΓ©cuter {command} : {error}" msgid "Error closing pipe to {command}: {error}" msgstr "Erreur en fermant le tube vers {command} : {error}" -#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:763 +#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:771 #, perl-brace-format msgid "{command} unexpectedly returned exit value {exitval}" msgstr "{command} a retournΓ© de maniΓ¨re inattendue la valeur {exitval}" -#: lib/App/Sqitch/Command.pm:283 +#: lib/App/Sqitch/Command.pm:284 #, fuzzy, perl-brace-format msgid "Unknown argument \"{arg}\"" msgid_plural "Unknown arguments: {arg}" msgstr[0] "Γ‰tiquette inconnue \"{tag}\"" msgstr[1] "Γ‰tiquette inconnue \"{tag}\"" -#: lib/App/Sqitch/Command.pm:295 +#: lib/App/Sqitch/Command.pm:296 msgid "Cannot specify both --all and engine, target, or plan arugments" msgstr "" -#: lib/App/Sqitch/Command.pm:315 lib/App/Sqitch/Command/add.pm:410 +#: lib/App/Sqitch/Command.pm:316 lib/App/Sqitch/Command/add.pm:421 #: lib/App/Sqitch/Command/init.pm:203 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:250 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:337 @@ -98,7 +98,7 @@ msgstr "" msgid "Created {file}" msgstr "{file} crΓ©e" -#: lib/App/Sqitch/Command.pm:322 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 +#: lib/App/Sqitch/Command.pm:323 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 #, perl-brace-format msgid "Error creating {path}: {error}" msgstr "Erreur Γ  la crΓ©ation de {path} : {error}" @@ -149,7 +149,7 @@ msgstr "AjoutΓ© \"{change}\" Γ  {file}" msgid "Skipped {file}: already exists" msgstr "IgnorΓ© {file}: existe dΓ©jΓ " -#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:416 +#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:427 #: lib/App/Sqitch/Plan.pm:136 lib/App/Sqitch/Plan.pm:602 #: lib/App/Sqitch/Plan.pm:982 lib/App/Sqitch/Plan/Line.pm:107 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:321 @@ -168,6 +168,11 @@ msgstr "Erreur Γ  la crΓ©ation de {path} : {error}" msgid "Error closing {file}: {error}" msgstr "Erreur Γ  la fermeture de {file} : {error}" +#: lib/App/Sqitch/Command/add.pm:415 +#, perl-brace-format +msgid "File {file} has a double extension of {ext}" +msgstr "" + #: lib/App/Sqitch/Command/bundle.pm:99 msgid "" "Use of --to or --from to bundle multiple targets is not recommended.\n" @@ -223,7 +228,7 @@ msgstr "Γ‰criture des scripts" #: lib/App/Sqitch/Command/check.pm:89 lib/App/Sqitch/Command/deploy.pm:118 #: lib/App/Sqitch/Command/log.pm:212 lib/App/Sqitch/Command/rebase.pm:63 -#: lib/App/Sqitch/Command/revert.pm:128 lib/App/Sqitch/Command/status.pm:110 +#: lib/App/Sqitch/Command/revert.pm:137 lib/App/Sqitch/Command/status.pm:110 #: lib/App/Sqitch/Command/verify.pm:89 #, perl-brace-format msgid "Too many targets specified; connecting to {target}" @@ -234,17 +239,17 @@ msgstr "" msgid "Too many changes specified; checking from \"{from}\" to \"{to}\"" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:67 +#: lib/App/Sqitch/Command/checkout.pm:65 #, perl-brace-format msgid "Already on branch {branch}" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:103 +#: lib/App/Sqitch/Command/checkout.pm:101 #, perl-brace-format msgid "Branch {branch} has no changes in common with current branch {current}" msgstr "" -#: lib/App/Sqitch/Command/checkout.pm:109 +#: lib/App/Sqitch/Command/checkout.pm:107 #, perl-brace-format msgid "Last change before the branches diverged: {last_change}" msgstr "" @@ -337,12 +342,12 @@ msgid "Extension" msgstr "" #: lib/App/Sqitch/Command/engine.pm:185 lib/App/Sqitch/Command/target.pm:177 -#: lib/App/Sqitch/ItemFormatter.pm:62 +#: lib/App/Sqitch/ItemFormatter.pm:61 msgid "Revert" msgstr "Annulation" #: lib/App/Sqitch/Command/engine.pm:186 lib/App/Sqitch/Command/target.pm:178 -#: lib/App/Sqitch/ItemFormatter.pm:61 +#: lib/App/Sqitch/ItemFormatter.pm:60 msgid "Deploy" msgstr "DΓ©ploiement" @@ -439,7 +444,16 @@ msgstr "" msgid "Too many changes specified; rebasing onto \"{onto}\" up to \"{upto}\"" msgstr "" -#: lib/App/Sqitch/Command/revert.pm:138 +#: lib/App/Sqitch/Command/revert.pm:150 +msgid "Must specify a target revision in strict mode" +msgstr "" + +#: lib/App/Sqitch/Command/revert.pm:158 +#, fuzzy +msgid "Too many changes specified" +msgstr "Impossible de trouver ce changement dans {file}" + +#: lib/App/Sqitch/Command/revert.pm:163 #, perl-brace-format msgid "Too many changes specified; reverting to \"{change}\"" msgstr "" @@ -464,12 +478,12 @@ msgstr[1] "Modification de ces fichiers comme il convient" msgid "Skipped {dest}: {src} does not exist" msgstr "{dest} ignorΓ© : {src} n'existe pas" -#: lib/App/Sqitch/Command/rework.pm:208 +#: lib/App/Sqitch/Command/rework.pm:211 #, perl-brace-format msgid "Cannot copy {src} to {dest}: {error}" msgstr "Impossible de copier {src} vers {dest} : {error}" -#: lib/App/Sqitch/Command/rework.pm:215 +#: lib/App/Sqitch/Command/rework.pm:218 #, perl-brace-format msgid "Copied {src} to {dest}" msgstr "{src} copiΓ© vers {dest}" @@ -518,8 +532,8 @@ msgstr "" msgid ", " msgstr ", " -#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:384 -#: lib/App/Sqitch/Engine.pm:1216 +#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:453 +#: lib/App/Sqitch/Engine.pm:1288 msgid "No changes deployed" msgstr "Pas de changements dΓ©ployΓ©s" @@ -586,11 +600,11 @@ msgstr "Impossible de trouver ce changement dans {file}" msgid "Make sure you are connected to the proper database for this project." msgstr "Assurez-vous d'Γͺtre connectΓ© Γ  la bonne base de donnΓ©es pour ce projet" -#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:217 +#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:237 msgid "Nothing to deploy (up-to-date)" msgstr "Rien Γ  dΓ©ployer (Γ  jour)" -#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:539 +#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:608 msgid "Undeployed change:" msgid_plural "Undeployed changes:" msgstr[0] "Changement non dΓ©ployΓ© :" @@ -655,207 +669,223 @@ msgstr "Impossible de dΓ©terminer le rΓ©pertoire de rΓ©fΓ©rence" msgid "Unknown date format \"{format}\"" msgstr "Format de date inconnu \"{format}\"" -#: lib/App/Sqitch/Engine.pm:148 lib/App/Sqitch/Engine.pm:160 +#: lib/App/Sqitch/Engine.pm:168 lib/App/Sqitch/Engine.pm:180 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:162 lib/App/Sqitch/Target.pm:251 #, fuzzy msgid "No engine specified; specify via target or core.engine" msgstr "Pas de moteur spΓ©cifiΓ©; utiliser --engine ou dΓ©finir core.engine" -#: lib/App/Sqitch/Engine.pm:182 +#: lib/App/Sqitch/Engine.pm:202 #, fuzzy, perl-brace-format msgid "{driver} required to manage {engine}" msgstr "Module DBD::Pg requis pour gΓ©rer PostgreSQL" -#: lib/App/Sqitch/Engine.pm:197 +#: lib/App/Sqitch/Engine.pm:217 msgid "Nothing to deploy (empty plan)" msgstr "Rien Γ  dΓ©ployer (plan vide)" -#: lib/App/Sqitch/Engine.pm:201 lib/App/Sqitch/Engine.pm:297 +#: lib/App/Sqitch/Engine.pm:221 lib/App/Sqitch/Engine.pm:348 #: lib/App/Sqitch/Plan.pm:749 lib/App/Sqitch/Plan/ChangeList.pm:121 #, perl-brace-format msgid "Unknown change: \"{change}\"" msgstr "Changement inconnu \"{change}\" " -#: lib/App/Sqitch/Engine.pm:208 +#: lib/App/Sqitch/Engine.pm:228 #, fuzzy, perl-brace-format msgid "Nothing to deploy (already at \"{change}\")" msgstr "Rien Γ  dΓ©ployer (dΓ©jΓ  sur \"{target}\"" -#: lib/App/Sqitch/Engine.pm:226 +#: lib/App/Sqitch/Engine.pm:246 #, fuzzy, perl-brace-format msgid "Adding registry tables to {destination}" msgstr "Ajout des tables de metadonnΓ©es Γ  {destination}" -#: lib/App/Sqitch/Engine.pm:235 +#: lib/App/Sqitch/Engine.pm:255 #, fuzzy msgid "Cannot deploy to an earlier change; use \"revert\" instead" msgstr "" "Impossible de dΓ©ployer vers une cible antΓ©rieure; utiliser \"revert\" plutΓ΄t" -#: lib/App/Sqitch/Engine.pm:243 +#: lib/App/Sqitch/Engine.pm:263 #, fuzzy, perl-brace-format msgid "Deploying changes through {change} to {destination}" msgstr "DΓ©ploiement des changements de {target} Γ  {destination}" -#: lib/App/Sqitch/Engine.pm:247 +#: lib/App/Sqitch/Engine.pm:267 #, perl-brace-format msgid "Deploying changes to {destination}" msgstr "DΓ©ploiement des changements vers {destination}" -#: lib/App/Sqitch/Engine.pm:260 +#: lib/App/Sqitch/Engine.pm:272 +msgid "Will deploy the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:285 #, perl-brace-format msgid "Unknown deployment mode: \"{mode}\"" msgstr "Mode de dΓ©ploiement inconnu : \"{mode}\"" -#: lib/App/Sqitch/Engine.pm:291 +#: lib/App/Sqitch/Engine.pm:313 +msgid "Missing required parameter $prompt_default" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:342 #, fuzzy, perl-brace-format msgid "Change not deployed: \"{change}\"" msgstr "Cible non dΓ©ployΓ©e : \"{target}\"" -#: lib/App/Sqitch/Engine.pm:306 +#: lib/App/Sqitch/Engine.pm:359 #, fuzzy, perl-brace-format msgid "No changes deployed since: \"{change}\"" msgstr "Cible non dΓ©ployΓ©e : \"{target}\"" -#: lib/App/Sqitch/Engine.pm:314 +#: lib/App/Sqitch/Engine.pm:369 #, fuzzy, perl-brace-format msgid "Reverting changes to {change} from {destination}" msgstr "Annulation des changements de {destination} Γ  {target}" -#: lib/App/Sqitch/Engine.pm:321 lib/App/Sqitch/Engine.pm:344 +#: lib/App/Sqitch/Engine.pm:373 lib/App/Sqitch/Engine.pm:403 +msgid "Will revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:376 lib/App/Sqitch/Engine.pm:406 +msgid "Would revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:380 lib/App/Sqitch/Engine.pm:410 #, fuzzy msgid "Nothing reverted" msgstr "Rien Γ  annuler (rien de dΓ©ployΓ©)" -#: lib/App/Sqitch/Engine.pm:324 +#: lib/App/Sqitch/Engine.pm:383 #, fuzzy, perl-brace-format msgid "Revert changes to {change} from {destination}?" msgstr "Annulation des changements de {destination} Γ  {target}" -#: lib/App/Sqitch/Engine.pm:332 +#: lib/App/Sqitch/Engine.pm:392 msgid "Nothing to revert (nothing deployed)" msgstr "Rien Γ  annuler (rien de dΓ©ployΓ©)" -#: lib/App/Sqitch/Engine.pm:338 +#: lib/App/Sqitch/Engine.pm:400 #, perl-brace-format msgid "Reverting all changes from {destination}" msgstr "Annulation de tous les changements de {destination}" -#: lib/App/Sqitch/Engine.pm:347 +#: lib/App/Sqitch/Engine.pm:413 #, fuzzy, perl-brace-format msgid "Revert all changes from {destination}?" msgstr "Annulation de tous les changements de {destination}" -#: lib/App/Sqitch/Engine.pm:378 +#: lib/App/Sqitch/Engine.pm:447 #, fuzzy, perl-brace-format msgid "Verifying {destination}" msgstr "DΓ©ploiement des changements vers {destination}" -#: lib/App/Sqitch/Engine.pm:385 +#: lib/App/Sqitch/Engine.pm:454 #, fuzzy msgid "Nothing to verify (no planned or deployed changes)" msgstr "Rien Γ  annuler (rien de dΓ©ployΓ©)" -#: lib/App/Sqitch/Engine.pm:392 +#: lib/App/Sqitch/Engine.pm:461 msgid "There are deployed changes, but none planned!" msgstr "" -#: lib/App/Sqitch/Engine.pm:405 +#: lib/App/Sqitch/Engine.pm:474 msgid "Verify Summary Report" msgstr "" -#: lib/App/Sqitch/Engine.pm:408 +#: lib/App/Sqitch/Engine.pm:477 #, fuzzy, perl-brace-format msgid "Changes: {number}" msgstr "Changement : {change_id}" -#: lib/App/Sqitch/Engine.pm:409 +#: lib/App/Sqitch/Engine.pm:478 #, perl-brace-format msgid "Errors: {number}" msgstr "" -#: lib/App/Sqitch/Engine.pm:410 +#: lib/App/Sqitch/Engine.pm:479 #, fuzzy msgid "Verify failed" msgstr "Echec du dΓ©ploiement" -#: lib/App/Sqitch/Engine.pm:415 +#: lib/App/Sqitch/Engine.pm:484 msgid "Verify successful" msgstr "" -#: lib/App/Sqitch/Engine.pm:444 +#: lib/App/Sqitch/Engine.pm:513 #, perl-brace-format msgid "Change \"{change}\" has not been deployed" msgstr "" -#: lib/App/Sqitch/Engine.pm:447 +#: lib/App/Sqitch/Engine.pm:516 #, fuzzy, perl-brace-format msgid "Cannot find \"{change}\" in the database or the plan" msgstr "Impossible de trouver {target} dans le plan" -#: lib/App/Sqitch/Engine.pm:454 +#: lib/App/Sqitch/Engine.pm:523 #, fuzzy, perl-brace-format msgid "Change \"{change}\" is deployed, but not planned" msgstr "" "Le changement \"{change}\" duplique une dΓ©claration prΓ©cΓ©dente Γ  la ligne " "{line}" -#: lib/App/Sqitch/Engine.pm:498 +#: lib/App/Sqitch/Engine.pm:567 msgid "Out of order" msgstr "" -#: lib/App/Sqitch/Engine.pm:504 +#: lib/App/Sqitch/Engine.pm:573 #, fuzzy msgid "Not present in the plan" msgstr "Impossible de trouver {target} dans le plan" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:527 -#: lib/App/Sqitch/Engine.pm:996 lib/App/Sqitch/Engine.pm:1026 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:596 +#: lib/App/Sqitch/Engine.pm:1068 lib/App/Sqitch/Engine.pm:1098 msgid "not ok" msgstr "" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:974 -#: lib/App/Sqitch/Engine.pm:1016 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:1046 +#: lib/App/Sqitch/Engine.pm:1088 msgid "ok" msgstr "" -#: lib/App/Sqitch/Engine.pm:529 +#: lib/App/Sqitch/Engine.pm:598 #, fuzzy msgid "Not deployed" msgstr "Pas de changements dΓ©ployΓ©s" -#: lib/App/Sqitch/Engine.pm:561 +#: lib/App/Sqitch/Engine.pm:630 #, perl-brace-format msgid "Verify script \"{script}\" failed." msgstr "" -#: lib/App/Sqitch/Engine.pm:570 +#: lib/App/Sqitch/Engine.pm:639 #, fuzzy, perl-brace-format msgid "Verify script {file} does not exist" msgstr "Le fichier de plan {file} n'existe pas" -#: lib/App/Sqitch/Engine.pm:612 +#: lib/App/Sqitch/Engine.pm:681 #, perl-brace-format msgid "Conflicts with previously deployed change: {changes}" msgid_plural "Conflicts with previously deployed changes: {changes}" msgstr[0] "Conflits avec le changement dΓ©ployΓ© prΓ©cΓ©demment : {changes}" msgstr[1] "Conflits avec les changements dΓ©ployΓ©s prΓ©cΓ©demment : {changes}" -#: lib/App/Sqitch/Engine.pm:619 +#: lib/App/Sqitch/Engine.pm:688 #, perl-brace-format msgid "Missing required change: {changes}" msgid_plural "Missing required changes: {changes}" msgstr[0] "Changement requis manquant : {changes}" msgstr[1] "Changements requis manquant : {changes}" -#: lib/App/Sqitch/Engine.pm:631 +#: lib/App/Sqitch/Engine.pm:700 #, perl-brace-format msgid "Change \"{changes}\" has already been deployed" msgid_plural "Changes have already been deployed: {changes}" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:654 +#: lib/App/Sqitch/Engine.pm:723 #, fuzzy, perl-brace-format msgid "Change \"{change}\" required by currently deployed change: {changes}" msgid_plural "" @@ -863,149 +893,149 @@ msgid_plural "" msgstr[0] "Requis par le changement actuellement dΓ©ployΓ© : {changes}" msgstr[1] "Requis par les changements actuellement dΓ©ployΓ©s : {changes}" -#: lib/App/Sqitch/Engine.pm:677 +#: lib/App/Sqitch/Engine.pm:746 #, perl-brace-format msgid "Invalid dependency: {dependency}" msgstr "DΓ©pendance invalide {dependency}" -#: lib/App/Sqitch/Engine.pm:813 lib/App/Sqitch/Plan/ChangeList.pm:88 +#: lib/App/Sqitch/Engine.pm:882 lib/App/Sqitch/Plan/ChangeList.pm:88 #, perl-brace-format msgid "" "Change \"{change}\" is ambiguous. Please specify a tag-qualified change:" msgstr "" -#: lib/App/Sqitch/Engine.pm:828 +#: lib/App/Sqitch/Engine.pm:897 msgid "Change Lookup Failed" msgstr "" -#: lib/App/Sqitch/Engine.pm:849 +#: lib/App/Sqitch/Engine.pm:918 #, fuzzy, perl-brace-format msgid "Reverting to {change}" msgstr "Annulation et retour vers {target}" -#: lib/App/Sqitch/Engine.pm:850 +#: lib/App/Sqitch/Engine.pm:919 msgid "Reverting all changes" msgstr "Annulation de tous les changements" -#: lib/App/Sqitch/Engine.pm:858 +#: lib/App/Sqitch/Engine.pm:927 msgid "The schema will need to be manually repaired" msgstr "Le schΓ©ma devra Γͺtre rΓ©parΓ© manuellement" -#: lib/App/Sqitch/Engine.pm:862 lib/App/Sqitch/Engine.pm:990 +#: lib/App/Sqitch/Engine.pm:931 lib/App/Sqitch/Engine.pm:1062 msgid "Deploy failed" msgstr "Echec du dΓ©ploiement" -#: lib/App/Sqitch/Engine.pm:919 +#: lib/App/Sqitch/Engine.pm:991 #, fuzzy, perl-brace-format msgid "Cannot find change {id} ({change}) in {file}" msgstr "Impossible de trouver ce changement dans {file}" -#: lib/App/Sqitch/Engine.pm:1041 +#: lib/App/Sqitch/Engine.pm:1113 #, perl-brace-format msgid "" "Blocked by another instance of Sqitch working on {dest}; waiting {secs} " "seconds..." msgstr "" -#: lib/App/Sqitch/Engine.pm:1051 +#: lib/App/Sqitch/Engine.pm:1123 #, perl-brace-format msgid "" "Timed out waiting {secs} seconds for another instance of Sqitch to finish " "work on {dest}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1110 +#: lib/App/Sqitch/Engine.pm:1182 #, perl-brace-format msgid "No registry found in {destination}. Have you ever deployed?" msgstr "" -#: lib/App/Sqitch/Engine.pm:1115 +#: lib/App/Sqitch/Engine.pm:1187 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " "Sqitch" msgstr "" -#: lib/App/Sqitch/Engine.pm:1121 +#: lib/App/Sqitch/Engine.pm:1193 #, perl-brace-format msgid "" "Registry is at version {old} but latest is {new}. Please run the \"upgrade\" " "command" msgstr "" -#: lib/App/Sqitch/Engine.pm:1136 +#: lib/App/Sqitch/Engine.pm:1208 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " "Sqitch." msgstr "" -#: lib/App/Sqitch/Engine.pm:1151 +#: lib/App/Sqitch/Engine.pm:1223 #, perl-brace-format msgid "Cannot upgrade to {version}: Cannot find upgrade script \"{file}\"" msgstr "" -#: lib/App/Sqitch/Engine.pm:1158 +#: lib/App/Sqitch/Engine.pm:1230 #, fuzzy, perl-brace-format msgid "Upgrading the Sqitch registry from {old} to {new}" msgstr "Ajout des tables de metadonnΓ©es Γ  {destination}" -#: lib/App/Sqitch/Engine.pm:1165 +#: lib/App/Sqitch/Engine.pm:1237 #, perl-brace-format msgid "From {old} to {new}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1210 +#: lib/App/Sqitch/Engine.pm:1282 #, fuzzy, perl-brace-format msgid "Checking {destination}" msgstr "DΓ©ploiement des changements vers {destination}" -#: lib/App/Sqitch/Engine.pm:1217 +#: lib/App/Sqitch/Engine.pm:1289 #, fuzzy msgid "Nothing to check (no planned or deployed changes)" msgstr "Rien Γ  annuler (rien de dΓ©ployΓ©)" -#: lib/App/Sqitch/Engine.pm:1230 +#: lib/App/Sqitch/Engine.pm:1302 #, fuzzy, perl-brace-format msgid "Script signatures diverge at change {change}" msgstr "Changement requis manquant : {changes}" -#: lib/App/Sqitch/Engine.pm:1238 +#: lib/App/Sqitch/Engine.pm:1310 #, perl-brace-format msgid "Failed one check" msgid_plural "Failed {count} checks" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:1246 +#: lib/App/Sqitch/Engine.pm:1318 msgid "Check successful" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:326 lib/App/Sqitch/Engine/oracle.pm:458 +#: lib/App/Sqitch/Engine/exasol.pm:323 lib/App/Sqitch/Engine/oracle.pm:462 msgid "Sqitch already initialized" msgstr "" -#: lib/App/Sqitch/Engine/exasol.pm:394 lib/App/Sqitch/Engine/oracle.pm:588 +#: lib/App/Sqitch/Engine/exasol.pm:391 lib/App/Sqitch/Engine/oracle.pm:592 #, fuzzy, perl-brace-format msgid "Cannot remove {file}: {error}" msgstr "Impossible d'ouvrir {file} : {error}" -#: lib/App/Sqitch/Engine/exasol.pm:403 lib/App/Sqitch/Engine/oracle.pm:597 +#: lib/App/Sqitch/Engine/exasol.pm:400 lib/App/Sqitch/Engine/oracle.pm:601 #, fuzzy, perl-brace-format msgid "Cannot copy {file} to {alias}: {error}" msgstr "Impossible de copier {src} vers {dest} : {error}" -#: lib/App/Sqitch/Engine/exasol.pm:412 lib/App/Sqitch/Engine/oracle.pm:606 +#: lib/App/Sqitch/Engine/exasol.pm:409 lib/App/Sqitch/Engine/oracle.pm:610 #, fuzzy, perl-brace-format msgid "Cannot symlink {file} to {alias}: {error}" msgstr "Impossible d'ouvrir {file} : {error}" -#: lib/App/Sqitch/Engine/exasol.pm:520 +#: lib/App/Sqitch/Engine/exasol.pm:522 #, fuzzy, perl-brace-format msgid "{command} unexpectedly failed; exit value = {exitval}" msgstr "{command} a retournΓ© de maniΓ¨re inattendue la valeur {exitval}" -#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:283 +#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:274 #: lib/App/Sqitch/Engine/sqlite.pm:158 #, perl-brace-format msgid "Sqitch database {database} already initialized" @@ -1021,45 +1051,52 @@ msgstr "Impossible de copier {src} vers {dest} : {error}" msgid "Database name missing in URI {uri}" msgstr "" -#: lib/App/Sqitch/Engine/firebird.pm:891 lib/App/Sqitch/Engine/firebird.pm:909 -#: lib/App/Sqitch/Engine/firebird.pm:920 +#: lib/App/Sqitch/Engine/firebird.pm:839 lib/App/Sqitch/Role/DBIEngine.pm:527 +#, fuzzy, perl-brace-format +msgid "Cannot log change \"{change}\": The deploy script is not unique" +msgstr "" +"Le changement \"{change}\" duplique une dΓ©claration prΓ©cΓ©dente Γ  la ligne " +"{line}" + +#: lib/App/Sqitch/Engine/firebird.pm:903 lib/App/Sqitch/Engine/firebird.pm:921 +#: lib/App/Sqitch/Engine/firebird.pm:932 #, fuzzy, perl-brace-format msgid "Cannot dup STDERR: {error}" msgstr "Impossible d'ouvrir {file} : {error}" -#: lib/App/Sqitch/Engine/firebird.pm:895 +#: lib/App/Sqitch/Engine/firebird.pm:907 #, fuzzy, perl-brace-format msgid "Cannot reirect STDERR: {error}" msgstr "Impossible d'exΓ©cuter {command} : {error}" -#: lib/App/Sqitch/Engine/firebird.pm:923 +#: lib/App/Sqitch/Engine/firebird.pm:935 msgid "" "Unable to locate Firebird ISQL; set \"engine.firebird.client\" via sqitch " "config" msgstr "" -#: lib/App/Sqitch/Engine/mysql.pm:126 +#: lib/App/Sqitch/Engine/mysql.pm:117 #, perl-brace-format msgid "" "Sqitch requires {rdbms} {want_version} or higher; this is {have_version}" msgstr "" -#: lib/App/Sqitch/Engine/mysql.pm:158 +#: lib/App/Sqitch/Engine/mysql.pm:149 #, perl-brace-format msgid "Database name missing in URI \"{uri}\"" msgstr "" -#: lib/App/Sqitch/Engine/pg.pm:214 lib/App/Sqitch/Engine/snowflake.pm:302 -#: lib/App/Sqitch/Engine/vertica.pm:144 +#: lib/App/Sqitch/Engine/pg.pm:213 lib/App/Sqitch/Engine/snowflake.pm:310 +#: lib/App/Sqitch/Engine/vertica.pm:139 #, perl-brace-format msgid "Sqitch schema \"{schema}\" already exists" msgstr "Le schΓ©ma Sqitch \"{schema}\" existe dΓ©jΓ " -#: lib/App/Sqitch/Engine/pg.pm:454 +#: lib/App/Sqitch/Engine/pg.pm:453 msgid "Sqitch registry not initialized" msgstr "" -#: lib/App/Sqitch/Engine/pg.pm:455 +#: lib/App/Sqitch/Engine/pg.pm:454 msgid "" "Because the \"changes\" table does not exist, Sqitch will now initialize the " "database to create its registry tables." @@ -1072,7 +1109,7 @@ msgstr "" #: lib/App/Sqitch/Engine/sqlite.pm:98 #, perl-brace-format msgid "" -"Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}" +"Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}" msgstr "" #: lib/App/Sqitch/Engine/sqlite.pm:121 @@ -1080,94 +1117,94 @@ msgstr "" msgid "Sqitch requires SQLite 3.3.9 or later; {client} is {version}" msgstr "" -#: lib/App/Sqitch/ItemFormatter.pm:63 +#: lib/App/Sqitch/ItemFormatter.pm:62 msgid "Fail" msgstr "Echec" -#: lib/App/Sqitch/ItemFormatter.pm:68 +#: lib/App/Sqitch/ItemFormatter.pm:67 msgid "deploy" msgstr "dΓ©ploiement" -#: lib/App/Sqitch/ItemFormatter.pm:69 +#: lib/App/Sqitch/ItemFormatter.pm:68 msgid "revert" msgstr "annulation" -#: lib/App/Sqitch/ItemFormatter.pm:70 +#: lib/App/Sqitch/ItemFormatter.pm:69 msgid "fail" msgstr "Γ©chec" -#: lib/App/Sqitch/ItemFormatter.pm:75 +#: lib/App/Sqitch/ItemFormatter.pm:74 +msgid "No label passed to the _ format" +msgstr "Pas d'Γ©tiquette passΓ©e au format _ " + +#: lib/App/Sqitch/ItemFormatter.pm:76 msgid "Event: " msgstr "EvΓ¨nement : " -#: lib/App/Sqitch/ItemFormatter.pm:76 +#: lib/App/Sqitch/ItemFormatter.pm:77 msgid "Change: " msgstr "Changement : " -#: lib/App/Sqitch/ItemFormatter.pm:77 +#: lib/App/Sqitch/ItemFormatter.pm:78 msgid "Committer:" msgstr "Committer : " -#: lib/App/Sqitch/ItemFormatter.pm:78 +#: lib/App/Sqitch/ItemFormatter.pm:79 msgid "Planner: " msgstr "Plannificateur : " -#: lib/App/Sqitch/ItemFormatter.pm:79 +#: lib/App/Sqitch/ItemFormatter.pm:80 msgid "By: " msgstr "Par : " -#: lib/App/Sqitch/ItemFormatter.pm:80 +#: lib/App/Sqitch/ItemFormatter.pm:81 msgid "Date: " msgstr "Date : " -#: lib/App/Sqitch/ItemFormatter.pm:81 +#: lib/App/Sqitch/ItemFormatter.pm:82 msgid "Committed:" msgstr "CommittΓ© : " -#: lib/App/Sqitch/ItemFormatter.pm:82 +#: lib/App/Sqitch/ItemFormatter.pm:83 msgid "Planned: " msgstr "PrΓ©vu : " -#: lib/App/Sqitch/ItemFormatter.pm:83 +#: lib/App/Sqitch/ItemFormatter.pm:84 msgid "Name: " msgstr "Nom : " -#: lib/App/Sqitch/ItemFormatter.pm:84 +#: lib/App/Sqitch/ItemFormatter.pm:85 msgid "Project: " msgstr "Projet : " -#: lib/App/Sqitch/ItemFormatter.pm:85 +#: lib/App/Sqitch/ItemFormatter.pm:86 msgid "Email: " msgstr "Email : " -#: lib/App/Sqitch/ItemFormatter.pm:86 lib/App/Sqitch/ItemFormatter.pm:176 +#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:172 msgid "Requires: " msgstr "Requis : " -#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:187 +#: lib/App/Sqitch/ItemFormatter.pm:88 lib/App/Sqitch/ItemFormatter.pm:183 msgid "Conflicts:" msgstr "Conflits : " -#: lib/App/Sqitch/ItemFormatter.pm:89 -msgid "No label passed to the _ format" -msgstr "Pas d'Γ©tiquette passΓ©e au format _ " - -#: lib/App/Sqitch/ItemFormatter.pm:93 +#: lib/App/Sqitch/ItemFormatter.pm:90 #, perl-brace-format msgid "Unknown label \"{label}\" passed to the _ format" msgstr "Γ‰tiquette \"{label}\" inconnue passΓ©e au format _" -#: lib/App/Sqitch/ItemFormatter.pm:150 +#: lib/App/Sqitch/ItemFormatter.pm:146 #, perl-brace-format msgid "{color} is not a valid ANSI color" msgstr "{color} n'est pas une couleur ANSI valide" -#: lib/App/Sqitch/ItemFormatter.pm:193 +#: lib/App/Sqitch/ItemFormatter.pm:189 #, perl-brace-format msgid "{attr} is not a valid change attribute" msgstr "{attr} n'est pas un changement d'attribut valide" -#: lib/App/Sqitch/ItemFormatter.pm:216 +#: lib/App/Sqitch/ItemFormatter.pm:212 #, fuzzy, perl-brace-format msgid "Unknown format code \"{code}\"" msgstr "Code de format de journalisation \"{code}\" inconnu" @@ -1377,8 +1414,8 @@ msgstr "" #: lib/App/Sqitch/Plan.pm:918 #, fuzzy, perl-brace-format msgid "" -"\"{name}\" is invalid: changes must not begin with punctuation, contain \"@" -"\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " +"\"{name}\" is invalid: changes must not begin with punctuation, contain " +"\"@\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " "following punctuation" msgstr "" "\"{name}\" est invalide : les changements ne doivent pas commencer par de la " @@ -1446,7 +1483,7 @@ msgid "" " Use --chdir instead." msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:353 +#: lib/App/Sqitch/Role/DBIEngine.pm:365 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with NULL URI" @@ -1454,7 +1491,7 @@ msgstr "" "Impossible d'enregistrer \"{project}\" avec l'URI {uri} : il existe dΓ©jΓ  " "avec un URI NULL" -#: lib/App/Sqitch/Role/DBIEngine.pm:359 +#: lib/App/Sqitch/Role/DBIEngine.pm:371 #, perl-brace-format msgid "" "Cannot register \"{project}\" without URI: already exists with URI {uri}" @@ -1462,7 +1499,7 @@ msgstr "" "Impossible d'enregistrer \"{project}\" sans URI : il existe dΓ©jΓ  avec l'URI " "{uri}" -#: lib/App/Sqitch/Role/DBIEngine.pm:365 +#: lib/App/Sqitch/Role/DBIEngine.pm:377 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with URI " @@ -1471,7 +1508,7 @@ msgstr "" "Impossible d'enregistrer \"{project}\" avec l'URI {uri} : il existe dΓ©jΓ  " "avec l'URI {reg_uri}" -#: lib/App/Sqitch/Role/DBIEngine.pm:383 +#: lib/App/Sqitch/Role/DBIEngine.pm:395 #, fuzzy, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: project \"{reg_proj}\" already " @@ -1480,6 +1517,13 @@ msgstr "" "Impossible d'enregistrer \"{project}\" avec l'URI {uri} : le projet " "\"{reg_prog}\" utilise dΓ©jΓ  cet URI" +#: lib/App/Sqitch/Role/RevertDeployCommand.pm:129 +#, perl-brace-format +msgid "" +"\"{command}\" cannot be used in strict mode.\\nUse explicity revert and " +"deploy commands instead." +msgstr "" + #: lib/App/Sqitch/Role/TargetConfigCommand.pm:96 #, fuzzy, perl-brace-format msgid "Unknown directory name: {dirs}" diff --git a/po/it_IT.po b/po/it_IT.po index 46749750..6b716b1c 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -1,5 +1,5 @@ # Sqitch Italian Localization Messages -# Copyright (c) 2012-2022 iovation Inc., David E. Wheeler +# Copyright (c) 2012-2023 iovation Inc., David E. Wheeler # This file is distributed under the same license as the App-Sqitch package. # Luca Ferrari , 2017 # @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: App-Sqitch 0.9996\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-10-01 14:23-0400\n" +"POT-Creation-Date: 2023-07-30 20:02-0400\n" "PO-Revision-Date: 2017-10-12 10:30+0200\n" "Last-Translator: Luca Ferrari \n" "Language-Team: Italian \n" @@ -37,7 +37,7 @@ msgstr "" msgid "Cannot change to directory {directory}: {error}" msgstr "Non posso copiare {src} in {dest}: {error}" -#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:113 +#: lib/App/Sqitch.pm:314 lib/App/Sqitch/Command.pm:114 #, perl-brace-format msgid "\"{command}\" is not a valid command" msgstr "\"{command}\" non Γ¨ un comando valido" @@ -76,24 +76,24 @@ msgstr "Non posso eseguire {command}: {error}" msgid "Error closing pipe to {command}: {error}" msgstr "Errore di chiusura pipe per {command}: {error}" -#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:763 +#: lib/App/Sqitch.pm:488 lib/App/Sqitch/Engine/oracle.pm:771 #, perl-brace-format msgid "{command} unexpectedly returned exit value {exitval}" msgstr "Il comando {command} ha restituito un exit value inatteso {exitval}" -#: lib/App/Sqitch/Command.pm:283 +#: lib/App/Sqitch/Command.pm:284 #, perl-brace-format msgid "Unknown argument \"{arg}\"" msgid_plural "Unknown arguments: {arg}" msgstr[0] "Argomento sconosciuto: \"{arg}\"" msgstr[1] "Argomenti sconosciuti: {arg}" -#: lib/App/Sqitch/Command.pm:295 +#: lib/App/Sqitch/Command.pm:296 msgid "Cannot specify both --all and engine, target, or plan arugments" msgstr "" "Non si puΓ² specificare contemporaneamente --all e target, target o plan." -#: lib/App/Sqitch/Command.pm:315 lib/App/Sqitch/Command/add.pm:410 +#: lib/App/Sqitch/Command.pm:316 lib/App/Sqitch/Command/add.pm:421 #: lib/App/Sqitch/Command/init.pm:203 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:250 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:337 @@ -101,7 +101,7 @@ msgstr "" msgid "Created {file}" msgstr "{file} creato" -#: lib/App/Sqitch/Command.pm:322 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 +#: lib/App/Sqitch/Command.pm:323 lib/App/Sqitch/Role/TargetConfigCommand.pm:256 #, perl-brace-format msgid "Error creating {path}: {error}" msgstr "Errore durante la creazione di {path}: {error}" @@ -154,7 +154,7 @@ msgstr "\"{change}\" aggiunta al file {file}" msgid "Skipped {file}: already exists" msgstr "Saltato {file}: esiste giΓ " -#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:416 +#: lib/App/Sqitch/Command/add.pm:386 lib/App/Sqitch/Command/add.pm:427 #: lib/App/Sqitch/Plan.pm:136 lib/App/Sqitch/Plan.pm:602 #: lib/App/Sqitch/Plan.pm:982 lib/App/Sqitch/Plan/Line.pm:107 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:321 @@ -173,6 +173,11 @@ msgstr "Errore nell'esecuzione di {template}: {error}" msgid "Error closing {file}: {error}" msgstr "Errore nella chiusura di {file}: {error}" +#: lib/App/Sqitch/Command/add.pm:415 +#, perl-brace-format +msgid "File {file} has a double extension of {ext}" +msgstr "" + #: lib/App/Sqitch/Command/bundle.pm:99 msgid "" "Use of --to or --from to bundle multiple targets is not recommended.\n" @@ -231,7 +236,7 @@ msgstr "Salvo gli script" #: lib/App/Sqitch/Command/check.pm:89 lib/App/Sqitch/Command/deploy.pm:118 #: lib/App/Sqitch/Command/log.pm:212 lib/App/Sqitch/Command/rebase.pm:63 -#: lib/App/Sqitch/Command/revert.pm:128 lib/App/Sqitch/Command/status.pm:110 +#: lib/App/Sqitch/Command/revert.pm:137 lib/App/Sqitch/Command/status.pm:110 #: lib/App/Sqitch/Command/verify.pm:89 #, perl-brace-format msgid "Too many targets specified; connecting to {target}" @@ -242,18 +247,18 @@ msgstr "Troppo target specificati: collegamento a {target}" msgid "Too many changes specified; checking from \"{from}\" to \"{to}\"" msgstr "Troppe modifiche specificate; verfica da \"{from}\" a \"{to}\"" -#: lib/App/Sqitch/Command/checkout.pm:67 +#: lib/App/Sqitch/Command/checkout.pm:65 #, perl-brace-format msgid "Already on branch {branch}" msgstr "GiΓ  nel ramo {branch}" -#: lib/App/Sqitch/Command/checkout.pm:103 +#: lib/App/Sqitch/Command/checkout.pm:101 #, perl-brace-format msgid "Branch {branch} has no changes in common with current branch {current}" msgstr "" "Il ramo {branch} non ha modifiche in comune con il ramo corrente {current}" -#: lib/App/Sqitch/Command/checkout.pm:109 +#: lib/App/Sqitch/Command/checkout.pm:107 #, perl-brace-format msgid "Last change before the branches diverged: {last_change}" msgstr "Ultima modifica prima della divergenza dei rami: {last_change}" @@ -346,12 +351,12 @@ msgid "Extension" msgstr "Estensione" #: lib/App/Sqitch/Command/engine.pm:185 lib/App/Sqitch/Command/target.pm:177 -#: lib/App/Sqitch/ItemFormatter.pm:62 +#: lib/App/Sqitch/ItemFormatter.pm:61 msgid "Revert" msgstr "Ripristina" #: lib/App/Sqitch/Command/engine.pm:186 lib/App/Sqitch/Command/target.pm:178 -#: lib/App/Sqitch/ItemFormatter.pm:61 +#: lib/App/Sqitch/ItemFormatter.pm:60 msgid "Deploy" msgstr "Implementa" @@ -447,7 +452,16 @@ msgid "Too many changes specified; rebasing onto \"{onto}\" up to \"{upto}\"" msgstr "" "Troppe modifiche specificate; riposiziono da \"{onto}\" fino a \"{upto}\"" -#: lib/App/Sqitch/Command/revert.pm:138 +#: lib/App/Sqitch/Command/revert.pm:150 +msgid "Must specify a target revision in strict mode" +msgstr "" + +#: lib/App/Sqitch/Command/revert.pm:158 +#, fuzzy +msgid "Too many changes specified" +msgstr "Troppi target specificati; si usa {target}" + +#: lib/App/Sqitch/Command/revert.pm:163 #, perl-brace-format msgid "Too many changes specified; reverting to \"{change}\"" msgstr "Troppe modifiche specificate; ritorno a \"{change}\"" @@ -472,12 +486,12 @@ msgstr[1] "Modifica questi file nel modo appropriato:" msgid "Skipped {dest}: {src} does not exist" msgstr "Saltato {dest}: {src} non esiste" -#: lib/App/Sqitch/Command/rework.pm:208 +#: lib/App/Sqitch/Command/rework.pm:211 #, perl-brace-format msgid "Cannot copy {src} to {dest}: {error}" msgstr "Non posso copiare {src} in {dest}: {error}" -#: lib/App/Sqitch/Command/rework.pm:215 +#: lib/App/Sqitch/Command/rework.pm:218 #, perl-brace-format msgid "Copied {src} to {dest}" msgstr "Copiato {src} in {dest}" @@ -525,8 +539,8 @@ msgstr "Usa --project per selezionare quale progetto interrogare: {projects}" msgid ", " msgstr ", " -#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:384 -#: lib/App/Sqitch/Engine.pm:1216 +#: lib/App/Sqitch/Command/status.pm:138 lib/App/Sqitch/Engine.pm:453 +#: lib/App/Sqitch/Engine.pm:1288 msgid "No changes deployed" msgstr "Nessuna modifica implementata" @@ -594,11 +608,11 @@ msgid "Make sure you are connected to the proper database for this project." msgstr "" "Assicurati di essere collegato al database corretto per questo progetto." -#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:217 +#: lib/App/Sqitch/Command/status.pm:308 lib/App/Sqitch/Engine.pm:237 msgid "Nothing to deploy (up-to-date)" msgstr "Niente da implementare (tutto giΓ  aggiornato)" -#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:539 +#: lib/App/Sqitch/Command/status.pm:311 lib/App/Sqitch/Engine.pm:608 msgid "Undeployed change:" msgid_plural "Undeployed changes:" msgstr[0] "Modifica rimosse dalla implementazione:" @@ -667,177 +681,193 @@ msgstr "Non riesco a stabiliare la home directory" msgid "Unknown date format \"{format}\"" msgstr "Formato data \"{format}\" sconosciuto" -#: lib/App/Sqitch/Engine.pm:148 lib/App/Sqitch/Engine.pm:160 +#: lib/App/Sqitch/Engine.pm:168 lib/App/Sqitch/Engine.pm:180 #: lib/App/Sqitch/Role/TargetConfigCommand.pm:162 lib/App/Sqitch/Target.pm:251 #, fuzzy msgid "No engine specified; specify via target or core.engine" msgstr "Nessun motore specificato: usa --engine o imposta core.engine" -#: lib/App/Sqitch/Engine.pm:182 +#: lib/App/Sqitch/Engine.pm:202 #, perl-brace-format msgid "{driver} required to manage {engine}" msgstr "{driver} Γ¨ necessario per gestire {engine}" -#: lib/App/Sqitch/Engine.pm:197 +#: lib/App/Sqitch/Engine.pm:217 msgid "Nothing to deploy (empty plan)" msgstr "Niente da implementare (piano di esecuzione vuoto)" -#: lib/App/Sqitch/Engine.pm:201 lib/App/Sqitch/Engine.pm:297 +#: lib/App/Sqitch/Engine.pm:221 lib/App/Sqitch/Engine.pm:348 #: lib/App/Sqitch/Plan.pm:749 lib/App/Sqitch/Plan/ChangeList.pm:121 #, perl-brace-format msgid "Unknown change: \"{change}\"" msgstr "Modifica \"{change}\" sconosciuta" -#: lib/App/Sqitch/Engine.pm:208 +#: lib/App/Sqitch/Engine.pm:228 #, perl-brace-format msgid "Nothing to deploy (already at \"{change}\")" msgstr "Niente da implementare (giΓ  a \"{change}\")" -#: lib/App/Sqitch/Engine.pm:226 +#: lib/App/Sqitch/Engine.pm:246 #, perl-brace-format msgid "Adding registry tables to {destination}" msgstr "Aggiungo le tabelle di registro a {destination}" -#: lib/App/Sqitch/Engine.pm:235 +#: lib/App/Sqitch/Engine.pm:255 msgid "Cannot deploy to an earlier change; use \"revert\" instead" msgstr "Non posso implementare una modifica precedente; usa \"revert\"." -#: lib/App/Sqitch/Engine.pm:243 +#: lib/App/Sqitch/Engine.pm:263 #, perl-brace-format msgid "Deploying changes through {change} to {destination}" msgstr "Implementazione delle modifiche da {change} a {destination}" -#: lib/App/Sqitch/Engine.pm:247 +#: lib/App/Sqitch/Engine.pm:267 #, perl-brace-format msgid "Deploying changes to {destination}" msgstr "Implementazione delle modifiche a {destination}" -#: lib/App/Sqitch/Engine.pm:260 +#: lib/App/Sqitch/Engine.pm:272 +msgid "Will deploy the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:285 #, perl-brace-format msgid "Unknown deployment mode: \"{mode}\"" msgstr "ModalitΓ  di implementazione \"{mode}\" sconosciuta" -#: lib/App/Sqitch/Engine.pm:291 +#: lib/App/Sqitch/Engine.pm:313 +msgid "Missing required parameter $prompt_default" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:342 #, perl-brace-format msgid "Change not deployed: \"{change}\"" msgstr "Modifica non implementata: \"{change}\"" -#: lib/App/Sqitch/Engine.pm:306 +#: lib/App/Sqitch/Engine.pm:359 #, perl-brace-format msgid "No changes deployed since: \"{change}\"" msgstr "Nessuna modifica implementata da: \"{change}\"" -#: lib/App/Sqitch/Engine.pm:314 +#: lib/App/Sqitch/Engine.pm:369 #, perl-brace-format msgid "Reverting changes to {change} from {destination}" msgstr "Annullo modifiche da {destination} a {change}" -#: lib/App/Sqitch/Engine.pm:321 lib/App/Sqitch/Engine.pm:344 +#: lib/App/Sqitch/Engine.pm:373 lib/App/Sqitch/Engine.pm:403 +msgid "Will revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:376 lib/App/Sqitch/Engine.pm:406 +msgid "Would revert the following changes:" +msgstr "" + +#: lib/App/Sqitch/Engine.pm:380 lib/App/Sqitch/Engine.pm:410 msgid "Nothing reverted" msgstr "Niente Γ¨ stato annullato" -#: lib/App/Sqitch/Engine.pm:324 +#: lib/App/Sqitch/Engine.pm:383 #, perl-brace-format msgid "Revert changes to {change} from {destination}?" msgstr "Annullo modifiche da {destination} a {change}" -#: lib/App/Sqitch/Engine.pm:332 +#: lib/App/Sqitch/Engine.pm:392 msgid "Nothing to revert (nothing deployed)" msgstr "Niente da annullare (niente da implementare)" -#: lib/App/Sqitch/Engine.pm:338 +#: lib/App/Sqitch/Engine.pm:400 #, perl-brace-format msgid "Reverting all changes from {destination}" msgstr "Annullo tutte le modifiche da {destination}" -#: lib/App/Sqitch/Engine.pm:347 +#: lib/App/Sqitch/Engine.pm:413 #, perl-brace-format msgid "Revert all changes from {destination}?" msgstr "Annullo tutte le modifiche da {destination}?" -#: lib/App/Sqitch/Engine.pm:378 +#: lib/App/Sqitch/Engine.pm:447 #, perl-brace-format msgid "Verifying {destination}" msgstr "Veifico {destination}" -#: lib/App/Sqitch/Engine.pm:385 +#: lib/App/Sqitch/Engine.pm:454 msgid "Nothing to verify (no planned or deployed changes)" msgstr "Niente da verificare (nessuna modifica pianificata o implementata)" -#: lib/App/Sqitch/Engine.pm:392 +#: lib/App/Sqitch/Engine.pm:461 msgid "There are deployed changes, but none planned!" msgstr "Ci sono modifiche implementate, ma nessuna pianificata!" -#: lib/App/Sqitch/Engine.pm:405 +#: lib/App/Sqitch/Engine.pm:474 msgid "Verify Summary Report" msgstr "Report Sommario di verifica" -#: lib/App/Sqitch/Engine.pm:408 +#: lib/App/Sqitch/Engine.pm:477 #, perl-brace-format msgid "Changes: {number}" msgstr "Modifiche: {number}" -#: lib/App/Sqitch/Engine.pm:409 +#: lib/App/Sqitch/Engine.pm:478 #, perl-brace-format msgid "Errors: {number}" msgstr "Errori: {number}" -#: lib/App/Sqitch/Engine.pm:410 +#: lib/App/Sqitch/Engine.pm:479 msgid "Verify failed" msgstr "Verifica fallita" -#: lib/App/Sqitch/Engine.pm:415 +#: lib/App/Sqitch/Engine.pm:484 msgid "Verify successful" msgstr "Verifica riuscita" -#: lib/App/Sqitch/Engine.pm:444 +#: lib/App/Sqitch/Engine.pm:513 #, perl-brace-format msgid "Change \"{change}\" has not been deployed" msgstr "Modifica \"{change}\" non implementata" -#: lib/App/Sqitch/Engine.pm:447 +#: lib/App/Sqitch/Engine.pm:516 #, perl-brace-format msgid "Cannot find \"{change}\" in the database or the plan" msgstr "Non posso trovare \"{change}\" nel database o nel piano di esecuzione" -#: lib/App/Sqitch/Engine.pm:454 +#: lib/App/Sqitch/Engine.pm:523 #, perl-brace-format msgid "Change \"{change}\" is deployed, but not planned" msgstr "La modifica \"{change}\" Γ¨ implementata ma non pianificata" -#: lib/App/Sqitch/Engine.pm:498 +#: lib/App/Sqitch/Engine.pm:567 msgid "Out of order" msgstr "Fuori servizio" -#: lib/App/Sqitch/Engine.pm:504 +#: lib/App/Sqitch/Engine.pm:573 msgid "Not present in the plan" msgstr "Non presente nel piano di esecuzione" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:527 -#: lib/App/Sqitch/Engine.pm:996 lib/App/Sqitch/Engine.pm:1026 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:596 +#: lib/App/Sqitch/Engine.pm:1068 lib/App/Sqitch/Engine.pm:1098 msgid "not ok" msgstr "Non OK" -#: lib/App/Sqitch/Engine.pm:515 lib/App/Sqitch/Engine.pm:974 -#: lib/App/Sqitch/Engine.pm:1016 +#: lib/App/Sqitch/Engine.pm:584 lib/App/Sqitch/Engine.pm:1046 +#: lib/App/Sqitch/Engine.pm:1088 msgid "ok" msgstr "OK" -#: lib/App/Sqitch/Engine.pm:529 +#: lib/App/Sqitch/Engine.pm:598 msgid "Not deployed" msgstr "Non implementato" -#: lib/App/Sqitch/Engine.pm:561 +#: lib/App/Sqitch/Engine.pm:630 #, perl-brace-format msgid "Verify script \"{script}\" failed." msgstr "Script di verifica \"{script}\" fallito" -#: lib/App/Sqitch/Engine.pm:570 +#: lib/App/Sqitch/Engine.pm:639 #, perl-brace-format msgid "Verify script {file} does not exist" msgstr "Lo script di verifica {file} non esiste" -#: lib/App/Sqitch/Engine.pm:612 +#: lib/App/Sqitch/Engine.pm:681 #, perl-brace-format msgid "Conflicts with previously deployed change: {changes}" msgid_plural "Conflicts with previously deployed changes: {changes}" @@ -846,21 +876,21 @@ msgstr[0] "" msgstr[1] "" "Ci sono conflitti con le modifiche precededentemente implementate: {changes}" -#: lib/App/Sqitch/Engine.pm:619 +#: lib/App/Sqitch/Engine.pm:688 #, perl-brace-format msgid "Missing required change: {changes}" msgid_plural "Missing required changes: {changes}" msgstr[0] "Modifica richiesta non trovata: {changes}" msgstr[1] "Modifiche richieste non trovate: {changes}" -#: lib/App/Sqitch/Engine.pm:631 +#: lib/App/Sqitch/Engine.pm:700 #, perl-brace-format msgid "Change \"{changes}\" has already been deployed" msgid_plural "Changes have already been deployed: {changes}" msgstr[0] "La modifica \"{changes}\" Γ¨ giΓ  stata implementata" msgstr[1] "Le modifiche \"{changes}\" sono giΓ  state implementate" -#: lib/App/Sqitch/Engine.pm:654 +#: lib/App/Sqitch/Engine.pm:723 #, perl-brace-format msgid "Change \"{change}\" required by currently deployed change: {changes}" msgid_plural "" @@ -872,66 +902,66 @@ msgstr[1] "" "La modifica \"{change}\" Γ¨ richiesta dalle modifiche correntemente " "implementate: {changes}" -#: lib/App/Sqitch/Engine.pm:677 +#: lib/App/Sqitch/Engine.pm:746 #, perl-brace-format msgid "Invalid dependency: {dependency}" msgstr "Dipendenza {dependency} non valida" -#: lib/App/Sqitch/Engine.pm:813 lib/App/Sqitch/Plan/ChangeList.pm:88 +#: lib/App/Sqitch/Engine.pm:882 lib/App/Sqitch/Plan/ChangeList.pm:88 #, perl-brace-format msgid "" "Change \"{change}\" is ambiguous. Please specify a tag-qualified change:" msgstr "" "La modifica \"{change}\" Γ¨ ambigua. Per favore indica la modifica con un tag." -#: lib/App/Sqitch/Engine.pm:828 +#: lib/App/Sqitch/Engine.pm:897 msgid "Change Lookup Failed" msgstr "Recupero della modifica fallito" -#: lib/App/Sqitch/Engine.pm:849 +#: lib/App/Sqitch/Engine.pm:918 #, perl-brace-format msgid "Reverting to {change}" msgstr "Ritorno a {change}" -#: lib/App/Sqitch/Engine.pm:850 +#: lib/App/Sqitch/Engine.pm:919 msgid "Reverting all changes" msgstr "Annullo tutte le modifiche" -#: lib/App/Sqitch/Engine.pm:858 +#: lib/App/Sqitch/Engine.pm:927 msgid "The schema will need to be manually repaired" msgstr "Lo schema richiede una riparazione manuale." -#: lib/App/Sqitch/Engine.pm:862 lib/App/Sqitch/Engine.pm:990 +#: lib/App/Sqitch/Engine.pm:931 lib/App/Sqitch/Engine.pm:1062 msgid "Deploy failed" msgstr "Implementazione fallita" -#: lib/App/Sqitch/Engine.pm:919 +#: lib/App/Sqitch/Engine.pm:991 #, perl-brace-format msgid "Cannot find change {id} ({change}) in {file}" msgstr "Non trovo la modifica {id} ({change}) in {file}" -#: lib/App/Sqitch/Engine.pm:1041 +#: lib/App/Sqitch/Engine.pm:1113 #, perl-brace-format msgid "" "Blocked by another instance of Sqitch working on {dest}; waiting {secs} " "seconds..." msgstr "" -#: lib/App/Sqitch/Engine.pm:1051 +#: lib/App/Sqitch/Engine.pm:1123 #, perl-brace-format msgid "" "Timed out waiting {secs} seconds for another instance of Sqitch to finish " "work on {dest}" msgstr "" -#: lib/App/Sqitch/Engine.pm:1110 +#: lib/App/Sqitch/Engine.pm:1182 #, perl-brace-format msgid "No registry found in {destination}. Have you ever deployed?" msgstr "" "Nessun registro trovato in {destination}. E' mai stata fatta una " "implementazione prima?" -#: lib/App/Sqitch/Engine.pm:1115 +#: lib/App/Sqitch/Engine.pm:1187 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " @@ -940,7 +970,7 @@ msgstr "" "La versione di registro Γ¨ {old} ma {new} Γ¨ la piΓΉ recente conosciuta. Per " "favore aggiorna Sqitch." -#: lib/App/Sqitch/Engine.pm:1121 +#: lib/App/Sqitch/Engine.pm:1193 #, perl-brace-format msgid "" "Registry is at version {old} but latest is {new}. Please run the \"upgrade\" " @@ -949,7 +979,7 @@ msgstr "" "La versione di registro Γ¨ {old} ma {new} Γ¨ la piΓΉ recente conosciuta. Per " "favore esegui il comando \"upgrade\"." -#: lib/App/Sqitch/Engine.pm:1136 +#: lib/App/Sqitch/Engine.pm:1208 #, perl-brace-format msgid "" "Registry version is {old} but {new} is the latest known. Please upgrade " @@ -958,75 +988,75 @@ msgstr "" "La versione di registro Γ¨ {old} ma {new} Γ¨ la piΓΉ recente conosciuta. Per " "favore aggiorna Sqitch." -#: lib/App/Sqitch/Engine.pm:1151 +#: lib/App/Sqitch/Engine.pm:1223 #, perl-brace-format msgid "Cannot upgrade to {version}: Cannot find upgrade script \"{file}\"" msgstr "" "Non posso aggiornare a {version}: non trovo lo script \"{file}\" per " "l'aggiornamento" -#: lib/App/Sqitch/Engine.pm:1158 +#: lib/App/Sqitch/Engine.pm:1230 #, fuzzy, perl-brace-format msgid "Upgrading the Sqitch registry from {old} to {new}" msgstr "Aggiorno il registro {registry} alla versione {version}" -#: lib/App/Sqitch/Engine.pm:1165 +#: lib/App/Sqitch/Engine.pm:1237 #, perl-brace-format msgid "From {old} to {new}" msgstr "Da {old} a {new}" -#: lib/App/Sqitch/Engine.pm:1210 +#: lib/App/Sqitch/Engine.pm:1282 #, fuzzy, perl-brace-format msgid "Checking {destination}" msgstr "Veifico {destination}" -#: lib/App/Sqitch/Engine.pm:1217 +#: lib/App/Sqitch/Engine.pm:1289 #, fuzzy msgid "Nothing to check (no planned or deployed changes)" msgstr "Niente da verificare (nessuna modifica pianificata o implementata)" -#: lib/App/Sqitch/Engine.pm:1230 +#: lib/App/Sqitch/Engine.pm:1302 #, fuzzy, perl-brace-format msgid "Script signatures diverge at change {change}" msgstr "Modifica richiesta non trovata: {changes}" -#: lib/App/Sqitch/Engine.pm:1238 +#: lib/App/Sqitch/Engine.pm:1310 #, perl-brace-format msgid "Failed one check" msgid_plural "Failed {count} checks" msgstr[0] "" msgstr[1] "" -#: lib/App/Sqitch/Engine.pm:1246 +#: lib/App/Sqitch/Engine.pm:1318 #, fuzzy msgid "Check successful" msgstr "Verifica riuscita" -#: lib/App/Sqitch/Engine/exasol.pm:326 lib/App/Sqitch/Engine/oracle.pm:458 +#: lib/App/Sqitch/Engine/exasol.pm:323 lib/App/Sqitch/Engine/oracle.pm:462 msgid "Sqitch already initialized" msgstr "Sqitch Γ¨ giΓ  stato inizializzato" -#: lib/App/Sqitch/Engine/exasol.pm:394 lib/App/Sqitch/Engine/oracle.pm:588 +#: lib/App/Sqitch/Engine/exasol.pm:391 lib/App/Sqitch/Engine/oracle.pm:592 #, perl-brace-format msgid "Cannot remove {file}: {error}" msgstr "Non posso rimuovere {file}: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:403 lib/App/Sqitch/Engine/oracle.pm:597 +#: lib/App/Sqitch/Engine/exasol.pm:400 lib/App/Sqitch/Engine/oracle.pm:601 #, perl-brace-format msgid "Cannot copy {file} to {alias}: {error}" msgstr "Non posso copiare {file} su {alias}: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:412 lib/App/Sqitch/Engine/oracle.pm:606 +#: lib/App/Sqitch/Engine/exasol.pm:409 lib/App/Sqitch/Engine/oracle.pm:610 #, perl-brace-format msgid "Cannot symlink {file} to {alias}: {error}" msgstr "Non posso creare un link simbolico da {file} a {alias}: {error}" -#: lib/App/Sqitch/Engine/exasol.pm:520 +#: lib/App/Sqitch/Engine/exasol.pm:522 #, fuzzy, perl-brace-format msgid "{command} unexpectedly failed; exit value = {exitval}" msgstr "Il comando {command} ha restituito un exit value inatteso {exitval}" -#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:283 +#: lib/App/Sqitch/Engine/firebird.pm:208 lib/App/Sqitch/Engine/mysql.pm:274 #: lib/App/Sqitch/Engine/sqlite.pm:158 #, perl-brace-format msgid "Sqitch database {database} already initialized" @@ -1042,18 +1072,23 @@ msgstr "Non posso creare il database {database}: {error}" msgid "Database name missing in URI {uri}" msgstr "Il nome di database non Γ¨ specificato nell'URI {uri}" -#: lib/App/Sqitch/Engine/firebird.pm:891 lib/App/Sqitch/Engine/firebird.pm:909 -#: lib/App/Sqitch/Engine/firebird.pm:920 +#: lib/App/Sqitch/Engine/firebird.pm:839 lib/App/Sqitch/Role/DBIEngine.pm:527 +#, fuzzy, perl-brace-format +msgid "Cannot log change \"{change}\": The deploy script is not unique" +msgstr "La modifica \"{change}\" Γ¨ implementata ma non pianificata" + +#: lib/App/Sqitch/Engine/firebird.pm:903 lib/App/Sqitch/Engine/firebird.pm:921 +#: lib/App/Sqitch/Engine/firebird.pm:932 #, perl-brace-format msgid "Cannot dup STDERR: {error}" msgstr "Non posso effettuare la dup su STDERR: {error}" -#: lib/App/Sqitch/Engine/firebird.pm:895 +#: lib/App/Sqitch/Engine/firebird.pm:907 #, perl-brace-format msgid "Cannot reirect STDERR: {error}" msgstr "Non posso redirezionare STDERR: {error}" -#: lib/App/Sqitch/Engine/firebird.pm:923 +#: lib/App/Sqitch/Engine/firebird.pm:935 msgid "" "Unable to locate Firebird ISQL; set \"engine.firebird.client\" via sqitch " "config" @@ -1061,7 +1096,7 @@ msgstr "" "Non trovo Firebirs ISQL: imposta \"engine.firebird.client\" attraverso " "\"sqitch config\"" -#: lib/App/Sqitch/Engine/mysql.pm:126 +#: lib/App/Sqitch/Engine/mysql.pm:117 #, perl-brace-format msgid "" "Sqitch requires {rdbms} {want_version} or higher; this is {have_version}" @@ -1069,23 +1104,23 @@ msgstr "" "Sqitch richiede {rdbms} alla version {want_version} o superiore: questa Γ¨ la " "versione {have_version}" -#: lib/App/Sqitch/Engine/mysql.pm:158 +#: lib/App/Sqitch/Engine/mysql.pm:149 #, perl-brace-format msgid "Database name missing in URI \"{uri}\"" msgstr "Il nome di database non Γ¨ specificato nell'URI {uri}" -#: lib/App/Sqitch/Engine/pg.pm:214 lib/App/Sqitch/Engine/snowflake.pm:302 -#: lib/App/Sqitch/Engine/vertica.pm:144 +#: lib/App/Sqitch/Engine/pg.pm:213 lib/App/Sqitch/Engine/snowflake.pm:310 +#: lib/App/Sqitch/Engine/vertica.pm:139 #, perl-brace-format msgid "Sqitch schema \"{schema}\" already exists" msgstr "Lo schema \"{schema}\" per Sqitch esiste giΓ ." -#: lib/App/Sqitch/Engine/pg.pm:454 +#: lib/App/Sqitch/Engine/pg.pm:453 #, fuzzy msgid "Sqitch registry not initialized" msgstr "Sqitch Γ¨ giΓ  stato inizializzato" -#: lib/App/Sqitch/Engine/pg.pm:455 +#: lib/App/Sqitch/Engine/pg.pm:454 msgid "" "Because the \"changes\" table does not exist, Sqitch will now initialize the " "database to create its registry tables." @@ -1096,9 +1131,9 @@ msgid "Cannot determine Snowflake account name" msgstr "" #: lib/App/Sqitch/Engine/sqlite.pm:98 -#, perl-brace-format +#, fuzzy, perl-brace-format msgid "" -"Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}" +"Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}" msgstr "" "Sqitch richiede SQLite 3.7.11 or superiore; DBD::SQLite non Γ¨ stato " "compilato per {version}" @@ -1108,96 +1143,96 @@ msgstr "" msgid "Sqitch requires SQLite 3.3.9 or later; {client} is {version}" msgstr "Sqitch richiede SQLite 3.3.9 o superiore: {client} Γ¨ {version}" -#: lib/App/Sqitch/ItemFormatter.pm:63 +#: lib/App/Sqitch/ItemFormatter.pm:62 msgid "Fail" msgstr "Fallito" -#: lib/App/Sqitch/ItemFormatter.pm:68 +#: lib/App/Sqitch/ItemFormatter.pm:67 msgid "deploy" msgstr "implementa" -#: lib/App/Sqitch/ItemFormatter.pm:69 +#: lib/App/Sqitch/ItemFormatter.pm:68 msgid "revert" msgstr "annullo" -#: lib/App/Sqitch/ItemFormatter.pm:70 +#: lib/App/Sqitch/ItemFormatter.pm:69 msgid "fail" msgstr "fallito" -#: lib/App/Sqitch/ItemFormatter.pm:75 +#: lib/App/Sqitch/ItemFormatter.pm:74 +#, fuzzy +msgid "No label passed to the _ format" +msgstr "Nessuna etichetta passata al formato _" + +#: lib/App/Sqitch/ItemFormatter.pm:76 msgid "Event: " msgstr "Evento:" -#: lib/App/Sqitch/ItemFormatter.pm:76 +#: lib/App/Sqitch/ItemFormatter.pm:77 msgid "Change: " msgstr "Modifica:" -#: lib/App/Sqitch/ItemFormatter.pm:77 +#: lib/App/Sqitch/ItemFormatter.pm:78 msgid "Committer:" msgstr "Autore:" -#: lib/App/Sqitch/ItemFormatter.pm:78 +#: lib/App/Sqitch/ItemFormatter.pm:79 #, fuzzy msgid "Planner: " msgstr "Esecutore:" -#: lib/App/Sqitch/ItemFormatter.pm:79 +#: lib/App/Sqitch/ItemFormatter.pm:80 msgid "By: " msgstr "Autore:" -#: lib/App/Sqitch/ItemFormatter.pm:80 +#: lib/App/Sqitch/ItemFormatter.pm:81 msgid "Date: " msgstr "Data:" -#: lib/App/Sqitch/ItemFormatter.pm:81 +#: lib/App/Sqitch/ItemFormatter.pm:82 msgid "Committed:" msgstr "Creata:" -#: lib/App/Sqitch/ItemFormatter.pm:82 +#: lib/App/Sqitch/ItemFormatter.pm:83 msgid "Planned: " msgstr "Pianificato:" -#: lib/App/Sqitch/ItemFormatter.pm:83 +#: lib/App/Sqitch/ItemFormatter.pm:84 msgid "Name: " msgstr "Nome:" -#: lib/App/Sqitch/ItemFormatter.pm:84 +#: lib/App/Sqitch/ItemFormatter.pm:85 msgid "Project: " msgstr "Progetto:" -#: lib/App/Sqitch/ItemFormatter.pm:85 +#: lib/App/Sqitch/ItemFormatter.pm:86 msgid "Email: " msgstr "Email:" -#: lib/App/Sqitch/ItemFormatter.pm:86 lib/App/Sqitch/ItemFormatter.pm:176 +#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:172 msgid "Requires: " msgstr "Richiede:" -#: lib/App/Sqitch/ItemFormatter.pm:87 lib/App/Sqitch/ItemFormatter.pm:187 +#: lib/App/Sqitch/ItemFormatter.pm:88 lib/App/Sqitch/ItemFormatter.pm:183 msgid "Conflicts:" msgstr "Conflitti:" -#: lib/App/Sqitch/ItemFormatter.pm:89 -#, fuzzy -msgid "No label passed to the _ format" -msgstr "Nessuna etichetta passata al formato _" - -#: lib/App/Sqitch/ItemFormatter.pm:93 +#: lib/App/Sqitch/ItemFormatter.pm:90 #, fuzzy, perl-brace-format msgid "Unknown label \"{label}\" passed to the _ format" msgstr "Etichetta \"{label}\" sconosciuta passata al formato _" -#: lib/App/Sqitch/ItemFormatter.pm:150 +#: lib/App/Sqitch/ItemFormatter.pm:146 #, perl-brace-format msgid "{color} is not a valid ANSI color" msgstr "{color} non Γ¨ un colore ANSI valido" -#: lib/App/Sqitch/ItemFormatter.pm:193 +#: lib/App/Sqitch/ItemFormatter.pm:189 #, perl-brace-format msgid "{attr} is not a valid change attribute" msgstr "{attr} non Γ¨ un attributo valido" -#: lib/App/Sqitch/ItemFormatter.pm:216 +#: lib/App/Sqitch/ItemFormatter.pm:212 #, perl-brace-format msgid "Unknown format code \"{code}\"" msgstr "Formato codice \"{code}\" sconosciuto" @@ -1410,8 +1445,8 @@ msgstr "" #: lib/App/Sqitch/Plan.pm:918 #, fuzzy, perl-brace-format msgid "" -"\"{name}\" is invalid: changes must not begin with punctuation, contain \"@" -"\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " +"\"{name}\" is invalid: changes must not begin with punctuation, contain " +"\"@\", \":\", \"#\", \"\\\", or blanks, or end in punctuation or digits " "following punctuation" msgstr "" "\"{name}\" non Γ¨ valido: le modifiche non devono iniziare con segni di " @@ -1479,7 +1514,7 @@ msgid "" " Use --chdir instead." msgstr "" -#: lib/App/Sqitch/Role/DBIEngine.pm:353 +#: lib/App/Sqitch/Role/DBIEngine.pm:365 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with NULL URI" @@ -1487,7 +1522,7 @@ msgstr "" "Non posso registrare \"{project}\" con l'URI {uri}: Γ¨ giΓ  esistente con URI " "NULL." -#: lib/App/Sqitch/Role/DBIEngine.pm:359 +#: lib/App/Sqitch/Role/DBIEngine.pm:371 #, perl-brace-format msgid "" "Cannot register \"{project}\" without URI: already exists with URI {uri}" @@ -1495,7 +1530,7 @@ msgstr "" "Non posso registrare \"{project}\" senza un URI: Γ¨ giΓ  esistente con URI " "{uri}." -#: lib/App/Sqitch/Role/DBIEngine.pm:365 +#: lib/App/Sqitch/Role/DBIEngine.pm:377 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: already exists with URI " @@ -1504,7 +1539,7 @@ msgstr "" "Non posso registrare \"{project}\" con URI {uri}: Γ¨ giΓ  esistente con URI " "{reg_uri}." -#: lib/App/Sqitch/Role/DBIEngine.pm:383 +#: lib/App/Sqitch/Role/DBIEngine.pm:395 #, perl-brace-format msgid "" "Cannot register \"{project}\" with URI {uri}: project \"{reg_proj}\" already " @@ -1513,6 +1548,13 @@ msgstr "" "Non posso registrare \"{project}\" con URI {uri}: il progetto \"{reg_proj}\" " "esiste giΓ  con l'URI specificato" +#: lib/App/Sqitch/Role/RevertDeployCommand.pm:129 +#, perl-brace-format +msgid "" +"\"{command}\" cannot be used in strict mode.\\nUse explicity revert and " +"deploy commands instead." +msgstr "" + #: lib/App/Sqitch/Role/TargetConfigCommand.pm:96 #, perl-brace-format msgid "Unknown directory name: {dirs}" diff --git a/t/add.t b/t/add.t index 231df72d..533cd13e 100644 --- a/t/add.t +++ b/t/add.t @@ -3,7 +3,7 @@ use strict; use warnings; use utf8; -use Test::More tests => 238; +use Test::More tests => 242; #use Test::More 'no_plan'; use App::Sqitch; use App::Sqitch::Target; @@ -440,6 +440,18 @@ BEGIN; COMMIT; EOF unlink $out; + + # Test with file name having a double extension + $out = file 'test-add', 'duplicate_extension_test.sql.sql'; + $add->_add('duplicate_extension_test.sql', $out, $tmpl, 'sqlite', 'add'); + is_deeply +MockOutput->get_info, [[__x 'Created {file}', file => $out ]], + 'Info should show $out created'; + is_deeply +MockOutput->get_warn, [[__x( + 'File {file} has a double extension of {ext}', + file => $out, + ext => 'sql', + )]], 'Should have warned about double extension'; + unlink $out; }; # First, test with Template::Tiny. @@ -459,7 +471,7 @@ $test_add->('Template::Tiny'); shift @INC; delete $INC{'Template.pm'}; SKIP: { - skip 'Template Toolkit not installed', 14 unless eval 'use Template; 1'; + skip 'Template Toolkit not installed', 16 unless eval 'use Template; 1'; $test_add->('Template Toolkit'); # Template Toolkit should throw an error on template syntax errors. diff --git a/t/check.t b/t/check.t index 18eeaa29..6fff6a35 100644 --- a/t/check.t +++ b/t/check.t @@ -281,7 +281,7 @@ is_deeply +MockOutput->get_warn, [[__x( # Make sure we get an exception for unknown args. throws_ok { $check->execute(qw(greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'check', 'Unknow arg ident should be "check"'; +is $@->ident, 'check', 'Unknown arg ident should be "check"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', @@ -291,7 +291,7 @@ is $@->message, __nx( throws_ok { $check->execute(qw(greg jon)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'check', 'Unknow args ident should be "check"'; +is $@->ident, 'check', 'Unknown args ident should be "check"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', diff --git a/t/checkout.t b/t/checkout.t old mode 100644 new mode 100755 index c88fe25d..73cd324c --- a/t/checkout.t +++ b/t/checkout.t @@ -282,6 +282,26 @@ CONFIG: { _params => [], _cx => [], }, 'Should have no_prompt true with -y'; + + # Should die in strict mode. + for my $cfg ( + ['revert.strict', 1], + ['checkout.strict', 1], + ) { + throws_ok { + $CLASS->configure(TestConfig->new(@{$ cfg})) + } 'App::Sqitch::X', "$cfg->[0] should die"; + is $@->ident, 'checkout', 'Strict err ident should be "checkout"'; + is $@->message, __x( + '"{command}" cannot be used in strict mode.\n'. + 'Use explicity revert and deploy commands instead.', + command => 'checkout', + ), 'Should have corect strict error message' + } + + lives_ok { $CLASS->configure( + TestConfig->new('revert.strict', 1, 'checkout.strict', 0) + ) } 'App::Sqitch::X'; } ############################################################################## @@ -583,7 +603,7 @@ is_deeply +MockOutput->get_info, [[__x( )]], 'Should have emitted info identifying the last common change'; # Did it revert? -is_deeply \@rev_args, [$checkout->default_target->plan->get('users')->id], +is_deeply \@rev_args, [$checkout->default_target->plan->get('users')->id, 1, undef], '"users" ID and 1 should be passed to the engine revert'; is_deeply \@rev_changes, [qw(roles users widgets)], 'Should have had the current changes for revision'; @@ -653,23 +673,23 @@ is_deeply +MockOutput->get_warn, [[__x( # Make sure we get an exception for unknown args. throws_ok { $checkout->execute(qw(main greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'checkout', 'Unknow arg ident should be "checkout"'; +is $@->ident, 'checkout', 'Unknown arg ident should be "checkout"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', 1, arg => 'greg', -), 'Should get an exeption for two unknown arg'; +), 'Should get an exception for two unknown arg'; throws_ok { $checkout->execute(qw(main greg widgets)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'checkout', 'Unknow args ident should be "checkout"'; +is $@->ident, 'checkout', 'Unknown args ident should be "checkout"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', 2, arg => 'greg, widgets', -), 'Should get an exeption for two unknown args'; +), 'Should get an exception for two unknown args'; # Should die for fatal, unknown, or confirmation errors. for my $spec ( diff --git a/t/command.t b/t/command.t index 140da2b9..7b79955f 100644 --- a/t/command.t +++ b/t/command.t @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010; use utf8; -use Test::More tests => 198; +use Test::More tests => 199; #use Test::More 'no_plan'; use Test::NoWarnings; use List::Util qw(first); @@ -131,6 +131,15 @@ DEBUG: { 'Should have sent error to debug'; } +############################################################################## +# Test ENGINES. +my $dir = Path::Class::Dir->new( + Path::Class::File->new($INC{"App/Sqitch.pm"})->dir, + qw(Sqitch Engine), +); +my @exp = sort grep { s/\.pm$// } map { $_->basename } $dir->children; +is_deeply [sort $CLASS->ENGINES], \@exp, 'ENGINES should include all engines'; + ############################################################################## # Test load(). ok $sqitch = App::Sqitch->new(config => $config), 'Load a sqitch object'; diff --git a/t/deploy.t b/t/deploy.t index 8ddcb5aa..6dddf2b2 100644 --- a/t/deploy.t +++ b/t/deploy.t @@ -320,7 +320,7 @@ for my $bad (qw(foo bad gar)) { # Make sure we get an exception for unknown args. throws_ok { $deploy->execute(qw(greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'deploy', 'Unknow arg ident should be "deploy"'; +is $@->ident, 'deploy', 'Unknown arg ident should be "deploy"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', @@ -330,7 +330,7 @@ is $@->message, __nx( throws_ok { $deploy->execute(qw(greg jon)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'deploy', 'Unknow args ident should be "deploy"'; +is $@->ident, 'deploy', 'Unknown args ident should be "deploy"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', diff --git a/t/engine.t b/t/engine.t old mode 100644 new mode 100755 index f923ab72..ee971371 --- a/t/engine.t +++ b/t/engine.t @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010; use utf8; -use Test::More tests => 769; +use Test::More tests => 775; # use Test::More 'no_plan'; use App::Sqitch; use App::Sqitch::Plan; @@ -14,6 +14,7 @@ use Test::Exception; use Test::NoWarnings; use Test::MockModule; use Test::MockObject::Extends; +use Test::Warn qw(warning_is); use Time::HiRes qw(sleep); use Locale::TextDomain qw(App-Sqitch); use App::Sqitch::X qw(hurl); @@ -34,7 +35,7 @@ BEGIN { delete $ENV{USER}; } -can_ok $CLASS, qw(load new name no_prompt run_deploy run_revert run_verify uri); +can_ok $CLASS, qw(load new name run_deploy run_revert run_verify uri); my ($is_deployed_tag, $is_deployed_change) = (0, 0); my @deployed_changes; @@ -281,7 +282,7 @@ $engine->seen; # Make sure it's checked on revert and verify. for my $meth (qw(revert verify)) { - throws_ok { $engine->$meth } 'App::Sqitch::X', "Should get error from $meth"; + throws_ok { $engine->$meth(undef, 1, 1) } 'App::Sqitch::X', "Should get error from $meth"; is $@->ident, 'engine', qq{$meth registry error ident should be "engine"}; is $@->message, __x( 'No registry found in {destination}. Have you ever deployed?', @@ -972,6 +973,12 @@ is_deeply $engine->seen, [ is $state->{script_hash}, $latest_change_id, 'The script hash should have been set to the change ID'; +# Have _no_registry return true. +$mock_engine->mock(_no_registry => 1); +ok $engine->_sync_plan, 'Sync the plan with no registry'; +is $plan->position, -1, 'Plan should start at position -1'; +$mock_engine->unmock('_no_registry'); + ############################################################################## # Test deploy. can_ok $CLASS, 'deploy'; @@ -1159,8 +1166,6 @@ is_deeply $engine->seen, [ ], 'Should have deployed to change 2'; is_deeply +MockOutput->get_info, [ [__x 'Deploying changes to {destination}', destination => $engine->destination ], - # [__ 'ok'], - # [__ 'ok'], ], 'Should have emitted deploy announcement and successes'; # Make sure we can deploy everything by change. @@ -1911,7 +1916,7 @@ $engine->plan($plan); # Start with no deployed IDs. @deployed_changes = (); -ok $engine->revert, +ok $engine->revert(undef, 1, 1), 'Should return success for no changes to revert'; is_deeply +MockOutput->get_info, [ [__ 'Nothing to revert (nothing deployed)'] @@ -1922,8 +1927,21 @@ is_deeply $engine->seen, [ ], 'It should only have called deployed_changes()'; is_deeply +MockOutput->get_info, [], 'Nothing should have been output'; +# Make sure deprecation warning happens. +warning_is { $engine->revert } + "Engine::revert() requires the `prompt` and `prompt_default` arguments.\n", + 'Should get warning omitting required arguments'; +is_deeply +MockOutput->get_info, [ + [__ 'Nothing to revert (nothing deployed)'] +], 'Should have notified that there is nothing to revert'; +is_deeply $engine->seen, [ + [lock_destination => []], + [deployed_changes => undef], +], 'It should only have called deployed_changes()'; +is_deeply +MockOutput->get_info, [], 'Nothing should have been output'; + # Try reverting to an unknown change. -throws_ok { $engine->revert('nonexistent') } 'App::Sqitch::X', +throws_ok { $engine->revert('nonexistent', 1, 1) } 'App::Sqitch::X', 'Revert should die on unknown change'; is $@->ident, 'revert', 'Should be another "revert" error'; is $@->message, __x( @@ -1939,7 +1957,7 @@ is_deeply $engine->seen, [ [lock_destination => []], ['change_id_for', { is_deeply +MockOutput->get_info, [], 'Nothing should have been output'; # Try reverting to an unknown change ID. -throws_ok { $engine->revert('8d77c5f588b60bc0f2efcda6369df5cb0177521d') } 'App::Sqitch::X', +throws_ok { $engine->revert('8d77c5f588b60bc0f2efcda6369df5cb0177521d', 1, 1) } 'App::Sqitch::X', 'Revert should die on unknown change ID'; is $@->ident, 'revert', 'Should be another "revert" error'; is $@->message, __x( @@ -1955,7 +1973,7 @@ is_deeply $engine->seen, [ [lock_destination => []], ['change_id_for', { is_deeply +MockOutput->get_info, [], 'Nothing should have been output'; # Revert an undeployed change. -throws_ok { $engine->revert('@alpha') } 'App::Sqitch::X', +throws_ok { $engine->revert('@alpha', 1, 1) } 'App::Sqitch::X', 'Revert should die on undeployed change'; is $@->ident, 'revert', 'Should be another "revert" error'; is $@->message, __x( @@ -1973,7 +1991,7 @@ is_deeply +MockOutput->get_info, [], 'Nothing should have been output'; # Revert to a point with no following changes. $offset_change = $changes[0]; push @resolved => $offset_change->id; -ok $engine->revert($changes[0]->id), +ok $engine->revert($changes[0]->id, 1, 1), 'Should return success for revert even with no changes'; is_deeply +MockOutput->get_info, [ [__x( @@ -1996,7 +2014,7 @@ is_deeply $engine->seen, [ ], 'Should have called change_id_for and deployed_changes_since'; # Revert with nothing deployed. -ok $engine->revert, +ok $engine->revert(undef, 1, 1), 'Should return success for known but undeployed change'; is_deeply +MockOutput->get_info, [ [__ 'Nothing to revert (nothing deployed)'] @@ -2033,7 +2051,7 @@ my @dbchanges; } @changes[0..3]; MockOutput->ask_yes_no_returns(1); -is $engine->revert, $engine, 'Revert all changes'; +is $engine->revert(undef, 1, 1), $engine, 'Revert all changes'; is_deeply $engine->seen, [ [lock_destination => []], [deployed_changes => undef], @@ -2060,6 +2078,11 @@ is_deeply +MockOutput->get_info_literal, [ [' - roles ..', '........', ' '], ], 'It should have said it was reverting all changes and listed them'; is_deeply +MockOutput->get_info, [ + [__ 'Would revert the following changes:'], + ['roles'], + ['users @alpha'], + ['widgets @beta'], + ['lolz'], [__ 'ok'], [__ 'ok'], [__ 'ok'], @@ -2068,7 +2091,7 @@ is_deeply +MockOutput->get_info, [ # Try with log-only. ok $engine->log_only(1), 'Enable log_only'; -ok $engine->revert(undef, 1), 'Revert all changes log-only'; +ok $engine->revert(undef, 1, 1), 'Revert all changes log-only'; delete @{ $_ }{qw(_path_segments _rework_tags)} for @dbchanges; # These need to be invisible. is_deeply $engine->seen, [ [lock_destination => []], @@ -2092,6 +2115,11 @@ is_deeply +MockOutput->get_info_literal, [ [' - roles ..', '........', ' '], ], 'It should have said it was reverting all changes and listed them'; is_deeply +MockOutput->get_info, [ + [__ 'Would revert the following changes:'], + ['roles'], + ['users @alpha'], + ['widgets @beta'], + ['lolz'], [__ 'ok'], [__ 'ok'], [__ 'ok'], @@ -2100,7 +2128,7 @@ is_deeply +MockOutput->get_info, [ # Should exit if the revert is declined. MockOutput->ask_yes_no_returns(0); -throws_ok { $engine->revert } 'App::Sqitch::X', 'Should abort declined revert'; +throws_ok { $engine->revert(undef, 1, 1) } 'App::Sqitch::X', 'Should abort declined revert'; is $@->ident, 'revert', 'Declined revert ident should be "revert"'; is $@->exitval, 1, 'Should have exited with value 1'; is $@->message, __ 'Nothing reverted', 'Should have exited with proper message'; @@ -2115,13 +2143,17 @@ is_deeply +MockOutput->get_ask_yes_no, [ ), 1], ], 'Should have prompt to revert all changes'; is_deeply +MockOutput->get_info, [ + [__ 'Would revert the following changes:'], + ['roles'], + ['users @alpha'], + ['widgets @beta'], + ['lolz'], ], 'It should have emitted nothing else'; # Revert all changes with no prompt. MockOutput->ask_yes_no_returns(1); $engine->log_only(0); -$engine->no_prompt(1); -ok $engine->revert, 'Revert all changes with no prompt'; +ok $engine->revert(undef, 0, 1), 'Revert all changes with no prompt'; is_deeply $engine->seen, [ [lock_destination => []], [deployed_changes => undef], @@ -2148,6 +2180,11 @@ is_deeply +MockOutput->get_info, [ 'Reverting all changes from {destination}', destination => $engine->destination, )], + [__ 'Will revert the following changes:'], + ['roles'], + ['users @alpha'], + ['widgets @beta'], + ['lolz'], [__ 'ok'], [__ 'ok'], [__ 'ok'], @@ -2155,11 +2192,10 @@ is_deeply +MockOutput->get_info, [ ], 'And the revert successes should be emitted'; # Now just revert to an earlier change. -$engine->no_prompt(0); $offset_change = $dbchanges[1]; push @resolved => $offset_change->id; @deployed_changes = @deployed_changes[2..3]; -ok $engine->revert('@alpha'), 'Revert to @alpha'; +ok $engine->revert('@alpha', 1, 1), 'Revert to @alpha'; delete $dbchanges[1]->{_rework_tags}; # These need to be invisible. is_deeply $engine->seen, [ @@ -2185,6 +2221,9 @@ is_deeply +MockOutput->get_info_literal, [ [' - widgets @beta ..', '', ' '], ], 'Output should show what it reverts to'; is_deeply +MockOutput->get_info, [ + [__ 'Would revert the following changes:'], + ['widgets @beta'], + ['lolz'], [__ 'ok'], [__ 'ok'], ], 'And the revert successes should be emitted'; @@ -2192,7 +2231,7 @@ is_deeply +MockOutput->get_info, [ MockOutput->ask_yes_no_returns(0); $offset_change = $dbchanges[1]; push @resolved => $offset_change->id; -throws_ok { $engine->revert('@alpha') } 'App::Sqitch::X', +throws_ok { $engine->revert('@alpha', 1, 1) } 'App::Sqitch::X', 'Should abort declined revert to @alpha'; is $@->ident, 'revert:confirm', 'Declined revert ident should be "revert:confirm"'; is $@->exitval, 1, 'Should have exited with value 1'; @@ -2211,17 +2250,19 @@ is_deeply +MockOutput->get_ask_yes_no, [ ), 1], ], 'Should have prompt to revert to @alpha'; is_deeply +MockOutput->get_info, [ -], 'It should have emitted nothing else'; + [__ 'Would revert the following changes:'], + ['widgets @beta'], + ['lolz'], +], 'Should emit a detailed prompt.'; # Try to revert just the last change with no prompt MockOutput->ask_yes_no_returns(1); -$engine->no_prompt(1); my $rev_file = $dbchanges[-1]->revert_file; # Grab before deleting _rework_tags. my $rtags = delete $dbchanges[-1]->{_rework_tags}; # These need to be invisible. $offset_change = $dbchanges[-1]; push @resolved => $offset_change->id; @deployed_changes = $deployed_changes[-1]; -ok $engine->revert('@HEAD^'), 'Revert to @HEAD^'; +ok $engine->revert('@HEAD^', 0, 1), 'Revert to @HEAD^'; is_deeply $engine->seen, [ [lock_destination => []], [change_id_for => { change_id => undef, change => '', tag => 'HEAD', project => 'sql' }], @@ -2241,6 +2282,8 @@ is_deeply +MockOutput->get_info, [ destination => $engine->destination, change => $dbchanges[-1]->format_name_with_tags, )], + [__ 'Will revert the following changes:'], + ['lolz'], [__ 'ok'], ], 'And the header and "ok" should be emitted'; diff --git a/t/exasol.t b/t/exasol.t index 18fa2c39..a4df70e6 100644 --- a/t/exasol.t +++ b/t/exasol.t @@ -363,6 +363,7 @@ DBI: { $DBI::errstr = 'object foo not found'; ok $exa->_no_table_error, 'Should now have table error'; ok $exa->_no_column_error, 'Should now have no column error'; + ok !$exa->_unique_error, 'Unique constraints not supported by Exasol'; } is_deeply [$exa->_limit_offset(8, 4)], @@ -450,6 +451,7 @@ DBIEngineTest->run( is $dbh->selectcol_arrayref('SELECT current_schema')->[0], uc($reg2), 'The Sqitch schema should be the current schema'; }, + no_unique => 1, ); done_testing; diff --git a/t/firebird.t b/t/firebird.t index 1378ed8f..a5759410 100644 --- a/t/firebird.t +++ b/t/firebird.t @@ -369,7 +369,7 @@ DBH: { 'Should get undef from change_id_for when no useful params'; } -# Make sure defaul_client croaks when it finds no client. +# Make sure default_client croaks when it finds no client. FSPEC: { # Give it an invalid fbsql file to find. my $tmpdir = tempdir(CLEANUP => 1); diff --git a/t/item_formatter.t b/t/item_formatter.t index 709d156a..f71b9c75 100644 --- a/t/item_formatter.t +++ b/t/item_formatter.t @@ -3,7 +3,7 @@ use strict; use warnings; use utf8; -use Test::More tests => 158; +use Test::More tests => 172; #use Test::More 'no_plan'; use App::Sqitch; use Locale::TextDomain qw(App-Sqitch); @@ -99,6 +99,9 @@ for my $spec ( ['%o', { project => 'foo' }, 'foo'], ['%o', { project => 'bar' }, 'bar'], + ['%F', { deploy_file => 'deploy/change_file.sql' }, 'deploy/change_file.sql'], + ['%F', { deploy_file => 'deploy/change_file_with_tag@tag.sql' }, 'deploy/change_file_with_tag@tag.sql'], + ['%c', { committer_name => 'larry', committer_email => 'larry@example.com' }, 'larry '], ['%{n}c', { committer_name => 'damian' }, 'damian'], ['%{name}c', { committer_name => 'chip' }, 'chip'], @@ -129,6 +132,8 @@ for my $spec ( ['%{|}t', { tags => [] }, '' ], ['%{|}t', { tags => ['@foo'] }, ' @foo' ], ['%{|}t', { tags => ['@foo', '@bar'] }, ' @foo|@bar' ], + ['%{0}t', { tags => ['@foo', '@bar'] }, ' @foo0@bar' ], + ['%{}t', { tags => ['@foo', '@bar'] }, ' @foo@bar' ], ['%T', { tags => [] }, '' ], ['%T', { tags => ['@foo'] }, ' (@foo)' ], @@ -136,6 +141,8 @@ for my $spec ( ['%{|}T', { tags => [] }, '' ], ['%{|}T', { tags => ['@foo'] }, ' (@foo)' ], ['%{|}T', { tags => ['@foo', '@bar'] }, ' (@foo|@bar)' ], + ['%{0}T', { tags => ['@foo', '@bar'] }, ' (@foo0@bar)' ], + ['%{}T', { tags => ['@foo', '@bar'] }, ' (@foo@bar)' ], ['%r', { requires => [] }, '' ], ['%r', { requires => ['foo'] }, ' foo' ], @@ -143,6 +150,8 @@ for my $spec ( ['%{|}r', { requires => [] }, '' ], ['%{|}r', { requires => ['foo'] }, ' foo' ], ['%{|}r', { requires => ['foo', 'bar'] }, ' foo|bar' ], + ['%{0}r', { requires => ['foo', 'bar'] }, ' foo0bar' ], + ['%{}r', { requires => ['foo', 'bar'] }, ' foobar' ], ['%R', { requires => [] }, '' ], ['%R', { requires => ['foo'] }, __('Requires: ') . " foo\n" ], @@ -150,6 +159,8 @@ for my $spec ( ['%{|}R', { requires => [] }, '' ], ['%{|}R', { requires => ['foo'] }, __('Requires: ') . " foo\n" ], ['%{|}R', { requires => ['foo', 'bar'] }, __('Requires: ') . " foo|bar\n" ], + ['%{0}R', { requires => ['foo', 'bar'] }, __('Requires: ') . " foo0bar\n" ], + ['%{}R', { requires => ['foo', 'bar'] }, __('Requires: ') . " foobar\n" ], ['%x', { conflicts => [] }, '' ], ['%x', { conflicts => ['foo'] }, ' foo' ], @@ -157,6 +168,8 @@ for my $spec ( ['%{|}x', { conflicts => [] }, '' ], ['%{|}x', { conflicts => ['foo'] }, ' foo' ], ['%{|}x', { conflicts => ['foo', 'bax'] }, ' foo|bax' ], + ['%{0}x', { conflicts => ['foo', 'bax'] }, ' foo0bax' ], + ['%{}x', { conflicts => ['foo', 'bax'] }, ' foobax' ], ['%X', { conflicts => [] }, '' ], ['%X', { conflicts => ['foo'] }, __('Conflicts:') . " foo\n" ], @@ -164,6 +177,8 @@ for my $spec ( ['%{|}X', { conflicts => [] }, '' ], ['%{|}X', { conflicts => ['foo'] }, __('Conflicts:') . " foo\n" ], ['%{|}X', { conflicts => ['foo', 'bar'] }, __('Conflicts:') . " foo|bar\n" ], + ['%{0}X', { conflicts => ['foo', 'bar'] }, __('Conflicts:') . " foo0bar\n" ], + ['%{}X', { conflicts => ['foo', 'bar'] }, __('Conflicts:') . " foobar\n" ], ['%{yellow}C', {}, '' ], ['%{:event}C', { event => 'deploy' }, '' ], diff --git a/t/lib/DBIEngineTest.pm b/t/lib/DBIEngineTest.pm index 1385305f..c6168e39 100644 --- a/t/lib/DBIEngineTest.pm +++ b/t/lib/DBIEngineTest.pm @@ -331,12 +331,11 @@ sub run { is_deeply all_changes($engine), [[ $change->id, 'users', 'engine', 'User roles', $sqitch->user_name, $sqitch->user_email, $change->planner_name, $change->planner_email, - ]],'A record should have been inserted into the changes table'; + ]], 'A record should have been inserted into the changes table'; is_deeply get_dependencies($engine, $change->id), [], 'Should have no dependencies'; is_deeply [ $engine->changes_requiring_change($change) ], [], 'Change should not be required'; - my @event_data = ([ 'deploy', $change->id, @@ -1605,19 +1604,55 @@ sub run { ###################################################################### # Add a reworked change. - ok my $rev_change = $plan->rework( name => 'users' ), 'Rework change "users"'; + my $name = $change2->name; + ok my $rev_change = $plan->rework( name => $name ), qq{Rework change "$name"}; + $_->resolved_id( $engine->change_id_for_depend($_) ) for $rev_change->requires; + + # Should get an error for identical deploy script except on engines + # that don't support unique constraints. + is $rev_change->script_hash, $change2->script_hash, + 'It should have the same script hash'; + unless ($p{no_unique}) { + throws_ok { $engine->log_deploy_change($rev_change) } 'App::Sqitch::X', + 'Should die on unchanged rework deploy script'; + # diag "ERR: ", ($DBI::err // ''), " (", ($DBI::state // ''), "): ", $DBI::errstr // ''; + is $@->ident, 'engine', 'Mode should be "engine"'; + is $@->message, __x( + 'Cannot log change "{change}": The deploy script is not unique', + change => $name, + ), 'And it should report the script is not unique'; + + # Make sure log_deploy_change dies on any other error. + MOCKPROJECT: { + my $engine_mocker = Test::MockModule->new(ref $engine); + $engine_mocker->mock(_unique_error => 0); + throws_ok { $engine->log_deploy_change($rev_change) } 'App::Sqitch::X', + 'Should re-throw if not a unique erorr'; + is $@->ident, $DBI::state, 'Mode should be the error state'; + is $@->message, $DBI::errstr, 'Should not have the underlying DB error'; + } + } + + # Make a temporary copy of the deploy file so we can restore it later. my $deploy_file = $rev_change->deploy_file; my $tmp_dir = dir( tempdir CLEANUP => 1 ); - $deploy_file->copy_to($tmp_dir); + my $backup = $tmp_dir->file($deploy_file->basename); + ok $deploy_file->copy_to($backup), 'Back up deploy file'; + + # Modify the file so that its hash digest will vary. + delete $rev_change->{script_hash}; my $fh = $deploy_file->opena or die "Cannot open $deploy_file: $!\n"; try { say $fh '-- Append line to reworked script so it gets a new SHA-1 hash'; close $fh; - $_->resolved_id( $engine->change_id_for_depend($_) ) for $rev_change->requires; - ok $engine->log_deploy_change($rev_change), 'Deploy the reworked change'; + isnt $rev_change->script_hash, $change2->script_hash, + 'It should no longer have the same script hash'; + lives_ok { + ok $engine->log_deploy_change($rev_change), 'Deploy the reworked change'; + } 'The deploy should not fail'; } finally { # Restore the reworked script. - $tmp_dir->file( $deploy_file->basename )->copy_to($deploy_file); + $backup->copy_to($deploy_file); }; # Make sure that change_id_for() chokes on the dupe. @@ -1625,7 +1660,7 @@ sub run { my $sqitch_mocker = Test::MockModule->new(ref $sqitch); my @args; $sqitch_mocker->mock(vent => sub { shift; push @args => \@_ }); - throws_ok { $engine->change_id_for( change => 'users') } 'App::Sqitch::X', + throws_ok { $engine->change_id_for( change => $name) } 'App::Sqitch::X', 'Should die on ambiguous change spec'; is $@->ident, 'engine', 'Mode should be "engine"'; is $@->message, __ 'Change Lookup Failed', @@ -1633,36 +1668,42 @@ sub run { is_deeply \@args, [ [__x( 'Change "{change}" is ambiguous. Please specify a tag-qualified change:', - change => 'users', + change => $name, )], [ ' * ', $rev_change->format_name . '@HEAD' ], - [ ' * ', $change->format_tag_qualified_name ], + [ ' * ', $change2->format_tag_qualified_name ], ], 'Should have vented output for lookup failure'; # But it should work okay if we ask for the first ID. - ok my $id = $engine->change_id_for(change => 'users', first => 1), + ok my $id = $engine->change_id_for(change => $name, first => 1), 'Should get ID for first of ambiguous change spec'; - is $id, $change->id, 'Should now have first change id'; + is $id, $change2->id, 'Should now have first change id'; } - is $engine->change_id_for( change => 'users', tag => 'alpha'), $change->id, + is $engine->change_id_for( change => $change->name, tag => 'alpha'), + $change->id, 'change_id_for() should find the tag-qualified change ID'; - is $engine->change_id_for( change => 'users', tag => 'HEAD'), $rev_change->id, + is $engine->change_id_for( change => $name, tag => 'HEAD'), + $rev_change->id, 'change_id_for() should find the reworked change ID @HEAD'; + ###################################################################### # Tag and Rework the change again. ok $plan->tag(name => 'theta'), 'Tag the plan "theta"'; ok $engine->log_new_tags($rev_change), 'Log new tag'; - ok my $rev_change2 = $plan->rework( name => 'users' ), - 'Rework change "users" again'; + ok my $rev_change2 = $plan->rework( name => $name ), + qq{Rework change "$name" again}; $fh = $deploy_file->opena or die "Cannot open $deploy_file: $!\n"; try { say $fh '-- Append another line to reworked script for a new SHA-1 hash'; close $fh; $_->resolved_id( $engine->change_id_for_depend($_) ) for $rev_change2->requires; - ok $engine->log_deploy_change($rev_change2), 'Deploy the reworked change'; + lives_ok { + ok $engine->log_deploy_change($rev_change2), + 'Deploy the reworked change'; + } 'Should not die deploying the reworked change'; } finally { # Restore the reworked script. $tmp_dir->file( $deploy_file->basename )->copy_to($deploy_file); @@ -1671,18 +1712,19 @@ sub run { # make sure that change_id_for is still good with things. for my $spec ( [ - 'alpha instance of change', - { change => 'users', tag => 'alpha' }, - $change->id, + + 'beta instance of change', + { change => $name, tag => 'beta' }, + $change2->id, ], [ 'HEAD instance of change', - { change => 'users', tag => 'HEAD' }, + { change => $name, tag => 'HEAD' }, $rev_change2->id, ], [ 'second instance of change by tag', - { change => 'users', tag => 'theta' }, + { change => $name, tag => 'theta' }, $rev_change->id, ], ) { diff --git a/t/lib/upgradable_registries/vertica.sql b/t/lib/upgradable_registries/vertica.sql index dc7b8754..5ff2ddf4 100644 --- a/t/lib/upgradable_registries/vertica.sql +++ b/t/lib/upgradable_registries/vertica.sql @@ -3,26 +3,26 @@ CREATE SCHEMA :"registry"; COMMENT ON SCHEMA :"registry" IS 'Sqitch database deployment metadata v1.0.'; CREATE TABLE :"registry".releases ( - version FLOAT PRIMARY KEY, + version FLOAT PRIMARY KEY ENABLED, installed_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(), installer_name VARCHAR(1024) NOT NULL, installer_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".releases IS 'Sqitch registry releases.'; +COMMENT ON TABLE :"registry".releases IS 'Sqitch registry releases.'; CREATE TABLE :"registry".projects ( - project VARCHAR(1024) PRIMARY KEY ENCODING AUTO, - uri VARCHAR(1024) NULL UNIQUE, + project VARCHAR(1024) PRIMARY KEY ENABLED ENCODING AUTO, + uri VARCHAR(1024) NULL UNIQUE ENABLED, created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(), creator_name VARCHAR(1024) NOT NULL, creator_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".projects IS 'Sqitch projects deployed to this database.'; +COMMENT ON TABLE :"registry".projects IS 'Sqitch projects deployed to this database.'; CREATE TABLE :"registry".changes ( - change_id CHAR(40) PRIMARY KEY ENCODING AUTO, + change_id CHAR(40) PRIMARY KEY ENABLED ENCODING AUTO, change VARCHAR(1024) NOT NULL, project VARCHAR(1024) NOT NULL REFERENCES :"registry".projects(project), note VARCHAR(65000) NOT NULL DEFAULT '', @@ -34,10 +34,10 @@ CREATE TABLE :"registry".changes ( planner_email VARCHAR(1024) NOT NULL ); -COMMENT ON TABLE :"registry".changes IS 'Tracks the changes currently deployed to the database.'; +COMMENT ON TABLE :"registry".changes IS 'Tracks the changes currently deployed to the database.'; CREATE TABLE :"registry".tags ( - tag_id CHAR(40) PRIMARY KEY ENCODING AUTO, + tag_id CHAR(40) PRIMARY KEY ENABLED ENCODING AUTO, tag VARCHAR(1024) NOT NULL, project VARCHAR(1024) NOT NULL REFERENCES :"registry".projects(project), change_id CHAR(40) NOT NULL REFERENCES :"registry".changes(change_id), @@ -48,20 +48,20 @@ CREATE TABLE :"registry".tags ( planned_at TIMESTAMPTZ NOT NULL, planner_name VARCHAR(1024) NOT NULL, planner_email VARCHAR(1024) NOT NULL, - UNIQUE(project, tag) + UNIQUE(project, tag) ENABLED ); -COMMENT ON TABLE :"registry".tags IS 'Tracks the tags currently applied to the database.'; +COMMENT ON TABLE :"registry".tags IS 'Tracks the tags currently applied to the database.'; CREATE TABLE :"registry".dependencies ( change_id CHAR(40) NOT NULL REFERENCES :"registry".changes(change_id), type VARCHAR(8) NOT NULL ENCODING AUTO, dependency VARCHAR(2048) NOT NULL, dependency_id CHAR(40) NULL REFERENCES :"registry".changes(change_id), - PRIMARY KEY (change_id, dependency) + PRIMARY KEY (change_id, dependency) ENABLED ); -COMMENT ON TABLE :"registry".dependencies IS 'Tracks the currently satisfied dependencies.'; +COMMENT ON TABLE :"registry".dependencies IS 'Tracks the currently satisfied dependencies.'; CREATE TABLE :"registry".events ( event VARCHAR(6) NOT NULL ENCODING AUTO, @@ -78,7 +78,7 @@ CREATE TABLE :"registry".events ( planned_at TIMESTAMPTZ NOT NULL, planner_name VARCHAR(1024) NOT NULL, planner_email VARCHAR(1024) NOT NULL, - PRIMARY KEY (change_id, committed_at) + PRIMARY KEY (change_id, committed_at) ENABLED ); -COMMENT ON TABLE :"registry".events IS 'Contains full history of all deployment events.'; +COMMENT ON TABLE :"registry".events IS 'Contains full history of all deployment events.'; diff --git a/t/mysql.t b/t/mysql.t index bf34c720..33ce8aed 100644 --- a/t/mysql.t +++ b/t/mysql.t @@ -135,14 +135,14 @@ ok $mysql = $CLASS->new(sqitch => $sqitch, target => $target), is $mysql->client, '/path/to/mysql', 'client should be as configured'; is $mysql->uri->as_string, 'db:mysql://me:pwd@foo.com/widgets', 'URI should be as configured'; -is $mysql->target->name, 'db:mysql://me:@foo.com/widgets', +like $mysql->target->name, qr{^db:mysql://me:?\@foo\.com/widgets$}, 'target name should be the URI without the password'; -is $mysql->destination, 'db:mysql://me:@foo.com/widgets', +like $mysql->destination, qr{^db:mysql://me:?\@foo\.com/widgets$}, 'destination should be the URI without the password'; is $mysql->registry, 'meta', 'registry should be as configured'; is $mysql->registry_uri->as_string, 'db:mysql://me:pwd@foo.com/meta', 'Sqitch DB URI should be the same as uri but with DB name "meta"'; -is $mysql->registry_destination, 'db:mysql://me:@foo.com/meta', +like $mysql->registry_destination, qr{^db:mysql://me:?\@foo\.com/meta$}, 'registry_destination should be the sqitch DB URL without the password'; is_deeply [$mysql->mysql], [ '/path/to/mysql', diff --git a/t/oracle.t b/t/oracle.t index a5aabd22..587a1d40 100644 --- a/t/oracle.t +++ b/t/oracle.t @@ -113,6 +113,7 @@ use Try::Tiny; use App::Sqitch; use App::Sqitch::Target; use App::Sqitch::Plan; +use File::Temp 'tempdir'; use lib 't/lib'; use DBIEngineTest; use TestConfig; @@ -142,11 +143,36 @@ is $ora->name, 'Oracle', 'Name should be "Oracle"'; my $client = 'sqlplus' . (App::Sqitch::ISWIN ? '.exe' : ''); is $ora->client, $client, 'client should default to sqlplus'; ORACLE_HOME: { - local $ENV{ORACLE_HOME} = '/foo/bar'; + my $iswin = App::Sqitch::ISWIN || $^O eq 'cygwin'; + my $cli = 'sqlplus' . ($iswin ? '.exe' : ''); + + # Start with no ORACLE_HOME. my $target = App::Sqitch::Target->new(sqitch => $sqitch); isa_ok my $ora = $CLASS->new(sqitch => $sqitch, target => $target), $CLASS; - is $ora->client, Path::Class::file('/foo/bar', $client)->stringify, - 'client should use $ORACLE_HOME'; + is $ora->client, $cli, 'client should default to sqlplus'; + + # Put client in ORACLE_HOME. + my $tmpdir = tempdir(CLEANUP => 1); + my $tmp = Path::Class::Dir->new("$tmpdir"); + my $sqlplus = $tmp->file($cli); + $sqlplus->touch; + chmod '0755', $sqlplus unless $iswin; + + local $ENV{ORACLE_HOME} = "$tmpdir"; + $target = App::Sqitch::Target->new(sqitch => $sqitch); + isa_ok $ora = $CLASS->new(sqitch => $sqitch, target => $target), $CLASS; + is $ora->client, $sqlplus, 'client should use $ORACLE_HOME'; + + # ORACLE_HOME/bin takes precedence. + my $bin = Path::Class::Dir->new("$tmpdir", 'bin'); + $bin->mkpath; + $sqlplus = $bin->file($cli); + $sqlplus->touch; + chmod '0755', $sqlplus unless $iswin; + + $target = App::Sqitch::Target->new(sqitch => $sqitch); + isa_ok $ora = $CLASS->new(sqitch => $sqitch, target => $target), $CLASS; + is $ora->client, $sqlplus, 'client should use $ORACLE_HOME/bin'; } is $ora->registry, '', 'registry default should be empty'; @@ -243,7 +269,7 @@ $target = App::Sqitch::Target->new( sqitch => $sqitch, uri => URI::db->new('db:oracle:secure_user_tns.tpg'), ); -is $target->uri->dbi_dsn, 'dbi:Oracle:secure_user_tns.tpg', +like $target->uri->dbi_dsn, qr{^dbi:Oracle:(?:service_name=)?secure_user_tns\.tpg$}, 'Database-only URI should produce proper DSN'; isa_ok $ora = $CLASS->new( sqitch => $sqitch, @@ -263,7 +289,7 @@ $target = App::Sqitch::Target->new( sqitch => $sqitch, uri => URI::db->new('db:oracle://:@/wallet_tns_name'), ); -is $target->uri->dbi_dsn, 'dbi:Oracle:wallet_tns_name', +like $target->uri->dbi_dsn, qr{dbi:Oracle:(?:service_name=)?wallet_tns_name$}, 'Database and double-slash URI should produce proper DSN'; isa_ok $ora = $CLASS->new( sqitch => $sqitch, diff --git a/t/pg.t b/t/pg.t index a3be87a7..18ec9495 100644 --- a/t/pg.t +++ b/t/pg.t @@ -345,15 +345,15 @@ DBI: { q{ARRAY(SELECT * FROM UNNEST( array_agg(%1$s ORDER BY %1$s) ) a WHERE a IS NOT NULL)}, 'Should use ORDER BY in listagg_format on v9.2'; - $dbh->{pg_server_version} = 80400; + $dbh->{pg_server_version} = 90000; is $pg->_listagg_format, q{ARRAY(SELECT * FROM UNNEST( array_agg(%1$s ORDER BY %1$s) ) a WHERE a IS NOT NULL)}, - 'Should use ORDER BY in listagg_format on v8.4'; + 'Should use ORDER BY in listagg_format on v9.0'; - $dbh->{pg_server_version} = 80300; + $dbh->{pg_server_version} = 80400; is $pg->_listagg_format, q{ARRAY(SELECT * FROM UNNEST( array_agg(%s) ) a WHERE a IS NOT NULL)}, - 'Should not use ORDER BY in listagg_format on v8.3'; + 'Should not use ORDER BY in listagg_format on v8.4'; } ############################################################################## diff --git a/t/plan_cmd.t b/t/plan_cmd.t index a7925042..77586168 100644 --- a/t/plan_cmd.t +++ b/t/plan_cmd.t @@ -3,7 +3,7 @@ use strict; use warnings; use utf8; -use Test::More tests => 232; +use Test::More tests => 234; # use Test::More 'no_plan'; use App::Sqitch; use Locale::TextDomain qw(App-Sqitch); @@ -19,7 +19,7 @@ use MockOutput; use TestConfig; use LC; -local $ENV{TZ} = 'America/Sao_Paolo'; +local $ENV{TZ} = 'Asia/Tokyo'; my $CLASS = 'App::Sqitch::Command::plan'; require_ok $CLASS; @@ -313,6 +313,9 @@ for my $spec ( ['%o', { project => 'foo' }, 'foo'], ['%o', { project => 'bar' }, 'bar'], + ['%F', { deploy_file => 'deploy/change_file.sql' }, 'deploy/change_file.sql'], + ['%F', { deploy_file => 'deploy/change_file_with_tag@tag.sql' }, 'deploy/change_file_with_tag@tag.sql'], + ['%p', { planner_name => 'larry', planner_email => 'larry@example.com' }, 'larry '], ['%{n}p', { planner_name => 'damian' }, 'damian'], ['%{name}p', { planner_name => 'chip' }, 'chip'], @@ -564,6 +567,7 @@ my $fmt_params = { change_id => $change->id, change => $change->name, note => $change->note, + deploy_file => $change->deploy_file, tags => [ map { $_->format_name } $change->tags ], requires => [ map { $_->as_string } $change->requires ], conflicts => [ map { $_->as_string } $change->conflicts ], @@ -579,8 +583,6 @@ is_deeply +MockOutput->get_page, [ ], 'The event should have been paged'; # Set attributes and add more events. -my $change2 = $plan->change_at(1); -push @changes => $change, $change2; isa_ok $cmd = $CLASS->new( sqitch => $sqitch, event => 'deploy', @@ -592,7 +594,11 @@ isa_ok $cmd = $CLASS->new( reverse => 1, headers => 0, ), $CLASS, 'plan with attributes'; +$plan = $cmd->default_target->plan; +$change = $plan->change_at(0); +my $change2 = $plan->change_at(1); +push @changes => $change, $change2; ok $cmd->execute, 'Execute plan with attributes'; is_deeply $search_args, [ operation => 'deploy', @@ -609,6 +615,7 @@ my $fmt_params2 = { change_id => $change2->id, change => $change2->name, note => $change2->note, + deploy_file => $change2->deploy_file, tags => [ map { $_->format_name } $change2->tags ], requires => [ map { $_->as_string } $change2->requires ], conflicts => [ map { $_->as_string } $change2->conflicts ], @@ -626,8 +633,9 @@ is_deeply +MockOutput->get_page, [ my $cfg = $CLASS->configure( $config, { format => 'raw' } ); ok $cmd = $CLASS->new( sqitch => $sqitch, %{ $cfg } ), 'Create command with raw format'; -push @changes => $plan->changes; +$plan = $cmd->default_target->plan; +push @changes => $plan->changes; ok $cmd->execute, 'Execute plan with all changes'; is_deeply +MockOutput->get_page, [ ['# ', __x 'Project: {project}', project => $plan->project ], @@ -639,6 +647,7 @@ is_deeply +MockOutput->get_page, [ change_id => $_->id, change => $_->name, note => $_->note, + deploy_file => $_->deploy_file, tags => [ map { $_->format_name } $_->tags ], requires => [ map { $_->as_string } $_->requires ], conflicts => [ map { $_->as_string } $_->conflicts ], @@ -653,7 +662,9 @@ isa_ok $cmd = $CLASS->new( sqitch => $sqitch, format => '%Z', ), $CLASS, 'plan with bad format'; +$plan = $cmd->default_target->plan; +$change = $plan->change_at(0); push @changes, $change; throws_ok { $cmd->execute } 'App::Sqitch::X', 'Should get an exception for a bad format code'; diff --git a/t/rebase.t b/t/rebase.t old mode 100644 new mode 100755 index 40268afa..bbd743de --- a/t/rebase.t +++ b/t/rebase.t @@ -295,6 +295,26 @@ CONFIG: { _params => [], _cx => [], }, 'Should have no_prompt true with -y'; + + # Should die in strict mode. + for my $cfg ( + ['revert.strict', 1], + ['rebase.strict', 1], + ) { + throws_ok { + $CLASS->configure(TestConfig->new(@{$ cfg})) + } 'App::Sqitch::X', "$cfg->[0] should die"; + is $@->ident, 'rebase', 'Strict err ident should be "rebase"'; + is $@->message, __x( + '"{command}" cannot be used in strict mode.\n'. + 'Use explicity revert and deploy commands instead.', + command => 'rebase', + ), 'Should have corect strict error message' + } + + lives_ok { $CLASS->configure( + TestConfig->new('revert.strict', 1, 'rebase.strict', 0) + ) } 'App::Sqitch::X'; } ############################################################################## @@ -504,10 +524,13 @@ $config->replace( 'core.top_dir' => dir(qw(t sql))->stringify, 'core.plan_file' => file(qw(t sql sqitch.plan))->stringify, ); -$rebase = $CLASS->new( sqitch => $sqitch); ############################################################################## # Test execute(). +$rebase = $CLASS->new( + sqitch => $sqitch, + %{ $CLASS->configure($config, {}) }, +); my $mock_cmd = Test::MockModule->new($CLASS); my $orig_method; $mock_cmd->mock(parse_args => sub { @@ -522,9 +545,8 @@ is_deeply \@dep_args, [undef, 'all'], 'undef, and "all" should be passed to the engine deploy'; is_deeply \@vars, [[], []], 'No vars should have been passed through to the engine'; -is_deeply \@rev_args, ['@alpha'], +is_deeply \@rev_args, ['@alpha', 1, 1], '"@alpha" should be passed to the engine revert'; -ok !$target->engine->no_prompt, 'Engine should prompt'; ok !$target->engine->log_only, 'Engine should no be log only'; is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(), 'The lock timeout should be set to the default'; @@ -535,11 +557,10 @@ is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; ok $rebase->execute('db:sqlite:yow'), 'Execute with target'; is_deeply \@dep_args, [undef, 'all'], 'undef, and "all" should be passed to the engine deploy'; -is_deeply \@rev_args, [undef], +is_deeply \@rev_args, [undef, 1, 1], 'undef should be passed to the engine revert'; is_deeply \@vars, [[], []], 'No vars should have been passed through to the engine'; -ok !$target->engine->no_prompt, 'Engine should prompt'; ok !$target->engine->log_only, 'Engine should no be log only'; is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(), 'The lock timeout should be set to the default'; @@ -551,11 +572,10 @@ is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; ok $rebase->execute('db:sqlite:yow', 'widgets'), 'Execute with onto and target'; is_deeply \@dep_args, [undef, 'all'], 'undef, and "all" should be passed to the engine deploy'; -is_deeply \@rev_args, ['widgets'], +is_deeply \@rev_args, ['widgets', 1, 1], '"widgets" should be passed to the engine revert'; is_deeply \@vars, [[], []], 'No vars should have been passed through to the engine'; -ok !$target->engine->no_prompt, 'Engine should prompt'; ok !$target->engine->log_only, 'Engine should no be log only'; is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(), 'The lock timeout should be set to the default'; @@ -568,11 +588,10 @@ ok $rebase->execute('db:sqlite:yow', 'roles', 'widgets'), 'Execute with three args'; is_deeply \@dep_args, ['widgets', 'all'], '"widgets", and "all" should be passed to the engine deploy'; -is_deeply \@rev_args, ['roles'], +is_deeply \@rev_args, ['roles', 1, 1], '"roles" should be passed to the engine revert'; is_deeply \@vars, [[], []], 'No vars should have been passed through to the engine'; -ok !$target->engine->no_prompt, 'Engine should prompt'; ok !$target->engine->log_only, 'Engine should no be log only'; is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(), 'The lock timeout should be set to the default'; @@ -584,7 +603,7 @@ is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; ok $rebase->execute, 'Execute'; is_deeply \@dep_args, [undef, 'all'], 'undef and "all" should be passed to the engine deploy'; -is_deeply \@rev_args, [undef], +is_deeply \@rev_args, [undef, 1, 1], 'undef and = should be passed to the engine revert'; is_deeply \@vars, [[], []], 'No vars should have been passed through to the engine'; @@ -595,6 +614,7 @@ $common_ancestor_id = '42'; isa_ok $rebase = $CLASS->new( target => 'db:sqlite:lolwut', no_prompt => 1, + prompt_accept => 1, log_only => 1, lock_timeout => 30, verify => 1, @@ -605,16 +625,16 @@ isa_ok $rebase = $CLASS->new( @vars = @dep_args = @rev_args = (); ok $rebase->execute, 'Execute again'; is $target->name, 'db:sqlite:lolwut', 'Target name should be from option'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok $target->engine->log_only, 'Engine should be log_only'; is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30'; ok $target->engine->with_verify, 'Engine should verify'; -is_deeply \@rev_args, [$common_ancestor_id], 'the common ancestor id should be passed to the engine revert'; +is_deeply \@rev_args, [$common_ancestor_id, '', 1], 'the common ancestor id should be passed to the engine revert'; # Mix it up with options. isa_ok $rebase = $CLASS->new( target => 'db:sqlite:lolwut', no_prompt => 1, + prompt_accept => 1, log_only => 1, lock_timeout => 30, verify => 1, @@ -629,13 +649,12 @@ isa_ok $rebase = $CLASS->new( @vars = @dep_args = @rev_args = (); ok $rebase->execute, 'Execute again'; is $target->name, 'db:sqlite:lolwut', 'Target name should be from option'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok $target->engine->log_only, 'Engine should be log_only'; is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30'; ok $target->engine->with_verify, 'Engine should verify'; is_deeply \@dep_args, ['bar', 'tag'], '"bar", "tag", and 1 should be passed to the engine deploy'; -is_deeply \@rev_args, ['foo'], '"foo" and 1 should be passed to the engine revert'; +is_deeply \@rev_args, ['foo', '', 1], '"foo" should be passed to the engine revert'; is @vars, 2, 'Variables should have been passed to the engine twice'; is_deeply { @{ $vars[0] } }, { hey => 'there' }, 'The revert vars should have been passed first'; @@ -648,13 +667,12 @@ is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; ok $rebase->execute('db:sqlite:yow', 'roles', 'widgets'), 'Execute with three args'; is $target->name, 'db:sqlite:lolwut', 'Target name should be from option'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok $target->engine->log_only, 'Engine should be log_only'; is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30'; ok $target->engine->with_verify, 'Engine should verify'; is_deeply \@dep_args, ['bar', 'tag'], '"bar", "tag", and 1 should be passed to the engine deploy'; -is_deeply \@rev_args, ['foo'], '"foo" and 1 should be passed to the engine revert'; +is_deeply \@rev_args, ['foo', '', 1], '"foo" should be passed to the engine revert'; is @vars, 2, 'Variables should have been passed to the engine twice'; is_deeply { @{ $vars[0] } }, { hey => 'there' }, 'The revert vars should have been passed first'; @@ -672,23 +690,23 @@ is_deeply +MockOutput->get_warn, [[__x( # Make sure we get an exception for unknown args. throws_ok { $rebase->execute(qw(greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'rebase', 'Unknow arg ident should be "rebase"'; +is $@->ident, 'rebase', 'Unknown arg ident should be "rebase"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', 1, arg => 'greg', -), 'Should get an exeption for two unknown arg'; +), 'Should get an exception for two unknown arg'; throws_ok { $rebase->execute(qw(greg jon)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'rebase', 'Unknow args ident should be "rebase"'; +is $@->ident, 'rebase', 'Unknown args ident should be "rebase"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', 2, arg => 'greg, jon', -), 'Should get an exeption for two unknown args'; +), 'Should get an exception for two unknown args'; # If nothing is deployed, or we are already at the revert target, the revert # should be skipped. diff --git a/t/revert.t b/t/revert.t old mode 100644 new mode 100755 index 2f4c9bb7..54dd4087 --- a/t/revert.t +++ b/t/revert.t @@ -262,18 +262,17 @@ $orig_method = $mock_cmd->original('parse_args'); # Pass the change. ok $revert->execute('@alpha'), 'Execute to "@alpha"'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok !$target->engine->log_only, 'Engine should not be log_only'; is $target->engine->lock_timeout, App::Sqitch::Engine::default_lock_timeout(), 'The engine should have the default lock_timeout'; -is_deeply \@args, ['@alpha'], +is_deeply \@args, ['@alpha', '', undef], '"@alpha" should be passed to the engine'; is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; # Pass nothing. @args = (); ok $revert->execute, 'Execute'; -is_deeply \@args, [undef], +is_deeply \@args, [undef, '', undef], 'undef should be passed to the engine'; is_deeply {@vars}, { }, 'No vars should have been passed through to the engine'; @@ -281,27 +280,24 @@ is_deeply +MockOutput->get_warn, [], 'Should still have no warnings'; # Pass the target. ok $revert->execute('db:sqlite:hi'), 'Execute to target'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok !$target->engine->log_only, 'Engine should not be log_only'; -is_deeply \@args, [undef], +is_deeply \@args, [undef, '', undef], 'undef" should be passed to the engine'; is $target->name, 'db:sqlite:hi', 'Target name should be as passed'; is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; # Pass them both! ok $revert->execute('db:sqlite:lol', 'widgets'), 'Execute with change and target'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok !$target->engine->log_only, 'Engine should not be log_only'; -is_deeply \@args, ['widgets'], +is_deeply \@args, ['widgets', '', undef], '"widgets" should be passed to the engine'; is $target->name, 'db:sqlite:lol', 'Target name should be as passed'; is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; # And reverse them. ok $revert->execute('db:sqlite:lol', 'widgets'), 'Execute with target and change'; -ok $target->engine->no_prompt, 'Engine should be no_prompt'; ok !$target->engine->log_only, 'Engine should not be log_only'; -is_deeply \@args, ['widgets'], +is_deeply \@args, ['widgets', '', undef], '"widgets" should be passed to the engine'; is $target->name, 'db:sqlite:lol', 'Target name should be as passed'; is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; @@ -318,10 +314,9 @@ isa_ok $revert = $CLASS->new( @args = (); ok $revert->execute, 'Execute again'; -ok !$target->engine->no_prompt, 'Engine should not be no_prompt'; ok $target->engine->log_only, 'Engine should be log_only'; is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30'; -is_deeply \@args, ['foo'], +is_deeply \@args, ['foo', 1, undef], '"foo" and 1 should be passed to the engine'; is_deeply {@vars}, { foo => 'bar', one => 1 }, 'Vars should have been passed through to the engine'; @@ -330,10 +325,9 @@ is_deeply +MockOutput->get_warn, [], 'Should have no warnings'; # Try also passing the target and change. ok $revert->execute('db:sqlite:lol', '@alpha'), 'Execute with options and args'; -ok !$target->engine->no_prompt, 'Engine should not be no_prompt'; ok $target->engine->log_only, 'Engine should be log_only'; is $target->engine->lock_timeout, 30, 'The lock timeout should be set to 30'; -is_deeply \@args, ['foo'], +is_deeply \@args, ['foo', 1, undef], '"foo" and 1 should be passed to the engine'; is_deeply {@vars}, { foo => 'bar', one => 1 }, 'Vars should have been passed through to the engine'; @@ -349,7 +343,7 @@ is_deeply +MockOutput->get_warn, [[__x( # Make sure we get an exception for unknown args. throws_ok { $revert->execute(qw(greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'revert', 'Unknow arg ident should be "revert"'; +is $@->ident, 'revert', 'Unknown arg ident should be "revert"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', @@ -359,7 +353,7 @@ is $@->message, __nx( throws_ok { $revert->execute(qw(greg jon)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'revert', 'Unknow args ident should be "revert"'; +is $@->ident, 'revert', 'Unknown args ident should be "revert"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', @@ -378,6 +372,37 @@ $common_ancestor_id = 42; @args = (); ok $revert->execute, 'Execute again'; is $target->name, 'db:sqlite:welp', 'Target name should be from option'; -is_deeply \@args, [$common_ancestor_id], 'the common ancestor id should be passed to the engine revert'; +is_deeply \@args, [$common_ancestor_id, 1, undef], 'the common ancestor id should be passed to the engine revert'; + +# Test strict mode +$config = TestConfig->new( + 'core.engine' => 'sqlite', + 'core.top_dir' => dir(qw(t sql))->stringify, + 'core.plan_file' => file(qw(t sql sqitch.plan))->stringify, + 'revert.strict' => 1 +); +$sqitch = App::Sqitch->new(config => $config); +isa_ok $revert = $CLASS->new( + sqitch => $sqitch, + target => 'db:sqlite:welp', + no_prompt => 1, +), $CLASS, 'new revert with target'; +throws_ok { $revert->execute } + 'App::Sqitch::X', + 'In strict mode, cannot revert without a specified change'; +is $@->ident, 'revert:strict', + 'No change in strict mode ident should be "revert:strict"'; +is $@->message, __ 'Must specify a target revision in strict mode', + 'Should have expected message for no changes in strict mode error'; + +# Too many targets also fatal in strict mode. +$ENV{FOO}= 1; +throws_ok { $revert->execute('@alpha', '@beta') } + 'App::Sqitch::X', + 'In strict mode, too many targets is fatal'; +is $@->ident, 'revert:strict', + 'Too many targets ident should be "revert:strict"'; +is $@->message, __ 'Too many changes specified', + 'Should have expected message for too many targets error'; done_testing; diff --git a/t/rework.t b/t/rework.t index a1fa7536..beaf3bcb 100644 --- a/t/rework.t +++ b/t/rework.t @@ -3,8 +3,8 @@ use strict; use warnings; use utf8; -use Test::More tests => 234; -#use Test::More 'no_plan'; +use Test::More tests => 256; +# use Test::More 'no_plan'; use App::Sqitch; use Locale::TextDomain qw(App-Sqitch); use Test::Exception; @@ -396,8 +396,116 @@ MOCKSHELL: { MockOutput->get_debug; # empty debug. }; -# Make sure a configuration with multiple plans works. +# Make sure we properly handle a reworked directory. $mock_plan->unmock('plan'); +REWORKED_DIR: { + my $dstring = $test_dir->stringify; + remove_tree $dstring; + make_path $dstring; + END { remove_tree $dstring if -e $dstring }; + chdir $dstring; + + my $conf = file 'rework_dir.conf'; + $conf->spew(join "\n", + '[core]', + 'reworked_dir = _reworked', + 'engine = sqlite', + ); + + file('sqitch.plan')->spew(join "\n", + '%project=rework', '', + 'widgets 2012-07-16T17:25:07Z anna ', + 'gadgets 2012-07-16T18:25:07Z anna ', + '@foo 2012-07-16T17:24:07Z julie ', '', + ); + + # Create the scripts. + my (@change, @reworked); + for my $type (qw(deploy revert verify)) { + my $dir = dir $type; + $dir->mkpath; + my $script = $dir->file('gadgets.sql'); + $script->spew("-- $dir gadgets"); + push @change => $script; + push @reworked => dir('_reworked', $type)->file('gadgets@foo.sql'); + } + + # We should have the change scripts but not yet reworked. + file_exists_ok $_ for @change; + file_not_exists_ok '_reworked'; + file_not_exists_ok $_ for @reworked; + + my $config = TestConfig->from(local => $conf); + my $sqitch = App::Sqitch->new(config => $config); + ok $rework = $CLASS->new( + sqitch => $sqitch, + note => ['Testing reworked_dir'], + template_directory => dir->parent->subdir(qw(etc templates)) + ), 'Create another rework with custom reworked_dir config'; + + # Let's do this thing! + ok $rework->execute('gadgets'), 'Rework change "gadgets"'; + my $target = $rework->default_target; + ok my $head = $target->plan->get('gadgets@HEAD'), + "Get gadgets\@HEAD from the plan"; + ok my $foo = $target->plan->get('gadgets@foo'), + "Get gadgets\@foo from the plan"; + cmp_ok $head->id, 'ne', $foo->id, + "The two gadgets should be different changes"; + + # All the files should exist, now. + file_exists_ok '_reworked'; + file_exists_ok $_ for @change, @reworked; + + is_deeply \%request_params, { + for => __ 'rework', + scripts => \@change, + }, 'Should have listed scripts in the note prompt'; + + # Should have info output. + is_deeply +MockOutput->get_info, [ + [__x( + 'Added "{change}" to {file}.', + change => 'gadgets [gadgets@foo]', + file => $target->plan_file, + )], + [__n( + 'Modify this file as appropriate:', + 'Modify these files as appropriate:', + 3, + )], + map { [" * $_"] } @change, + ], 'And the info message should suggest editing the old files'; + # use Data::Dump; ddx +MockOutput->get_debug; + is_deeply +MockOutput->get_debug, [ + [' ', __x 'Created {file}', file => dir qw(_reworked deploy) ], + [__x( + 'Copied {src} to {dest}', + src => $change[0], + dest => $reworked[0], + )], + [' ', __x 'Created {file}', file => dir qw(_reworked revert) ], + [__x( + 'Copied {src} to {dest}', + src => $change[1], + dest => $reworked[1], + )], + [' ', __x 'Created {file}', file => dir qw(_reworked verify) ], + [__x( + 'Copied {src} to {dest}', + src => $change[2], + dest => $reworked[2], + )], + [__x( + 'Copied {src} to {dest}', + src => $change[0], + dest => $change[1], + )], + ], 'Debug should show directory creation and file copying'; + chdir File::Spec->updir; +} + +# Make sure a configuration with multiple plans works. MULTIPLAN: { my $dstring = $test_dir->stringify; remove_tree $dstring; @@ -584,7 +692,6 @@ MULTIPLAN: { my %targets = map { $_->engine_key => $_ } App::Sqitch::Target->all_targets(sqitch => $sqitch); is keys %targets, 3, 'Should still have three targets'; - my $name = 'gadgets@foo'; for my $ekey(qw(pg mysql)) { my $target = $targets{$ekey}; ok my $head = $target->plan->get('gadgets@HEAD'), diff --git a/t/snowflake.t b/t/snowflake.t index bec9e42e..e0001ad8 100644 --- a/t/snowflake.t +++ b/t/snowflake.t @@ -322,8 +322,8 @@ is $snow->registry, 'meta', 'registry should be as configured'; is $snow->uri->as_string, 'db:snowflake://fred:hi@foo.snowflakecomputing.com/try?warehouse=foo;role=yup', 'URI should be as configured with full domain name'; -is $snow->destination, - 'db:snowflake://fred:@foo.snowflakecomputing.com/try?warehouse=foo;role=yup', +like $snow->destination, + qr{^db:snowflake://fred:?\@foo\.snowflakecomputing\.com/try\?warehouse=foo;role=yup$}, 'Destination should omit password'; is $snow->client, '/path/to/snowsql', 'client should be as configured'; @@ -354,6 +354,7 @@ DBI: { $DBI::state = '42703'; ok !$snow->_no_table_error, 'Should again have no table error'; ok $snow->_no_column_error, 'Should now have no column error'; + ok !$snow->_unique_error, 'Unique constraints not supported by Snowflake'; } is_deeply [$snow->_limit_offset(8, 4)], @@ -514,6 +515,22 @@ ok my $now = App::Sqitch::DateTime->now, 'Construct a datetime object'; is $snow->_char2ts($now), $now->as_string(format => 'iso'), 'Should get ISO output from _char2ts'; +############################################################################## +# Test _quote_ident. +# Mock DBI method. +sub quote_identifier { qq{"$_[1]"} } + +ok my $quote_ident = $CLASS->can('_quote_ident'), 'Should have _quote_ident sub'; +# https://docs.snowflake.com/en/sql-reference/identifiers-syntax#unquoted-identifiers +for my $ident (qw(foo FOO _xXx _ a id1 My$Thing), "foo") { + is $quote_ident->(__PACKAGE__, $ident), $ident, "Should not quote β€œ$ident”"; +} + +for my $ident (qw(my.thing 1go $foo ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€), 'hi there', qq{'thing'}) { + is $quote_ident->(__PACKAGE__, $ident), quote_identifier(__PACKAGE__, $ident), + "Should quote β€œ$ident”"; +} + ############################################################################## # Can we do live tests? my $dbh; @@ -574,7 +591,7 @@ DBIEngineTest->run( uc($reg2), 'The Sqitch schema should be the current schema'; }, add_second_format => 'dateadd(second, 1, %s)', - + no_unique => 1, ); done_testing; diff --git a/t/sqlite.t b/t/sqlite.t index ce18fc45..07a83b2f 100644 --- a/t/sqlite.t +++ b/t/sqlite.t @@ -51,7 +51,7 @@ is $sqlite->registry_destination, $sqlite->registry_uri->as_string, # Pretend for now that we always have a valid SQLite. my $mock_sqitch = Test::MockModule->new(ref $sqitch); -my $sqlite_version = '3.7.12 2012-04-03 19:43:07 86b8481be7e76cccc92d14ce762d21bfb69504af'; +my $sqlite_version = '3.8.6 2014-08-15 19:43:07 86b8481be7e76cccc92d14ce762d21bfb69504af'; $mock_sqitch->mock(capture => sub { return $sqlite_version }); my @std_opts = ( @@ -70,10 +70,10 @@ my $tmp_dir = Path::Class::dir( tempdir CLEANUP => 1 ); my $have_sqlite = try { $sqlite->use_driver }; if ($have_sqlite) { # We have DBD::SQLite. - # Find out if it's built with SQLite >= 3.7.11. + # Find out if it's built with SQLite >= 3.8.6. my $dbh = DBI->connect('DBI:SQLite:'); my @v = split /[.]/ => $dbh->{sqlite_version}; - $have_sqlite = $v[0] > 3 || ($v[0] == 3 && ($v[1] > 7 || ($v[1] == 7 && $v[2] >= 11))); + $have_sqlite = $v[0] > 3 || ($v[0] == 3 && ($v[1] > 8 || ($v[1] == 8 && $v[2] >= 6))); unless ($have_sqlite) { # We have DBD::SQLite, but it is too old. Make sure we complain about that. isa_ok $sqlite = $CLASS->new( @@ -83,7 +83,7 @@ if ($have_sqlite) { throws_ok { $sqlite->dbh } 'App::Sqitch::X', 'Should get an error for old SQLite'; is $@->ident, 'sqlite', 'Unsupported SQLite error ident should be "sqlite"'; is $@->message, __x( - 'Sqitch requires SQLite 3.7.11 or later; DBD::SQLite was built with {version}', + 'Sqitch requires SQLite 3.8.6 or later; DBD::SQLite was built with {version}', version => $dbh->{sqlite_version} ), 'Unsupported SQLite error message should be correct'; } @@ -157,7 +157,7 @@ is $sqlite->destination, 'noext', 'Destination should be configured target name'; is $sqlite->registry_uri->as_string, 'db:sqlite://x:foo@/path/to/registry.db', 'registry_uri should fall back on config wth extension'; -is $sqlite->registry_destination, 'db:sqlite://x:@/path/to/registry.db', +like $sqlite->registry_destination, qr{^db:sqlite://x:?\@/path/to/registry\.db$}, 'Registry target should be configured registry_uri without password'; # Try a registry with an absolute path. diff --git a/t/verify.t b/t/verify.t index fe76a73c..d0967cd1 100644 --- a/t/verify.t +++ b/t/verify.t @@ -281,7 +281,7 @@ is_deeply +MockOutput->get_warn, [[__x( # Make sure we get an exception for unknown args. throws_ok { $verify->execute(qw(greg)) } 'App::Sqitch::X', 'Should get an exception for unknown arg'; -is $@->ident, 'verify', 'Unknow arg ident should be "verify"'; +is $@->ident, 'verify', 'Unknown arg ident should be "verify"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', @@ -291,7 +291,7 @@ is $@->message, __nx( throws_ok { $verify->execute(qw(greg jon)) } 'App::Sqitch::X', 'Should get an exception for unknown args'; -is $@->ident, 'verify', 'Unknow args ident should be "verify"'; +is $@->ident, 'verify', 'Unknown args ident should be "verify"'; is $@->message, __nx( 'Unknown argument "{arg}"', 'Unknown arguments: {arg}', diff --git a/t/vertica.t b/t/vertica.t index 4f56cdb8..3b42a582 100644 --- a/t/vertica.t +++ b/t/vertica.t @@ -217,7 +217,8 @@ is_deeply \@capture, [$vta->vsql, qw(foo bar baz)], 'Command should be passed to capture()'; ok $vta->_probe(qw(hi there)), 'Call _probe'; -is_deeply \@probe, [$vta->vsql, qw(hi there)]; +is_deeply \@probe, [$vta->vsql, qw(hi there)], + 'Should have expected arguments to _probe'; # Without password. $target = App::Sqitch::Target->new( sqitch => $sqitch ); @@ -236,8 +237,9 @@ ok $vta->_capture(qw(foo bar baz)), 'Call _capture again'; is_deeply \@capture, [$vta->vsql, qw(foo bar baz)], 'Command should be passed to capture() again'; -ok $vta->_probe(qw(go there)), 'Call _probe'; -is_deeply \@probe, [$vta->vsql, qw(go there)]; +ok $vta->_probe(qw(go there)), 'Call _probe again'; +is_deeply \@probe, [$vta->vsql, qw(go there)], + 'Should again have expected arguments to _probe'; ############################################################################## # Test file and handle running. diff --git a/xt/release.md b/xt/release.md index 66ad92e0..f7a4171a 100644 --- a/xt/release.md +++ b/xt/release.md @@ -6,7 +6,7 @@ use the `$VERSION` environment variable for consistency. The assumption is that it's set to the new version being released, e.g., ``` sh -export VERSION=1.3.1 +export VERSION=1.4.0 ``` Preparation @@ -40,7 +40,7 @@ First, update the sources so that everything is up-to-date. * Update copyright dates if a year has turned over since the last release: ``` sh - grep -ril copyright . | xargs perl -i -pe "s/-2022/-$(date +%Y)/g" + grep -ril copyright . | xargs perl -i -pe "s/-2023/-$(date +%Y)/g" ``` * Make a build and run `xt/dependency_report`: @@ -51,13 +51,13 @@ First, update the sources so that everything is up-to-date. ``` Review the build-time dependency list it outputs to ensure that they are - well and truly build-time-only. Also, check the runtime list to ensure that - they are runtime-only. And finally, review the overlapping list to ensure - that all of the items there are used at runtime. If it all checks out and - looks reasonable, copy the list of build-time-only dependencies into the - `__DATA__` section of `inc/Menlo/Sqitch.pm` and commit. This allows the - `./Build bundle` command to remove any build-only dependencies from the - bundle. + well and truly build-time-only. Copy the lists of dependencies into the + `__DATA__` section of `inc/Menlo/Sqitch.pm` and `git diff` to inspect the + changes. Check the runtime list to ensure that they are runtime-only, and + review the overlapping list to ensure that all of the items there are used + at runtime. Commit the changes if it all checks out and looks reasonable. + This allows the `./Build bundle` command to remove any build-only + dependencies from the bundle. * Add any new dependencies to `dist/sqitch.spec` and add a new entry to the top of the `%changelog` section for the new version. @@ -213,15 +213,15 @@ Finishing Up Time to get things started for the next version. Switch back to the `develop` branch, merge `main`, and change the version to a pre-release version. For -example, if you've just released `v1.2.0`, change the version to `v1.2.1-dev`. +example, if you've just released `v1.4.0`, change the version to `v1.4.1-dev`. ``` sh git checkout develop git merge main -perl -i -pe 's/^(version\s*=).+/$1 v1.3.1-dev/' dist.ini -perl -i -pe 's{(App/Sqitch version).+}{$1 v1.3.1-dev}' README.md -perl -i -pe 's/(Project-Id-Version: App-Sqitch)[^\\n]+/$1 v1.3.1-dev/' po/App-Sqitch.pot -perl -i -pe 's/(Version:\s*).+/${1}1.3.1-dev/' dist/sqitch.spec +perl -i -pe 's/^(version\s*=).+/$1 v1.4.1-dev/' dist.ini +perl -i -pe 's{(App/Sqitch version).+}{$1 v1.4.1-dev}' README.md +perl -i -pe 's/(Project-Id-Version: App-Sqitch)[^\\n]+/$1 v1.4.1-dev/' po/App-Sqitch.pot +perl -i -pe 's/(Version:\s*).+/${1}1.4.1-dev/' dist/sqitch.spec ``` Also add a line for the new version (without the pre-release part) to the top of diff --git a/xt/release/pod-spelling.t b/xt/release/pod-spelling.t index da090446..eb200151 100644 --- a/xt/release/pod-spelling.t +++ b/xt/release/pod-spelling.t @@ -4,6 +4,11 @@ use strict; use Test::More; use Test::Spelling; +# Suppress `Wide character in print`, which is emitted because +# Pod::Spelling::invalid_words_in sets no encoding $handle. Would go away with: +# open my $handle, '>:utf8', \$document; +$SIG{__WARN__} = sub { warn @_ if $_[0] !~ /^Wide character in print/ }; + add_stopwords(); all_pod_files_spelling_ok();