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 ITaskItem PackageItemAsResolvedAsset(PackageItem packageItem)
 {
     var item = new TaskItem(packageItem.OriginalItem);
     item.SetMetadata("Private", "false");
     item.SetMetadata("FromPkgProj", "true");
     item.SetMetadata("NuGetPackageId", packageItem.Package);
     item.SetMetadata("NuGetPackageVersion", packageItem.PackageVersion);
     return item;
 }
 private static ITaskItem SetPackageMetadata(ITaskItem item, PackageItem packageItem)
 {
     item.SetMetadata("Private", "false");
     item.SetMetadata("FromPkgProj", "true");
     item.SetMetadata("NuGetPackageId", packageItem.Package);
     item.SetMetadata("NuGetPackageVersion", packageItem.PackageVersion);
     return item;
 }
示例#4
0
        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 static ITaskItem PackageItemAsResolvedAsset(PackageItem packageItem)
 {
     return SetPackageMetadata(new TaskItem(packageItem.OriginalItem), packageItem);
 }
        private static IEnumerable<ITaskItem> PackageItemAndSymbolsAsResolvedAsset(PackageItem packageItem)
        {
            yield return PackageItemAsResolvedAsset(packageItem);

            string pdbPath = Path.ChangeExtension(packageItem.SourcePath, ".pdb");
            if (File.Exists(pdbPath))
            {
                var pdbItem = new TaskItem(Path.ChangeExtension(packageItem.OriginalItem.ItemSpec, ".pdb"));
                packageItem.OriginalItem.CopyMetadataTo(pdbItem);
                SetPackageMetadata(pdbItem, packageItem);
                
                if (!String.IsNullOrEmpty(packageItem.TargetPath))
                {
                    pdbItem.SetMetadata("TargetPath", Path.ChangeExtension(packageItem.TargetPath, ".pdb"));
                }

                yield return pdbItem;
            }
        }
示例#7
0
 private static ITaskItem GetOOBItem(PackageItem oobItem, string targetPath, string targetFramework)
 {
     TaskItem item = new TaskItem(oobItem.OriginalItem);
     item.SetMetadata("TargetPath", targetPath);
     item.SetMetadata("TargetFramework", targetFramework);
     return item;
 }
        public static BuildProject BuildProjectFromPackageItem(PackageItem packageItem)
        {
            if (packageItem.SourceProject == null)
            {
                return null;
            }

            return new BuildProject()
            {
                Project = packageItem.SourceProject,
                AdditionalProperties = packageItem.AdditionalProperties,
                UndefineProperties = packageItem.UndefineProperties
            };
        }
        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);
            }
        }
示例#10
0
        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 static ITaskItem PackageItemAsResolvedAsset(PackageItem packageItem)
 {
     return(SetPackageMetadata(new TaskItem(packageItem.OriginalItem), packageItem));
 }
示例#12
0
        public void HarvestFilesFromPackage()
        {
            string pathToPackage = Path.Combine(PackagesFolder, PackageId, PackageVersion);

            if (!Directory.Exists(pathToPackage))
            {
                Log.LogError($"Cannot harvest from package {PackageId}/{PackageVersion} because {pathToPackage} does not exist.");
                return;
            }

            var livePackageItems = Files.NullAsEmpty()
                                   .Where(f => IsIncludedExtension(f.GetMetadata("Extension")))
                                   .Select(f => new PackageItem(f));

            var livePackageFiles = new Dictionary <string, PackageItem>(StringComparer.OrdinalIgnoreCase);

            foreach (var livePackageItem in livePackageItems)
            {
                PackageItem existingitem;

                if (livePackageFiles.TryGetValue(livePackageItem.TargetPath, out existingitem))
                {
                    Log.LogError($"Package contains two files with same targetpath: {livePackageItem.TargetPath}, items:{livePackageItem.SourcePath}, {existingitem.SourcePath}.");
                }
                else
                {
                    livePackageFiles.Add(livePackageItem.TargetPath, livePackageItem);
                }
            }

            var harvestedFiles = new List <ITaskItem>();
            var removeFiles    = new List <ITaskItem>();

            // make sure we preserve refs that match desktop assemblies
            var liveDesktopDlls    = livePackageFiles.Values.Where(pi => pi.IsDll && pi.TargetFramework?.Framework == FrameworkConstants.FrameworkIdentifiers.Net);
            var desktopRefVersions = liveDesktopDlls.Where(d => d.IsRef && d.Version != null).Select(d => d.Version);
            var desktopLibVersions = liveDesktopDlls.Where(d => !d.IsRef && d.Version != null).Select(d => d.Version);

            // find destkop assemblies with no matching lib.
            var preserveRefVersion = new HashSet <Version>(desktopLibVersions);

            preserveRefVersion.ExceptWith(desktopRefVersions);

            foreach (var extension in s_includedExtensions)
            {
                foreach (var packageFile in Directory.EnumerateFiles(pathToPackage, $"*{extension}", SearchOption.AllDirectories))
                {
                    string harvestPackagePath = packageFile.Substring(pathToPackage.Length + 1).Replace('\\', '/');

                    // determine if we should include this file from the harvested package

                    // exclude if its specifically set for exclusion
                    if (ShouldExclude(harvestPackagePath))
                    {
                        Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is specifically excluded.");
                        continue;
                    }

                    ITaskItem includeItem = null;
                    if (!IncludeAllPaths && !ShouldInclude(harvestPackagePath, out includeItem))
                    {
                        Log.LogMessage(LogImportance.Low, $"Excluding package path {harvestPackagePath} because it is not included in {nameof(PathsToInclude)}.");
                        continue;
                    }

                    // allow for the harvested item to be moved
                    var remappedTargetPath = includeItem?.GetMetadata("TargetPath");
                    if (!String.IsNullOrEmpty(remappedTargetPath))
                    {
                        harvestPackagePath = remappedTargetPath + '/' + Path.GetFileName(packageFile);
                    }

                    List <string> targetPaths = new List <string>()
                    {
                        harvestPackagePath
                    };

                    var additionalTargetPaths = includeItem?.GetMetadata("AdditionalTargetPath");
                    if (!String.IsNullOrEmpty(additionalTargetPaths))
                    {
                        foreach (var additionalTargetPath in additionalTargetPaths.Split(';'))
                        {
                            if (!String.IsNullOrEmpty(additionalTargetPath))
                            {
                                targetPaths.Add(additionalTargetPath + '/' + Path.GetFileName(packageFile));
                            }
                        }
                    }

                    var assemblyVersion = extension == s_dll?VersionUtility.GetAssemblyVersion(packageFile) : null;

                    PackageItem liveFile = null;

                    foreach (var livePackagePath in targetPaths)
                    {
                        // determine if the harvested file clashes with a live built file
                        // we'll prefer the harvested reference assembly so long as it's the same API
                        // version and not required to match implementation 1:1 as is the case for desktop
                        if (livePackageFiles.TryGetValue(livePackagePath, out liveFile))
                        {
                            // Not a dll, or not a versioned assembly: prefer live built file.
                            if (extension != s_dll || assemblyVersion == null || liveFile.Version == null)
                            {
                                // we don't consider this an error even for explicitly included files
                                Log.LogMessage(LogImportance.Low, $"Preferring live build of package path {livePackagePath} over the asset from last stable package because the file is not versioned.");
                                continue;
                            }

                            // not a ref
                            if (!liveFile.IsRef)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it is a newer implementation.");
                                continue;
                            }

                            // preserve desktop references to ensure bindingRedirects will work.
                            if (liveFile.TargetFramework.Framework == FrameworkConstants.FrameworkIdentifiers.Net)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it is desktop reference.");
                                continue;
                            }

                            // as above but handle the case where a netstandard ref may be used for a desktop impl.
                            if (preserveRefVersion.Contains(liveFile.Version))
                            {
                                LogSkipIncludedFile(livePackagePath, " because it will be applicable for desktop projects.");
                                continue;
                            }

                            // preserve references with a different major.minor version
                            if (assemblyVersion.Major != liveFile.Version.Major ||
                                assemblyVersion.Minor != liveFile.Version.Minor)
                            {
                                LogSkipIncludedFile(livePackagePath, $" because it is a different API version ( {liveFile.Version.Major}.{liveFile.Version.Minor} vs {assemblyVersion.Major}.{assemblyVersion.Minor}.");
                                continue;
                            }

                            // preserve references that specifically set the preserve metadata.
                            bool preserve = false;
                            bool.TryParse(liveFile.OriginalItem.GetMetadata("Preserve"), out preserve);
                            if (preserve)
                            {
                                LogSkipIncludedFile(livePackagePath, " because it set metadata Preserve=true.");
                                continue;
                            }

                            // replace the live file with the harvested one, removing both the live file and PDB from the
                            // file list.
                            Log.LogMessage($"Using reference {livePackagePath} from last stable package {PackageId}/{PackageVersion} rather than the built reference {liveFile.SourcePath} since it is the same API version.  Set <Preserve>true</Preserve> on {liveFile.SourceProject} if you'd like to avoid this..");
                            removeFiles.Add(liveFile.OriginalItem);

                            PackageItem livePdbFile;
                            if (livePackageFiles.TryGetValue(Path.ChangeExtension(livePackagePath, ".pdb"), out livePdbFile))
                            {
                                removeFiles.Add(livePdbFile.OriginalItem);
                            }
                        }
                        else
                        {
                            Log.LogMessage(LogImportance.Low, $"Including {livePackagePath} from last stable package {PackageId}/{PackageVersion}.");
                        }

                        var item = new TaskItem(packageFile);

                        if (liveFile?.OriginalItem != null)
                        {
                            // preserve all the meta-data from the live file that was replaced.
                            liveFile.OriginalItem.CopyMetadataTo(item);
                        }
                        else
                        {
                            if (includeItem != null)
                            {
                                includeItem.CopyMetadataTo(item);
                            }
                            var targetPath = Path.GetDirectoryName(livePackagePath).Replace('\\', '/');
                            item.SetMetadata("TargetPath", targetPath);
                            string targetFramework = GetTargetFrameworkFromPackagePath(targetPath);
                            item.SetMetadata("TargetFramework", targetFramework);
                            // only harvest for non-portable frameworks, matches logic in packaging.targets.
                            bool harvestDependencies = !targetFramework.StartsWith("portable-");
                            item.SetMetadata("HarvestDependencies", harvestDependencies.ToString());
                            item.SetMetadata("IsReferenceAsset", IsReferencePackagePath(targetPath).ToString());
                        }

                        if (assemblyVersion != null)
                        {
                            // overwrite whatever metadata may have been copied from the live file.
                            item.SetMetadata("AssemblyVersion", assemblyVersion.ToString());
                        }

                        item.SetMetadata("HarvestedFrom", $"{PackageId}/{PackageVersion}/{harvestPackagePath}");

                        harvestedFiles.Add(item);
                    }
                }
            }

            HarvestedFiles = harvestedFiles.ToArray();

            if (_pathsNotIncluded != null)
            {
                foreach (var pathNotIncluded in _pathsNotIncluded)
                {
                    Log.LogError($"Path '{pathNotIncluded}' was specified in {nameof(PathsToInclude)} but was not found in the package {PackageId}/{PackageVersion}.");
                }
            }

            if (Files != null)
            {
                UpdatedFiles = Files.Except(removeFiles).ToArray();
            }
        }
示例#13
0
        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));
            }
        }