Quick and dirty util scripts, trim node modules
2 files changed, 214 insertions, 0 deletions
diff --git a/scripts/countDirs.cs b/scripts/countDirs.cs
new file mode 100755
index 00000000..a8e667bc
--- /dev/null
+++ b/scripts/countDirs.cs
@@ -0,0 +1,123 @@
+#!/usr/bin/env dotnet
+#:property Nullable=enable
+#:property PublishAOT=false
+#:package ArcaneLibs@1.0.0-preview.20251207*
+
+using ArcaneLibs;
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+if(args.Length == 0)
+{
+ Console.WriteLine("Usage: countExts [options] <directory_path>");
+ Console.WriteLine("Options:");
+ Console.WriteLine(" --size Sort by total size per extension (descending)");
+ Console.WriteLine(" --real-size Sort by estimated disk usage per extension (descending)");
+ Console.WriteLine(" --count Sort by file count per extension (ascending)");
+ Console.WriteLine(" --name Sort by extension name (ascending)");
+ Console.WriteLine(" --reverse Reverse the sort order");
+ return;
+}
+
+// undo chdir by dotnet
+Environment.CurrentDirectory = Environment.GetEnvironmentVariable("PWD") ?? Environment.CurrentDirectory;
+
+Dictionary<string, long> dirSizes = [];
+Dictionary<string, long> dirRealSizes = [];
+Dictionary<string, int> dirCounts = [];
+long totalSize = 0;
+long totalRealSize = 0;
+
+void GetDirSize(string path)
+{
+ long dirSize = 0;
+ long realDirSize = 0;
+ foreach (var file in Directory.GetFiles(path)) {
+ var len = new FileInfo(file).Length;
+ dirSize += len;
+ // assuming 4KiB block size
+ realDirSize += ((len + 4095) / 4096) * 4096;
+ }
+
+ // include filesystem entry sizes in real size
+ Glibc.stat(path, out var statbuf);
+ realDirSize += statbuf.st_size;
+
+ totalSize += dirSize;
+ totalRealSize += realDirSize;
+ var dirName = Path.GetFileName(path).ToLower();
+
+ if (!dirCounts.ContainsKey(dirName))
+ dirCounts[dirName] = 0;
+ dirCounts[dirName]++;
+
+ if (!dirSizes.ContainsKey(dirName))
+ dirSizes[dirName] = 0;
+ dirSizes[dirName] += dirSize;
+
+ if (!dirRealSizes.ContainsKey(dirName))
+ dirRealSizes[dirName] = 0;
+ dirRealSizes[dirName] += realDirSize;
+
+ foreach (var dir in Directory.GetDirectories(path)) GetDirSize(dir);
+}
+
+GetDirSize(args.First(a=>!a.StartsWith("--")));
+var extColWidth = dirCounts.Max(k => k.Key.Length) + 1;
+var numColWidth = dirCounts.Max(k=>k.Value.ToString().Length) + 1;
+
+IEnumerable<KeyValuePair<string, int>> sortedDirs = dirCounts.OrderByDescending(kvp => kvp.Value);
+
+if (args.Contains("--size"))
+ sortedDirs = dirCounts.OrderByDescending(kvp => dirSizes[kvp.Key]);
+if (args.Contains("--real-size"))
+ sortedDirs = dirCounts.OrderByDescending(kvp => dirRealSizes[kvp.Key]);
+if (args.Contains("--ext"))
+ sortedDirs = dirCounts.OrderBy(kvp => kvp.Key);
+if (args.Contains("--count"))
+ sortedDirs = dirCounts.OrderBy(kvp => kvp.Value);
+
+if (args.Contains("--reverse"))
+ sortedDirs = sortedDirs.Reverse();
+
+if (args.Contains("--duplicate-only"))
+ sortedDirs = sortedDirs.Where(kvp => kvp.Value > 1);
+
+foreach (var kvp in sortedDirs) Console.WriteLine($"{kvp.Value.ToString().PadLeft(numColWidth)} {kvp.Key.PadRight(extColWidth)} Total Size: {Util.BytesToString(dirSizes[kvp.Key]).PadRight(12)} Est. usage: {Util.BytesToString(dirRealSizes[kvp.Key])}");
+
+Console.WriteLine($"\nTotal unique directory names: {dirCounts.Count}");
+Console.WriteLine($"Total disk usage: {Util.BytesToString(totalSize)} (est. usage: {Util.BytesToString(totalRealSize)})");
+
+static class Glibc
+{
+ // to get filesystem entry size for directories
+ [DllImport("libc", SetLastError = true)]
+ public static extern int stat(string path, out Stat buf);
+}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct Stat
+{
+ public ulong st_dev;
+ public ulong st_ino;
+ public ulong st_nlink;
+ public uint st_mode;
+ public uint st_uid;
+ public uint st_gid;
+ public ulong st_rdev;
+ public long st_size;
+ public long st_blksize;
+ public long st_blocks;
+ public long st_atime;
+ public ulong st_atime_nsec;
+ public long st_mtime;
+ public ulong st_mtime_nsec;
+ public long st_ctime;
+ public ulong st_ctime_nsec;
+ public long __unused1;
+ public long __unused2;
+ public long __unused3;
+}
\ No newline at end of file
diff --git a/scripts/countExts.cs b/scripts/countExts.cs
new file mode 100755
index 00000000..af448edf
--- /dev/null
+++ b/scripts/countExts.cs
@@ -0,0 +1,91 @@
+#!/usr/bin/env dotnet
+#:property Nullable=enable
+#:property PublishAOT=false
+#:package ArcaneLibs@1.0.0-preview.20251207*
+
+using ArcaneLibs;
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+
+if(args.Length == 0)
+{
+ Console.WriteLine("Usage: countExts [options] <directory_path>");
+ Console.WriteLine("Options:");
+ Console.WriteLine(" --size Sort by total size per extension (descending)");
+ Console.WriteLine(" --real-size Sort by estimated disk usage per extension (descending)");
+ Console.WriteLine(" --ext Sort by extension name (ascending)");
+ Console.WriteLine(" --count Sort by file count per extension (ascending)");
+ Console.WriteLine(" --by-filename Use full filename instead of extension for counting");
+ Console.WriteLine(" --double-ext Consider double extensions (e.g., .test.js)");
+ Console.WriteLine(" --filename-fallback Use full filename as extension if no extension found");
+ return;
+}
+
+// undo chdir by dotnet
+Environment.CurrentDirectory = Environment.GetEnvironmentVariable("PWD") ?? Environment.CurrentDirectory;
+
+Dictionary<string, int> extCounts = [];
+Dictionary<string, long> extSizes = [];
+Dictionary<string, long> extRealSizes = [];
+long totalSize = 0;
+long totalRealSize = 0;
+
+void CountExtensions(string path)
+{
+ foreach (var file in Directory.GetFiles(path))
+ {
+ string ext = args.Contains("--by-filename") ? Path.GetFileName(file).ToLower() : Path.GetExtension(file).ToLower();
+
+ // handle double extensions, ie. .test.js, .min.js etc
+ if (args.Contains("--double-ext") && Path.GetFileName(file).Count(c => c == '.') >= 2)
+ {
+ var fname = Path.GetFileNameWithoutExtension(file);
+ var secondExt = Path.GetExtension(fname).ToLower();
+ if (!string.IsNullOrEmpty(secondExt))
+ ext = secondExt + ext;
+ }
+
+ if(string.IsNullOrEmpty(ext))
+ ext = args.Contains("--filename-fallback") ? Path.GetFileName(file).ToLower() : "<no_ext>";
+
+ if (!extCounts.ContainsKey(ext))
+ extCounts[ext] = 0;
+ extCounts[ext]++;
+
+ var fi = new FileInfo(file);
+ if (!extSizes.ContainsKey(ext))
+ extSizes[ext] = 0;
+ extSizes[ext] += fi.Length;
+ totalSize += fi.Length;
+
+ // Assuming 4KiB block size
+ if (!extRealSizes.ContainsKey(ext))
+ extRealSizes[ext] = 0;
+ extRealSizes[ext] += (((fi.Length + 4095) / 4096) * 4096);
+ totalRealSize += (((fi.Length + 4095) / 4096) * 4096);
+ }
+
+ foreach (var dir in Directory.GetDirectories(path)) CountExtensions(dir);
+}
+
+CountExtensions(args.First(a=>!a.StartsWith("--")));
+var extColWidth = extCounts.Max(k => k.Key.Length) + 1;
+var numColWidth = extCounts.Max(k=>k.Value.ToString().Length) + 1;
+
+var sortedExts = extCounts.OrderByDescending(kvp => kvp.Value);
+
+if (args.Contains("--size"))
+ sortedExts = extCounts.OrderByDescending(kvp => extSizes[kvp.Key]);
+if (args.Contains("--real-size"))
+ sortedExts = extCounts.OrderByDescending(kvp => extRealSizes[kvp.Key]);
+if (args.Contains("--ext"))
+ sortedExts = extCounts.OrderBy(kvp => kvp.Key);
+if (args.Contains("--count"))
+ sortedExts = extCounts.OrderBy(kvp => kvp.Value);
+
+foreach (var kvp in sortedExts) Console.WriteLine($"{kvp.Value.ToString().PadLeft(numColWidth)} {kvp.Key.PadRight(extColWidth)} Total Size: {Util.BytesToString(extSizes[kvp.Key]).PadRight(12)} Est. usage: {Util.BytesToString(extRealSizes[kvp.Key])}");
+
+Console.WriteLine($"\nTotal unique extensions: {extCounts.Count}");
+Console.WriteLine($"Total disk usage: {Util.BytesToString(totalSize)} (est. usage: {Util.BytesToString(totalRealSize)})");
\ No newline at end of file
|