Apply basic git repo functionality operation: add, change, destroy user ssh_key. Create, destroy, open/close project git repos. Calc project owner. Improve UI for users, groups and projects: fix links and routes, add actions refactor. Other minor fixes and refactoring. Add ssh_key uniqness check. Add uname uniqness check between User and Group. Check project owner ssh_key existance before project creation. Temporary disable uname and unixname change due to gitolite stranges. Refs #2136

This commit is contained in:
Pavel Chipiga 2011-10-26 23:57:51 +03:00
parent ab9b1569a9
commit 0171a0a42a
42 changed files with 334 additions and 250 deletions

View File

@ -21,6 +21,7 @@ gem "will_paginate", "~> 3.0.2"
gem "russian"
gem "grit"
gem 'gitolito', :git => 'git@github.com:warpc/gitolito.git'
gem 'whenever', :require => false
gem 'delayed_job'
gem 'whenever', :require => false

View File

@ -1,3 +1,10 @@
GIT
remote: git@github.com:warpc/gitolito.git
revision: 8608b9bdfd33e961d9f9d71dd594e62780c074f6
specs:
gitolito (0.0.1)
grit
GEM
remote: http://rubygems.org/
specs:
@ -104,7 +111,7 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
mime-types (1.17.2)
multi_json (1.0.3)
multi_xml (0.4.1)
multipart-post (1.1.3)
@ -158,7 +165,7 @@ GEM
oa-oauth (= 0.3.2)
oa-openid (= 0.3.2)
orm_adapter (0.0.5)
paperclip (2.4.4)
paperclip (2.4.5)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
@ -192,7 +199,7 @@ GEM
rdoc (~> 3.4)
thor (~> 0.14.4)
raindrops (0.8.0)
rake (0.9.2)
rake (0.9.2.2)
rbx-require-relative (0.0.5)
rdoc (3.11)
json (~> 1.4)
@ -222,7 +229,8 @@ GEM
ruby_parser (2.3.1)
sexp_processor (~> 3.0)
rubyntlm (0.1.1)
russian (0.2.7)
russian (0.6.0)
i18n (>= 0.5.0)
sass (3.1.10)
sexp_processor (3.0.7)
silent-postgres (0.1.1)
@ -260,6 +268,7 @@ DEPENDENCIES
delayed_job
devise (~> 1.4.8)
factory_girl_rails (~> 1.3.0)
gitolito!
grit
haml-rails (~> 0.3.4)
hirb

View File

@ -8,6 +8,11 @@ class ApplicationController < ActionController::Base
after_filter lambda { EventLog.current_controller = nil }
protected
def get_owner
params['user_id'] && User.find_by_id(params['user_id']) ||
params['group_id'] && Group.find_by_id(params['group_id']) || current_user
end
def layout_by_resource
if devise_controller?
"sessions"

View File

@ -1,12 +1,10 @@
# coding: UTF-8
class GroupsController < ApplicationController
before_filter :authenticate_user!
before_filter :find_group, :only => [:show, :edit, :update, :destroy]
def index
@groups = Group.paginate(:page => params[:page], :per_page => 15)
@groups = Group.paginate(:page => params[:group_page])
end
def show
@ -15,20 +13,13 @@ class GroupsController < ApplicationController
@projects = @group.projects.paginate(:page => params[:project_page], :per_page => 10)
end
def edit
end
def destroy
@user.destroy
flash[:notice] = t("flash.group.destroyed")
redirect_to groups_path
end
def new
@group = Group.new
end
def edit
end
def create
@group = Group.new params[:group]
@group.owner = current_user
@ -42,9 +33,25 @@ class GroupsController < ApplicationController
end
end
private
def update
if @group.update_attributes(params[:group])
flash[:notice] = t('flash.group.saved')
redirect_to groups_path
else
flash[:error] = t('flash.group.save_error')
render :action => :edit
end
end
def destroy
@group.destroy
flash[:notice] = t("flash.group.destroyed")
redirect_to groups_path
end
protected
def find_group
@group = Group.find(params[:id])
end
end

View File

@ -37,7 +37,7 @@ class PlatformsController < ApplicationController
def create
@platform = Platform.new params[:platform]
@platform.owner = get_acter
@platform.owner = get_owner
if @platform.save
flash[:notice] = I18n.t("flash.platform.saved")

View File

@ -1,14 +1,51 @@
class ProjectsController < ApplicationController
before_filter :authenticate_user!
before_filter :find_project, :only => [:show, :destroy, :build, :process_build]
before_filter :get_paths, :only => [:new, :create]
before_filter :find_project, :only => [:show, :edit, :update, :destroy, :build, :process_build]
before_filter :get_paths, :only => [:new, :create, :edit, :update]
def index
@projects = Project.paginate(:page => params[:project_page])
end
def show
@current_build_lists = @project.build_lists.current.recent.paginate :page => params[:page]
end
def new
@project = Project.new
end
def show
@current_build_lists = @project.build_lists.current.recent.paginate :page => params[:page]
def edit
end
def create
@project = Project.new params[:project]
@project.owner = get_owner
if @project.save
flash[:notice] = t('flash.project.saved')
redirect_to @project.owner
else
flash[:error] = t('flash.project.save_error')
flash[:warning] = @project.errors[:base]
render :action => :new
end
end
def update
if @project.update_attributes(params[:project])
flash[:notice] = t('flash.project.saved')
redirect_to @project.owner
else
flash[:error] = t('flash.project.save_error')
render :action => :edit
end
end
def destroy
@project.destroy
flash[:notice] = t("flash.project.destroyed")
redirect_to redirect_to @project.owner
end
def build
@ -57,38 +94,16 @@ class ProjectsController < ApplicationController
end
end
def create
@project = Project.new params[:project]
# @project.owner = get_acter
if @project.save
flash[:notice] = t('flash.project.saved')
# redirect_to @project.owner
redirect_to @project
else
flash[:error] = t('flash.project.save_error')
render :action => :new
end
end
def destroy
@project.destroy
flash[:notice] = t("flash.project.destroyed")
#redirect_to platform_repository_path(@platform, @repository)
redirect_to root_path
end
protected
def get_paths
if params[:user_id]
@user = User.find params[:user_id]
@projects_path = user_projects_path @user
@projects_path = user_path(@user) # user_projects_path @user
@new_project_path = new_user_project_path @user
elsif params[:group_id]
@group = Group.find params[:group_id]
@projects_path = group_projects_path @group
@projects_path = user_path(@user) # group_projects_path @group
@new_projects_path = new_group_project_path @group
else
@projects_path = projects_path

View File

@ -30,7 +30,7 @@ class RepositoriesController < ApplicationController
def create
@repository = Repository.new(params[:repository])
@repository.owner = get_acter
@repository.owner = get_owner
if @repository.save
flash[:notice] = t('flash.repository.saved')
redirect_to @repositories_path
@ -58,7 +58,8 @@ class RepositoriesController < ApplicationController
redirect_to url_for(:action => :add_project)
end
else
@projects = (Project.all - @repository.projects).paginate(:page => params[:project_page])
# @projects = (Project.all - @repository.projects).paginate(:page => params[:project_page])
@projects = Project.where('id <> ?', @repository.projects.map(&:id)).paginate(:page => params[:project_page])
render 'projects_list'
end
end

View File

@ -1,14 +1,13 @@
# coding: UTF-8
class UsersController < ApplicationController
before_filter :authenticate_user!
before_filter :find_user, :only => [:show, :edit, :update, :destroy]
def index
@users = User.all
@users = User.paginate(:page => params[:user_page])
end
def show
puts params.inspect
@groups = @user.groups.uniq
@platforms = @user.platforms.paginate(:page => params[:platform_page], :per_page => 10)
@repositories = @user.repositories.paginate(:page => params[:repository_page], :per_page => 10)
@ -22,13 +21,6 @@ class UsersController < ApplicationController
def edit
end
def destroy
@user.destroy
flash[:notice] = t("flash.user.destroyed")
redirect_to users_path
end
def create
@user = User.new params[:user]
if @user.save
@ -50,7 +42,14 @@ class UsersController < ApplicationController
end
end
def destroy
@user.destroy
flash[:notice] = t("flash.user.destroyed")
redirect_to users_path
end
protected
def find_user
@user = User.find(params[:id])
end

View File

@ -1,2 +1,5 @@
module ProjectsHelper
def git_repo_url(name)
"ssh://git@#{request.domain}:722/#{name}.git"
end
end

View File

@ -2,26 +2,28 @@ class Group < ActiveRecord::Base
relationable :as => :object
relationable :as => :target
has_many :roles, :through => :targets
validates :name, :uname, :owner_id, :presence => true
validates :name, :uname, :uniqueness => true
validates :uname, :format => { :with => /^[a-zA-Z0-9_]+$/ }, :allow_nil => false, :allow_blank => false
belongs_to :global_role, :class_name => 'Role'
belongs_to :owner, :class_name => 'User'
has_many :own_projects, :as => :owner, :class_name => 'Project'
has_many :objects, :as => :target, :class_name => 'Relation'
has_many :targets, :as => :object, :class_name => 'Relation'
has_many :roles, :through => :targets
has_many :members, :through => :objects, :source => :object, :source_type => 'User', :autosave => true
has_many :projects, :through => :targets, :source => :target, :source_type => 'Project', :autosave => true
has_many :platforms, :through => :targets, :source => :target, :source_type => 'Platform', :autosave => true
has_many :repositories, :through => :targets, :source => :target, :source_type => 'Repository', :autosave => true
before_save :create_dir
after_destroy :remove_dir
validates :name, :uname, :owner_id, :presence => true
validates :name, :uname, :uniqueness => true
validates :uname, :format => { :with => /^[a-zA-Z0-9_]+$/ }, :allow_nil => false, :allow_blank => false
validate { errors.add(:uname, :taken) if User.where('uname LIKE ?', uname).present? }
attr_readonly :uname
delegate :ssh_key, :to => :owner
def roles_of(user)
objects.where(:object_id => user.id, :object_type => user.class).map {|rel| rel.role}.reject {|r| r.nil?}
@ -36,31 +38,4 @@ class Group < ActiveRecord::Base
rel.save
end
end
def path
build_path(uname)
end
protected
def build_path(dir)
File.join(APP_CONFIG['root_path'], 'groups', dir)
end
def create_dir
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} already exists" if exists
if new_record?
FileUtils.mkdir_p(path)
elsif uname_changed?
FileUtils.mv(build_path(uname_was), build_path(uname))
end
end
def remove_dir
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} didn't exists" unless exists
FileUtils.rm_rf(path)
end
end

View File

@ -8,31 +8,31 @@ class Project < ActiveRecord::Base
has_many :build_lists, :dependent => :destroy
has_many :project_to_repositories
has_many :project_to_repositories, :dependent => :destroy
has_many :repositories, :through => :project_to_repositories
has_many :relations, :as => :target
has_many :relations, :as => :target, :dependent => :destroy
has_many :collaborators, :through => :relations, :source => :object, :source_type => 'User'
has_many :groups, :through => :relations, :source => :object, :source_type => 'Group'
validates :name, :uniqueness => {:scope => [:owner_id, :owner_type]}, :presence => true, :allow_nil => false, :allow_blank => false
validates :unixname, :uniqueness => {:scope => [:owner_id, :owner_type]}, :presence => true, :format => { :with => /^[a-zA-Z0-9_]+$/ }, :allow_nil => false, :allow_blank => false
# validates :unixname, :uniqueness => {:scope => [:owner_id, :owner_type]}, :presence => true, :format => { :with => /^[a-zA-Z0-9\-.]+$/ }, :allow_nil => false, :allow_blank => false
validates :owner, :presence => true
validate {errors.add(:base, I18n.t('flash.project.save_warning_ssh_key')) if owner.ssh_key.blank?}
include Project::HasRepository
# attr_accessible :visibility
attr_readonly :unixname
scope :recent, order("name ASC")
scope :by_name, lambda { |name| {:conditions => ['name like ?', '%' + name + '%']} }
scope :by_visibilities, lambda {|v| {:conditions => ['visibility in (?)', v.join(',')]}}
before_save :create_directory#, :create_git_repo
before_save :make_owner_rel
after_destroy :remove_directory
# before_create :xml_rpc_create
# before_destroy :xml_rpc_destroy
before_create :create_git_repo, :make_owner_rel
before_update :update_git_repo
before_destroy :destroy_git_repo
# before_create :xml_rpc_create
# before_destroy :xml_rpc_destroy
attr_accessible :visibility
def project_versions
self.git_repository.tags
end
@ -41,13 +41,24 @@ class Project < ActiveRecord::Base
collaborators + groups
end
include Project::HasRepository
# Redefining a method from Project::HasRepository module to reflect current situation
def git_repo_path
@git_repo_path ||= File.join("#{APP_CONFIG['git_projects_path']}/#{owner.uname}/#{self.unixname}.git")
@git_repo_path ||= File.join(APP_CONFIG['git_projects_path'], "#{git_repo_name}.git")
end
def git_repo_clone_path
"git@gitolite:#{git_repo_name}.git"
end
def git_repo_name
[owner.uname, unixname].join('/')
end
def git_repo_name_was
[owner.uname, unixname_was].join('/')
end
def git_repo_name_changed?; git_repo_name != git_repo_name_was; end
def path
build_path(unixname)
def public?
visibility == 'open'
end
def clone
@ -75,26 +86,30 @@ class Project < ActiveRecord::Base
end
end
#TODO: Remove it from code if git_repo_path and build_path (or path) have the same purpose
def build_path(dir)
#File.join(APP_CONFIG['root_path'], 'projects', dir)
File.join("#{APP_CONFIG['git_projects_path']}/#{owner.uname}/#{dir}.git")
def create_git_repo
with_ga do |ga|
repo = ga.add_repo git_repo_name
repo.add_key owner.ssh_key, 'RW'
repo.has_anonymous_access!('R') if public?
ga.save_and_release
end
end
def create_directory
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} already exists" if exists
if new_record?
FileUtils.mkdir_p(path)
elsif unixname_changed?
FileUtils.mv(build_path(unixname_was), buildpath(unixname))
end
def update_git_repo
with_ga do |ga|
if repo = ga.find_repo(git_repo_name_was)
repo.rename(git_repo_name) if git_repo_name_changed?
public? ? repo.has_anonymous_access!('R') : repo.has_not_anonymous_access!
ga.save_and_release
end
end if git_repo_name_changed? or visibility_changed?
end
def remove_directory
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} didn't exists" unless exists
FileUtils.rm_rf(path)
def destroy_git_repo
with_ga do |ga|
ga.rm_repo git_repo_name
ga.save_and_release
end
end
def xml_rpc_create

View File

@ -21,13 +21,23 @@ class User < ActiveRecord::Base
has_many :repositories, :through => :targets, :source => :target, :source_type => 'Repository', :autosave => true
validates :uname, :presence => true, :uniqueness => {:case_sensitive => false}, :format => { :with => /^[a-zA-Z0-9_]+$/ }, :allow_nil => false, :allow_blank => false
validates :ssh_key, :uniqueness => true
validate { errors.add(:uname, :taken) if Group.where('uname LIKE ?', uname).present? }
attr_accessible :email, :password, :password_confirmation, :remember_me, :login, :name, :ssh_key, :uname
attr_readonly :uname
attr_accessor :login
before_save :create_dir
after_destroy :remove_dir
before_update {
if ssh_key_was.blank? and ssh_key.present?
create_ssh_key ssh_key
elsif ssh_key_was.present? and ssh_key.blank?
destroy_ssh_key ssh_key_was
elsif ssh_key_changed?
update_ssh_key ssh_key_was, ssh_key
end
}
before_destroy { destroy_ssh_key(ssh_key) }
# after_create() { UserMailer.new_user_notification(self).deliver }
class << self
@ -64,30 +74,36 @@ class User < ActiveRecord::Base
result
end
def path
build_path(uname)
end
protected
def build_path(dir)
puts APP_CONFIG['root_path']
puts dir
File.join(APP_CONFIG['root_path'], 'users', dir)
def create_ssh_key(key)
with_ga do |ga|
ga.store_key! key
own_projects.each do |project|
repo = ga.find_repo(project.git_repo_name)
repo.add_key(key, 'RW') if repo
end
ga.save_and_release
end
end
def create_dir
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} already exists" if exists
if new_record?
FileUtils.mkdir_p(path)
elsif uname_changed?
FileUtils.mv(build_path(uname_was), build_path(uname))
end
def update_ssh_key(old_key, new_key)
with_ga do |ga|
ga.replace_key! old_key, new_key
begin
ga.repos.replace_key old_key, new_key #, options = {}
rescue Gitolito::GitoliteAdmin::Repo::KeyDoesntExistsError
nil
end
ga.save_and_release
end
end
def remove_dir
exists = File.exists?(path) && File.directory?(path)
raise "Directory #{path} didn't exists" unless exists
FileUtils.rm_rf(path)
def destroy_ssh_key(key)
with_ga do |ga|
ga.repos.rm_key key
ga.rm_key! key
ga.save_and_release
end
end
end

View File

@ -4,7 +4,7 @@
= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put, :class => "form" }) do |f|
- if resource.errors.present?
.flash
.message.errorresource.errors.full_messages.map { |msg| content_tag(:p, msg) }.join.html_safe
.message.error= resource.errors.full_messages.map { |msg| content_tag(:p, msg) }.join.html_safe
.group.wat-cf
.left

View File

@ -3,7 +3,7 @@
= f.text_field :name, :class => 'text_field'
.group
= f.label :uname, t("activerecord.attributes.group.uname"), :class => :label
= f.text_field :uname, :class => 'text_field'
= f.text_field :uname, :class => 'text_field', :disabled => f.object.try(:persisted?)
.group.navform.wat-cf
%button.button{:type => "submit"}

View File

@ -1,24 +0,0 @@
.content
%h2.title
= t("layout.groups.list_header")
.inner
%table.table
%tr
%th.first ID
%th= t("activerecord.attributes.group.name")
%th= t("activerecord.attributes.group.owner")
%th.last &nbsp;
- @groups.each do |group|
%tr{:class => cycle("odd", "even")}
%td
= group.id
%td
= link_to group.name, group_path(group)
%td
= link_to group.owner.name, user_path(group.owner)
%td.last
#{link_to t("layout.show"), group_path(group)} | #{link_to t("layout.edit"), edit_group_path(group)} | #{link_to t("layout.delete"), group_path(group), :method => :delete, :confirm => t("layout.groups.confirm_delete")}
.actions-bar.wat-cf
.actions
- if !!paginate
= paginate

View File

@ -1,5 +1,5 @@
.block.notice
%h3= t("layout.groups.members")
.content
- @group.members.uniq.each do |member|
%p= link_to member.name + " (#{@group.roles_of(member).map{|r| r.name}.join(', ')})", user_path(member)
- @group.members.each do |member|
%p= link_to member.name, member # @group.roles_to(member).map(&:name).join(', ')

View File

@ -9,4 +9,5 @@
.inner
= form_for @group, :url => group_path(@group), :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
- content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -3,5 +3,27 @@
%ul.wat-cf
%li.first.active= link_to t("layout.groups.list"), users_path
%li= link_to t("layout.groups.new"), new_group_path
=render :partial => 'list', :object => @groups, :locals => {:paginate => will_paginate(@groups)}
-# content_for :sidebar, render(:partial => 'sidebar')
.content
%h2.title
= t("layout.groups.list_header")
.inner
%table.table
%tr
%th.first ID
%th= t("activerecord.attributes.group.name")
%th= t("activerecord.attributes.group.owner")
%th.last &nbsp;
- @groups.each do |group|
%tr{:class => cycle("odd", "even")}
%td
= group.id
%td
= link_to group.name, group_path(group)
%td
= link_to group.owner.name, user_path(group.owner)
%td.last
#{link_to t("layout.show"), group_path(group)} | #{link_to t("layout.edit"), edit_group_path(group)} | #{link_to t("layout.delete"), group_path(group), :method => :delete, :confirm => t("layout.groups.confirm_delete")}
.actions-bar.wat-cf
.actions= will_paginate @groups, :param_name => :group_page
-# content_for :sidebar, render('sidebar')

View File

@ -6,6 +6,7 @@
.content
%h2.title= t("layout.groups.new_header")
.inner
= form_for :group, :url => groups_path, :html => { :class => :form } do |f|
= form_for @group, :url => groups_path, :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
-# content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -75,4 +75,4 @@
.actions
= will_paginate @projects, :param_name => :project_page
- content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -6,7 +6,10 @@
= f.text_field :name, :class => 'text_field'
.group
= f.label :unixname, t("activerecord.attributes.project.unixname"), :class => :label
= f.text_field :unixname, :class => 'text_field'
= f.text_field :unixname, :class => 'text_field', :disabled => f.object.try(:persisted?)
.group
= f.label :visibility, t("activerecord.attributes.project.visibility"), :class => :label
= f.select :visibility, Project::VISIBILITIES
.group
= f.label :description, t("activerecord.attributes.project.description"), :class => :label
= f.text_area :description, :class => 'text_field', :cols => 80

View File

@ -1,10 +1,11 @@
%table.table
%tr
%th.first= t("activerecord.attributes.project.name")
%th= t("activerecord.attributes.project.unixname")
%th.last &nbsp;
- @projects.each do |project|
%tr{:class => cycle("odd", "even")}
%td
= link_to project.name, project_path(project)
%td= link_to project.name, project
%td= project.unixname
%td.last
#{link_to t("layout.show"), project_path(project)} | #{link_to t("layout.delete"), project_path(project), :method => :delete, :confirm => t("layout.projects.confirm_delete")}
#{link_to t("layout.edit"), edit_project_path(project)} | #{link_to t("layout.delete"), project_path(project), :method => :delete, :confirm => t("layout.projects.confirm_delete")}

View File

@ -1,9 +1,9 @@
.block.notice
%h3= t("layout.platforms.current_platform_header")
.content
%p= link_to @platform.name, platform_path(@platform)
.block.notice
%h3= t("layout.repositories.current_repository_header")
.content
%p= link_to @repository.name + repository_name_postfix(@platform), platform_repository_path(@platform, @repository)
/ .block.notice
/ %h3= t("layout.platforms.current_platform_header")
/ .content
/ %p= link_to @platform.name, platform_path(@platform)
/
/ .block.notice
/ %h3= t("layout.repositories.current_repository_header")
/ .content
/ %p= link_to @repository.name + repository_name_postfix(@platform), platform_repository_path(@platform, @repository)

View File

@ -0,0 +1,14 @@
.block
.secondary-navigation
%ul.wat-cf
%li.first= link_to t("layout.projects.list"), @projects_path # url_for(get_owner) + "#projects"
%li= link_to t("layout.projects.new"), @new_project_path # new_platform_repository_project_path(@platform, @repository)
%li.active= link_to t("layout.projects.edit"), @edit_project_path
.content
%h2.title= t("layout.projects.edit_header")
.inner
= form_for @project, :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
- content_for :sidebar, render('sidebar')

View File

@ -0,0 +1,16 @@
.block
.secondary-navigation
%ul.wat-cf
%li.first.active= link_to t("layout.projects.list"), projects_path
%li= link_to t("layout.projects.new"), new_project_path
.content
%h2.title
= t("layout.projects.list_header")
.inner
= render :partial => 'shared/search_form'
= render :partial => 'projects/list', :object => @projects
.actions-bar.wat-cf
.actions
= will_paginate @projects, :param_name => :project_page
-# content_for :sidebar, render(:partial => 'sidebar')

View File

@ -1,7 +1,7 @@
.block
.secondary-navigation
%ul.wat-cf
%li.first= link_to t("layout.projects.list"), @projects_path#url_for(get_acter) + "#projects"
%li.first= link_to t("layout.projects.list"), @projects_path#url_for(get_owner) + "#projects"
%li.active= link_to t("layout.projects.new"), @new_project_path#new_platform_repository_project_path(@platform, @repository)
-#%li= link_to "git-repo", platform_repository_project_repo_path(@platform, @repository, @project)
-#%li= link_to t("layout.projects.build"), build_platform_repository_project_path(@platform, @repository, @project)
@ -9,6 +9,7 @@
.content
%h2.title= t("layout.projects.new_header")
.inner
= form_for :project, :url => @projects_path, :html => { :class => :form } do |f|
= form_for @project, :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
-# content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -29,11 +29,12 @@
= t("activerecord.attributes.project.visibility")
\:
= @project.visibility
/ %p
/ %b
/ = t("activerecord.attributes.project.repository")
/ \:
/ = @project.repository.name
%p
%b
= t("activerecord.attributes.project.repository")
\:
= git_repo_url @project.git_repo_name
.wat-cf
= link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_path(@project), :method => "delete", :class => "button", :confirm => t("layout.projects.confirm_delete")
@ -45,7 +46,6 @@
%li= link_to t("layout.build_lists.all"), project_build_lists_path(@project)
.content
= render :partial => "build_lists/build_lists", :object => @current_build_lists
-# content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -25,7 +25,7 @@
%b
= t("activerecord.attributes.repository.owner")
\:
= link_to @repository.owner.name, url_for(@repository.owner)
= link_to @repository.owner.try(:name), url_for(@repository.owner)
%p
%b
= t("activerecord.attributes.repository.visibility")

View File

@ -25,7 +25,7 @@
%b
= t("activerecord.attributes.repository.owner")
\:
= link_to @repository.owner.name, url_for(@repository.owner)
= link_to @repository.owner.try(:name), url_for(@repository.owner)
%p
%b
= t("activerecord.attributes.repository.visibility")

View File

@ -3,10 +3,7 @@
= f.text_field :name, :class => 'text_field'
.group
= f.label :uname, t("activerecord.attributes.user.uname"), :class => :label
= f.text_field :uname, :class => 'text_field'
/ .group
/ = f.label :nickname, t("activerecord.attributes.user.nickname"), :class => :label
/ = f.text_field :nickname, :class => 'text_field'
= f.text_field :uname, :class => 'text_field', :disabled => f.object.try(:persisted?)
.group
= f.label :email, t("activerecord.attributes.user.email"), :class => :label
= f.text_field :email, :class => 'text_field'

View File

@ -1,25 +0,0 @@
.block
.content
%h2.title
= t("layout.groups.list_header")
.inner
%table.table
%tr
%th.first ID
%th= t("activerecord.attributes.group.name")
%th= t("activerecord.attributes.user.roles")
%th.last &nbsp;
- @groups.each do |group|
%tr{:class => cycle("odd", "even")}
%td
= group.id
%td
= link_to group.name, group_path(group)
%td
= group.roles_of(@user).map {|r| r.name}.join(', ')
%td.last
#{link_to t("layout.show"), group_path(group)} | #{link_to t("layout.edit"), edit_group_path(group)} | #{link_to t("layout.delete"), group_path(group), :method => :delete, :confirm => t("layout.groups.confirm_delete")}
.actions-bar.wat-cf
.actions
- if paginate
= paginate

View File

@ -1,5 +1,5 @@
.block.notice
%h3= t("layout.users.groups")
.content
- @groups.each do |group|
%p= link_to group.name + " (#{group.roles_of(@user).map{|r| r.name}.join(', ')})", group_path(group)
- @user.groups.each do |group|
%p= link_to group.name, group # @user.roles_to(group).map(&:name).join(', ')

View File

@ -9,4 +9,5 @@
.inner
= form_for @user, :url => user_path(@user), :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
- content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -24,5 +24,4 @@
%td.last
#{link_to t("layout.show"), user_path(user)} | #{link_to t("layout.edit"), edit_user_path(user)} | #{link_to t("layout.delete"), user_path(user), :method => :delete, :confirm => t("layout.users.confirm_delete")}
.actions-bar.wat-cf
.actions
-# content_for :sidebar, render(:partial => 'sidebar')
.actions= will_paginate @users, :param_name => :user_page

View File

@ -6,6 +6,7 @@
.content
%h2.title= t("layout.users.new_header")
.inner
= form_for :user, :url => users_path, :html => { :class => :form } do |f|
= form_for @user, :url => users_path, :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}
-# content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -75,4 +75,4 @@
.actions
= will_paginate @projects, :param_name => :project_page
- content_for :sidebar, render(:partial => 'sidebar')
- content_for :sidebar, render('sidebar')

View File

@ -32,7 +32,7 @@ module Rosa
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
config.i18n.default_locale = :ru
config.action_view.javascript_expansions[:defaults] = %w()
@ -43,6 +43,5 @@ module Rosa
config.filter_parameters += [:password]
config.action_mailer.default_url_options = { :host => 'abs.rosalab.ru' }
end
end

View File

@ -1 +1,8 @@
APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
def with_ga(&block)
Gitolito::GitoliteAdmin.thread_safe(File.join(APP_CONFIG['root_path'], 'gitolite-admin'), {:wait_lock => true, :seconds => 5}) do |ga|
block.call(ga)
end
# ga = Gitolito::GitoliteAdmin.new File.join(APP_CONFIG['root_path'], 'gitolite-admin'); block.call(ga)
end

View File

@ -151,8 +151,10 @@ ru:
projects:
add: Добавить
edit: Редактировать
list: Список
list_header: Проекты
edit_header: Редактировать проект
show: Проект
build: Собрать
new_build: Новая сборка
@ -249,6 +251,7 @@ ru:
project:
saved: Проект успешно сохранен
save_error: Не удалось сохранить проект
save_warning_ssh_key: Владельцу проекта необходимо указать в профиле свой SSH ключ
destroyed: Проект успешно удален
user:

View File

@ -2,12 +2,12 @@ class DeleteNicknameInitUname < ActiveRecord::Migration
def self.up
remove_column :users, :nickname
add_index :users, :uname, :unique => true
User.all.each {|u| User.where(:id => u.id).update_all(:uname => u.email.split('@').first)}
User.all.each {|u| User.where(:id => u.id).update_all(:uname => u.email.split('@').first.gsub(/[^a-zA-Z0-9_]/, '_'))}
end
def self.down
add_column :users, :nickname, :string
remove_index :users, :uname
User.all.each {|u| User.where(:id => u.id).update_all(:nickname => u.email.split('@').first)}
User.all.each {|u| User.where(:id => u.id).update_all(:nickname => u.email.split('@').first.gsub(/[^a-zA-Z0-9_]/, '_'))}
end
end

View File

@ -207,7 +207,6 @@ ActiveRecord::Schema.define(:version => 20111026135125) do
t.string "object_type"
t.integer "target_id"
t.string "target_type"
t.integer "role_id"
t.datetime "created_at"
t.datetime "updated_at"
end
@ -268,9 +267,8 @@ ActiveRecord::Schema.define(:version => 20111026135125) do
t.datetime "remember_created_at"
t.datetime "created_at"
t.datetime "updated_at"
t.string "uname"
t.text "ssh_key"
t.integer "role_id"
t.string "uname"
t.integer "global_role_id"
end

23
doc/gitolite.md Normal file
View File

@ -0,0 +1,23 @@
===================== Setup gitolite
--------------- As root (sudo su -) on server
* urpmi.addmedia --distrib --mirrorlist '$MIRRORLIST'
* urpmi git
* useradd git
* passwd git
--------------- As user who will manage gitolite
* scp -o preferredauthentications=password ~/.ssh/id_rsa.pub git@gitolite:/tmp/ga_admin.pub
--------------- As git user (su - git) on server
* git clone git://github.com/sitaramc/gitolite
* cd gitolite
* src/gl-system-install
* gl-setup /tmp/ga_admin.pub
--------------- As user who will manage gitolite
* git clone git@gitolite:gitolite-admin