Commit a516a8469b73a7d1bc8d3ccc163fbd1e85a557a5

Authored by Dmitriy Zaporozhets
2 parents 75303241 986697a9

Merge branch 'feature/edit_file_api' of /home/git/repositories/gitlab/gitlabhq

app/contexts/files/create_context.rb
... ... @@ -33,11 +33,10 @@ module Files
33 33 return error("Your changes could not be commited, because file with such name exists")
34 34 end
35 35  
36   - new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, path)
  36 + new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path)
37 37 created_successfully = new_file_action.commit!(
38 38 params[:content],
39   - params[:commit_message],
40   - file_name,
  39 + params[:commit_message]
41 40 )
42 41  
43 42 if created_successfully
... ...
app/contexts/files/update_context.rb
... ... @@ -24,8 +24,7 @@ module Files
24 24 new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
25 25 created_successfully = new_file_action.commit!(
26 26 params[:content],
27   - params[:commit_message],
28   - params[:last_commit]
  27 + params[:commit_message]
29 28 )
30 29  
31 30 if created_successfully
... ...
doc/api/repositories.md
... ... @@ -384,3 +384,16 @@ Parameters:
384 384 + `branch_name` (required) - The name of branch
385 385 + `content` (required) - File content
386 386 + `commit_message` (required) - Commit message
  387 +
  388 +## Update existing file in repository
  389 +
  390 +```
  391 +PUT /projects/:id/repository/files
  392 +```
  393 +
  394 +Parameters:
  395 +
  396 ++ `file_path` (required) - Full path to file. Ex. lib/class.rb
  397 ++ `branch_name` (required) - The name of branch
  398 ++ `content` (required) - New file content
  399 ++ `commit_message` (required) - Commit message
... ...
lib/api/files.rb
... ... @@ -16,9 +16,10 @@ module API
16 16 #
17 17 # Example Request:
18 18 # POST /projects/:id/repository/files
  19 + #
19 20 post ":id/repository/files" do
20   - required_attributes! [:file_name, :branch_name, :content]
21   - attrs = attributes_for_keys [:file_name, :file_path, :branch_name, :content]
  21 + required_attributes! [:file_name, :branch_name, :content, :commit_message]
  22 + attrs = attributes_for_keys [:file_name, :file_path, :branch_name, :content, :commit_message]
22 23 branch_name = attrs.delete(:branch_name)
23 24 file_path = attrs.delete(:file_path)
24 25 result = ::Files::CreateContext.new(user_project, current_user, attrs, branch_name, file_path).execute
... ... @@ -35,6 +36,37 @@ module API
35 36 render_api_error!(result[:error], 400)
36 37 end
37 38 end
  39 +
  40 + # Update existing file in repository
  41 + #
  42 + # Parameters:
  43 + # file_name (required) - The name of new file. Ex. class.rb
  44 + # file_path (optional) - The path to new file. Ex. lib/
  45 + # branch_name (required) - The name of branch
  46 + # content (required) - File content
  47 + # commit_message (required) - Commit message
  48 + #
  49 + # Example Request:
  50 + # PUT /projects/:id/repository/files
  51 + #
  52 + put ":id/repository/files" do
  53 + required_attributes! [:file_path, :branch_name, :content, :commit_message]
  54 + attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message]
  55 + branch_name = attrs.delete(:branch_name)
  56 + file_path = attrs.delete(:file_path)
  57 + result = ::Files::UpdateContext.new(user_project, current_user, attrs, branch_name, file_path).execute
  58 +
  59 + if result[:status] == :success
  60 + status(200)
  61 +
  62 + {
  63 + file_path: file_path,
  64 + branch_name: branch_name
  65 + }
  66 + else
  67 + render_api_error!(result[:error], 400)
  68 + end
  69 + end
38 70 end
39 71 end
40 72 end
... ...
lib/gitlab/satellite/files/edit_file_action.rb
... ... @@ -10,9 +10,7 @@ module Gitlab
10 10 # Returns false if committing the change fails
11 11 # Returns false if pushing from the satellite to Gitolite failed or was rejected
12 12 # Returns true otherwise
13   - def commit!(content, commit_message, last_commit)
14   - return false unless can_edit?(last_commit)
15   -
  13 + def commit!(content, commit_message)
16 14 in_locked_and_timed_satellite do |repo|
17 15 prepare_satellite!(repo)
18 16  
... ...
lib/gitlab/satellite/files/file_action.rb
... ... @@ -8,13 +8,6 @@ module Gitlab
8 8 @file_path = file_path
9 9 @ref = ref
10 10 end
11   -
12   - protected
13   -
14   - def can_edit?(last_commit)
15   - current_last_commit = Gitlab::Git::Commit.last_for_path(@project.repository, ref, file_path).sha
16   - last_commit == current_last_commit
17   - end
18 11 end
19 12 end
20 13 end
... ...
lib/gitlab/satellite/files/new_file_action.rb
... ... @@ -9,7 +9,7 @@ module Gitlab
9 9 # Returns false if committing the change fails
10 10 # Returns false if pushing from the satellite to Gitolite failed or was rejected
11 11 # Returns true otherwise
12   - def commit!(content, commit_message, file_name)
  12 + def commit!(content, commit_message)
13 13 in_locked_and_timed_satellite do |repo|
14 14 prepare_satellite!(repo)
15 15  
... ... @@ -17,7 +17,7 @@ module Gitlab
17 17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
18 18  
19 19 # update the file in the satellite's working dir
20   - file_path_in_satellite = File.join(repo.working_dir, file_path || '', file_name)
  20 + file_path_in_satellite = File.join(repo.working_dir, file_path)
21 21 File.open(file_path_in_satellite, 'w') { |f| f.write(content) }
22 22  
23 23 # add new file
... ...
spec/requests/api/files_spec.rb
... ... @@ -10,6 +10,15 @@ describe API::API do
10 10 before { project.team << [user, :developer] }
11 11  
12 12 describe "POST /projects/:id/repository/files" do
  13 + let(:valid_params) {
  14 + {
  15 + file_name: 'newfile.rb',
  16 + branch_name: 'master',
  17 + content: 'puts 8',
  18 + commit_message: 'Added newfile'
  19 + }
  20 + }
  21 +
13 22 it "should create a new file in project repo" do
14 23 Gitlab::Satellite::NewFileAction.any_instance.stub(
15 24 commit!: true,
... ... @@ -35,12 +44,38 @@ describe API::API do
35 44 end
36 45 end
37 46  
38   - def valid_params
39   - {
40   - file_name: 'newfile.rb',
41   - branch_name: 'master',
42   - content: 'puts 8',
43   - commit_message: 'Added newfile'
  47 + describe "PUT /projects/:id/repository/files" do
  48 + let(:valid_params) {
  49 + {
  50 + file_path: 'spec/spec_helper.rb',
  51 + branch_name: 'master',
  52 + content: 'puts 8',
  53 + commit_message: 'Changed file'
  54 + }
44 55 }
  56 +
  57 + it "should update existing file in project repo" do
  58 + Gitlab::Satellite::EditFileAction.any_instance.stub(
  59 + commit!: true,
  60 + )
  61 +
  62 + put api("/projects/#{project.id}/repository/files", user), valid_params
  63 + response.status.should == 200
  64 + json_response['file_path'].should == 'spec/spec_helper.rb'
  65 + end
  66 +
  67 + it "should return a 400 bad request if no params given" do
  68 + put api("/projects/#{project.id}/repository/files", user)
  69 + response.status.should == 400
  70 + end
  71 +
  72 + it "should return a 400 if satellite fails to create file" do
  73 + Gitlab::Satellite::EditFileAction.any_instance.stub(
  74 + commit!: false,
  75 + )
  76 +
  77 + put api("/projects/#{project.id}/repository/files", user), valid_params
  78 + response.status.should == 400
  79 + end
45 80 end
46 81 end
... ...