Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VersionSelector"/> class.
 /// </summary>
 public VersionSelector(Pool pool)
 {
     this.pool = pool;
     parser    = new VersionParser();
 }
Ejemplo n.º 3
0
        private IPackage CreatePackage(string version)
        {
            var parser = new BVersionParser();

            return(new BPackage("foo", parser.Normalize(version), version));
        }
Ejemplo n.º 4
0
        /// <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());
        }
Ejemplo n.º 5
0
        /// <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;
            }
        }