From 71ed858508e350aa304278ece867f54bd0814921 Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Fri, 29 Dec 2023 19:00:22 -0500 Subject: [PATCH] Use locale pragma instead of POSIX::set_locale() The Pragma is more likely to do the right thing, as confirmed by new tests, which fail when using `setlocale` and now succeed with `use locale`. The tests, in `xt/locale`, include compiled locale dictionaries (`*.mo` files) with a single message for the tested languages. This is in contrast to the released locale dictionaries, which are generated at release time but not stored in the repository. Update the `os.yml` and `perl.yml` workflows, which run all tests including the new locale tests, to install the required locales on Linux and to set the full `runs-on:` image name in the matrix (in response to shogo82148/actions-setup-perl#1699). Also remove the installation of an older version of Locale::TextDomain from those workflows, since gflohr/libintl-perl#7 has been fixed and released. While at it, upgrade to `actions/checkout@v4` in all workflows and use `runner.os` instead of `matrix.os` in conditionals. --- .github/workflows/cockroach.yml | 2 +- .github/workflows/coverage.yml | 2 +- .github/workflows/exasol.yml | 2 +- .github/workflows/firebird.yml | 2 +- .github/workflows/mysql.yml | 2 +- .github/workflows/oracle.yml | 2 +- .github/workflows/os.yml | 18 +++---- .github/workflows/perl.yml | 14 +++--- .github/workflows/pg.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/snowflake.yml | 2 +- .github/workflows/sqlite.yml | 2 +- .github/workflows/vertica.yml | 2 +- .github/workflows/yugabyte.yml | 2 +- .gitignore | 3 +- Changes | 3 ++ bin/sqitch | 11 +---- t/sqitch | 10 +--- .../de_DE/LC_MESSAGES/App-Sqitch.mo | Bin 0 -> 209 bytes .../fr_FR/LC_MESSAGES/App-Sqitch.mo | Bin 0 -> 212 bytes .../it_IT/LC_MESSAGES/App-Sqitch.mo | Bin 0 -> 207 bytes xt/locale/README.md | 45 ++++++++++++++++++ xt/locale/po/de_DE.po | 6 +++ xt/locale/po/fr_FR.po | 6 +++ xt/locale/po/it_IT.po | 6 +++ xt/locale/test-cli.t | 36 ++++++++++++++ 26 files changed, 136 insertions(+), 46 deletions(-) create mode 100644 xt/locale/LocaleData/de_DE/LC_MESSAGES/App-Sqitch.mo create mode 100644 xt/locale/LocaleData/fr_FR/LC_MESSAGES/App-Sqitch.mo create mode 100644 xt/locale/LocaleData/it_IT/LC_MESSAGES/App-Sqitch.mo create mode 100644 xt/locale/README.md create mode 100644 xt/locale/po/de_DE.po create mode 100644 xt/locale/po/fr_FR.po create mode 100644 xt/locale/po/it_IT.po create mode 100644 xt/locale/test-cli.t diff --git a/.github/workflows/cockroach.yml b/.github/workflows/cockroach.yml index a6087cac3..6466785b3 100644 --- a/.github/workflows/cockroach.yml +++ b/.github/workflows/cockroach.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Start CockroachDB run: docker run -d -p 26257:26257 cockroachdb/cockroach:latest-v${{ matrix.version }} start-single-node --insecure - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b433912a1..500bc8eb4 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,7 +49,7 @@ jobs: 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@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.github/workflows/exasol.yml b/.github/workflows/exasol.yml index d10db9d22..1f33fd39a 100644 --- a/.github/workflows/exasol.yml +++ b/.github/workflows/exasol.yml @@ -20,7 +20,7 @@ jobs: ports: [ 8563 ] options: --privileged steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/exasol.sh - name: Setup Perl diff --git a/.github/workflows/firebird.yml b/.github/workflows/firebird.yml index 36a5541a4..de7c120ed 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@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/firebird.sh - name: Setup Perl diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 14cb78ac6..03a7beecf 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -39,7 +39,7 @@ jobs: ports: [ 3306 ] options: --health-cmd="healthcheck.sh --innodb_initialized || mysqladmin ping --protocol=tcp" --health-interval=5s --health-timeout=2s --health-retries=3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/mysql.sh - name: Setup Perl diff --git a/.github/workflows/oracle.yml b/.github/workflows/oracle.yml index 186501eb3..ea8487ace 100644 --- a/.github/workflows/oracle.yml +++ b/.github/workflows/oracle.yml @@ -40,7 +40,7 @@ jobs: --health-timeout 10s --health-retries 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/oracle.sh - name: Setup Perl diff --git a/.github/workflows/os.yml b/.github/workflows/os.yml index 6293bb68e..5ecf1d417 100644 --- a/.github/workflows/os.yml +++ b/.github/workflows/os.yml @@ -12,27 +12,29 @@ jobs: strategy: matrix: include: - - { icon: 🐧, os: ubuntu, name: Linux } - - { icon: 🍎, os: macos, name: macOS } - - { icon: 🪟, os: windows, name: Windows } + - { icon: 🐧, on: ubuntu-latest, name: Linux } + - { icon: 🍎, on: macos-latest, name: macOS } + - { icon: 🪟, on: windows-latest, name: Windows } name: ${{ matrix.icon }} ${{ matrix.name }} - runs-on: ${{ matrix.os }}-latest + runs-on: ${{ matrix.on }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: latest } - run: perl -V + - if: runner.os == 'Linux' + name: Install Apt Packages + run: sudo apt-get install -qq aspell-en language-pack-fr language-pack-en language-pack-de language-pack-it - name: Cache CPAN Modules uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} - run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends ExtUtils::MakeMaker List::MoreUtils::XS - # Remove Locale::TextDomain if https://github.com/gflohr/libintl-perl/issues/7 fixed and released. - - if: ${{ matrix.os == 'windows' }} - run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends Encode Win32::Console::ANSI Win32API::Net Win32::Locale Win32::ShellQuote DateTime::TimeZone::Local::Win32 Locale::TextDomain@1.31 + - if: runner.os == 'Windows' + run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends Encode Win32::Console::ANSI Win32API::Net Win32::Locale Win32::ShellQuote DateTime::TimeZone::Local::Win32 - 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 Test::Spelling Test::Pod Test::Pod::Coverage - name: prove diff --git a/.github/workflows/perl.yml b/.github/workflows/perl.yml index 22ddac38e..110aa8681 100644 --- a/.github/workflows/perl.yml +++ b/.github/workflows/perl.yml @@ -11,28 +11,30 @@ jobs: Perl: strategy: matrix: - os: [[🐧, ubuntu], [🍎, macos], [🪟, windows]] + os: [[🐧, ubuntu-latest], [🍎, macos-latest], [🪟, windows-latest]] 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 + runs-on: ${{ matrix.os[1] }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 with: { perl-version: "${{ matrix.perl }}" } - run: perl -V + - if: runner.os == 'Linux' + name: Install Apt Packages + run: sudo apt-get install -qq language-pack-fr language-pack-en language-pack-de language-pack-it - name: Cache CPAN Modules uses: actions/cache@v3 with: path: local key: perl-${{ steps.perl.outputs.perl-hash }} - # Remove Locale::TextDomain if https://github.com/gflohr/libintl-perl/issues/7 fixed and released. - - if: ${{ matrix.os[1] == 'windows' }} - run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends Encode Win32::Console::ANSI Win32API::Net Win32::Locale Win32::ShellQuote DateTime::TimeZone::Local::Win32 Locale::TextDomain@1.31 + - if: runner.os == 'Windows' + run: cpm install --verbose --show-build-log-on-failure --no-test --with-recommends Encode Win32::Console::ANSI Win32API::Net Win32::Locale Win32::ShellQuote DateTime::TimeZone::Local::Win32 - 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 Test::Spelling Test::Pod Test::Pod::Coverage - name: prove diff --git a/.github/workflows/pg.yml b/.github/workflows/pg.yml index c97c11ba7..39a81739f 100644 --- a/.github/workflows/pg.yml +++ b/.github/workflows/pg.yml @@ -15,7 +15,7 @@ jobs: name: 🐘 Postgres ${{ matrix.pg }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f5a1c1a0..f27f3336c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,7 +10,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - name: Check out the repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.github/workflows/snowflake.yml b/.github/workflows/snowflake.yml index 7dc089c56..45ddd26cc 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@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/snowflake.sh - name: Setup Perl diff --git a/.github/workflows/sqlite.yml b/.github/workflows/sqlite.yml index 4c0b758d1..12e1f4c16 100644 --- a/.github/workflows/sqlite.yml +++ b/.github/workflows/sqlite.yml @@ -16,7 +16,7 @@ jobs: name: 💡 SQLite ${{ matrix.sqlite }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.github/workflows/vertica.yml b/.github/workflows/vertica.yml index b524bbd3c..5b734dfbd 100644 --- a/.github/workflows/vertica.yml +++ b/.github/workflows/vertica.yml @@ -27,7 +27,7 @@ jobs: image: ${{ matrix.image }}:${{ matrix.version }} ports: [ 5433 ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Clients run: .github/ubuntu/vertica.sh - name: Setup Perl diff --git a/.github/workflows/yugabyte.yml b/.github/workflows/yugabyte.yml index 9524be9c2..34c886e38 100644 --- a/.github/workflows/yugabyte.yml +++ b/.github/workflows/yugabyte.yml @@ -34,7 +34,7 @@ jobs: uses: jameshartig/yugabyte-db-action@master with: yb_image_tag: "${{ matrix.tag }}" - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Perl id: perl uses: shogo82148/actions-setup-perl@v1 diff --git a/.gitignore b/.gitignore index 8033e00ee..a3efe757b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,8 @@ /_rpmbuild /target .build/ -*.mo .al /latest_changes.md /local/ +/LocaleData/ +/lib/LocaleData/ diff --git a/Changes b/Changes index a3fa86e31..a0a5e75c6 100644 --- a/Changes +++ b/Changes @@ -22,6 +22,9 @@ Revision history for Perl extension App::Sqitch (#795)! - Fixed Oracle and Firebird test failures due to incorrect use of `chmod`. Thanks to Slaven Rezić for the report and the fix (#807)! + - Updated the locale configuration to fix issues in more recent versions + of Perl, and added tests to ensure that the sqitch CLI executes and + properly emits localized messages. 1.4.0 2023-08-01T23:37:30Z - Fixed Snowflake warehouse and role setup to properly quote identifiers diff --git a/bin/sqitch b/bin/sqitch index e14a01115..89c77f22d 100755 --- a/bin/sqitch +++ b/bin/sqitch @@ -1,15 +1,6 @@ #!perl -w -CAS # VERSION -use POSIX qw(setlocale); -BEGIN { - if ($^O eq 'MSWin32') { - require Win32::Locale; - setlocale POSIX::LC_ALL, Win32::Locale::get_locale(); - } else { - setlocale POSIX::LC_ALL, ''; - } -} +use locale; use App::Sqitch; - exit App::Sqitch->go; diff --git a/t/sqitch b/t/sqitch index 350e7fc0a..cf9171dca 100755 --- a/t/sqitch +++ b/t/sqitch @@ -1,14 +1,6 @@ #!/usr/bin/env perl -CAS -use POSIX qw(setlocale); -BEGIN { - if ($^O eq 'MSWin32') { - require Win32::Locale; - setlocale POSIX::LC_ALL, Win32::Locale::get_locale(); - } else { - setlocale POSIX::LC_ALL, ''; - } -} +use locale; use FindBin; use lib "$FindBin::Bin/../lib"; use App::Sqitch; diff --git a/xt/locale/LocaleData/de_DE/LC_MESSAGES/App-Sqitch.mo b/xt/locale/LocaleData/de_DE/LC_MESSAGES/App-Sqitch.mo new file mode 100644 index 0000000000000000000000000000000000000000..b50dd0a33c7fc90fee01b7d92251e3986c8e2dd1 GIT binary patch literal 209 zcmca7#4?ou2$+Ca28eZlm=%a^fEWYg4>~ z+{C<;S|x?dVuif?5`{#Cvc#Os6a}aRgHK{!dTC;Ms+B@YDwlJ9UP)?RiEc<`0Z^bM zwW377ASW?1&srflBeAGBwZt|w#7)g4>~ z+{C<;S|x?dVuif?5`{#Cvc#Os6a}aRgHK{!dTC;Ms+B@o5tnm*UP)?RiEc<`0Z^bM zwW377ASW?1&srflBeAGBwZt|w#7)g4>~ z+{C<;S|x?dVuif?5`{#Cvc#Os6a}aRgHK{!dTC;Ms+B@!372zzUP)?RiEc<`0Z^bM zwW377ASW?1&srflBeAGBwZt|w#7) 4; +use File::Spec; +use Capture::Tiny qw(:all); + +# Requires xt/locale/LocaleData; see xt/lcoale/README.md for details. +my @cli = (qw(-Ilib -CAS -Ixt/locale), File::Spec->catfile(qw(bin sqitch))); + +# Each locale must be installed on the local system. Adding a new lang? Also add +# the relevant language-pack-XX package to os.yml and perl.yml. +for my $tc ( + { lang => 'en_US', err => q{"nonesuch" is not a valid command} }, + { lang => 'fr_FR', err => q{"nonesuch" n'est pas une commande valide} }, + { lang => 'de_DE', err => q{"nonesuch" ist ein ungültiger Befehl} }, + { lang => 'it_IT', err => q{"nonesuch" non è un comando valido} }, +) { + subtest $tc->{lang} || 'default' => sub { + local $ENV{LC_ALL} = "$tc->{lang}.UTF-8"; + + # Test successful run. + my ($stdout, $stderr, $exit) = capture { system $^X, @cli, 'help' }; + is $exit >> 8, 0, 'Should have exited normally'; + like $stdout, qr/\AUsage\b/, 'Should have usage statement in STDOUT'; + is $stderr, '', 'Should have no STDERR'; + + # Test localized error. + ($stdout, $stderr, $exit) = capture { system $^X, @cli, 'nonesuch' }; + is $exit >> 8, 2, 'Should have exit val 2'; + is $stdout, '', 'Should have no STDOUT'; + like $stderr, qr/\A\Q$tc->{err}/, + 'Should have localized error message in STDERR'; + }; +}