diff options
author | 🙈 jacopo beschi 🙉 <intrip@gmail.com> | 2018-09-21 10:30:15 +0300 |
---|---|---|
committer | Zeger-Jan van de Weg <zegerjan@gitlab.com> | 2018-09-21 10:30:15 +0300 |
commit | 6b5f1009db5becb5ee21fd7f24feb84ab122b58f (patch) | |
tree | c16e6f6b177440efdbf9af97a057910624a49fac | |
parent | a491a6a3f0d7272692e7d069259e13cb448e8a6f (diff) |
Implements CHMOD action of UserCommitFiles API
-rw-r--r-- | changelogs/unreleased/adds-chmod-execute-permissions-to-operations-service.yml | 5 | ||||
-rw-r--r-- | internal/service/operations/commit_files_test.go | 52 | ||||
-rw-r--r-- | ruby/lib/gitaly_server/operations_service.rb | 3 | ||||
-rw-r--r-- | ruby/lib/gitlab/git/index.rb | 18 | ||||
-rw-r--r-- | ruby/spec/lib/gitlab/git/index_spec.rb | 33 |
5 files changed, 102 insertions, 9 deletions
diff --git a/changelogs/unreleased/adds-chmod-execute-permissions-to-operations-service.yml b/changelogs/unreleased/adds-chmod-execute-permissions-to-operations-service.yml new file mode 100644 index 000000000..3d03ee2fe --- /dev/null +++ b/changelogs/unreleased/adds-chmod-execute-permissions-to-operations-service.yml @@ -0,0 +1,5 @@ +--- +title: Implements CHMOD action of UserCommitFiles API +merge_request: 884 +author: Jacopo Beschi @jacopo-beschi +type: added diff --git a/internal/service/operations/commit_files_test.go b/internal/service/operations/commit_files_test.go index 67a19270a..c5816e7c0 100644 --- a/internal/service/operations/commit_files_test.go +++ b/internal/service/operations/commit_files_test.go @@ -1,6 +1,7 @@ package operations_test import ( + "fmt" "io/ioutil" "os" "path" @@ -46,12 +47,13 @@ func TestSuccessfulUserCommitFilesRequest(t *testing.T) { authorName := []byte("Jane Doe") authorEmail := []byte("janedoe@gitlab.com") testCases := []struct { - desc string - repo *pb.Repository - repoPath string - branchName string - repoCreated bool - branchCreated bool + desc string + repo *pb.Repository + repoPath string + branchName string + repoCreated bool + branchCreated bool + executeFilemode bool }{ { desc: "existing repo and branch", @@ -77,6 +79,15 @@ func TestSuccessfulUserCommitFilesRequest(t *testing.T) { repoCreated: true, branchCreated: true, }, + { + desc: "create executable file", + repo: testRepo, + repoPath: testRepoPath, + branchName: "feature-executable", + repoCreated: false, + branchCreated: true, + executeFilemode: true, + }, } for _, tc := range testCases { @@ -86,6 +97,7 @@ func TestSuccessfulUserCommitFilesRequest(t *testing.T) { actionsRequest1 := createFileHeaderRequest(filePath) actionsRequest2 := actionContentRequest("My") actionsRequest3 := actionContentRequest(" content") + actionsRequest4 := chmodFileHeaderRequest(filePath, tc.executeFilemode) stream, err := client.UserCommitFiles(ctx) require.NoError(t, err) @@ -93,6 +105,7 @@ func TestSuccessfulUserCommitFilesRequest(t *testing.T) { require.NoError(t, stream.Send(actionsRequest1)) require.NoError(t, stream.Send(actionsRequest2)) require.NoError(t, stream.Send(actionsRequest3)) + require.NoError(t, stream.Send(actionsRequest4)) r, err := stream.CloseAndRecv() require.NoError(t, err) @@ -109,6 +122,13 @@ func TestSuccessfulUserCommitFilesRequest(t *testing.T) { fileContent := testhelper.MustRunCommand(t, nil, "git", "-C", tc.repoPath, "show", headCommit.GetId()+":"+filePath) require.Equal(t, "My content", string(fileContent)) + + commitInfo := testhelper.MustRunCommand(t, nil, "git", "-C", tc.repoPath, "show", headCommit.GetId()) + expectedFilemode := "100644" + if tc.executeFilemode { + expectedFilemode = "100755" + } + require.Contains(t, string(commitInfo), fmt.Sprint("new file mode ", expectedFilemode)) }) } } @@ -186,6 +206,14 @@ func TestFailedUserCommitFilesRequestDueToIndexError(t *testing.T) { indexError: "A file with this name already exists", }, { + desc: "file doesn't exists", + requests: []*pb.UserCommitFilesRequest{ + headerRequest(testRepo, user, "feature", commitFilesMessage, nil, nil), + chmodFileHeaderRequest("documents/story.txt", true), + }, + indexError: "A file with this name doesn't exist", + }, + { desc: "dir already exists", requests: []*pb.UserCommitFilesRequest{ headerRequest(testRepo, user, "utf-dir", commitFilesMessage, nil, nil), @@ -301,6 +329,18 @@ func createFileHeaderRequest(filePath string) *pb.UserCommitFilesRequest { }) } +func chmodFileHeaderRequest(filePath string, executeFilemode bool) *pb.UserCommitFilesRequest { + return actionRequest(&pb.UserCommitFilesAction{ + UserCommitFilesActionPayload: &pb.UserCommitFilesAction_Header{ + Header: &pb.UserCommitFilesActionHeader{ + Action: pb.UserCommitFilesActionHeader_CHMOD, + FilePath: []byte(filePath), + ExecuteFilemode: executeFilemode, + }, + }, + }) +} + func actionContentRequest(content string) *pb.UserCommitFilesRequest { return actionRequest(&pb.UserCommitFilesAction{ UserCommitFilesActionPayload: &pb.UserCommitFilesAction_Content{ diff --git a/ruby/lib/gitaly_server/operations_service.rb b/ruby/lib/gitaly_server/operations_service.rb index a63aaffe1..45a99031e 100644 --- a/ruby/lib/gitaly_server/operations_service.rb +++ b/ruby/lib/gitaly_server/operations_service.rb @@ -332,7 +332,8 @@ module GitalyServer file_path: set_utf8!(header.file_path), previous_path: set_utf8!(header.previous_path), encoding: header.base64_content ? 'base64' : '', - content: '' + content: '', + execute_filemode: header.execute_filemode } end diff --git a/ruby/lib/gitlab/git/index.rb b/ruby/lib/gitlab/git/index.rb index 2d4120c8a..7f002e7f4 100644 --- a/ruby/lib/gitlab/git/index.rb +++ b/ruby/lib/gitlab/git/index.rb @@ -4,9 +4,10 @@ module Gitlab IndexError = Class.new(StandardError) DEFAULT_MODE = 0o100644 + EXECUTE_MODE = 0o100755 - ACTIONS = %w(create create_dir update move delete).freeze - ACTION_OPTIONS = %i(file_path previous_path content encoding).freeze + ACTIONS = %w(create create_dir update move delete chmod).freeze + ACTION_OPTIONS = %i(file_path previous_path content encoding execute_filemode).freeze attr_reader :repository, :raw_index @@ -96,6 +97,19 @@ module Gitlab raw_index.remove(options[:file_path]) end + def chmod(options) + options = normalize_options(options) + + file_entry = get(options[:file_path]) + unless file_entry + raise IndexError, "A file with this name doesn't exist" + end + + mode = options[:execute_filemode] ? EXECUTE_MODE : DEFAULT_MODE + + raw_index.add(path: options[:file_path], oid: file_entry[:oid], mode: mode) + end + private def normalize_options(options) diff --git a/ruby/spec/lib/gitlab/git/index_spec.rb b/ruby/spec/lib/gitlab/git/index_spec.rb index 6d4da8c6f..fc54f77da 100644 --- a/ruby/spec/lib/gitlab/git/index_spec.rb +++ b/ruby/spec/lib/gitlab/git/index_spec.rb @@ -228,6 +228,39 @@ describe Gitlab::Git::Index do end end + describe '#chmod' do + def entry + index.get(options[:file_path]) + end + + let(:options) do + { + file_path: 'README.md', + execute_filemode: true + } + end + + context 'when no file at that path exists' do + before do + options[:file_path] = 'documents/story.txt' + end + + it 'raises an error' do + expect { index.chmod(options) }.to raise_error("A file with this name doesn't exist") + end + end + + context 'when a file at that path exists' do + it 'updates the execute file mode' do + expect { index.chmod(options) }.to change { entry[:mode] }.from(0o100644).to(0o100755) + end + + it 'leaves the content unchanged' do + expect { index.chmod(options) }.not_to change { lookup(entry[:oid]).content } + end + end + end + def lookup(revision) repository.rugged.rev_parse(revision) end |