summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-02-18 12:27:02 +0200
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-02-18 12:27:02 +0200
commitddbe978041753d7851780165f8c6c66865570862 (patch)
treee063ebab3b86a4a60b2b7b7f6a3981c303c2e99b
parent87a449f264684551d0b9cdfa9ed2d32f21110adb (diff)
downloadgitlab-ce-ddbe978041753d7851780165f8c6c66865570862.tar.gz
Complete api files CRUD
Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
-rw-r--r--app/models/repository.rb12
-rw-r--r--app/views/help/_api_layout.html.haml2
-rw-r--r--doc/api/README.md1
-rw-r--r--doc/api/repositories.md41
-rw-r--r--doc/api/repository_files.md102
-rw-r--r--lib/api/files.rb53
-rw-r--r--spec/requests/api/files_spec.rb30
7 files changed, 192 insertions, 49 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 2c2bf242b94..99d908b5d81 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -180,13 +180,13 @@ class Repository
end
def blob_at_branch(branch_name, path)
- last_commit = commit(branch_name)
+ last_commit = commit(branch_name)
- if last_commit
- blob_at(last_commit.sha, path)
- else
- nil
- end
+ if last_commit
+ blob_at(last_commit.sha, path)
+ else
+ nil
+ end
end
# Returns url for submodule
diff --git a/app/views/help/_api_layout.html.haml b/app/views/help/_api_layout.html.haml
index c211b658410..9f7bc78355e 100644
--- a/app/views/help/_api_layout.html.haml
+++ b/app/views/help/_api_layout.html.haml
@@ -5,7 +5,7 @@
%i.icon-angle-left
Back to help
%ul.nav.nav-pills.nav-stacked
- - %w(README projects project_snippets repositories deploy_keys users groups session issues milestones merge_requests notes system_hooks).each do |file|
+ - %w(README projects project_snippets repositories repository_files deploy_keys users groups session issues milestones merge_requests notes system_hooks).each do |file|
%li{class: file == @category ? 'active' : nil}
= link_to file.titleize, help_api_file_path(file)
diff --git a/doc/api/README.md b/doc/api/README.md
index 517a9fae6f6..f13f319a843 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -127,6 +127,7 @@ But when you want to create a link to web page - use `http:://host/project/issu
+ [Projects](projects.md)
+ [Project Snippets](project_snippets.md)
+ [Repositories](repositories.md)
++ [Repository Files](repository_files.md)
+ [Merge Requests](merge_requests.md)
+ [Issues](issues.md)
+ [Milestones](milestones.md)
diff --git a/doc/api/repositories.md b/doc/api/repositories.md
index 01607263008..70e297f1bcb 100644
--- a/doc/api/repositories.md
+++ b/doc/api/repositories.md
@@ -388,44 +388,3 @@ GET /projects/:id/repository/archive
Parameters:
+ `id` (required) - The ID of a project
+ `sha` (optional) - The commit sha to download defaults to the tip of the default branch
-
-
-## Create new file in repository
-
-```
-POST /projects/:id/repository/files
-```
-
-Parameters:
-
-+ `file_path` (optional) - Full path to new file. Ex. lib/class.rb
-+ `branch_name` (required) - The name of branch
-+ `encoding` (optional) - 'text' or 'base64'. Text is default.
-+ `content` (required) - File content
-+ `commit_message` (required) - Commit message
-
-## Update existing file in repository
-
-```
-PUT /projects/:id/repository/files
-```
-
-Parameters:
-
-+ `file_path` (required) - Full path to file. Ex. lib/class.rb
-+ `branch_name` (required) - The name of branch
-+ `encoding` (optional) - 'text' or 'base64'. Text is default.
-+ `content` (required) - New file content
-+ `commit_message` (required) - Commit message
-
-## Delete existing file in repository
-
-```
-DELETE /projects/:id/repository/files
-```
-
-Parameters:
-
-+ `file_path` (required) - Full path to file. Ex. lib/class.rb
-+ `branch_name` (required) - The name of branch
-+ `commit_message` (required) - Commit message
diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md
new file mode 100644
index 00000000000..cafab8c828f
--- /dev/null
+++ b/doc/api/repository_files.md
@@ -0,0 +1,102 @@
+# CRUD for repository files
+
+## Create, read, update and delete repository files using this API
+
+- - -
+
+## Get file from repository
+
+Allows you to receive information about file in repository like name, size, content.
+Note that file content is Base64 encoded.
+
+```
+GET /projects/:id/repository/files
+```
+
+Example response:
+
+```json
+{
+ "file_name": "key.rb",
+ "file_path": "app/models/key.rb",
+ "size": 1476,
+ "encoding": "base64",
+ "content": "IyA9PSBTY2hlbWEgSW5mb3...",
+ "ref": "master",
+ "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
+ "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
+}
+```
+
+Parameters:
+
++ `file_path` (required) - Full path to new file. Ex. lib/class.rb
++ `ref` (required) - The name of branch, tag or commit
+
+## Create new file in repository
+
+```
+POST /projects/:id/repository/files
+```
+
+Example response:
+
+```json
+{
+ "file_name": "app/project.rb",
+ "branch_name": "master",
+}
+```
+
+Parameters:
+
++ `file_path` (required) - Full path to new file. Ex. lib/class.rb
++ `branch_name` (required) - The name of branch
++ `encoding` (optional) - 'text' or 'base64'. Text is default.
++ `content` (required) - File content
++ `commit_message` (required) - Commit message
+
+## Update existing file in repository
+
+```
+PUT /projects/:id/repository/files
+```
+
+Example response:
+
+```json
+{
+ "file_name": "app/project.rb",
+ "branch_name": "master",
+}
+```
+
+Parameters:
+
++ `file_path` (required) - Full path to file. Ex. lib/class.rb
++ `branch_name` (required) - The name of branch
++ `encoding` (optional) - 'text' or 'base64'. Text is default.
++ `content` (required) - New file content
++ `commit_message` (required) - Commit message
+
+## Delete existing file in repository
+
+```
+DELETE /projects/:id/repository/files
+```
+
+Example response:
+
+```json
+{
+ "file_name": "app/project.rb",
+ "branch_name": "master",
+}
+```
+
+Parameters:
+
++ `file_path` (required) - Full path to file. Ex. lib/class.rb
++ `branch_name` (required) - The name of branch
++ `commit_message` (required) - Commit message
+
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 213604915a6..e0c46f92b84 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -5,10 +5,61 @@ module API
before { authorize! :push_code, user_project }
resource :projects do
+ # Get file from repository
+ # File content is Base64 encoded
+ #
+ # Parameters:
+ # file_path (required) - The path to the file. Ex. lib/class.rb
+ # ref (required) - The name of branch, tag or commit
+ #
+ # Example Request:
+ # GET /projects/:id/repository/files
+ #
+ # Example response:
+ # {
+ # "file_name": "key.rb",
+ # "file_path": "app/models/key.rb",
+ # "size": 1476,
+ # "encoding": "base64",
+ # "content": "IyA9PSBTY2hlbWEgSW5mb3...",
+ # "ref": "master",
+ # "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
+ # "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
+ # }
+ #
+ get ":id/repository/files" do
+ required_attributes! [:file_path, :ref]
+ attrs = attributes_for_keys [:file_path, :ref]
+ ref = attrs.delete(:ref)
+ file_path = attrs.delete(:file_path)
+
+ commit = user_project.repository.commit(ref)
+ not_found! "Commit" unless commit
+
+ blob = user_project.repository.blob_at(commit.sha, file_path)
+
+ if blob
+ status(200)
+
+ {
+ file_name: blob.name,
+ file_path: blob.path,
+ size: blob.size,
+ encoding: "base64",
+ content: Base64.encode64(blob.data),
+ ref: ref,
+ blob_id: blob.id,
+ commit_id: commit.id,
+ }
+ else
+ render_api_error!('File not found', 404)
+ end
+ end
+
# Create new file in repository
#
# Parameters:
- # file_path (optional) - The path to new file. Ex. lib/class.rb
+ # file_path (required) - The path to new file. Ex. lib/class.rb
# branch_name (required) - The name of branch
# content (required) - File content
# commit_message (required) - Commit message
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index acef7df8777..fa25a4bec6a 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -9,6 +9,36 @@ describe API::API do
let!(:project) { create(:project, namespace: user.namespace ) }
before { project.team << [user, :developer] }
+ describe "GET /projects/:id/repository/files" do
+ it "should return file info" do
+ params = {
+ file_path: 'app/models/key.rb',
+ ref: 'master',
+ }
+
+ get api("/projects/#{project.id}/repository/files", user), params
+ response.status.should == 200
+ json_response['file_path'].should == 'app/models/key.rb'
+ json_response['file_name'].should == 'key.rb'
+ Base64.decode64(json_response['content']).lines.first.should == "class Key < ActiveRecord::Base\n"
+ end
+
+ it "should return a 400 bad request if no params given" do
+ get api("/projects/#{project.id}/repository/files", user)
+ response.status.should == 400
+ end
+
+ it "should return a 404 if such file does not exist" do
+ params = {
+ file_path: 'app/models/application.rb',
+ ref: 'master',
+ }
+
+ get api("/projects/#{project.id}/repository/files", user), params
+ response.status.should == 404
+ end
+ end
+
describe "POST /projects/:id/repository/files" do
let(:valid_params) {
{