using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Needle.Engine.Codegen; using Needle.Engine.Core.References; using Needle.Engine.Utils; using UnityEditor; namespace Needle.Engine.ProjectBundle { internal static class NodeModulesComponentGeneration { private static readonly ComponentGeneratorRunner generator = new ComponentGeneratorRunner(); /// /// Generate c# component stubs for node_module packages with needle engine typescript components /// /// The directory to scan for components to generate /// The directory where the web project exists internal static async void GenerateComponents(string packageDirectory, string baseDirectory, string versionDirectory, string webProjectDirectory) { if (!Directory.Exists(webProjectDirectory)) return; if (!CodeWatcher.TryFindCodeGeneratorPath(webProjectDirectory, out var generatorInstallPath)) { return; } generatorInstallPath = Path.GetDirectoryName(generatorInstallPath); using (new AssemblyReloadLockScope()) { var versionDirInfo = new DirectoryInfo(versionDirectory); var outputDirectory = versionDirInfo.FullName + "/codegen"; // var outputDirectory = $"{baseDirectory}/{version}"; // If we already generated types once we can skip this step if (Directory.Exists(outputDirectory)) { var directoryHasFiles = Directory.EnumerateFiles(outputDirectory, "*", SearchOption.AllDirectories) .Any(); if (directoryHasFiles) return; } if(!versionDirInfo.Exists) Directory.CreateDirectory(versionDirInfo.FullName); // If the directory doesnt exist we want to scan for all types once more TypesGenerator.GenerateTypesIfNecessary(true); var types = new List(); TypeScanner.FindTypesExcludingNodeModules(packageDirectory, types); foreach (var type in types) { var relativePath = type.FilePath.RelativeTo(packageDirectory); var targetDirectory = $"{outputDirectory}/{Path.GetDirectoryName(relativePath)}"; await generator.Run(generatorInstallPath, type.FilePath, targetDirectory); } if (types.Count <= 0) { File.WriteAllText(outputDirectory + "/empty", ""); } else { // If no cs file was generated we want to put an empty marker in the directory // Just so we know we dont have to re-generate and can check it into source control var anyFiles = Directory.EnumerateFiles(outputDirectory, "*", SearchOption.AllDirectories).Any(); if (!anyFiles) { await FileUtils.DeleteDirectoryRecursive(outputDirectory); } } } AssetDatabase.Refresh(); } } }