Commit d25b5d029d539ccccbea25d7efceeddbf4002459

Authored by Dmitriy Zaporozhets
2 parents e680228b 7cc25205

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

Add support for various archive formats.
app/controllers/projects/repositories_controller.rb
@@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController @@ -16,7 +16,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
16 16
17 storage_path = Rails.root.join("tmp", "repositories") 17 storage_path = Rails.root.join("tmp", "repositories")
18 18
19 - file_path = @repository.archive_repo(params[:ref], storage_path) 19 + file_path = @repository.archive_repo(params[:ref], storage_path, params[:format].downcase)
20 20
21 if file_path 21 if file_path
22 # Send file to user 22 # Send file to user
config/routes.rb
@@ -217,7 +217,7 @@ Gitlab::Application.routes.draw do @@ -217,7 +217,7 @@ Gitlab::Application.routes.draw do
217 resource :repository, only: [:show] do 217 resource :repository, only: [:show] do
218 member do 218 member do
219 get "stats" 219 get "stats"
220 - get "archive" 220 + get "archive", constraints: { format: Gitlab::Regex.archive_formats_regex }
221 end 221 end
222 end 222 end
223 223
lib/api/repositories.rb
  1 +require 'mime/types'
  2 +
1 module API 3 module API
2 # Projects API 4 # Projects API
3 class Repositories < Grape::API 5 class Repositories < Grape::API
@@ -206,18 +208,20 @@ module API @@ -206,18 +208,20 @@ module API
206 # sha (optional) - the commit sha to download defaults to the tip of the default branch 208 # sha (optional) - the commit sha to download defaults to the tip of the default branch
207 # Example Request: 209 # Example Request:
208 # GET /projects/:id/repository/archive 210 # GET /projects/:id/repository/archive
209 - get ":id/repository/archive" do 211 + get ":id/repository/archive", requirements: { format: Gitlab::Regex.archive_formats_regex } do
210 authorize! :download_code, user_project 212 authorize! :download_code, user_project
211 repo = user_project.repository 213 repo = user_project.repository
212 ref = params[:sha] 214 ref = params[:sha]
  215 + format = params[:format]
213 storage_path = Rails.root.join("tmp", "repositories") 216 storage_path = Rails.root.join("tmp", "repositories")
214 217
215 - file_path = repo.archive_repo(ref, storage_path) 218 + file_path = repo.archive_repo(ref, storage_path, format)
216 if file_path && File.exists?(file_path) 219 if file_path && File.exists?(file_path)
217 data = File.open(file_path, 'rb').read 220 data = File.open(file_path, 'rb').read
218 221
219 - header "Content-Disposition:", " infile; filename=\"#{File.basename(file_path)}\""  
220 - content_type 'application/x-gzip' 222 + header["Content-Disposition"] = "attachment; filename=\"#{File.basename(file_path)}\""
  223 +
  224 + content_type MIME::Types.type_for(file_path).first.content_type
221 225
222 env['api.format'] = :binary 226 env['api.format'] = :binary
223 227
lib/gitlab/regex.rb
@@ -17,6 +17,11 @@ module Gitlab @@ -17,6 +17,11 @@ module Gitlab
17 def path_regex 17 def path_regex
18 default_regex 18 default_regex
19 end 19 end
  20 +
  21 + def archive_formats_regex
  22 + #|zip|tar| tar.gz | tar.bz2 |
  23 + /(zip|tar|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/
  24 + end
20 25
21 def git_reference_regex 26 def git_reference_regex
22 # Valid git ref regex, see: 27 # Valid git ref regex, see:
spec/requests/api/repositories_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
  2 +require 'mime/types'
2 3
3 describe API::API do 4 describe API::API do
4 include ApiHelpers 5 include ApiHelpers
@@ -232,11 +233,29 @@ describe API::API do @@ -232,11 +233,29 @@ describe API::API do
232 end 233 end
233 end 234 end
234 235
235 - describe "GET /projects/:id/repository/archive/:sha" do 236 + describe "GET /projects/:id/repository/archive(.:format)?:sha" do
236 it "should get the archive" do 237 it "should get the archive" do
237 get api("/projects/#{project.id}/repository/archive", user) 238 get api("/projects/#{project.id}/repository/archive", user)
  239 + repo_name = project.repository.name.gsub("\.git", "")
238 response.status.should == 200 240 response.status.should == 200
239 - response.content_type.should == 'application/x-gzip' 241 + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.gz\"/
  242 + response.content_type.should == MIME::Types.type_for('file.tar.gz').first.content_type
  243 + end
  244 +
  245 + it "should get the archive.zip" do
  246 + get api("/projects/#{project.id}/repository/archive.zip", user)
  247 + repo_name = project.repository.name.gsub("\.git", "")
  248 + response.status.should == 200
  249 + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.zip\"/
  250 + response.content_type.should == MIME::Types.type_for('file.zip').first.content_type
  251 + end
  252 +
  253 + it "should get the archive.tar.bz2" do
  254 + get api("/projects/#{project.id}/repository/archive.tar.bz2", user)
  255 + repo_name = project.repository.name.gsub("\.git", "")
  256 + response.status.should == 200
  257 + response.headers['Content-Disposition'].should =~ /filename\=\"#{repo_name}\-[^\.]+\.tar.bz2\"/
  258 + response.content_type.should == MIME::Types.type_for('file.tar.bz2').first.content_type
240 end 259 end
241 260
242 it "should return 404 for invalid sha" do 261 it "should return 404 for invalid sha" do
spec/routing/project_routing_spec.rb
@@ -130,6 +130,14 @@ describe Projects::RepositoriesController, &quot;routing&quot; do @@ -130,6 +130,14 @@ describe Projects::RepositoriesController, &quot;routing&quot; do
130 get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq') 130 get("/gitlab/gitlabhq/repository/archive").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq')
131 end 131 end
132 132
  133 + it "to #archive format:zip" do
  134 + get("/gitlab/gitlabhq/repository/archive.zip").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'zip')
  135 + end
  136 +
  137 + it "to #archive format:tar.bz2" do
  138 + get("/gitlab/gitlabhq/repository/archive.tar.bz2").should route_to('projects/repositories#archive', project_id: 'gitlab/gitlabhq', format: 'tar.bz2')
  139 + end
  140 +
133 it "to #show" do 141 it "to #show" do
134 get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq') 142 get("/gitlab/gitlabhq/repository").should route_to('projects/repositories#show', project_id: 'gitlab/gitlabhq')
135 end 143 end