diff --git a/src/GitLabApiClient/CommitsClient.cs b/src/GitLabApiClient/CommitsClient.cs index 9240ec41..c4383052 100644 --- a/src/GitLabApiClient/CommitsClient.cs +++ b/src/GitLabApiClient/CommitsClient.cs @@ -7,7 +7,6 @@ using GitLabApiClient.Internal.Paths; using GitLabApiClient.Internal.Queries; using GitLabApiClient.Models.Commits.Requests; -using GitLabApiClient.Models.Commits.Requests.CreateCommitRequest; using GitLabApiClient.Models.Commits.Responses; using GitLabApiClient.Models.Projects.Responses; diff --git a/src/GitLabApiClient/CommitsClient.cs.orig b/src/GitLabApiClient/CommitsClient.cs.orig new file mode 100644 index 00000000..f2bfdf7b --- /dev/null +++ b/src/GitLabApiClient/CommitsClient.cs.orig @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using GitLabApiClient.Internal.Http; +using GitLabApiClient.Internal.Paths; +using GitLabApiClient.Internal.Queries; +using GitLabApiClient.Models.Commits.Requests; +using GitLabApiClient.Models.Commits.Requests.CreateCommitRequest; +using GitLabApiClient.Models.Commits.Responses; +using GitLabApiClient.Models.Projects.Responses; + +namespace GitLabApiClient +{ + public sealed class CommitsClient : ICommitsClient + { + private readonly GitLabHttpFacade _httpFacade; + private readonly CommitQueryBuilder _commitQueryBuilder; + private readonly CommitRefsQueryBuilder _commitRefsQueryBuilder; + private readonly CommitStatusesQueryBuilder _commitStatusesQueryBuilder; + + internal CommitsClient(GitLabHttpFacade httpFacade, CommitQueryBuilder commitQueryBuilder, CommitRefsQueryBuilder commitRefsQueryBuilder, CommitStatusesQueryBuilder commitStatusesQueryBuilder) + { + _httpFacade = httpFacade; + _commitQueryBuilder = commitQueryBuilder; + _commitRefsQueryBuilder = commitRefsQueryBuilder; + _commitStatusesQueryBuilder = commitStatusesQueryBuilder; + } + + /// + /// Get a commit from commit sha + /// + /// The ID, path or of the project. + /// The commit hash or name of a repository branch or tag + /// + public async Task GetAsync(ProjectId projectId, string sha) => + await _httpFacade.Get($"projects/{projectId}/repository/commits/{sha}"); + + /// + /// Retrieve a list of commits from a project + /// + /// The ID, path or of the project. + /// Query Options . + /// + public async Task> GetAsync(ProjectId projectId, Action options = null) + { + var queryOptions = new CommitQueryOptions(); + options?.Invoke(queryOptions); + + string url = _commitQueryBuilder.Build($"projects/{projectId}/repository/commits", queryOptions); + return await _httpFacade.GetPagedList(url); + } + + /// + /// Retrieve a list of references (from branch or / and tag) that this commit belongs to + /// + /// The ID, path or of the project. + /// Query Options . + /// The commit hash or name of a repository branch or tag + /// + public async Task> GetRefsAsync(ProjectId projectId, string sha, Action options) + { + var queryOptions = new CommitRefsQueryOptions(); + options?.Invoke(queryOptions); + + string url = _commitRefsQueryBuilder.Build($"projects/{projectId}/repository/commits/{sha}/refs", queryOptions); + return await _httpFacade.GetPagedList(url); + } + + /// + /// Retrieve a list of differences in this commit + /// + /// The ID, path or of the project. + /// The commit hash or name of a repository branch or tag + /// + public async Task> GetDiffsAsync(ProjectId projectId, string sha) + { + string url = $"projects/{projectId}/repository/commits/{sha}/diff"; + return await _httpFacade.GetPagedList(url); + } + + /// + /// Retrieve a list of statuses in this commit + /// + /// The ID, path or of the project. + /// Query Options . + /// The commit hash + /// + public async Task> GetStatusesAsync(ProjectId projectId, string sha, Action options = null) + { + var queryOptions = new CommitStatusesQueryOptions(); + options?.Invoke(queryOptions); + + string url = _commitStatusesQueryBuilder.Build($"projects/{projectId}/repository/commits/{sha}/statuses", queryOptions); + return await _httpFacade.GetPagedList(url); + } + + /// +<<<<<<< HEAD + /// Create new commit + /// + /// The ID, path or of the project. + /// Create Commit request. + /// newly created Commit + public async Task CreateAsync(ProjectId projectId, CreateCommitRequest request) => + await _httpFacade.Post($"projects/{projectId}/repository/commits", request); +======= + /// Creates a commit with multiple files and actions. + /// + /// The ID, path or of the project. + /// Create commit request. + /// Automatically encode contents to base64 (default false). + public async Task CreateAsync(ProjectId projectId, CreateCommitRequest request, bool autoEncodeToBase64 = false) + { + if (autoEncodeToBase64) + { + foreach (var action in request.Actions.Where(action => !string.IsNullOrEmpty(action.Content))) + { + action.Encoding = CreateCommitRequestActionEncoding.Base64; + action.Content = Convert.ToBase64String(Encoding.UTF8.GetBytes(action.Content)); + } + } + return await _httpFacade.Post($"projects/{projectId}/repository/commits", request); + } +>>>>>>> master + } +} diff --git a/src/GitLabApiClient/FilesClient.cs b/src/GitLabApiClient/FilesClient.cs index 57e14f8c..048a4bd3 100644 --- a/src/GitLabApiClient/FilesClient.cs +++ b/src/GitLabApiClient/FilesClient.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using GitLabApiClient.Internal.Http; using GitLabApiClient.Internal.Paths; @@ -16,5 +17,10 @@ public async Task GetAsync(ProjectId projectId, string filePath, string re { return await _httpFacade.Get($"projects/{projectId}/repository/files/{filePath.UrlEncode()}?ref={reference}"); } + + public async Task GetRawAsync(ProjectId projectId, string filePath, string reference = "master") + { + return await _httpFacade.GetString($"projects/{projectId}/repository/files/{filePath.UrlEncode()}/raw?ref={reference}"); + } } } diff --git a/src/GitLabApiClient/ICommitsClient.cs b/src/GitLabApiClient/ICommitsClient.cs index ee8abfaa..c9651ac8 100644 --- a/src/GitLabApiClient/ICommitsClient.cs +++ b/src/GitLabApiClient/ICommitsClient.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using GitLabApiClient.Internal.Paths; using GitLabApiClient.Models.Commits.Requests; -using GitLabApiClient.Models.Commits.Requests.CreateCommitRequest; using GitLabApiClient.Models.Commits.Responses; using GitLabApiClient.Models.Projects.Responses; diff --git a/src/GitLabApiClient/ICommitsClient.cs.orig b/src/GitLabApiClient/ICommitsClient.cs.orig new file mode 100644 index 00000000..f7d4cef8 --- /dev/null +++ b/src/GitLabApiClient/ICommitsClient.cs.orig @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using GitLabApiClient.Internal.Paths; +using GitLabApiClient.Models.Commits.Requests; +using GitLabApiClient.Models.Commits.Requests.CreateCommitRequest; +using GitLabApiClient.Models.Commits.Responses; +using GitLabApiClient.Models.Projects.Responses; + +namespace GitLabApiClient +{ + public interface ICommitsClient + { + /// + /// Get a commit from commit sha + /// + /// The ID, path or of the project. + /// The commit hash or name of a repository branch or tag + /// + Task GetAsync(ProjectId projectId, string sha); + + /// + /// Retrieve a list of commits from a project + /// + /// The ID, path or of the project. + /// Query Options . + /// + Task> GetAsync(ProjectId projectId, Action options = null); + + /// + /// Retrieve a list of references (from branch or / and tag) that this commit belongs to + /// + /// The ID, path or of the project. + /// Query Options . + /// The commit hash or name of a repository branch or tag + /// + Task> GetRefsAsync(ProjectId projectId, string sha, Action options); + + /// + /// Retrieve a list of differences in this commit + /// + /// The ID, path or of the project. + /// The commit hash or name of a repository branch or tag + /// + Task> GetDiffsAsync(ProjectId projectId, string sha); + + /// + /// Retrieve a list of statuses in this commit + /// + /// The ID, path or of the project. + /// Query Options . + /// The commit hash + /// + Task> GetStatusesAsync(ProjectId projectId, string sha, Action options = null); + + /// +<<<<<<< HEAD + /// Create new commit + /// + /// The ID, path or of the project. + /// Create Commit request. + /// newly created Commit + Task CreateAsync(ProjectId projectId, CreateCommitRequest request); +======= + /// Creates a commit with multiple files and actions. + /// + /// The ID, path or of the project. + /// Create commit request. + /// Automatically encode contents to base64 (default false). + Task CreateAsync(ProjectId projectId, CreateCommitRequest request, bool autoEncodeToBase64 = false); +>>>>>>> master + } +} diff --git a/src/GitLabApiClient/IFilesClient.cs b/src/GitLabApiClient/IFilesClient.cs index f848d759..b100a8f1 100644 --- a/src/GitLabApiClient/IFilesClient.cs +++ b/src/GitLabApiClient/IFilesClient.cs @@ -7,5 +7,6 @@ namespace GitLabApiClient public interface IFilesClient { Task GetAsync(ProjectId projectId, string filePath, string reference = "master"); + Task GetRawAsync(ProjectId projectId, string filePath, string reference = "master"); } } diff --git a/src/GitLabApiClient/Internal/Http/GitLabHttpFacade.cs b/src/GitLabApiClient/Internal/Http/GitLabHttpFacade.cs index 0ca82fd2..0d2f2c39 100644 --- a/src/GitLabApiClient/Internal/Http/GitLabHttpFacade.cs +++ b/src/GitLabApiClient/Internal/Http/GitLabHttpFacade.cs @@ -68,6 +68,9 @@ public Task> GetPagedList(string uri) => public Task Get(string uri) => _requestor.Get(uri); + public Task GetString(string uri) => + _requestor.GetString(uri); + public Task GetFile(string uri, string outputPath) => _requestor.GetFile(uri, outputPath); diff --git a/src/GitLabApiClient/Internal/Http/GitlabApiRequestor.cs b/src/GitLabApiClient/Internal/Http/GitlabApiRequestor.cs index c4d6947f..6ebbf7a5 100644 --- a/src/GitLabApiClient/Internal/Http/GitlabApiRequestor.cs +++ b/src/GitLabApiClient/Internal/Http/GitlabApiRequestor.cs @@ -28,6 +28,13 @@ public async Task Get(string url) return await ReadResponse(responseMessage); } + public async Task GetString(string url) + { + var responseMessage = await _client.GetAsync(url); + await EnsureSuccessStatusCode(responseMessage); + return await responseMessage.Content.ReadAsStringAsync(); + } + public async Task GetFile(string url, string outputPath) { var response = await _client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); diff --git a/src/GitLabApiClient/Models/Commits/Requests/CreateCommitActionRequest.cs b/src/GitLabApiClient/Models/Commits/Requests/CreateCommitActionRequest.cs new file mode 100644 index 00000000..02fcfbf6 --- /dev/null +++ b/src/GitLabApiClient/Models/Commits/Requests/CreateCommitActionRequest.cs @@ -0,0 +1,68 @@ +using GitLabApiClient.Internal.Utilities; +using Newtonsoft.Json; + +namespace GitLabApiClient.Models.Commits.Requests +{ + /// + /// Used to create a commit in a project. + /// + public sealed class CreateCommitActionRequest + { + /// + /// The action to perform, create, delete, move, update, chmod. + /// + [JsonProperty("action")] + public string Action { get; set; } + + /// + /// Full path to the file. Ex. lib/class.rb. + /// + [JsonProperty("file_path")] + public string FilePath { get; set; } + + /// + /// Original full path to the file being moved. Ex. lib/class1.rb. Only considered for move action. + /// + [JsonProperty("previous_path")] + public string PreviousPath { get; set; } + + /// + /// File content, required for all except delete, chmod, and move. Move actions that do not specify content preserve the existing file content, + /// and any other value of content overwrites the file content. + /// + [JsonProperty("content")] + public string Content { get; set; } + + /// + /// text or base64. text is default. + /// + [JsonProperty("encoding")] + public string Encoding { get; set; } + + /// + /// Last known file commit ID. Only considered in update, move, and delete actions. + /// + [JsonProperty("last_commit_id")] + public string LastCommitId { get; set; } + + /// + /// When true/false enables/disables the execute flag on the file. Only considered for chmod action. + /// + [JsonProperty("execute_filemode")] + public bool ExecuteFilemode { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the branch to commit into. To create a new branch, also provide either start_branch or start_sha, and optionally start_project. + /// Commit message. + public CreateCommitActionRequest(string action, string filePath) + { + Guard.NotEmpty(action, nameof(action)); + Guard.NotEmpty(filePath, nameof(filePath)); + + Action = action; + FilePath = filePath; + } + } +} diff --git a/src/GitLabApiClient/Models/Commits/Requests/CreateCommitRequest.cs b/src/GitLabApiClient/Models/Commits/Requests/CreateCommitRequest.cs new file mode 100644 index 00000000..8071738c --- /dev/null +++ b/src/GitLabApiClient/Models/Commits/Requests/CreateCommitRequest.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using GitLabApiClient.Internal.Utilities; +using Newtonsoft.Json; + +namespace GitLabApiClient.Models.Commits.Requests +{ + /// + /// Used to create a commit in a project. + /// + public sealed class CreateCommitRequest + { + /// + /// Name of the branch to commit into. To create a new branch, also provide either start_branch or start_sha, and optionally start_project. + /// + [JsonProperty("branch")] + public string Branch { get; set; } + + /// + /// Commit message. + /// + [JsonProperty("commit_message")] + public string CommitMessage { get; set; } + + /// + /// Name of the branch to start the new branch from. + /// + [JsonProperty("start_branch")] + public string StartBranch { get; set; } + + /// + /// SHA of the commit to start the new branch from. + /// + [JsonProperty("start_sha")] + public string StartSha { get; set; } + + /// + /// The project ID or URL-encoded path of the project to start the new branch from. Defaults to the value of project id. + /// + [JsonProperty("start_project")] + public string ReleaseDescription { get; set; } + + /// + /// Specify the commit author's email address. + /// + [JsonProperty("author_email")] + public string AuthorEmail { get; set; } + + /// + /// Specify the commit author's name. + /// + [JsonProperty("author_name")] + public string AuthorName { get; set; } + + /// + /// Include commit stats. Default is true. + /// + [JsonProperty("stats")] + public bool Stats { get; set; } + + /// + /// When true overwrites the target branch with a new commit based on the start_branch or start_sha. + /// + [JsonProperty("force")] + public bool Force { get; set; } + + /// + /// A list of action hashes to commit as a batch. + /// + [JsonProperty("actions")] + public IList Actions { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the branch to commit into. To create a new branch, also provide either start_branch or start_sha, and optionally start_project. + /// Commit message. + /// A list of action hashes to commit as a batch. + public CreateCommitRequest(string branch, string commitMessage, IList actions) + { + Guard.NotEmpty(branch, nameof(branch)); + + Branch = branch; + CommitMessage = commitMessage; + Actions = actions; + Stats = true; + } + } +} diff --git a/src/GitLabApiClient/Models/MergeRequests/Requests/AcceptMergeRequest.cs b/src/GitLabApiClient/Models/MergeRequests/Requests/AcceptMergeRequest.cs index 27694931..0dcf8c0b 100644 --- a/src/GitLabApiClient/Models/MergeRequests/Requests/AcceptMergeRequest.cs +++ b/src/GitLabApiClient/Models/MergeRequests/Requests/AcceptMergeRequest.cs @@ -30,5 +30,17 @@ public sealed class AcceptMergeRequest /// [JsonProperty("sha")] public string Sha { get; set; } + + /// + /// Custom squash commit message. + /// + [JsonProperty("squash_commit_message")] + public string SquashCommitMessage { get; set; } + + /// + /// If true, the commits are squashed into a single commit on merge. + /// + [JsonProperty("squash")] + public bool? Squash { get; set; } } }