1212using Microsoft . Build . Framework ;
1313using Microsoft . Build . Utilities ;
1414using NuGet . Common ;
15- using NuGet . Frameworks ;
1615using NuGet . ProjectModel ;
1716using NuGet . Versioning ;
1817
@@ -156,8 +155,16 @@ public sealed class ResolvePackageAssets : TaskBase
156155 [ Required ]
157156 public string DotNetAppHostExecutableNameWithoutExtension { get ; set ; }
158157
158+ /// <summary>
159+ /// True indicates we are doing a design-time build. Otherwise we are in a build.
160+ /// </summary>
159161 public bool DesignTimeBuild { get ; set ; }
160162
163+ /// <summary>
164+ /// Enable publishing XML documentation
165+ /// </summary>
166+ public bool PublishReferencesDocumentationFiles { get ; set ; }
167+
161168 /// <summary>
162169 /// Full paths to assemblies from packages to pass to compiler as analyzers.
163170 /// </summary>
@@ -231,6 +238,24 @@ public sealed class ResolvePackageAssets : TaskBase
231238 [ Output ]
232239 public ITaskItem [ ] PackageDependencies { get ; private set ; }
233240
241+ /// <summary>
242+ /// List of symbol files (.pdb) related to NuGet packages.
243+ /// </summary>
244+ /// <remarks>
245+ /// Pdb files to be copied to the output directory
246+ /// </remarks>
247+ [ Output ]
248+ public ITaskItem [ ] DebugSymbolsFiles { get ; private set ; }
249+
250+ /// <summary>
251+ /// List of xml files related to NuGet packages.
252+ /// </summary>
253+ /// <remarks>
254+ /// The XML files should only be included in the publish output if PublishReferencesDocumentationFiles is true
255+ /// </remarks>
256+ [ Output ]
257+ public ITaskItem [ ] DebugXmlFiles { get ; private set ; }
258+
234259 /// <summary>
235260 /// Messages from the assets file.
236261 /// These are logged directly and therefore not returned to the targets (note private here).
@@ -311,6 +336,8 @@ private void ReadItemGroups()
311336 ApphostsForShimRuntimeIdentifiers = reader . ReadItemGroup ( ) ;
312337 CompileTimeAssemblies = reader . ReadItemGroup ( ) ;
313338 ContentFilesToPreprocess = reader . ReadItemGroup ( ) ;
339+ DebugSymbolsFiles = reader . ReadItemGroup ( ) ;
340+ DebugXmlFiles = reader . ReadItemGroup ( ) ;
314341 FrameworkAssemblies = reader . ReadItemGroup ( ) ;
315342 FrameworkReferences = reader . ReadItemGroup ( ) ;
316343 NativeLibraries = reader . ReadItemGroup ( ) ;
@@ -443,6 +470,7 @@ internal byte[] HashSettings()
443470 }
444471 writer . Write ( TargetFramework ) ;
445472 writer . Write ( VerifyMatchingImplicitPackageVersion ) ;
473+ writer . Write ( PublishReferencesDocumentationFiles ) ;
446474 }
447475
448476 stream . Position = 0 ;
@@ -510,7 +538,7 @@ private static BinaryReader CreateReaderFromDisk(ResolvePackageAssets task, byte
510538 BinaryReader reader = null ;
511539 try
512540 {
513- if ( File . GetLastWriteTimeUtc ( task . ProjectAssetsCacheFile ) > File . GetLastWriteTimeUtc ( task . ProjectAssetsFile ) )
541+ if ( IsCacheFileUpToDate ( ) )
514542 {
515543 reader = OpenCacheFile ( task . ProjectAssetsCacheFile , settingsHash ) ;
516544 }
@@ -537,6 +565,8 @@ private static BinaryReader CreateReaderFromDisk(ResolvePackageAssets task, byte
537565 }
538566
539567 return reader ;
568+
569+ bool IsCacheFileUpToDate ( ) => File . GetLastWriteTimeUtc ( task . ProjectAssetsCacheFile ) > File . GetLastWriteTimeUtc ( task . ProjectAssetsFile ) ;
540570 }
541571
542572 private static BinaryReader OpenCacheStream ( Stream stream , byte [ ] settingsHash )
@@ -651,6 +681,8 @@ internal sealed class CacheWriter : IDisposable
651681
652682 private const string NetCorePlatformLibrary = "Microsoft.NETCore.App" ;
653683
684+ private const char RelatedPropertySeparator = ';' ;
685+
654686 public CacheWriter ( ResolvePackageAssets task )
655687 {
656688 _targetFramework = task . TargetFramework ;
@@ -776,6 +808,8 @@ private void WriteItemGroups()
776808 WriteItemGroup ( WriteApphostsForShimRuntimeIdentifiers ) ;
777809 WriteItemGroup ( WriteCompileTimeAssemblies ) ;
778810 WriteItemGroup ( WriteContentFilesToPreprocess ) ;
811+ WriteItemGroup ( WriteDebugSymbolsFiles ) ;
812+ WriteItemGroup ( WriteDebugXmlFiles ) ;
779813 WriteItemGroup ( WriteFrameworkAssemblies ) ;
780814 WriteItemGroup ( WriteFrameworkReferences ) ;
781815 WriteItemGroup ( WriteNativeLibraries ) ;
@@ -1091,6 +1125,57 @@ private void WriteContentFilesToPreprocess()
10911125 } ) ;
10921126 }
10931127
1128+ private void WriteDebugSymbolsFiles ( )
1129+ {
1130+ WriteDebugItems (
1131+ p => p . RuntimeAssemblies ,
1132+ MetadataKeys . PdbExtension ) ;
1133+ }
1134+
1135+ private void WriteDebugXmlFiles ( )
1136+ {
1137+ if ( _task . PublishReferencesDocumentationFiles )
1138+ {
1139+ WriteDebugItems (
1140+ p => p . CompileTimeAssemblies ,
1141+ MetadataKeys . XmlExtension ) ;
1142+ }
1143+ }
1144+
1145+ private void WriteDebugItems < T > (
1146+ Func < LockFileTargetLibrary , IEnumerable < T > > getAssets ,
1147+ string extension )
1148+ where T : LockFileItem
1149+ {
1150+ foreach ( var library in _runtimeTarget . Libraries )
1151+ {
1152+ if ( ! library . IsPackage ( ) )
1153+ {
1154+ continue ;
1155+ }
1156+
1157+ foreach ( T asset in getAssets ( library ) )
1158+ {
1159+ if ( asset . IsPlaceholderFile ( ) || ! asset . Properties . ContainsKey ( MetadataKeys . RelatedProperty ) )
1160+ {
1161+ continue ;
1162+ }
1163+
1164+ string itemSpec = _packageResolver . ResolvePackageAssetPath ( library , asset . Path ) ;
1165+
1166+ asset . Properties . TryGetValue ( MetadataKeys . RelatedProperty , out string relatedExtensions ) ;
1167+
1168+ foreach ( string fileExtension in relatedExtensions . Split ( RelatedPropertySeparator ) )
1169+ {
1170+ if ( fileExtension . ToLower ( ) == extension )
1171+ {
1172+ WriteItem ( Path . ChangeExtension ( itemSpec , extension ) , library ) ;
1173+ }
1174+ }
1175+ }
1176+ }
1177+ }
1178+
10941179 private void WriteFrameworkAssemblies ( )
10951180 {
10961181 if ( _task . DisableFrameworkAssemblies )
0 commit comments