/// <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/"); }
public void TestExecuteWithStdout() { var process = new BucketProcessExecutor(); process.Execute("echo foo && echo bar", out string stdout); StringAssert.Contains(stdout, "foo"); StringAssert.Contains(stdout, "bar"); }
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()); }
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); }
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); }
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()); }
/// <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); }
/// <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); }
/// <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); }