Program.cs
1 using System.Security.Cryptography; 2 using System.Text; 3 using Utils; 4 5 public static class Program 6 { 7 private const string Search = "<INSERT-OPENAPI-YAML-HASH>"; 8 private const string CodexPluginFolderName = "CodexPlugin"; 9 private const string ProjectPluginsFolderName = "ProjectPlugins"; 10 11 public static void Main(string[] args) 12 { 13 Console.WriteLine("Injecting hash of 'openapi.yaml'..."); 14 15 var pluginRoot = FindCodexPluginFolder(); 16 var clientRoot = FindCodexClientFolder(); 17 Console.WriteLine("Located CodexPlugin: " + pluginRoot); 18 var openApiFile = Path.Combine(clientRoot, "openapi.yaml"); 19 var clientFile = Path.Combine(clientRoot, "obj", "openapiClient.cs"); 20 var targetFile = Path.Combine(pluginRoot, "ApiChecker.cs"); 21 22 // Force client rebuild by deleting previous artifact. 23 File.Delete(clientFile); 24 25 var hash = CreateHash(openApiFile); 26 // This hash is used to verify that the Codex docker image being used is compatible 27 // with the openapi.yaml being used by the Codex plugin. 28 // If the openapi.yaml files don't match, an exception is thrown. 29 30 SearchAndInject(hash, targetFile); 31 32 // This program runs as the pre-build trigger for "CodexPlugin". 33 // You might be wondering why this work isn't done by a shell script. 34 // This is because this project is being run on many different platforms. 35 // (Mac, Unix, Win, but also desktop/cloud containers.) 36 // In order to not go insane trying to make a shell script that works in all possible cases, 37 // instead we use the one tool that's definitely installed in all platforms and locations 38 // when you're trying to run this plugin. 39 40 Console.WriteLine("Done!"); 41 } 42 43 private static string FindCodexPluginFolder() 44 { 45 var folder = Path.Combine(PluginPathUtils.ProjectPluginsDir, "CodexPlugin"); 46 if (!Directory.Exists(folder)) throw new Exception("CodexPlugin folder not found. Expected: " + folder); 47 return folder; 48 } 49 50 private static string FindCodexClientFolder() 51 { 52 var folder = Path.Combine(PluginPathUtils.ProjectPluginsDir, "CodexClient"); 53 if (!Directory.Exists(folder)) throw new Exception("CodexClient folder not found. Expected: " + folder); 54 return folder; 55 } 56 57 private static string CreateHash(string openApiFile) 58 { 59 var file = File.ReadAllText(openApiFile); 60 var fileBytes = Encoding.ASCII.GetBytes(file 61 .Replace(Environment.NewLine, "")); 62 63 var sha = SHA256.Create(); 64 var hash = sha.ComputeHash(fileBytes); 65 return BitConverter.ToString(hash); 66 } 67 68 private static void SearchAndInject(string hash, string targetFile) 69 { 70 var lines = File.ReadAllLines(targetFile); 71 Inject(lines, hash); 72 File.WriteAllLines(targetFile, lines); 73 } 74 75 private static void Inject(string[] lines, string hash) 76 { 77 for (var i = 0; i < lines.Length; i++) 78 { 79 if (lines[i].Contains(Search)) 80 { 81 lines[i + 1] = $" private const string OpenApiYamlHash = \"{hash}\";"; 82 return; 83 } 84 } 85 } 86 }