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,11 +33,10 @@ module Files
33 return error("Your changes could not be commited, because file with such name exists") 33 return error("Your changes could not be commited, because file with such name exists")
34 end 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 created_successfully = new_file_action.commit!( 37 created_successfully = new_file_action.commit!(
38 params[:content], 38 params[:content],
39 - params[:commit_message],  
40 - file_name, 39 + params[:commit_message]
41 ) 40 )
42 41
43 if created_successfully 42 if created_successfully
app/contexts/files/update_context.rb
@@ -24,8 +24,7 @@ module Files @@ -24,8 +24,7 @@ module Files
24 new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) 24 new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
25 created_successfully = new_file_action.commit!( 25 created_successfully = new_file_action.commit!(
26 params[:content], 26 params[:content],
27 - params[:commit_message],  
28 - params[:last_commit] 27 + params[:commit_message]
29 ) 28 )
30 29
31 if created_successfully 30 if created_successfully
doc/api/repositories.md
@@ -384,3 +384,16 @@ Parameters: @@ -384,3 +384,16 @@ Parameters:
384 + `branch_name` (required) - The name of branch 384 + `branch_name` (required) - The name of branch
385 + `content` (required) - File content 385 + `content` (required) - File content
386 + `commit_message` (required) - Commit message 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,9 +16,10 @@ module API
16 # 16 #
17 # Example Request: 17 # Example Request:
18 # POST /projects/:id/repository/files 18 # POST /projects/:id/repository/files
  19 + #
19 post ":id/repository/files" do 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 branch_name = attrs.delete(:branch_name) 23 branch_name = attrs.delete(:branch_name)
23 file_path = attrs.delete(:file_path) 24 file_path = attrs.delete(:file_path)
24 result = ::Files::CreateContext.new(user_project, current_user, attrs, branch_name, file_path).execute 25 result = ::Files::CreateContext.new(user_project, current_user, attrs, branch_name, file_path).execute
@@ -35,6 +36,37 @@ module API @@ -35,6 +36,37 @@ module API
35 render_api_error!(result[:error], 400) 36 render_api_error!(result[:error], 400)
36 end 37 end
37 end 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 end 70 end
39 end 71 end
40 end 72 end
lib/gitlab/satellite/files/edit_file_action.rb
@@ -10,9 +10,7 @@ module Gitlab @@ -10,9 +10,7 @@ module Gitlab
10 # Returns false if committing the change fails 10 # Returns false if committing the change fails
11 # Returns false if pushing from the satellite to Gitolite failed or was rejected 11 # Returns false if pushing from the satellite to Gitolite failed or was rejected
12 # Returns true otherwise 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 in_locked_and_timed_satellite do |repo| 14 in_locked_and_timed_satellite do |repo|
17 prepare_satellite!(repo) 15 prepare_satellite!(repo)
18 16
lib/gitlab/satellite/files/file_action.rb
@@ -8,13 +8,6 @@ module Gitlab @@ -8,13 +8,6 @@ module Gitlab
8 @file_path = file_path 8 @file_path = file_path
9 @ref = ref 9 @ref = ref
10 end 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 end 11 end
19 end 12 end
20 end 13 end
lib/gitlab/satellite/files/new_file_action.rb
@@ -9,7 +9,7 @@ module Gitlab @@ -9,7 +9,7 @@ module Gitlab
9 # Returns false if committing the change fails 9 # Returns false if committing the change fails
10 # Returns false if pushing from the satellite to Gitolite failed or was rejected 10 # Returns false if pushing from the satellite to Gitolite failed or was rejected
11 # Returns true otherwise 11 # Returns true otherwise
12 - def commit!(content, commit_message, file_name) 12 + def commit!(content, commit_message)
13 in_locked_and_timed_satellite do |repo| 13 in_locked_and_timed_satellite do |repo|
14 prepare_satellite!(repo) 14 prepare_satellite!(repo)
15 15
@@ -17,7 +17,7 @@ module Gitlab @@ -17,7 +17,7 @@ module Gitlab
17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") 17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
18 18
19 # update the file in the satellite's working dir 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 File.open(file_path_in_satellite, 'w') { |f| f.write(content) } 21 File.open(file_path_in_satellite, 'w') { |f| f.write(content) }
22 22
23 # add new file 23 # add new file
spec/requests/api/files_spec.rb
@@ -10,6 +10,15 @@ describe API::API do @@ -10,6 +10,15 @@ describe API::API do
10 before { project.team << [user, :developer] } 10 before { project.team << [user, :developer] }
11 11
12 describe "POST /projects/:id/repository/files" do 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 it "should create a new file in project repo" do 22 it "should create a new file in project repo" do
14 Gitlab::Satellite::NewFileAction.any_instance.stub( 23 Gitlab::Satellite::NewFileAction.any_instance.stub(
15 commit!: true, 24 commit!: true,
@@ -35,12 +44,38 @@ describe API::API do @@ -35,12 +44,38 @@ describe API::API do
35 end 44 end
36 end 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 end 80 end
46 end 81 end