diff --git a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs
index bbe9ca16b2..2843a46cb4 100644
--- a/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs
+++ b/Octokit.Reactive/Clients/IObservableRepositoriesClient.cs
@@ -38,6 +38,29 @@ public interface IObservableRepositoriesClient
/// An for the operation
IObservable Delete(long repositoryId);
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The current owner of the repository
+ /// The name of the repository
+ /// Repository transfer information
+ /// A
+ IObservable Transfer(string owner, string name, RepositoryTransfer repositoryTransfer);
+
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The id of the repository
+ /// Repository transfer information
+ /// A
+ IObservable Transfer(long repositoryId, RepositoryTransfer repositoryTransfer);
+
///
/// Retrieves the for the specified owner and name.
///
diff --git a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs
index e12e92dce1..2b0061d8e0 100644
--- a/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs
+++ b/Octokit.Reactive/Clients/ObservableRepositoriesClient.cs
@@ -95,6 +95,41 @@ public IObservable Delete(long repositoryId)
{
return _client.Delete(repositoryId).ToObservable();
}
+
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The current owner of the repository
+ /// The name of the repository
+ /// Repository transfer information
+ /// A
+ public IObservable Transfer(string owner, string name, RepositoryTransfer repositoryTransfer)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(repositoryTransfer, nameof(repositoryTransfer));
+
+ return _client.Transfer(owner, name, repositoryTransfer).ToObservable();
+ }
+
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The id of the repository
+ /// Repository transfer information
+ /// A
+ public IObservable Transfer(long repositoryId, RepositoryTransfer repositoryTransfer)
+ {
+ Ensure.ArgumentNotNull(repositoryTransfer, nameof(repositoryTransfer));
+
+ return _client.Transfer(repositoryId, repositoryTransfer).ToObservable();
+ }
///
/// Retrieves the for the specified owner and name.
diff --git a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs
index baa6c39c4e..4784be35b8 100644
--- a/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs
+++ b/Octokit.Tests.Integration/Clients/RepositoriesClientTests.cs
@@ -1681,4 +1681,126 @@ public async Task ReturnsLicenseContentWithRepositoryId()
Assert.Equal("MIT License", license.License.Name);
}
}
+
+ public class TheTransferMethod
+ {
+ [IntegrationTest]
+ public async Task TransfersFromOrgToUser()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.UserName;
+ using (var context = await github.CreateRepositoryContext(Helper.Organization, newRepo))
+ {
+ var transfer = new RepositoryTransfer(newOwner);
+ await github.Repository.Transfer(context.RepositoryOwner, context.RepositoryName, transfer);
+ var transferred = await github.Repository.Get(newOwner, context.RepositoryName);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ }
+ }
+
+ [IntegrationTest]
+ public async Task TransfersFromOrgToUserById()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.UserName;
+ using (var context = await github.CreateRepositoryContext(Helper.Organization, newRepo))
+ {
+ var transfer = new RepositoryTransfer(newOwner);
+ await github.Repository.Transfer(context.RepositoryId, transfer);
+ var transferred = await github.Repository.Get(context.RepositoryId);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ }
+ }
+
+ [IntegrationTest]
+ public async Task TransfersFromUserToOrg()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.Organization;
+ using (var context = await github.CreateRepositoryContext(newRepo))
+ {
+ var transfer = new RepositoryTransfer(newOwner);
+ await github.Repository.Transfer(context.RepositoryOwner, context.RepositoryName, transfer);
+ var transferred = await github.Repository.Get(newOwner, context.RepositoryName);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ }
+ }
+
+ [IntegrationTest]
+ public async Task TransfersFromUserToOrgById()
+ {
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.Organization;
+ using (var context = await github.CreateRepositoryContext(newRepo))
+ {
+ var transfer = new RepositoryTransfer(newOwner);
+ await github.Repository.Transfer(context.RepositoryId, transfer);
+ var transferred = await github.Repository.Get(context.RepositoryId);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ }
+ }
+
+ [IntegrationTest]
+ public async Task TransfersFromUserToOrgWithTeams()
+ {
+ // FIXME API doesn't add teams when transferring to an organization
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.Organization;
+
+ using (var repositoryContext = await github.CreateRepositoryContext(newRepo))
+ {
+ NewTeam team = new NewTeam(Helper.MakeNameWithTimestamp("transfer-team"));
+ using (var teamContext = await github.CreateTeamContext(Helper.Organization, team)) {
+ var transferTeamIds = new int[] { teamContext.TeamId };
+ var transfer = new RepositoryTransfer(newOwner, transferTeamIds);
+ await github.Repository.Transfer(
+ repositoryContext.RepositoryOwner, repositoryContext.RepositoryName, transfer);
+ var transferred = await github.Repository.Get(repositoryContext.RepositoryId);
+ var repoTeams = await github.Repository.GetAllTeams(repositoryContext.RepositoryId);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ // transferTeamIds is a subset of repoTeams
+ Assert.Empty(
+ transferTeamIds.Except(
+ repoTeams.Select(t => t.Id)));
+ }
+ }
+ }
+
+ [IntegrationTest]
+ public async Task TransfersFromUserToOrgWithTeamsById()
+ {
+ // FIXME API doesn't add teams when transferring to an organization
+ var github = Helper.GetAuthenticatedClient();
+ var newRepo = new NewRepository(Helper.MakeNameWithTimestamp("transferred-repo"));
+ var newOwner = Helper.Organization;
+
+ using (var repositoryContext = await github.CreateRepositoryContext(newRepo))
+ {
+ NewTeam team = new NewTeam(Helper.MakeNameWithTimestamp("transfer-team"));
+ using (var teamContext = await github.CreateTeamContext(Helper.Organization, team)) {
+ var transferTeamIds = new int[] { teamContext.TeamId };
+ var transfer = new RepositoryTransfer(newOwner, transferTeamIds);
+ await github.Repository.Transfer(repositoryContext.RepositoryId, transfer);
+ var transferred = await github.Repository.Get(repositoryContext.RepositoryId);
+ var repoTeams = await github.Repository.GetAllTeams(repositoryContext.RepositoryId);
+
+ Assert.Equal(newOwner, transferred.Owner.Login);
+ // transferTeamIds is a subset of repoTeams
+ Assert.Empty(
+ transferTeamIds.Except(
+ repoTeams.Select(t => t.Id)));
+ }
+ }
+ }
+ }
}
diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs
index a59156c395..2ca658c42d 100644
--- a/Octokit.Tests/Clients/RepositoriesClientTests.cs
+++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs
@@ -211,6 +211,158 @@ public async Task ThrowsRepositoryExistsExceptionForEnterpriseInstance()
}
}
+ public class TheTransferMethod
+ {
+ [Fact]
+ public async Task EnsuresNonNullArguments()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ await Assert.ThrowsAsync(
+ () => client.Transfer(null, "name", transfer));
+ await Assert.ThrowsAsync(
+ () => client.Transfer("owner", null, transfer));
+ await Assert.ThrowsAsync(
+ () => client.Transfer("owner", "name", null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonNullArgumentsById()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var transfer = new RepositoryTransfer("newOwner");
+ var repositoryId = 1;
+
+ await Assert.ThrowsAsync(
+ () => client.Transfer(repositoryId, null));
+ }
+
+ [Fact]
+ public async Task EnsuresNonEmptyArguments()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ await Assert.ThrowsAsync(
+ () => client.Transfer("", "name", transfer));
+ await Assert.ThrowsAsync(
+ () => client.Transfer("owner", "", transfer));
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+
+ await client.Transfer("owner", "name", transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Is(u => u.ToString() == "repos/owner/name/transfer"),
+ Arg.Any(),
+ Arg.Any());
+ }
+
+ [Fact]
+ public async Task RequestsCorrectUrlById()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+ var repositoryId = 1;
+
+ await client.Transfer(repositoryId, transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Is(u => u.ToString() == "repositories/1/transfer"),
+ Arg.Any(),
+ Arg.Any());
+ }
+
+ [Fact]
+ public async Task SendsCorrectRequest()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+
+ await client.Transfer("owner", "name", transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Any(),
+ Arg.Is(
+ t => t.NewOwner == "newOwner" && object.Equals(teamId, t.TeamIds)),
+ Arg.Any());
+ }
+
+ [Fact]
+ public async Task SendsCorrectRequestById()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+ var repositoryId = 1;
+
+ await client.Transfer(repositoryId, transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Any(),
+ Arg.Is(
+ t => t.NewOwner == "newOwner" && object.Equals(teamId, t.TeamIds)),
+ Arg.Any());
+ }
+
+ [Fact]
+ public async Task SendsPreviewHeader()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+
+ await client.Transfer("owner", "name", transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Any(),
+ Arg.Any(),
+ Arg.Is(
+ s => s.Contains(AcceptHeaders.RepositoryTransferPreview)));
+ }
+
+ [Fact]
+ public async Task SendsPreviewHeaderById()
+ {
+ var connection = Substitute.For();
+ var client = new RepositoriesClient(connection);
+ var teamId = new int[2] {35, 42};
+ var transfer = new RepositoryTransfer("newOwner", teamId);
+ var repositoryId = 1;
+
+ await client.Transfer(repositoryId, transfer);
+
+ connection.Received()
+ .Post(
+ Arg.Any(),
+ Arg.Any(),
+ Arg.Is(
+ s => s.Contains(AcceptHeaders.RepositoryTransferPreview)));
+ }
+ }
+
public class TheDeleteMethod
{
[Fact]
diff --git a/Octokit.Tests/Models/RepositoryTransferTest.cs b/Octokit.Tests/Models/RepositoryTransferTest.cs
new file mode 100644
index 0000000000..300923f97b
--- /dev/null
+++ b/Octokit.Tests/Models/RepositoryTransferTest.cs
@@ -0,0 +1,86 @@
+using Xunit;
+using System;
+
+namespace Octokit.Tests.Models
+{
+ public class RepositoryTransferTest
+ {
+ public static readonly string emptyName = "";
+ public static readonly string nonemptyName = "name";
+ public static readonly int[] emptyTeamId = new int[] {};
+ public static readonly int[] nonemptyTeamId = new int[] {1, 2, 3};
+
+ public class TheSingleArgumentConstructor
+ {
+ [Fact]
+ public void ChecksForEmptyName()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(emptyName);});
+ }
+
+ [Fact]
+ public void ChecksForNullName()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(null);});
+ }
+
+ [Fact]
+ public void StoresGivenName()
+ {
+ string testName = nonemptyName;
+ RepositoryTransfer repositoryTransfer = new RepositoryTransfer(testName);
+ Assert.Equal(repositoryTransfer.NewOwner, testName);
+ }
+
+ [Fact]
+ public void SetsTeamIdToNull()
+ {
+ RepositoryTransfer repositoryTransfer = new RepositoryTransfer(nonemptyName);
+ Assert.Null(repositoryTransfer.TeamIds);
+ }
+ }
+
+ public class TheFullConstructor
+ {
+ [Fact]
+ public void ChecksForEmptyName()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(emptyName, nonemptyTeamId);});
+ }
+
+ [Fact]
+ public void ChecksForNullName()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(null, nonemptyTeamId);});
+ }
+
+ [Fact]
+ public void ChecksForEmptyTeamId()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(nonemptyName, emptyTeamId);});
+ }
+
+ [Fact]
+ public void ChecksForNullTeamId()
+ {
+ Assert.Throws(() => {new RepositoryTransfer(nonemptyName, null);});
+ }
+
+ [Fact]
+ public void StoresGivenName()
+ {
+ string testName = nonemptyName;
+ RepositoryTransfer repositoryTransfer = new RepositoryTransfer(testName, nonemptyTeamId);
+ Assert.Equal(repositoryTransfer.NewOwner, testName);
+ }
+
+ [Fact]
+ public void StoresGivenTeamId()
+ {
+ int[] testTeamId = nonemptyTeamId;
+ RepositoryTransfer repositoryTransfer = new RepositoryTransfer(nonemptyName, testTeamId);
+ Assert.Equal(repositoryTransfer.TeamIds, testTeamId);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs
index 29f6b04d6e..7bbfc4e867 100644
--- a/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs
+++ b/Octokit.Tests/Reactive/ObservableRepositoriesClientTests.cs
@@ -21,6 +21,71 @@ public void EnsuresNonNullArguments()
}
}
+ public class TheTransferMethod
+ {
+ [Fact]
+ public void EnsuresNonNullArguments()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableRepositoriesClient(gitHubClient);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ Assert.Throws(
+ () => client.Transfer(null, "name", transfer));
+ Assert.Throws(
+ () => client.Transfer("owner", null, transfer));
+ Assert.Throws(
+ () => client.Transfer("owner", "name", null));
+ }
+
+ [Fact]
+ public void EnsuresNonNullArgumentsById()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableRepositoriesClient(gitHubClient);
+ var transfer = new RepositoryTransfer("newOwner");
+ var repositoryId = 1;
+
+ Assert.Throws(
+ () => client.Transfer(repositoryId, null));
+ }
+
+ [Fact]
+ public void EnsuresNonEmptyArguments()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableRepositoriesClient(gitHubClient);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ Assert.Throws(
+ () => client.Transfer("", "name", transfer));
+ Assert.Throws(
+ () => client.Transfer("owner", "", transfer));
+ }
+
+ [Fact]
+ public void CallsIntoClient()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableRepositoriesClient(gitHubClient);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ client.Transfer("owner", "name", transfer);
+ gitHubClient.Repository.Received().Transfer("owner", "name", transfer);
+ }
+
+ [Fact]
+ public void CallsIntoClientById()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableRepositoriesClient(gitHubClient);
+ var transfer = new RepositoryTransfer("newOwner");
+
+ client.Transfer(1, transfer);
+ gitHubClient.Repository.Received().Transfer(1, transfer);
+ }
+ }
+
public class TheDeleteMethod
{
[Fact]
diff --git a/Octokit/Clients/IRepositoriesClient.cs b/Octokit/Clients/IRepositoriesClient.cs
index f77f0bfb19..617b93c2fb 100644
--- a/Octokit/Clients/IRepositoriesClient.cs
+++ b/Octokit/Clients/IRepositoriesClient.cs
@@ -100,6 +100,29 @@ public interface IRepositoriesClient
/// Thrown when a general API error occurs.
Task Delete(long repositoryId);
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The current owner of the repository
+ /// The name of the repository
+ /// Repository transfer information
+ /// A
+ Task Transfer(string owner, string name, RepositoryTransfer repositoryTransfer);
+
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The id of the repository
+ /// Repository transfer information
+ /// A
+ Task Transfer(long repositoryId, RepositoryTransfer repositoryTransfer);
+
///
/// Gets the specified repository.
///
diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs
index 68565559e1..558f4828cf 100644
--- a/Octokit/Clients/RepositoriesClient.cs
+++ b/Octokit/Clients/RepositoriesClient.cs
@@ -163,6 +163,41 @@ public Task Delete(long repositoryId)
return ApiConnection.Delete(ApiUrls.Repository(repositoryId));
}
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The current owner of the repository
+ /// The name of the repository
+ /// Repository transfer information
+ /// A
+ public Task Transfer(string owner, string name, RepositoryTransfer repositoryTransfer)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
+ Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
+ Ensure.ArgumentNotNull(repositoryTransfer, nameof(repositoryTransfer));
+
+ return ApiConnection.Post(ApiUrls.RepositoryTransfer(owner, name), repositoryTransfer, AcceptHeaders.RepositoryTransferPreview);
+ }
+
+ ///
+ /// Transfers the ownership of the specified repository.
+ ///
+ ///
+ /// See the API documentation for more information.
+ ///
+ /// The id of the repository
+ /// Repository transfer information
+ /// A
+ public Task Transfer(long repositoryId, RepositoryTransfer repositoryTransfer)
+ {
+ Ensure.ArgumentNotNull(repositoryTransfer, nameof(repositoryTransfer));
+
+ return ApiConnection.Post(ApiUrls.RepositoryTransfer(repositoryId), repositoryTransfer, AcceptHeaders.RepositoryTransferPreview);
+ }
+
///
/// Updates the specified repository with the values given in
///
diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs
index c096074e44..d9bbfc424b 100644
--- a/Octokit/Helpers/AcceptHeaders.cs
+++ b/Octokit/Helpers/AcceptHeaders.cs
@@ -61,6 +61,8 @@ public static class AcceptHeaders
public const string LabelsApiPreview = "application/vnd.github.symmetra-preview+json";
+ public const string RepositoryTransferPreview = "application/vnd.github.nightshade-preview+json";
+
///
/// Combines multiple preview headers. GitHub API supports Accept header with multiple
/// values separated by comma.
diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs
index cd978d596b..6cda2e72bc 100644
--- a/Octokit/Helpers/ApiUrls.cs
+++ b/Octokit/Helpers/ApiUrls.cs
@@ -1834,6 +1834,27 @@ public static Uri RepositoryTags(string owner, string name)
return "repos/{0}/{1}/tags".FormatUri(owner, name);
}
+ ///
+ /// Returns the for a repository transfer.
+ ///
+ /// The current owner of the repository
+ /// The name of the repository
+ ///
+ public static Uri RepositoryTransfer(string owner, string name)
+ {
+ return "repos/{0}/{1}/transfer".FormatUri(owner, name);
+ }
+
+ ///
+ /// Returns the for a repository transfer.
+ ///
+ /// The id of the repository
+ ///
+ public static Uri RepositoryTransfer(long repositoryId)
+ {
+ return "repositories/{0}/transfer".FormatUri(repositoryId);
+ }
+
///
/// Returns the for repository commits.
///
diff --git a/Octokit/Helpers/Ensure.cs b/Octokit/Helpers/Ensure.cs
index e089f152fc..59a7a23b09 100644
--- a/Octokit/Helpers/Ensure.cs
+++ b/Octokit/Helpers/Ensure.cs
@@ -1,4 +1,6 @@
using System;
+using System.Linq;
+using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Octokit
@@ -47,6 +49,19 @@ public static void GreaterThanZero([ValidatedNotNull]TimeSpan value, string name
throw new ArgumentException("Timespan must be greater than zero", name);
}
+
+ ///
+ /// Checks an enumerable argument to ensure it isn't null or empty.
+ ///
+ /// The argument value to check
+ /// The name of the argument
+ public static void ArgumentNotNullOrEmptyEnumerable([ValidatedNotNull]IEnumerable value, string name)
+ {
+ ArgumentNotNull(value, name);
+ if (Enumerable.Any(value)) return;
+
+ throw new ArgumentException("List cannot be empty", name);
+ }
}
[AttributeUsage(AttributeTargets.Parameter)]
diff --git a/Octokit/Models/Request/RepositoryTransfer.cs b/Octokit/Models/Request/RepositoryTransfer.cs
new file mode 100644
index 0000000000..ce57bf6817
--- /dev/null
+++ b/Octokit/Models/Request/RepositoryTransfer.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Text;
+using System.Diagnostics;
+using System.Globalization;
+using System.Collections.Generic;
+
+namespace Octokit
+{
+ ///
+ /// Describes the transfer of a repository to a new owner.
+ ///
+ [DebuggerDisplay("{DebuggerDisplay,nq}")]
+ public class RepositoryTransfer
+ {
+ ///
+ /// Creates a new repository transfer description with no team Ids.
+ ///
+ /// The new owner of the repository after the transfer.
+ public RepositoryTransfer(string newOwner)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(newOwner, nameof(newOwner));
+
+ NewOwner = newOwner;
+ }
+
+ ///
+ /// Creates a new repository transfer description.
+ ///
+ /// The new owner of the repository after the transfer.
+ /// A list of team Ids to add to the repository after the transfer (only applies to transferring to an Organization).
+ public RepositoryTransfer(string newOwner, IReadOnlyList teamIds)
+ : this(newOwner)
+ {
+ Ensure.ArgumentNotNullOrEmptyEnumerable(teamIds, nameof(teamIds));
+
+ TeamIds = teamIds;
+ }
+
+ ///
+ /// The new owner of the repository after the transfer.
+ ///
+ public string NewOwner { get; set; }
+
+ ///
+ /// A list of team Ids to add to the repository after the transfer (only applies to transferring to an Organization).
+ ///
+ public IReadOnlyList TeamIds { get; set; }
+
+ internal string DebuggerDisplay
+ {
+ get
+ {
+ string teamIdsStr = string.Join(", ", TeamIds ?? new int[0]);
+ return string.Format(CultureInfo.InvariantCulture, "NewOwner: {0}, TeamIds: [{1}]", NewOwner, teamIdsStr);
+ }
+ }
+ }
+}
\ No newline at end of file