示例#1
0
        public void Build(Project model)
        {
            LogMessage($"Scanning project {model.ProjectFilePath} for eventsource definitions");

            model.ProjectBasePath = System.IO.Path.GetDirectoryName(model.ProjectFilePath);

            var projectItems = new List <ProjectItem>();

            if (model.ProjectFilePath == null)
            {
                LogMessage($"Could not find basePath of {model.ProjectFilePath}");
            }
            if (model.ProjectBasePath != null)
            {
                var projectName       = System.IO.Path.GetFileNameWithoutExtension(model.ProjectFilePath);
                var configuration     = "Debug";
                var projectTool       = new FG.Utils.BuildTools.ProjectTool(model.ProjectFilePath, null);
                var projectFiles      = projectTool.ScanFilesInProjectFolder();
                var projectReferences = projectTool.GetProjectReferences();
                var projectProperties = projectTool.GetProjectProperties(configuration, model.Platform);
                LogMessage($"Loaded project {model.ProjectFilePath} from XML with {projectFiles.Count()} items");


                var rootNamespace = projectProperties.ContainsKey("RootNamespace") ? projectProperties["RootNamespace"] : projectName;
                var assemblyName  = projectProperties.ContainsKey("AssemblyName") ? projectProperties["AssemblyName"] : projectName;
                model.RootNamespace = rootNamespace;
                model.AssemblyName  = assemblyName;

                var hasEventSource = false;
                foreach (var projectItem in projectFiles.Where(item =>
                                                               item.Name.EndsWith(@".eventsource.json", StringComparison.InvariantCultureIgnoreCase)))
                {
                    projectItems.Add(new ProjectItem <EventSourceModel>(ProjectItemType.EventSourceDefinition, projectItem.Path)
                    {
                        Include       = projectItem.Name,
                        RootNamespace = rootNamespace,
                        AssemblyName  = assemblyName,
                    });
                    hasEventSource = true;
                }

                foreach (var projectItem in projectFiles.Where(item =>
                                                               item.Name.Matches(@"*.eventsource.output.json", StringComparison.InvariantCultureIgnoreCase, useWildcards: true) &&
                                                               item.IncludeType == "Content"))
                {
                    var projectItemFilePath = projectItem.Path;
                    projectItems.Add(new ProjectItem <ProjectSummary>(ProjectItemType.ProjectSummary, projectItemFilePath)
                    {
                        Include = projectItem.Name,
                    });
                }

                var autogeneratedMetadataTypes = new[]
                {
                    ProjectItemType.ProjectSummary,
                    ProjectItemType.DefaultGeneratedEventSourceDefinition,
                    ProjectItemType.EventSource,
                    ProjectItemType.EventSourceLoggerPartial,
                    ProjectItemType.LoggerImplementation
                }
                .Select(metadata => Enum.GetName(typeof(ProjectItemType), metadata))
                .ToArray();
                foreach (var projectItem in projectFiles.Where(item =>
                                                               item.Name.Matches(@"(^|\\)I[^\\]*Logger.cs", StringComparison.InvariantCultureIgnoreCase, useWildcards: false) &&
                                                               item.IncludeType == "Compile" &&
                                                               !autogeneratedMetadataTypes.Contains((item.Properties.ContainsKey("AutoGenerated") ? item.Properties["AutoGenerated"] : "") ?? "")))
                {
                    var projectItemFilePath = projectItem.Path;
                    projectItems.Add(new ProjectItem <LoggerTemplateModel>(ProjectItemType.LoggerInterface, projectItemFilePath)
                    {
                        Include = projectItem.Name
                    });
                }

                foreach (var projectItem in projectFiles.Where(item =>
                                                               item.Name.Matches(@"(^|\\)[^\\]*Extension.cs", StringComparison.InvariantCultureIgnoreCase, useWildcards: false) &&
                                                               item.IncludeType == "Compile" &&
                                                               !autogeneratedMetadataTypes.Contains((item.Properties.ContainsKey("AutoGenerated") ? item.Properties["AutoGenerated"] : "") ?? "")))
                {
                    var projectItemFilePath = projectItem.Path;
                    projectItems.Add(new ProjectItem(ProjectItemType.BuilderExtension, projectItemFilePath)
                    {
                        Include = projectItem.Name
                    });
                }

                var outputPath       = projectTool.GetProjectOutputPath(configuration, null);
                var buildOutputPath  = PathExtensions.GetAbsolutePath(model.ProjectBasePath, outputPath);
                var outputPathExists = System.IO.Directory.Exists(buildOutputPath);
                if (!outputPathExists)
                {
                    outputPath       = projectTool.GetProjectOutputPath(configuration, "x64");
                    buildOutputPath  = PathExtensions.GetAbsolutePath(model.ProjectBasePath, outputPath);
                    outputPathExists = System.IO.Directory.Exists(buildOutputPath);
                }

                if (outputPathExists)
                {
                    var outputFiles = System.IO.Directory.GetFiles(buildOutputPath, "*.*", SearchOption.AllDirectories);
                    foreach (var outputFile in outputFiles)
                    {
                        var outputFileType = System.IO.Path.GetExtension(outputFile);
                        if (outputFileType == ".dll" || outputFileType == ".exe")
                        {
                            var referenceFilePath = outputFile;
                            var referenceName     = System.IO.Path.GetFileNameWithoutExtension(outputFile);
                            projectItems.Add(
                                new ProjectItem(ProjectItemType.Reference, referenceFilePath)
                            {
                                Include = referenceName
                            });
                        }
                    }
                }

                if (!hasEventSource)
                {
                    var defaultEventSourceName = $"{assemblyName}EventSource";
                    defaultEventSourceName = defaultEventSourceName.RemoveNonWordCharacters();

                    var include             = $"{defaultEventSourceName}.eventsource.json";
                    var projectItemFilePath = System.IO.Path.Combine(model.ProjectBasePath, include);
                    projectItems.Add(new ProjectItem <EventSourceModel>(ProjectItemType.DefaultGeneratedEventSourceDefinition, projectItemFilePath)
                    {
                        Include       = include,
                        RootNamespace = rootNamespace,
                        AssemblyName  = assemblyName,
                    });
                }
            }

            model.ProjectItems = projectItems.ToArray();
        }
示例#2
0
        private void AddGeneratedOutputsToProject(Project model, bool saveChanges = true)
        {
            var projectFilePath = model.ProjectFilePath;
            var includes        = model.ProjectItems.Where(p => p.ItemType != ProjectItemType.Reference && p.ItemType != ProjectItemType.ProjectReference && p.ItemType != ProjectItemType.Unknown);

            LogMessage($"Loading projectfile {projectFilePath} to include new files");

            var updatedProjectFile          = false;
            var loadedFromProjectCollection = false;

            var project = new FG.Utils.BuildTools.ProjectTool(projectFilePath, null);

            LogMessage($"Loaded project {projectFilePath} from XML to {project.Name}, {(project.IsCpsDocument ? "as CPS project" : "as classic project")}");


            var projectFiles  = project.ScanFilesInProjectFolder();
            var existingItems = new List <FG.Utils.BuildTools.FileReference>();

            existingItems.AddRange(projectFiles.Where(item => item.Properties.ContainsKey("AutoGenerated")));

            // Add or check that it already exists
            foreach (var include in includes)
            {
                var includeName         = model.GetIncludeName(include);
                var filePath            = include.Name;
                var isAutogeneratedType = include.ItemType.IsAutogeneratedType();
                try
                {
                    var matchingItem = projectFiles.FirstOrDefault(item => item.Name.Matches($"{includeName}", StringComparison.InvariantCultureIgnoreCase));

                    var metadata = include.ItemType.Name();
                    IDictionary <string, string> properties = new Dictionary <string, string>();
                    if (include.ItemType == ProjectItemType.DefaultGeneratedEventSourceDefinition)
                    {
                        var hash = include.Output.ToMD5().ToHex();
                        properties = new Dictionary <string, string>
                        {
                            { "AutoGenerated", metadata },
                            { "Hash", hash }
                        };
                    }
                    else if (isAutogeneratedType)
                    {
                        properties = new Dictionary <string, string>
                        {
                            { "AutoGen", "true" },
                            { "AutoGenerated", metadata },
                            { "DependentUpon", include.DependentUpon.Include.RemoveCommonPrefix(includeName, System.IO.Path.DirectorySeparatorChar) },
                        };
                    }

                    var fileType    = System.IO.Path.GetExtension(include.Include);
                    var includeType = (include.ItemType == ProjectItemType.DefaultGeneratedEventSourceDefinition ||
                                       include.ItemType == ProjectItemType.ProjectSummary) ? "None" : fileType == ".cs" ? "Compile" : "Content";

                    if (matchingItem == null || !FG.Utils.BuildTools.DictionaryExtensions.AreEquivalent(matchingItem.Properties, properties))
                    {
                        //var metadata = Enum.GetName(typeof(ProjectItemType), include.ItemType);
                        updatedProjectFile = true;
                        var addedItems = new List <string>();
                        project.AddFileToProject(filePath, includeType, properties);
                        addedItems.Add(includeName);

                        foreach (var addedItem in addedItems)
                        {
                            LogMessage($"Including project item {addedItem}");
                            existingItems.RemoveAll(fr => fr.Name == addedItem);
                        }
                    }
                    else
                    {
                        LogMessage($"Matched existing project item {matchingItem.Name}");
                        existingItems.Remove(matchingItem);
                    }
                }
                catch (Exception ex)
                {
                    LogError($"Failed to include/add {includeName} - {ex.Message}\n{ex}");
                }
            }
            // Check if we should remove the AutoGenerated DefaultEventSource.eventsource
            var autoGeneratedDefaultEventSource = existingItems.FirstOrDefault(
                existingItem => existingItem.Properties.ContainsKey("AutoGenerated") && existingItem.Properties["AutoGenerated"] == "DefaultEventSource");

            if (autoGeneratedDefaultEventSource != null)
            {
                if (autoGeneratedDefaultEventSource.Name != "DefaultEventSource.cs")
                {
                    updatedProjectFile = true;
                    LogMessage($"Updating Project Metadata for {autoGeneratedDefaultEventSource.Name} as it has been changed from it's original state");
                    var properties = autoGeneratedDefaultEventSource.Properties;
                    if (properties.ContainsKey("AutoGenerated"))
                    {
                        properties.Remove("AutoGenerated");
                    }
                    project.AddFileToProject(autoGeneratedDefaultEventSource.Name, autoGeneratedDefaultEventSource.IncludeType, properties);
                    existingItems.Remove(autoGeneratedDefaultEventSource);
                }
                else
                {
                    var hash = autoGeneratedDefaultEventSource.Properties.ContainsKey("Hash") ? autoGeneratedDefaultEventSource.Properties["Hash"] : "";

                    var filePath    = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(projectFilePath), autoGeneratedDefaultEventSource.Name);
                    var fileContent = System.IO.File.ReadAllText(filePath);

                    var hashCheck = StringMatchExtensions.ToHex(StringMatchExtensions.ToMD5(fileContent));

                    if (hash != hashCheck)
                    {
                        updatedProjectFile = true;
                        LogMessage($"Updating Project Metadata for {autoGeneratedDefaultEventSource.Name} as it's content been changed from it's original state");
                        var properties = autoGeneratedDefaultEventSource.Properties;
                        if (properties.ContainsKey("AutoGenerated"))
                        {
                            properties.Remove("AutoGenerated");
                        }
                        project.AddFileToProject(autoGeneratedDefaultEventSource.Name, autoGeneratedDefaultEventSource.IncludeType, properties);
                        existingItems.Remove(autoGeneratedDefaultEventSource);
                    }
                }
            }

            // Remove old items that are no longer referenced
            foreach (var existingItem in existingItems)
            {
                LogMessage($"Removing existing project item {existingItem.Name}");
            }
            if (existingItems.Count > 0)
            {
                updatedProjectFile = true;
                foreach (var fileReference in existingItems)
                {
                    project.RemoveFileFromProject(fileReference.Path);
                }
            }

            if (!updatedProjectFile)
            {
                LogMessage($"Igoring to save project file {projectFilePath} - no changes performed");
            }
            else
            {
                if (saveChanges)
                {
                    LogMessage($"Saving project file {projectFilePath}");
                    project.Save();
                }
                else
                {
                    LogMessage($"Project file {projectFilePath} changed");
                    var rawXml = System.IO.File.ReadAllText(project.FilePath);

                    LogMessage(rawXml);
                }
            }
        }