示例#1
0
        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;
                    }
                }
            }
        }