Commit d25b5d02 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #5891 from jhollingsworth/feature/zip-archive

Add support for various archive formats.
parents e680228b 7cc25205
...@@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController ...@@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
storage_path = Rails.root.join("tmp", "repositories") storage_path = Rails.root.join("tmp", "repositories")
file_path = @repository.archive_repo(params[:ref], storage_path) file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase)
if file_path if file_path
# Send file to user # Send file to user
......
...@@ -217,7 +217,7 @@ Gitlab::Application.routes.draw do ...@@ -217,7 +217,7 @@ Gitlab::Application.routes.draw do
resource :repository, only: [:show] do resource :repository, only: [:show] do
member do member do
get "stats" get "stats"
get "archive" get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
end end
end end
......
require 'mime/types'
module API module API
# Projects API # Projects API
class Repositories < Grape::API class Repositories < Grape::API
...@@ -206,18 +208,20 @@ module API ...@@ -206,18 +208,20 @@ module API
# sha (optional) - the commit sha to download defaults to the tip of the default branch # sha (optional) - the commit sha to download defaults to the tip of the default branch
# Example Request: # Example Request:
# GET /projects/:id/repository/archive # GET /projects/:id/repository/archive
get ":id/repository/archive" do get ":id/repository/archive", requirements: { format: Gitlab::Regex.archive_formats_regex } do
authorize! :download_code, user_project authorize! :download_code, user_project
repo = user_project.repository repo = user_project.repository
ref = params[:sha] ref = params[:sha]
format = params[:format]
storage_path = Rails.root.join("tmp", "repositories") storage_path = Rails.root.join("tmp", "repositories")
file_path = repo.archive_repo(ref, storage_path) file_path = repo.archive_repo(ref, storage_path, format)
if file_path && File.exists?(file_path) if file_path && File.exists?(file_path)
data = File.open(file_path, 'rb').read data = File.open(file_path, 'rb').read
header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\"" header["Content-Disposition"] = "attachment; filename=\"#{File.basename(file_path)}\""
content_type 'application/x-gzip'
content_type MIME::Types.type_for(file_path).first.content_type
env['api.format'] = :binary env['api.format'] = :binary
......
...@@ -18,6 +18,11 @@ module Gitlab ...@@ -18,6 +18,11 @@ module Gitlab
default_regex default_regex
end end
def archive_formats_regex
#|zip|tar| tar.gz | tar.bz2 |
/(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/
end
def git_reference_regex def git_reference_regex
# Valid git ref regex, see: # Valid git ref regex, see:
# https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
......
require 'spec_helper' require 'spec_helper'
require 'mime/types'
describe API::API do describe API::API do
include ApiHelpers include ApiHelpers
...@@ -232,11 +233,29 @@ describe API::API do ...@@ -232,11 +233,29 @@ describe API::API do
end end
end end
describe "GET /projects/:id/repository/archive/:sha" do describe "GET /projects/:id/repository/archive(.:format)?:sha" do
it "should get the archive" do it "should get the archive" do
get api("/projects/#{project.id}/repository/archive", user) get api("/projects/#{project.id}/repository/archive", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200 response.status.should == 200
response.content_type.should == 'application/x-gzip' response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/
response.content_type.should == MIME::Types.type_for('file.tar.gz').first.content_type
end
it "should get the archive.zip" do
get api("/projects/#{project.id}/repository/archive.zip", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.zip\"/
response.content_type.should == MIME::Types.type_for('file.zip').first.content_type
end
it "should get the archive.tar.bz2" do
get api("/projects/#{project.id}/repository/archive.tar.bz2", user)
repo_name = project.repository.name.gsub("\.git", "")
response.status.should == 200
response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/
response.content_type.should == MIME::Types.type_for('file.tar.bz2').first.content_type
end end
it "should return 404 for invalid sha" do it "should return 404 for invalid sha" do
......
...@@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" do ...@@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" do
get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq') get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq')
end end
it "to #archive format:zip" do
get("/gitlab/gitlabhq/repository/archive.zip").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'zip')
end
it "to #archive format:tar.bz2" do
get("/gitlab/gitlabhq/repository/archive.tar.bz2").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'tar.bz2')
end
it "to #show" do it "to #show" do
get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq') get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq')
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment