private void CheckCompatibility(TemplateDescription template, Entity dataModel) { IEnumerable <TemplateDescription> roots = FindCompatibleRoots(); TemplateEntity templateEntity = TemplateEntity.Decorate(dataModel.Root); List <TemplateDescription> dataModelTemplates = GetTemplateHierarchy(); if (templateEntity.HasTemplate && !roots.Any(dataModelTemplates.Contains)) { throw new TemplateIncompatibleException(template.name, templateEntity.Template.name); } List <TemplateDescription> GetTemplateHierarchy() { List <TemplateDescription> result = new List <TemplateDescription>(); if (!templateEntity.HasTemplate) { return(result); } TemplateDescription current = templateEntity.Template; result.Add(current); while (!string.IsNullOrEmpty(current?.basedOn)) { current = repository.Template(current.basedOn); result.Add(current); } return(result); } IEnumerable <TemplateDescription> FindCompatibleRoots() { List <TemplateDescription> unvisited = new List <TemplateDescription>(new [] { template }); List <TemplateDescription> visited = new List <TemplateDescription>(); List <TemplateDescription> result = new List <TemplateDescription>(); while (unvisited.Except(visited).Any()) { TemplateDescription visiting = unvisited.Except(visited).First(); visited.Add(visiting); if (visiting.isRoot) { result.Add(visiting); } else { unvisited.AddRange(visiting.Relationship .Where(relationship => repository.Template(relationship.type) != null) .Select(relationship => repository.Template(relationship.type))); } } return(result.Distinct()); } }
public async Task <int> Execute(CommandDefinition definition, ChangeObservable observable) { if (definition.BaseDefinition == newCommand) { Entity dataModel = entityFactory.Create(definition.Name, definition); IEnumerable <VirtualFile> files = await templateFileGenerator.InitalizeTemplate(dataModel, observable).ConfigureAwait(false); userInterface.WriteInformation($"Successfully created template '{dataModel.Template().name}' in {GetCommonPath(files,dataModel.Path)}."); } if (generateCommands.Contains(definition)) { Entity dataModel = entityFactory.Create(definition.Name, definition); userInterface.WriteInformation(definition.Name == "all" ? $"Generating all files for {dataModel.Root.Path}." : $"Generating all files with the '{definition.Name}' " + $"generator for {dataModel.Root.Path}."); SingleValueArgument singleValueArgument = definition.Argument <SingleValueArgument>(Constants.OutputArgumentName); await templateFileGenerator.GenerateFiles(dataModel.Root, definition.Name, singleValueArgument.Value, singleValueArgument.IsDefined, observable) .ConfigureAwait(false); userInterface.WriteInformation(definition.Name == "all" ? $"Successfully generated all files for {dataModel.Root.Path}." : $"Successfully generated all files with the '{definition.Name}' " + $"generator for {dataModel.Root.Path}."); } if (definition == deployCommand) { Entity dataModel = entityFactory.Create(definition.Name, definition); deployService.DeployFiles(dataModel); Entity root = dataModel.Root; TemplateDescription template = TemplateEntity.Decorate(root).Template; foreach (templateDeployPostStep deployPostStep in template.DeployPostStep ?? Enumerable.Empty <templateDeployPostStep>()) { IDeployStep step = deploySteps.FirstOrDefault(s => s.Identifier == deployPostStep.identifier); if (step != null) { step.Execute(dataModel, observable); } else { executionContext.WriteWarning( $"Deploy post step '{deployPostStep.identifier}' could not be executed because there is no implementation. " + $"Available implementations are:{Environment.NewLine}" + $"{string.Join(Environment.NewLine, deploySteps.Select(d => d.Identifier))}"); } } userInterface.WriteInformation($"Successfully deployed all files for {dataModel.Root.Path}."); } return(0); string GetCommonPath(IEnumerable <VirtualFile> generatedFiles, string fallback) { IEnumerable <IEnumerable <VirtualDirectory> > paths = generatedFiles.Select(GetPath); VirtualDirectory commonDirectory = paths.Transpose() .TakeWhile(d => d.Distinct().Count() == 1) .FirstOrDefault() ?.First(); return(commonDirectory?.FullName ?? fallback); IEnumerable <VirtualDirectory> GetPath(VirtualFile file) { VirtualDirectory current = file.Parent; while (current != null) { yield return(current); current = current.Parent; } } } }