Commit d25b5d029d539ccccbea25d7efceeddbf4002459
Exists in
spb-stable
and in
3 other branches
Merge pull request #5891 from jhollingsworth/feature/zip-archive
Add support for various archive formats.
Showing
6 changed files
with
44 additions
and
8 deletions
Show diff stats
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, "routing" do | @@ -130,6 +130,14 @@ describe Projects::RepositoriesController, "routing" 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 |