public void TestFindRecommendedRequireVersion(string versionPretty, bool isDev, Stabilities stability, string expectedVersion) { var versionParser = new BVersionParser(); var package = new Mock <IPackage>(); package.Setup((o) => o.GetVersionPretty()).Returns(versionPretty); package.Setup((o) => o.GetVersion()).Returns(versionParser.Normalize(versionPretty)); package.Setup((o) => o.IsDev).Returns(isDev); package.Setup((o) => o.GetStability()).Returns(stability); var recommended = selector.FindRecommendedRequireVersion(package.Object); Assert.AreEqual(expectedVersion, recommended); }
/// <summary> /// Initializes a new instance of the <see cref="VersionSelector"/> class. /// </summary> public VersionSelector(Pool pool) { this.pool = pool; parser = new VersionParser(); }
private IPackage CreatePackage(string version) { var parser = new BVersionParser(); return(new BPackage("foo", parser.Normalize(version), version)); }
/// <summary> /// Determine the requirements packages. /// </summary> protected virtual string[] DetermineRequirements(IInput input, IOutput output, string[] requires, Stabilities preferredStability, bool checkProvidedVersions) { var result = new List <string>(); var io = GetIO(); if (!requires.Empty()) { var normalizedRequires = NormalizeRequirements(requires); foreach (var(name, version) in normalizedRequires) { if (string.IsNullOrEmpty(version)) { // determine the best version automatically var(bestName, bestVersion) = FindBestVersionAndNameForPackage(input, name, preferredStability); io.WriteError($"Using version <info>{bestVersion}</info> for <info>{bestName}</info>"); result.Add($"{bestName} {bestVersion}"); } else { // check that the specified version/constraint exists before we proceed var(bestName, bestVersion) = FindBestVersionAndNameForPackage(input, name, preferredStability, checkProvidedVersions ? version : null, Stabilities.Dev); result.Add($"{bestName} {version}"); } } return(result.ToArray()); } bool AskPackage(out string name) { name = io.Ask("Search for a package: "); return(!string.IsNullOrEmpty(name)); } var versionParser = new BVersionParser(); while (AskPackage(out string name)) { var matches = FindPackages(name); if (matches.Empty()) { continue; } var exactMatch = false; var choices = new List <string>(); for (var i = 0; i < matches.Length; i++) { var deprecated = string.Empty; if (matches[i].IsDeprecated) { var replacement = matches[i].GetReplacementPackage(); if (string.IsNullOrEmpty(replacement)) { deprecated = "No replacement was suggested."; } else { deprecated = $"Use {replacement} instead."; } deprecated = $"<warning>Deprecated. {deprecated}</warning>"; } choices.Add($" <info>[{i}]</info> {matches[i].GetName()} {deprecated}"); if (matches[i].GetName() == name) { exactMatch = true; break; } } // no match, prompt which to pick if (!exactMatch) { io.WriteError(new[] { string.Empty, $"Found <info>{matches.Length}</info> packages matching <info>{name}</info>", string.Empty, }); io.WriteError(choices); Mixture Validator(Mixture selection) { if (string.IsNullOrEmpty(selection)) { return(null); } if (int.TryParse(selection, out int index) && index < matches.Length) { return(matches[index].GetName()); } var packageMatches = Regex.Match(selection, @"^\s*(?<name>[\S/]+)(?:\s+(?<version>\S+))?\s*$"); if (!packageMatches.Success) { throw new RuntimeException("Not a valid selection"); } var version = packageMatches.Groups["version"].Value; if (string.IsNullOrEmpty(version)) { return(packageMatches.Groups["name"].Value); } // validate version constraint. versionParser.ParseConstraints(version); return(packageMatches.Groups["name"].Value + Str.Space + version); } name = io.AskAndValidate("Enter package # to add, or the complete package name if it is not listed: ", Validator, 3); } // no constraint yet, determine the best version automatically. if (string.IsNullOrEmpty(name)) { continue; } if (name.Contains(Str.Space)) { result.Add(name); continue; } Mixture ValidatorConstraint(Mixture value) { if (string.IsNullOrEmpty(value)) { return(null); } var version = value.ToString().Trim(); // validate version constraint. versionParser.ParseConstraints(version); return(version); } string constraint = io.AskAndValidate( "Enter the version constraint to require (or leave blank to use the latest version): ", ValidatorConstraint, 3); if (string.IsNullOrEmpty(constraint)) { (_, constraint) = FindBestVersionAndNameForPackage(input, name, preferredStability); io.WriteError($"Using version <info>{constraint}</info> for <info>{name}</info>"); } result.Add($"{name} {constraint}"); } return(result.ToArray()); }
/// <inheritdoc /> protected override int Execute(IInput input, IOutput output) { file = Factory.GetBucketFile(); filePath = Path.Combine(Environment.CurrentDirectory, file); var io = GetIO(); newlyCreated = !File.Exists(filePath); if (newlyCreated) { try { File.WriteAllText(filePath, NewBucketContent); } #pragma warning disable CA1031 catch (SException ex) #pragma warning restore CA1031 { io.WriteError($"<error>{file} could not be created: {ex.Message}.</error>"); return(ExitCodes.GeneralException); } } backup = File.ReadAllText(filePath); if (string.IsNullOrEmpty(backup)) { File.WriteAllText(filePath, NewBucketContent); backup = NewBucketContent; } json = new JsonFile(filePath); var bucket = GetBucket(true, input.GetOption("no-plugins")); // todo: import mock platform repository = new RepositoryComposite( Arr.Merge( new[] { new RepositoryPlatform(bucket.GetPackage().GetPlatforms()) }, bucket.GetRepositoryManager().GetRepositories())); var preferredStability = Stabilities.Stable; var preferredStable = bucket.GetPackage().IsPreferStable ?? false; if (!preferredStable) { preferredStability = bucket.GetPackage().GetMinimumStability() ?? preferredStability; } var requireKey = input.GetOption("dev") ? LinkType.RequireDev : LinkType.Require; var removeKey = input.GetOption("dev") ? LinkType.Require : LinkType.RequireDev; var requirements = FormatRequirements( DetermineRequirements(input, output, input.GetArgument("packages"), preferredStability, !input.GetOption("no-update"))); // validate requirements format. var versionParser = new BVersionParser(); foreach (var item in requirements) { var package = item.Key; var constraint = item.Value; if (package.ToLower() == bucket.GetPackage().GetName()) { io.WriteError($"<error>Root package \"{package}\" cannot require itself in its bucket.json</error>"); return(ExitCodes.Normal); } versionParser.ParseConstraints(constraint); } var sortPackages = input.GetOption("sort-packages") || bucket.GetConfig().Get(Settings.SortPackages); if (!UpdateFileCleanly(json, requirements, requireKey, removeKey, sortPackages)) { File.WriteAllText(filePath, backup); throw new RuntimeException("Failed to write to file successfully, operation has been rolled back."); } io.WriteError($"<info>{file} has been {(newlyCreated ? "created" : "update")}</info>"); if (input.GetOption("no-update")) { return(ExitCodes.Normal); } try { return(DoUpdate(input, output, io, requirements)); } catch (SException) { RevertBucketFile(false); throw; } }