#907: add ProjectTags table, update UI, logic

This commit is contained in:
Vokhmin Alexey V 2013-02-14 16:46:25 +04:00
parent 901ccce79a
commit 5c286a6aa0
6 changed files with 86 additions and 10 deletions

View File

@ -11,17 +11,18 @@ class Projects::Git::TreesController < Projects::Git::BaseController
def archive
format, @treeish = params[:format], params[:treeish]
if (@treeish =~ /^#{@project.owner.uname}-#{@project.name}-/) && !(@treeish =~ /[\s]+/) && (format =~ /^(zip|tar\.gz)$/)
@treeish = @treeish.gsub(/^#{@project.owner.uname}-#{@project.name}-/, '')
if (@treeish =~ /^#{@project.name}-/) && !(@treeish =~ /[\s]+/) && (format =~ /^(zip|tar\.gz)$/)
@treeish = @treeish.gsub(/^#{@project.name}-/, '')
@commit = @project.repo.commits(@treeish, 1).first
end
raise Grit::NoSuchPathError unless @commit
name = "#{@project.owner.uname}-#{@project.name}-#{@treeish}"
fullname = "#{name}.#{format == 'zip' ? 'zip' : 'tar.gz'}"
file = Tempfile.new fullname, 'tmp'
system("cd #{@project.path}; git archive --format=#{format == 'zip' ? 'zip' : 'tar'} --prefix=#{name}/ #{@treeish} #{format == 'zip' ? '' : ' | gzip -9'} > #{file.path}")
file.close
send_file file.path, :disposition => 'attachment', :type => "application/#{format == 'zip' ? 'zip' : 'x-tar-gz'}", :filename => fullname
tag = @project.repo.tags.find{ |t| t.name == @treeish }
if tag
redirect_to "#{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{@project.get_project_tag_sha1(tag, format)}"
else
archive = @project.create_archive @treeish, format
send_file archive[:path], :disposition => 'attachment', :type => "application/#{format == 'zip' ? 'zip' : 'x-tar-gz'}", :filename => archive[:fullname]
end
end
def tags

View File

@ -15,6 +15,7 @@ class Project < ActiveRecord::Base
has_many :project_imports, :dependent => :destroy
has_many :project_to_repositories, :dependent => :destroy
has_many :repositories, :through => :project_to_repositories
has_many :project_tags, :dependent => :destroy
has_many :relations, :as => :target, :dependent => :destroy
has_many :collaborators, :through => :relations, :source => :actor, :source_type => 'User'
@ -190,8 +191,51 @@ class Project < ActiveRecord::Base
end
end
def create_archive(treeish, format)
file_name = "#{name}-#{treeish}"
fullname = "#{file_name}.#{tag_file_format(format)}"
file = Tempfile.new fullname, 'tmp'
system("cd #{path}; git archive --format=#{format == 'zip' ? 'zip' : 'tar'} --prefix=#{file_name}/ #{treeish} #{format == 'zip' ? '' : ' | gzip -9'} > #{file.path}")
file.close
{
:path => file.path,
:fullname => fullname
}
end
def get_project_tag_sha1(tag, format)
format_id = ProjectTag::Formats["#{tag_file_format(format)}"]
project_tag = project_tags.where(:tag_name => tag.name, :format_id => format_id).first
return project_tag.sha1 if project_tag && project_tag.commit_id == tag.commit.id
archive = create_archive(tag.name, format)
sha1 = Digest::SHA1.file(archive[:path]).hexdigest
token = User.find_by_uname('rosa_system').authentication_token
if %x[ curl #{APP_CONFIG['file_store_url']}/api/v1/file_stores.json?hash=#{sha1} ] == '[]'
system "curl --user #{token}: -POST -F 'file_store[file]=@#{archive[:path]}' #{APP_CONFIG['file_store_url']}/api/v1/upload?file['name']=#{name}-#{tag.name}.#{tag_file_format(format)}"
end
if project_tag
old_sha1 = project_tag.sha1
project_tag.update_attributes(:sha1 => sha1)
system "curl --user #{token}: -X DELETE #{APP_CONFIG['file_store_url']}/api/v1/file_stores/#{old_sha1}.json"
else
project_tags.create(
:tag_name => tag.name,
:format_id => format_id,
:commit_id => tag.commit.id,
:sha1 => sha1
)
end
return sha1
end
protected
def tag_file_format(format)
format == 'zip' ? 'zip' : 'tar.gz'
end
def truncate_name
self.name = name.strip if name
end

19
app/models/project_tag.rb Normal file
View File

@ -0,0 +1,19 @@
# -*- encoding : utf-8 -*-
class ProjectTag < ActiveRecord::Base
FORMATS = {
'zip' => 0,
'tar.gz' => 1
}
belongs_to :project
validates :project_id, :commit_id, :sha1, :tag_name, :format_id, :presence => true
validates :project_id, :uniqueness => {:scope => [:tag_name, :format_id]}
attr_accessible :project_id,
:commit_id,
:sha1,
:tag_name,
:format_id
end

View File

@ -7,7 +7,7 @@
=image_tag 'zip.png', :alt => 'ZIP'
%b.caret
%ul.dropdown-menu
- file_name = "#{@project.owner.uname}-#{@project.name}-#{treeish}"
- file_name = "#{@project.name}-#{treeish}"
%li=link_to "tar.gz", archive_path(project, file_name, 'tar.gz')
%li=link_to "zip", archive_path(project, file_name, 'zip')

View File

@ -1,6 +1,6 @@
%li
= link_to t('layout.projects.browse_code'), tree_path(@project, tag.name), :class => 'detail-link'
- file_name = "#{@project.owner.uname}-#{@project.name}-#{tag.name}"
- file_name = "#{@project.name}-#{tag.name}"
- %w(zip tar.gz).each do |type|
= link_to t('layout.projects.source_code', :type => type), archive_path(@project, file_name, type), :class => 'detail-link'
%p.name

View File

@ -0,0 +1,12 @@
class CreateProjectTagsTable < ActiveRecord::Migration
def change
create_table :project_tags do |t|
t.integer :project_id
t.string :commit_id
t.string :sha1
t.string :tag_name
t.integer :format_id
t.timestamps
end
end
end