Example #1
0
        public void Process(BundleContext context, BundleResponse response)
        {
            if (response == null)
            {
                throw new ArgumentNullException("response");
            }

            context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

            var         lessParser = new Parser();
            ILessEngine lessEngine = CreateLessEngine(lessParser);

            foreach (FileInfo fileInfo in response.Files)
            {
                SetCurrentFilePath(lessParser, fileInfo.FullName);

                var source = File.ReadAllText(fileInfo.FullName);

                var result = lessEngine.TransformToCss(source, fileInfo.FullName);

                // NOTE: HttpContext.Items is used instead of BundleResponse.Content
                // to pass processed files
                context.HttpContext.Items.Add(fileInfo.FullName, result);

                AddFileDependencies(lessParser);
            }
        }
Example #2
0
        private static IEnumerable<string> Compile(ILessEngine engine, string inputFilePath, string outputFilePath)
        {
            Console.Write("Compiling {0} -> {1} ", inputFilePath, outputFilePath);
            try
            {
                var source = new FileReader().GetFileContents(inputFilePath);
                var css = engine.TransformToCss(source, inputFilePath);

                File.WriteAllText(outputFilePath, css);
                Console.WriteLine("[Done]");

                return new[] { inputFilePath }.Concat(engine.GetImports());
            }
            catch(IOException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[FAILED]");
                Console.WriteLine("Compilation failed: {0}", ex.Message);
                Console.WriteLine(ex.StackTrace);
                return null;
            }
        }
Example #3
0
        public void Process(BundleContext context, BundleResponse bundle)
        {
            if (bundle == null)
            {
                throw new ArgumentNullException("bundle");
            }

            context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

            var         lessParser = new Parser();
            ILessEngine lessEngine = CreateLessEngine(lessParser);

            var content = new StringBuilder(bundle.Content.Length);

            foreach (FileInfo file in bundle.Files)
            {
                SetCurrentFilePath(lessParser, file.FullName);
                string source = File.ReadAllText(file.FullName);
                content.Append(lessEngine.TransformToCss(source, file.FullName));
                content.AppendLine();

                AddFileDependencies(lessParser);
            }

            bundle.ContentType = "text/css";
            bundle.Content     = content.ToString();
        }
Example #4
0
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            DotlessConfiguration config = DotlessConfiguration.GetDefault();

            config.Logger = typeof(LessLogger);
            EngineFactory engineFactory = new EngineFactory(config);

            return(inputs.AsParallel().Select(x =>
            {
                context.Trace.Verbose("Processing Less for {0}", x.Source);
                ILessEngine engine = engineFactory.GetEngine();

                // TODO: Get rid of RefelectionMagic and this ugly hack as soon as dotless gets better external DI support
                engine.AsDynamic().Underlying.Cache = new LessCache(context.ExecutionCache);

                string path = x.Get <string>(Keys.SourceFilePath, null);
                string fileName = null;
                if (path != null)
                {
                    engine.CurrentDirectory = Path.GetDirectoryName(path);
                    fileName = Path.GetFileName(path);
                }
                else
                {
                    engine.CurrentDirectory = context.InputFolder;
                    fileName = Path.GetRandomFileName();
                }
                string content = engine.TransformToCss(x.Content, fileName);
                return x.Clone(content);
            }));
        }
Example #5
0
        public string TransformToCss(string source, string fileName)
        {
            var sb         = new StringBuilder();
            var parameters = parameterSource.GetParameters()
                             .Where(ValueIsNotNullOrEmpty);

            var parser = new Parser.Parser();

            foreach (var parameter in parameters)
            {
                var variableDeclaration = string.Format("@{0}: {1};", parameter.Key, parameter.Value);

                try
                {
                    // Attempt to evaluate the generated variable to see if it's OK
                    parser.Parse(variableDeclaration, "").ToCSS(new Env());
                    sb.AppendLine(variableDeclaration);
                }
                catch (ParserException)
                {
                    // Result wasn't valid LESS, output a comment instead
                    sb.AppendFormat("/* Omitting variable '{0}'. The expression '{1}' is not valid. */", parameter.Key,
                                    parameter.Value);
                    sb.AppendLine();
                }
            }
            sb.Append(source);
            return(Underlying.TransformToCss(sb.ToString(), fileName));
        }
Example #6
0
        public void ProcessRequest(HttpContextBase context)
        {
            var physicalPath = context.Server.MapPath(context.Request.Path);
            var querystring  = context.Request.QueryString.ToString();
            var response     = context.Response;

            try
            {
                var source     = fileWrapper.GetFileString(physicalPath);
                var lessEngine = (LessEngine)((ParameterDecorator)engine).Underlying;
                ((LessLogger)lessEngine.Logger).Response = response;
                var result = engine.TransformToCss(source, physicalPath + (string.IsNullOrWhiteSpace(querystring) ? string.Empty : "?" + querystring));
                response.ContentType = "text/css";
                if (!string.IsNullOrEmpty(result))
                {
                    response.Write(result);
                }
            }
            catch (System.IO.FileNotFoundException ex)
            {
                response.StatusCode = 404;
                response.Write("/* File Not Found while parsing: " + ex.Message + " */");
            }
            catch (System.Exception ex)
            {
                response.StatusCode = 500;
                response.Write("/* Error in less parsing: " + ex + " */");
            }
        }
Example #7
0
        /// <inheritdoc />
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            DotlessConfiguration config = DotlessConfiguration.GetDefault();

            config.Logger = typeof(LessLogger);
            EngineFactory    engineFactory    = new EngineFactory(config);
            FileSystemReader fileSystemReader = new FileSystemReader(context.FileSystem);

            return(inputs.AsParallel().Select(context, input =>
            {
                Trace.Verbose("Processing Less for {0}", input.SourceString());
                ILessEngine engine = engineFactory.GetEngine();

                // TODO: Get rid of RefelectionMagic and this ugly hack as soon as dotless gets better external DI support
                engine.AsDynamic().Underlying.Cache = new LessCache(context.ExecutionCache);
                engine.AsDynamic().Underlying.Underlying.Parser.Importer.FileReader = fileSystemReader;

                FilePath path = input.FilePath(Keys.RelativeFilePath);
                string fileName = null;
                if (path != null)
                {
                    engine.CurrentDirectory = path.Directory.FullPath;
                    fileName = path.FileName.FullPath;
                }
                else
                {
                    engine.CurrentDirectory = string.Empty;
                    fileName = Path.GetRandomFileName();
                }
                string content = engine.TransformToCss(input.Content, fileName);
                return context.GetDocument(input, content);
            }));
        }
Example #8
0
        public void Execute()
        {
            var localPath = Http.Context.Request.Url.LocalPath;

            var source = FileReader.GetFileContents(localPath);

            Response.WriteCss(Engine.TransformToCss(source, localPath));
        }
        private static string TransformCss(Parser lessParser, FileInfo bundleFile, ILessEngine lessEngine)
        {
            SetCurrentFilePath(lessParser, bundleFile.FullName);
            string source = File.ReadAllText(bundleFile.FullName);
            string css    = lessEngine.TransformToCss(source, bundleFile.FullName);

            return(css);
        }
Example #10
0
        public void Execute()
        {
            Engine.CurrentDirectory = Http.Context.Server.MapPath("~");

            var localPath = Http.Context.Request.Url.LocalPath;

            var source = FileReader.GetFileContents(localPath);

            Response.WriteHeaders();
            Response.WriteCss(Engine.TransformToCss(source, localPath));
        }
Example #11
0
        public string TransformToCss(string source, string fileName)
        {
            var sb         = new StringBuilder();
            var parameters = parameterSource.GetParameters()
                             .Where(ValueIsNotNullOrEmpty);

            foreach (var parameter in parameters)
            {
                sb.AppendFormat("@{0}: {1};\n", parameter.Key, parameter.Value);
            }
            sb.Append(source);
            return(Underlying.TransformToCss(sb.ToString(), fileName));
        }
Example #12
0
        public Task <LessCompilationResult> CompileAsync(string content, PathString virtualPathPrefix, string filePath, IFileProvider fileProvider, PathString outputPath, CancellationToken token)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            token.ThrowIfCancellationRequested();

            string fileBasePath, fileName;

            if (filePath != null)
            {
                filePath        = UrlUtils.NormalizePath(filePath.Replace('\\', '/'));
                fileName        = UrlUtils.GetFileNameSegment(filePath, out StringSegment basePathSegment).Value;
                basePathSegment = UrlUtils.NormalizePathSegment(basePathSegment, trailingNormalization: PathNormalization.ExcludeSlash);
                fileBasePath    = basePathSegment.Value;
            }
            else
            {
                fileBasePath = "/";
                fileName     = string.Empty;
            }

            ILessEngine engine = _engineFactory.Create(fileBasePath, virtualPathPrefix, fileProvider, outputPath, token);

            Exception transformException = null;

            try { content = engine.TransformToCss(content, fileName); }
            catch (FileNotFoundException ex) { transformException = ex; }

            if (transformException != null || !engine.LastTransformationSuccessful)
            {
                if (transformException == null && engine is LessEngine lessEngine)
                {
                    transformException = lessEngine.LastTransformationError;
                }

                filePath = filePath ?? "(content)";

                const string messageFormat = "Less compilation of '{0}' failed.";

                _logger.LogError(string.Format(messageFormat, "{FILEPATH}") + Environment.NewLine + "{REASON}", filePath, transformException?.Message ?? "Unknown reason.");

                throw new BundlingErrorException(string.Format(messageFormat, filePath), transformException);
            }

            return(Task.FromResult(new LessCompilationResult(content, engine.GetImports().Select(path => UrlUtils.NormalizePath(path, canonicalize: true)).ToArray())));
        }
Example #13
0
        public void Process(BundleContext context, BundleResponse bundle)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (bundle == null)
            {
                throw new ArgumentNullException("bundle");
            }

            context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

            var         lessParser = new Parser();
            ILessEngine lessEngine = CreateLessEngine(lessParser);

            var content = new StringBuilder(bundle.Content.Length);

            var bundleFiles = new List <BundleFile>();

            foreach (var bundleFile in bundle.Files)
            {
                bundleFiles.Add(bundleFile);

                var name = context.HttpContext.Server.MapPath(bundleFile.VirtualFile.VirtualPath);
                SetCurrentFilePath(lessParser, name);
                using (var stream = bundleFile.VirtualFile.Open())
                    using (var reader = new StreamReader(stream))
                    {
                        string source = reader.ReadToEnd();
                        content.Append(lessEngine.TransformToCss(source, name));
                        content.AppendLine();
                    }

                bundleFiles.AddRange(GetFileDependencies(lessParser));
            }

            if (BundleTable.EnableOptimizations)
            {
                // include imports in bundle files to register cache dependencies
                bundle.Files = bundleFiles.Distinct();
            }

            bundle.ContentType = "text/css";
            bundle.Content     = content.ToString();
        }
Example #14
0
        /// <inheritdoc />
        public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
        {
            DotlessConfiguration config = DotlessConfiguration.GetDefault();

            config.Logger = typeof(LessLogger);
            EngineFactory    engineFactory    = new EngineFactory(config);
            FileSystemReader fileSystemReader = new FileSystemReader(context.FileSystem);

            return(inputs.AsParallel().Select(context, input =>
            {
                Trace.Verbose("Processing Less for {0}", input.SourceString());
                ILessEngine engine = engineFactory.GetEngine();

                // TODO: Get rid of RefelectionMagic and this ugly hack as soon as dotless gets better external DI support
                engine.AsDynamic().Underlying.Cache = new LessCache(context.ExecutionCache);
                engine.AsDynamic().Underlying.Underlying.Parser.Importer.FileReader = fileSystemReader;

                // Less conversion
                FilePath path = _inputPath.Invoke <FilePath>(input, context);
                if (path != null)
                {
                    engine.CurrentDirectory = path.Directory.FullPath;
                }
                else
                {
                    engine.CurrentDirectory = string.Empty;
                    path = new FilePath(Path.GetRandomFileName());
                    Trace.Warning($"No input path found for document {input.SourceString()}, using {path.FileName.FullPath}");
                }
                string content = engine.TransformToCss(input.Content, path.FileName.FullPath);

                // Process the result
                FilePath cssPath = path.ChangeExtension("css");
                return context.GetDocument(
                    input,
                    context.GetContentStream(content),
                    new MetadataItems
                {
                    { Keys.RelativeFilePath, cssPath },
                    { Keys.WritePath, cssPath }
                });
            }));
        }
Example #15
0
        public string TransformToCss(string source, string fileName)
        {
            //Compute Cache Key
            var hash     = ComputeContentHash(source);
            var cacheKey = fileName + hash;

            if (!Cache.Exists(cacheKey))
            {
                Logger.Debug(String.Format("Inserting cache entry for {0}", cacheKey));

                var css = Underlying.TransformToCss(source, fileName);
                var dependancies = new[] { fileName }.Concat(GetImports());

                Cache.Insert(cacheKey, dependancies, css);

                return(css);
            }
            Logger.Debug(String.Format("Retrieving cache entry {0}", cacheKey));
            return(Cache.Retrieve(cacheKey));
        }
Example #16
0
        public Task <LessCompilationResult> CompileAsync(string content, string virtualPathPrefix, string filePath, IFileProvider fileProvider, CancellationToken token)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            token.ThrowIfCancellationRequested();

            string fileBasePath, virtualBasePath, fileName;

            if (filePath != null)
            {
                fileBasePath    = Path.GetDirectoryName(filePath).Replace('\\', '/');
                virtualBasePath = new PathString(virtualPathPrefix).Add(fileBasePath);
                fileName        = Path.GetFileName(filePath);
            }
            else
            {
                fileBasePath = virtualBasePath = fileName = null;
            }

            ILessEngine engine = _engineFactory.Create(fileBasePath ?? string.Empty, virtualBasePath ?? string.Empty, fileProvider);

            content = engine.TransformToCss(content, fileName);

            if (!engine.LastTransformationSuccessful)
            {
                _logger.LogWarning($"Less compilation of '{{FILEPATH}}' failed:{Environment.NewLine}{{REASON}}",
                                   (filePath ?? "(content)"),
                                   (engine is LessEngine lessEngine ? lessEngine.LastTransformationError?.Message : null) ?? "Unknown reason.");

                content = null;
            }

            return(Task.FromResult(
                       content != null ?
                       new LessCompilationResult(content, engine.GetImports().ToArray()) :
                       LessCompilationResult.Failure));
        }
Example #17
0
        private static IEnumerable <string> CompileImpl(ILessEngine engine, string inputFilePath, string outputFilePath)
        {
            var currentDir = Directory.GetCurrentDirectory();

            try
            {
                Console.WriteLine("{0} -> {1}", inputFilePath, outputFilePath);
                var directoryPath = Path.GetDirectoryName(inputFilePath);
                var source        = new dotless.Core.Input.FileReader().GetFileContents(inputFilePath);
                Directory.SetCurrentDirectory(directoryPath);
                var css = engine.TransformToCss(source, inputFilePath);
                File.WriteAllText(outputFilePath, css);
                Console.WriteLine("[Done]");

                var files = new List <string>();
                files.Add(inputFilePath);
                foreach (var file in engine.GetImports())
                {
                    files.Add(Path.Combine(directoryPath, Path.ChangeExtension(file, "less")));
                }
                engine.ResetImports();
                return(files);
            }
            catch (IOException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[FAILED]");
                Console.WriteLine("Compilation failed: {0}", ex.Message);
                Console.WriteLine(ex.StackTrace);
                return(null);
            }
            finally
            {
                Directory.SetCurrentDirectory(currentDir);
            }
        }
    public void ProcessRequest(HttpContext context)
    {
        var    request   = context.Request;
        var    response  = context.Response;
        var    user      = context.User;
        string assetUrl  = request.Url.LocalPath;
        string assetPath = context.Server.MapPath(assetUrl);
        //load less file into the data.
        var data = "";

        using (var file = new StreamReader(assetPath))
        {
            data = file.ReadToEnd();
        }
        DotlessConfiguration lessEngineConfig = DotlessConfiguration.GetDefault();

        lessEngineConfig.MapPathsToWeb       = false;
        lessEngineConfig.CacheEnabled        = false;
        lessEngineConfig.DisableUrlRewriting = false;
        lessEngineConfig.Web          = false;
        lessEngineConfig.MinifyOutput = true;
        lessEngineConfig.LessSource   = typeof(VirtualFileReader);
        var         lessEngineFactory = new EngineFactory(lessEngineConfig);
        ILessEngine lessEngine        = lessEngineFactory.GetEngine();
        string      vars = "";

        //TODO set default for vars
        if (user != null)
        {
            //TODO get vars for user
        }
        var content = lessEngine.TransformToCss(string.Format("{0}{1}", vars, data), null);

        // Output text content of asset
        response.ContentType = "text/css";
        response.Write(content);
        response.End();
    }
Example #19
0
        public void Process(BundleContext context, BundleResponse bundle)
        {
            context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();

            var content = new StringBuilder();

            var bundleFiles = new List <BundleFile>();

            foreach (var bundleFile in bundle.Files)
            {
                var         lessParser = new Parser();
                ILessEngine lessEngine = this.CreateLessEngine(lessParser);

                bool foundMinimizedVersion = false;
                bundleFiles.Add(bundleFile);

                if (BundleTable.EnableOptimizations)
                {
                    var ext = Path.GetExtension(bundleFile.VirtualFile.VirtualPath);
                    if (ext != null && ext.Equals(".less", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var filepath          = bundleFile.VirtualFile.VirtualPath;
                        var minimizedFileName = string.Format(
                            "{0}.min.css",
                            filepath.Substring(0, filepath.LastIndexOf(ext, StringComparison.Ordinal)));
                        var virtualPathProvider = HostingEnvironment.VirtualPathProvider;
                        if (virtualPathProvider.FileExists(minimizedFileName))
                        {
                            var minimizedFile = virtualPathProvider.GetFile(minimizedFileName);
                            foundMinimizedVersion = true;
                            using (var reader = new StreamReader(minimizedFile.Open()))
                            {
                                content.Append(reader.ReadToEnd());
                                content.AppendLine();

                                bundleFiles.Add(new BundleFile(minimizedFile.VirtualPath, minimizedFile));
                            }
                        }
                    }
                }

                if (!foundMinimizedVersion)
                {
                    this.SetCurrentFilePath(lessParser, bundleFile.VirtualFile.VirtualPath);

                    using (var reader = new StreamReader(VirtualPathProvider.OpenFile(bundleFile.VirtualFile.VirtualPath)))
                    {
                        var fileContent = reader.ReadToEnd();
                        content.Append(lessEngine.TransformToCss(fileContent, bundleFile.VirtualFile.VirtualPath));
                        content.AppendLine();

                        bundleFiles.AddRange(this.GetFileDependencies(lessParser).Select(f => new BundleFile(f.VirtualPath, f)));
                    }
                }
            }

            if (BundleTable.EnableOptimizations)
            {
                // include imports in bundle files to register cache dependencies
                bundle.Files = bundleFiles.Distinct().ToList();
            }

            bundle.ContentType = "text/css";
            bundle.Content     = content.ToString();
        }
 public string Compile(string less)
 {
     return(_engine.TransformToCss(less, null));
 }
Example #21
0
 public string TransformToCss(string source, string fileName)
 {
     return(underlying.TransformToCss(source, fileName));
 }
Example #22
0
 public static string Parse(ILessEngine engine, string less, DotlessConfiguration config)
 {
     return(engine.TransformToCss(less, null));
 }
Example #23
0
        private static IEnumerable<string> CompileImpl(ILessEngine engine, string inputFilePath, string outputFilePath)
        {
            var currentDir = Directory.GetCurrentDirectory();
            try
            {
                Console.WriteLine("{0} -> {1}", inputFilePath, outputFilePath);
                var directoryPath = Path.GetDirectoryName(inputFilePath);
                var source = new dotless.Core.Input.FileReader().GetFileContents(inputFilePath);
                Directory.SetCurrentDirectory(directoryPath);
                var css = engine.TransformToCss(source, inputFilePath);
                File.WriteAllText(outputFilePath, css);
                Console.WriteLine("[Done]");

                var files = new List<string>();
                files.Add(inputFilePath);
                foreach (var file in engine.GetImports())
                    files.Add(Path.Combine(directoryPath, Path.ChangeExtension(file, "less")));
                engine.ResetImports();
                return files;
            }
            catch (IOException)
            {
                throw;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[FAILED]");
                Console.WriteLine("Compilation failed: {0}", ex.Message);
                Console.WriteLine(ex.StackTrace);
                return null;
            }
            finally
            {
                Directory.SetCurrentDirectory(currentDir);
            }
        }
Example #24
0
        internal static string Process(ref IEnumerable <BundleFile> files)
        {
            DotlessConfiguration lessConfig = new WebConfigConfigurationLoader().GetConfiguration();

            if (!lessConfig.LessSource.GetInterfaces().Contains(typeof(IFileReaderWithResolver)))
            {
                lessConfig.LessSource = typeof(LessVirtualFileReader);
            }

            // system.Web.Optimization cache is used instead
            lessConfig.CacheEnabled = false;

            var content = new StringBuilder();

            var targetFiles = new List <BundleFile>();

            foreach (BundleFile bundleFile in files)
            {
                // initialize the less engine once for each file.
                // this is to prevent leaking state between files
                ILessEngine lessEngine           = LessWeb.GetEngine(lessConfig);
                LessEngine  underlyingLessEngine = lessEngine.ResolveLessEngine();
                Parser      lessParser           = underlyingLessEngine.Parser;

                targetFiles.Add(bundleFile);
                string filePath = bundleFile.IncludedVirtualPath;
                filePath = filePath.Replace('\\', '/');
                filePath = VirtualPathUtility.ToAppRelative(filePath);

                lessParser.SetCurrentFilePath(filePath);
                string source    = bundleFile.ApplyTransforms();
                string extension = VirtualPathUtility.GetExtension(filePath);

                // if plain CSS file, do not transform LESS
                if (lessConfig.ImportAllFilesAsLess ||
                    ".less".Equals(extension, StringComparison.InvariantCultureIgnoreCase) ||
                    ".less.css".Equals(extension, StringComparison.InvariantCultureIgnoreCase))
                {
                    string lessOutput = lessEngine.TransformToCss(source, filePath);

                    // pass the transformation result if successful
                    if (lessEngine.LastTransformationSuccessful)
                    {
                        source = lessOutput;
                    }
                    else
                    {
                        // otherwise write out error message.
                        // the transformation error is logged in LessEngine.TransformToCss
                        if (lessConfig.Debug)
                        {
                            content.AppendLine(string.Format(
                                                   "/* Error occurred in LESS transformation of the file: {0}. Please see details in the dotless log */",
                                                   bundleFile.IncludedVirtualPath));
                        }
                        continue;
                    }
                }

                source = ConvertUrlsToAbsolute(bundleFile.IncludedVirtualPath, source);

                content.AppendLine(source);

                BundleFile[] fileDependencies = GetFileDependencies(underlyingLessEngine).ToArray();
                targetFiles.AddRange(fileDependencies);

                DependencyCache.SaveFileDependencies(filePath, fileDependencies.Select(file => file.IncludedVirtualPath).ToArray());
            }

            // include imports in bundle files to register cache dependencies
            files = BundleTable.EnableOptimizations ? targetFiles.Distinct() : targetFiles;

            return(content.ToString());
        }
Example #25
0
        private static IEnumerable<string> CompileImpl(ILessEngine engine, string inputFilePath, string outputFilePath, StringBuilder sb, bool silent)
        {
            try
            {
                if (!silent)
                {
                    sb.AppendFormat("{0} -> {1}\n", inputFilePath, outputFilePath);
                }

                var directoryPath = Path.GetDirectoryName(inputFilePath);
                var source = new dotless.Core.Input.FileReader(directoryPath).GetFileContents(inputFilePath);
                var css = engine.TransformToCss(source, inputFilePath);
                File.WriteAllText(outputFilePath, css);

                if (!silent)
                {
                    sb.AppendLine("[Done]");
                }

                var files = new List<string>();
                files.Add(inputFilePath);
                foreach (var file in engine.GetImports())
                {
                    files.Add(Path.Combine(directoryPath, Path.ChangeExtension(file, "less")));
                }
                engine.ResetImports();
                return files;
            }
            catch (IOException)
            {
                throw;
            }
            catch (Exception ex)
            {
                if (silent)
                {
                    // Need to know the file now
                    sb.AppendFormat("{0} -> {1}\n", inputFilePath, outputFilePath);
                }

                sb.AppendLine("[FAILED]");
                sb.AppendFormat("Compilation failed: {0}\n", ex.Message);
                sb.AppendLine(ex.StackTrace);
                return null;
            }
        }