def build(output, worklist, force=False): """Given the ``output`` target and the list of things to do, first determine if any action is necessary at all (i.e. resource may already be built), and if so, build or rebuild the asset. """ # a) Get all files involved (regardless of filters), as absolute paths. output_path = abspath(output) source_paths = [] for f, files in worklist: source_paths.extend(map(abspath, files)) # b) Check if the output file needs to be (re)created. update_needed = False if not os.path.exists(output_path): if not settings.ASSETS_AUTO_CREATE and not force: raise MergeError('\'%s\' needs to be created, but ' 'ASSETS_AUTO_CREATE is disabled' % output) else: update_needed = True elif not force: update_needed = get_updater()(output_path, source_paths) # c) If an update is required, build the asset. if update_needed or force: output = output_path try: try: for filters, files in worklist: output = merge(map(abspath, files), output, filters, output_path, close=False) finally: # might still be a string object. if hasattr(output, 'close'): output.close() except: # If there was an error above make sure we delete a possibly # partly created output file, or it might be considered "done" # from now on. if os.path.exists(output_path): os.remove(output_path) raise
def build(self, force=False, no_filters=False): """Build this bundle, meaning create the file given by the ``output`` attribute, applying the configured filters etc. A ``FileHunk`` will be returned. TODO: Support locking. When called from inside a template tag, this should lock, so that multiple requests don't all start to build. When called from the command line, there is no need to lock. """ if not self.output: raise BuildError('No output target found for %s' % self) # Determine if we really need to build, or if the output file # already exists and nothing has changed. if force: update_needed = True elif not path.exists(abspath(self.output)): if not settings.ASSETS_AUTO_CREATE: raise BuildError(('\'%s\' needs to be created, but ' 'ASSETS_AUTO_CREATE is disabled') % self) else: update_needed = True else: source_paths = [abspath(p) for p in self.get_files()] update_needed = get_updater()(abspath(self.output), source_paths) if not update_needed: # We can simply return the existing output file return FileHunk(self.output) hunk = self._build(self.output, force, no_filters) # If the output directory does not exist, create it output_directory = path.dirname(abspath(self.output)) if not path.exists(output_directory): try: makedirs(output_directory) except OSError, e: if e.errno != errno.EEXISTS: raise