/// <summary> /// Subtract content from the right folder. /// </summary> /// <param name="left">The left content.</param> /// <param name="right">The right content.</param> /// <returns>Returns new directory contents.</returns> public static DirectoryContents Subtract(DirectoryContents left, DirectoryContents right) { return(new DirectoryContents { files = Arr.Difference(left.files, right.files), directories = Arr.Difference(left.directories, right.directories), }); }
public void TestDifference() { var data = new[] { "a", "b", "c", "d", "e" }; var result = Arr.Difference(data, new[] { "e", "d" }); Assert.AreEqual(3, result.Length); Assert.AreEqual("a", result[0]); Assert.AreEqual("b", result[1]); Assert.AreEqual("c", result[2]); }
public void TestDifferenceEmptyMatch() { var actual = Arr.Difference(foobar, null); CollectionAssert.AreEqual( new[] { "foo", "bar", "baz", }, actual); }
public void TestDifferenceEmptyMatch() { var data = new[] { "a", "b", "c", "d", "e" }; var result = Arr.Difference(data, null); Assert.AreEqual(5, result.Length); Assert.AreEqual("a", result[0]); Assert.AreEqual("b", result[1]); Assert.AreEqual("c", result[2]); Assert.AreEqual("d", result[3]); Assert.AreEqual("e", result[4]); }
/// <inheritdoc cref="GetRemoteContent(string, bool)"/> /// <param name="fetchingRepoData">Whether is fetching the main repository data.</param> protected (string Content, HttpHeaders Headers) GetRemoteContent(string uri, bool fetchingRepoData = false) { try { return(base.GetRemoteContent(uri)); } catch (TransportException ex) { var github = new Github(IO, Config, Process, GetTransport()); switch (ex.HttpStatusCode) { case HttpStatusCode.Unauthorized: case HttpStatusCode.NotFound: if (!fetchingRepoData) { throw; } if (github.AuthorizeOAuth(host)) { return(base.GetRemoteContent(uri)); } if (!IO.IsInteractive && AttemptCloneFallback()) { return(null, null); } var scopesIssued = Array.Empty <string>(); var scopesNeeded = Array.Empty <string>(); var headers = ex.GetHeaders(); if (headers != null) { if (headers.TryGetValues("X-OAuth-Scopes", out IEnumerable <string> values)) { var scopes = string.Join(string.Empty, values); scopesIssued = scopes.Split(' '); } if (headers.TryGetValues("X-Accepted-OAuth-Scopes", out values)) { var scopes = string.Join(string.Empty, values); scopesNeeded = scopes.Split(' '); } } var scopesFailed = Arr.Difference(scopesIssued, scopesNeeded); // non-authenticated requests get no scopesNeeded, so ask // for credentials authenticated requests which failed some // scopes should ask for new credentials too if (headers == null || scopesNeeded.Length == 0 || scopesFailed.Length > 0) { github.AuthorizeOAuthInteractively(host, $"Your GitHub credentials are required to fetch private repository metadata (<info>{uri}</info>)"); } return(base.GetRemoteContent(uri)); case HttpStatusCode.Forbidden: if (!IO.HasAuthentication(host) && github.AuthorizeOAuth(host)) { return(base.GetRemoteContent(uri)); } if (!IO.IsInteractive && fetchingRepoData && AttemptCloneFallback()) { return(null, null); } var isRateLimited = github.IsRateLimit(ex.GetHeaders()); if (!IO.HasAuthentication(host)) { if (!IO.IsInteractive) { IO.WriteError($"<error>GitHub API limit exhausted. Failed to get metadata for the {uri} repository, try running in interactive mode so that you can enter your GitHub credentials to increase the API limit</error>"); throw; } github.AuthorizeOAuthInteractively(host, $"API limit exhausted. Enter your GitHub credentials to get a larger API limit (<info>{uri}</info>)"); return(base.GetRemoteContent(uri)); } if (isRateLimited) { var(limit, reset) = github.GetRateLimit(ex.GetHeaders()); IO.WriteError($"<error>GitHub API limit ({limit} calls/hr) is exhausted. You are already authorized so you have to wait until {reset} before doing more requests</error>"); } throw; default: throw; } } }