private void ProcessFile(IFile sourceFile, string sourceRel, string targetDir, IGlobalRunSpec spec, IProcessor fallback, IEnumerable <KeyValuePair <IPathMatcher, IProcessor> > fileGlobProcessors, IReadOnlyList <IOperationProvider> locOperations) { IProcessor runner = fileGlobProcessors.FirstOrDefault(x => x.Key.IsMatch(sourceRel)).Value ?? fallback; if (runner == null) { throw new InvalidOperationException("At least one of [runner] or [fallback] cannot be null"); } if (locOperations != null) { runner = runner.CloneAndAppendOperations(locOperations); } if (!spec.TryGetTargetRelPath(sourceRel, out string targetRel)) { targetRel = sourceRel; } string targetPath = Path.Combine(targetDir, targetRel); //TODO: Update context with the current file & such here bool customBufferSize = TryGetBufferSize(sourceFile, out int bufferSize); bool customFlushThreshold = TryGetFlushThreshold(sourceFile, out int flushThreshold); string fullTargetDir = Path.GetDirectoryName(targetPath); sourceFile.MountPoint.EnvironmentSettings.Host.FileSystem.CreateDirectory(fullTargetDir); try { using (Stream source = sourceFile.OpenRead()) using (Stream target = sourceFile.MountPoint.EnvironmentSettings.Host.FileSystem.CreateFile(targetPath)) { if (!customBufferSize) { runner.Run(source, target); } else { if (!customFlushThreshold) { runner.Run(source, target, bufferSize); } else { runner.Run(source, target, bufferSize, flushThreshold); } } } } catch (Exception ex) { throw new ContentGenerationException($"Error while processing file {sourceFile.FullPath}", ex); } }