prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Resources from third party add-ons are not being included in compiled plone-legacy bundle
  Seems JS resources registered in Plone 5 using old approach (`jsregistry.xml`) are not included in the final compilation: I installed an add-on and, even as I can see the JS resources listed in `default.js`, the source code is not present.
  
  If I enable development mode, then I can see the source code included in `plone-legacy-compiled.js` and it's executed normally.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `Products/CMFPlone/resources/browser/combine.py`
  Content:
  ```
  1 import re
  2 from zExceptions import NotFound
  3 from Acquisition import aq_base
  4 from datetime import datetime
  5 from plone.registry.interfaces import IRegistry
  6 from plone.resource.file import FilesystemFile
  7 from plone.resource.interfaces import IResourceDirectory
  8 from Products.CMFPlone.interfaces import IBundleRegistry
  9 from Products.CMFPlone.interfaces.resources import (
  10     OVERRIDE_RESOURCE_DIRECTORY_NAME,
  11 )
  12 from StringIO import StringIO
  13 from zope.component import getUtility
  14 from zope.component import queryUtility
  15 
  16 PRODUCTION_RESOURCE_DIRECTORY = "production"
  17 
  18 
  19 def get_production_resource_directory():
  20     persistent_directory = queryUtility(IResourceDirectory, name="persistent")
  21     if persistent_directory is None:
  22         return ''
  23     container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
  24     try:
  25         production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
  26     except NotFound:
  27         return "%s/++unique++1" % PRODUCTION_RESOURCE_DIRECTORY
  28     timestamp = production_folder.readFile('timestamp.txt')
  29     return "%s/++unique++%s" % (
  30         PRODUCTION_RESOURCE_DIRECTORY, timestamp)
  31 
  32 
  33 def get_resource(context, path):
  34     resource = context.unrestrictedTraverse(path)
  35     if isinstance(resource, FilesystemFile):
  36         (directory, sep, filename) = path.rpartition('/')
  37         return context.unrestrictedTraverse(directory).readFile(filename)
  38     else:
  39         if hasattr(aq_base(resource), 'GET'):
  40             # for FileResource
  41             return resource.GET()
  42         else:
  43             # any BrowserView
  44             return resource()
  45 
  46 
  47 def write_js(context, folder, meta_bundle):
  48     registry = getUtility(IRegistry)
  49     resources = []
  50 
  51     # default resources
  52     if meta_bundle == 'default' and registry.records.get(
  53         'plone.resources/jquery.js'
  54     ):
  55         resources.append(get_resource(context,
  56             registry.records['plone.resources/jquery.js'].value))
  57         resources.append(get_resource(context,
  58             registry.records['plone.resources.requirejs'].value))
  59         resources.append(get_resource(context,
  60             registry.records['plone.resources.configjs'].value))
  61 
  62     # bundles
  63     bundles = registry.collectionOfInterface(
  64         IBundleRegistry, prefix="plone.bundles", check=False)
  65     for bundle in bundles.values():
  66         if bundle.merge_with == meta_bundle:
  67             resources.append(get_resource(context, bundle.jscompilation))
  68 
  69     fi = StringIO()
  70     for script in resources:
  71         fi.write(script + '\n')
  72     folder.writeFile(meta_bundle + ".js", fi)
  73 
  74 
  75 def write_css(context, folder, meta_bundle):
  76     registry = getUtility(IRegistry)
  77     resources = []
  78 
  79     bundles = registry.collectionOfInterface(
  80         IBundleRegistry, prefix="plone.bundles", check=False)
  81     for bundle in bundles.values():
  82         if bundle.merge_with == meta_bundle:
  83             css = get_resource(context, bundle.csscompilation)
  84             # Preserve relative urls:
  85             # we prefix with '../'' any url not starting with '/'
  86             # or http: or data:
  87             css = re.sub(
  88                 r"""(url\(['"]?(?!['"]?([a-z]+:|\/)))""",
  89                 r'\1../',
  90                 css)
  91             resources.append(css)
  92 
  93     fi = StringIO()
  94     for script in resources:
  95         fi.write(script + '\n')
  96     folder.writeFile(meta_bundle + ".css", fi)
  97 
  98 
  99 def combine_bundles(context):
  100     persistent_directory = queryUtility(IResourceDirectory, name="persistent")
  101     if persistent_directory is None:
  102         return
  103     if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:
  104         persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)
  105     container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
  106     if PRODUCTION_RESOURCE_DIRECTORY not in container:
  107         container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)
  108     production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
  109 
  110     # store timestamp
  111     fi = StringIO()
  112     fi.write(datetime.now().isoformat())
  113     production_folder.writeFile("timestamp.txt", fi)
  114 
  115     # generate new combined bundles
  116     write_js(context, production_folder, 'default')
  117     write_js(context, production_folder, 'logged-in')
  118     write_css(context, production_folder, 'default')
  119     write_css(context, production_folder, 'logged-in')
  120
  ```
  --- 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/Products/CMFPlone/resources/browser/combine.py b/Products/CMFPlone/resources/browser/combine.py
  --- a/Products/CMFPlone/resources/browser/combine.py
  +++ b/Products/CMFPlone/resources/browser/combine.py
  @@ -31,6 +31,14 @@
   
   
   def get_resource(context, path):
  +    if path.startswith('++plone++'):
  +        # ++plone++ resources can be customized, we return their override
  +        # value if any
  +        overrides = get_override_directory(context)
  +        filepath = path[9:]
  +        if overrides.isFile(filepath):
  +            return overrides.readFile(filepath)
  +
       resource = context.unrestrictedTraverse(path)
       if isinstance(resource, FilesystemFile):
           (directory, sep, filename) = path.rpartition('/')
  @@ -96,13 +104,17 @@
       folder.writeFile(meta_bundle + ".css", fi)
   
   
  -def combine_bundles(context):
  +def get_override_directory(context):
       persistent_directory = queryUtility(IResourceDirectory, name="persistent")
       if persistent_directory is None:
           return
       if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:
           persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)
  -    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
  +    return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
  +
  +
  +def combine_bundles(context):
  +    container = get_override_directory(context)
       if PRODUCTION_RESOURCE_DIRECTORY not in container:
           container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)
       production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
  
verification_info: {"golden_diff": "diff --git a/Products/CMFPlone/resources/browser/combine.py b/Products/CMFPlone/resources/browser/combine.py\n--- a/Products/CMFPlone/resources/browser/combine.py\n+++ b/Products/CMFPlone/resources/browser/combine.py\n@@ -31,6 +31,14 @@\n \n \n def get_resource(context, path):\n+    if path.startswith('++plone++'):\n+        # ++plone++ resources can be customized, we return their override\n+        # value if any\n+        overrides = get_override_directory(context)\n+        filepath = path[9:]\n+        if overrides.isFile(filepath):\n+            return overrides.readFile(filepath)\n+\n     resource = context.unrestrictedTraverse(path)\n     if isinstance(resource, FilesystemFile):\n         (directory, sep, filename) = path.rpartition('/')\n@@ -96,13 +104,17 @@\n     folder.writeFile(meta_bundle + \".css\", fi)\n \n \n-def combine_bundles(context):\n+def get_override_directory(context):\n     persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n     if persistent_directory is None:\n         return\n     if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:\n         persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)\n-    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n+    return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n+\n+\n+def combine_bundles(context):\n+    container = get_override_directory(context)\n     if PRODUCTION_RESOURCE_DIRECTORY not in container:\n         container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)\n     production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n", "issue": "Resources from third party add-ons are not being included in compiled plone-legacy bundle\nSeems JS resources registered in Plone 5 using old approach (`jsregistry.xml`) are not included in the final compilation: I installed an add-on and, even as I can see the JS resources listed in `default.js`, the source code is not present.\n\nIf I enable development mode, then I can see the source code included in `plone-legacy-compiled.js` and it's executed normally.\n\n", "before_files": [{"content": "import re\nfrom zExceptions import NotFound\nfrom Acquisition import aq_base\nfrom datetime import datetime\nfrom plone.registry.interfaces import IRegistry\nfrom plone.resource.file import FilesystemFile\nfrom plone.resource.interfaces import IResourceDirectory\nfrom Products.CMFPlone.interfaces import IBundleRegistry\nfrom Products.CMFPlone.interfaces.resources import (\n    OVERRIDE_RESOURCE_DIRECTORY_NAME,\n)\nfrom StringIO import StringIO\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nPRODUCTION_RESOURCE_DIRECTORY = \"production\"\n\n\ndef get_production_resource_directory():\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return ''\n    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n    try:\n        production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n    except NotFound:\n        return \"%s/++unique++1\" % PRODUCTION_RESOURCE_DIRECTORY\n    timestamp = production_folder.readFile('timestamp.txt')\n    return \"%s/++unique++%s\" % (\n        PRODUCTION_RESOURCE_DIRECTORY, timestamp)\n\n\ndef get_resource(context, path):\n    resource = context.unrestrictedTraverse(path)\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n    else:\n        if hasattr(aq_base(resource), 'GET'):\n            # for FileResource\n            return resource.GET()\n        else:\n            # any BrowserView\n            return resource()\n\n\ndef write_js(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    # default resources\n    if meta_bundle == 'default' and registry.records.get(\n        'plone.resources/jquery.js'\n    ):\n        resources.append(get_resource(context,\n            registry.records['plone.resources/jquery.js'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.requirejs'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.configjs'].value))\n\n    # bundles\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle:\n            resources.append(get_resource(context, bundle.jscompilation))\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".js\", fi)\n\n\ndef write_css(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle:\n            css = get_resource(context, bundle.csscompilation)\n            # Preserve relative urls:\n            # we prefix with '../'' any url not starting with '/'\n            # or http: or data:\n            css = re.sub(\n                r\"\"\"(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))\"\"\",\n                r'\\1../',\n                css)\n            resources.append(css)\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".css\", fi)\n\n\ndef combine_bundles(context):\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return\n    if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:\n        persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)\n    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n    if PRODUCTION_RESOURCE_DIRECTORY not in container:\n        container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)\n    production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n\n    # store timestamp\n    fi = StringIO()\n    fi.write(datetime.now().isoformat())\n    production_folder.writeFile(\"timestamp.txt\", fi)\n\n    # generate new combined bundles\n    write_js(context, production_folder, 'default')\n    write_js(context, production_folder, 'logged-in')\n    write_css(context, production_folder, 'default')\n    write_css(context, production_folder, 'logged-in')\n", "path": "Products/CMFPlone/resources/browser/combine.py"}], "after_files": [{"content": "import re\nfrom zExceptions import NotFound\nfrom Acquisition import aq_base\nfrom datetime import datetime\nfrom plone.registry.interfaces import IRegistry\nfrom plone.resource.file import FilesystemFile\nfrom plone.resource.interfaces import IResourceDirectory\nfrom Products.CMFPlone.interfaces import IBundleRegistry\nfrom Products.CMFPlone.interfaces.resources import (\n    OVERRIDE_RESOURCE_DIRECTORY_NAME,\n)\nfrom StringIO import StringIO\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nPRODUCTION_RESOURCE_DIRECTORY = \"production\"\n\n\ndef get_production_resource_directory():\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return ''\n    container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n    try:\n        production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n    except NotFound:\n        return \"%s/++unique++1\" % PRODUCTION_RESOURCE_DIRECTORY\n    timestamp = production_folder.readFile('timestamp.txt')\n    return \"%s/++unique++%s\" % (\n        PRODUCTION_RESOURCE_DIRECTORY, timestamp)\n\n\ndef get_resource(context, path):\n    if path.startswith('++plone++'):\n        # ++plone++ resources can be customized, we return their override\n        # value if any\n        overrides = get_override_directory(context)\n        filepath = path[9:]\n        if overrides.isFile(filepath):\n            return overrides.readFile(filepath)\n\n    resource = context.unrestrictedTraverse(path)\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n    else:\n        if hasattr(aq_base(resource), 'GET'):\n            # for FileResource\n            return resource.GET()\n        else:\n            # any BrowserView\n            return resource()\n\n\ndef write_js(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    # default resources\n    if meta_bundle == 'default' and registry.records.get(\n        'plone.resources/jquery.js'\n    ):\n        resources.append(get_resource(context,\n            registry.records['plone.resources/jquery.js'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.requirejs'].value))\n        resources.append(get_resource(context,\n            registry.records['plone.resources.configjs'].value))\n\n    # bundles\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle:\n            resources.append(get_resource(context, bundle.jscompilation))\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".js\", fi)\n\n\ndef write_css(context, folder, meta_bundle):\n    registry = getUtility(IRegistry)\n    resources = []\n\n    bundles = registry.collectionOfInterface(\n        IBundleRegistry, prefix=\"plone.bundles\", check=False)\n    for bundle in bundles.values():\n        if bundle.merge_with == meta_bundle:\n            css = get_resource(context, bundle.csscompilation)\n            # Preserve relative urls:\n            # we prefix with '../'' any url not starting with '/'\n            # or http: or data:\n            css = re.sub(\n                r\"\"\"(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))\"\"\",\n                r'\\1../',\n                css)\n            resources.append(css)\n\n    fi = StringIO()\n    for script in resources:\n        fi.write(script + '\\n')\n    folder.writeFile(meta_bundle + \".css\", fi)\n\n\ndef get_override_directory(context):\n    persistent_directory = queryUtility(IResourceDirectory, name=\"persistent\")\n    if persistent_directory is None:\n        return\n    if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:\n        persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)\n    return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]\n\n\ndef combine_bundles(context):\n    container = get_override_directory(context)\n    if PRODUCTION_RESOURCE_DIRECTORY not in container:\n        container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)\n    production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]\n\n    # store timestamp\n    fi = StringIO()\n    fi.write(datetime.now().isoformat())\n    production_folder.writeFile(\"timestamp.txt\", fi)\n\n    # generate new combined bundles\n    write_js(context, production_folder, 'default')\n    write_js(context, production_folder, 'logged-in')\n    write_css(context, production_folder, 'default')\n    write_css(context, production_folder, 'logged-in')\n", "path": "Products/CMFPlone/resources/browser/combine.py"}]}