[damned-lies] Add ability to commit new files when linguas_location is 'no'



commit f9173f25394aee355cbe1d5b941cb5faa36c2adf
Author: Claude Paroz <claude 2xlibre net>
Date:   Mon Sep 10 13:26:27 2018 +0200

    Add ability to commit new files when linguas_location is 'no'

 stats/models.py      | 61 ++++++++++++++++++++++++++++++++--------------------
 stats/tests/tests.py | 34 +++++++++++++++++++++++++++--
 vertimus/models.py   | 12 +++++------
 3 files changed, 76 insertions(+), 31 deletions(-)
---
diff --git a/stats/models.py b/stats/models.py
index 76a6b5e5..0b0987d5 100644
--- a/stats/models.py
+++ b/stats/models.py
@@ -52,6 +52,11 @@ BRANCH_HEAD_NAMES = (
     'master'
 )
 
+
+class UnableToCommit(Exception):
+    pass
+
+
 class Module(models.Model):
     name = models.CharField(max_length=50, unique=True, validators=[validate_slug])
     homepage = models.URLField(blank=True,
@@ -625,44 +630,36 @@ class Branch(models.Model):
 
     def commit_po(self, po_file, domain, language, author):
         """ Commit the file 'po_file' in the branch VCS repository """
-        if self.is_vcs_readonly():
-            raise Exception("This branch is in read-only mode. Unable to commit")
         vcs_type = self.module.vcs_type
         if vcs_type not in ("git",):
             raise NotImplementedError("Commit is not implemented for '%s'" % vcs_type)
 
-        locale = language.locale
-        base_path = self.co_path
-        dest_path = domain.get_po_path(locale)
-        dest_full_path = base_path / dest_path
+        dest_full_path, existing, linguas_path = domain.commit_info(self, language)
 
         with ModuleLock(self.module):
             self.update_repo()
             if vcs_type == "git":
-                already_exist = dest_full_path.exists()
-                if not already_exist:
-                    linguas_path = domain.get_linguas_path(self)
-                    if linguas_path is None:
-                        raise Exception(
-                            _("Sorry, adding new translations when the LINGUAS file is not known is not 
supported.")
-                        )
+                base_path = self.co_path
 
                 # Copy file in repo
                 shutil.copyfile(str(po_file), str(dest_full_path))
 
                 # git add file.po
                 run_shell_command(
-                    ['git', 'add', dest_path], raise_on_error=True, cwd=base_path)
-                if not already_exist:
+                    ['git', 'add', str(dest_full_path.relative_to(base_path))],
+                    raise_on_error=True, cwd=base_path
+                )
+                if linguas_path:
                     # Add locale to LINGUAS
-                    utils.insert_locale_in_linguas(linguas_path, locale)
+                    utils.insert_locale_in_linguas(linguas_path, language.locale)
                     run_shell_command(
                         ['git', 'add', str(linguas_path.relative_to(base_path))],
                         raise_on_error=True, cwd=base_path
                     )
-                    msg = "Add %s translation" % language.name
-                else:
+                if existing:
                     msg = "Update %s translation" % language.name
+                else:
+                    msg = "Add %s translation" % language.name
 
                 commit_cmd = ['git', 'commit', '-m', msg]
                 if author:
@@ -683,7 +680,7 @@ class Branch(models.Model):
                     commit_hash = out.split()[0] if out else ''
 
         # Finish by updating stats
-        if already_exist:
+        if existing:
             try:
                 stat = Statistics.objects.get(language=language, branch=self, domain=domain)
             except Statistics.DoesNotExist:
@@ -975,10 +972,28 @@ class Domain(models.Model):
             pot_command.extend(['--msgid-bugs-address', bugs_url])
         return pot_command, env
 
-    def get_linguas_path(self, branch):
-        """Return a LINGUAS file path, or None."""
-        path = branch.co_path / self.base_dir / 'LINGUAS'
-        return path if path.exists() else None
+    def commit_info(self, branch, language):
+        """
+        Return a 3-tuple: (
+            absolute path to po file,
+            boolean telling if the file is new
+            linguas_path -> if linguas edition needed, else None
+        )
+        Raise an exception if file cannot be committed.
+        """
+        if branch.is_vcs_readonly():
+            raise UnableToCommit(_("The repository is read only"))
+
+        abs_po_path = branch.co_path / self.get_po_path(language.locale)
+        existing = abs_po_path.exists()
+        linguas = None
+        if not existing and self.linguas_location != 'no':
+            linguas = branch.co_path / self.base_dir / 'LINGUAS'
+            if not linguas.exists():
+                raise UnableToCommit(
+                    _("Sorry, adding new translations when the LINGUAS file is not known is not supported.")
+                )
+        return abs_po_path, existing, linguas
 
     def get_linguas(self, branch):
         """ Return a linguas dict like this: {'langs':['lang1', lang2], 'error':"Error"} """
diff --git a/stats/tests/tests.py b/stats/tests/tests.py
index d51aba2b..0ffd5357 100644
--- a/stats/tests/tests.py
+++ b/stats/tests/tests.py
@@ -17,7 +17,7 @@ from django.test.utils import override_settings
 from common.utils import run_shell_command
 from stats.models import (
     Module, Domain, Branch, Release, CategoryName, Statistics, FakeLangStatistics,
-    Information,
+    Information, UnableToCommit
 )
 from stats import utils
 from languages.models import Language
@@ -279,13 +279,43 @@ class ModuleTestCase(TestCase):
         response = self.client.get(dyn_url)
         self.assertContains(response, """# Tamil translation for gnome-hello.""")
 
+    @test_scratchdir
+    def test_commit_ability(self):
+        branch = self.mod.get_head_branch()
+        domain = self.mod.domain_set.get(name='po')
+        fr_lang = Language.objects.get(locale='fr')
+
+        with self.assertRaises(UnableToCommit):
+            # read-only VCS
+            domain.commit_info(branch, fr_lang)
+
+        # Setup as a writable repo
+        self.mod.vcs_root = 'git gitlab gnome org:GNOME/%s.git' % self.mod.name
+        linguas = branch.co_path / 'po' / 'LINGUAS'
+        os.remove(str(linguas))
+        bem_lang = Language.objects.get(locale='bem')
+        with self.assertRaises(UnableToCommit):
+            # unaccessible LINGUAS file for a new lang
+            domain.commit_info(branch, bem_lang)
+
+        domain.linguas_location = 'no'
+        self.assertEqual(
+            domain.commit_info(branch, bem_lang),
+            (branch.co_path / 'po' / 'bem.po', False, None)
+        )
+
+        self.assertEqual(
+            domain.commit_info(branch, fr_lang),
+            (branch.co_path / 'po' / 'fr.po', True, None)
+        )
+
     @test_scratchdir
     def test_commit_po(self):
         branch = self.mod.get_head_branch()
         po_file = Path(__file__).parent / 'test.po'
         domain = self.mod.domain_set.get(name='po')
         fr_lang = Language.objects.get(locale='fr')
-        with self.assertRaisesRegex(Exception, 'read-only mode'):
+        with self.assertRaisesRegex(UnableToCommit, 'read only'):
             branch.commit_po(po_file, domain, fr_lang, 'Author <someone example org>')
         # Setup as a writable repo
         self.mod.vcs_root = 'git gitlab gnome org:GNOME/%s.git' % self.mod.name
diff --git a/vertimus/models.py b/vertimus/models.py
index 5996f75a..1724dd16 100644
--- a/vertimus/models.py
+++ b/vertimus/models.py
@@ -11,7 +11,7 @@ from django.urls import reverse
 from django.utils.translation import override, ugettext, ugettext_noop, ugettext_lazy as _
 
 from common.utils import run_shell_command, send_mail
-from stats.models import Branch, Domain, Statistics, PoFile
+from stats.models import Branch, Domain, Statistics, PoFile, UnableToCommit
 from stats.signals import pot_has_changed
 from stats.utils import STATUS_OK, is_po_reduced, po_grep
 from languages.models import Language
@@ -74,11 +74,11 @@ class State(models.Model):
             return None
 
     def able_to_commit(self):
-        return (
-            not self.branch.is_vcs_readonly() and
-            self.get_latest_po_file_action() is not None and
-            (self.stats is not None or self.domain.get_linguas_path(self.branch) is not None)
-        )
+        try:
+            self.domain.commit_info(self.branch, self.language)
+        except UnableToCommit:
+            return False
+        return self.get_latest_po_file_action() is not None
 
     def change_state(self, state_class, person=None):
         self.name = state_class._name


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]