diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/changelog b/changelog index 32c1fb3..a9c4410 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,12 @@ +* Fri Jan 17 2025 Fedora Release Engineering - 0.51.0-29 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Tue Aug 6 2024 Manish Tiwari - 0.51.0-28 +- CI gating tests migration to tmt + +* Thu Jul 18 2024 Fedora Release Engineering - 0.51.0-27 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed Jan 24 2024 Fedora Release Engineering - 0.51.0-26 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild diff --git a/intltool-cache-race.patch b/intltool-cache-race.patch new file mode 100644 index 0000000..e77abde --- /dev/null +++ b/intltool-cache-race.patch @@ -0,0 +1,46 @@ +From 7355bdbca18c95a2b99cb254434ad2c2248d6747 Mon Sep 17 00:00:00 2001 +From: Gianfranco Costamagna +Date: Wed, 2 Dec 2020 16:52:53 +0100 +Subject: [PATCH] [PATCH] Avoid a race where some processes try to use a + partial cache + +Gbp-Pq: 0001-Avoid-a-race-where-some-processes-try-to-use-a-parti.patch. +--- + intltool-merge.in | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/intltool-merge.in b/intltool-merge.in +index 05db7cf930..89923a7da1 100644 +--- a/intltool-merge.in ++++ b/intltool-merge.in +@@ -43,6 +43,7 @@ use Getopt::Long; + use Text::Wrap; + use File::Basename; + use Encode; ++use Fcntl qw(:flock); + + my $must_end_tag = -1; + my $last_depth = -1; +@@ -392,11 +393,14 @@ sub load_cache + + sub get_cached_translation_database + { ++ open(my $lockfh, ">", "$cache_file.lock") or die $!; ++ flock($lockfh, LOCK_EX) or die "Could not lock '$cache_file.lock' - $!"; + my $cache_file_age = -M $cache_file; + if (defined $cache_file_age) + { + if ($cache_file_age <= &get_newest_po_age) + { ++ close($lockfh); + &load_cache; + return; + } +@@ -404,6 +408,7 @@ sub get_cached_translation_database + } + + &create_cache; ++ close($lockfh); + } + + sub add_translation diff --git a/intltool.spec b/intltool.spec index 597af02..36f5fc4 100644 --- a/intltool.spec +++ b/intltool.spec @@ -18,19 +18,18 @@ BuildRequires: perl(Getopt::Long) BuildRequires: perl(XML::Parser) BuildRequires: gettext BuildRequires: make -# http://bugzilla.gnome.org/show_bug.cgi?id=568845 -# Dropping this patch per the last comment on that thread: -# Martin Pitt: As the reporter of the bug I close this, as the new API du jour is gsettings, -# which has a sensible gettext integration. -#Patch0: schemas-merge.patch + # Fix intltool-update to work with perl 5.26. Patch taken from # Debian's intltool_0.51.0-4.debian.tar.xz -Patch1: intltool-perl5.26-regex-fixes.patch +Patch: intltool-perl5.26-regex-fixes.patch # https://bugs.launchpad.net/intltool/+bug/1505260 # https://bugzilla.redhat.com/show_bug.cgi?id=1249051 -Patch2: intltool-merge-Create-cache-file-atomically.patch +Patch: intltool-merge-Create-cache-file-atomically.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1318674 -Patch3: intltool_distcheck-fix.patch +Patch: intltool_distcheck-fix.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2268342 +# https://bugs.launchpad.net/intltool/+bug/1687644 +Patch: intltool-cache-race.patch %description This tool automatically extracts translatable strings from oaf, glade, @@ -38,10 +37,7 @@ bonobo ui, nautilus theme, .desktop, and other data files and puts them in the po files. %prep -%setup -q -%patch 1 -p1 -%patch 2 -p1 -%patch 3 -p1 +%autosetup -p1 %build %configure diff --git a/plans/basic.fmf b/plans/basic.fmf new file mode 100644 index 0000000..c1627f9 --- /dev/null +++ b/plans/basic.fmf @@ -0,0 +1,5 @@ +summary: Basic smoke test +discover: + how: fmf +execute: + how: tmt diff --git a/schemas-merge.patch b/schemas-merge.patch deleted file mode 100644 index caa1e3c..0000000 --- a/schemas-merge.patch +++ /dev/null @@ -1,153 +0,0 @@ -diff -up intltool-0.40.6/intltool-merge.in.schemas intltool-0.40.6/intltool-merge.in ---- intltool-0.40.6/intltool-merge.in.schemas 2009-02-14 17:12:28.000000000 -0500 -+++ intltool-0.40.6/intltool-merge.in 2009-04-27 01:41:11.099450891 -0400 -@@ -38,8 +38,9 @@ my $PACKAGE = "@PACKAGE@"; - my $VERSION = "@VERSION@"; - - ## Loaded modules --use strict; -+use strict; - use Getopt::Long; -+use Cwd; - use Text::Wrap; - use File::Basename; - use Encode; -@@ -68,6 +69,9 @@ my $PASS_THROUGH_ARG = 0; - my $UTF8_ARG = 0; - my $MULTIPLE_OUTPUT = 0; - my $cache_file; -+my $GETTEXT_PACKAGE = ""; -+my %varhash = (); -+my $SRCDIR = $ENV{"srcdir"} || "."; - - ## Handle options - GetOptions -@@ -87,7 +91,8 @@ GetOptions - "pass-through|p" => \$PASS_THROUGH_ARG, - "utf8|u" => \$UTF8_ARG, - "multiple-output|m" => \$MULTIPLE_OUTPUT, -- "cache|c=s" => \$cache_file -+ "cache|c=s" => \$cache_file, -+ "gettext-package|g=s" => \$GETTEXT_PACKAGE - ) or &error; - - my $PO_DIR; -@@ -103,6 +108,8 @@ my $w = "[-A-Za-z0-9._:]"; - # XML quoted string contents - my $q = "[^\\\"]*"; - -+my $MODULE = $GETTEXT_PACKAGE || FindPackageName() || "unknown"; -+ - ## Check for options. - - if ($VERSION_ARG) -@@ -216,6 +223,8 @@ Other options: - a single file containing all localized elements - -c, --cache=FILE specify cache file name - (usually \$top_builddir/po/.intltool-merge-cache) -+ -g, --gettext-package=NAME -+ specify gettext domain, needed for --schemas-style - -q, --quiet suppress most messages - --help display this help and exit - --version output version information and exit -@@ -241,6 +250,25 @@ sub print_message - } - - -+sub FindPackageName -+{ -+ my $name = ""; -+ -+ my $conf_source; { -+ local (*IN); -+ open (IN, "; -+ close IN; -+ } -+ -+ $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE = \[?([^\n\]]+)/m; -+ -+ return $name if $name; -+} -+ -+ - sub preparation - { - $PO_DIR = $ARGV[0]; -@@ -1246,50 +1274,41 @@ sub schemas_merge_translations - my $short_string = $9 ? $9 : ''; - my $long_string = $12 ? $12 : ''; - -- print OUTPUT "$locale_start_spaces$c_default_block"; -- - $default_string =~ s/\s+/ /g; -- $default_string = entity_decode($default_string); - $short_string =~ s/\s+/ /g; -- $short_string = entity_decode($short_string); - $long_string =~ s/\s+/ /g; -- $long_string = entity_decode($long_string); - -- for my $lang (sort keys %po_files_by_lang) -- { -- my $default_translation = $translations{$lang, $default_string}; -- my $short_translation = $translations{$lang, $short_string}; -- my $long_translation = $translations{$lang, $long_string}; -- -- next if (!$default_translation && !$short_translation && -- !$long_translation); -- -- print OUTPUT "\n$locale_start_spaces"; -+ print OUTPUT "$locale_start_spaces$MODULE"; - -+ print OUTPUT "$locale_start_spaces"; - print OUTPUT "$default_spaces"; -- -- if ($default_translation) -- { -- $default_translation = entity_encode($default_translation); -- print OUTPUT "$default_translation"; -+ if ($default_string) { -+ print OUTPUT "$default_string"; - } -+ print OUTPUT "$short_spaces"; -+ if ($short_string) { -+ print OUTPUT "$short_string"; -+ } -+ print OUTPUT "$long_spaces"; -+ if ($long_string) { -+ print OUTPUT "$long_string"; -+ } -+ print OUTPUT "$locale_end_spaces"; - -- print OUTPUT "$short_spaces"; -+ $default_string = entity_decode($default_string); -+ $short_string = entity_decode($short_string); -+ $long_string = entity_decode($long_string); - -- if ($short_translation) -- { -- $short_translation = entity_encode($short_translation); -- print OUTPUT "$short_translation"; -- } -+ for my $lang (sort keys %po_files_by_lang) -+ { -+ my $default_translation = $translations{$lang, $default_string}; - -- print OUTPUT "$long_spaces"; -+ next if (!$default_translation || ($default_translation eq $default_string)); - -- if ($long_translation) -- { -- $long_translation = entity_encode($long_translation); -- print OUTPUT "$long_translation"; -- } -+ $default_translation = entity_encode($default_translation); - -+ print OUTPUT "\n$locale_start_spaces"; -+ print OUTPUT "$default_spaces$default_translation"; - print OUTPUT "$locale_end_spaces"; - } - } -diff -up intltool-0.40.6/tests/results/test.schemas intltool-0.40.6/tests/results/test diff --git a/tests/cases/context.xml b/tests/cases/context.xml new file mode 100644 index 0000000..e21ad0e --- /dev/null +++ b/tests/cases/context.xml @@ -0,0 +1,19 @@ + + + <_name>Foo + + + + <_name msgctxt="1"> +Bar + + + + <_name msgctxt="2"> +Bar + + + + <_name>Baz + + diff --git a/tests/cases/context.xml.in b/tests/cases/context.xml.in new file mode 100644 index 0000000..4b58d97 --- /dev/null +++ b/tests/cases/context.xml.in @@ -0,0 +1,17 @@ + + + <_name>Foo + + + + <_name msgctxt="1">Bar + + + + <_name msgctxt="2">Bar + + + + <_name>Baz + + diff --git a/tests/cases/context.xml.in.h b/tests/cases/context.xml.in.h new file mode 100644 index 0000000..161a65b --- /dev/null +++ b/tests/cases/context.xml.in.h @@ -0,0 +1,7 @@ +char *s = N_("Foo"); +/* This is the comment on the first Bar */ +char *s = C_("1", "Bar"); +/* This is the comment on the second Bar */ +char *s = C_("2", "Bar"); +/* This is the comment on Baz */ +char *s = N_("Baz"); diff --git a/tests/intltool_tests.py b/tests/intltool_tests.py new file mode 100644 index 0000000..4a0ffa2 --- /dev/null +++ b/tests/intltool_tests.py @@ -0,0 +1,109 @@ +#!/usr/bin/python3 + +import logging +import subprocess +from difflib import Differ + +logging.basicConfig(level=logging.INFO) + + +COMMANDS = [ + "intltool-extract", + "intltool-merge" + ] +INPUT_FILE = "cases/context.xml.in" + + +def test_intltool_installation(cmd: str): + """ + Check if intltool is installed correctly + """ + try: + intltool_cmd = subprocess.Popen([cmd], stdout=subprocess.PIPE) + intltool_cmd_execution_response = intltool_cmd.communicate() + assert "Usage" in str(intltool_cmd_execution_response) + except FileNotFoundError: + logging.error(f"Either {cmd} is not installed or not accessible.") + except OSError: + logging.error(f"Some OSError occurred while executing {cmd}") + except AssertionError: + logging.error(f"[CMD] output does not include text: Usage.") + else: + logging.info(f"Execution of {cmd} succeed. Test Passed.") + + +def test_intltool_extract(cmd, input_file): + """ + Check intltool extract behavior + """ + try: + intltool_extract = subprocess.Popen( + [cmd, "--type=gettext/xml", input_file, "--update"], + stdout=subprocess.PIPE) + intltool_extract_execution_response = intltool_extract.communicate() + assert "Wrote" in str(intltool_extract_execution_response) + except AssertionError: + logging.error(f"Writing output file for {input_file} file failed.") + except Exception as e: + logging.error(e) + else: + logging.info(f"Writing output file for {input_file} succeed.") + + comparison_test_pass = True + with open("{}.h".format(input_file)) as output_file, open("results/{}.h".format("context.xml.in")) as refer_file: + differ = Differ() + for line in differ.compare(output_file.readlines(), refer_file.readlines()): + if line.startswith("+") or line.startswith("-"): + comparison_test_pass = False + + try: + assert comparison_test_pass + except AssertionError: + logging.error("Extracted file does NOT match with the result. Test failed.") + else: + logging.info("Extracted file does match with the result. Test passed.") + + +def test_intltool_merge(cmd, input_file): + """ + Check intltool merge behavior + """ + merged_file = "context.xml" + try: + intltool_merge = subprocess.Popen( + [cmd, "-o", "cases", input_file, "cases/{}".format(merged_file)], + stdout=subprocess.PIPE) + intltool_merge_execution_response = intltool_merge.communicate() + assert "Merging" in str(intltool_merge_execution_response) + except AssertionError: + logging.error(f"Writing output file for {input_file} file failed.") + except Exception as e: + logging.error(e) + else: + logging.info(f"Writing output file for {input_file} succeed.") + + comparison_test_pass = True + with open("cases/{}".format(merged_file)) as output_file, open("results/{}".format(merged_file)) as refer_file: + differ = Differ() + for line in differ.compare(output_file.readlines(), refer_file.readlines()): + if line.startswith("+") or line.startswith("-"): + comparison_test_pass = False + + try: + assert comparison_test_pass + except AssertionError: + logging.error("Merged file does NOT match with the result. Test failed.") + else: + logging.info("Merged file does match with the result. Test passed.") + + +if __name__ == "__main__": + """ + Executes test cases + """ + logging.info("Executing test cases for Intltool..") + for CMD in COMMANDS: + test_intltool_installation(CMD) + test_intltool_extract(COMMANDS[0], INPUT_FILE) + test_intltool_merge(COMMANDS[1], INPUT_FILE) + logging.info("Tests execution of Intltool completed!") diff --git a/tests/main.fmf b/tests/main.fmf new file mode 100644 index 0000000..278bfa9 --- /dev/null +++ b/tests/main.fmf @@ -0,0 +1,6 @@ +summary: Run intltool test +test: ./test.sh +framework: beakerlib +require: + - intltool + - python3 diff --git a/tests/results/context.xml b/tests/results/context.xml new file mode 100644 index 0000000..e21ad0e --- /dev/null +++ b/tests/results/context.xml @@ -0,0 +1,19 @@ + + + <_name>Foo + + + + <_name msgctxt="1"> +Bar + + + + <_name msgctxt="2"> +Bar + + + + <_name>Baz + + diff --git a/tests/results/context.xml.in.h b/tests/results/context.xml.in.h new file mode 100644 index 0000000..161a65b --- /dev/null +++ b/tests/results/context.xml.in.h @@ -0,0 +1,7 @@ +char *s = N_("Foo"); +/* This is the comment on the first Bar */ +char *s = C_("1", "Bar"); +/* This is the comment on the second Bar */ +char *s = C_("2", "Bar"); +/* This is the comment on Baz */ +char *s = N_("Baz"); diff --git a/tests/test.sh b/tests/test.sh new file mode 100755 index 0000000..35c7015 --- /dev/null +++ b/tests/test.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="intltool" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + rlRun "TmpDir=\`mktemp -d\`" 0 "Creating tmp directory" + rlRun "cp -r cases results intltool_tests.py $TmpDir" + rlRun "pushd $TmpDir" + rlPhaseEnd + + rlPhaseStartTest + rlLog "Run intltool_tests.py" + rlRun "python3 intltool_tests.py" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" + rlRun "rm -r $TmpDir" 0 "Removing tmp directory" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd