Пример #1
0
        /// <summary>
        /// Whether the driver support the specified uri.
        /// </summary>
        /// <param name="io">The input/output instance.</param>
        /// <param name="config">The config instance.</param>
        /// <param name="uri">Thr specified uri.</param>
        /// <param name="deep">Whether is deep checker.</param>
        /// <returns>True if the driver is supported.</returns>
        public static bool IsSupport(IIO io, Config config, string uri, bool deep = false)
        {
            if (Regex.IsMatch(uri, @"(^git://|\.git/?$|git(?:olite)?@|//git\.|//github\.com/|//gitlib\.com/)", RegexOptions.IgnoreCase))
            {
                return(true);
            }

            bool ProcessCheck(string command, string cwd)
            {
                var process = new BucketProcessExecutor(io);

                return(process.Execute(command, cwd) == 0);
            }

            if (FileSystemLocal.IsLocalPath(uri))
            {
                uri = FileSystemLocal.GetPlatformPath(uri);
                if (!Directory.Exists(uri))
                {
                    return(false);
                }

                return(ProcessCheck("git tag", uri));
            }

            if (!deep)
            {
                return(false);
            }

            return(ProcessCheck($"git ls-remote --heads {ProcessExecutor.Escape(uri)}", null));
        }
        public void TestExecuteCapturesErrorOutput()
        {
            var process = new BucketProcessExecutor();

            process.Execute("unknow foo", out _, out string stderr);

            StringAssert.Contains(stderr, "unknow");
        }
        public void TestDoesntHidePorts()
        {
            var tester  = new TesterIOConsole();
            var process = new BucketProcessExecutor(tester.Mock(AbstractTester.OptionVerbosity(OutputOptions.VerbosityDebug)));

            process.Execute("echo https://localhost:1234/");

            StringAssert.Contains(tester.GetDisplay(), "Executing command (CWD): echo https://localhost:1234/");
        }
        public void TestHidenSensitive()
        {
            var tester  = new TesterIOConsole();
            var process = new BucketProcessExecutor(tester.Mock(AbstractTester.OptionVerbosity(OutputOptions.VerbosityDebug)));

            process.Execute("echo https://foo:[email protected]/ && echo http://[email protected] && echo http://abcdef1234567890234578:[email protected]/", out string stdout);

            StringAssert.Contains(tester.GetDisplay(), "Executing command (CWD): echo https://foo:***@example.org/ && echo http://[email protected] && echo http://***:***@github.com/");
        }
Пример #5
0
        public void TestExecuteWithStdout()
        {
            var process = new BucketProcessExecutor();

            process.Execute("echo foo && echo bar", out string stdout);

            StringAssert.Contains(stdout, "foo");
            StringAssert.Contains(stdout, "bar");
        }
Пример #6
0
        public void TestExecuteWithStdoutArray()
        {
            var process = new BucketProcessExecutor();

            process.Execute("echo foo && echo bar", out string[] stdout);

            Assert.AreEqual("foo", stdout[0].Trim());
            Assert.AreEqual("bar", stdout[1].Trim());
        }
Пример #7
0
        public void TestExecuteWithStdoutStderr()
        {
            var process = new BucketProcessExecutor();

            process.Execute("echo foo", out string stdout, out string stderr);

            Assert.AreEqual("foo", stdout.Trim());
            Assert.AreEqual(string.Empty, stderr);
        }
Пример #8
0
        private System.Exception CreateException(string message, string uri)
        {
            if (process.Execute("git --version", out _, out string stderr) != 0)
            {
                return(new RuntimeException(BucketProcessExecutor.FilterSensitive($"Failed to clone {uri}, git was not found, check that it is installed and in your PATH env.{Environment.NewLine}{Environment.NewLine}{stderr}")));
            }

            return(new RuntimeException(BucketProcessExecutor.FilterSensitive(message)));
        }
        public void TestExecuteCapturesOutput()
        {
            var process = new BucketProcessExecutor();

            process.Execute("echo foo", out string stdout);

            Assert.AreEqual(
                @"foo
", stdout);
        }
Пример #10
0
        public void TestDefaultTimeout()
        {
            var process        = new BucketProcessExecutor();
            var processDefault = new BucketProcessExecutor
            {
                Timeout = 1,
            };

            Assert.AreEqual(Timeout.Infinite, process.Timeout);
            Assert.AreEqual(1, processDefault.Timeout);

            BucketProcessExecutor.SetDefaultTimeout(999);

            Assert.AreEqual(999, process.Timeout);
            Assert.AreEqual(1, processDefault.Timeout);

            Assert.AreEqual(999, BucketProcessExecutor.GetDefaultTimeout());
        }
Пример #11
0
        /// <inheritdoc />
        protected override int Execute(IInput input, IOutput output)
        {
            if (input.GetOption("list"))
            {
                return(ListScripts(output));
            }

            string script = input.GetArgument("script");

            if (string.IsNullOrEmpty(script))
            {
                throw new RuntimeException("Missing required argument \"script\"");
            }

            var defiendEvents  = new HashSet <string>(ScriptEvents.GetEvents());
            var disabledScript = script.ToUpper().Replace("-", "_");

            if (!defiendEvents.Contains(script) && defiendEvents.Contains(disabledScript))
            {
                throw new RuntimeException($"Script \"{script}\" cannot be run with this command");
            }

            var bucket          = GetBucket();
            var devMode         = input.GetOption("dev") || !input.GetOption("no-dev");
            var eventDispatcher = bucket.GetEventDispatcher();

            if (!eventDispatcher.HasListener(script))
            {
                throw new RuntimeException($"Script \"{script}\" is not defined in this package");
            }

            string[] args    = input.GetArgument("args");
            string   timeout = input.GetOption("timeout");

            if (timeout != null)
            {
                BucketProcessExecutor.SetDefaultTimeout(int.Parse(timeout));
            }

            var eventArgs = new ScriptEventArgs(script, bucket, GetIO(), devMode, args);

            eventDispatcher.Dispatch(this, eventArgs);
            return(eventArgs.ExitCode);
        }
Пример #12
0
        /// <summary>
        /// Create a new <see cref="DownloadManager"/> instance.
        /// </summary>
        /// <param name="io">The input/output instance.</param>
        /// <param name="config">The config instance.</param>
        /// <param name="transport">The transport instance.</param>
        /// <param name="eventDispatcher">The event dispatcher instance.</param>
        public static DownloadManager CreateManager(IIO io, Config config, ITransport transport = null, IEventDispatcher eventDispatcher = null)
        {
            var manager = new DownloadManager(io);

            InstallationSource GetInstallationSource(string prefer)
            {
                switch (prefer ?? "auto")
                {
                case "dist":
                    return(InstallationSource.Dist);

                case "source":
                    return(InstallationSource.Source);

                case "auto":
                default:
                    return(InstallationSource.Auto);
                }
            }

            try
            {
                var prefer = GetInstallationSource(config.Get(Settings.PreferredInstall));
                switch (prefer)
                {
                case InstallationSource.Dist:
                    manager.SetPreferDist();
                    break;

                case InstallationSource.Source:
                    manager.SetPreferSource();
                    break;

                default:
                    break;
                }
            }
            catch (ConfigException)
            {
                // Maybe the developer is using fine configuration.
                var preferred = config.Get <ConfigPreferred>(Settings.PreferredInstall);
                manager.SetPreferences(Arr.Map(preferred, (item) => (item.Key, GetInstallationSource(item.Value))));
            }

            transport = transport ?? new TransportHttp(io, config);
            var process    = new BucketProcessExecutor(io);
            var fileSystem = new FileSystemLocal(process: process);

            ICache cache = null;

            if (config.Get(Settings.CacheFilesTTL) > 0)
            {
                cache = new CacheFileSystem(config.Get(Settings.CacheFilesDir), io, "a-z0-9_./", fileSystem);
            }

            manager.SetDownloader("git", new DownloaderGit(io, config, process, fileSystem));
            manager.SetDownloader("zip", new DownloaderZip(io, config, transport, eventDispatcher, cache, fileSystem, process));
            manager.SetDownloader("file", new DownloaderFile(io, config, transport, eventDispatcher, cache, fileSystem));

            return(manager);
        }
Пример #13
0
        /// <summary>
        /// Updates the given path to the given commit ref.
        /// </summary>
        /// <param name="cwd">The given path.</param>
        /// <param name="reference">Checkout to specified reference(commit ref, tag, branch).</param>
        /// <param name="branch">The name of the branch to use when checking out.</param>
        /// <returns>If a string is returned, it is the commit reference that was checked out if the original could not be found.</returns>
        protected virtual string UpdateToCommit(string cwd, string reference, string branch, DateTime?releaseDate)
        {
            Process.Execute("git branch -r", out string branches, cwd);

            bool IsGitHash(string hash)
            {
                return(Regex.IsMatch(hash, "^[a-f0-9]{40}$"));
            }

            bool IsBranchesHasRemote(string remote)
            {
                return(Regex.IsMatch(branches, $"^\\s+bucket/{Regex.Escape(remote)}\r?$", RegexOptions.Multiline));
            }

            string command;
            var    force = hasDiscardedChanges || hasStashedChanges ? "-f " : string.Empty;

            branch = Regex.Replace(branch ?? string.Empty, @"(?:^dev-|(?:\.x)?-dev$)", string.Empty, RegexOptions.IgnoreCase);

            // check whether non-commitish are branches or tags, and fetch branches
            // with the remote name. Use branch(in the context may be the version)
            // as the new branch name.
            if (!IsGitHash(reference) &&
                !string.IsNullOrEmpty(branches) &&
                IsBranchesHasRemote(reference))
            {
                var escapedBranch    = ProcessExecutor.Escape(branch);
                var escapedReference = ProcessExecutor.Escape($"bucket/{reference}");
                command = $"git checkout {force}-B {escapedBranch} {escapedReference} -- && git reset --hard {escapedReference} --";
                if (Process.Execute(command, cwd) == 0)
                {
                    return(null);
                }
            }

            // try to checkout branch by name and then reset it so it's on the proper branch name.
            if (IsGitHash(reference))
            {
                // add 'v' in front of the branch if it was stripped when generating the pretty name.
                if (!IsBranchesHasRemote(branch) && IsBranchesHasRemote($"v{branch}"))
                {
                    branch = $"v{branch}";
                }

                var escapedBranch = ProcessExecutor.Escape(branch);
                command = $"git checkout {escapedBranch} --";
                var fallbackCommand = $"git checkout {force}-B {escapedBranch} {ProcessExecutor.Escape($"bucket/{branch}")} --";
                if (Process.Execute(command, cwd) == 0 || Process.Execute(fallbackCommand, cwd) == 0)
                {
                    command = $"git reset --hard {ProcessExecutor.Escape(reference)} --";
                    if (Process.Execute(command, cwd) == 0)
                    {
                        return(null);
                    }
                }
            }

            // This uses the "--" sequence to separate branch from file parameters.
            //
            // Otherwise git tries the branch name as well as file name.
            // If the non-existent branch is actually the name of a file, the file
            // is checked out.
            var escapedGitReference = ProcessExecutor.Escape(reference);

            command = $"git checkout {force}{escapedGitReference} -- && git reset --hard {escapedGitReference} --";
            if (Process.Execute(command, out _, out string stderr, cwd) == 0)
            {
                return(null);
            }

            // reference was not found (prints "fatal: reference is not a tree: $ref").
            if (stderr.Contains(reference))
            {
                IO.WriteError($"    <warning>{reference} is gone (history was rewritten?)</warning>");
            }

            stderr = BucketProcessExecutor.FilterSensitive($"Failed to execute \"{command}\" {Environment.NewLine}{Environment.NewLine}{stderr}");
            throw new RuntimeException(stderr);
        }