@@ -22,71 +22,13 @@ public static class NuGetUtils
22
22
public static string GodotFallbackFolderPath
23
23
=> Path . Combine ( GodotSharpDirs . MonoUserDir , "GodotNuGetFallbackFolder" ) ;
24
24
25
- private static void AddFallbackFolderToNuGetConfig ( string nuGetConfigPath , string name , string path )
26
- {
27
- var xmlDoc = new XmlDocument ( ) ;
28
- xmlDoc . Load ( nuGetConfigPath ) ;
29
-
30
- const string nuGetConfigRootName = "configuration" ;
31
-
32
- var rootNode = xmlDoc . DocumentElement ;
33
-
34
- if ( rootNode == null )
35
- {
36
- // No root node, create it
37
- rootNode = xmlDoc . CreateElement ( nuGetConfigRootName ) ;
38
- xmlDoc . AppendChild ( rootNode ) ;
39
-
40
- // Since this can be considered pretty much a new NuGet.Config, add the default nuget.org source as well
41
- XmlElement nugetOrgSourceEntry = xmlDoc . CreateElement ( "add" ) ;
42
- nugetOrgSourceEntry . Attributes . Append ( xmlDoc . CreateAttribute ( "key" ) ) . Value = "nuget.org" ;
43
- nugetOrgSourceEntry . Attributes . Append ( xmlDoc . CreateAttribute ( "value" ) ) . Value =
44
- "https://api.nuget.org/v3/index.json" ;
45
- nugetOrgSourceEntry . Attributes . Append ( xmlDoc . CreateAttribute ( "protocolVersion" ) ) . Value = "3" ;
46
- rootNode . AppendChild ( xmlDoc . CreateElement ( "packageSources" ) ) . AppendChild ( nugetOrgSourceEntry ) ;
47
- }
48
- else
49
- {
50
- // Check that the root node is the expected one
51
- if ( rootNode . Name != nuGetConfigRootName )
52
- throw new FormatException ( "Invalid root Xml node for NuGet.Config. " +
53
- $ "Expected '{ nuGetConfigRootName } ' got '{ rootNode . Name } '.") ;
54
- }
55
-
56
- var fallbackFoldersNode = rootNode [ "fallbackPackageFolders" ] ??
57
- rootNode . AppendChild ( xmlDoc . CreateElement ( "fallbackPackageFolders" ) ) ;
58
-
59
- // Check if it already has our fallback package folder
60
- for ( var xmlNode = fallbackFoldersNode . FirstChild ; xmlNode != null ; xmlNode = xmlNode . NextSibling )
61
- {
62
- if ( xmlNode . NodeType != XmlNodeType . Element )
63
- continue ;
64
-
65
- var xmlElement = ( XmlElement ) xmlNode ;
66
- if ( xmlElement . Name == "add" &&
67
- xmlElement . Attributes [ "key" ] ? . Value == name &&
68
- xmlElement . Attributes [ "value" ] ? . Value == path )
69
- {
70
- return ;
71
- }
72
- }
73
-
74
- XmlElement newEntry = xmlDoc . CreateElement ( "add" ) ;
75
- newEntry . Attributes . Append ( xmlDoc . CreateAttribute ( "key" ) ) . Value = name ;
76
- newEntry . Attributes . Append ( xmlDoc . CreateAttribute ( "value" ) ) . Value = path ;
77
-
78
- fallbackFoldersNode . AppendChild ( newEntry ) ;
79
-
80
- xmlDoc . Save ( nuGetConfigPath ) ;
81
- }
82
-
83
25
/// <summary>
84
- /// Returns all the paths where the user NuGet .Config files can be found.
26
+ /// Returns all the paths where the Godot.Offline .Config files can be found.
85
27
/// Does not determine whether the returned files exist or not.
86
28
/// </summary>
87
- private static string [ ] GetAllUserNuGetConfigFilePaths ( )
29
+ private static string [ ] GetAllGodotNuGetConfigFilePaths ( )
88
30
{
89
- // Where to find 'NuGet/NuGet .Config':
31
+ // Where to find 'NuGet/config/Godot.Offline .Config':
90
32
//
91
33
// - Mono/.NETFramework (standalone NuGet):
92
34
// Uses Environment.SpecialFolder.ApplicationData
@@ -98,10 +40,12 @@ private static string[] GetAllUserNuGetConfigFilePaths()
98
40
99
41
string applicationData = Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ;
100
42
43
+ const string configFileName = "Godot.Offline.Config" ;
44
+
101
45
if ( Utils . OS . IsWindows )
102
46
{
103
47
// %APPDATA% for both
104
- return new [ ] { Path . Combine ( applicationData , "NuGet" , "NuGet.Config" ) } ;
48
+ return new [ ] { Path . Combine ( applicationData , "NuGet" , "config" , configFileName ) } ;
105
49
}
106
50
107
51
var paths = new string [ 2 ] ;
@@ -111,20 +55,20 @@ private static string[] GetAllUserNuGetConfigFilePaths()
111
55
string dotnetCliHome = Environment . GetEnvironmentVariable ( "DOTNET_CLI_HOME" ) ;
112
56
if ( ! string . IsNullOrEmpty ( dotnetCliHome ) )
113
57
{
114
- paths [ 0 ] = Path . Combine ( dotnetCliHome , ".nuget" , "NuGet" , "NuGet.Config" ) ;
58
+ paths [ 0 ] = Path . Combine ( dotnetCliHome , ".nuget" , "NuGet" , "config" , configFileName ) ;
115
59
}
116
60
else
117
61
{
118
62
string home = Environment . GetEnvironmentVariable ( "HOME" ) ;
119
63
if ( string . IsNullOrEmpty ( home ) )
120
64
throw new InvalidOperationException ( "Required environment variable 'HOME' is not set." ) ;
121
- paths [ 0 ] = Path . Combine ( home , ".nuget" , "NuGet" , "NuGet.Config" ) ;
65
+ paths [ 0 ] = Path . Combine ( home , ".nuget" , "NuGet" , "config" , configFileName ) ;
122
66
}
123
67
124
68
// Mono/.NETFramework (standalone NuGet)
125
69
126
70
// ApplicationData is $HOME/.config on Linux/macOS
127
- paths [ 1 ] = Path . Combine ( applicationData , "NuGet" , "NuGet.Config" ) ;
71
+ paths [ 1 ] = Path . Combine ( applicationData , "NuGet" , "config" , configFileName ) ;
128
72
129
73
return paths ;
130
74
}
@@ -141,28 +85,26 @@ private static string[] GetAllUserNuGetConfigFilePaths()
141
85
// The nuspec is not lower case inside the nupkg but must be made lower case when extracted.
142
86
143
87
/// <summary>
144
- /// Adds the specified fallback folder to the user NuGet .Config files,
88
+ /// Adds the specified fallback folder to the Godot.Offline .Config files,
145
89
/// for both standalone NuGet (Mono/.NETFramework) and dotnet CLI NuGet.
146
90
/// </summary>
147
- public static void AddFallbackFolderToUserNuGetConfigs ( string name , string path )
91
+ public static void AddFallbackFolderToGodotNuGetConfigs ( string name , string path )
148
92
{
149
- foreach ( string nuGetConfigPath in GetAllUserNuGetConfigFilePaths ( ) )
93
+ // Make sure the fallback folder exists to avoid error:
94
+ // MSB4018: The "ResolvePackageAssets" task failed unexpectedly.
95
+ System . IO . Directory . CreateDirectory ( path ) ;
96
+
97
+ foreach ( string nuGetConfigPath in GetAllGodotNuGetConfigFilePaths ( ) )
150
98
{
151
- if ( ! System . IO . File . Exists ( nuGetConfigPath ) )
152
- {
153
- // It doesn't exist, so we create a default one
154
- const string defaultConfig = @"<?xml version=""1.0"" encoding=""utf-8""?>
99
+ string defaultConfig = @$ "<?xml version=""1.0"" encoding=""utf-8""?>
155
100
<configuration>
156
- <packageSources >
157
- <add key=""nuget.org "" value=""https://api.nuget.org/v3/index.json"" protocolVersion=""3 "" />
158
- </packageSources >
101
+ <fallbackPackageFolders >
102
+ <add key=""{ name } "" value=""{ path } "" />
103
+ </fallbackPackageFolders >
159
104
</configuration>
160
105
" ;
161
- System . IO . Directory . CreateDirectory ( Path . GetDirectoryName ( nuGetConfigPath ) ) ;
162
- System . IO . File . WriteAllText ( nuGetConfigPath , defaultConfig , Encoding . UTF8 ) ; // UTF-8 with BOM
163
- }
164
-
165
- AddFallbackFolderToNuGetConfig ( nuGetConfigPath , name , path ) ;
106
+ System . IO . Directory . CreateDirectory ( Path . GetDirectoryName ( nuGetConfigPath ) ) ;
107
+ System . IO . File . WriteAllText ( nuGetConfigPath , defaultConfig , Encoding . UTF8 ) ; // UTF-8 with BOM
166
108
}
167
109
}
168
110
@@ -189,6 +131,7 @@ private static void AddPackageToFallbackFolder(string fallbackFolder,
189
131
string destDir = Path . Combine ( fallbackFolder , packageIdLower , packageVersionLower ) ;
190
132
string nupkgDestPath = Path . Combine ( destDir , $ "{ packageIdLower } .{ packageVersionLower } .nupkg") ;
191
133
string nupkgSha512DestPath = Path . Combine ( destDir , $ "{ packageIdLower } .{ packageVersionLower } .nupkg.sha512") ;
134
+ string nupkgMetadataDestPath = Path . Combine ( destDir , ".nupkg.metadata" ) ;
192
135
193
136
if ( File . Exists ( nupkgDestPath ) && File . Exists ( nupkgSha512DestPath ) )
194
137
return ; // Already added (for speed we don't check if every file is properly extracted)
@@ -197,12 +140,18 @@ private static void AddPackageToFallbackFolder(string fallbackFolder,
197
140
198
141
// Generate .nupkg.sha512 file
199
142
200
- using ( var alg = SHA512 . Create ( ) )
201
- {
202
- alg . ComputeHash ( File . ReadAllBytes ( nupkgPath ) ) ;
203
- string base64Hash = Convert . ToBase64String ( alg . Hash ) ;
204
- File . WriteAllText ( nupkgSha512DestPath , base64Hash ) ;
205
- }
143
+ byte [ ] hash = SHA512 . HashData ( File . ReadAllBytes ( nupkgPath ) ) ;
144
+ string base64Hash = Convert . ToBase64String ( hash ) ;
145
+ File . WriteAllText ( nupkgSha512DestPath , base64Hash ) ;
146
+
147
+ // Generate .nupkg.metadata file
148
+ // Spec: https://github.com/NuGet/Home/wiki/Nupkg-Metadata-File
149
+
150
+ File . WriteAllText ( nupkgMetadataDestPath , @$ "{{
151
+ ""version"": 2,
152
+ ""contentHash"": ""{ base64Hash } "",
153
+ ""source"": null
154
+ }}" ) ;
206
155
207
156
// Extract nupkg
208
157
ExtractNupkg ( destDir , nupkgPath , packageId , packageVersion ) ;
@@ -251,7 +200,7 @@ private static void ExtractNupkg(string destDir, string nupkgPath, string packag
251
200
entryFullName . EndsWith ( ".nupkg.sha512" , StringComparison . OrdinalIgnoreCase ) ||
252
201
entryFullName . EndsWith ( ".nupkg.metadata" , StringComparison . OrdinalIgnoreCase ) ||
253
202
// Nuspec at root level. We already extracted it previously but in lower case.
254
- entryFullName . IndexOf ( '/' ) == - 1 && entryFullName . EndsWith ( ".nuspec" ) )
203
+ ! entryFullName . Contains ( '/' ) && entryFullName . EndsWith ( ".nuspec" ) )
255
204
{
256
205
continue ;
257
206
}
@@ -297,6 +246,8 @@ private static readonly (string packageId, string packageVersion)[] PackagesToAd
297
246
{
298
247
( "Godot.NET.Sdk" , GeneratedGodotNupkgsVersions . GodotNETSdk ) ,
299
248
( "Godot.SourceGenerators" , GeneratedGodotNupkgsVersions . GodotSourceGenerators ) ,
249
+ ( "GodotSharp" , GeneratedGodotNupkgsVersions . GodotSharp ) ,
250
+ ( "GodotSharpEditor" , GeneratedGodotNupkgsVersions . GodotSharp ) ,
300
251
} ;
301
252
}
302
253
}
0 commit comments