please_build_formatter/proj/please_formatter.cs

118 lines
3.5 KiB
C#

#!/usr/bin/env dotnet-script
using System.Text.RegularExpressions;
ProcessDirectory(Directory.GetCurrentDirectory());
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")
{
Console.WriteLine();
Console.WriteLine(fs);
Console.WriteLine("======== ======== ======== ======== ======== ======== ======== ========");
FormatBuildFile(fs);
Console.WriteLine("======== ======== ======== ======== ======== ======== ======== ========");
Console.WriteLine();
}
}
else if (Directory.Exists(fs))
{
ProcessDirectory(fs);
}
}
}
void FormatBuildFile(string filename)
{
var oldcontent = File.ReadAllText(filename);
var newcontent = FormatFile(filename, oldcontent);
if (oldcontent != newcontent)
{
//File.WriteAllText(filename, newcontent);
Console.WriteLine("Auto-Formatted file :: " + filename);
}
}
string FormatFile(string filename, string content)
{
var depsRex = new Regex(@"^\s*deps\s*=\s*\[(\s*\n)?(?<deps>[^\]\)]+?)[\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)
{
Console.WriteLine("+++++++++++++ OLD +++++++++++++++++");
Console.WriteLine(oldDeps);
Console.WriteLine("++++++++++++++ NEW ++++++++++++++++");
Console.WriteLine(newDeps);
Console.WriteLine("++++++++++++++++++++++++++++++");
Console.WriteLine();
}
}
return content;
}
string FormatDeps(string filename, int linenum, string deps)
{
var lines = deps.Split("\n");
if (lines.Length == 0) return deps;
var allindents = lines.Where(l => !string.IsNullOrWhiteSpace(l)).Select(l => l.Length - l.TrimStart().Length).Distinct().ToList();
if (allindents.Count != 1)
{
throw new Exception($"Different deps-indents in file {filename}:{linenum} ( [ {string.Join(", ", allindents)} ] )");
}
var indent = new string(' ', allindents[0]);
var result = lines.
Where(p => !string.IsNullOrWhiteSpace(p)).
Select(p => GetDepGroup(filename, linenum, p)).
GroupBy(p => p.group).
OrderBy(p => p.Key).
SelectMany(p => p.OrderBy(q => q.clean).Select(q => $"{indent}\"{q.clean}\",").Append("")).
Aggregate((a, b) => a + "\n" + b);
return result;
}
(int group, 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 - 4);
}
else if (rowB)
{
v = v.Substring(1, v.Length - 3);
}
v = v.Trim();
//TODO group
return (0, v, value);
}