diff --git a/Octokit.Tests.Integration/Helpers/ReferenceExtensionsTests.cs b/Octokit.Tests.Integration/Helpers/ReferenceExtensionsTests.cs new file mode 100644 index 00000000..6a47e8bb --- /dev/null +++ b/Octokit.Tests.Integration/Helpers/ReferenceExtensionsTests.cs @@ -0,0 +1,32 @@ +using Octokit.Helpers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Integration.Helpers +{ + public class ReferenceExtensionsTests + { + [IntegrationTest] + public async Task CreateABranch() + { + var client = Helper.GetAuthenticatedClient(); + var fixture = client.Git.Reference; + + using (var context = await client.CreateRepositoryContext("public-repo")) + { + var branchFromMaster = await fixture.CreateBranch(context.RepositoryOwner, context.RepositoryName, "patch-1"); + + var branchFromPath = await fixture.CreateBranch(context.RepositoryOwner, context.RepositoryName, "patch-2", branchFromMaster); + + var allBranchNames = (await client.Repository.GetAllBranches(context.RepositoryOwner, context.RepositoryName)).Select(b => b.Name); + + Assert.Contains("patch-1", allBranchNames); + Assert.Contains("patch-2", allBranchNames); + } + } + } +} diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj index c5d863e8..d12eff12 100644 --- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj +++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj @@ -118,6 +118,7 @@ + diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index 618c591b..e74cc97b 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -376,6 +376,47 @@ namespace Octokit.Tests.Clients Arg.Is>(d => d["type"] == "member" && d["sort"] == "updated" && d["direction"] == "asc")); } + + [Fact] + public void CanFilterByVisibility() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + + var request = new RepositoryRequest + { + Visibility = RepositoryVisibility.Private + }; + client.GetAllForCurrent(request); + + connection.Received() + .GetAll( + Arg.Is(u => u.ToString() == "user/repos"), + Arg.Is>(d => + d["visibility"] == "private")); + } + + [Fact] + public void CanFilterByAffiliation() + { + var connection = Substitute.For(); + var client = new RepositoriesClient(connection); + + var request = new RepositoryRequest + { + + Affiliation = RepositoryAffiliation.Owner, + Sort = RepositorySort.FullName + }; + + client.GetAllForCurrent(request); + + connection.Received() + .GetAll( + Arg.Is(u => u.ToString() == "user/repos"), + Arg.Is>(d => + d["affiliation"] == "owner" && d["sort"] == "full_name")); + } } public class TheGetAllForUserMethod diff --git a/Octokit.Tests/Clients/RepositoryContentsClientTests.cs b/Octokit.Tests/Clients/RepositoryContentsClientTests.cs index 85707ee9..0e59b533 100644 --- a/Octokit.Tests/Clients/RepositoryContentsClientTests.cs +++ b/Octokit.Tests/Clients/RepositoryContentsClientTests.cs @@ -219,5 +219,22 @@ namespace Octokit.Tests.Clients await Assert.ThrowsAsync(() => client.UpdateFile("org", "repo", "path/to/file", null)); } } + + public class TheGetArchiveMethod + { + [Fact] + public void EnsurePassingCorrectParameters() + { + var connection = Substitute.For(); + var client = new RepositoryContentsClient(connection); + + client.GetArchive("org", "repo", ArchiveFormat.Tarball, "dev"); + + const string expectedUri = "repos/org/repo/tarball/dev"; + var expectedTimeSpan = TimeSpan.FromMinutes(60); + + connection.Connection.Received().Get(Arg.Is(uri => uri.ToString() == expectedUri), Arg.Is(span => span == expectedTimeSpan)); + } + } } } \ No newline at end of file diff --git a/Octokit/Clients/RepositoryContentsClient.cs b/Octokit/Clients/RepositoryContentsClient.cs index d7770db4..7f3081c2 100644 --- a/Octokit/Clients/RepositoryContentsClient.cs +++ b/Octokit/Clients/RepositoryContentsClient.cs @@ -238,7 +238,7 @@ namespace Octokit /// The binary contents of the archive public Task GetArchive(string owner, string name, ArchiveFormat archiveFormat, string reference) { - return GetArchive(owner, name, archiveFormat, string.Empty, TimeSpan.FromMinutes(60)); + return GetArchive(owner, name, archiveFormat, reference, TimeSpan.FromMinutes(60)); } /// diff --git a/Octokit/Helpers/ReferenceExtensions.cs b/Octokit/Helpers/ReferenceExtensions.cs new file mode 100644 index 00000000..93bd4f70 --- /dev/null +++ b/Octokit/Helpers/ReferenceExtensions.cs @@ -0,0 +1,57 @@ +using System; +using System.Globalization; +using System.Threading.Tasks; + +namespace Octokit.Helpers +{ + /// + /// Represents operations to simplify working with references + /// + public static class ReferenceExtensions + { + /// + /// Creates a branch, based off the branch specified. + /// + /// The this method extends + /// The owner of the repository. + /// The name of the repository. + /// The new branch name + /// The to base the branch from + public static async Task CreateBranch(this IReferencesClient referencesClient, string owner, string name, string branchName, Reference baseReference) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNullOrEmptyString(branchName, "branchName"); + Ensure.ArgumentNotNull(baseReference, "baseReference"); + + if (branchName.StartsWith("refs/heads")) + { + throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName"); + } + + return await referencesClient.Create(owner, name, new NewReference("refs/heads/" + branchName, baseReference.Object.Sha)); + } + + /// + /// Creates a branch, based off the master branch. + /// + /// The this method extends + /// The owner of the repository. + /// The name of the repository. + /// The new branch name + public static async Task CreateBranch(this IReferencesClient referencesClient, string owner, string name, string branchName) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNullOrEmptyString(branchName, "branchName"); + + if (branchName.StartsWith("refs/heads")) + { + throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The specified branch name '{0}' appears to be a ref name and not a branch name because it starts with the string 'refs/heads'. Either specify just the branch name or use the Create method if you need to specify the full ref name", branchName), "branchName"); + } + + var baseBranch = await referencesClient.Get(owner, name, "heads/master"); + return await referencesClient.Create(owner, name, new NewReference("refs/heads/" + branchName, baseBranch.Object.Sha)); + } + } +} diff --git a/Octokit/Helpers/UriExtensions.cs b/Octokit/Helpers/UriExtensions.cs index a2db9969..2ee1b873 100644 --- a/Octokit/Helpers/UriExtensions.cs +++ b/Octokit/Helpers/UriExtensions.cs @@ -10,7 +10,7 @@ namespace Octokit public static class UriExtensions { /// - /// Merge a dictionary of valeus with an existing + /// Merge a dictionary of values with an existing /// /// Original request Uri /// Collection of key-value pairs diff --git a/Octokit/Models/Request/RepositoryRequest.cs b/Octokit/Models/Request/RepositoryRequest.cs index f22b881f..1f5d2e89 100644 --- a/Octokit/Models/Request/RepositoryRequest.cs +++ b/Octokit/Models/Request/RepositoryRequest.cs @@ -37,6 +37,22 @@ namespace Octokit /// public SortDirection Direction { get; set; } + /// + /// Gets or sets the visibility property. + /// + /// + /// The visibility. + /// + public RepositoryVisibility Visibility { get; set; } + + /// + /// Gets or sets the affiliation property. + /// + /// + /// The affiliation. + /// + public RepositoryAffiliation Affiliation { get; set; } + internal string DebuggerDisplay { get @@ -103,4 +119,72 @@ namespace Octokit [Parameter(Value = "full_name")] FullName } + + /// + /// The properties that repositories can be visible by. + /// + public enum RepositoryVisibility + { + /// + /// Returns only public repositories + /// + Public, + + /// + /// Returns only private repositories + /// + Private, + + /// + /// Return both public and private repositories + /// + All, + } + + /// + /// The properties that repositories can be affiliated by. + /// + public enum RepositoryAffiliation + { + /// + /// Repositories that are owned by the authenticated user + /// + Owner, + + /// + /// Repositories that the user has been added to as a collaborator. + /// + Collaborator, + + /// + /// Repositories that the user has access to through being a member of an organization. + /// This includes every repository on every team that the user is on. + /// + [Parameter(Value = "organization_member")] + OrganizationMember, + + /// + /// Return repositories that are owned by authenticated user and added to as a collaborator. + /// + [Parameter(Value = "owner, collaborator")] + OwnerAndCollaborator, + + /// + /// Return repositories that are owned by authenticated user or user is a organization member. + /// + [Parameter(Value = "owner, organization_member")] + OwnerAndOrganizationMember, + + /// + /// Return repositories that user has been added as collaborator or user is a organization member. + /// + [Parameter(Value = "collaborator, organization_member")] + CollaboratorAndOrganizationMember, + + /// + /// Returns all repositories where user is owner,collaborator or organization member. + /// + [Parameter(Value = "owner, collaborator, organization_member")] + All + } } diff --git a/Octokit/Octokit-Mono.csproj b/Octokit/Octokit-Mono.csproj index 34776289..674e22ac 100644 --- a/Octokit/Octokit-Mono.csproj +++ b/Octokit/Octokit-Mono.csproj @@ -437,6 +437,7 @@ + diff --git a/Octokit/Octokit-MonoAndroid.csproj b/Octokit/Octokit-MonoAndroid.csproj index f57c2adf..15d146fc 100644 --- a/Octokit/Octokit-MonoAndroid.csproj +++ b/Octokit/Octokit-MonoAndroid.csproj @@ -450,6 +450,7 @@ + diff --git a/Octokit/Octokit-Monotouch.csproj b/Octokit/Octokit-Monotouch.csproj index fab21afa..98e4beee 100644 --- a/Octokit/Octokit-Monotouch.csproj +++ b/Octokit/Octokit-Monotouch.csproj @@ -446,6 +446,7 @@ + diff --git a/Octokit/Octokit-Portable.csproj b/Octokit/Octokit-Portable.csproj index 93d40338..eedca311 100644 --- a/Octokit/Octokit-Portable.csproj +++ b/Octokit/Octokit-Portable.csproj @@ -434,6 +434,7 @@ + diff --git a/Octokit/Octokit-netcore45.csproj b/Octokit/Octokit-netcore45.csproj index 00a65ff9..8478f6f5 100644 --- a/Octokit/Octokit-netcore45.csproj +++ b/Octokit/Octokit-netcore45.csproj @@ -441,6 +441,7 @@ + diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index 7616a418..45a35727 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -105,6 +105,7 @@ +