prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Dont create project if command fails in init_fs_project
  atm if for some reason this command fails it leaves a project behind
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pootle/apps/pootle_fs/management/commands/init_fs_project.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 #
  3 # Copyright (C) Pootle contributors.
  4 #
  5 # This file is a part of the Pootle project. It is distributed under the GPL3
  6 # or later license. See the LICENSE file for a copy of the license and the
  7 # AUTHORS file for copyright and authorship information.
  8 
  9 import logging
  10 
  11 from django.core.exceptions import ValidationError
  12 from django.core.management import BaseCommand, CommandError
  13 
  14 from pootle_format.models import Format
  15 from pootle_fs.utils import FSPlugin, parse_fs_url
  16 from pootle_language.models import Language
  17 from pootle_project.models import Project
  18 
  19 
  20 logger = logging.getLogger('pootle.fs')
  21 
  22 
  23 class Command(BaseCommand):
  24     help = "Init a new Pootle FS project."
  25 
  26     def add_arguments(self, parser):
  27         parser.add_argument(
  28             'code',
  29             metavar='CODE',
  30             help='Project code'
  31         )
  32         parser.add_argument(
  33             'fs',
  34             metavar='FS_URL',
  35             help='FS url "filesystem_type+/repo/path/"'
  36         )
  37         parser.add_argument(
  38             'translation_mapping',
  39             help='Translation mapping "<language_code>/<filename>.<ext>"',
  40             metavar='TRANSLATION_MAPPING'
  41         )
  42         parser.add_argument(
  43             '-n', '--name',
  44             action='store',
  45             dest='name',
  46             nargs='?',
  47             help='Project name',
  48         )
  49         parser.add_argument(
  50             '--filetypes',
  51             action='append',
  52             dest='filetypes',
  53             help='File types',
  54         )
  55         parser.add_argument(
  56             '--checkstyle',
  57             action='store',
  58             dest='checkstyle',
  59             help='Checkstyle',
  60             nargs='?',
  61             default='standard'
  62         )
  63         parser.add_argument(
  64             '-l', '--source-language',
  65             action='store',
  66             dest='source_language',
  67             help="Code for the project's source language",
  68             nargs='?',
  69             default='en'
  70         )
  71         parser.add_argument(
  72             '--nosync',
  73             action='store_false',
  74             dest='sync',
  75             help='Flag if sync is unnecessary',
  76             default=True
  77         )
  78 
  79     def handle(self, **options):
  80         source_language_code = options['source_language']
  81         try:
  82             source_language = Language.objects.get(code=source_language_code)
  83         except Language.DoesNotExist as e:
  84             self.stdout.write('%s: Unknown language code.' %
  85                               source_language_code)
  86             raise CommandError(e)
  87 
  88         fs_type, fs_url = parse_fs_url(options['fs'])
  89         code = options['code']
  90         name = options['name'] or code.capitalize()
  91 
  92         try:
  93             project = Project.objects.create(
  94                 code=code,
  95                 fullname=name,
  96                 treestyle='pootle_fs',
  97                 checkstyle=options['checkstyle'],
  98                 source_language=source_language)
  99         except ValidationError as e:
  100             raise CommandError(e)
  101 
  102         for filetype in options["filetypes"] or ["po"]:
  103             try:
  104                 filetype = Format.objects.get(name=filetype)
  105                 project.filetypes.add(filetype)
  106             except Format.DoesNotExist as e:
  107                 raise CommandError(e)
  108 
  109         project.config['pootle_fs.fs_type'] = fs_type
  110         project.config['pootle_fs.fs_url'] = fs_url
  111         project.config['pootle_fs.translation_mappings'] = {
  112             'default': options['translation_mapping']
  113         }
  114         if options['sync']:
  115             plugin = FSPlugin(project)
  116             plugin.fetch()
  117             plugin.add()
  118             plugin.sync()
  119
  ```
  
  Path: `pootle/apps/pootle_fs/localfs.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 #
  3 # Copyright (C) Pootle contributors.
  4 #
  5 # This file is a part of the Pootle project. It is distributed under the GPL3
  6 # or later license. See the LICENSE file for a copy of the license and the
  7 # AUTHORS file for copyright and authorship information.
  8 
  9 import logging
  10 import uuid
  11 
  12 import dirsync
  13 
  14 from django import forms
  15 
  16 from pootle.core.delegate import revision
  17 from pootle_project.models import Project
  18 
  19 from .plugin import Plugin
  20 
  21 
  22 class LocalFSPlugin(Plugin):
  23 
  24     fs_type = "localfs"
  25     _pulled = False
  26 
  27     @property
  28     def latest_hash(self):
  29         return revision.get(Project)(
  30             self.project).get(key="pootle.fs.fs_hash")
  31 
  32     def push(self, response):
  33         dirsync.sync(
  34             self.project.local_fs_path,
  35             self.fs_url,
  36             "sync",
  37             purge=True,
  38             logger=logging.getLogger(dirsync.__name__))
  39         return response
  40 
  41     def fetch(self):
  42         synced = dirsync.sync(
  43             self.fs_url,
  44             self.project.local_fs_path,
  45             "sync",
  46             create=True,
  47             purge=True,
  48             logger=logging.getLogger(dirsync.__name__))
  49         if synced:
  50             revision.get(Project)(self.project).set(
  51                 keys=["pootle.fs.fs_hash"], value=uuid.uuid4().hex)
  52 
  53 
  54 class LocalFSUrlValidator(object):
  55 
  56     help_text = "Enter an absolute path to a directory on your filesystem"
  57 
  58     def validate(self, url):
  59         if not url.startswith("/"):
  60             raise forms.ValidationError(self.help_text)
  61
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pootle/apps/pootle_fs/localfs.py b/pootle/apps/pootle_fs/localfs.py
  --- a/pootle/apps/pootle_fs/localfs.py
  +++ b/pootle/apps/pootle_fs/localfs.py
  @@ -16,6 +16,7 @@
   from pootle.core.delegate import revision
   from pootle_project.models import Project
   
  +from .exceptions import FSFetchError
   from .plugin import Plugin
   
   
  @@ -39,13 +40,16 @@
           return response
   
       def fetch(self):
  -        synced = dirsync.sync(
  -            self.fs_url,
  -            self.project.local_fs_path,
  -            "sync",
  -            create=True,
  -            purge=True,
  -            logger=logging.getLogger(dirsync.__name__))
  +        try:
  +            synced = dirsync.sync(
  +                self.fs_url,
  +                self.project.local_fs_path,
  +                "sync",
  +                create=True,
  +                purge=True,
  +                logger=logging.getLogger(dirsync.__name__))
  +        except ValueError as e:
  +            raise FSFetchError(e)
           if synced:
               revision.get(Project)(self.project).set(
                   keys=["pootle.fs.fs_hash"], value=uuid.uuid4().hex)
  diff --git a/pootle/apps/pootle_fs/management/commands/init_fs_project.py b/pootle/apps/pootle_fs/management/commands/init_fs_project.py
  --- a/pootle/apps/pootle_fs/management/commands/init_fs_project.py
  +++ b/pootle/apps/pootle_fs/management/commands/init_fs_project.py
  @@ -12,6 +12,7 @@
   from django.core.management import BaseCommand, CommandError
   
   from pootle_format.models import Format
  +from pootle_fs.exceptions import FSFetchError
   from pootle_fs.utils import FSPlugin, parse_fs_url
   from pootle_language.models import Language
   from pootle_project.models import Project
  @@ -112,7 +113,11 @@
               'default': options['translation_mapping']
           }
           if options['sync']:
  -            plugin = FSPlugin(project)
  -            plugin.fetch()
  -            plugin.add()
  -            plugin.sync()
  +            try:
  +                plugin = FSPlugin(project)
  +                plugin.fetch()
  +                plugin.add()
  +                plugin.sync()
  +            except FSFetchError as e:
  +                project.delete()
  +                raise CommandError(e)
  
verification_info: {"golden_diff": "diff --git a/pootle/apps/pootle_fs/localfs.py b/pootle/apps/pootle_fs/localfs.py\n--- a/pootle/apps/pootle_fs/localfs.py\n+++ b/pootle/apps/pootle_fs/localfs.py\n@@ -16,6 +16,7 @@\n from pootle.core.delegate import revision\n from pootle_project.models import Project\n \n+from .exceptions import FSFetchError\n from .plugin import Plugin\n \n \n@@ -39,13 +40,16 @@\n         return response\n \n     def fetch(self):\n-        synced = dirsync.sync(\n-            self.fs_url,\n-            self.project.local_fs_path,\n-            \"sync\",\n-            create=True,\n-            purge=True,\n-            logger=logging.getLogger(dirsync.__name__))\n+        try:\n+            synced = dirsync.sync(\n+                self.fs_url,\n+                self.project.local_fs_path,\n+                \"sync\",\n+                create=True,\n+                purge=True,\n+                logger=logging.getLogger(dirsync.__name__))\n+        except ValueError as e:\n+            raise FSFetchError(e)\n         if synced:\n             revision.get(Project)(self.project).set(\n                 keys=[\"pootle.fs.fs_hash\"], value=uuid.uuid4().hex)\ndiff --git a/pootle/apps/pootle_fs/management/commands/init_fs_project.py b/pootle/apps/pootle_fs/management/commands/init_fs_project.py\n--- a/pootle/apps/pootle_fs/management/commands/init_fs_project.py\n+++ b/pootle/apps/pootle_fs/management/commands/init_fs_project.py\n@@ -12,6 +12,7 @@\n from django.core.management import BaseCommand, CommandError\n \n from pootle_format.models import Format\n+from pootle_fs.exceptions import FSFetchError\n from pootle_fs.utils import FSPlugin, parse_fs_url\n from pootle_language.models import Language\n from pootle_project.models import Project\n@@ -112,7 +113,11 @@\n             'default': options['translation_mapping']\n         }\n         if options['sync']:\n-            plugin = FSPlugin(project)\n-            plugin.fetch()\n-            plugin.add()\n-            plugin.sync()\n+            try:\n+                plugin = FSPlugin(project)\n+                plugin.fetch()\n+                plugin.add()\n+                plugin.sync()\n+            except FSFetchError as e:\n+                project.delete()\n+                raise CommandError(e)\n", "issue": "Dont create project if command fails in init_fs_project\natm if for some reason this command fails it leaves a project behind\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nimport logging\n\nfrom django.core.exceptions import ValidationError\nfrom django.core.management import BaseCommand, CommandError\n\nfrom pootle_format.models import Format\nfrom pootle_fs.utils import FSPlugin, parse_fs_url\nfrom pootle_language.models import Language\nfrom pootle_project.models import Project\n\n\nlogger = logging.getLogger('pootle.fs')\n\n\nclass Command(BaseCommand):\n    help = \"Init a new Pootle FS project.\"\n\n    def add_arguments(self, parser):\n        parser.add_argument(\n            'code',\n            metavar='CODE',\n            help='Project code'\n        )\n        parser.add_argument(\n            'fs',\n            metavar='FS_URL',\n            help='FS url \"filesystem_type+/repo/path/\"'\n        )\n        parser.add_argument(\n            'translation_mapping',\n            help='Translation mapping \"<language_code>/<filename>.<ext>\"',\n            metavar='TRANSLATION_MAPPING'\n        )\n        parser.add_argument(\n            '-n', '--name',\n            action='store',\n            dest='name',\n            nargs='?',\n            help='Project name',\n        )\n        parser.add_argument(\n            '--filetypes',\n            action='append',\n            dest='filetypes',\n            help='File types',\n        )\n        parser.add_argument(\n            '--checkstyle',\n            action='store',\n            dest='checkstyle',\n            help='Checkstyle',\n            nargs='?',\n            default='standard'\n        )\n        parser.add_argument(\n            '-l', '--source-language',\n            action='store',\n            dest='source_language',\n            help=\"Code for the project's source language\",\n            nargs='?',\n            default='en'\n        )\n        parser.add_argument(\n            '--nosync',\n            action='store_false',\n            dest='sync',\n            help='Flag if sync is unnecessary',\n            default=True\n        )\n\n    def handle(self, **options):\n        source_language_code = options['source_language']\n        try:\n            source_language = Language.objects.get(code=source_language_code)\n        except Language.DoesNotExist as e:\n            self.stdout.write('%s: Unknown language code.' %\n                              source_language_code)\n            raise CommandError(e)\n\n        fs_type, fs_url = parse_fs_url(options['fs'])\n        code = options['code']\n        name = options['name'] or code.capitalize()\n\n        try:\n            project = Project.objects.create(\n                code=code,\n                fullname=name,\n                treestyle='pootle_fs',\n                checkstyle=options['checkstyle'],\n                source_language=source_language)\n        except ValidationError as e:\n            raise CommandError(e)\n\n        for filetype in options[\"filetypes\"] or [\"po\"]:\n            try:\n                filetype = Format.objects.get(name=filetype)\n                project.filetypes.add(filetype)\n            except Format.DoesNotExist as e:\n                raise CommandError(e)\n\n        project.config['pootle_fs.fs_type'] = fs_type\n        project.config['pootle_fs.fs_url'] = fs_url\n        project.config['pootle_fs.translation_mappings'] = {\n            'default': options['translation_mapping']\n        }\n        if options['sync']:\n            plugin = FSPlugin(project)\n            plugin.fetch()\n            plugin.add()\n            plugin.sync()\n", "path": "pootle/apps/pootle_fs/management/commands/init_fs_project.py"}, {"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nimport logging\nimport uuid\n\nimport dirsync\n\nfrom django import forms\n\nfrom pootle.core.delegate import revision\nfrom pootle_project.models import Project\n\nfrom .plugin import Plugin\n\n\nclass LocalFSPlugin(Plugin):\n\n    fs_type = \"localfs\"\n    _pulled = False\n\n    @property\n    def latest_hash(self):\n        return revision.get(Project)(\n            self.project).get(key=\"pootle.fs.fs_hash\")\n\n    def push(self, response):\n        dirsync.sync(\n            self.project.local_fs_path,\n            self.fs_url,\n            \"sync\",\n            purge=True,\n            logger=logging.getLogger(dirsync.__name__))\n        return response\n\n    def fetch(self):\n        synced = dirsync.sync(\n            self.fs_url,\n            self.project.local_fs_path,\n            \"sync\",\n            create=True,\n            purge=True,\n            logger=logging.getLogger(dirsync.__name__))\n        if synced:\n            revision.get(Project)(self.project).set(\n                keys=[\"pootle.fs.fs_hash\"], value=uuid.uuid4().hex)\n\n\nclass LocalFSUrlValidator(object):\n\n    help_text = \"Enter an absolute path to a directory on your filesystem\"\n\n    def validate(self, url):\n        if not url.startswith(\"/\"):\n            raise forms.ValidationError(self.help_text)\n", "path": "pootle/apps/pootle_fs/localfs.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nimport logging\n\nfrom django.core.exceptions import ValidationError\nfrom django.core.management import BaseCommand, CommandError\n\nfrom pootle_format.models import Format\nfrom pootle_fs.exceptions import FSFetchError\nfrom pootle_fs.utils import FSPlugin, parse_fs_url\nfrom pootle_language.models import Language\nfrom pootle_project.models import Project\n\n\nlogger = logging.getLogger('pootle.fs')\n\n\nclass Command(BaseCommand):\n    help = \"Init a new Pootle FS project.\"\n\n    def add_arguments(self, parser):\n        parser.add_argument(\n            'code',\n            metavar='CODE',\n            help='Project code'\n        )\n        parser.add_argument(\n            'fs',\n            metavar='FS_URL',\n            help='FS url \"filesystem_type+/repo/path/\"'\n        )\n        parser.add_argument(\n            'translation_mapping',\n            help='Translation mapping \"<language_code>/<filename>.<ext>\"',\n            metavar='TRANSLATION_MAPPING'\n        )\n        parser.add_argument(\n            '-n', '--name',\n            action='store',\n            dest='name',\n            nargs='?',\n            help='Project name',\n        )\n        parser.add_argument(\n            '--filetypes',\n            action='append',\n            dest='filetypes',\n            help='File types',\n        )\n        parser.add_argument(\n            '--checkstyle',\n            action='store',\n            dest='checkstyle',\n            help='Checkstyle',\n            nargs='?',\n            default='standard'\n        )\n        parser.add_argument(\n            '-l', '--source-language',\n            action='store',\n            dest='source_language',\n            help=\"Code for the project's source language\",\n            nargs='?',\n            default='en'\n        )\n        parser.add_argument(\n            '--nosync',\n            action='store_false',\n            dest='sync',\n            help='Flag if sync is unnecessary',\n            default=True\n        )\n\n    def handle(self, **options):\n        source_language_code = options['source_language']\n        try:\n            source_language = Language.objects.get(code=source_language_code)\n        except Language.DoesNotExist as e:\n            self.stdout.write('%s: Unknown language code.' %\n                              source_language_code)\n            raise CommandError(e)\n\n        fs_type, fs_url = parse_fs_url(options['fs'])\n        code = options['code']\n        name = options['name'] or code.capitalize()\n\n        try:\n            project = Project.objects.create(\n                code=code,\n                fullname=name,\n                treestyle='pootle_fs',\n                checkstyle=options['checkstyle'],\n                source_language=source_language)\n        except ValidationError as e:\n            raise CommandError(e)\n\n        for filetype in options[\"filetypes\"] or [\"po\"]:\n            try:\n                filetype = Format.objects.get(name=filetype)\n                project.filetypes.add(filetype)\n            except Format.DoesNotExist as e:\n                raise CommandError(e)\n\n        project.config['pootle_fs.fs_type'] = fs_type\n        project.config['pootle_fs.fs_url'] = fs_url\n        project.config['pootle_fs.translation_mappings'] = {\n            'default': options['translation_mapping']\n        }\n        if options['sync']:\n            try:\n                plugin = FSPlugin(project)\n                plugin.fetch()\n                plugin.add()\n                plugin.sync()\n            except FSFetchError as e:\n                project.delete()\n                raise CommandError(e)\n", "path": "pootle/apps/pootle_fs/management/commands/init_fs_project.py"}, {"content": "# -*- coding: utf-8 -*-\n#\n# Copyright (C) Pootle contributors.\n#\n# This file is a part of the Pootle project. It is distributed under the GPL3\n# or later license. See the LICENSE file for a copy of the license and the\n# AUTHORS file for copyright and authorship information.\n\nimport logging\nimport uuid\n\nimport dirsync\n\nfrom django import forms\n\nfrom pootle.core.delegate import revision\nfrom pootle_project.models import Project\n\nfrom .exceptions import FSFetchError\nfrom .plugin import Plugin\n\n\nclass LocalFSPlugin(Plugin):\n\n    fs_type = \"localfs\"\n    _pulled = False\n\n    @property\n    def latest_hash(self):\n        return revision.get(Project)(\n            self.project).get(key=\"pootle.fs.fs_hash\")\n\n    def push(self, response):\n        dirsync.sync(\n            self.project.local_fs_path,\n            self.fs_url,\n            \"sync\",\n            purge=True,\n            logger=logging.getLogger(dirsync.__name__))\n        return response\n\n    def fetch(self):\n        try:\n            synced = dirsync.sync(\n                self.fs_url,\n                self.project.local_fs_path,\n                \"sync\",\n                create=True,\n                purge=True,\n                logger=logging.getLogger(dirsync.__name__))\n        except ValueError as e:\n            raise FSFetchError(e)\n        if synced:\n            revision.get(Project)(self.project).set(\n                keys=[\"pootle.fs.fs_hash\"], value=uuid.uuid4().hex)\n\n\nclass LocalFSUrlValidator(object):\n\n    help_text = \"Enter an absolute path to a directory on your filesystem\"\n\n    def validate(self, url):\n        if not url.startswith(\"/\"):\n            raise forms.ValidationError(self.help_text)\n", "path": "pootle/apps/pootle_fs/localfs.py"}]}