def compile_sass(self, sass_filename, sass_fileurl): """ Compile the given SASS file into CSS """ compile_kwargs = { 'filename': sass_filename, 'include_paths': SassProcessor.include_paths + APPS_INCLUDE_DIRS, 'custom_functions': get_custom_functions(), } if self.sass_precision: compile_kwargs['precision'] = self.sass_precision if self.sass_output_style: compile_kwargs['output_style'] = self.sass_output_style content = sass.compile(**compile_kwargs) self.save_to_destination(content, sass_filename, sass_fileurl) self.processed_files.append(sass_filename) if self.verbosity > 1: self.stdout.write("Compiled SASS/SCSS file: '{0}'\n".format(sass_filename))
def __call__(self, path): basename, ext = os.path.splitext(path) filename = find_file(path) if filename is None: raise FileNotFoundError( "Unable to locate file {path}".format(path=path)) if ext not in self.sass_extensions: # return the given path, since it ends neither in `.scss` nor in `.sass` return path # compare timestamp of sourcemap file with all its dependencies, and check if we must recompile css_filename = basename + '.css' if not self.processor_enabled: return css_filename sourcemap_filename = css_filename + '.map' base = os.path.dirname(filename) if find_file(css_filename) and self.is_latest(sourcemap_filename, base): return css_filename # with offline compilation, raise an error, if css file could not be found. if sass is None: msg = "Offline compiled file `{}` is missing and libsass has not been installed." raise ImproperlyConfigured(msg.format(css_filename)) # otherwise compile the SASS/SCSS file into .css and store it filename_map = filename.replace(ext, '.css.map') compile_kwargs = { 'filename': filename, 'source_map_filename': filename_map, 'include_paths': self.include_paths + APPS_INCLUDE_DIRS, 'custom_functions': get_custom_functions(), } if self.sass_precision: compile_kwargs['precision'] = self.sass_precision if self.sass_output_style: compile_kwargs['output_style'] = self.sass_output_style content, sourcemap = sass.compile(**compile_kwargs) content, sourcemap = force_bytes(content), force_bytes(sourcemap) # autoprefix CSS files using postcss in external JavaScript process if self.node_npx_path and os.path.isdir(self.node_modules_dir or ''): os.environ['NODE_PATH'] = self.node_modules_dir try: options = [ self.node_npx_path, 'postcss', '--use', 'autoprefixer' ] if not settings.DEBUG: options.append('--no-map') proc = subprocess.Popen(options, stdin=subprocess.PIPE, stdout=subprocess.PIPE) proc.stdin.write(content) proc.stdin.close() autoprefixed_content = proc.stdout.read() proc.wait() except (FileNotFoundError, BrokenPipeError) as exc: logger.warning("Unable to postcss {}. Reason: {}".format( filename, exc)) else: if len(autoprefixed_content) >= len(content): content = autoprefixed_content if self.storage.exists(css_filename): self.storage.delete(css_filename) self.storage.save(css_filename, ContentFile(content)) if self.storage.exists(sourcemap_filename): self.storage.delete(sourcemap_filename) self.storage.save(sourcemap_filename, ContentFile(sourcemap)) return css_filename