Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package transifex-client for
openSUSE:Factory checked in at 2022-04-27 21:41:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/transifex-client (Old)
and /work/SRC/openSUSE:Factory/.transifex-client.new.1538 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "transifex-client"
Wed Apr 27 21:41:12 2022 rev:18 rq:973025 version:0.14.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/transifex-client/transifex-client.changes
2022-01-13 00:23:20.535972210 +0100
+++
/work/SRC/openSUSE:Factory/.transifex-client.new.1538/transifex-client.changes
2022-04-27 21:41:19.789013603 +0200
@@ -1,0 +2,23 @@
+Tue Apr 26 11:43:00 UTC 2022 - [email protected]
+
+- fix tests on 32 bit arch
+- added patches
+ fix https://github.com/transifex/transifex-client/pull/316
+ + transifex-client-fix-test-on-32bit.patch
+
+-------------------------------------------------------------------
+Tue Apr 26 11:30:16 UTC 2022 - [email protected]
+
+- version update to 0.14.4
+ * Patch issue 317
+ * Change download path when supplied language is source language
+ * Fix for CLI option of custom CA certificate bundle file
+ * Use authored date as git timestamp
+ * CLI option for custom CA certificate bundle file
+ * New flag to compare file timestamp through git and slugify update
+- do not require python-mock for build
+- added patches
+ fix https://github.com/transifex/transifex-client/pull/314
+ + transifex-client-no-mock.patch
+
+-------------------------------------------------------------------
Old:
----
0.13.9.tar.gz
New:
----
0.14.4.tar.gz
transifex-client-fix-test-on-32bit.patch
transifex-client-no-mock.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ transifex-client.spec ++++++
--- /var/tmp/diff_new_pack.7Ce5Ui/_old 2022-04-27 21:41:20.489014428 +0200
+++ /var/tmp/diff_new_pack.7Ce5Ui/_new 2022-04-27 21:41:20.489014428 +0200
@@ -17,16 +17,20 @@
Name: transifex-client
-Version: 0.13.9
+Version: 0.14.4
Release: 0
Summary: Transifex Command-line Client
License: GPL-2.0-only
Group: Productivity/Text/Utilities
URL: https://github.com/transifex/transifex-client
Source:
https://github.com/transifex/transifex-client/archive/%{version}.tar.gz
+# https://github.com/transifex/transifex-client/pull/314
+Patch0: transifex-client-no-mock.patch
+# https://github.com/transifex/transifex-client/pull/316
+Patch1: transifex-client-fix-test-on-32bit.patch
BuildRequires: python-rpm-macros
-BuildRequires: python3-mock
-BuildRequires: python3-mock >= 3.0.5
+BuildRequires: python3-GitPython
+BuildRequires: python3-pytest
BuildRequires: python3-python-slugify
BuildRequires: python3-requests >= 2.19.1
BuildRequires: python3-setuptools
@@ -52,8 +56,8 @@
%prep
%setup -q
-sed -i -e "s/slugify<.*/slugify/" requirements.txt
-sed -i -e "s/mock>=3.0.5,<4.0/mock>=3.0.5/" setup.py
+%patch0 -p1
+%patch1 -p1
sed -i -e '1{\,^#!/usr/bin/env python,d}' txclib/cmdline.py
%build
@@ -69,7 +73,8 @@
ln -s -f %{_sysconfdir}/alternatives/tx %{buildroot}%{_bindir}/tx
%check
-python3 -m unittest
+# test_fetch_timestamp_from_git_tree: this is not a git tree
+pytest -k 'not test_fetch_timestamp_from_git_tree'
%post
%{_sbindir}/update-alternatives --install %{_bindir}/tx tx
%{_bindir}/transifex-tx 20
++++++ 0.13.9.tar.gz -> 0.14.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/.circleci/config.yml
new/transifex-client-0.14.4/.circleci/config.yml
--- old/transifex-client-0.13.9/.circleci/config.yml 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/.circleci/config.yml 2021-12-23
11:34:36.000000000 +0100
@@ -5,8 +5,14 @@
environment:
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
- TOX_PY2: 2.7.13
- TOX_PY3: 3.8.0
+ TOX_PY2: '2.7'
+ TOX_PY3: '3.9'
+ # NOTE(honles): The following are the official names, but point releases
+ # will likely be aliased as above pending either:
+ # - https://github.com/randomknowledge/docker-pyenv-tox/pull/6
+ # - https://github.com/randomknowledge/docker-pyenv-tox/pull/7
+ TOX_PY2_FALLBACK: 2.7.13
+ TOX_PY3_FALLBACK: 3.9.0
# To see the list of pre-built images that CircleCI provides for most
# common languages see
# https://circleci.com/docs/2.0/circleci-images/
@@ -38,9 +44,24 @@
# This is based on your 1.0 configuration file or project settings
- run: pip -V
- run: pip install -U ipdb
- - run: pyenv install -s $TOX_PY2
- - run: pyenv install -s $TOX_PY3
- - run: pyenv local $TOX_PY2 $TOX_PY3
+ # allow installing pyenv versions not in the base image
+ - run: |
+ if ! pyenv install -s $TOX_PY2; then
+ TOX_PY2=$TOX_PY2_FALLBACK
+ PYENV_UPDATED=1
+ # update pyenv just in case
+ : $(cd /pyenv/ && git pull)
+ pyenv install -s $TOX_PY2
+ fi
+
+ if ! pyenv install -s $TOX_PY3; then
+ TOX_PY3=$TOX_PY3_FALLBACK
+ # if not already updated, update pyenv
+ test -z "$PYENV_UPDATED" && : $(cd /pyenv/ && git pull)
+ pyenv install -s $TOX_PY3
+ fi
+
+ pyenv local $TOX_PY2 $TOX_PY3
# Save dependency cache
- save_cache:
key: txclient-{{ .Branch }}-{{ epoch }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/README.md
new/transifex-client-0.14.4/README.md
--- old/transifex-client-0.13.9/README.md 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/README.md 2021-12-23 11:34:36.000000000
+0100
@@ -5,7 +5,7 @@
[](https://codecov.io/gh/transifex/transifex-client)
[](https://badge.fury.io/py/transifex-client)
-
+> _?????? A new client, compatible with the [new
API](https://transifex.github.io/openapi/), is under development. Check out the
Alpha version [here](https://github.com/transifex/cli)._
## Getting started
Whether you have experience with the command line or not, [this interactive
tutorial](https://www.transifex.com/learn/txclient/) is intended for everyone
who wishes to learn how the Transifex client works. There is no need to
download anything - Just click on the link provided above, and follow the
instructions.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/appveyor.yml
new/transifex-client-0.14.4/appveyor.yml
--- old/transifex-client-0.13.9/appveyor.yml 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/appveyor.yml 2021-12-23 11:34:36.000000000
+0100
@@ -48,7 +48,7 @@
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "python -m pip install --disable-pip-version-check --user --upgrade pip"
- - "python -m pip install --no-use-pep517 pyinstaller==3.4"
+ - "python -m pip install --no-use-pep517 pyinstaller==3.6"
# Set up the project in develop mode. If some dependencies contain
# compiled extensions and are not provided as pre-built wheel packages,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/contrib/tx.spec
new/transifex-client-0.14.4/contrib/tx.spec
--- old/transifex-client-0.13.9/contrib/tx.spec 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/contrib/tx.spec 2021-12-23 11:34:36.000000000
+0100
@@ -26,4 +26,4 @@
debug=False,
strip=None,
upx=False,
- console=True , icon='contrib/tx.ico')
+ console=True , icon='tx.ico')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/requirements.txt
new/transifex-client-0.14.4/requirements.txt
--- old/transifex-client-0.13.9/requirements.txt 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/requirements.txt 2021-12-23
11:34:36.000000000 +0100
@@ -1,4 +1,5 @@
urllib3>=1.24.2,<2.0.0
six<2.0.0
requests>=2.19.1,<3.0.0
-python-slugify<2.0.0
+python-slugify<5.0.0
+gitpython<4.0.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/setup.py
new/transifex-client-0.14.4/setup.py
--- old/transifex-client-0.13.9/setup.py 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/setup.py 2021-12-23 11:34:36.000000000
+0100
@@ -24,7 +24,7 @@
license="GPLv2",
dependency_links=[],
setup_requires=[],
- python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<3.9",
+ python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<3.10",
install_requires=get_file_content("requirements.txt").splitlines(),
tests_require=["mock>=3.0.5,<4.0"],
data_files=[],
@@ -42,5 +42,6 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: 3.9",
],
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/transifex-client-0.13.9/tests/project_dir/.transifexrc
new/transifex-client-0.14.4/tests/project_dir/.transifexrc
--- old/transifex-client-0.13.9/tests/project_dir/.transifexrc 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/tests/project_dir/.transifexrc 2021-12-23
11:34:36.000000000 +0100
@@ -3,4 +3,3 @@
hostname = https://www.transifex.com
password = foo
username = bar
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/tests/test_commands.py
new/transifex-client-0.14.4/tests/test_commands.py
--- old/transifex-client-0.13.9/tests/test_commands.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/tests/test_commands.py 2021-12-23
11:34:36.000000000 +0100
@@ -81,7 +81,7 @@
def test_init(self):
argv = []
- config_text = "[main]\nhost = https://www.transifex.com\n\n"
+ config_text = "[main]\nhost = https://www.transifex.com\n"
with patch('txclib.commands.project.Project'):
with patch('txclib.commands.cmd_config') as set_mock:
cmd_init(argv, '')
@@ -163,7 +163,8 @@
branch='a-branch', fetchall=False, fetchsource=False,
force=False, languages=[], minimum_perc=None, mode=None,
overwrite=True, pseudo=False, resources=[], skip=False,
- xliff=False, parallel=False, no_interactive=False
+ xliff=False, parallel=False, no_interactive=False,
+ use_git_timestamps=False
)
pr_instance.pull.assert_has_calls([pull_call])
@@ -182,7 +183,8 @@
branch='somebranch', fetchall=False, fetchsource=False,
force=False, languages=[], minimum_perc=None, mode=None,
overwrite=True, pseudo=False, resources=[], skip=False,
- xliff=False, parallel=False, no_interactive=False
+ xliff=False, parallel=False, no_interactive=False,
+ use_git_timestamps=False
)
pr_instance.pull.assert_has_calls([pull_call])
@@ -196,7 +198,24 @@
fetchall=False, force=False, minimum_perc=None,
skip=False, no_interactive=True, resources=[], pseudo=False,
languages=[], fetchsource=False, mode=None, branch=None,
- xliff=False, parallel=False, overwrite=True
+ xliff=False, parallel=False, overwrite=True,
+ use_git_timestamps=False
+ )
+ self.assertEqual(pr_instance.pull.call_count, 1)
+ pr_instance.pull.assert_has_calls([pull_call])
+
+ @patch('txclib.commands.project')
+ def test_pull_with_git_timestamps(self, project_mock):
+ pr_instance = MagicMock()
+ pr_instance.pull.return_value = True
+ project_mock.Project.return_value = pr_instance
+ cmd_pull(['--use-git-timestamps'], '.')
+ pull_call = call(
+ fetchall=False, force=False, minimum_perc=None,
+ skip=False, no_interactive=False, resources=[], pseudo=False,
+ languages=[], fetchsource=False, mode=None, branch=None,
+ xliff=False, parallel=False, overwrite=True,
+ use_git_timestamps=True
)
self.assertEqual(pr_instance.pull.call_count, 1)
pr_instance.pull.assert_has_calls([pull_call])
@@ -236,7 +255,7 @@
def test_bare_set_source_file(self):
expected = ("[main]\nhost = https://foo.var\n\n[project1.resource1]\n"
- "source_file = test.txt\nsource_lang = en\n\n")
+ "source_file = test.txt\nsource_lang = en\n")
args = ["-r", "project1.resource1", '--source', '-l', 'en', 'test.txt']
cmd_config(args, self.path_to_tx)
with open(self.config_file) as config:
@@ -245,7 +264,7 @@
# set translation file for de
expected = ("[main]\nhost = https://foo.var\n\n[project1.resource1]\n"
"source_file = test.txt\nsource_lang = en\n"
- "trans.de = translations/de.txt\n\n")
+ "trans.de = translations/de.txt\n")
args = ["-r", "project1.resource1", '-l', 'de', 'translations/de.txt']
cmd_config(args, self.path_to_tx)
with open(self.config_file) as config:
@@ -270,7 +289,7 @@
expected = ("[main]\nhost = https://foo.var\n\n[project1.resource1]\n"
"file_filter = translations/<lang>/test.txt\n"
"source_file = translations/en/test.txt\n"
- "source_lang = en\n\n")
+ "source_lang = en\n")
args = ["--auto-local", "-r", "project1.resource1",
'--source-language', 'en', '--execute',
@@ -283,7 +302,7 @@
expected = ("[main]\nhost = https://foo.var\n\n[project1.resource1]\n"
"file_filter = translations/<lang>/test.txt\n"
"source_file = translations/en/test.txt\n"
- "source_lang = en\n\n")
+ "source_lang = en\n")
args = [MAPPING, "-r", "project1.resource1", '--source-language',
'en', '--execute', 'translations/<lang>/test.txt']
@@ -314,7 +333,7 @@
"file_filter = translations/proj.resource_1/<lang>.txt\n"
"source_lang = fr\ntype = TXT\n\n[proj.resource_2]\n"
"file_filter = translations/proj.resource_2/<lang>.txt\n"
- "source_lang = fr\ntype = TXT\n\n")
+ "source_lang = fr\ntype = TXT\n")
extension_mock.return_value = ".txt"
get_details_mock.side_effect = [
# project details
@@ -353,7 +372,7 @@
"file_filter = translations/proj.resource_1/<lang>.txt\n"
"source_lang = fr\ntype = TXT\n\n[proj.resource_2]\n"
"file_filter = translations/proj.resource_2/<lang>.txt\n"
- "source_lang = fr\ntype = TXT\n\n")
+ "source_lang = fr\ntype = TXT\n")
extension_mock.return_value = ".txt"
get_details_mock.side_effect = [
# project details
@@ -398,7 +417,7 @@
"[test-project.translations_en_test]\n"
"file_filter = translations/<lang>/en/test.txt\n"
"source_file = translations/en/test.txt\n"
- "source_lang = en\ntype = TXT\n\n")
+ "source_lang = en\ntype = TXT\n")
args = [MAPPINGBULK, "-p", "test-project", "--source-file-dir",
"translations", "--source-language", "en", "-t", "TXT",
"--file-extension", ".txt", "--execute", "--expression",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/tests/test_project.py
new/transifex-client-0.14.4/tests/test_project.py
--- old/transifex-client-0.13.9/tests/test_project.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/tests/test_project.py 2021-12-23
11:34:36.000000000 +0100
@@ -704,6 +704,27 @@
res = self.p._should_download('pt', self.stats, None, True)
self.assertEqual(res, True)
+ with patch.object(utils, 'get_git_file_timestamp') as ts_mock:
+ # Note that the test needs an existing file path
+ # The current test (__file__) is the only file
+ # we're sure will exist and won't change
+
+ # Old timestamp (1990)
+ ts_mock.return_value = 640124371
+ res = self.p._should_download(
+ 'pt', self.stats, os.path.abspath(__file__), False,
+ use_git_timestamps=True
+ )
+ self.assertEqual(res, True)
+
+ # "Recent" timestamp (in the future - 2100)
+ ts_mock.return_value = 4111417171
+ res = self.p._should_download(
+ 'pt', self.stats, os.path.abspath(__file__), False,
+ use_git_timestamps=True
+ )
+ self.assertEqual(res, False)
+
def test_get_url_by_pull_mode(self):
self.assertEqual(
'pull_sourceastranslation_file',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/tests/test_utils.py
new/transifex-client-0.14.4/tests/test_utils.py
--- old/transifex-client-0.13.9/tests/test_utils.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/tests/test_utils.py 2021-12-23
11:34:36.000000000 +0100
@@ -1,7 +1,8 @@
import os
+import time
import unittest
import six
-from mock import patch, MagicMock, mock_open
+from mock import patch, MagicMock, Mock, mock_open
from urllib3.exceptions import SSLError
from txclib import utils, exceptions
@@ -364,3 +365,31 @@
with six.assertRaisesRegex(self, exceptions.MalformedConfigFile, msg):
for file, lang in utils.get_project_files(os.getcwd(), expression):
pass
+
+class GitUtilsTestCase(unittest.TestCase):
+
+ def test_fetch_timestamp_from_git_tree(self):
+ # A bit meta, lets try to get the timestamp of the
+ # current file
+ epoch_ts = utils.get_git_file_timestamp(
+ os.path.dirname(os.path.abspath(__file__))
+ )
+ self.assertIsNotNone(epoch_ts)
+
+ def test_git_timestamp_is_parsable(self):
+ # A bit meta, lets try to get the timestamp of the
+ # current file
+ epoch_ts = utils.get_git_file_timestamp(
+ os.path.dirname(os.path.abspath(__file__))
+ )
+ parsed_ts = time.mktime(time.gmtime(epoch_ts))
+ self.assertIsNotNone(parsed_ts)
+
+ def test_uses_authorized_date(self):
+ commit = Mock()
+ commit.authored_date = 1590969254
+ commit.committed_date = 1590970456
+ with patch('txclib.utils.git.Repo') as repo:
+ repo.return_value.iter_commits.return_value = [commit]
+ epoch_ts = utils.get_git_file_timestamp('any')
+ self.assertEqual(1590969254, epoch_ts)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/tox.ini
new/transifex-client-0.14.4/tox.ini
--- old/transifex-client-0.13.9/tox.ini 2020-04-07 15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/tox.ini 2021-12-23 11:34:36.000000000 +0100
@@ -1,5 +1,5 @@
[tox]
-envlist = py{27,38}-{vanilla,pyopenssl}
+envlist = py{27,39}-{vanilla,pyopenssl}
[testenv]
deps =
@@ -14,4 +14,4 @@
commands = python -V
coverage run setup.py test
bash ./contrib/test_build.sh
- bash -c 'test -n "$CI" && codecov -e TOX_ENV_NAME'
+ bash -c 'if [ -n "$CI" ]; then codecov -e TOX_ENV_NAME; fi'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/__init__.py
new/transifex-client-0.14.4/txclib/__init__.py
--- old/transifex-client-0.13.9/txclib/__init__.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/__init__.py 2021-12-23
11:34:36.000000000 +0100
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
#
https://www.python.org/dev/peps/pep-0440/#examples-of-compliant-version-schemes
-__version__ = '0.13.9'
+__version__ = '0.14.4'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/cmdline.py
new/transifex-client-0.14.4/txclib/cmdline.py
--- old/transifex-client-0.13.9/txclib/cmdline.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/cmdline.py 2021-12-23
11:34:36.000000000 +0100
@@ -4,7 +4,7 @@
import sys
from urllib3.exceptions import SSLError
-from txclib import utils
+from txclib import utils, web
from txclib.log import set_log_level, logger
from txclib.parsers import tx_main_parser
from txclib.exceptions import AuthenticationError
@@ -62,6 +62,8 @@
elif options.debug:
set_log_level('DEBUG')
+ web.cacerts_file = options.cacert
+
# find .tx
path_to_tx = options.root_dir or utils.find_dot_tx()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/commands.py
new/transifex-client-0.14.4/txclib/commands.py
--- old/transifex-client-0.13.9/txclib/commands.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/commands.py 2021-12-23
11:34:36.000000000 +0100
@@ -414,6 +414,7 @@
skip = options.skip_errors
xliff = options.xliff
parallel = options.parallel
+ use_git_timestamps = options.use_git_timestamps
prj = project.Project(path_to_tx)
if not (options.push_source or options.push_translations):
parser.error("You need to specify at least one of the -s|--source, "
@@ -425,7 +426,8 @@
skip=skip, source=options.push_source,
translations=options.push_translations,
no_interactive=options.no_interactive,
- xliff=xliff, branch=branch, parallel=parallel
+ xliff=xliff, branch=branch, parallel=parallel,
+ use_git_timestamps=use_git_timestamps,
)
logger.info("Done.")
@@ -445,6 +447,7 @@
parallel = options.parallel
skip = options.skip_errors
minimum_perc = options.minimum_perc or None
+ use_git_timestamps = options.use_git_timestamps
_go_to_dir(path_to_tx)
@@ -457,6 +460,7 @@
force=options.force, skip=skip, minimum_perc=minimum_perc,
mode=options.mode, pseudo=pseudo, xliff=xliff, branch=branch,
parallel=parallel, no_interactive=options.no_interactive,
+ use_git_timestamps=use_git_timestamps
)
logger.info("Done.")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/config.py
new/transifex-client-0.14.4/txclib/config.py
--- old/transifex-client-0.13.9/txclib/config.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/config.py 2021-12-23
11:34:36.000000000 +0100
@@ -14,20 +14,21 @@
"""
def write(self, fp):
"""Write an .ini-format representation of the configuration state."""
+ section_prefix = ''
if self._defaults:
fp.write("[%s]\n" % DEFAULTSECT)
for key in sorted(self._defaults):
fp.write("%s = %s\n" % (key, str(self._defaults[key]).
replace('\n', '\n\t')))
- fp.write("\n")
+ section_prefix = '\n'
for section in self._sections:
- fp.write("[%s]\n" % section)
+ fp.write("%s[%s]\n" % (section_prefix, section))
for key in sorted(self._sections[section]):
if key != "__name__":
fp.write("%s = %s\n" %
(key, str(self._sections[section][key]).
replace('\n', '\n\t')))
- fp.write("\n")
+ section_prefix = '\n'
optionxform = str
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/parsers.py
new/transifex-client-0.14.4/txclib/parsers.py
--- old/transifex-client-0.13.9/txclib/parsers.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/parsers.py 2021-12-23
11:34:36.000000000 +0100
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+import argparse
import os
import sys
@@ -11,6 +12,12 @@
'mapping', 'mapping-remote', 'mapping-bulk'
)
+def check_file_exists(file=None):
+ if file and not os.path.isfile(file):
+ raise argparse.ArgumentTypeError(
+ 'certificate file %s not found' % file)
+ return file
+
def tx_main_parser():
description = "This is the Transifex command line client which"\
@@ -46,6 +53,12 @@
default=(os.name == 'nt' or not sys.stdout.isatty()),
help="disable colors in the output of commands"
)
+ # set a private CA cert bundle file to override the system one
+ parser.add_argument(
+ "--cacert", action="store", dest="cacert", default=None,
+ help="set path to CA certificate bundle file",
+ metavar='/path/to/ca-cert-bundle-file', type=check_file_exists
+ )
parser.add_argument(
"command", action="store", help="TX command", nargs='?', default=None
)
@@ -182,6 +195,11 @@
parser.add_argument("--pseudo", action="store_true", dest="pseudo",
default=False, help="Apply this option to download "
"a pseudo file.")
+ parser.add_argument("--use-git-timestamps", action="store_true",
+ dest="use_git_timestamps", default=False,
+ help="Compare local files to their Transifex version "
+ "by their latest commit timestamps. Use this option, "
+ "for example, when cloning a Git repository.")
parser.add_argument(
"--mode", action="store", dest="mode", help=(
"Specify the mode of the translation file to pull (e.g. "
@@ -244,6 +262,11 @@
parser.add_argument("-x", "--xliff", action="store_true", dest="xliff",
default=False, help="Apply this option to upload "
"file as xliff.")
+ parser.add_argument("--use-git-timestamps", action="store_true",
+ dest="use_git_timestamps", default=False,
+ help="Compare local files to their Transifex version "
+ "by their latest commit timestamps. Use this option, "
+ "for example, when cloning a Git repository.")
parser.add_argument(
"-b", "--branch", action="store", dest="branch",
default=None, nargs="?", const='-1',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/project.py
new/transifex-client-0.14.4/txclib/project.py
--- old/transifex-client-0.13.9/txclib/project.py 2020-04-07
15:17:40.000000000 +0200
+++ new/transifex-client-0.14.4/txclib/project.py 2021-12-23
11:34:36.000000000 +0100
@@ -394,7 +394,7 @@
def pull(self, languages=None, resources=None, overwrite=True,
fetchall=False, fetchsource=False, force=False, skip=False,
minimum_perc=0, mode=None, pseudo=False, xliff=False, branch=None,
- parallel=False, no_interactive=False):
+ parallel=False, no_interactive=False, use_git_timestamps=False):
"""Pull all translations file from Transifex server."""
languages = languages or []
resources = resources or []
@@ -460,7 +460,9 @@
pseudo_file = self._get_pseudo_file(
slang, resource, file_filter
)
- if self._should_download(slang, stats, local_file=pseudo_file):
+ if self._should_download(
+ slang, stats, local_file=pseudo_file,
+ use_git_timestamps=use_git_timestamps):
logger.info("Pulling pseudo file for resource %s (%s)." % (
resource,
utils.color_text(pseudo_file, "RED")
@@ -473,7 +475,7 @@
if fetchall:
new_translations = self._new_translations_to_add(
- files, slang, lang_map, stats, force
+ files, slang, lang_map, stats, force, use_git_timestamps
)
if new_translations:
msg = ("New translations found "
@@ -487,7 +489,9 @@
new_translations |= new
logger.debug("Adding to new translations: %s" % new)
- if fetchsource:
+ if fetchsource or slang in languages:
+ new_translations.discard(slang)
+ pull_languages.discard(slang)
if sfile and slang not in pull_languages:
pull_languages.add(slang)
elif slang not in new_translations:
@@ -527,6 +531,7 @@
'local_file': local_file,
'force': force,
'mode': mode,
+ 'use_git_timestamps': use_git_timestamps
}
# xliff files should be always pulled
@@ -611,7 +616,7 @@
def push(self, source=False, translations=False, force=False,
resources=None, languages=None, skip=False, no_interactive=False,
- xliff=False, branch=None, parallel=False):
+ xliff=False, branch=None, parallel=False,
use_git_timestamps=False):
"""Push all the resources"""
languages = languages or []
resources = resources or []
@@ -744,6 +749,7 @@
'stats': stats,
'local_file': local_file,
'force': force,
+ 'use_git_timestamps': use_git_timestamps,
}
if not self._should_push_translation(**kwargs):
msg = "Skipping '%s' translation (file: %s)."
@@ -987,7 +993,7 @@
)
def _should_update_translation(self, lang, stats, local_file, force=False,
- mode=None):
+ mode=None, use_git_timestamps=False):
"""Whether a translation should be udpated from Transifex.
We use the following criteria for that:
@@ -1002,12 +1008,15 @@
local_file: The local translation file.
force: A boolean flag.
mode: The mode for the translation.
+ use_git_timestamps: Boolean flag - use latest commit timestamp
+ instead of system timestamps for checking if local file is
+ older than Transifex's.
Returns:
True or False.
"""
- return self._should_download(lang, stats, local_file, force)
+ return self._should_download(lang, stats, local_file, force,
use_git_timestamps=use_git_timestamps)
- def _should_add_translation(self, lang, stats, force=False, mode=None):
+ def _should_add_translation(self, lang, stats, force=False, mode=None,
use_git_timestamps=False):
"""Whether a translation should be added from Transifex.
We use the following criteria for that:
@@ -1020,13 +1029,16 @@
stats: The (global) statistics object.
force: A boolean flag.
mode: The mode for the translation.
+ use_git_timestamps: Boolean flag - use latest commit timestamp
+ instead of system timestamps for checking if local file is
+ older than Transifex's.
Returns:
True or False.
"""
- return self._should_download(lang, stats, None, force)
+ return self._should_download(lang, stats, None, force,
use_git_timestamps=use_git_timestamps)
def _should_download(self, lang, stats, local_file=None, force=False,
- mode=None):
+ mode=None, use_git_timestamps=False):
"""Return whether a translation should be downloaded.
If local_file is None, skip the timestamps check (the file does
@@ -1048,12 +1060,12 @@
if local_file is not None:
remote_update = self._extract_updated(lang_stats)
- if not self._remote_is_newer(remote_update, local_file):
+ if not self._remote_is_newer(remote_update, local_file,
use_git_timestamps):
logger.debug("Local is newer than remote for lang %s" % lang)
return False
return True
- def _should_push_translation(self, lang, stats, local_file, force=False):
+ def _should_push_translation(self, lang, stats, local_file, force=False,
use_git_timestamps=False):
"""Return whether a local translation file should be
pushed to Trasnifex.
@@ -1067,6 +1079,9 @@
stats: The (global) statistics object.
local_file: The local translation file.
force: A boolean flag.
+ use_git_timestamps: Boolean flag - use latest commit timestamp
+ instead of system timestamps for checking if local file is
+ older than Transifex's.
Returns:
True or False.
"""
@@ -1080,7 +1095,7 @@
return True
if local_file is not None:
remote_update = self._extract_updated(lang_stats)
- if self._remote_is_newer(remote_update, local_file):
+ if self._remote_is_newer(remote_update, local_file,
use_git_timestamps):
msg = "Remote translation is newer than local file for lang %s"
logger.debug(msg % lang)
return False
@@ -1102,16 +1117,29 @@
).utctimetuple()
)
- def _get_time_of_local_file(self, path):
+ def _get_time_of_local_file(self, path, use_git_timestamps=False):
"""Get the modified time of the path_.
Args:
path: The path we want the mtime for.
+ use_git_timestamps: Boolean flag - use latest commit timestamp
+ instead of system timestamps for checking if local file is
+ older than Transifex's.
Returns:
The time as a timestamp or None, if the file does not exist
"""
if not os.path.exists(path):
return None
+
+ if use_git_timestamps:
+ epoch_timestamp = utils.get_git_file_timestamp(path)
+ if epoch_timestamp:
+ return time.mktime(time.gmtime(epoch_timestamp))
+ else:
+ logger.warning(
+ "Failed to find git repository. Fallback to OS timstamp"
+ )
+
return time.mktime(time.gmtime(os.path.getmtime(path)))
def _satisfies_min_translated(self, stats, mode=None):
@@ -1139,13 +1167,16 @@
minimum_percent = resource_minimum
return cur >= minimum_percent
- def _remote_is_newer(self, remote_updated, local_file):
+ def _remote_is_newer(self, remote_updated, local_file,
use_git_timestamps=False):
"""Check whether the remote translation is newer that the local file.
Args:
remote_updated: The date and time the translation was last
updated remotely.
local_file: The local file.
+ use_git_timestamps: Boolean flag - use latest commit timestamp
+ instead of system timestamps for checking if local file is
+ older than Transifex's.
Returns:
True or False.
"""
@@ -1154,7 +1185,8 @@
return False
remote_time = self._generate_timestamp(remote_updated)
local_time = self._get_time_of_local_file(
- self.get_full_path(local_file)
+ self.get_full_path(local_file),
+ use_git_timestamps
)
logger.debug(
"Remote time is %s and local %s" % (remote_time, local_time)
@@ -1211,7 +1243,7 @@
fd.write(response['content'].encode("utf-8"))
def _new_translations_to_add(self, files, slang, lang_map,
- stats, force=False):
+ stats, force=False, use_git_timestamps=False):
"""Return a list of translations which are
new to the local installation.
"""
@@ -1227,7 +1259,7 @@
)
if lang_exists or lang_is_source or mapped_lang_exists:
continue
- if self._should_add_translation(lang, stats, force):
+ if self._should_add_translation(lang, stats, force,
use_git_timestamps):
new_translations.append(lang)
return set(new_translations)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/utils.py
new/transifex-client-0.14.4/txclib/utils.py
--- old/transifex-client-0.13.9/txclib/utils.py 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/txclib/utils.py 2021-12-23 11:34:36.000000000
+0100
@@ -3,6 +3,7 @@
import os
import sys
import re
+import git
import errno
import urllib3
import collections
@@ -733,3 +734,23 @@
# Print a new line when done
if done == total:
sys.stdout.write('\n')
+
+
+def get_git_file_timestamp(file_path):
+ """
+ Return the timestamp (epoch) for the latest commit of a file
+ """
+ try:
+ repo = git.Repo()
+ commits_touching_path = list(
+ repo.iter_commits(paths=file_path, max_count=1)
+ )
+ if commits_touching_path:
+ latest_commit = commits_touching_path[0]
+ latest_commit_ts = latest_commit.authored_date
+ return latest_commit_ts
+ else:
+ return None
+ except git.InvalidGitRepositoryError:
+ # Current path is not a git repo.
+ return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/transifex-client-0.13.9/txclib/web.py
new/transifex-client-0.14.4/txclib/web.py
--- old/transifex-client-0.13.9/txclib/web.py 2020-04-07 15:17:40.000000000
+0200
+++ new/transifex-client-0.14.4/txclib/web.py 2021-12-23 11:34:36.000000000
+0100
@@ -6,6 +6,8 @@
import txclib
+cacerts_file = None
+
def user_agent_identifier():
"""Return the user agent for the client."""
client_info = (txclib.__version__, platform.system(), platform.machine())
@@ -13,6 +15,10 @@
def certs_file():
+ return cacerts_file or system_certs_file()
+
+
+def system_certs_file():
if platform.system() == 'Windows':
return os.path.join(txclib.utils.get_base_dir(), 'cacert.pem')
else:
++++++ transifex-client-fix-test-on-32bit.patch ++++++
Index: transifex-client-0.14.4/tests/test_project.py
===================================================================
--- transifex-client-0.14.4.orig/tests/test_project.py
+++ transifex-client-0.14.4/tests/test_project.py
@@ -720,8 +720,8 @@ class TestProjectPull(unittest.TestCase)
)
self.assertEqual(res, True)
- # "Recent" timestamp (in the future - 2100)
- ts_mock.return_value = 4111417171
+ # "Recent" timestamp (in the future - 2038)
+ ts_mock.return_value = 2147483000
res = self.p._should_download(
'pt', self.stats, os.path.abspath(__file__), False,
use_git_timestamps=True
++++++ transifex-client-no-mock.patch ++++++
diff --git a/setup.py b/setup.py
index 8d6028e5..89b26e0a 100755
--- a/setup.py
+++ b/setup.py
@@ -26,7 +26,7 @@ def get_file_content(filename):
setup_requires=[],
python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,<3.10",
install_requires=get_file_content("requirements.txt").splitlines(),
- tests_require=["mock>=3.0.5,<4.0"],
+ tests_require=["mock>=3.0.5,<4.0; python_version < '3.3'"],
data_files=[],
test_suite="tests",
zip_safe=False,
diff --git a/tests/test_api.py b/tests/test_api.py
index 554da392..01c4c5ef 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
import unittest
-from mock import MagicMock, patch
+try:
+ from unittest.mock import MagicMock, patch
+except ImportError:
+ from mock import MagicMock, patch
from txclib.api import Api
diff --git a/tests/test_commands.py b/tests/test_commands.py
index b2e4bbd9..062d29c0 100644
--- a/tests/test_commands.py
+++ b/tests/test_commands.py
@@ -7,7 +7,10 @@
from StringIO import StringIO
except ImportError:
from io import StringIO
-from mock import patch, MagicMock, call
+try:
+ from unittest.mock import patch, MagicMock, call
+except ImportError:
+ from mock import patch, MagicMock, call
from six import assertRaisesRegex
from txclib.commands import _set_source_file, _set_translation, cmd_pull, \
cmd_init, cmd_config, cmd_status, cmd_help, UnInitializedError
diff --git a/tests/test_paths.py b/tests/test_paths.py
index 09702805..14d6abda 100644
--- a/tests/test_paths.py
+++ b/tests/test_paths.py
@@ -2,7 +2,10 @@
import os
import unittest
-from mock import patch
+try:
+ from unittest.mock import patch
+except ImportError:
+ from mock import patch
from txclib.paths import posix_path, native_path
diff --git a/tests/test_project.py b/tests/test_project.py
index 1d90dd86..0986bbca 100644
--- a/tests/test_project.py
+++ b/tests/test_project.py
@@ -13,7 +13,10 @@
import ConfigParser as configparser
from functools import wraps
-from mock import Mock, patch, mock_open
+try:
+ from unittest.mock import Mock, patch, mock_open
+except ImportError:
+ from mock import Mock, patch, mock_open
from collections import namedtuple
from os.path import dirname
from sys import modules, version_info
diff --git a/tests/test_utils.py b/tests/test_utils.py
index a605cf6d..40b26125 100755
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -2,7 +2,10 @@
import time
import unittest
import six
-from mock import patch, MagicMock, Mock, mock_open
+try:
+ from unittest.mock import patch, MagicMock, Mock, mock_open
+except ImportError:
+ from mock import patch, MagicMock, Mock, mock_open
from urllib3.exceptions import SSLError
from txclib import utils, exceptions
diff --git a/tests/test_wizard.py b/tests/test_wizard.py
index bfed3d0f..03286822 100644
--- a/tests/test_wizard.py
+++ b/tests/test_wizard.py
@@ -1,7 +1,10 @@
# -*- coding: utf-8 -*-
import unittest
-from mock import patch, MagicMock
+try:
+ from unittest.mock import patch, MagicMock
+except ImportError:
+ from mock import patch, MagicMock
from six import assertRaisesRegex