using System.Text.RegularExpressions; var DEBUG = false; string[] clargs = Args.ToArray(); var dir = Directory.GetCurrentDirectory(); if (clargs.Length > 0) dir = Path.Combine(dir, clargs[0]); dir = Path.GetFullPath(dir); if (File.Exists(dir)) { FormatBuildFile(dir); } else if (Directory.Exists(dir)) { ProcessDirectory(dir); } else { Console.Error.WriteLine($"Invalid Directory/File argument: '{dir}'"); } void ProcessDirectory(string baseDir) { foreach (var subDir in Directory.EnumerateFileSystemEntries(baseDir)) { var fs = Path.Combine(baseDir, subDir); if (File.Exists(fs)) { if (Path.GetFileName(fs) == "BUILD") FormatBuildFile(fs); } else if (Directory.Exists(fs)) { ProcessDirectory(fs); } } } void FormatBuildFile(string filename) { var oldcontent = File.ReadAllText(filename); var newcontent = FormatFile(filename, oldcontent); if (oldcontent == newcontent) return; File.WriteAllText(filename, newcontent); Console.WriteLine("Auto-Formatted file :: " + filename); } string FormatFile(string filename, string content) { if (DEBUG) { Console.WriteLine(""); Console.WriteLine("============================== "+filename+" =============================="); Console.WriteLine(""); } var depsRex = new Regex(@"^\s*deps\s*=\s*\[(\s*\n)?(?[^\]\)]+?)[\s\r\n]*\]", RegexOptions.Multiline); var matches = depsRex.Matches(content); foreach (Match m in matches) { var oldDeps = m.Groups["deps"].Value; if (string.IsNullOrWhiteSpace(oldDeps)) continue; var linenum = 1 + content[..m.Groups["deps"].Index].AsEnumerable().Count(p => p == '\n'); var newDeps = FormatDeps(filename, linenum, oldDeps); if (oldDeps != newDeps) { if (DEBUG) { Console.WriteLine("+++++++++++++ OLD +++++++++++++++++"); Console.WriteLine(oldDeps); Console.WriteLine("++++++++++++++ NEW ++++++++++++++++"); Console.WriteLine(newDeps); Console.WriteLine("++++++++++++++++++++++++++++++"); Console.WriteLine(); } else { content = content.Replace(oldDeps, newDeps); } } else { if (DEBUG) { Console.WriteLine(" ( no changes )"); } } } return content; } string FormatDeps(string filename, int linenum, string deps) { var lines = deps.Split("\n"); if (lines.Length == 0) return deps; if (lines.Length == 1) return deps; var allindents = lines.Where(l => !string.IsNullOrWhiteSpace(l)).Select(l => l.Length - l.TrimStart().Length).Distinct().ToList(); if (allindents.Count != 1) { foreach (var l in lines) Console.Error.WriteLine(l); throw new Exception($"Different deps-indents in file {filename}:{linenum} ( [ {string.Join(", ", allindents)} ] )"); } var indent = new string(' ', allindents[0]); var data = lines. Where(p => !string.IsNullOrWhiteSpace(p)). Select(p => GetDepGroup(filename, linenum, p)). GroupBy(p => p.group). OrderBy(p => p.Key). ToList(); var result = ""; var first = true; for (var i = 0; i < data.Count; i++) { foreach (var d in data[i].OrderBy(p => p.clean)) { if (!first) result += "\n"; result += $"{indent}\"{d.clean}\","; first = false; } if (i+1 < data.Count) result += "\n"; } return result; } (int group, string sgroup, string clean, string raw) GetDepGroup(string filename, int linenum, string value) { var v = value.Trim(); var rowA = v.Length > 3 && v[0] == '"' && v[^2] == '"' && v[^1] == ','; var rowB = v.Length > 2 && v[0] == '"' && v[^1] == '"'; if (!rowA && !rowB) throw new Exception($"Invalid Dependency in file {filename}:{linenum} => '{v}'"); if (rowA) { v = v.Substring(1, v.Length - 3); } else if (rowB) { v = v.Substring(1, v.Length - 2); } v = v.Trim(); if (v.StartsWith(":")) return (100, "local", v, value); if (v.StartsWith("//common")) return (200, "common", v, value); if (v.StartsWith("//apcommon")) return (201, "common", v, value); if (v.StartsWith("//accessor")) return (220, "accessor", v, value); if (v.StartsWith("//models")) return (221, "models", v, value); if (v.StartsWith("//routing")) return (222, "routing", v, value); if (v.StartsWith("//service")) return (223, "service", v, value); if (v.StartsWith("//artifacts")) return (224, "artifacts", v, value); if (v.StartsWith("//services")) return (251, "services", v, value); if (v.StartsWith("//gateways")) return (252, "gateways", v, value); if (v.StartsWith("//jobs")) return (253, "jobs", v, value); if (v.StartsWith("//adminpanel")) return (301, "accessor", v, value); if (v.StartsWith("//proto/common:")) return (401, "commonproto", v, value); if (v.StartsWith("//proto")) return (402, "proto", v, value); if (v.StartsWith("//library/go/private")) return (500, "privatelib", v, value); if (v.StartsWith("//library/go:")) return (501, "golib", v, value); if (v.StartsWith("//library/go/")) return (502, "sublib", v, value); throw new Exception($"unknown dep group in file {filename}:{linenum} => '{v}'"); }