private void LoadFiles() { _packageToPackageItems = new Dictionary <string, List <PackageItem> >(); foreach (var file in PackageAssets) { try { var packageItem = new PackageItem(file); if (String.IsNullOrWhiteSpace(packageItem.TargetPath)) { Log.LogError($"{packageItem.TargetPath} is missing TargetPath metadata"); } if (!_packageToPackageItems.ContainsKey(packageItem.Package)) { _packageToPackageItems[packageItem.Package] = new List <PackageItem>(); } _packageToPackageItems[packageItem.Package].Add(packageItem); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary <string, PackageItem>(); foreach (var packageFiles in _packageToPackageItems) { foreach (PackageItem packageFile in packageFiles.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageFiles.Key, packageFile.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {packageFile.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = packageFile; } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in _packageToPackageItems.Keys) { _resolver.AddPackageItems(packageId, _packageToPackageItems[packageId].Select(f => f.TargetPath)); } }
private void LoadFiles() { _packageToPackageItems = new Dictionary<string, List<PackageItem>>(); foreach (var file in PackageAssets) { try { var packageItem = new PackageItem(file); if (String.IsNullOrWhiteSpace(packageItem.TargetPath)) { Log.LogError($"{packageItem.TargetPath} is missing TargetPath metadata"); } if (!_packageToPackageItems.ContainsKey(packageItem.Package)) { _packageToPackageItems[packageItem.Package] = new List<PackageItem>(); } _packageToPackageItems[packageItem.Package].Add(packageItem); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary<string, PackageItem>(); foreach (var packageFiles in _packageToPackageItems) { foreach (PackageItem packageFile in packageFiles.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageFiles.Key, packageFile.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {packageFile.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = packageFile; } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in _packageToPackageItems.Keys) { _resolver.AddPackageItems(packageId, _packageToPackageItems[packageId].Select(f => f.TargetPath)); } }
private void HarvestSupportedFrameworks() { List <ITaskItem> supportedFrameworks = new List <ITaskItem>(); AggregateNuGetAssetResolver resolver = new AggregateNuGetAssetResolver(RuntimeFile); string packagePath = Path.Combine(PackagesFolder, PackageId, PackageVersion); // add the primary package resolver.AddPackageItems(PackageId, GetPackageItems(packagePath)); if (RuntimePackages != null) { // add any split runtime packages foreach (var runtimePackage in RuntimePackages) { var runtimePackageId = runtimePackage.ItemSpec; var runtimePackageVersion = runtimePackage.GetMetadata("Version"); resolver.AddPackageItems(runtimePackageId, GetPackageItems(PackagesFolder, runtimePackageId, runtimePackageVersion)); } } // create a resolver that can be used to determine the API version for inbox assemblies // since inbox assemblies are represented with placeholders we can remove the placeholders // and use the netstandard reference assembly to determine the API version var filesWithoutPlaceholders = GetPackageItems(packagePath) .Where(f => !NuGetAssetResolver.IsPlaceholder(f)); NuGetAssetResolver resolverWithoutPlaceholders = new NuGetAssetResolver(RuntimeFile, filesWithoutPlaceholders); string package = $"{PackageId}/{PackageVersion}"; foreach (var framework in Frameworks) { var runtimeIds = framework.GetMetadata("RuntimeIDs")?.Split(';'); NuGetFramework fx; try { fx = FrameworkUtilities.ParseNormalized(framework.ItemSpec); } catch (Exception ex) { Log.LogError($"Could not parse Framework {framework.ItemSpec}. {ex}"); continue; } if (fx.Equals(NuGetFramework.UnsupportedFramework)) { Log.LogError($"Did not recognize {framework.ItemSpec} as valid Framework."); continue; } var compileAssets = resolver.ResolveCompileAssets(fx, PackageId); bool hasCompileAsset, hasCompilePlaceHolder; NuGetAssetResolver.ExamineAssets(Log, "Compile", package, fx.ToString(), compileAssets, out hasCompileAsset, out hasCompilePlaceHolder); // start by making sure it has some asset available for compile var isSupported = hasCompileAsset || hasCompilePlaceHolder; if (!isSupported) { Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported."); continue; } foreach (var runtimeId in runtimeIds) { string target = String.IsNullOrEmpty(runtimeId) ? fx.ToString() : $"{fx}/{runtimeId}"; var runtimeAssets = resolver.ResolveRuntimeAssets(fx, runtimeId); bool hasRuntimeAsset, hasRuntimePlaceHolder; NuGetAssetResolver.ExamineAssets(Log, "Runtime", package, target, runtimeAssets, out hasRuntimeAsset, out hasRuntimePlaceHolder); isSupported &= hasCompileAsset == hasRuntimeAsset; isSupported &= hasCompilePlaceHolder == hasRuntimePlaceHolder; if (!isSupported) { Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported on {target}."); break; } } if (isSupported) { var supportedFramework = new TaskItem(framework.ItemSpec); supportedFramework.SetMetadata("HarvestedFromPackage", package); // set version // first try the resolved compile asset for this package var refAssm = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r))?.Substring(PackageId.Length + 1); if (refAssm == null) { // if we didn't have a compile asset it means this framework is supported inbox with a placeholder // resolve the assets without placeholders to pick up the netstandard reference assembly. compileAssets = resolverWithoutPlaceholders.ResolveCompileAssets(fx); refAssm = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r)); } string version = "unknown"; if (refAssm != null) { version = VersionUtility.GetAssemblyVersion(Path.Combine(packagePath, refAssm))?.ToString() ?? version; } supportedFramework.SetMetadata("Version", version); Log.LogMessage($"Validating version {version} for {supportedFramework.ItemSpec} because it was supported by {PackageId}/{PackageVersion}."); supportedFrameworks.Add(supportedFramework); } } SupportedFrameworks = supportedFrameworks.ToArray(); }
private void LoadFiles() { _validateFiles = new Dictionary<string, List<PackageItem>>(); foreach (var file in Files) { try { var validateFile = new PackageItem(file); if (String.IsNullOrWhiteSpace(validateFile.TargetPath)) { Log.LogError($"{validateFile.TargetPath} is missing TargetPath metadata"); } if (IsDll(validateFile.SourcePath)) { if (validateFile.TargetFramework == null) { Log.LogError($"{validateFile.SourcePath} is missing TargetFramework metadata"); } else if (validateFile.TargetPath.IndexOf(validateFile.TargetFramework.GetShortFolderName(), StringComparison.OrdinalIgnoreCase) == -1) { Log.LogError($"{validateFile.SourcePath} specifies TargetFramework {validateFile.TargetFramework} but TargetPath {validateFile.TargetPath} is missing the {validateFile.TargetFramework.GetShortFolderName()} qualifier"); } } if (!_validateFiles.ContainsKey(validateFile.Package)) { _validateFiles[validateFile.Package] = new List<PackageItem>(); } _validateFiles[validateFile.Package].Add(validateFile); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary<string, PackageItem>(); foreach (var packageFiles in _validateFiles) { foreach (PackageItem validateFile in packageFiles.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageFiles.Key, validateFile.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {validateFile.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = validateFile; } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in _validateFiles.Keys) { _resolver.AddPackageItems(packageId, _validateFiles[packageId].Select(f => f.TargetPath)); } }
private void LoadFiles() { _validateFiles = new Dictionary <string, List <PackageItem> >(); foreach (var file in Files) { try { var validateFile = new PackageItem(file); if (String.IsNullOrWhiteSpace(validateFile.TargetPath)) { Log.LogError($"{validateFile.TargetPath} is missing TargetPath metadata"); } if (IsDll(validateFile.SourcePath)) { if (validateFile.TargetFramework == null) { Log.LogError($"{validateFile.SourcePath} is missing TargetFramework metadata"); } else if (validateFile.TargetPath.IndexOf(validateFile.TargetFramework.GetShortFolderName(), StringComparison.OrdinalIgnoreCase) == -1) { Log.LogError($"{validateFile.SourcePath} specifies TargetFramework {validateFile.TargetFramework} but TargetPath {validateFile.TargetPath} is missing the {validateFile.TargetFramework.GetShortFolderName()} qualifier"); } } if (!_validateFiles.ContainsKey(validateFile.Package)) { _validateFiles[validateFile.Package] = new List <PackageItem>(); } _validateFiles[validateFile.Package].Add(validateFile); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary <string, PackageItem>(); foreach (var packageFiles in _validateFiles) { foreach (PackageItem validateFile in packageFiles.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageFiles.Key, validateFile.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {validateFile.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = validateFile; } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in _validateFiles.Keys) { _resolver.AddPackageItems(packageId, _validateFiles[packageId].Select(f => f.TargetPath)); } }
private void LoadFiles() { var packageItems = new Dictionary <string, List <PackageItem> >(); foreach (var file in Files) { try { var packageItem = new PackageItem(file); if (!packageItem.TargetPath.StartsWith("runtimes") && !packageItem.IsDll && !packageItem.IsPlaceholder) { continue; } if (String.IsNullOrWhiteSpace(packageItem.TargetPath)) { Log.LogError($"{packageItem.TargetPath} is missing TargetPath metadata"); } string packageId = packageItem.Package ?? PackageId; if (!packageItems.ContainsKey(packageId)) { packageItems[packageId] = new List <PackageItem>(); } packageItems[packageId].Add(packageItem); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary <string, PackageItem>(); _unusedTargetPaths = new HashSet <string>(); foreach (var packageSpecificItems in packageItems) { foreach (PackageItem packageItem in packageSpecificItems.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageSpecificItems.Key, packageItem.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {packageItem.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = packageItem; _unusedTargetPaths.Add(packageSpecificTargetPath); } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in packageItems.Keys) { _resolver.AddPackageItems(packageId, packageItems[packageId].Select(f => f.TargetPath)); } // create a resolver that can be used to determine the API version for inbox assemblies // since inbox assemblies are represented with placeholders we can remove the placeholders // and use the netstandard reference assembly to determine the API version if (packageItems.Any() && packageItems.ContainsKey(PackageId)) { var filesWithoutPlaceholders = packageItems[PackageId] .Select(pf => pf.TargetPath) .Where(f => !NuGetAssetResolver.IsPlaceholder(f)); _resolverWithoutPlaceholders = new NuGetAssetResolver(RuntimeFile, filesWithoutPlaceholders); } }
private void LoadFiles() { var packageItems = new Dictionary<string, List<PackageItem>>(); foreach (var file in Files) { try { var packageItem = new PackageItem(file); if (!packageItem.TargetPath.StartsWith("runtimes") && !packageItem.IsDll && !packageItem.IsPlaceholder) { continue; } if (String.IsNullOrWhiteSpace(packageItem.TargetPath)) { Log.LogError($"{packageItem.TargetPath} is missing TargetPath metadata"); } string packageId = packageItem.Package ?? PackageId; if (!packageItems.ContainsKey(packageId)) { packageItems[packageId] = new List<PackageItem>(); } packageItems[packageId].Add(packageItem); } catch (Exception ex) { Log.LogError($"Could not parse File {file.ItemSpec}. {ex}"); // skip it. } } // build a map to translate back to source file from resolved asset // we use package-specific paths since we're resolving a set of packages. _targetPathToPackageItem = new Dictionary<string, PackageItem>(); _unusedTargetPaths = new HashSet<string>(); foreach (var packageSpecificItems in packageItems) { foreach (PackageItem packageItem in packageSpecificItems.Value) { string packageSpecificTargetPath = AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageSpecificItems.Key, packageItem.TargetPath); if (_targetPathToPackageItem.ContainsKey(packageSpecificTargetPath)) { Log.LogError($"Files {_targetPathToPackageItem[packageSpecificTargetPath].SourcePath} and {packageItem.SourcePath} have the same TargetPath {packageSpecificTargetPath}."); } _targetPathToPackageItem[packageSpecificTargetPath] = packageItem; _unusedTargetPaths.Add(packageSpecificTargetPath); } } _resolver = new AggregateNuGetAssetResolver(RuntimeFile); foreach (string packageId in packageItems.Keys) { _resolver.AddPackageItems(packageId, packageItems[packageId].Select(f => f.TargetPath)); } // create a resolver that can be used to determine the API version for inbox assemblies // since inbox assemblies are represented with placeholders we can remove the placeholders // and use the netstandard reference assembly to determine the API version if (packageItems.Any() && packageItems.ContainsKey(PackageId)) { var filesWithoutPlaceholders = packageItems[PackageId] .Select(pf => pf.TargetPath) .Where(f => !NuGetAssetResolver.IsPlaceholder(f)); _resolverWithoutPlaceholders = new NuGetAssetResolver(RuntimeFile, filesWithoutPlaceholders); } }
private void HarvestSupportedFrameworks() { List<ITaskItem> supportedFrameworks = new List<ITaskItem>(); AggregateNuGetAssetResolver resolver = new AggregateNuGetAssetResolver(RuntimeFile); string packagePath = Path.Combine(PackagesFolder, PackageId, PackageVersion); // add the primary package resolver.AddPackageItems(PackageId, GetPackageItems(packagePath)); if (RuntimePackages != null) { // add any split runtime packages foreach (var runtimePackage in RuntimePackages) { var runtimePackageId = runtimePackage.ItemSpec; var runtimePackageVersion = runtimePackage.GetMetadata("Version"); resolver.AddPackageItems(runtimePackageId, GetPackageItems(PackagesFolder, runtimePackageId, runtimePackageVersion)); } } // create a resolver that can be used to determine the API version for inbox assemblies // since inbox assemblies are represented with placeholders we can remove the placeholders // and use the netstandard reference assembly to determine the API version var filesWithoutPlaceholders = GetPackageItems(packagePath) .Where(f => !NuGetAssetResolver.IsPlaceholder(f)); NuGetAssetResolver resolverWithoutPlaceholders = new NuGetAssetResolver(RuntimeFile, filesWithoutPlaceholders); string package = $"{PackageId}/{PackageVersion}"; foreach (var framework in Frameworks) { var runtimeIds = framework.GetMetadata("RuntimeIDs")?.Split(';'); NuGetFramework fx; try { fx = FrameworkUtilities.ParseNormalized(framework.ItemSpec); } catch (Exception ex) { Log.LogError($"Could not parse Framework {framework.ItemSpec}. {ex}"); continue; } if (fx.Equals(NuGetFramework.UnsupportedFramework)) { Log.LogError($"Did not recognize {framework.ItemSpec} as valid Framework."); continue; } var compileAssets = resolver.ResolveCompileAssets(fx, PackageId); bool hasCompileAsset, hasCompilePlaceHolder; NuGetAssetResolver.ExamineAssets(Log, "Compile", package, fx.ToString(), compileAssets, out hasCompileAsset, out hasCompilePlaceHolder); // start by making sure it has some asset available for compile var isSupported = hasCompileAsset || hasCompilePlaceHolder; if (!isSupported) { Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported."); continue; } foreach (var runtimeId in runtimeIds) { string target = String.IsNullOrEmpty(runtimeId) ? fx.ToString() : $"{fx}/{runtimeId}"; var runtimeAssets = resolver.ResolveRuntimeAssets(fx, runtimeId); bool hasRuntimeAsset, hasRuntimePlaceHolder; NuGetAssetResolver.ExamineAssets(Log, "Runtime", package, target, runtimeAssets, out hasRuntimeAsset, out hasRuntimePlaceHolder); isSupported &= hasCompileAsset == hasRuntimeAsset; isSupported &= hasCompilePlaceHolder == hasRuntimePlaceHolder; if (!isSupported) { Log.LogMessage(LogImportance.Low, $"Skipping {fx} because it is not supported on {target}."); break; } } if (isSupported) { var supportedFramework = new TaskItem(framework.ItemSpec); supportedFramework.SetMetadata("HarvestedFromPackage", package); // set version // first try the resolved compile asset for this package var refAssm = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r))?.Substring(PackageId.Length + 1); if (refAssm == null) { // if we didn't have a compile asset it means this framework is supported inbox with a placeholder // resolve the assets without placeholders to pick up the netstandard reference assembly. compileAssets = resolverWithoutPlaceholders.ResolveCompileAssets(fx); refAssm = compileAssets.FirstOrDefault(r => !NuGetAssetResolver.IsPlaceholder(r)); } string version = "unknown"; if (refAssm != null) { version = VersionUtility.GetAssemblyVersion(Path.Combine(packagePath, refAssm))?.ToString() ?? version; } supportedFramework.SetMetadata("Version", version); Log.LogMessage(LogImportance.Low, $"Validating version {version} for {supportedFramework.ItemSpec} because it was supported by {PackageId}/{PackageVersion}."); supportedFrameworks.Add(supportedFramework); } } SupportedFrameworks = supportedFrameworks.ToArray(); }