We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Plone 5.1.4 to 5.1.5 update: resource registry meta bundle generator comments first css construct of individual bundles
In one of our projects, after upgrading from Plone 5.1.4 to Plone 5.1.5  A very small part of the css became broken in plone.app.mosaic layouts . Images inside a tile no longer had a "height: auto" on them. This is normally included in mosaic-styles.css , and the mosaic styles were included in default.css.  

We quickly patched the missing statement into our theme file and did a patch release, but the underlying problem was vague.  The problem would only appear on production, running the site locally did not show the problem, so my attention was pulled to the metabundle generation. This was modified between 5.1.4 and 5.1.5 in https://github.com/plone/Products.CMFPlone/commit/397918cd39ba0be4e2e150df5f5f2220e6ecc828 by @vangheem 

The problematic code is in this part:

https://github.com/plone/Products.CMFPlone/blob/2195c4a43ba100fb2b7973dccb4299dad2de42fe/Products/CMFPlone/resources/browser/combine.py#L123-L132

The individual bundles are separated by comment lines with // Start bundle and // End Bundle, but // actually comments out the first following css construct , more info at  https://www.xanthir.com/b4U10

And the mosaic-styles.css individual bundle start with:

```
// Start Bundle: mosaic-styles
/* Images will never be bigger then a tile */
.mosaic-tile img {
  max-width: 100%;
  height: auto;
}
```

If even skips over the /* */ comment on the next line and comments the first {} it sees
So that is how only our height: auto; got disabled in production . 

This is  at the moment only broken in Plone 5.1 , In Plone 5.2 the whole bundler got rewritten again, partly because of Python3 support and doesn't seem to insert these comments. I have swapped the // comment for /* */ comments and this also solves the problem. I'll create a pull request shortly. 


--- 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 # -*- coding: utf-8 -*-
2 from Acquisition import aq_base
3 from datetime import datetime
4 from plone.registry.interfaces import IRegistry
5 from plone.resource.file import FilesystemFile
6 from plone.resource.interfaces import IResourceDirectory
7 from Products.CMFPlone.interfaces import IBundleRegistry
8 from Products.CMFPlone.interfaces.resources import OVERRIDE_RESOURCE_DIRECTORY_NAME  # noqa
9 from StringIO import StringIO
10 from zExceptions import NotFound
11 from zope.component import getUtility
12 from zope.component import queryUtility
13 
14 from collections import OrderedDict
15 import logging
16 import re
17 
18 
19 PRODUCTION_RESOURCE_DIRECTORY = 'production'
20 logger = logging.getLogger(__name__)
21 
22 
23 def get_production_resource_directory():
24     persistent_directory = queryUtility(IResourceDirectory, name='persistent')
25     if persistent_directory is None:
26         return ''
27     container = persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
28     try:
29         production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
30     except NotFound:
31         return '%s/++unique++1' % PRODUCTION_RESOURCE_DIRECTORY
32     if 'timestamp.txt' not in production_folder:
33         return '%s/++unique++1' % PRODUCTION_RESOURCE_DIRECTORY
34     timestamp = production_folder.readFile('timestamp.txt')
35     return '%s/++unique++%s' % (
36         PRODUCTION_RESOURCE_DIRECTORY, timestamp)
37 
38 
39 def get_resource(context, path):
40     if path.startswith('++plone++'):
41         # ++plone++ resources can be customized, we return their override
42         # value if any
43         overrides = get_override_directory(context)
44         filepath = path[9:]
45         if overrides.isFile(filepath):
46             return overrides.readFile(filepath)
47 
48     try:
49         resource = context.unrestrictedTraverse(path)
50     except NotFound:
51         logger.warn(u'Could not find resource {0}. You may have to create it first.'.format(path))  # noqa
52         return
53 
54     if isinstance(resource, FilesystemFile):
55         (directory, sep, filename) = path.rpartition('/')
56         return context.unrestrictedTraverse(directory).readFile(filename)
57 
58     # calling the resource may modify the header, i.e. the content-type.
59     # we do not want this, so keep the original header intact.
60     response_before = context.REQUEST.response
61     context.REQUEST.response = response_before.__class__()
62     if hasattr(aq_base(resource), 'GET'):
63         # for FileResource
64         result = resource.GET()
65     else:
66         # any BrowserView
67         result = resource()
68     context.REQUEST.response = response_before
69     return result
70 
71 
72 class MetaBundleWriter(object):
73 
74     def __init__(self, context, folder, name):
75         self.context = context
76         self.folder = folder
77         self.name = name
78         self.js_resources = OrderedDict()
79         self.css_resources = OrderedDict()
80         self.registry = getUtility(IRegistry)
81         self.bundles = self.registry.collectionOfInterface(
82             IBundleRegistry, prefix='plone.bundles', check=False)
83 
84     def write_js(self):
85 
86         # default resources
87         if self.name == 'default' and self.registry.records.get(
88             'plone.resources/jquery.js'
89         ):
90             self.js_resources['_jquery'] = get_resource(
91                 self.context,
92                 self.registry.records['plone.resources/jquery.js'].value)
93             self.js_resources['_requirejs'] = get_resource(
94                 self.context,
95                 self.registry.records['plone.resources.requirejs'].value)
96             self.js_resources['_configjs'] = get_resource(
97                 self.context,
98                 self.registry.records['plone.resources.configjs'].value)
99 
100         # bundles
101         for name, bundle in self.bundles.items():
102             self.load_js_bundle(name, bundle)
103 
104         self._write_out(self.js_resources, '.js')
105 
106     def load_js_bundle(self, name, bundle, depth=0):
107         if depth > 10:
108             # recursion detection
109             return
110         if bundle.merge_with != self.name:
111             return
112         if bundle.jscompilation:
113             if bundle.depends and bundle.depends in self.bundles:
114                 self.load_js_bundle(
115                     bundle.depends, self.bundles[bundle.depends], depth + 1)
116             if name in self.js_resources:
117                 return
118             resource = get_resource(self.context, bundle.jscompilation)
119             if not resource:
120                 return
121             self.js_resources[name] = resource
122 
123     def _write_out(self, resources, postfix):
124         fi = StringIO()
125         for bname, script in resources.items():
126             fi.write('''
127 // Start Bundle: {0}
128 {1}
129 // End Bundle: {2}
130 '''.format(bname, script, bname))
131         self.folder.writeFile(self.name + postfix, fi)
132         resources.clear()
133 
134     def load_css_bundle(self, name, bundle, depth=0):
135         if depth > 10:
136             # recursion detection
137             return
138 
139         if bundle.merge_with != self.name:
140             return
141 
142         if bundle.csscompilation:
143             if bundle.depends and bundle.depends in self.bundles:
144                 self.load_css_bundle(
145                     bundle.depends, self.bundles[bundle.depends], depth + 1)
146             if name in self.css_resources:
147                 return
148 
149             css = get_resource(self.context, bundle.csscompilation)
150             if not css:
151                 return
152             (path, sep, filename) = bundle.csscompilation.rpartition('/')
153             # Process relative urls:
154             # we prefix with current resource path any url not starting with
155             # '/' or http: or data:
156             css = re.sub(
157                 r'''(url\(['"]?(?!['"]?([a-z]+:|\/)))''',
158                 r'\1%s/' % path,
159                 css)
160             self.css_resources[name] = css
161 
162     def write_css(self):
163         for name, bundle in self.bundles.items():
164             self.load_css_bundle(name, bundle)
165 
166         self._write_out(self.css_resources, '.css')
167 
168 
169 def get_override_directory(context):
170     persistent_directory = queryUtility(IResourceDirectory, name='persistent')
171     if persistent_directory is None:
172         return
173     if OVERRIDE_RESOURCE_DIRECTORY_NAME not in persistent_directory:
174         persistent_directory.makeDirectory(OVERRIDE_RESOURCE_DIRECTORY_NAME)
175     return persistent_directory[OVERRIDE_RESOURCE_DIRECTORY_NAME]
176 
177 
178 def combine_bundles(context):
179     container = get_override_directory(context)
180     if PRODUCTION_RESOURCE_DIRECTORY not in container:
181         container.makeDirectory(PRODUCTION_RESOURCE_DIRECTORY)
182     production_folder = container[PRODUCTION_RESOURCE_DIRECTORY]
183 
184     # store timestamp
185     fi = StringIO()
186     fi.write(datetime.now().isoformat())
187     production_folder.writeFile('timestamp.txt', fi)
188 
189     # generate new combined bundles
190     default_writer = MetaBundleWriter(
191         context, production_folder, 'default')
192     default_writer.write_js()
193     logged_in_writer = MetaBundleWriter(
194         context, production_folder, 'logged-in')
195     logged_in_writer.write_js()
196     default_writer.write_css()
197     logged_in_writer.write_css()
198
```
--- 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()

```

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
@@ -124,9 +124,9 @@
         fi = StringIO()
         for bname, script in resources.items():
             fi.write('''
-// Start Bundle: {0}
+/* Start Bundle: {0} */
 {1}
-// End Bundle: {2}
+/* End Bundle: {2} */
 '''.format(bname, script, bname))
         self.folder.writeFile(self.name + postfix, fi)
         resources.clear()

{"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@@ -124,9 +124,9 @@\n         fi = StringIO()\n         for bname, script in resources.items():\n             fi.write('''\n-// Start Bundle: {0}\n+/* Start Bundle: {0} */\n {1}\n-// End Bundle: {2}\n+/* End Bundle: {2} */\n '''.format(bname, script, bname))\n         self.folder.writeFile(self.name + postfix, fi)\n         resources.clear()\n", "issue": "Plone 5.1.4 to 5.1.5 update: resource registry meta bundle generator comments first css construct of individual bundles\nIn one of our projects, after upgrading from Plone 5.1.4 to Plone 5.1.5  A very small part of the css became broken in plone.app.mosaic layouts . Images inside a tile no longer had a \"height: auto\" on them. This is normally included in mosaic-styles.css , and the mosaic styles were included in default.css.  \r\n\r\nWe quickly patched the missing statement into our theme file and did a patch release, but the underlying problem was vague.  The problem would only appear on production, running the site locally did not show the problem, so my attention was pulled to the metabundle generation. This was modified between 5.1.4 and 5.1.5 in https://github.com/plone/Products.CMFPlone/commit/397918cd39ba0be4e2e150df5f5f2220e6ecc828 by @vangheem \r\n\r\nThe problematic code is in this part:\r\n\r\nhttps://github.com/plone/Products.CMFPlone/blob/2195c4a43ba100fb2b7973dccb4299dad2de42fe/Products/CMFPlone/resources/browser/combine.py#L123-L132\r\n\r\nThe individual bundles are separated by comment lines with // Start bundle and // End Bundle, but // actually comments out the first following css construct , more info at  https://www.xanthir.com/b4U10\r\n\r\nAnd the mosaic-styles.css individual bundle start with:\r\n\r\n```\r\n// Start Bundle: mosaic-styles\r\n/* Images will never be bigger then a tile */\r\n.mosaic-tile img {\r\n  max-width: 100%;\r\n  height: auto;\r\n}\r\n```\r\n\r\nIf even skips over the /* */ comment on the next line and comments the first {} it sees\r\nSo that is how only our height: auto; got disabled in production . \r\n\r\nThis is  at the moment only broken in Plone 5.1 , In Plone 5.2 the whole bundler got rewritten again, partly because of Python3 support and doesn't seem to insert these comments. I have swapped the // comment for /* */ comments and this also solves the problem. I'll create a pull request shortly. \r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\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 OVERRIDE_RESOURCE_DIRECTORY_NAME  # noqa\nfrom StringIO import StringIO\nfrom zExceptions import NotFound\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nfrom collections import OrderedDict\nimport logging\nimport re\n\n\nPRODUCTION_RESOURCE_DIRECTORY = 'production'\nlogger = logging.getLogger(__name__)\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    if 'timestamp.txt' not in production_folder:\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    try:\n        resource = context.unrestrictedTraverse(path)\n    except NotFound:\n        logger.warn(u'Could not find resource {0}. You may have to create it first.'.format(path))  # noqa\n        return\n\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n\n    # calling the resource may modify the header, i.e. the content-type.\n    # we do not want this, so keep the original header intact.\n    response_before = context.REQUEST.response\n    context.REQUEST.response = response_before.__class__()\n    if hasattr(aq_base(resource), 'GET'):\n        # for FileResource\n        result = resource.GET()\n    else:\n        # any BrowserView\n        result = resource()\n    context.REQUEST.response = response_before\n    return result\n\n\nclass MetaBundleWriter(object):\n\n    def __init__(self, context, folder, name):\n        self.context = context\n        self.folder = folder\n        self.name = name\n        self.js_resources = OrderedDict()\n        self.css_resources = OrderedDict()\n        self.registry = getUtility(IRegistry)\n        self.bundles = self.registry.collectionOfInterface(\n            IBundleRegistry, prefix='plone.bundles', check=False)\n\n    def write_js(self):\n\n        # default resources\n        if self.name == 'default' and self.registry.records.get(\n            'plone.resources/jquery.js'\n        ):\n            self.js_resources['_jquery'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources/jquery.js'].value)\n            self.js_resources['_requirejs'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources.requirejs'].value)\n            self.js_resources['_configjs'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources.configjs'].value)\n\n        # bundles\n        for name, bundle in self.bundles.items():\n            self.load_js_bundle(name, bundle)\n\n        self._write_out(self.js_resources, '.js')\n\n    def load_js_bundle(self, name, bundle, depth=0):\n        if depth > 10:\n            # recursion detection\n            return\n        if bundle.merge_with != self.name:\n            return\n        if bundle.jscompilation:\n            if bundle.depends and bundle.depends in self.bundles:\n                self.load_js_bundle(\n                    bundle.depends, self.bundles[bundle.depends], depth + 1)\n            if name in self.js_resources:\n                return\n            resource = get_resource(self.context, bundle.jscompilation)\n            if not resource:\n                return\n            self.js_resources[name] = resource\n\n    def _write_out(self, resources, postfix):\n        fi = StringIO()\n        for bname, script in resources.items():\n            fi.write('''\n// Start Bundle: {0}\n{1}\n// End Bundle: {2}\n'''.format(bname, script, bname))\n        self.folder.writeFile(self.name + postfix, fi)\n        resources.clear()\n\n    def load_css_bundle(self, name, bundle, depth=0):\n        if depth > 10:\n            # recursion detection\n            return\n\n        if bundle.merge_with != self.name:\n            return\n\n        if bundle.csscompilation:\n            if bundle.depends and bundle.depends in self.bundles:\n                self.load_css_bundle(\n                    bundle.depends, self.bundles[bundle.depends], depth + 1)\n            if name in self.css_resources:\n                return\n\n            css = get_resource(self.context, bundle.csscompilation)\n            if not css:\n                return\n            (path, sep, filename) = bundle.csscompilation.rpartition('/')\n            # Process relative urls:\n            # we prefix with current resource path any url not starting with\n            # '/' or http: or data:\n            css = re.sub(\n                r'''(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))''',\n                r'\\1%s/' % path,\n                css)\n            self.css_resources[name] = css\n\n    def write_css(self):\n        for name, bundle in self.bundles.items():\n            self.load_css_bundle(name, bundle)\n\n        self._write_out(self.css_resources, '.css')\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    default_writer = MetaBundleWriter(\n        context, production_folder, 'default')\n    default_writer.write_js()\n    logged_in_writer = MetaBundleWriter(\n        context, production_folder, 'logged-in')\n    logged_in_writer.write_js()\n    default_writer.write_css()\n    logged_in_writer.write_css()\n", "path": "Products/CMFPlone/resources/browser/combine.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\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 OVERRIDE_RESOURCE_DIRECTORY_NAME  # noqa\nfrom StringIO import StringIO\nfrom zExceptions import NotFound\nfrom zope.component import getUtility\nfrom zope.component import queryUtility\n\nfrom collections import OrderedDict\nimport logging\nimport re\n\n\nPRODUCTION_RESOURCE_DIRECTORY = 'production'\nlogger = logging.getLogger(__name__)\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    if 'timestamp.txt' not in production_folder:\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    try:\n        resource = context.unrestrictedTraverse(path)\n    except NotFound:\n        logger.warn(u'Could not find resource {0}. You may have to create it first.'.format(path))  # noqa\n        return\n\n    if isinstance(resource, FilesystemFile):\n        (directory, sep, filename) = path.rpartition('/')\n        return context.unrestrictedTraverse(directory).readFile(filename)\n\n    # calling the resource may modify the header, i.e. the content-type.\n    # we do not want this, so keep the original header intact.\n    response_before = context.REQUEST.response\n    context.REQUEST.response = response_before.__class__()\n    if hasattr(aq_base(resource), 'GET'):\n        # for FileResource\n        result = resource.GET()\n    else:\n        # any BrowserView\n        result = resource()\n    context.REQUEST.response = response_before\n    return result\n\n\nclass MetaBundleWriter(object):\n\n    def __init__(self, context, folder, name):\n        self.context = context\n        self.folder = folder\n        self.name = name\n        self.js_resources = OrderedDict()\n        self.css_resources = OrderedDict()\n        self.registry = getUtility(IRegistry)\n        self.bundles = self.registry.collectionOfInterface(\n            IBundleRegistry, prefix='plone.bundles', check=False)\n\n    def write_js(self):\n\n        # default resources\n        if self.name == 'default' and self.registry.records.get(\n            'plone.resources/jquery.js'\n        ):\n            self.js_resources['_jquery'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources/jquery.js'].value)\n            self.js_resources['_requirejs'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources.requirejs'].value)\n            self.js_resources['_configjs'] = get_resource(\n                self.context,\n                self.registry.records['plone.resources.configjs'].value)\n\n        # bundles\n        for name, bundle in self.bundles.items():\n            self.load_js_bundle(name, bundle)\n\n        self._write_out(self.js_resources, '.js')\n\n    def load_js_bundle(self, name, bundle, depth=0):\n        if depth > 10:\n            # recursion detection\n            return\n        if bundle.merge_with != self.name:\n            return\n        if bundle.jscompilation:\n            if bundle.depends and bundle.depends in self.bundles:\n                self.load_js_bundle(\n                    bundle.depends, self.bundles[bundle.depends], depth + 1)\n            if name in self.js_resources:\n                return\n            resource = get_resource(self.context, bundle.jscompilation)\n            if not resource:\n                return\n            self.js_resources[name] = resource\n\n    def _write_out(self, resources, postfix):\n        fi = StringIO()\n        for bname, script in resources.items():\n            fi.write('''\n/* Start Bundle: {0} */\n{1}\n/* End Bundle: {2} */\n'''.format(bname, script, bname))\n        self.folder.writeFile(self.name + postfix, fi)\n        resources.clear()\n\n    def load_css_bundle(self, name, bundle, depth=0):\n        if depth > 10:\n            # recursion detection\n            return\n\n        if bundle.merge_with != self.name:\n            return\n\n        if bundle.csscompilation:\n            if bundle.depends and bundle.depends in self.bundles:\n                self.load_css_bundle(\n                    bundle.depends, self.bundles[bundle.depends], depth + 1)\n            if name in self.css_resources:\n                return\n\n            css = get_resource(self.context, bundle.csscompilation)\n            if not css:\n                return\n            (path, sep, filename) = bundle.csscompilation.rpartition('/')\n            # Process relative urls:\n            # we prefix with current resource path any url not starting with\n            # '/' or http: or data:\n            css = re.sub(\n                r'''(url\\(['\"]?(?!['\"]?([a-z]+:|\\/)))''',\n                r'\\1%s/' % path,\n                css)\n            self.css_resources[name] = css\n\n    def write_css(self):\n        for name, bundle in self.bundles.items():\n            self.load_css_bundle(name, bundle)\n\n        self._write_out(self.css_resources, '.css')\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    default_writer = MetaBundleWriter(\n        context, production_folder, 'default')\n    default_writer.write_js()\n    logged_in_writer = MetaBundleWriter(\n        context, production_folder, 'logged-in')\n    logged_in_writer.write_js()\n    default_writer.write_css()\n    logged_in_writer.write_css()\n", "path": "Products/CMFPlone/resources/browser/combine.py"}]}