Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e6edaa3b50
64 changed files with 763 additions and 198 deletions
2
Gemfile
2
Gemfile
|
@ -14,7 +14,7 @@ gem "devise", "~> 2.1.0"
|
|||
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
|
||||
gem "gitolite", :git => "https://github.com/gitlabhq/gitolite-client.git", :ref => "9b715ca8bab6529f6c92204a25f84d12f25a6eb0"
|
||||
gem "pygments.rb", :git => "https://github.com/gitlabhq/pygments.rb.git", :ref => "2cada028da5054616634a1d9ca6941b65b3ce188"
|
||||
gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "7edf27d0281e09561838122982c16b7e62181f44"
|
||||
gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e"
|
||||
gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
|
||||
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
|
||||
gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git"
|
||||
|
|
|
@ -42,8 +42,8 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
||||
revision: 7edf27d0281e09561838122982c16b7e62181f44
|
||||
ref: 7edf27d0281e09561838122982c16b7e62181f44
|
||||
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||
ref: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||
specs:
|
||||
omniauth-ldap (1.0.2)
|
||||
net-ldap (~> 0.2.2)
|
||||
|
|
|
@ -33,7 +33,7 @@ init:
|
|||
})
|
||||
|
||||
$("#note_note").live("focus", function(){
|
||||
$(this).css("height", "100px");
|
||||
$(this).css("height", "80px");
|
||||
$('.note_advanced_opts').show();
|
||||
});
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ var Pager = {
|
|||
this.limit=limit;
|
||||
this.offset=limit;
|
||||
this.initLoadMore();
|
||||
$('.loading').show();
|
||||
},
|
||||
|
||||
getOld:
|
||||
|
|
|
@ -337,6 +337,15 @@ p.time {
|
|||
padding: 15px 5px;
|
||||
&:last-child { border:none }
|
||||
.wll:hover { background:none }
|
||||
|
||||
.event_commits {
|
||||
margin-top: 5px;
|
||||
|
||||
li.commit {
|
||||
padding:5px;
|
||||
border:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ico {
|
||||
|
|
|
@ -18,7 +18,8 @@ a {
|
|||
}
|
||||
|
||||
&.lined {
|
||||
text-decoration:underlined;
|
||||
text-decoration:underline;
|
||||
&:hover { text-decoration:underline; }
|
||||
}
|
||||
|
||||
&.gray {
|
||||
|
@ -74,10 +75,6 @@ h5 {
|
|||
font-size:14px;
|
||||
}
|
||||
|
||||
code {
|
||||
background:#FCEEC1;
|
||||
color:$style_color;
|
||||
}
|
||||
|
||||
table {
|
||||
width:100%;
|
||||
|
@ -381,7 +378,6 @@ form {
|
|||
min-height: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
cursor:pointer;
|
||||
&.smoke {
|
||||
background-color:#f5f5f5;
|
||||
}
|
||||
|
@ -516,7 +512,8 @@ form {
|
|||
.row_title {
|
||||
font-weight:bold;
|
||||
color:#444;
|
||||
&:hover {
|
||||
&:hover {
|
||||
color:#444;
|
||||
text-decoration:underline;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
border-bottom:1px solid #aaa;
|
||||
}
|
||||
|
||||
.issue_notes {
|
||||
.issue_notes,
|
||||
.wiki_notes {
|
||||
.note_content {
|
||||
float:left;
|
||||
width:400px;
|
||||
|
@ -23,8 +24,8 @@
|
|||
|
||||
/* Note textare */
|
||||
#note_note {
|
||||
height:100px;
|
||||
width:97%;
|
||||
height:80px;
|
||||
width:99%;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
|
@ -99,8 +100,25 @@ tr.line_notes_row {
|
|||
td {
|
||||
border-bottom:1px solid #ddd;
|
||||
}
|
||||
.actions {
|
||||
.note_actions {
|
||||
margin:0;
|
||||
padding-top: 10px;
|
||||
|
||||
.buttons {
|
||||
float:left;
|
||||
width:300px;
|
||||
}
|
||||
.options {
|
||||
.labels {
|
||||
float:left;
|
||||
padding-left:10px;
|
||||
label {
|
||||
padding: 6px 0;
|
||||
margin: 0;
|
||||
width:120px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,4 +194,16 @@
|
|||
float:right;
|
||||
@extend .cgray;
|
||||
}
|
||||
|
||||
code {
|
||||
background:#FCEEC1;
|
||||
color:$style_color;
|
||||
}
|
||||
|
||||
.commit_short_id {
|
||||
float:left;
|
||||
@extend .lined;
|
||||
min-width:65px;
|
||||
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,13 +30,14 @@
|
|||
.issue {
|
||||
padding:7px 10px;
|
||||
|
||||
p {
|
||||
padding-top:0;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
|
||||
img.avatar {
|
||||
width:32px;
|
||||
margin-top:4px;
|
||||
}
|
||||
p.row_title {
|
||||
padding:0px;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ class NotesLoad < BaseContext
|
|||
then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
||||
when "merge_request"
|
||||
then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
||||
when "wiki"
|
||||
then project.wikis.reverse.map {|w| w.notes.fresh }.flatten[0..20]
|
||||
end
|
||||
|
||||
@notes = if last_id
|
||||
|
|
|
@ -17,6 +17,7 @@ class CommitsController < ApplicationController
|
|||
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
|
||||
|
||||
@commits = @project.commits(@ref, params[:path], @limit, @offset)
|
||||
@commits = CommitDecorator.decorate(@commits)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
|
@ -51,6 +52,8 @@ class CommitsController < ApplicationController
|
|||
@commit = result[:commit]
|
||||
@diffs = result[:diffs]
|
||||
@line_notes = []
|
||||
|
||||
@commits = CommitDecorator.decorate(@commits)
|
||||
end
|
||||
|
||||
def patch
|
||||
|
|
|
@ -143,5 +143,6 @@ class MergeRequestsController < ApplicationController
|
|||
# Get commits from repository
|
||||
# or from cache if already merged
|
||||
@commits = @merge_request.commits
|
||||
@commits = CommitDecorator.decorate(@commits)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,13 +3,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
# Extend the standard message generation to accept our custom exception
|
||||
def failure_message
|
||||
exception = env["omniauth.error"]
|
||||
if exception.class == OmniAuth::Error
|
||||
error = exception.message
|
||||
else
|
||||
error = exception.error_reason if exception.respond_to?(:error_reason)
|
||||
error ||= exception.error if exception.respond_to?(:error)
|
||||
error ||= env["omniauth.error.type"].to_s
|
||||
end
|
||||
error = exception.error_reason if exception.respond_to?(:error_reason)
|
||||
error ||= exception.error if exception.respond_to?(:error)
|
||||
error ||= exception.message if exception.respond_to?(:message)
|
||||
error ||= env["omniauth.error.type"].to_s
|
||||
error.to_s.humanize if error
|
||||
end
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ class RefsController < ApplicationController
|
|||
@logs = contents.map do |content|
|
||||
file = params[:path] ? File.join(params[:path], content.name) : content.name
|
||||
last_commit = @project.commits(@commit.id, file, 1).last
|
||||
{
|
||||
last_commit = CommitDecorator.decorate(last_commit)
|
||||
{
|
||||
:file_name => content.name,
|
||||
:commit => last_commit
|
||||
}
|
||||
|
|
|
@ -13,16 +13,16 @@ class WikisController < ApplicationController
|
|||
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
|
||||
end
|
||||
|
||||
unless @wiki
|
||||
return render_404 unless can?(current_user, :write_wiki, @project)
|
||||
end
|
||||
@note = @project.notes.new(:noteable => @wiki)
|
||||
|
||||
respond_to do |format|
|
||||
if @wiki
|
||||
format.html
|
||||
else
|
||||
if @wiki
|
||||
render 'show'
|
||||
else
|
||||
if can?(current_user, :write_wiki, @project)
|
||||
@wiki = @project.wikis.new(:slug => params[:id])
|
||||
format.html { render "edit" }
|
||||
render 'edit'
|
||||
else
|
||||
render 'empty'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,6 +46,13 @@ class Notify < ActionMailer::Base
|
|||
mail(:to => recipient.email, :subject => "gitlab | note for issue #{@issue.id} | #{@note.project_name} ")
|
||||
end
|
||||
|
||||
def note_wiki_email(recipient_id, note_id)
|
||||
recipient = User.find(recipient_id)
|
||||
@note = Note.find(note_id)
|
||||
@wiki = @note.noteable
|
||||
mail(:to => recipient.email, :subject => "gitlab | note for wiki | #{@note.project_name}")
|
||||
end
|
||||
|
||||
def new_merge_request_email(merge_request_id)
|
||||
@merge_request = MergeRequest.find(merge_request_id)
|
||||
mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ")
|
||||
|
|
|
@ -114,6 +114,10 @@ class Commit
|
|||
@head = head
|
||||
end
|
||||
|
||||
def short_id(length = 10)
|
||||
id.to_s[0..length]
|
||||
end
|
||||
|
||||
def safe_message
|
||||
utf8 message
|
||||
end
|
||||
|
@ -150,4 +154,8 @@ class Commit
|
|||
def prev_commit_id
|
||||
prev_commit.try :id
|
||||
end
|
||||
|
||||
def parents_count
|
||||
parents && parents.count || 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class Wiki < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
has_many :notes, :as => :noteable, :dependent => :destroy
|
||||
|
||||
validates :content, :title, :user_id, :presence => true
|
||||
validates :title, :length => 1..250
|
||||
|
|
|
@ -34,6 +34,7 @@ class MailerObserver < ActiveRecord::Observer
|
|||
case note.noteable_type
|
||||
when "Commit"; Notify.note_commit_email(u.id, note.id).deliver
|
||||
when "Issue"; Notify.note_issue_email(u.id, note.id).deliver
|
||||
when "Wiki"; Notify.note_wiki_email(u.id, note.id).deliver
|
||||
when "MergeRequest"; Notify.note_merge_request_email(u.id, note.id).deliver
|
||||
when "Snippet"; true
|
||||
else
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
.browse_code_link_holder
|
||||
%p
|
||||
%strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), :class => "right"
|
||||
= link_to project_commit_path(@project, :id => commit.id) do
|
||||
%p
|
||||
%code.left= commit.id.to_s[0..10]
|
||||
%strong.cgray= commit.author_name
|
||||
–
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||
%span.row_title= truncate(commit.safe_message, :length => 50)
|
||||
%p
|
||||
= link_to commit.short_id(8), project_commit_path(@project, :id => commit.id), :class => "commit_short_id"
|
||||
%strong.cgray= commit.author_name
|
||||
–
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||
= link_to truncate(commit.title, :length => 50), project_commit_path(@project, :id => commit.id), :class => "row_title"
|
||||
|
||||
%span.committed_ago
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
ago
|
||||
|
||||
%span.committed_ago
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
ago
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.commit-box{class: @commit.parents.count > 1 ? "merge-commit" : ""}
|
||||
.commit-box{class: @commit.parents_count > 1 ? "merge-commit" : ""}
|
||||
.commit-head
|
||||
.right
|
||||
- if @notes_count > 0
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
|
||||
- unless @commits.empty?
|
||||
%h4 Commits (#{@commits.count})
|
||||
%ul.unstyled= render @commits
|
||||
%div.ui-box
|
||||
%h5.small Commits (#{@commits.count})
|
||||
%ul.unstyled= render @commits
|
||||
|
||||
- unless @diffs.empty?
|
||||
%h4 Diff
|
||||
|
|
|
@ -10,14 +10,14 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
|||
xml.entry do
|
||||
xml.id project_commit_url(@project, :id => commit.id)
|
||||
xml.link :href => project_commit_url(@project, :id => commit.id)
|
||||
xml.title truncate(commit.safe_message, :length => 80)
|
||||
xml.title truncate(commit.title, :length => 80)
|
||||
xml.updated commit.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
xml.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(commit.author_email)
|
||||
xml.author do |author|
|
||||
xml.name commit.author_name
|
||||
xml.email commit.author_email
|
||||
end
|
||||
xml.summary commit.safe_message
|
||||
xml.summary commit.description
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
%h3.page_title
|
||||
Merge Requests
|
||||
%small (authored or assigned to you)
|
||||
%small (authored by or assigned to you)
|
||||
%small.right #{@merge_requests.total_count} merge requests
|
||||
|
||||
%br
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
.alert-message.block-message.error
|
||||
%h3 Gitolite Error
|
||||
%hr
|
||||
%h4 Application cant get access to your gitolite system.
|
||||
%ol
|
||||
%li
|
||||
%p
|
||||
Check 'config/gitlab.yml' for correct settings.
|
||||
%li
|
||||
%p
|
||||
Make sure web server user has access to gitolite.
|
||||
%a{:href => "https://github.com/gitlabhq/gitlabhq/wiki/Gitolite"} Setup tutorial
|
||||
%li
|
||||
%p
|
||||
Try:
|
||||
|
||||
|
||||
|
||||
|
||||
%h4 Tips for Administrator:
|
||||
|
||||
%ul
|
||||
%li
|
||||
%p
|
||||
Check git logs in admin area
|
||||
%li
|
||||
%p
|
||||
Check config/gitlab.yml for correct settings.
|
||||
%li
|
||||
%p
|
||||
Diagnostic tool:
|
||||
%pre
|
||||
= preserve do
|
||||
sudo chmod -R 770 /home/git/repositories/
|
||||
sudo chown -R git:git /home/git/repositories/
|
||||
bundle exec rake gitlab:app:status RAILS_ENV=production
|
||||
%li
|
||||
%p
|
||||
Permissions:
|
||||
%pre
|
||||
= preserve do
|
||||
sudo chmod -R 770 /home/git/repositories/
|
||||
sudo chown -R git:git /home/git/repositories/
|
||||
sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
- commit = CommitDecorator.decorate(commit)
|
||||
%li.wll.commit
|
||||
= link_to project_commit_path(project, :id => commit.id) do
|
||||
%p
|
||||
%code.left= commit.id.to_s[0..10]
|
||||
%strong.cgray= commit.author_name
|
||||
–
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||
%span.row_title= truncate(commit.safe_message, :length => 50) rescue "--broken encoding"
|
||||
%p
|
||||
= link_to commit.short_id(8), project_commit_path(project, :id => commit.id), :class => "commit_short_id"
|
||||
%strong.cdark= commit.author_name
|
||||
–
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||
= truncate(commit.title, :length => 50) rescue "--broken encoding"
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
%h3 API
|
||||
.back_link
|
||||
= link_to help_path do
|
||||
= link_to help_path do
|
||||
← to index
|
||||
%hr
|
||||
|
||||
%ol
|
||||
%li
|
||||
%li
|
||||
%a{:href => "#README"} README
|
||||
%li
|
||||
%li
|
||||
%a{:href => "#projects"} Projects
|
||||
%li
|
||||
%li
|
||||
%a{:href => "#users"} Users
|
||||
%li
|
||||
%a{:href => "#issues"} Issues
|
||||
|
||||
.file_holder#README
|
||||
.file_title
|
||||
|
@ -39,3 +41,13 @@
|
|||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown File.read(Rails.root.join("doc", "api", "users.md"))
|
||||
|
||||
%br
|
||||
|
||||
.file_holder#issues
|
||||
.file_title
|
||||
%i.icon-file
|
||||
Issues
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown File.read(Rails.root.join("doc", "api", "issues.md"))
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
%li Push to non-protected branches
|
||||
%li Remove non-protected branches
|
||||
%li Add tags
|
||||
%li Create new merge request
|
||||
%li Write a wiki
|
||||
|
||||
.ui-box.span3
|
||||
|
@ -55,7 +54,6 @@
|
|||
%li Push to non-protected branches
|
||||
%li Remove non-protected branches
|
||||
%li Add tags
|
||||
%li Create new merge request
|
||||
%li Write a wiki
|
||||
%li Add new team members
|
||||
%li Push to protected branches
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
- else
|
||||
= image_tag "no_avatar.png", :class => "avatar"
|
||||
|
||||
= link_to project_issue_path(issue.project, issue) do
|
||||
%p.row_title= truncate(issue.title, :length => 100)
|
||||
%p= link_to truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title"
|
||||
|
||||
%span.update-author
|
||||
%small.cdark= "##{issue.id}"
|
||||
|
|
|
@ -46,9 +46,7 @@
|
|||
- if @issue.milestone
|
||||
- milestone = @issue.milestone
|
||||
%cite.cgray and attached to milestone
|
||||
= link_to project_milestone_path(milestone.project, milestone) do
|
||||
%strong
|
||||
= truncate(milestone.title, :length => 20)
|
||||
%strong= link_to truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone)
|
||||
|
||||
.right
|
||||
- @issue.labels.each do |label|
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
= merge_request.target_branch
|
||||
= image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
|
||||
|
||||
= link_to project_merge_request_path(merge_request.project, merge_request) do
|
||||
%p.row_title= truncate(merge_request.title, :length => 80)
|
||||
%p= link_to truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title"
|
||||
|
||||
%span.update-author
|
||||
%small.cdark= "##{merge_request.id}"
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
= link_to 'Browse Issues', project_issues_path(milestone.project, :milestone_id => milestone.id), :class => "btn small grouped"
|
||||
- if can? current_user, :admin_milestone, milestone.project
|
||||
= link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), :class => "btn small edit-milestone-link grouped"
|
||||
= link_to project_milestone_path(milestone.project, milestone) do
|
||||
%h4.row_title
|
||||
= truncate(milestone.title, :length => 100)
|
||||
%small
|
||||
= milestone.expires_at
|
||||
%br
|
||||
.progress.progress-success.span3
|
||||
.bar{:style => "width: #{milestone.percent_complete}%;"}
|
||||
%h4
|
||||
= link_to truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title"
|
||||
%small
|
||||
= milestone.expires_at
|
||||
%br
|
||||
.progress.progress-success.span3
|
||||
.bar{:style => "width: #{milestone.percent_complete}%;"}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
%td
|
||||
= link_to [@project, issue] do
|
||||
%span.badge.badge-info ##{issue.id}
|
||||
–
|
||||
= truncate issue.title, :length => 60
|
||||
–
|
||||
= link_to truncate(issue.title, :length => 60), [@project, issue]
|
||||
%br
|
||||
= paginate @issues, :theme => "gitlab"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
||||
%h3 Leave a comment
|
||||
%h3.page_title Leave a comment
|
||||
-if @note.errors.any?
|
||||
.alert-message.block-message.error
|
||||
- @note.errors.full_messages.each do |msg|
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
%tr.per_line_form
|
||||
%td{:colspan => 3 }
|
||||
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
||||
%h3 Leave a note
|
||||
%h3.page_title Leave a note
|
||||
%div.span10
|
||||
-if @note.errors.any?
|
||||
.alert-message.block-message.error
|
||||
|
@ -13,19 +13,21 @@
|
|||
= f.hidden_field :noteable_type
|
||||
= f.hidden_field :line_code
|
||||
= f.text_area :note, :size => 255
|
||||
%h5 Notify via email:
|
||||
.clearfix
|
||||
= label_tag :notify do
|
||||
= check_box_tag :notify, 1, @note.noteable_type != "Commit"
|
||||
%span Project team
|
||||
.note_actions
|
||||
.buttons
|
||||
= f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
|
||||
= link_to "Cancel", "#", :class => "btn hide-button"
|
||||
.options
|
||||
%h6.left Notify via email:
|
||||
.labels
|
||||
= label_tag :notify do
|
||||
= check_box_tag :notify, 1, @note.noteable_type != "Commit"
|
||||
%span Project team
|
||||
|
||||
- if @note.notify_only_author?(current_user)
|
||||
= label_tag :notify_author do
|
||||
= check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
|
||||
%span Commit author
|
||||
.actions
|
||||
= f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
|
||||
= link_to "Close", "#", :class => "btn hide-button"
|
||||
- if @note.notify_only_author?(current_user)
|
||||
= label_tag :notify_author do
|
||||
= check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
|
||||
%span Commit author
|
||||
|
||||
:javascript
|
||||
$(function(){
|
||||
|
|
24
app/views/notify/note_wiki_email.html.haml
Normal file
24
app/views/notify/note_wiki_email.html.haml
Normal file
|
@ -0,0 +1,24 @@
|
|||
%td.content{:align => "left", :style => "font-family: Helvetica, Arial, sans-serif; padding: 20px 0 0;", :valign => "top", :width => "600"}
|
||||
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :style => "color: #717171; font: normal 11px Helvetica, Arial, sans-serif; margin: 0; padding: 0;", :width => "600"}
|
||||
%tr
|
||||
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
|
||||
%td{:align => "left", :style => "padding: 20px 0 0;"}
|
||||
%h2{:style => "color:#646464 !important; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "}
|
||||
New comment -
|
||||
= link_to project_issue_url(@wiki.project, @wiki, :anchor => "note_#{@note.id}") do
|
||||
= "Wiki ##{@wiki.title.to_s}"
|
||||
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
|
||||
%tr
|
||||
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
|
||||
%td{:style => "padding: 15px 0 15px;", :valign => "top"}
|
||||
%p{:style => "color:#767676; font-weight: normal; margin: 0; padding: 0; line-height: 20px; font-size: 12px;font-family: Helvetica, Arial, sans-serif; "}
|
||||
%a{:href => "#", :style => "color: #0eb6ce; text-decoration: none;"} #{@note.author_name}
|
||||
commented on Wiki page:
|
||||
%br
|
||||
%table{:border => "0", :cellpadding => "0", :cellspacing => "0", :width => "558"}
|
||||
%tr
|
||||
%td{:valign => "top"}
|
||||
%div{ :style => "background:#f5f5f5; padding:20px;border:1px solid #ddd" }
|
||||
= markdown(@note.note)
|
||||
%td{:style => "font-size: 1px; line-height: 1px;", :width => "21"}
|
||||
|
|
@ -14,6 +14,6 @@
|
|||
ago
|
||||
- else
|
||||
.alert-message.block-message
|
||||
%p All files attached to project wall, issues etc will be displayed here
|
||||
%span All files attached to project wall, issues etc will be displayed here
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
- if tm
|
||||
%strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, tm)
|
||||
= link_to truncate(content_commit.safe_message, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
|
||||
= link_to truncate(content_commit.title, :length => tm ? 30 : 50), project_commit_path(@project, content_commit.id), :class => "tree-commit-link"
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
%table
|
||||
- @blame.each do |commit, lines|
|
||||
- commit = Commit.new(commit)
|
||||
- commit = CommitDecorator.decorate(commit)
|
||||
%tr
|
||||
%td.author
|
||||
= image_tag gravatar_icon(commit.author_email, 16)
|
||||
= commit.author_name
|
||||
%td.blame_commit
|
||||
|
||||
= link_to project_commit_path(@project, :id => commit.id) do
|
||||
%code= commit.id.to_s[0..10]
|
||||
%span.row_title= truncate(commit.safe_message, :length => 30) rescue "--broken encoding"
|
||||
%code= link_to commit.short_id, project_commit_path(@project, :id => commit.id)
|
||||
= link_to truncate(commit.title, :length => 30), project_commit_path(@project, :id => commit.id), :class => "row_title" rescue "--broken encoding"
|
||||
%td.lines
|
||||
= preserve do
|
||||
%pre
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
- commit = Commit.new(branch.commit)
|
||||
- commit = CommitDecorator.decorate(commit)
|
||||
%tr
|
||||
%td
|
||||
= link_to project_commits_path(@project, :ref => branch.name) do
|
||||
|
@ -5,14 +7,14 @@
|
|||
- if branch.name == @project.root_ref
|
||||
%span.label default
|
||||
%td
|
||||
= link_to project_commit_path(@project, :id => branch.commit.id) do
|
||||
%code= branch.commit.id.to_s[0..10]
|
||||
= link_to project_commit_path(@project, :id => commit.id) do
|
||||
%code= commit.short_id
|
||||
|
||||
= image_tag gravatar_icon(Commit.new(branch.commit).author_email), :class => "", :width => 16
|
||||
= truncate(Commit.new(branch.commit).safe_message, :length => 40)
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||
= truncate(commit.title, :length => 40)
|
||||
%td
|
||||
%span.update-author.right
|
||||
= time_ago_in_words(branch.commit.committed_date)
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
ago
|
||||
%td
|
||||
- if can? current_user, :download_code, @project
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
- commit = update
|
||||
- commit = CommitDecorator.new(commit)
|
||||
%tr
|
||||
%td
|
||||
= link_to project_commits_path(@project, :ref => commit.head.name) do
|
||||
|
@ -10,9 +11,9 @@
|
|||
%td
|
||||
%div
|
||||
= link_to project_commits_path(@project, commit.id) do
|
||||
%code= commit.id.to_s[0..10]
|
||||
%code= commit.short_id
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||
= truncate(commit.safe_message, :length => 40)
|
||||
= truncate(commit.title, :length => 40)
|
||||
%td
|
||||
%span.right.cgray
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
|
|
|
@ -9,14 +9,15 @@
|
|||
%th
|
||||
- @tags.each do |tag|
|
||||
- commit = Commit.new(tag.commit)
|
||||
- commit = CommitDecorator.decorate(commit)
|
||||
%tr
|
||||
%td
|
||||
%strong= link_to tag.name, project_commits_path(@project, :ref => tag.name), :class => ""
|
||||
%td
|
||||
= link_to project_commit_path(@project, commit.id) do
|
||||
%code= commit.id.to_s[0..10]
|
||||
%code= commit.short_id
|
||||
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||
= truncate(commit.safe_message, :length => 40)
|
||||
= truncate(commit.title, :length => 40)
|
||||
%td
|
||||
%span.update-author.right
|
||||
= time_ago_in_words(commit.committed_date)
|
||||
|
|
|
@ -6,19 +6,21 @@
|
|||
- @wiki.errors.full_messages.each do |msg|
|
||||
%li= msg
|
||||
|
||||
.alert-message.block-message.warning
|
||||
%p
|
||||
Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
|
||||
%br
|
||||
To add link to new page you can just type
|
||||
%code [Link Title](page-slug)
|
||||
.clearfix
|
||||
= f.label :title
|
||||
.input= f.text_field :title, :class => :xxlarge
|
||||
= f.hidden_field :slug
|
||||
.clearfix
|
||||
= f.label :content
|
||||
.input= f.text_area :content, :class => :xxlarge
|
||||
.main_box
|
||||
.top_box_content
|
||||
= f.label :title
|
||||
.input= f.text_field :title, :class => 'span8'
|
||||
= f.hidden_field :slug
|
||||
.middle_box_content
|
||||
.input
|
||||
%span.cgray
|
||||
Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
|
||||
To add link to new page you can just type
|
||||
%code [Link Title](page-slug)
|
||||
|
||||
.bottom_box_content
|
||||
= f.label :content
|
||||
.input= f.text_area :content, :class => 'span8'
|
||||
.actions
|
||||
= f.submit 'Save', :class => "primary btn"
|
||||
= link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
%h3 Editing page
|
||||
%h3.page_title Editing page
|
||||
%hr
|
||||
= render 'form'
|
||||
|
|
4
app/views/wikis/empty.html.haml
Normal file
4
app/views/wikis/empty.html.haml
Normal file
|
@ -0,0 +1,4 @@
|
|||
%h3.page_title Empty page
|
||||
%hr
|
||||
.alert-message.block-message.warning
|
||||
%span You are not allowed to create wiki pages
|
|
@ -1,5 +1,6 @@
|
|||
%h3 Versions
|
||||
%table
|
||||
%h3.page_title Versions
|
||||
%br
|
||||
%table.admin-table
|
||||
%thead
|
||||
%tr
|
||||
%th #
|
||||
|
|
|
@ -5,13 +5,18 @@
|
|||
= link_to history_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
||||
History
|
||||
= link_to edit_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
||||
%i.icon-edit
|
||||
Edit
|
||||
%hr
|
||||
.wiki_content
|
||||
= preserve do
|
||||
= markdown @wiki.content
|
||||
%br
|
||||
.file_holder
|
||||
.file_content.wiki
|
||||
= preserve do
|
||||
= markdown @wiki.content
|
||||
|
||||
%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago
|
||||
- if can? current_user, :admin_wiki, @project
|
||||
= link_to project_wiki_path(@project, @wiki), :confirm => "Are you sure you want to delete this page?", :method => :delete do
|
||||
Delete this page
|
||||
|
||||
%hr
|
||||
.wiki_notes#notes= render "notes/notes", :tid => @wiki.id, :tt => "wiki"
|
||||
|
|
|
@ -27,3 +27,4 @@ The API uses JSON to serialize data. You don't need to specify `.json` at the en
|
|||
|
||||
+ [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
|
||||
+ [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md)
|
||||
+ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md)
|
||||
|
|
184
doc/api/issues.md
Normal file
184
doc/api/issues.md
Normal file
|
@ -0,0 +1,184 @@
|
|||
## List issues
|
||||
|
||||
Get all issues created by authenticed user.
|
||||
|
||||
```
|
||||
GET /issues
|
||||
```
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 43,
|
||||
"project_id": 8,
|
||||
"title": "4xx/5xx pages",
|
||||
"description": "",
|
||||
"labels": [ ],
|
||||
"milestone": null,
|
||||
"assignee": null,
|
||||
"author": {
|
||||
"id": 1,
|
||||
"email": "john@example.com",
|
||||
"name": "John Smith",
|
||||
"blocked": false,
|
||||
"created_at": "2012-05-23T08:00:58Z"
|
||||
},
|
||||
"closed": true,
|
||||
"updated_at": "2012-07-02T17:53:12Z",
|
||||
"created_at": "2012-07-02T17:53:12Z"
|
||||
},
|
||||
{
|
||||
"id": 42,
|
||||
"project_id": 8,
|
||||
"title": "Add user settings",
|
||||
"description": "",
|
||||
"labels": [
|
||||
"feature"
|
||||
],
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "v1.0",
|
||||
"description": "",
|
||||
"due_date": "2012-07-20",
|
||||
"closed": false,
|
||||
"updated_at": "2012-07-04T13:42:48Z",
|
||||
"created_at": "2012-07-04T13:42:48Z"
|
||||
},
|
||||
"assignee": {
|
||||
"id": 2,
|
||||
"email": "jack@example.com",
|
||||
"name": "Jack Smith",
|
||||
"blocked": false,
|
||||
"created_at": "2012-05-23T08:01:01Z"
|
||||
},
|
||||
"author": {
|
||||
"id": 1,
|
||||
"email": "john@example.com",
|
||||
"name": "John Smith",
|
||||
"blocked": false,
|
||||
"created_at": "2012-05-23T08:00:58Z"
|
||||
},
|
||||
"closed": false,
|
||||
"updated_at": "2012-07-12T13:43:19Z",
|
||||
"created_at": "2012-06-28T12:58:06Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## List project issues
|
||||
|
||||
Get a list of project issues.
|
||||
|
||||
```
|
||||
GET /projects/:id/issues
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
|
||||
## Single issue
|
||||
|
||||
Get a project issue.
|
||||
|
||||
```
|
||||
GET /projects/:id/issues/:issue_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `issue_id` (required) - The ID of a project issue
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 42,
|
||||
"project_id": 8,
|
||||
"title": "Add user settings",
|
||||
"description": "",
|
||||
"labels": [
|
||||
"feature"
|
||||
],
|
||||
"milestone": {
|
||||
"id": 1,
|
||||
"title": "v1.0",
|
||||
"description": "",
|
||||
"due_date": "2012-07-20",
|
||||
"closed": false,
|
||||
"updated_at": "2012-07-04T13:42:48Z",
|
||||
"created_at": "2012-07-04T13:42:48Z"
|
||||
},
|
||||
"assignee": {
|
||||
"id": 2,
|
||||
"email": "jack@example.com",
|
||||
"name": "Jack Smith",
|
||||
"blocked": false,
|
||||
"created_at": "2012-05-23T08:01:01Z"
|
||||
},
|
||||
"author": {
|
||||
"id": 1,
|
||||
"email": "john@example.com",
|
||||
"name": "John Smith",
|
||||
"blocked": false,
|
||||
"created_at": "2012-05-23T08:00:58Z"
|
||||
},
|
||||
"closed": false,
|
||||
"updated_at": "2012-07-12T13:43:19Z",
|
||||
"created_at": "2012-06-28T12:58:06Z"
|
||||
}
|
||||
```
|
||||
|
||||
## New issue
|
||||
|
||||
Create a new project issue.
|
||||
|
||||
```
|
||||
POST /projects/:id/issues
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `title` (required) - The title of an issue
|
||||
+ `description` (optional) - The description of an issue
|
||||
+ `assignee_id` (optional) - The ID of a user to assign issue
|
||||
+ `milestone_id` (optional) - The ID of a milestone to assign issue
|
||||
+ `labels` (optional) - Comma-separated label names for an issue
|
||||
|
||||
Will return created issue with status `201 Created` on success, or `404 Not found` on fail.
|
||||
|
||||
## Edit issue
|
||||
|
||||
Update an existing project issue.
|
||||
|
||||
```
|
||||
PUT /projects/:id/issues/:issue_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `issue_id` (required) - The ID of a project's issue
|
||||
+ `title` (optional) - The title of an issue
|
||||
+ `description` (optional) - The description of an issue
|
||||
+ `assignee_id` (optional) - The ID of a user to assign issue
|
||||
+ `milestone_id` (optional) - The ID of a milestone to assign issue
|
||||
+ `labels` (optional) - Comma-separated label names for an issue
|
||||
+ `closed` (optional) - The state of an issue (0 = false, 1 = true)
|
||||
|
||||
Will return updated issue with status `200 OK` on success, or `404 Not found` on fail.
|
||||
|
||||
## Delete issue
|
||||
|
||||
Delete existing project issue.
|
||||
|
||||
```
|
||||
DELETE /projects/:id/issues/:issue_id
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `issue_id` (required) - The ID of a project's issue
|
||||
|
||||
Status code `200` will be returned on success.
|
|
@ -1,6 +1,6 @@
|
|||
## List projects
|
||||
|
||||
Get a list of authenticated users' projects.
|
||||
Get a list of authenticated user's projects.
|
||||
|
||||
```
|
||||
GET /projects
|
||||
|
@ -63,7 +63,7 @@ GET /projects/:id
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
|
||||
```json
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ Parameters:
|
|||
|
||||
## Project repository branches
|
||||
|
||||
Get a list of project repository branches.
|
||||
Get a list of project repository branches sorted by name alphabetically.
|
||||
|
||||
```
|
||||
GET /projects/:id/repository/branches
|
||||
|
@ -99,7 +99,7 @@ GET /projects/:id/repository/branches
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
|
||||
```json
|
||||
[
|
||||
|
@ -131,7 +131,7 @@ Parameters:
|
|||
|
||||
## Project repository tags
|
||||
|
||||
Get a list of project repository tags.
|
||||
Get a list of project repository tags sorted by name in reverse alphabetical order.
|
||||
|
||||
```
|
||||
GET /projects/:id/repository/tags
|
||||
|
@ -139,7 +139,7 @@ GET /projects/:id/repository/tags
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
|
||||
```json
|
||||
[
|
||||
|
@ -183,7 +183,7 @@ GET /projects/:id/snippets/:snippet_id
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `snippet_id` (required) - The ID of a project's snippet
|
||||
|
||||
```json
|
||||
|
@ -214,7 +214,7 @@ GET /projects/:id/snippets/:snippet_id/raw
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `snippet_id` (required) - The ID of a project's snippet
|
||||
|
||||
## New snippet
|
||||
|
@ -227,7 +227,7 @@ POST /projects/:id/snippets
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `title` (required) - The title of a snippet
|
||||
+ `file_name` (required) - The name of a snippet file
|
||||
+ `lifetime` (optional) - The expiration date of a snippet
|
||||
|
@ -245,7 +245,7 @@ PUT /projects/:id/snippets/:snippet_id
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `snippet_id` (required) - The ID of a project's snippet
|
||||
+ `title` (optional) - The title of a snippet
|
||||
+ `file_name` (optional) - The name of a snippet file
|
||||
|
@ -264,7 +264,7 @@ DELETE /projects/:id/snippets/:snippet_id
|
|||
|
||||
Parameters:
|
||||
|
||||
+ `id` (required) - The code name of a project
|
||||
+ `id` (required) - The ID or code name of a project
|
||||
+ `snippet_id` (required) - The ID of a project's snippet
|
||||
|
||||
Status code `200` will be returned on success.
|
||||
|
|
|
@ -119,6 +119,7 @@ Permissions:
|
|||
|
||||
sudo chmod -R g+rwX /home/git/repositories/
|
||||
sudo chown -R git:git /home/git/repositories/
|
||||
sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive
|
||||
|
||||
#### CHECK: Logout & login again to apply git group to your user
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ Given /^I click atom feed link$/ do
|
|||
end
|
||||
|
||||
Then /^I see commits atom feed$/ do
|
||||
commit = @project.commit
|
||||
commit = CommitDecorator.decorate(@project.commit)
|
||||
page.response_headers['Content-Type'].should have_content("application/atom+xml")
|
||||
page.body.should have_selector("title", :text => "Recent commits to #{@project.name}")
|
||||
page.body.should have_selector("author email", :text => commit.author_email)
|
||||
page.body.should have_selector("entry summary", :text => commit.message)
|
||||
page.body.should have_selector("entry summary", :text => commit.description)
|
||||
end
|
||||
|
||||
Given /^I click on commit link$/ do
|
||||
|
|
|
@ -15,5 +15,6 @@ module Gitlab
|
|||
|
||||
mount Users
|
||||
mount Projects
|
||||
mount Issues
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,11 +16,7 @@ module Gitlab
|
|||
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
|
||||
end
|
||||
|
||||
class ProjectRepositoryBranches < Grape::Entity
|
||||
expose :name, :commit
|
||||
end
|
||||
|
||||
class ProjectRepositoryTags < Grape::Entity
|
||||
class RepoObject < Grape::Entity
|
||||
expose :name, :commit
|
||||
end
|
||||
|
||||
|
@ -29,5 +25,19 @@ module Gitlab
|
|||
expose :author, :using => Entities::UserBasic
|
||||
expose :expires_at, :updated_at, :created_at
|
||||
end
|
||||
|
||||
class Milestone < Grape::Entity
|
||||
expose :id, :title, :description, :due_date, :closed, :updated_at, :created_at
|
||||
end
|
||||
|
||||
class Issue < Grape::Entity
|
||||
expose :id
|
||||
expose (:project_id) {|issue| issue.project.id}
|
||||
expose :title, :description
|
||||
expose :label_list, :as => :labels
|
||||
expose :milestone, :using => Entities::Milestone
|
||||
expose :assignee, :author, :using => Entities::UserBasic
|
||||
expose :closed, :updated_at, :created_at
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,16 @@ module Gitlab
|
|||
@current_user ||= User.find_by_authentication_token(params[:private_token])
|
||||
end
|
||||
|
||||
def user_project
|
||||
if @project ||= current_user.projects.find_by_id(params[:id]) ||
|
||||
current_user.projects.find_by_code(params[:id])
|
||||
else
|
||||
error!({'message' => '404 Not found'}, 404)
|
||||
end
|
||||
|
||||
@project
|
||||
end
|
||||
|
||||
def authenticate!
|
||||
error!({'message' => '401 Unauthorized'}, 401) unless current_user
|
||||
end
|
||||
|
|
111
lib/api/issues.rb
Normal file
111
lib/api/issues.rb
Normal file
|
@ -0,0 +1,111 @@
|
|||
module Gitlab
|
||||
# Issues API
|
||||
class Issues < Grape::API
|
||||
before { authenticate! }
|
||||
|
||||
resource :issues do
|
||||
# Get currently authenticated user's issues
|
||||
#
|
||||
# Example Request:
|
||||
# GET /issues
|
||||
get do
|
||||
present current_user.issues, :with => Entities::Issue
|
||||
end
|
||||
end
|
||||
|
||||
resource :projects do
|
||||
# Get a list of project issues
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID or code name of a project
|
||||
# Example Request:
|
||||
# GET /projects/:id/issues
|
||||
get ":id/issues" do
|
||||
present user_project.issues, :with => Entities::Issue
|
||||
end
|
||||
|
||||
# Get a single project issue
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID or code name of a project
|
||||
# issue_id (required) - The ID of a project issue
|
||||
# Example Request:
|
||||
# GET /projects/:id/issues/:issue_id
|
||||
get ":id/issues/:issue_id" do
|
||||
@issue = user_project.issues.find(params[:issue_id])
|
||||
present @issue, :with => Entities::Issue
|
||||
end
|
||||
|
||||
# Create a new project issue
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID or code name of a project
|
||||
# title (required) - The title of an issue
|
||||
# description (optional) - The description of an issue
|
||||
# assignee_id (optional) - The ID of a user to assign issue
|
||||
# milestone_id (optional) - The ID of a milestone to assign issue
|
||||
# labels (optional) - The labels of an issue
|
||||
# Example Request:
|
||||
# POST /projects/:id/issues
|
||||
post ":id/issues" do
|
||||
@issue = user_project.issues.new(
|
||||
:title => params[:title],
|
||||
:description => params[:description],
|
||||
:assignee_id => params[:assignee_id],
|
||||
:milestone_id => params[:milestone_id],
|
||||
:label_list => params[:labels]
|
||||
)
|
||||
@issue.author = current_user
|
||||
|
||||
if @issue.save
|
||||
present @issue, :with => Entities::Issue
|
||||
else
|
||||
error!({'message' => '404 Not found'}, 404)
|
||||
end
|
||||
end
|
||||
|
||||
# Update an existing issue
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID or code name of a project
|
||||
# issue_id (required) - The ID of a project issue
|
||||
# title (optional) - The title of an issue
|
||||
# description (optional) - The description of an issue
|
||||
# assignee_id (optional) - The ID of a user to assign issue
|
||||
# milestone_id (optional) - The ID of a milestone to assign issue
|
||||
# labels (optional) - The labels of an issue
|
||||
# closed (optional) - The state of an issue (0 = false, 1 = true)
|
||||
# Example Request:
|
||||
# PUT /projects/:id/issues/:issue_id
|
||||
put ":id/issues/:issue_id" do
|
||||
@issue = user_project.issues.find(params[:issue_id])
|
||||
parameters = {
|
||||
:title => (params[:title] || @issue.title),
|
||||
:description => (params[:description] || @issue.description),
|
||||
:assignee_id => (params[:assignee_id] || @issue.assignee_id),
|
||||
:milestone_id => (params[:milestone_id] || @issue.milestone_id),
|
||||
:label_list => (params[:labels] || @issue.label_list),
|
||||
:closed => (params[:closed] || @issue.closed)
|
||||
}
|
||||
|
||||
if @issue.update_attributes(parameters)
|
||||
present @issue, :with => Entities::Issue
|
||||
else
|
||||
error!({'message' => '404 Not found'}, 404)
|
||||
end
|
||||
end
|
||||
|
||||
# Delete a project issue
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The ID or code name of a project
|
||||
# issue_id (required) - The ID of a project issue
|
||||
# Example Request:
|
||||
# DELETE /projects/:id/issues/:issue_id
|
||||
delete ":id/issues/:issue_id" do
|
||||
@issue = user_project.issues.find(params[:issue_id])
|
||||
@issue.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,53 +16,49 @@ module Gitlab
|
|||
# Get a single project
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# Example Request:
|
||||
# GET /projects/:id
|
||||
get ":id" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
present @project, :with => Entities::Project
|
||||
present user_project, :with => Entities::Project
|
||||
end
|
||||
|
||||
# Get a project repository branches
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# Example Request:
|
||||
# GET /projects/:id/repository/branches
|
||||
get ":id/repository/branches" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches
|
||||
present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject
|
||||
end
|
||||
|
||||
# Get a project repository tags
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# Example Request:
|
||||
# GET /projects/:id/repository/tags
|
||||
get ":id/repository/tags" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags
|
||||
present user_project.repo.tags.sort_by(&:name).reverse, :with => Entities::RepoObject
|
||||
end
|
||||
|
||||
# Get a project snippet
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# snippet_id (required) - The ID of a project snippet
|
||||
# Example Request:
|
||||
# GET /projects/:id/snippets/:snippet_id
|
||||
get ":id/snippets/:snippet_id" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
@snippet = @project.snippets.find(params[:snippet_id])
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
present @snippet, :with => Entities::ProjectSnippet
|
||||
end
|
||||
|
||||
# Create a new project snippet
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code name of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# title (required) - The title of a snippet
|
||||
# file_name (required) - The name of a snippet file
|
||||
# lifetime (optional) - The expiration date of a snippet
|
||||
|
@ -70,8 +66,7 @@ module Gitlab
|
|||
# Example Request:
|
||||
# POST /projects/:id/snippets
|
||||
post ":id/snippets" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
@snippet = @project.snippets.new(
|
||||
@snippet = user_project.snippets.new(
|
||||
:title => params[:title],
|
||||
:file_name => params[:file_name],
|
||||
:expires_at => params[:lifetime],
|
||||
|
@ -89,7 +84,7 @@ module Gitlab
|
|||
# Update an existing project snippet
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code name of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# snippet_id (required) - The ID of a project snippet
|
||||
# title (optional) - The title of a snippet
|
||||
# file_name (optional) - The name of a snippet file
|
||||
|
@ -98,8 +93,7 @@ module Gitlab
|
|||
# Example Request:
|
||||
# PUT /projects/:id/snippets/:snippet_id
|
||||
put ":id/snippets/:snippet_id" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
@snippet = @project.snippets.find(params[:snippet_id])
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
parameters = {
|
||||
:title => (params[:title] || @snippet.title),
|
||||
:file_name => (params[:file_name] || @snippet.file_name),
|
||||
|
@ -117,26 +111,24 @@ module Gitlab
|
|||
# Delete a project snippet
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# snippet_id (required) - The ID of a project snippet
|
||||
# Example Request:
|
||||
# DELETE /projects/:id/snippets/:snippet_id
|
||||
delete ":id/snippets/:snippet_id" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
@snippet = @project.snippets.find(params[:snippet_id])
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
@snippet.destroy
|
||||
end
|
||||
|
||||
# Get a raw project snippet
|
||||
#
|
||||
# Parameters:
|
||||
# id (required) - The code of a project
|
||||
# id (required) - The ID or code name of a project
|
||||
# snippet_id (required) - The ID of a project snippet
|
||||
# Example Request:
|
||||
# GET /projects/:id/snippets/:snippet_id/raw
|
||||
get ":id/snippets/:snippet_id/raw" do
|
||||
@project = current_user.projects.find_by_code(params[:id])
|
||||
@snippet = @project.snippets.find(params[:snippet_id])
|
||||
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||
present @snippet.content
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ module Gitlab
|
|||
|
||||
def self.read_latest
|
||||
path = Rails.root.join("log/githost.log")
|
||||
self.build unless File.exist?(path)
|
||||
logs = File.read(path).split("\n")
|
||||
end
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace :gitlab do
|
|||
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
||||
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
|
||||
puts "Dumping repositories:"
|
||||
project = Project.all.map { |n| [n.name,n.path_to_repo] }
|
||||
project = Project.all.map { |n| [n.path,n.path_to_repo] }
|
||||
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
|
||||
project.each do |project|
|
||||
print "- Dumping repository #{project.first}... "
|
||||
|
@ -136,12 +136,18 @@ namespace :gitlab do
|
|||
task :repo_restore => :environment do
|
||||
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
||||
puts "Restoring repositories:"
|
||||
project = Project.all.map { |n| [n.name,n.path_to_repo] }
|
||||
project = Project.all.map { |n| [n.path,n.path_to_repo] }
|
||||
project << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
|
||||
project.each do |project|
|
||||
print "- Restoring repository #{project.first}... "
|
||||
FileUtils.rm_rf(project.second) if File.dirname(project.second) # delet old stuff
|
||||
if Kernel.system("cd #{File.dirname(project.second)} > /dev/null 2>&1 && git clone --bare #{backup_path_repo}/#{project.first}.bundle #{project.first}.git > /dev/null 2>&1")
|
||||
permission_commands = [
|
||||
"sudo chmod -R g+rwX #{Gitlab.config.git_base_path}",
|
||||
"sudo chown -R #{Gitlab.config.ssh_user}:#{Gitlab.config.ssh_user} #{Gitlab.config.git_base_path}",
|
||||
"sudo chown gitlab:gitlab /home/git/repositories/**/hooks/post-receive"
|
||||
]
|
||||
permission_commands.each { |command| Kernel.system(command) }
|
||||
puts "[DONE]".green
|
||||
else
|
||||
puts "[FAILED]".red
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace :gitlab do
|
|||
namespace :app do
|
||||
desc "GITLAB | Check gitlab installation status"
|
||||
task :status => :environment do
|
||||
puts "Starting diagnostic"
|
||||
puts "Starting diagnostic".yellow
|
||||
git_base_path = Gitlab.config.git_base_path
|
||||
|
||||
print "config/database.yml............"
|
||||
|
@ -56,7 +56,28 @@ namespace :gitlab do
|
|||
return
|
||||
end
|
||||
|
||||
puts "\nFinished"
|
||||
if Project.count > 0
|
||||
puts "Validating projects repositories:".yellow
|
||||
Project.find_each(:batch_size => 100) do |project|
|
||||
print "#{project.name}....."
|
||||
hook_file = File.join(project.path_to_repo, 'hooks','post-receive')
|
||||
|
||||
unless File.exists?(hook_file)
|
||||
puts "post-receive file missing".red
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
unless File.owned?(hook_file)
|
||||
puts "post-receive file is not owner by gitlab".red
|
||||
next
|
||||
end
|
||||
|
||||
puts "post-reveice file ok".green
|
||||
end
|
||||
end
|
||||
|
||||
puts "\nFinished".blue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
71
spec/api/issues_spec.rb
Normal file
71
spec/api/issues_spec.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::API do
|
||||
let(:user) { Factory :user }
|
||||
let!(:project) { Factory :project, :owner => user }
|
||||
let!(:issue) { Factory :issue, :author => user, :assignee => user, :project => project }
|
||||
before { project.add_access(user, :read) }
|
||||
|
||||
describe "GET /issues" do
|
||||
it "should return authentication error" do
|
||||
get "#{api_prefix}/issues"
|
||||
response.status.should == 401
|
||||
end
|
||||
|
||||
describe "authenticated GET /issues" do
|
||||
it "should return an array of issues" do
|
||||
get "#{api_prefix}/issues?private_token=#{user.private_token}"
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['title'].should == issue.title
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/issues" do
|
||||
it "should return project issues" do
|
||||
get "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}"
|
||||
response.status.should == 200
|
||||
json_response.should be_an Array
|
||||
json_response.first['title'].should == issue.title
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/issues/:issue_id" do
|
||||
it "should return a project issue by id" do
|
||||
get "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
|
||||
response.status.should == 200
|
||||
json_response['title'].should == issue.title
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /projects/:id/issues" do
|
||||
it "should create a new project issue" do
|
||||
post "#{api_prefix}/projects/#{project.code}/issues?private_token=#{user.private_token}",
|
||||
:title => 'new issue', :labels => 'label, label2'
|
||||
response.status.should == 201
|
||||
json_response['title'].should == 'new issue'
|
||||
json_response['description'].should be_nil
|
||||
json_response['labels'].should == ['label', 'label2']
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /projects/:id/issues/:issue_id" do
|
||||
it "should update a project issue" do
|
||||
put "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}",
|
||||
:title => 'updated title', :labels => 'label2', :closed => 1
|
||||
response.status.should == 200
|
||||
json_response['title'].should == 'updated title'
|
||||
json_response['labels'].should == ['label2']
|
||||
json_response['closed'].should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /projects/:id/issues/:issue_id" do
|
||||
it "should delete a project issue" do
|
||||
expect {
|
||||
delete "#{api_prefix}/projects/#{project.code}/issues/#{issue.id}?private_token=#{user.private_token}"
|
||||
}.to change { Issue.count }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,11 +25,23 @@ describe Gitlab::API do
|
|||
|
||||
describe "GET /projects/:id" do
|
||||
it "should return a project by id" do
|
||||
get "#{api_prefix}/projects/#{project.code}?private_token=#{user.private_token}"
|
||||
get "#{api_prefix}/projects/#{project.id}?private_token=#{user.private_token}"
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project.name
|
||||
json_response['owner']['email'].should == user.email
|
||||
end
|
||||
|
||||
it "should return a project by code name" do
|
||||
get "#{api_prefix}/projects/#{project.code}?private_token=#{user.private_token}"
|
||||
response.status.should == 200
|
||||
json_response['name'].should == project.name
|
||||
end
|
||||
|
||||
it "should return a 404 error if not found" do
|
||||
get "#{api_prefix}/projects/42?private_token=#{user.private_token}"
|
||||
response.status.should == 404
|
||||
json_response['message'].should == '404 Not found'
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /projects/:id/repository/branches" do
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
describe "Commits" do
|
||||
let(:project) { Factory :project }
|
||||
let!(:commit) { project.commit }
|
||||
let!(:commit) { CommitDecorator.decorate(project.commit) }
|
||||
before do
|
||||
login_as :user
|
||||
project.add_access(@user, :read)
|
||||
|
@ -22,8 +22,8 @@ describe "Commits" do
|
|||
end
|
||||
|
||||
it "should list commits" do
|
||||
page.should have_content(commit.message)
|
||||
page.should have_content(commit.id.to_s[0..5])
|
||||
page.should have_content(commit.description)
|
||||
page.should have_content(commit.short_id(8))
|
||||
end
|
||||
|
||||
it "should render atom feed" do
|
||||
|
@ -32,7 +32,7 @@ describe "Commits" do
|
|||
page.response_headers['Content-Type'].should have_content("application/atom+xml")
|
||||
page.body.should have_selector("title", :text => "Recent commits to #{project.name}")
|
||||
page.body.should have_selector("author email", :text => commit.author_email)
|
||||
page.body.should have_selector("entry summary", :text => commit.message)
|
||||
page.body.should have_selector("entry summary", :text => commit.description)
|
||||
end
|
||||
|
||||
it "should render atom feed via private token" do
|
||||
|
@ -42,7 +42,7 @@ describe "Commits" do
|
|||
page.response_headers['Content-Type'].should have_content("application/atom+xml")
|
||||
page.body.should have_selector("title", :text => "Recent commits to #{project.name}")
|
||||
page.body.should have_selector("author email", :text => commit.author_email)
|
||||
page.body.should have_selector("entry summary", :text => commit.message)
|
||||
page.body.should have_selector("entry summary", :text => commit.description)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
29
spec/requests/wikis_notes_spec.rb
Normal file
29
spec/requests/wikis_notes_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Wikis" do
|
||||
let(:project) { Factory :project }
|
||||
|
||||
before do
|
||||
login_as :user
|
||||
project.add_access(@user, :read, :write)
|
||||
end
|
||||
|
||||
describe "add new note", :js => true do
|
||||
before do
|
||||
visit project_wiki_path(project, :index)
|
||||
|
||||
fill_in "Title", :with => 'Test title'
|
||||
fill_in "Content", :with => '[link test](test)'
|
||||
click_on "Save"
|
||||
|
||||
page.should have_content("Test title")
|
||||
|
||||
fill_in "note_note", :with => "Comment on wiki!"
|
||||
click_button "Add Comment"
|
||||
end
|
||||
|
||||
it "should contain the new note" do
|
||||
page.should have_content("Comment on wiki!")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue