Esempio n. 1
0
        public WriteOutputResult WriteOutput([NotNull] SingleTemplateRenderResults result)
        {
            if (result == null)
            {
                throw new ArgumentNullException(nameof(result));
            }

            var fileOutputPreferences = _preferencesManager.GetPreferenceInstance <FileOutputPreferences>();

            string outputFilename = fileOutputPreferences.ForcedFilename;
            object val;

            if (!fileOutputPreferences.FilenameSetting.IsNullOrEmpty() &&
                result.Configuration.TryGetValue(fileOutputPreferences.FilenameSetting, out val) &&
                val != null)
            {
                outputFilename = val.ToString();
            }

            if (outputFilename.IsNullOrEmpty())
            {
                outputFilename = $"{result.ConfigurationName}.xml";
            }

            outputFilename = Path.Combine($"{result.ConfigurationName}", outputFilename);

            if (!fileOutputPreferences.OutputDirectory.IsNullOrEmpty())
            {
                outputFilename = Path.Combine(fileOutputPreferences.OutputDirectory, outputFilename);
            }

            var fullPath = new FileInfo(outputFilename);


            Encoding encoding = result.Encoding ?? Encoding.UTF8;

            using (var stream = new MemoryStream())
                using (var writer = new StreamWriter(stream, encoding))
                {
                    writer.Write(result.RenderedResult);
                    writer.Flush();
                    stream.Position = 0;

                    bool hasChanged = !_streamComparer.AreEqual(stream, fullPath.FullName);

                    if (hasChanged && !fileOutputPreferences.InhibitWrite)
                    {
                        if (!fullPath.Directory.Exists)
                        {
                            fullPath.Directory.Create();
                        }

                        stream.Position = 0;
                        File.WriteAllBytes(fullPath.FullName, stream.ToArray());
                    }

                    return(new WriteOutputResult(fullPath.FullName, hasChanged, hasChanged));
                }
        }
        public SingleTemplateRenderResults PostProcessResult(SingleTemplateRenderResults renderResult)
        {
            //TODO: Improve on using SingleTemplateRenderResults at each step of the pipeline?

            var postProcesingPreferences = _preferencesManager.GetPreferenceInstance <PostProcessingPreferences>();

            string renderedResult = renderResult.RenderedResult;

            if (postProcesingPreferences.XmlPrettyPrintEnabled)
            {
                //TODO: Nice error message if this step fails? (e.g. are you sure this is xml?)
                renderedResult = _prettyPrintProcessor.Process(renderedResult);
            }

            return(new SingleTemplateRenderResults(
                       renderResult.Configuration,
                       renderResult.Status,
                       renderedResult,
                       renderResult.Encoding,
                       renderResult.Errors));
        }
        public GenerationResults GenerateConfigurations()
        {
            var configGenerationPreferences = _preferencesManager.GetPreferenceInstance <ConfigurationGeneratorPreferences>();

            //TODO - To API: Template Load stuff?
            ITemplate       template;
            TryCreateResult templateCreationResult = _templateFactory.TryCreateItem(configGenerationPreferences.TemplateFilePath, configGenerationPreferences.TemplateFileType, out template);

            using (template)
            {
                switch (templateCreationResult)
                {
                case TryCreateResult.FileNotFound:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.TemplateFileNotFound,
                                                            $"Specified template file not found: {configGenerationPreferences.TemplateFilePath}")));

                case TryCreateResult.FailedByExtension:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.TemplateTypeResolutionFailure,
                                                            $"Failed to resolve template type from file extension: {configGenerationPreferences.TemplateFilePath.GetFileExtension()}")));

                case TryCreateResult.FailedByType:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.UnknownTemplateType,
                                                            $"Unknown template type: {configGenerationPreferences.TemplateFileType}")));
                }

                //TODO - To API: Settings Load stuff?
                ISettingsLoader settingsLoader;
                TryCreateResult settingsLoaderCreationResult = _configurationCollectionLoaderFactory.TryCreateItem(configGenerationPreferences.SettingsFilePath,
                                                                                                                   configGenerationPreferences.SettingsFileType, out settingsLoader);

                switch (settingsLoaderCreationResult)
                {
                case TryCreateResult.FileNotFound:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.SettingsFileNotFound,
                                                            $"Specified settings file not found: {configGenerationPreferences.SettingsFilePath}")));

                case TryCreateResult.FailedByExtension:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.SettingsLoaderTypeResolutionFailure,
                                                            $"Failed to resolve settings loader type from file extension: {configGenerationPreferences.SettingsFilePath.GetFileExtension()}")));

                case TryCreateResult.FailedByType:
                    return(GenerationResults.CreateFail(new ConfigurationGeneratorError(
                                                            ConfigurationGeneratorErrorCodes.UnknownSettingsLoaderType,
                                                            $"Unknown settings loader type: {configGenerationPreferences.SettingsFileType}")));
                }

                var result = settingsLoader.LoadSettings(configGenerationPreferences.SettingsFilePath);

                if (!result.Success)
                {
                    return(GenerationResults.CreateFail(result.Error));
                }

                IEnumerable <IDictionary <string, object> > loadedSettings = result.Value;

                var configurationCreationResult = _configurationFactory.CreateConfigurations(configGenerationPreferences, loadedSettings);
                if (!configurationCreationResult.Success)
                {
                    return(GenerationResults.CreateFail(configurationCreationResult.Error));
                }

                IEnumerable <IConfiguration> configurations = configurationCreationResult.Value;

                var configurationCollectionFilterPreferences = _preferencesManager.GetPreferenceInstance <ConfigurationCollectionFilterPreferences>();

                var globallyUsedTokens = new HashSet <string>();

                configurations = _configurationCollectionFilter.Filter(
                    configurationCollectionFilterPreferences,
                    configurations,
                    token => globallyUsedTokens.Add(token)); //NOPUSH - duplicate will throw error?


                //TODO: make this pipeline async and parallelised
                //TODO: need to extract this out - or maybe move into the template itself (after all, this does represent a real template with its data)
                using (var templateStream = File.OpenRead(configGenerationPreferences.TemplateFilePath))
                {
                    var loadResults = template.Load(templateStream);

                    if (!loadResults.Success)
                    {
                        return(GenerationResults.CreateFail(loadResults.TemplateLoadErrors));
                    }

                    var singleFileGenerationResults = new List <SingleFileGenerationResult>();

                    foreach (var configuration in configurations)
                    {
                        SingleTemplateRenderResults renderResult = template.Render(configuration);

                        if (renderResult.Errors.Any())
                        {
                            singleFileGenerationResults.Add(
                                new SingleFileGenerationResult(
                                    renderResult.Configuration,
                                    null,
                                    renderResult.Errors,
                                    false,
                                    false));
                        }
                        else
                        {
                            renderResult = _postProcessorPipeline.PostProcessResult(renderResult);
                            var writeResults = _fileOutputWriter.WriteOutput(renderResult);

                            //TODO: clean this up - why is the errors collection in here?
                            singleFileGenerationResults.Add(
                                new SingleFileGenerationResult(
                                    renderResult.Configuration,
                                    writeResults.FullPath,
                                    renderResult.Errors,
                                    writeResults.FileChanged,
                                    writeResults.WasWritten));
                        }
                    }

                    return(GenerationResults.CreateSuccess(singleFileGenerationResults));
                }
            }
        }