public static VirtualFileSystemRoot GetRoot() { var applicationBase = LoaderLock.ApplicationBase ?? string.Empty; if (_vfs.TryGetValue(applicationBase, out var root)) { return(root); } var newRoot = new VirtualFileSystemRoot(); if (0 < applicationBase.Length) { newRoot.LoadFrom(applicationBase); } _vfs.Add(applicationBase, newRoot); return(newRoot); }
public static void Compile(UserQueryTypeInfo userQuery, QueryInfo currentQuery, CompilationOptions options, QueryInfo currentQueryInfo) { Debug.WriteLine("==== Compiler pass begin ====", nameof(Compiler)); // ==== if (options.OutDir == null) { throw new InvalidOperationException("Compilation option 'OutDir' cannot be null"); } // ==== var functions = FunctionBinder.BindAll(userQuery.Type); // ==== var functionDirs = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // ==== var assemblyName = typeof(Program).Assembly.GetName(); var generatedBy = assemblyName.Name + "-" + assemblyName.Version.Major + "." + assemblyName.Version.Minor + "." + assemblyName.Version.Build; // .NET calls build what semver calls revision foreach (var f in functions) { var functionJson = new JObject(); functionJson["generatedBy"] = assemblyName.Name + "-" + assemblyName.Version.Major + "." + assemblyName.Version.Minor + "." + assemblyName.Version.Build; // .NET calls build what semver calls revision // "attributes" is used by the Azure Web Jobs SDK // to bind using metadata and takes precedence // over "config". we do not want this. functionJson["configurationSource"] = "config"; functionJson["bindings"] = JToken.FromObject(f.Trigger.GetBindings()); functionJson["disabled"] = false; functionJson["scriptFile"] = "../bin/CloudPad.FunctionApp.dll"; functionJson["entryPoint"] = f.Trigger.GetEntryPoint(); var cloudPad = new JObject(); cloudPad["applicationBase"] = $"../scripts/{options.QueryName}_{userQuery.Id}"; cloudPad["scriptFile"] = userQuery.AssemblyLocationFileName; cloudPad["typeName"] = userQuery.Type.FullName; cloudPad["methodName"] = f.Method.Name; var connInfo = currentQueryInfo.GetConnectionInfo(); if (connInfo != null) { cloudPad["providerName"] = connInfo.Provider; cloudPad["connectionString"] = Util.CurrentCxString; } functionJson["cloudPad"] = cloudPad; // ==== var functionName = options.QueryName + "_" + f.Method.Name; var functionDir = Path.Combine(options.OutDir, functionName); Directory.CreateDirectory(functionDir); File.WriteAllText(Path.Combine(functionDir, "function.json"), JsonConvert.SerializeObject(functionJson, Formatting.Indented)); functionDirs.Add(functionName); } if (Directory.Exists(options.OutDir)) { foreach (var d in Directory.EnumerateDirectories(options.OutDir, "*", SearchOption.TopDirectoryOnly)) { var name = Path.GetFileName(d); if ("bin".Equals(name, StringComparison.OrdinalIgnoreCase)) { continue; } if ("scripts".Equals(name, StringComparison.OrdinalIgnoreCase)) { continue; } if (!functionDirs.Contains(name)) { Directory.Delete(d, true); } } } // ==== var userAssemblies = LoadAllUserAssemblies2(userQuery, currentQuery); // ==== var lib = Path.Combine(options.OutDir, "scripts", options.QueryName + "_" + userQuery.Id); Directory.CreateDirectory(lib); foreach (var userAssembly in userAssemblies) { var destination = Path.Combine(lib, Path.GetFileName(userAssembly.Name.Name + ".dll")); // stabilize DLL name (simplifies assembly resolve) if (File.Exists(destination)) { Debug.WriteLine($"Output file exists '{destination}'", nameof(Compiler)); continue; } AssemblyBindingTarget.Rewrite(userAssembly.Location, destination); } // ==== var root = VirtualFileSystemRoot.GetRoot(); root.SaveTo(lib); // ==== Debug.WriteLine($"==== Compiler pass end, OutDir= {options.OutDir} ====", nameof(Compiler)); }