コード例 #1
0
		public static ICommand Create(
			   string project,
			   string configuration,
			   NuGetFramework framework,
			   string buildBasePath,
			   string output)
		{
			var args = new List<string>()
			{
				project,
				"--configuration", configuration,
				"--framework", framework.GetShortFolderName()
			};

			if (buildBasePath != null)
			{
				args.Add("--build-base-path");
				args.Add(buildBasePath);
			}

			if (output != null)
			{
				args.Add("--output");
				args.Add(output);
			}

			return Command.CreateDotNet(
				"build",
				args,
				framework,
				configuration);
		}
コード例 #2
0
ファイル: ToolPathCalculator.cs プロジェクト: krytarowski/cli
 public string GetLockFilePath(string packageId, NuGetVersion version, NuGetFramework framework)
 {
     return Path.Combine(
         GetBaseToolPath(packageId),
         version.ToNormalizedString(),
         framework.GetShortFolderName(),
         "project.lock.json");
 }
コード例 #3
0
        public string GetLockFilePath(string packageId, NuGetVersion version, NuGetFramework framework)
        {
            if (version == null)
            {
                throw new ArgumentNullException(nameof(version));
            }

            if (framework == null)
            {
                throw new ArgumentNullException(nameof(framework));
            }

            return Path.Combine(
                GetBaseToolPath(packageId),
                version.ToNormalizedString(),
                framework.GetShortFolderName(),
                "project.lock.json");
        }
コード例 #4
0
        // HACK(anurse): NuGet.Frameworks turns "dnxcore50" into "dnxcore5" :(
        public static string GetTwoDigitShortFolderName(this NuGetFramework self)
        {
            var original = self.GetShortFolderName();
            var index    = 0;

            for (; index < original.Length; index++)
            {
                if (char.IsDigit(original[index]))
                {
                    break;
                }
            }

            var versionPart = original.Substring(index);

            if (versionPart.Length >= 2)
            {
                return(original);
            }

            // Assume if the version part was preserved then leave it alone
            if (versionPart.IndexOf('.') != -1)
            {
                return(original);
            }

            var name    = original.Substring(0, index);
            var version = self.Version.ToString(2);

            if (self.Framework.Equals(FrameworkConstants.FrameworkIdentifiers.NetPlatform))
            {
                return(name + version);
            }

            return(name + version.Replace(".", string.Empty));
        }
コード例 #5
0
ファイル: ValidatePackage.cs プロジェクト: dsgouda/buildtools
        private void LoadSupport()
        {
            _frameworks = new Dictionary<NuGetFramework, ValidationFramework>();

            // determine which TxM:RIDs should be considered for support based on Frameworks item
            foreach (var framework in Frameworks)
            {
                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;
                }

                string runtimeIdList = framework.GetMetadata("RuntimeIDs");
                
                if (_frameworks.ContainsKey(fx))
                {
                    Log.LogError($"Framework {fx} has been listed in Frameworks more than once.");
                    continue;
                }

                _frameworks[fx] = new ValidationFramework(fx);

                if (!String.IsNullOrWhiteSpace(runtimeIdList))
                {
                    _frameworks[fx].RuntimeIds = runtimeIdList.Split(';');
                }
            }

            // keep a list of explicitly listed supported frameworks so that we can check for conflicts.
            HashSet<NuGetFramework> explicitlySupportedFrameworks = new HashSet<NuGetFramework>();

            // determine what version should be supported based on SupportedFramework items
            foreach (var supportedFramework in SupportedFrameworks)
            {
                NuGetFramework fx;
                string fxString = supportedFramework.ItemSpec;
                bool isExclusiveVersion = fxString.Length > 1 && fxString[0] == '[' && fxString[fxString.Length - 1] == ']';
                if (isExclusiveVersion)
                {
                    fxString = fxString.Substring(1, fxString.Length - 2);
                }

                try
                {
                    fx = FrameworkUtilities.ParseNormalized(fxString);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse TargetFramework {fxString} as a SupportedFramework. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize TargetFramework {fxString} as a SupportedFramework.");
                    continue;
                }

                Version supportedVersion;
                string version = supportedFramework.GetMetadata("Version");
                try
                {
                    supportedVersion = Version.Parse(version);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Version {version} on SupportedFramework item {supportedFramework.ItemSpec}. {ex}");
                    continue;
                }

                ValidationFramework validationFramework = null;
                if (!_frameworks.TryGetValue(fx, out validationFramework))
                {
                    Log.LogError($"SupportedFramework {fx} was specified but is not part of the Framework list to use for validation.");
                    continue;
                }


                if (explicitlySupportedFrameworks.Contains(fx))
                {
                    if (validationFramework.SupportedVersion != supportedVersion)
                    {
                        Log.LogError($"Framework {fx} has been listed in SupportedFrameworks more than once with different versions {validationFramework.SupportedVersion} and {supportedVersion}.  Framework should only be listed once with the expected API version for that platform.");
                    }
                    continue;
                }
                explicitlySupportedFrameworks.Add(fx);

                validationFramework.SupportedVersion = supportedVersion;
                
                if (!isExclusiveVersion)
                {
                    // find all frameworks of higher version, sorted by version ascending
                    var higherFrameworks = _frameworks.Values.Where(vf => vf.Framework.Framework == fx.Framework && vf.Framework.Version > fx.Version).OrderBy(vf => vf.Framework.Version);

                    foreach(var higherFramework in higherFrameworks)
                    {
                        if (higherFramework.SupportedVersion != null && higherFramework.SupportedVersion > supportedVersion)
                        {
                            // found an higher framework version a higher API version, stop applying this supported version
                            break;
                        }

                        higherFramework.SupportedVersion = supportedVersion;
                    }
                }
            }


            // determine which Frameworks should support inbox
            _frameworkSet = FrameworkSet.Load(FrameworkListsPath);
            foreach (IEnumerable<Framework> inboxFxGroup in _frameworkSet.Frameworks.Values)
            {
                foreach (Framework inboxFx in inboxFxGroup)
                {
                    // get currently supported version to see if we have OOB'ed it
                    Version inboxVersion = null;
                    inboxFx.Assemblies.TryGetValue(ContractName, out inboxVersion);

                    if (inboxVersion != null)
                    {
                        NuGetFramework fx = FrameworkUtilities.ParseNormalized(inboxFx.ShortName);
                        ValidationFramework validationFramework = null;
                        if (_frameworks.TryGetValue(fx, out validationFramework))
                        {
                            Version supportedVersion = validationFramework.SupportedVersion;

                            if (supportedVersion != null &&
                                (supportedVersion.Major > inboxVersion.Major ||
                                (supportedVersion.Major == inboxVersion.Major && supportedVersion.Minor > inboxVersion.Minor)))
                            {
                                // Higher major.minor
                                Log.LogMessage(LogImportance.Low, $"Framework {fx} supported {ContractName} as inbox but the current supported version {supportedVersion} is higher in major.minor than inbox version {inboxVersion}.  Assuming out of box.");
                                continue;
                            }
                            else if (supportedVersion != null && supportedVersion < inboxVersion)
                            {
                                // Lower version
                                Log.LogError($"Framework {fx} supports {ContractName} as inbox but the current supported version {supportedVersion} is lower than the inbox version {inboxVersion}");
                            }

                            // equal major.minor, build.revision difference is permitted, prefer the version listed by ContractSupport item
                        }

                        if (validationFramework == null)
                        {
                            // we may not be explicitly validating for this framework so add it to validate inbox assets.
                            _frameworks[fx] = validationFramework = new ValidationFramework(fx)
                            {
                                SupportedVersion = inboxVersion
                            };
                        }

                        validationFramework.IsInbox = true;
                    }
                }
            }

            // for every framework we know about, also validate it's generation to ensure it can
            // be targeted by PCL.  Even if a package only supports a single framework we still
            // want to include a portable reference assembly.  This allows 3rd parties to add 
            // their own implementation via a lineup/runtime.json.

            // only consider frameworks that support the contract at a specific version
            var portableFrameworks = _frameworks.Values.Where(fx => fx.SupportedVersion != null && fx.SupportedVersion != s_maxVersion).ToArray();

            var genVersionSuppression = GetSuppressionValues(Suppression.PermitPortableVersionMismatch) ?? new HashSet<string>();
            Dictionary<NuGetFramework, ValidationFramework> generationsToValidate = new Dictionary<NuGetFramework, ValidationFramework>();
            foreach (var framework in portableFrameworks)
            {
                NuGetFramework generation = new NuGetFramework(_generationIdentifier, Generations.DetermineGenerationForFramework(framework.Framework, UseNetPlatform));
                Log.LogMessage(LogImportance.Low, $"Validating {generation} for {ContractName}, {framework.SupportedVersion} since it is supported by {framework.Framework}");

                ValidationFramework existingGeneration = null;
                if (generationsToValidate.TryGetValue(generation, out existingGeneration))
                {
                    if (!VersionUtility.IsCompatibleApiVersion(framework.SupportedVersion, existingGeneration.SupportedVersion) && !genVersionSuppression.Contains(framework.Framework.ToString()))
                    {
                        Log.LogError($"Framework {framework.Framework} supports {ContractName} at {framework.SupportedVersion} which is lower than {existingGeneration.SupportedVersion} supported by generation {generation.GetShortFolderName()}");
                    }
                }
                else
                {
                    generationsToValidate.Add(generation, new ValidationFramework(generation) { SupportedVersion = framework.SupportedVersion });
                }
            }

            foreach (var generation in generationsToValidate)
            {
                _frameworks.Add(generation.Key, generation.Value);
            }

            // for every generation supported explcitly in implementation, ensure
            // it can be targeted by PCL.
            foreach (var packageGroup in _resolver.GetAllRuntimeItems())
            {
                var allGenerationalImplementations = packageGroup.Value
                    .Where(contentGroup => FrameworkUtilities.IsGenerationMoniker(contentGroup.Properties[PropertyNames.TargetFrameworkMoniker] as NuGetFramework))
                    .SelectMany(contentGroup => contentGroup.Items.Select(item => _targetPathToPackageItem[AggregateNuGetAssetResolver.AsPackageSpecificTargetPath(packageGroup.Key, item.Path)]));

                foreach (var generationalImplementation in allGenerationalImplementations)
                {
                    NuGetFramework generation = generationalImplementation.TargetFramework;
                    if (_frameworks.ContainsKey(generation))
                    {
                        continue;
                    }

                    Version supportedVersion = generationalImplementation.Version;

                    Log.LogMessage(LogImportance.Low, $"Validating {generation} for {ContractName}, {supportedVersion} since it is supported by {generationalImplementation.TargetPath}");

                    _frameworks.Add(generation, new ValidationFramework(generation) { SupportedVersion = supportedVersion });
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Sort PCLs using these criteria
        /// 1. Lowest number of frameworks (highest surface area) wins first
        /// 2. Profile with the highest version numbers wins next
        /// 3. String compare is used as a last resort
        /// </summary>
        private bool IsBetterPCL(NuGetFramework current, NuGetFramework considering)
        {
            Debug.Assert(considering.IsPCL && current.IsPCL, "This method should be used only to compare PCLs");

            // Find all frameworks in the profile
            var consideringFrameworks = ExplodePortableFramework(considering, false);

            var currentFrameworks = ExplodePortableFramework(current, false);

            // The PCL with the least frameworks (highest surface area) goes first
            if (consideringFrameworks.Count() < currentFrameworks.Count())
            {
                return(true);
            }
            else if (currentFrameworks.Count() < consideringFrameworks.Count())
            {
                return(false);
            }

            // If both frameworks have the same number of frameworks take the framework that has the highest
            // overall set of framework versions

            // Find Frameworks that both profiles have in common
            var sharedFrameworkIds = consideringFrameworks.Select(f => f.Framework)
                                     .Where(f =>
                                            currentFrameworks.Any(consideringFramework => StringComparer.OrdinalIgnoreCase.Equals(f, consideringFramework.Framework)));

            var consideringHighest = 0;
            var currentHighest     = 0;

            // Determine which framework has the highest version of each shared framework
            foreach (var sharedId in sharedFrameworkIds)
            {
                var consideringFramework = consideringFrameworks.First(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId));
                var currentFramework     = currentFrameworks.First(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId));

                if (consideringFramework.Version < currentFramework.Version)
                {
                    currentHighest++;
                }
                else if (currentFramework.Version < consideringFramework.Version)
                {
                    consideringHighest++;
                }
            }

            // Prefer the highest count
            if (currentHighest < consideringHighest)
            {
                return(true);
            }
            else if (consideringHighest < currentHighest)
            {
                return(false);
            }

            // Take the highest version of .NET if no winner could be determined, this is usually a good indicator of which is newer
            var consideringNet = consideringFrameworks.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net));
            var currentNet     = currentFrameworks.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net));

            // Compare using .NET only if both frameworks have it. PCLs should always have .NET, but since users can make these strings up we should
            // try to handle that as best as possible.
            if (consideringNet != null &&
                currentNet != null)
            {
                if (currentNet.Version < consideringNet.Version)
                {
                    return(true);
                }
                else if (consideringNet.Version < currentNet.Version)
                {
                    return(false);
                }
            }

            // In the very rare case that both frameworks are still equal, we have to pick one.
            // There is nothing but we need to be deterministic, so compare the profiles as strings.
            if (StringComparer.OrdinalIgnoreCase.Compare(considering.GetShortFolderName(_mappings), current.GetShortFolderName(_mappings)) < 0)
            {
                return(true);
            }

            return(false);
        }
コード例 #7
0
        private IEnumerable<string> GetRuntimeAssetFoldersForPromotion(ContentItemGroup runtimeAssets, NuGetFramework targetFramework, string targetFrameworkName)
        {
            if (runtimeAssets == null || runtimeAssets.Items.Count == 0)
            {
                return Enumerable.Empty<string>();
            }

            if (runtimeAssets.Items.All(ci => NuGetAssetResolver.IsPlaceholder(ci.Path)))
            {
                return Enumerable.Empty<string>();
            }

            if (targetFrameworkName == null)
            {
                targetFrameworkName = targetFramework.GetShortFolderName();
            }

            var resolvedFramework = runtimeAssets.Properties["tfm"] as NuGetFramework;
            if (targetFramework.Equals(resolvedFramework))
            {
                Log.LogMessage(LogImportance.Low, $"Not promoting explicit implementation for {targetFrameworkName}");
                return Enumerable.Empty<string>();
            }

            return NuGetAssetResolver.GetPackageTargetDirectories(runtimeAssets);
        }
コード例 #8
0
        private IEnumerable<string> GetObscuredAssetFolders(ContentItemGroup assets, ContentItemGroup obscuredAssets, NuGetFramework targetFramework, string targetFrameworkName, string expectedAssetFolder, string ignoredAssetFolder = null)
        {
            if (assets == null || assets.Items.Count == 0)
            {
                return Enumerable.Empty<string>();
            }

            if (assets.Items.Any(ci => !NuGetAssetResolver.IsPlaceholder(ci.Path)))
            {
                return Enumerable.Empty<string>();
            }

            if (targetFrameworkName == null)
            {
                targetFrameworkName = targetFramework.GetShortFolderName();
            }

            var resolvedFramework = assets.Properties["tfm"] as NuGetFramework;
            if (targetFramework.Equals(resolvedFramework))
            {
                Log.LogMessage(LogImportance.Low, $"Not overriding explicit placeholder for {targetFrameworkName}");
                return Enumerable.Empty<string>();
            }

            var obscuredAssetPaths = NuGetAssetResolver.GetPackageTargetDirectories(obscuredAssets);

            if (ignoredAssetFolder != null)
            {
                string ignoredFolder = ignoredAssetFolder + '/';
                obscuredAssetPaths = obscuredAssetPaths.Where(i => -1 == i.IndexOf(ignoredFolder, StringComparison.OrdinalIgnoreCase));
            }

            if (expectedAssetFolder != null)
            {
                var unexpectedAssetPaths = obscuredAssetPaths.Where(ri => !ri.StartsWith(expectedAssetFolder, StringComparison.OrdinalIgnoreCase));
                foreach (var unexpectedAssetPath in unexpectedAssetPaths)
                {
                    Log.LogWarning($"Unexpected targetPath {unexpectedAssetPath}.  Expected only {expectedAssetFolder}.");
                }

                // filter after we've warned
                obscuredAssetPaths = obscuredAssetPaths.Except(unexpectedAssetPaths);
            }

            if (!obscuredAssetPaths.Any())
            {
                // it's acceptable to have no override, this is the case for packages which 
                // carry implementation in a runtime-specific package
                Log.LogMessage(LogImportance.Low, $"No {expectedAssetFolder} assets could be found to override inbox placeholder for {targetFrameworkName}.");
            }

            return obscuredAssetPaths;
        }
コード例 #9
0
ファイル: OutputPathsCalculator.cs プロジェクト: ericstj/cli
        public static OutputPaths GetOutputPaths(
            Project project,
            NuGetFramework framework,
            string runtimeIdentifier,
            string configuration,
            string solutionRootPath,
            string buildBasePath,
            string outputPath)
        {
            string resolvedBuildBasePath;
            if (string.IsNullOrEmpty(buildBasePath))
            {
                resolvedBuildBasePath = project.ProjectDirectory;
            }
            else
            {
                if (string.IsNullOrEmpty(solutionRootPath))
                {
                    resolvedBuildBasePath = Path.Combine(buildBasePath, project.Name);
                }
                else
                {
                    resolvedBuildBasePath = project.ProjectDirectory.Replace(solutionRootPath, buildBasePath);
                }
            }

            var compilationOutputPath = PathUtility.EnsureTrailingSlash(Path.Combine(resolvedBuildBasePath,
                BinDirectoryName,
                configuration,
                framework.GetShortFolderName()));

            string runtimeOutputPath = null;
            if (string.IsNullOrEmpty(outputPath))
            {
                if (!string.IsNullOrEmpty(runtimeIdentifier))
                {
                    runtimeOutputPath = PathUtility.EnsureTrailingSlash(Path.Combine(compilationOutputPath, runtimeIdentifier));
                }
                else
                {
                    // "Runtime" assets (i.e. the deps file) will be dropped to the compilation output path, because
                    // we are building a RID-less target.
                    runtimeOutputPath = compilationOutputPath;
                }
            }
            else
            {
                runtimeOutputPath = PathUtility.EnsureTrailingSlash(Path.GetFullPath(outputPath));
            }

            var intermediateOutputPath = PathUtility.EnsureTrailingSlash(Path.Combine(
                resolvedBuildBasePath,
                ObjDirectoryName,
                configuration,
                framework.GetTwoDigitShortFolderName()));

            var compilationFiles = new CompilationOutputFiles(compilationOutputPath, project, configuration, framework);

            RuntimeOutputFiles runtimeFiles = null;
            if (runtimeOutputPath != null)
            {
                runtimeFiles = new RuntimeOutputFiles(runtimeOutputPath, project, configuration, framework);
            }
            return new OutputPaths(intermediateOutputPath, compilationOutputPath, runtimeOutputPath, compilationFiles, runtimeFiles);
        }
コード例 #10
0
 public DotNetFramework(NuGetFramework framework)
 {
     Name = framework.Framework;
     FriendlyName = framework.Framework;
     ShortName = framework.GetShortFolderName();
 }
コード例 #11
0
        /// <summary>
        /// Возвращает информацию о файле пакета для указанного источника и фреймворка.
        /// </summary>
        /// <param name="packagePath">Путь к каталогу пакета.</param>
        /// <param name="sourcePath">Путь к файлу в каталоге пакетов.</param>
        /// <param name="sourcePart">Каталог файла пакета ('lib', 'content' и т.д.).</param>
        /// <param name="sourceFramework">Версия фремворка файла пакета.</param>
        private static PackageFile GetPackageItem(string packagePath,
                                                  string sourcePath,
                                                  string sourcePart,
                                                  NuGetFramework sourceFramework)
        {
            // Путь файла в пакете обычно имеет вид 'lib/net45/some.dll'
            // или 'lib/some.dll' для NuGetFramework.AnyFramework

            sourcePath = sourcePath.Replace('/', Path.DirectorySeparatorChar);

            var installPath = sourcePath;

            // Определение части пути источника, которая указывает на NuGetFramework файла,
            // например, 'lib/net45/' или 'lib/' для NuGetFramework.AnyFramework

            var partFrameworkPath = sourcePart + Path.DirectorySeparatorChar;

            if (!Equals(sourceFramework, NuGetFramework.AnyFramework))
            {
                partFrameworkPath += sourceFramework.GetShortFolderName() + Path.DirectorySeparatorChar;
            }

            // Определение относительного пути для установки файла, например, для источника
            // 'lib/net45/some.dll' путь для установки будет 'some.dll', а для источника
            // 'lib/net45/en-US/resources.dll' путь для установки будет 'en-US/resources.dll'

            if (sourcePath.StartsWith(partFrameworkPath, StringComparison.OrdinalIgnoreCase))
            {
                installPath = sourcePath.Substring(partFrameworkPath.Length);
            }
            else if (!Equals(sourceFramework, NuGetFramework.AnyFramework))
            {
                // Обработка нестандартных путей, например, 'lib/net45-full/log4net.dll'

                var index = sourcePath.IndexOf(Path.DirectorySeparatorChar, sourcePart.Length + 1);

                if (index >= 0)
                {
                    installPath = sourcePath.Substring(index + 1);
                }
            }

            return new PackageFile(Path.Combine(packagePath, sourcePath), installPath);
        }
コード例 #12
0
ファイル: ValidatePackage.cs プロジェクト: roncain/buildtools
        private void LoadSupport()
        {
            _frameworks = new Dictionary<NuGetFramework, ValidationFramework>();

            // determine which TxM:RIDs should be considered for support based on Frameworks item
            foreach (var framework in Frameworks)
            {
                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;
                }

                string runtimeIdList = framework.GetMetadata("RuntimeIDs");
                
                if (_frameworks.ContainsKey(fx))
                {
                    Log.LogError($"Framework {fx} has been listed in Frameworks more than once.");
                    continue;
                }

                _frameworks[fx] = new ValidationFramework(fx);

                if (!String.IsNullOrWhiteSpace(runtimeIdList))
                {
                    _frameworks[fx].RuntimeIds = runtimeIdList.Split(';');
                }
            }

            // keep a list of explicitly listed supported frameworks so that we can check for conflicts.
            HashSet<NuGetFramework> explicitlySupportedFrameworks = new HashSet<NuGetFramework>();

            // determine what version should be supported based on SupportedFramework items
            foreach (var supportedFramework in SupportedFrameworks)
            {
                NuGetFramework fx;
                string fxString = supportedFramework.ItemSpec;
                bool isExclusiveVersion = fxString.Length > 1 && fxString[0] == '[' && fxString[fxString.Length - 1] == ']';
                if (isExclusiveVersion)
                {
                    fxString = fxString.Substring(1, fxString.Length - 2);
                }

                try
                {
                    fx = FrameworkUtilities.ParseNormalized(fxString);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse TargetFramework {fxString} as a SupportedFramework. {ex}");
                    continue;
                }

                if (fx.Equals(NuGetFramework.UnsupportedFramework))
                {
                    Log.LogError($"Did not recognize TargetFramework {fxString} as a SupportedFramework.");
                    continue;
                }

                Version supportedVersion;
                string version = supportedFramework.GetMetadata("Version");
                try
                {
                    supportedVersion = Version.Parse(version);
                }
                catch (Exception ex)
                {
                    Log.LogError($"Could not parse Version {version} on SupportedFramework item {supportedFramework.ItemSpec}. {ex}");
                    continue;
                }

                ValidationFramework validationFramework = null;
                if (!_frameworks.TryGetValue(fx, out validationFramework))
                {
                    Log.LogError($"SupportedFramework {fx} was specified but is not part of the Framework list to use for validation.");
                    continue;
                }


                if (explicitlySupportedFrameworks.Contains(fx))
                {
                    if (supportedVersion <= validationFramework.SupportedVersion)
                    {
                        // if we've already picked up a higher/equal version, prefer it
                        continue;
                    }
                }
                else
                {
                    explicitlySupportedFrameworks.Add(fx);
                }

                validationFramework.SupportedVersion = supportedVersion;
                
                if (!isExclusiveVersion)
                {
                    // find all frameworks of higher version, sorted by version ascending
                    IEnumerable<ValidationFramework> higherFrameworks = _frameworks.Values.Where(vf => vf.Framework.Framework == fx.Framework && vf.Framework.Version > fx.Version).OrderBy(vf => vf.Framework.Version);

                    // netcore50 is the last `netcore` framework, after that we use `uap`
                    if (fx.Framework == FrameworkConstants.FrameworkIdentifiers.NetCore)
                    {
                        var uapFrameworks = _frameworks.Values.Where(vf => vf.Framework.Framework == FrameworkConstants.FrameworkIdentifiers.UAP).OrderBy(vf => vf.Framework.Version);
                        higherFrameworks = higherFrameworks.Concat(uapFrameworks);
                    }


                    foreach (var higherFramework in higherFrameworks)
                    {
                        if (higherFramework.SupportedVersion != null && higherFramework.SupportedVersion > supportedVersion)
                        {
                            // found an higher framework version a higher API version, stop applying this supported version
                            break;
                        }

                        higherFramework.SupportedVersion = supportedVersion;
                    }
                }
            }


            // determine which Frameworks should support inbox
            _frameworkSet = FrameworkSet.Load(FrameworkListsPath);
            foreach (IEnumerable<Framework> inboxFxGroup in _frameworkSet.Frameworks.Values)
            {
                foreach (Framework inboxFx in inboxFxGroup)
                {
                    // get currently supported version to see if we have OOB'ed it
                    Version inboxVersion = null;
                    inboxFx.Assemblies.TryGetValue(ContractName, out inboxVersion);

                    if (inboxVersion != null)
                    {
                        NuGetFramework fx = FrameworkUtilities.ParseNormalized(inboxFx.ShortName);
                        ValidationFramework validationFramework = null;
                        if (_frameworks.TryGetValue(fx, out validationFramework))
                        {
                            Version supportedVersion = validationFramework.SupportedVersion;

                            if (supportedVersion != null &&
                                (supportedVersion.Major > inboxVersion.Major ||
                                (supportedVersion.Major == inboxVersion.Major && supportedVersion.Minor > inboxVersion.Minor)))
                            {
                                // Higher major.minor
                                Log.LogMessage(LogImportance.Low, $"Framework {fx} supported {ContractName} as inbox but the current supported version {supportedVersion} is higher in major.minor than inbox version {inboxVersion}.  Assuming out of box.");
                                continue;
                            }
                            else if (supportedVersion != null && supportedVersion < inboxVersion && inboxVersion != s_maxVersion)
                            {
                                // Lower version
                                Log.LogError($"Framework {fx} supports {ContractName} as inbox but the current supported version {supportedVersion} is lower than the inbox version {inboxVersion}");
                            }

                            // equal major.minor, build.revision difference is permitted, prefer the version listed by ContractSupport item
                        }

                        if (validationFramework == null)
                        {
                            // we may not be explicitly validating for this framework so add it to validate inbox assets.
                            _frameworks[fx] = validationFramework = new ValidationFramework(fx)
                            {
                                SupportedVersion = inboxVersion
                            };
                        }

                        validationFramework.IsInbox = true;
                    }
                }
            }

            // for every framework we know about, also infer it's netstandard version to ensure it can
            // be targeted by PCL.  Even if a package only supports a single framework we still
            // want to include a portable reference assembly.  This allows 3rd parties to add 
            // their own implementation via a lineup/runtime.json.

            // only consider frameworks that support the contract at a specific version
            var inferFrameworks = _frameworks.Values.Where(fx => fx.SupportedVersion != null && fx.SupportedVersion != s_maxVersion).ToArray();

            var genVersionSuppression = GetSuppressionValues(Suppression.PermitPortableVersionMismatch) ?? new HashSet<string>();
            var inferNETStandardSuppression = GetSuppressionValues(Suppression.SuppressNETStandardInference) ?? new HashSet<string>();
            Dictionary<NuGetFramework, ValidationFramework> generationsToValidate = new Dictionary<NuGetFramework, ValidationFramework>();
            foreach (var inferFramework in inferFrameworks)
            {
                var inferFrameworkMoniker = inferFramework.Framework.ToString();
                if (inferNETStandardSuppression.Contains(inferFrameworkMoniker))
                {
                    continue;
                }

                NuGetFramework generation = new NuGetFramework(_generationIdentifier, Generations.DetermineGenerationForFramework(inferFramework.Framework, UseNetPlatform));
                Log.LogMessage(LogImportance.Low, $"Validating {generation} for {ContractName}, {inferFramework.SupportedVersion} since it is supported by {inferFrameworkMoniker}");

                ValidationFramework existingGeneration = null;
                if (generationsToValidate.TryGetValue(generation, out existingGeneration))
                {
                    // the netstandard version should be the minimum version supported by all platforms that support that netstandard version.
                    if (inferFramework.SupportedVersion < existingGeneration.SupportedVersion)
                    {
                        Log.LogMessage($"Framework {inferFramework.Framework} supports {ContractName} at {inferFramework.SupportedVersion} which is lower than {existingGeneration.SupportedVersion} supported by generation {generation.GetShortFolderName()}.  Lowering the version supported by {generation.GetShortFolderName()}.");
                        existingGeneration.SupportedVersion = inferFramework.SupportedVersion;
                    }
                }
                else
                {
                    generationsToValidate.Add(generation, new ValidationFramework(generation) { SupportedVersion = inferFramework.SupportedVersion });
                }
            }

            foreach (var generation in generationsToValidate)
            {
                _frameworks.Add(generation.Key, generation.Value);
            }
        }
コード例 #13
0
 public static bool IsPortableMoniker(NuGetFramework nuGetFramework)
 {
     return nuGetFramework == null ? false : nuGetFramework.GetShortFolderName().StartsWith("portable-");
 }
コード例 #14
0
ファイル: FrameworkReducer.cs プロジェクト: eerhardt/NuGet3
        /// <summary>
        /// Sort PCLs using these criteria
        /// 1. Lowest number of frameworks (highest surface area) wins first
        /// 2. Profile with the highest version numbers wins next
        /// 3. String compare is used as a last resort
        /// </summary>
        private bool IsBetterPCL(NuGetFramework current, NuGetFramework considering)
        {
            Debug.Assert(considering.IsPCL && current.IsPCL, "This method should be used only to compare PCLs");

            // Find all frameworks in the profile
            var consideringFrameworks = ExplodePortableFramework(considering, false);

            var currentFrameworks = ExplodePortableFramework(current, false);

            // The PCL with the least frameworks (highest surface area) goes first
            if (consideringFrameworks.Count() < currentFrameworks.Count())
            {
                return true;
            }
            else if (currentFrameworks.Count() < consideringFrameworks.Count())
            {
                return false;
            }

            // If both frameworks have the same number of frameworks take the framework that has the highest 
            // overall set of framework versions

            // Find Frameworks that both profiles have in common
            var sharedFrameworkIds = consideringFrameworks.Select(f => f.Framework)
                .Where(f =>
                    currentFrameworks.Any(consideringFramework => StringComparer.OrdinalIgnoreCase.Equals(f, consideringFramework.Framework)));

            var consideringHighest = 0;
            var currentHighest = 0;

            // Determine which framework has the highest version of each shared framework
            foreach (var sharedId in sharedFrameworkIds)
            {
                var consideringFramework = consideringFrameworks.Where(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId)).First();
                var currentFramework = currentFrameworks.Where(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, sharedId)).First();

                if (consideringFramework.Version < currentFramework.Version)
                {
                    currentHighest++;
                }
                else if (currentFramework.Version < consideringFramework.Version)
                {
                    consideringHighest++;
                }
            }

            // Prefer the highest count
            if (currentHighest < consideringHighest)
            {
                return true;
            }
            else if (consideringHighest < currentHighest)
            {
                return false;
            }

            // Take the highest version of .NET if no winner could be determined, this is usually a good indicator of which is newer
            var consideringNet = consideringFrameworks.Where(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net)).First();
            var currentNet = currentFrameworks.Where(f => StringComparer.OrdinalIgnoreCase.Equals(f.Framework, FrameworkConstants.FrameworkIdentifiers.Net)).First();

            // Compare using .NET only if both frameworks have it. PCLs should always have .NET, but since users can make these strings up we should
            // try to handle that as best as possible.
            if (consideringNet != null
                && currentNet != null)
            {
                if (currentNet.Version < consideringNet.Version)
                {
                    return true;
                }
                else if (consideringNet.Version < currentNet.Version)
                {
                    return false;
                }
            }

            // In the very rare case that both frameworks are still equal, we have to pick one. 
            // There is nothing but we need to be deterministic, so compare the profiles as strings.
            if (StringComparer.OrdinalIgnoreCase.Compare(considering.GetShortFolderName(_mappings), current.GetShortFolderName(_mappings)) < 0)
            {
                return true;
            }

            return false;
        }
コード例 #15
0
 public ITaskItem GetItemWithTargetFramework(NuGetFramework framework)
 {
     var newItem = new TaskItem(OriginalItem);
     newItem.SetMetadata("TargetFramework", framework.GetShortFolderName());
     return newItem;
 }
コード例 #16
0
        private void Add(NuGetFramework framework, string runtime)
        {
            var path = new StringBuilder();
            if (!String.IsNullOrEmpty(runtime) && !IsReferenceAssembly)
            {
                path.Append($"runtimes/{runtime}/");
            }

            string folder = IsReferenceAssembly ? "ref" : "lib";
            string fx = framework.GetShortFolderName();
            path.Append($"{folder}/{fx}");

            _packageDestinations.Add(CreatePackageDestination(path.ToString(), fx));

            // RID-specific desktop libraries should also be packaged without a RID to work in packages.config projects
            if (framework.Framework == FrameworkConstants.FrameworkIdentifiers.Net)
            {
                if (!String.IsNullOrEmpty(runtime) && PackageDesktopAsLib)
                {
                    _packageDestinations.Add(CreatePackageDestination($"lib/{fx}", fx));
                }

                if (PackageDesktopAsRef)
                {
                    _packageDestinations.Add(CreatePackageDestination($"ref/{fx}", fx));
                    IsReferenceAsset = true;
                }
            }
        }
コード例 #17
0
 private IEnumerable<ITaskItem> CopyDependencies(IEnumerable<Dependency> dependencies, NuGetFramework targetFramework)
 {
     foreach (var dependency in dependencies)
     {
         if (!Frameworks.IsInbox(FrameworkListsPath, targetFramework, dependency.Id, dependency.Version))
         {
             var copiedDepenedency = new TaskItem(dependency.OriginalItem);
             copiedDepenedency.SetMetadata(TargetFrameworkMetadataName, targetFramework.GetShortFolderName());
             yield return copiedDepenedency;
         }
     }
 }
コード例 #18
0
        public override bool Execute()
        {
            if (String.IsNullOrEmpty(PackageTargetFramework))
            {
                Log.LogMessage(LogImportance.Low, $"Skipping validation since PackageTargetFramework is not defined");
                return true;
            }

            NuGetFramework fx = null;
            try
            {
                fx = NuGetFramework.Parse(PackageTargetFramework);
            }
            catch(Exception ex)
            {
                Log.LogError($"Could not parse PackageTargetFramework {PackageTargetFramework}. {ex}");
                return false;
            }

            Version assemblyVersion = null;
            if (!Version.TryParse(AssemblyVersion, out assemblyVersion))
            {
                Log.LogError($"Could not parse AssemblyVersion {AssemblyVersion}.");
                return false;
            }

            if (UseNetPlatform)
            {
                if (fx.Framework == FrameworkConstants.FrameworkIdentifiers.NetStandard)
                {
                    Log.LogError($"Validating for legacy 'dotnet' moniker but package targets new 'netstandard' moniker.");
                    return false;
                }
                else if (fx.Framework != FrameworkConstants.FrameworkIdentifiers.NetPlatform)
                {
                    Log.LogMessage(LogImportance.Low, $"Skipping validation since PackageTargetFramework {fx} is not {FrameworkConstants.FrameworkIdentifiers.NetPlatform}");
                    return true;
                }
            }
            else
            {
                if (fx.Framework == FrameworkConstants.FrameworkIdentifiers.NetPlatform)
                {
                    if (fx.Version > new Version(5, 0))
                    {
                        NuGetFramework netstandardFx = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetStandard, new Version(fx.Version.Major - 4, fx.Version.Minor - 1));
                        Log.LogError($"{fx.GetShortFolderName()} is no longer supported please update to {netstandardFx.GetShortFolderName()}.  Validating as {netstandardFx.GetShortFolderName()}.");
                        // update to netstandard so that we can get the right number of errors
                        fx = netstandardFx;
                    }
                    else
                    {
                        Log.LogError($"Invalid framework version {fx.GetShortFolderName()} please update to appropriate netstandard version.");
                        // update to nestandard so that we'll do the actual calculation
                        fx = FrameworkConstants.CommonFrameworks.NetStandard;
                    }
                }


                if (fx.Framework != FrameworkConstants.FrameworkIdentifiers.NetStandard)
                {
                    Log.LogMessage(LogImportance.Low, $"Skipping validation since PackageTargetFramework {fx} is not {FrameworkConstants.FrameworkIdentifiers.NetStandard}");
                    return true;
                }
            }

            _generations = Generations.Load(GenerationDefinitionsFile, UseNetPlatform);

            Dictionary<string, string> candidateRefs = CandidateReferences.ToDictionary(r => r.GetMetadata("FileName"), r => r.GetMetadata("FullPath"));

            Version idealGeneration = _generations.DetermineGenerationFromSeeds(AssemblyName, assemblyVersion, Log) ?? new Version(0, 0, 0, 0);
            if (idealGeneration > fx.Version)
            {
                Log.LogError($"Assembly {AssemblyName}, Version={assemblyVersion} is generation {idealGeneration} based on the seed data in {GenerationDefinitionsFile} which is greater than project generation {fx.Version}.");
            }

            HashSet<string> ignoredRefs = null;

            if (IgnoredReferences != null)
            {
                ignoredRefs = new HashSet<string>(IgnoredReferences.Select(ir => ir.ItemSpec), StringComparer.OrdinalIgnoreCase);
            }

            Version defaultGeneration = UseNetPlatform ? FrameworkConstants.CommonFrameworks.DotNet.Version : FrameworkConstants.CommonFrameworks.NetStandard.Version;

            foreach (var reference in DirectReferences)
            {
                string path = reference.GetMetadata("FullPath");

                // workaround issue where portable targeting pack design time facades
                // include dangling refs and refs to higher versions of contracts than 
                // exist in the targeting pack.
                if (path.IndexOf(".NETPortable", StringComparison.OrdinalIgnoreCase) != -1 &&
                    designTimeFacades.Contains(Path.GetFileNameWithoutExtension(path)))
                {
                    continue;
                }

                if (ignoredRefs != null && ignoredRefs.Contains(Path.GetFileNameWithoutExtension(path)))
                {
                    continue;
                }
                
                if (!File.Exists(path))
                {
                    Log.LogError($"Reference {path} does not exist.");
                    continue;
                }

                var dependencyGeneration = _generations.DetermineGenerationFromFile(path, Log, candidateRefs: candidateRefs, ignoredRefs: ignoredRefs) ?? defaultGeneration;

                if (dependencyGeneration > fx.Version)
                {
                    Log.LogError($"Dependency {path} is generation {dependencyGeneration} which is greater than project generation {fx.Version}.");
                }
                
                if (dependencyGeneration > idealGeneration)
                {
                    idealGeneration = dependencyGeneration;
                }
            }

            if (fx.Version > idealGeneration)
            {
                Log.LogMessage(LogImportance.Low, $"Generation {fx.Version} is higher than the ideal miniumum {idealGeneration}.");
            }


            return !Log.HasLoggedErrors;
        }