public void FolderExclude() { var matcher = new Matcher(); matcher.AddInclude(@"**/*.*"); matcher.AddExclude(@"obj"); matcher.AddExclude(@"bin"); matcher.AddExclude(@".*"); ExecuteAndVerify(matcher, @"src/project", "src/project/source1.cs", "src/project/sub/source2.cs", "src/project/sub/source3.cs", "src/project/sub2/source4.cs", "src/project/sub2/source5.cs", "src/project/compiler/preprocess/preprocess-source1.cs", "src/project/compiler/preprocess/sub/preprocess-source2.cs", "src/project/compiler/preprocess/sub/sub/preprocess-source3.cs", "src/project/compiler/preprocess/sub/sub/preprocess-source3.txt", "src/project/compiler/shared/shared1.cs", "src/project/compiler/shared/shared1.txt", "src/project/compiler/shared/sub/shared2.cs", "src/project/compiler/shared/sub/shared2.txt", "src/project/compiler/shared/sub/sub/sharedsub.cs", "src/project/compiler/resources/resource.res", "src/project/compiler/resources/sub/resource2.res", "src/project/compiler/resources/sub/sub/resource3.res", "src/project/content1.txt"); }
static void Main(string[] args) { var printPathsOnly = true; string header = "// Copyright (c) 2020 some person\n"; string rootDirectory = @"my/root/directory/path"; var matcher = new Matcher(); matcher.AddInclude("**/*.md"); matcher.AddInclude("**/*.ts"); matcher.AddInclude("**/*.js"); matcher.AddInclude("**/*.c"); matcher.AddInclude("**/*.h"); matcher.AddInclude("**/*.hpp"); matcher.AddInclude("**/*.cpp"); matcher.AddExclude("**/node_modules/"); matcher.AddExclude("**/googletest/"); var results = matcher.GetResultsInFullPath(rootDirectory); foreach (var filePath in results) { if (printPathsOnly == false) { var content = File.ReadAllText(filePath); File.WriteAllText(filePath, header + content); } Console.WriteLine(filePath); } }
public ExitCode Run() { _logger.LogDebug("Identifying file to process in {Count} directories. {CountInclude} includes, {CountExclude} excludes were provided", _settings.Directories.Length, _settings.Includes?.Length ?? 0, _settings.Excludes?.Length ?? 0); Matcher globber = new Matcher(StringComparison.OrdinalIgnoreCase); if (_settings.Includes != null) { globber.AddIncludePatterns(_settings.Includes); } if (_settings.Excludes != null) { globber.AddExcludePatterns(_settings.Excludes); } if (!_settings.NoDefaultExcludes) { globber.AddExclude("**/obj/**.targets"); globber.AddExclude("**/bin/**.targets"); } foreach (string directory in _settings.Directories) { using (_logger.BeginScope(new Dictionary <string, object> { { "Directory", directory } })) { _logger.LogDebug("Searching for files in {Directory}", directory); if (Directory.Exists(directory)) { IEnumerable <string> files = globber.GetResultsInFullPath(directory); foreach (string file in files) { HandleFile(_formatter, file); ProcessedFiles++; } } else { _logger.LogWarning("{Directory} was not found", directory); } } } return(ExitCode.Ok); }
private static string CreateUnityPackage(IPackage meta, IPackageVariation variation) { var matcher = new Matcher(); matcher.AddIncludePatterns(variation.UnityPackage.Includes); matcher.AddExclude("**/*.meta"); if (variation.UnityPackage.Excludes != null) { matcher.AddExcludePatterns(variation.UnityPackage.Excludes); } var rootDirectory = new DirectoryInfoWrapper(new DirectoryInfo(Application.dataPath)); var assets = matcher.Execute(rootDirectory).Files.Select(w => $"Assets/{w.Path}"); var destDirectory = Path.Combine(Application.dataPath, meta.Describe.Output); if (!Directory.Exists(destDirectory)) { Directory.CreateDirectory(destDirectory); } var destName = string.IsNullOrWhiteSpace(variation.UnityPackage.Name) ? $"{meta.Name}.unitypackage" : $"{variation.UnityPackage.Name}.unitypackage"; var publishTo = Path.Combine(destDirectory, destName); if (File.Exists(publishTo)) { File.Delete(publishTo); } AssetDatabase.ExportPackage(assets.ToArray(), publishTo, ExportPackageOptions.Default); return(publishTo); }
internal static IEnumerable <string> Expand(string source, params string[] patterns) { if (patterns is null || !patterns.Any()) { return(Enumerable.Empty <string>()); } var files = new List <string>(); var matcher = new Matcher(); foreach (var pattern in patterns) { if (pattern.StartsWith("!")) { matcher.AddExclude(pattern.Substring(1)); } else { matcher.AddInclude(pattern); } } var results = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(source))); files.AddRange(results.Files.Select(file => file.Stem.Replace('/', '\\'))); return(files); }
public void Main(string[] args) { var matcher = new Matcher(); matcher.AddInclude(@"**\*.cs"); matcher.AddExclude(OutputFileName); var inputFiles = new List <string>(); var latestChange = DateTime.MinValue; foreach (var f in matcher.GetResultsInFullPath(_projectDir)) { inputFiles.Add(f); var change = File.GetLastWriteTimeUtc(f); if (change > latestChange) { latestChange = change; } } var outputFile = Path.Combine(_projectDir, OutputFileName); if (!File.Exists(outputFile) || latestChange > File.GetLastWriteTimeUtc(outputFile)) { Console.WriteLine("Rewriting async methods in " + _projectDir); var asyncCode = new Rewriter().RewriteAndMerge(inputFiles.ToArray()); File.WriteAllText(outputFile, asyncCode); } else { Console.WriteLine("Skipping async rewriting, generated code up to date"); } }
public FileSystemGlobbingTestContext Exclude(params string[] patterns) { foreach (var pattern in patterns) { _patternMatching.AddExclude(pattern); } return(this); }
public void ExcludeCaseInsensitive(string root, string excludePattern, string[] expectedFiles) { var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); matcher.AddInclude("**/*.*"); matcher.AddExclude(excludePattern); ExecuteAndVerify(matcher, root, expectedFiles.Select(f => root + "/" + f).ToArray()); }
public Include(FileBundleSourceItem item, string[] excludePatterns) { AutoDetectEncoding = item.InputEncoding == null; Encoding = item.InputEncoding ?? Encoding.UTF8; ItemTransforms = item.ItemTransforms; Matcher = new Matcher().AddInclude(item.Pattern); Array.ForEach(excludePatterns, p => Matcher.AddExclude(p)); }
public static void AddExcludePatterns(this Matcher matcher, params IEnumerable <string>[] excludePatternsGroups) { foreach (IEnumerable <string> excludePatternsGroup in excludePatternsGroups) { foreach (string pattern in excludePatternsGroup) { matcher.AddExclude(pattern); } } }
private void OnDebug() { var matcher = new Matcher(); matcher.AddExclude("**/*.meta"); matcher.AddIncludePatterns(_includes); matcher.AddExcludePatterns(_excludes); var rootDirectory = new DirectoryInfoWrapper(new DirectoryInfo(Application.dataPath)); _matches.Clear(); _matches.AddRange(matcher.Execute(rootDirectory).Files.Select(w => $"Assets/{w.Path}")); }
public Include(FileBundleSourceItem item, string[] _excludePatterns, Func <IChangeToken> changeTokenFactory, Action changeCallback) { Pattern = item.Pattern; AutoDetectEncoding = item.InputEncoding == null; Encoding = item.InputEncoding ?? Encoding.UTF8; ItemTransforms = item.ItemTransforms; Matcher = new Matcher().AddInclude(item.Pattern); Array.ForEach(_excludePatterns, p => Matcher.AddExclude(p)); _changeCallback = changeCallback; Initialize(changeTokenFactory); }
public static int Main(string[] args) { var workDir = args.Length > 0 ? args[0] : "."; var outputFileNameWithPath = workDir == "." ? OutputFileName : Path.Combine(workDir, OutputFileName); var matcher = new Matcher(); matcher.AddInclude(@"**\*.cs"); matcher.AddExclude(OutputFileName); var inputFiles = matcher.GetResultsInFullPath(workDir).ToArray(); Console.WriteLine("Rewriting async methods"); var asyncCode = new Rewriter().RewriteAndMerge(inputFiles); File.WriteAllText(outputFileNameWithPath, asyncCode); return(0); }
/// <summary> /// Gets files from the specified directory using globbing patterns. /// </summary> /// <param name="directory">The directory to search.</param> /// <param name="patterns">The globbing pattern(s) to use.</param> /// <returns>Files that match the globbing pattern(s).</returns> public static IEnumerable <FileInfo> GetFiles(DirectoryInfo directory, IEnumerable <string> patterns) { // Initially based on code from Reliak.FileSystemGlobbingExtensions (https://github.com/reliak/Reliak.FileSystemGlobbingExtensions) var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); // Expand braces var expandedPatterns = patterns .SelectMany(ExpandBraces) .Select(f => f.Replace("\\{", "{").Replace("\\}", "}")); // Unescape braces // Add the patterns, any that start with ! are exclusions foreach (var expandedPattern in expandedPatterns) { var isExclude = expandedPattern[0] == '!'; var finalPattern = isExclude ? expandedPattern.Substring(1) : expandedPattern; finalPattern = finalPattern .Replace("\\!", "!") // Unescape negation .Replace("\\", "/"); // Normalize slashes // No support for absolute paths if (System.IO.Path.IsPathRooted(finalPattern)) { throw new ArgumentException($"Rooted globbing patterns are not supported ({expandedPattern})", nameof(patterns)); } // Add exclude or include pattern to matcher if (isExclude) { matcher.AddExclude(finalPattern); } else { matcher.AddInclude(finalPattern); } } DirectoryInfoBase directoryInfo = new DirectoryInfoWrapper(directory); var result = matcher.Execute(directoryInfo); return(result.Files.Select(match => directoryInfo.GetFile(match.Path)).Select(fb => new FileInfo(fb.FullName))); }
private List <FileMatchResult> FindFiles(string directory, params string[] patterns) { var matcher = new Matcher(); foreach (var pattern in patterns) { if (pattern.StartsWith("!")) { matcher.AddExclude(NormalizeGlob(pattern).TrimStart('!')); } else { matcher.AddInclude(NormalizeGlob(pattern)); } } var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(directory))); return(result.Files.Select(x => new FileMatchResult(Path.Combine(directory, x.Path), x.Stem)).ToList()); }
public override IEnumerable <object[]> GetData(MethodInfo testMethod) { var matcher = new Matcher(); if (Includes != null) { foreach (var include in Includes) { matcher.AddInclude(include); } } if (Excludes != null) { foreach (var exclude in Excludes) { matcher.AddExclude(exclude); } } var basePath = Directory ?? Path.Combine("TestFiles", testMethod.DeclaringType !.Name, testMethod.Name); var result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(basePath))); if (!result.HasMatches) { throw new ArgumentException("No matching files found: " + this); } return(result.Files.Select(file => { var fullPath = Path.Join(basePath, file.Stem); var row = new FileTheoryDataRow(fullPath) { SourceInformation = new SourceInformation() { FileName = fullPath, LineNumber = 0 }, TestDisplayName = file.Stem, }; return new[] { row }; })); }
/// <summary> /// Gets files from the specified directory using globbing patterns. /// </summary> /// <param name="directory">The directory to search.</param> /// <param name="patterns">The globbing pattern(s) to use.</param> /// <returns>Files that match the globbing pattern(s).</returns> /// <remarks>Initially based on code from Reliak.FileSystemGlobbingExtensions (https://github.com/reliak/Reliak.FileSystemGlobbingExtensions).</remarks> public static IEnumerable <IFile> GetFiles(IDirectory directory, IEnumerable <string> patterns) { Matcher matcher = new Matcher(NormalizedPath.DefaultComparisonType); // Expand braces IEnumerable <string> expandedPatterns = patterns .SelectMany(ExpandBraces) .Select(f => f.Replace("\\{", "{").Replace("\\}", "}")); // Unescape braces // Add the patterns, any that start with ! are exclusions foreach (string expandedPattern in expandedPatterns) { bool isExclude = expandedPattern[0] == '!'; string finalPattern = isExclude ? expandedPattern.Substring(1) : expandedPattern; finalPattern = finalPattern .Replace("\\!", "!") // Unescape negation .Replace("\\", "/"); // Normalize slashes // No support for absolute paths if (Path.IsPathRooted(finalPattern)) { throw new ArgumentException($"Rooted globbing patterns are not supported ({expandedPattern})", nameof(patterns)); } // Add exclude or include pattern to matcher if (isExclude) { matcher.AddExclude(finalPattern); } else { matcher.AddInclude(finalPattern); } } DirectoryInfoBase directoryInfo = new DirectoryInfo(directory); PatternMatchingResult result = matcher.Execute(directoryInfo); return(result.Files.Select(match => directory.GetFile(match.Path))); }
/// <summary> /// Enumerate all the PowerShell (ps1, psm1, psd1) files in the workspace in a recursive manner. /// </summary> /// <returns>An enumerator over the PowerShell files found in the workspace.</returns> public IEnumerable <string> EnumeratePSFiles( string[] excludeGlobs, string[] includeGlobs, int maxDepth, bool ignoreReparsePoints ) { if (WorkspacePath == null || !Directory.Exists(WorkspacePath)) { yield break; } var matcher = new Matcher(); foreach (string pattern in includeGlobs) { matcher.AddInclude(pattern); } foreach (string pattern in excludeGlobs) { matcher.AddExclude(pattern); } var fsFactory = new WorkspaceFileSystemWrapperFactory( WorkspacePath, maxDepth, VersionUtils.IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework, ignoreReparsePoints, logger ); var fileMatchResult = matcher.Execute(fsFactory.RootDirectory); foreach (FilePatternMatch item in fileMatchResult.Files) { // item.Path always contains forward slashes in paths when it should be backslashes on Windows. // Since we're returning strings here, it's important to use the correct directory separator. var path = VersionUtils.IsWindows ? item.Path.Replace('/', Path.DirectorySeparatorChar) : item.Path; yield return(Path.Combine(WorkspacePath, path)); } }
/// <summary> /// Search SAF service assemblies /// </summary> /// <param name="basePath">Base path where search starts</param> /// <param name="searchPath">Search path (glob pattern). The ';' character is used as delimiter for multiple patterns and '|' as prefix for exclusions</param> /// <param name="fileNameFilterRegEx">Filter regex that each filename must satisfy (if in doubt use ".*")</param> /// <returns></returns> internal static IEnumerable <string> SearchServiceAssemblies(string basePath, string searchPath, string fileNameFilterRegEx) { // This function probably should be moved somewhere else if (basePath == null) { throw new ArgumentNullException(nameof(basePath)); } if (searchPath == null) { throw new ArgumentNullException(nameof(searchPath)); } if (fileNameFilterRegEx == null) { throw new ArgumentNullException(nameof(fileNameFilterRegEx)); } // Use matcher to find service assemblies var serviceMatcher = new Matcher(); foreach (var pattern in searchPath.Split(';')) { if (pattern.StartsWith("|")) { serviceMatcher.AddExclude(pattern.Substring(1)); } else { serviceMatcher.AddInclude(pattern); } } IList <string> results = serviceMatcher.GetResultsInFullPath(basePath).ToList(); // Filter assemblies using RegEx var serviceAssemblyNameRegEx = new Regex(fileNameFilterRegEx, RegexOptions.IgnoreCase); results = results.Where(assembly => serviceAssemblyNameRegEx.IsMatch(Path.GetFileName(assembly))).ToList(); return(results); }
void TryCopyDirectory(UDirectory sourceDirectory, UDirectory targetDirectory, string exclude = null) { var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); matcher.AddInclude("**/*.*"); if (exclude != null) { foreach (var excludeEntry in exclude.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { matcher.AddExclude(excludeEntry); } } //var resourceFiles = Directory.EnumerateFiles(sourceDirectory, "*.*", SearchOption.AllDirectories); foreach (var resourceFile in matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(sourceDirectory))).Files) { var resourceFilePath = UPath.Combine(sourceDirectory, (UFile)resourceFile.Path); var targetFilePath = UPath.Combine(targetDirectory, (UFile)resourceFile.Path); TryCopyResource(resourceFilePath, targetFilePath); } }
/// <summary> /// Enumerate all the PowerShell (ps1, psm1, psd1) files in the workspace in a recursive manner. /// </summary> /// <returns>An enumerator over the PowerShell files found in the workspace.</returns> public IEnumerable <string> EnumeratePSFiles( string[] excludeGlobs, string[] includeGlobs, int maxDepth, bool ignoreReparsePoints ) { if (WorkspacePath == null || !Directory.Exists(WorkspacePath)) { yield break; } var matcher = new Matcher(); foreach (string pattern in includeGlobs) { matcher.AddInclude(pattern); } foreach (string pattern in excludeGlobs) { matcher.AddExclude(pattern); } var fsFactory = new WorkspaceFileSystemWrapperFactory( WorkspacePath, maxDepth, VersionUtils.IsNetCore ? s_psFileExtensionsCoreFramework : s_psFileExtensionsFullFramework, ignoreReparsePoints, logger ); var fileMatchResult = matcher.Execute(fsFactory.RootDirectory); foreach (FilePatternMatch item in fileMatchResult.Files) { yield return(Path.Combine(WorkspacePath, item.Path)); } }
internal static IEnumerable <string> SearchMessagingAssemblies(string basePath, string searchPath, string fileNameFilterRegEx) { if (basePath == null) { throw new ArgumentNullException(nameof(basePath)); } if (searchPath == null) { throw new ArgumentNullException(nameof(searchPath)); } if (fileNameFilterRegEx == null) { throw new ArgumentNullException(nameof(fileNameFilterRegEx)); } var serviceMatcher = new Matcher(); foreach (var pattern in searchPath.Split(';')) { if (pattern.StartsWith("|")) { serviceMatcher.AddExclude(pattern.Substring(1)); } else { serviceMatcher.AddInclude(pattern); } } IList <string> results = serviceMatcher.GetResultsInFullPath(basePath).ToList(); var serviceAssemblyNameRegEx = new Regex(fileNameFilterRegEx, RegexOptions.IgnoreCase); results = results.Where(r => serviceAssemblyNameRegEx.IsMatch(Path.GetFileName(r))).ToList(); return(results); }
/// <summary> /// Apply build actions from the nuspec to items from the contentFiles folder. /// </summary> internal static List <LockFileContentFile> GetContentFileGroup( NuspecReader nuspec, List <ContentItemGroup> contentFileGroups) { var results = new List <LockFileContentFile>(contentFileGroups.Count); var rootFolderPathLength = ContentFilesFolderName.Length; // Read the contentFiles section of the nuspec // Read the entries so that the bottom entry has priority var nuspecContentFiles = nuspec.GetContentFiles().ToList(); // Initialize mappings var entryMappings = new Dictionary <string, List <ContentFilesEntry> >(StringComparer.OrdinalIgnoreCase); var languageMappings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var group in contentFileGroups) { var codeLanguage = group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage] as string; foreach (var item in group.Items) { if (!entryMappings.ContainsKey(item.Path)) { entryMappings.Add(item.Path, new List <ContentFilesEntry>()); languageMappings.Add(item.Path, codeLanguage); } } } // Virtual root for file globbing var rootDirectory = new VirtualFileInfo(VirtualFileProvider.RootDir, isDirectory: true); // Apply all nuspec property mappings to the files returned by content model foreach (var filesEntry in nuspecContentFiles) { // this is validated in the nuspec reader Debug.Assert(filesEntry.Include != null, "invalid contentFiles entry"); // Create a filesystem matcher for globbing patterns var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); matcher.AddInclude(filesEntry.Include); if (filesEntry.Exclude != null) { matcher.AddExclude(filesEntry.Exclude); } // Check each file against the patterns foreach (var file in entryMappings.Keys) { // Remove contentFiles/ from the string Debug.Assert(file.StartsWith(ContentFilesFolderName, StringComparison.OrdinalIgnoreCase), "invalid file path: " + file); // All files should begin with the same root folder if (file.Length > rootFolderPathLength) { var relativePath = file.Substring(rootFolderPathLength, file.Length - rootFolderPathLength); // Check if the nuspec group include/exclude patterns apply to the file var virtualDirectory = new VirtualFileProvider(new List <string>() { relativePath }); var globbingDirectory = new FileProviderGlobbingDirectory( virtualDirectory, fileInfo: rootDirectory, parent: null); // Currently Matcher only returns the file name not the full path, each file must be // check individually. var matchResults = matcher.Execute(globbingDirectory); if (matchResults.Files.Any()) { entryMappings[file].Add(filesEntry); } } } } // Create lock file entries for each item in the contentFiles folder foreach (var file in entryMappings.Keys) { // defaults var action = BuildAction.Parse(PackagingConstants.ContentFilesDefaultBuildAction); var copyToOutput = false; var flatten = false; // _._ is needed for empty codeLanguage groups if (file.EndsWith(PackagingCoreConstants.ForwardSlashEmptyFolder, StringComparison.Ordinal)) { action = BuildAction.None; } else { // apply each entry // entries may not have all the attributes, if a value is null // ignore it and continue using the previous value. foreach (var filesEntry in entryMappings[file]) { if (!string.IsNullOrEmpty(filesEntry.BuildAction)) { action = BuildAction.Parse(filesEntry.BuildAction); } if (filesEntry.CopyToOutput.HasValue) { copyToOutput = filesEntry.CopyToOutput.Value; } if (filesEntry.Flatten.HasValue) { flatten = filesEntry.Flatten.Value; } } } // Add attributes to the lock file item var lockFileItem = new LockFileContentFile(file); // Add the language from the directory path lockFileItem.CodeLanguage = languageMappings[file].ToLowerInvariant(); if (!action.IsKnown) { // Throw an error containing the package identity, invalid action, and file where it occurred. var message = string.Format(CultureInfo.CurrentCulture, Strings.Error_UnknownBuildAction, nuspec.GetIdentity(), action, file); throw new PackagingException(message); } lockFileItem.BuildAction = action; lockFileItem.CopyToOutput = copyToOutput; // Check if this is a .pp transform. If the filename is ".pp" ignore it since it will // have no file name after the transform. var isPP = lockFileItem.Path.EndsWith(".pp", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(Path.GetFileNameWithoutExtension(lockFileItem.Path)); if (copyToOutput) { string destination = null; if (flatten) { destination = Path.GetFileName(lockFileItem.Path); } else { // Find path relative to the TxM // Ex: contentFiles/cs/net45/config/config.xml -> config/config.xml destination = GetContentFileFolderRelativeToFramework(file); } if (isPP) { // Remove .pp from the output file path destination = destination.Substring(0, destination.Length - 3); } lockFileItem.OutputPath = destination; } // Add the pp transform file if one exists if (isPP) { var destination = lockFileItem.Path.Substring(0, lockFileItem.Path.Length - 3); destination = GetContentFileFolderRelativeToFramework(destination); lockFileItem.PPOutputPath = destination; } results.Add(lockFileItem); } return(results); }
public static IHostBuilder UsePluginLoader(this IHostBuilder builder, PluginConfig config) { var assemblyInfos = new List <IAssemblyInformation>(); var context = AssemblyLoadContext.Default; // Add the plugins and libraries. var pluginPaths = new List <string>(config.Paths); var libraryPaths = new List <string>(config.LibraryPaths); CheckPaths(pluginPaths); CheckPaths(libraryPaths); var rootFolder = Directory.GetCurrentDirectory(); pluginPaths.Add(Path.Combine(rootFolder, "plugins")); libraryPaths.Add(Path.Combine(rootFolder, "libraries")); var matcher = new Matcher(StringComparison.OrdinalIgnoreCase); matcher.AddInclude("*.dll"); matcher.AddExclude("Impostor.Api.dll"); RegisterAssemblies(pluginPaths, matcher, assemblyInfos, true); RegisterAssemblies(libraryPaths, matcher, assemblyInfos, false); // Register the resolver to the current context. // TODO: Move this to a new context so we can unload/reload plugins. context.Resolving += (loadContext, name) => { Logger.Verbose("Loading assembly {0} v{1}", name.Name, name.Version); // Some plugins may be referencing another Impostor.Api version and try to load it. // We want to only use the one shipped with the server. if (name.Name == "Impostor.Api") { return(typeof(IPlugin).Assembly); } var info = assemblyInfos.FirstOrDefault(a => a.AssemblyName.Name == name.Name); return(info?.Load(loadContext)); }; // TODO: Catch uncaught exceptions. var assemblies = assemblyInfos .Where(a => a.IsPlugin) .Select(a => context.LoadFromAssemblyName(a.AssemblyName)) .ToList(); // Find all plugins. var plugins = new List <PluginInformation>(); foreach (var assembly in assemblies) { // Find plugin startup. var pluginStartup = assembly .GetTypes() .Where(t => typeof(IPluginStartup).IsAssignableFrom(t) && t.IsClass) .ToList(); if (pluginStartup.Count > 1) { Logger.Warning("A plugin may only define zero or one IPluginStartup implementation ({0}).", assembly); continue; } // Find plugin. var plugin = assembly .GetTypes() .Where(t => typeof(IPlugin).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract && t.GetCustomAttribute <ImpostorPluginAttribute>() != null) .ToList(); if (plugin.Count != 1) { Logger.Warning("A plugin must define exactly one IPlugin or PluginBase implementation ({0}).", assembly); continue; } // Save plugin. plugins.Add(new PluginInformation( pluginStartup .Select(Activator.CreateInstance) .Cast <IPluginStartup>() .FirstOrDefault(), plugin.Single())); } var orderedPlugins = LoadOrderPlugins(plugins); foreach (var plugin in orderedPlugins) { plugin.Startup?.ConfigureHost(builder); } builder.ConfigureServices(services => { services.AddHostedService(provider => ActivatorUtilities.CreateInstance <PluginLoaderService>(provider, orderedPlugins)); foreach (var plugin in orderedPlugins) { plugin.Startup?.ConfigureServices(services); } }); return(builder); }
public static int InstallOptions(InstallOptions options) { ParkitectConfiguration configuration = JsonConvert.DeserializeObject <ParkitectConfiguration>( File.ReadAllText("./" + Constants.PARKITECT_CONFIG_FILE)); if (String.IsNullOrEmpty(configuration.Name)) { Console.WriteLine("name not set exiting"); Environment.Exit(0); } DepotDownloader downloader = new DepotDownloader(); String gamePath = Path.Join(Constants.HIDDEN_FOLDER, "Game"); if (!String.IsNullOrEmpty(options.SteamUsername) && !String.IsNullOrEmpty(options.SteamPassword)) { if (downloader.Login(options.SteamUsername, options.SteamPassword)) { Console.WriteLine("Download Parkitect ..."); downloader.DownloadDepot(gamePath, 453090, 453094, "public", s => s.EndsWith(".dll")).Wait(); } else { Console.WriteLine("Failed to Login"); Environment.Exit(0); } } else if (!String.IsNullOrEmpty(options.ParkitectPath)) { gamePath = options.ParkitectPath; } Console.WriteLine("Setup Project ..."); Project project = new Project(); var assemblyMatcher = new Matcher(); assemblyMatcher.AddInclude(Path.Join(gamePath, Constants.PARKITECT_ASSEMBLY_PATH) + "/*.dll"); if (configuration.Include != null) { foreach (var inc in configuration.Include) { assemblyMatcher.AddInclude(inc); } } HashSet <String> additionalTargets = new HashSet <String>(configuration.AdditionalAssemblies); HashSet <String> targets = new HashSet <String>(configuration.Assemblies); foreach (var additionalTarget in additionalTargets) { targets.Add(additionalTarget); } foreach (var file in assemblyMatcher.GetResultsInFullPath("./")) { if (!file.EndsWith(".dll")) { continue; } var asmb = Path.GetFileNameWithoutExtension(file); if (targets.Contains(asmb)) { targets.Remove(asmb); FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(file); if (Constants.SYSTEM_ASSEMBLIES.Contains(asmb) || asmb.StartsWith("System") || asmb.StartsWith("Mono")) { project.Assemblies.Add(new Project.AssemblyInfo { Name = asmb }); Console.WriteLine( $"System Assembly {asmb} -- {file}"); } else { project.Assemblies.Add(new Project.AssemblyInfo { Name = asmb, HintPath = file, Version = versionInfo.ProductVersion, Culture = "neutral", PublicKeyToken = "null", IsPrivate = additionalTargets.Contains(asmb) }); Console.WriteLine( $"Resolved Assembly: {asmb} -- {file}"); } } } foreach (var tg in targets) { if (Constants.SYSTEM_ASSEMBLIES.Contains(tg) || tg.StartsWith("System") || tg.StartsWith("Mono")) { project.Assemblies.Add(new Project.AssemblyInfo { Name = tg }); Console.WriteLine( $"System Assembly {tg}"); } else { Console.WriteLine( $"Unresolved Assembly -- {tg}"); } } // String assemblyPath = Path.Join(gamePath, Constants.PARKITECT_ASSEMBLY_PATH); // foreach (var asmb in configuration.Assemblies) // { // if (Directory.Exists(assemblyPath)) // { // String lowerAsmb = asmb.ToLower(); // String parkitectAssemblyPath = Path.Join(assemblyPath, $"{asmb}.dll"); // FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(parkitectAssemblyPath); // if (File.Exists(parkitectAssemblyPath)) // { // if (lowerAsmb.StartsWith("mono") || lowerAsmb.StartsWith("system") || // lowerAsmb.StartsWith("microsoft") || // Constants.SYSTEM_ASSEMBLIES.Contains(asmb)) // { // if (Constants.SYSTEM_ASSEMBLIES.Contains(asmb)) // { // Console.WriteLine($"Resolved Known Standard System Assembly -- {asmb}"); // } // else // { // Console.WriteLine( // $"Warning: Resolved to Unknown System assembly but found in Parkitect Managed -- {asmb}"); // } // // project.Assemblies.Add(new Project.AssemblyInfo // { // Name = asmb // }); // } // else if (Constants.PARKITECT_ASSEMBLIES.Contains(asmb)) // { // project.Assemblies.Add(new Project.AssemblyInfo // { // Name = asmb, // HintPath = parkitectAssemblyPath, // Version = versionInfo.FileVersion, // Culture = "neutral", // PublicKeyToken = "null", // IsPrivate = false // }); // Console.WriteLine( // $"Resolved to Known System assembly but found in Parkitect Managed -- {asmb}"); // } // else // { // project.Assemblies.Add(new Project.AssemblyInfo // { // Name = asmb, // HintPath = parkitectAssemblyPath, // Version = versionInfo.FileVersion, // Culture = "neutral", // PublicKeyToken = "null", // IsPrivate = false // }); // Console.WriteLine( // $"Warning: Resolved to Unknown System assembly but found in Parkitect managed: -- {asmb}"); // } // } // else // { // project.Assemblies.Add(new Project.AssemblyInfo() // { // Name = asmb // }); // Console.WriteLine($"Warning: Unknown Assembly -- {asmb}"); // } // } // else // { // Console.WriteLine("Error: Can't find Parkitect Assemblies"); // Environment.Exit(0); // } // } var matcher = new Matcher(); foreach (var s in Constants.IGNORE_FILES) { matcher.AddExclude(s); } if (configuration.Assets != null) { foreach (var asset in configuration.Assets) { matcher.AddInclude(asset); } } foreach (var file in matcher.GetResultsInFullPath("./")) { Console.WriteLine($"Asset: {file}"); project.Content.Add(new Project.ContentGroup { Include = file, CopyToOutput = Project.CopyOuputRule.ALWAYS }); } matcher = new Matcher(); foreach (var s in Constants.IGNORE_FILES) { matcher.AddExclude(s); } if (configuration.Sources != null) { foreach (var source in configuration.Sources) { matcher.AddInclude(source); } } else { matcher.AddInclude("*.cs"); matcher.AddInclude("**/*.cs"); } foreach (var file in matcher.GetResultsInFullPath("./")) { project.Compile.Add(file); } if (!String.IsNullOrEmpty(configuration.Workshop)) { File.WriteAllLines("./steam_workshop-id", new[] { configuration.Workshop }); project.Content.Add(new Project.ContentGroup() { Include = "./steam_workshop-id", CopyToOutput = Project.CopyOuputRule.ALWAYS }); } if (!String.IsNullOrEmpty(configuration.Preview)) { project.Content.Add(new Project.ContentGroup() { Include = configuration.Preview, CopyToOutput = Project.CopyOuputRule.ALWAYS, TargetPath = "preview.png" }); } project.None.Add("parkitect.json"); if (File.Exists("packages.config")) { project.None.Add("packages.config"); } project.OutputPath = Path.Combine(Constants.GetParkitectPath, !String.IsNullOrEmpty(configuration.Folder) ? configuration.Folder : configuration.Name); Console.WriteLine($"Output Path: {project.OutputPath}"); if (!project.Save($"./{configuration.Name}.csproj")) { Console.WriteLine($"Failed to create project: {configuration.Name}.csproj"); } Console.WriteLine("Completed"); Environment.Exit(0); return(0); }