private static void AddPackageToFallbackFolder(string fallbackFolder, string nupkgPath, string packageId, string packageVersion) { // dotnet CLI provides no command for this, but we can do it manually. // // - The expected structure is as follows: // fallback_folder/ // <package.name>/<version>/ // <package.name>.<version>.nupkg // <package.name>.<version>.nupkg.sha512 // <package.name>.nuspec // ... extracted nupkg files (check code for excluded files) ... // // - <package.name> and <version> must be in lower case. // - The sha512 of the nupkg is base64 encoded. // - We can get the nuspec from the nupkg which is a Zip file. string packageIdLower = packageId.ToLower(); string packageVersionLower = packageVersion.ToLower(); string destDir = Path.Combine(fallbackFolder, packageIdLower, packageVersionLower); string nupkgDestPath = Path.Combine(destDir, $"{packageIdLower}.{packageVersionLower}.nupkg"); string nupkgSha512DestPath = Path.Combine(destDir, $"{packageIdLower}.{packageVersionLower}.nupkg.sha512"); if (File.Exists(nupkgDestPath) && File.Exists(nupkgSha512DestPath)) { return; // Already added (for speed we don't check if every file is properly extracted) } Directory.CreateDirectory(destDir); // Generate .nupkg.sha512 file using (var alg = SHA512.Create()) { alg.ComputeHash(File.ReadAllBytes(nupkgPath)); string base64Hash = Convert.ToBase64String(alg.Hash); File.WriteAllText(nupkgSha512DestPath, base64Hash); } // Extract nupkg ExtractNupkg(destDir, nupkgPath, packageId, packageVersion); // Copy .nupkg File.Copy(nupkgPath, nupkgDestPath); }
public static void GenerateScriptsMetadata(string projectPath, string outputPath) { var metadataDict = Internal.GetScriptsMetadataOrNothing().Duplicate(); bool IsUpToDate(string includeFile, ulong modifiedTime) { return(metadataDict.TryGetValue(includeFile, out var oldFileVar) && ulong.TryParse(((Dictionary)oldFileVar)["modified_time"] as string, out ulong storedModifiedTime) && storedModifiedTime == modifiedTime); } var outdatedFiles = ProjectUtils.GetIncludeFiles(projectPath, "Compile") .Select(path => ("res://" + path).SimplifyGodotPath()) .ToDictionary(path => path, path => File.GetLastWriteTime(path).ConvertToTimestamp()) .Where(pair => !IsUpToDate(includeFile: pair.Key, modifiedTime: pair.Value)) .ToArray(); foreach (var pair in outdatedFiles) { metadataDict.Remove(pair.Key); string includeFile = pair.Key; if (TryParseFileMetadata(includeFile, modifiedTime: pair.Value, out var fileMetadata)) { metadataDict[includeFile] = fileMetadata; } } string json = metadataDict.Count <= 0 ? "{}" : JSON.Print(metadataDict); string baseDir = outputPath.GetBaseDir(); if (!Directory.Exists(baseDir)) { Directory.CreateDirectory(baseDir); } File.WriteAllText(outputPath, json); }
public static void GenerateScriptsMetadata(string projectPath, string outputPath) { if (File.Exists(outputPath)) { File.Delete(outputPath); } var oldDict = Internal.GetScriptsMetadataOrNothing(); var newDict = new Godot.Collections.Dictionary <string, object>(); foreach (var includeFile in ProjectUtils.GetIncludeFiles(projectPath, "Compile")) { string projectIncludeFile = ("res://" + includeFile).SimplifyGodotPath(); ulong modifiedTime = File.GetLastWriteTime(projectIncludeFile).ConvertToTimestamp(); if (oldDict.TryGetValue(projectIncludeFile, out var oldFileVar)) { var oldFileDict = (Dictionary)oldFileVar; if (ulong.TryParse(oldFileDict["modified_time"] as string, out ulong storedModifiedTime)) { if (storedModifiedTime == modifiedTime) { // No changes so no need to parse again newDict[projectIncludeFile] = oldFileDict; continue; } } } ScriptClassParser.ParseFileOrThrow(projectIncludeFile, out var classes); string searchName = System.IO.Path.GetFileNameWithoutExtension(projectIncludeFile); var classDict = new Dictionary(); foreach (var classDecl in classes) { if (classDecl.BaseCount == 0) { continue; // Does not inherit nor implement anything, so it can't be a script class } string classCmp = classDecl.Nested ? classDecl.Name.Substring(classDecl.Name.LastIndexOf(".", StringComparison.Ordinal) + 1) : classDecl.Name; if (classCmp != searchName) { continue; } classDict["namespace"] = classDecl.Namespace; classDict["class_name"] = classDecl.Name; classDict["nested"] = classDecl.Nested; break; } if (classDict.Count == 0) { continue; // Not found } newDict[projectIncludeFile] = new Dictionary { ["modified_time"] = $"{modifiedTime}", ["class"] = classDict }; } if (newDict.Count > 0) { string json = JSON.Print(newDict); string baseDir = outputPath.GetBaseDir(); if (!Directory.Exists(baseDir)) { Directory.CreateDirectory(baseDir); } File.WriteAllText(outputPath, json); } }