public IEnumerable <CodeGeneratorSettings> GenerateSettings(CodeGeneratorSettingsLoaderDefaults settings, IEnumerable <string> paths) { var root = Directory.GetCurrentDirectory(); // we need to multi pass the source files looking for items to load var toProcess = new Queue <string>(paths.SelectMany(x => GlobExpander.FindFiles(root, x))); List <SimpleSourceFile> sourceFiles = new List <SimpleSourceFile>(); List <string> processedPaths = new List <string>(); while (toProcess.Any()) { var path = toProcess.Dequeue(); processedPaths.Add(path); var loaded = Load(path, settings); var newPaths = loaded.Includes.Where(x => !processedPaths.Contains(x)); foreach (var p in newPaths) { toProcess.Enqueue(p); } sourceFiles.Add(loaded); } var schemaFiles = sourceFiles.Select(x => x.SchemaSource?.Location); var grouped = sourceFiles .Where(x => !schemaFiles.Contains(x.Path)) // exclude files linked in a schemas .GroupBy(x => new { hash = x.SettingsHash() }).ToList(); return(grouped.Select(x => { var first = x.First(); var nspc = ""; var cn = first.ClassName; var idx = first.ClassName.LastIndexOf('.'); if (idx > 0) { cn = first.ClassName.Substring(idx); nspc = first.ClassName.Substring(0, idx); } cn = cn.Trim('.'); nspc = nspc.Trim('.'); var templates = DefaultTemplates(first.OutputPath); templates.AddRange(x.First().Templates); return new CodeGeneratorSettings { ClassName = cn, Namespace = nspc, OutputPath = first.OutputPath, RootPath = first.RootPath, TypeNameDirective = first.TypeNameDirective, SourceFiles = x.Select(p => new NamedSource { Body = p.Body, Path = p.Path }).ToList(), Schema = x.First().SchemaSource, Templates = templates, TemplateSettings = first.TemplateSettings }; }).ToList()); }
private SimpleSourceFile Load(string path, CodeGeneratorSettingsLoaderDefaults settings) { // path must be a real full path by here var gql = File.ReadAllText(path); // lets discover / cache all settings files from this point up the stack and root them out var file = new SimpleSourceFile() { Path = path, Body = gql }; var root = Path.GetDirectoryName(path); var matches = regex.Matches(gql); var pairs = matches.OfType <Match>().Select(m => (key: m.Groups[1].Value.ToLower(), val: m.Groups[2].Value)).ToList(); foreach (var m in pairs) { // process them in order to later directives overwrite previous ones switch (m.key) { case "schema": file.SchemaSource = file.SchemaSource ?? new SchemaSource(); file.SchemaSource.Location = GenerateFullPath(root, m.val); break; case "schema.querytype": file.SchemaSource = file.SchemaSource ?? new SchemaSource(); file.SchemaSource.QueryType.Add(m.val); break; case "schema.mutationtype": file.SchemaSource = file.SchemaSource ?? new SchemaSource(); file.SchemaSource.MutationType.Add(m.val); break; case "output": file.OutputPath = GenerateFullPath(root, m.val); break; case "class": file.ClassName = m.val; break; case "typedirective": file.TypeNameDirective = m.val; break; case "format": file.Format = m.val; break; case "settings": ExpandSettings(GenerateFullPath(root, m.val), file); break; case "template": var templateFiles = GlobExpander.FindFiles(root, m.val); file.Templates.AddRange(templateFiles); break; case "include": var includeFiles = GlobExpander.FindFiles(root, m.val); file.Includes.AddRange(includeFiles); break; default: break; } } LoadSettingsTree(file); if (File.Exists(settings.OverridesPath)) { ExpandSettings(settings.OverridesPath, file, true); } if (string.IsNullOrWhiteSpace(file.TypeNameDirective)) { file.TypeNameDirective = "__codeGenTypeName"; } if (string.IsNullOrWhiteSpace(file.Format)) { if (!string.IsNullOrWhiteSpace(file.OutputPath)) { file.Format = Path.GetExtension(file.OutputPath).Trim('.').ToLower(); } if (string.IsNullOrWhiteSpace(file.Format)) { file.Format = settings.Format; } } if (string.IsNullOrWhiteSpace(file.OutputPath)) { if (string.IsNullOrWhiteSpace(settings.OutputPath)) { file.OutputPath = file.Path; } else { file.OutputPath = settings.OutputPath; } } if (!Path.GetExtension(file.OutputPath).Trim('.').Equals(file.Format, StringComparison.OrdinalIgnoreCase)) { file.OutputPath += "." + file.Format; } if (string.IsNullOrWhiteSpace(file.ClassName)) { file.ClassName = Path.GetFileNameWithoutExtension(file.Path); } settings.FixFile?.Invoke(file); file.OutputPath = file.OutputPath.Replace("{classname}", file.ClassName); return(file); }