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 "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
|
||||||
gem "gitolite", :git => "https://github.com/gitlabhq/gitolite-client.git", :ref => "9b715ca8bab6529f6c92204a25f84d12f25a6eb0"
|
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 "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 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
|
||||||
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
|
gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
|
||||||
gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git"
|
gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git"
|
||||||
|
|
|
@ -42,8 +42,8 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
remote: https://github.com/gitlabhq/omniauth-ldap.git
|
||||||
revision: 7edf27d0281e09561838122982c16b7e62181f44
|
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||||
ref: 7edf27d0281e09561838122982c16b7e62181f44
|
ref: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
|
||||||
specs:
|
specs:
|
||||||
omniauth-ldap (1.0.2)
|
omniauth-ldap (1.0.2)
|
||||||
net-ldap (~> 0.2.2)
|
net-ldap (~> 0.2.2)
|
||||||
|
|
|
@ -33,7 +33,7 @@ init:
|
||||||
})
|
})
|
||||||
|
|
||||||
$("#note_note").live("focus", function(){
|
$("#note_note").live("focus", function(){
|
||||||
$(this).css("height", "100px");
|
$(this).css("height", "80px");
|
||||||
$('.note_advanced_opts').show();
|
$('.note_advanced_opts').show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ var Pager = {
|
||||||
this.limit=limit;
|
this.limit=limit;
|
||||||
this.offset=limit;
|
this.offset=limit;
|
||||||
this.initLoadMore();
|
this.initLoadMore();
|
||||||
$('.loading').show();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getOld:
|
getOld:
|
||||||
|
|
|
@ -337,6 +337,15 @@ p.time {
|
||||||
padding: 15px 5px;
|
padding: 15px 5px;
|
||||||
&:last-child { border:none }
|
&:last-child { border:none }
|
||||||
.wll:hover { background:none }
|
.wll:hover { background:none }
|
||||||
|
|
||||||
|
.event_commits {
|
||||||
|
margin-top: 5px;
|
||||||
|
|
||||||
|
li.commit {
|
||||||
|
padding:5px;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ico {
|
.ico {
|
||||||
|
|
|
@ -18,7 +18,8 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.lined {
|
&.lined {
|
||||||
text-decoration:underlined;
|
text-decoration:underline;
|
||||||
|
&:hover { text-decoration:underline; }
|
||||||
}
|
}
|
||||||
|
|
||||||
&.gray {
|
&.gray {
|
||||||
|
@ -74,10 +75,6 @@ h5 {
|
||||||
font-size:14px;
|
font-size:14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
|
||||||
background:#FCEEC1;
|
|
||||||
color:$style_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
table {
|
||||||
width:100%;
|
width:100%;
|
||||||
|
@ -381,7 +378,6 @@ form {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
cursor:pointer;
|
|
||||||
&.smoke {
|
&.smoke {
|
||||||
background-color:#f5f5f5;
|
background-color:#f5f5f5;
|
||||||
}
|
}
|
||||||
|
@ -516,7 +512,8 @@ form {
|
||||||
.row_title {
|
.row_title {
|
||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
color:#444;
|
color:#444;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
color:#444;
|
||||||
text-decoration:underline;
|
text-decoration:underline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
border-bottom:1px solid #aaa;
|
border-bottom:1px solid #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issue_notes {
|
.issue_notes,
|
||||||
|
.wiki_notes {
|
||||||
.note_content {
|
.note_content {
|
||||||
float:left;
|
float:left;
|
||||||
width:400px;
|
width:400px;
|
||||||
|
@ -23,8 +24,8 @@
|
||||||
|
|
||||||
/* Note textare */
|
/* Note textare */
|
||||||
#note_note {
|
#note_note {
|
||||||
height:100px;
|
height:80px;
|
||||||
width:97%;
|
width:99%;
|
||||||
font-size:14px;
|
font-size:14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +100,25 @@ tr.line_notes_row {
|
||||||
td {
|
td {
|
||||||
border-bottom:1px solid #ddd;
|
border-bottom:1px solid #ddd;
|
||||||
}
|
}
|
||||||
.actions {
|
.note_actions {
|
||||||
margin:0;
|
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;
|
float:right;
|
||||||
@extend .cgray;
|
@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 {
|
.issue {
|
||||||
padding:7px 10px;
|
padding:7px 10px;
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding-top:0;
|
||||||
|
padding-bottom:2px;
|
||||||
|
}
|
||||||
|
|
||||||
img.avatar {
|
img.avatar {
|
||||||
width:32px;
|
width:32px;
|
||||||
margin-top:4px;
|
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)
|
then project.issues.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
||||||
when "merge_request"
|
when "merge_request"
|
||||||
then project.merge_requests.find(target_id).notes.inc_author.order("created_at DESC").limit(20)
|
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
|
end
|
||||||
|
|
||||||
@notes = if last_id
|
@notes = if last_id
|
||||||
|
|
|
@ -17,6 +17,7 @@ class CommitsController < ApplicationController
|
||||||
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
|
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
|
||||||
|
|
||||||
@commits = @project.commits(@ref, params[:path], @limit, @offset)
|
@commits = @project.commits(@ref, params[:path], @limit, @offset)
|
||||||
|
@commits = CommitDecorator.decorate(@commits)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # index.html.erb
|
format.html # index.html.erb
|
||||||
|
@ -51,6 +52,8 @@ class CommitsController < ApplicationController
|
||||||
@commit = result[:commit]
|
@commit = result[:commit]
|
||||||
@diffs = result[:diffs]
|
@diffs = result[:diffs]
|
||||||
@line_notes = []
|
@line_notes = []
|
||||||
|
|
||||||
|
@commits = CommitDecorator.decorate(@commits)
|
||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
|
|
|
@ -143,5 +143,6 @@ class MergeRequestsController < ApplicationController
|
||||||
# Get commits from repository
|
# Get commits from repository
|
||||||
# or from cache if already merged
|
# or from cache if already merged
|
||||||
@commits = @merge_request.commits
|
@commits = @merge_request.commits
|
||||||
|
@commits = CommitDecorator.decorate(@commits)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,13 +3,10 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
# Extend the standard message generation to accept our custom exception
|
# Extend the standard message generation to accept our custom exception
|
||||||
def failure_message
|
def failure_message
|
||||||
exception = env["omniauth.error"]
|
exception = env["omniauth.error"]
|
||||||
if exception.class == OmniAuth::Error
|
error = exception.error_reason if exception.respond_to?(:error_reason)
|
||||||
error = exception.message
|
error ||= exception.error if exception.respond_to?(:error)
|
||||||
else
|
error ||= exception.message if exception.respond_to?(:message)
|
||||||
error = exception.error_reason if exception.respond_to?(:error_reason)
|
error ||= env["omniauth.error.type"].to_s
|
||||||
error ||= exception.error if exception.respond_to?(:error)
|
|
||||||
error ||= env["omniauth.error.type"].to_s
|
|
||||||
end
|
|
||||||
error.to_s.humanize if error
|
error.to_s.humanize if error
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,8 @@ class RefsController < ApplicationController
|
||||||
@logs = contents.map do |content|
|
@logs = contents.map do |content|
|
||||||
file = params[:path] ? File.join(params[:path], content.name) : content.name
|
file = params[:path] ? File.join(params[:path], content.name) : content.name
|
||||||
last_commit = @project.commits(@commit.id, file, 1).last
|
last_commit = @project.commits(@commit.id, file, 1).last
|
||||||
{
|
last_commit = CommitDecorator.decorate(last_commit)
|
||||||
|
{
|
||||||
:file_name => content.name,
|
:file_name => content.name,
|
||||||
:commit => last_commit
|
:commit => last_commit
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ class WikisController < ApplicationController
|
||||||
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
|
@wiki = @project.wikis.where(:slug => params[:id]).order("created_at").last
|
||||||
end
|
end
|
||||||
|
|
||||||
unless @wiki
|
@note = @project.notes.new(:noteable => @wiki)
|
||||||
return render_404 unless can?(current_user, :write_wiki, @project)
|
|
||||||
end
|
|
||||||
|
|
||||||
respond_to do |format|
|
if @wiki
|
||||||
if @wiki
|
render 'show'
|
||||||
format.html
|
else
|
||||||
else
|
if can?(current_user, :write_wiki, @project)
|
||||||
@wiki = @project.wikis.new(:slug => params[:id])
|
@wiki = @project.wikis.new(:slug => params[:id])
|
||||||
format.html { render "edit" }
|
render 'edit'
|
||||||
|
else
|
||||||
|
render 'empty'
|
||||||
end
|
end
|
||||||
end
|
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} ")
|
mail(:to => recipient.email, :subject => "gitlab | note for issue #{@issue.id} | #{@note.project_name} ")
|
||||||
end
|
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)
|
def new_merge_request_email(merge_request_id)
|
||||||
@merge_request = MergeRequest.find(merge_request_id)
|
@merge_request = MergeRequest.find(merge_request_id)
|
||||||
mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ")
|
mail(:to => @merge_request.assignee_email, :subject => "gitlab | new merge request | #{@merge_request.title} ")
|
||||||
|
|
|
@ -114,6 +114,10 @@ class Commit
|
||||||
@head = head
|
@head = head
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def short_id(length = 10)
|
||||||
|
id.to_s[0..length]
|
||||||
|
end
|
||||||
|
|
||||||
def safe_message
|
def safe_message
|
||||||
utf8 message
|
utf8 message
|
||||||
end
|
end
|
||||||
|
@ -150,4 +154,8 @@ class Commit
|
||||||
def prev_commit_id
|
def prev_commit_id
|
||||||
prev_commit.try :id
|
prev_commit.try :id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parents_count
|
||||||
|
parents && parents.count || 0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
class Wiki < ActiveRecord::Base
|
class Wiki < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
has_many :notes, :as => :noteable, :dependent => :destroy
|
||||||
|
|
||||||
validates :content, :title, :user_id, :presence => true
|
validates :content, :title, :user_id, :presence => true
|
||||||
validates :title, :length => 1..250
|
validates :title, :length => 1..250
|
||||||
|
|
|
@ -34,6 +34,7 @@ class MailerObserver < ActiveRecord::Observer
|
||||||
case note.noteable_type
|
case note.noteable_type
|
||||||
when "Commit"; Notify.note_commit_email(u.id, note.id).deliver
|
when "Commit"; Notify.note_commit_email(u.id, note.id).deliver
|
||||||
when "Issue"; Notify.note_issue_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 "MergeRequest"; Notify.note_merge_request_email(u.id, note.id).deliver
|
||||||
when "Snippet"; true
|
when "Snippet"; true
|
||||||
else
|
else
|
||||||
|
|
|
@ -2,16 +2,15 @@
|
||||||
.browse_code_link_holder
|
.browse_code_link_holder
|
||||||
%p
|
%p
|
||||||
%strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), :class => "right"
|
%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
|
||||||
%p
|
= link_to commit.short_id(8), project_commit_path(@project, :id => commit.id), :class => "commit_short_id"
|
||||||
%code.left= commit.id.to_s[0..10]
|
%strong.cgray= commit.author_name
|
||||||
%strong.cgray= commit.author_name
|
–
|
||||||
–
|
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||||
= 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.row_title= truncate(commit.safe_message, :length => 50)
|
|
||||||
|
|
||||||
%span.committed_ago
|
%span.committed_ago
|
||||||
= time_ago_in_words(commit.committed_date)
|
= time_ago_in_words(commit.committed_date)
|
||||||
ago
|
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
|
.commit-head
|
||||||
.right
|
.right
|
||||||
- if @notes_count > 0
|
- if @notes_count > 0
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
|
|
||||||
- unless @commits.empty?
|
- unless @commits.empty?
|
||||||
%h4 Commits (#{@commits.count})
|
%div.ui-box
|
||||||
%ul.unstyled= render @commits
|
%h5.small Commits (#{@commits.count})
|
||||||
|
%ul.unstyled= render @commits
|
||||||
|
|
||||||
- unless @diffs.empty?
|
- unless @diffs.empty?
|
||||||
%h4 Diff
|
%h4 Diff
|
||||||
|
|
|
@ -10,14 +10,14 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
||||||
xml.entry do
|
xml.entry do
|
||||||
xml.id project_commit_url(@project, :id => commit.id)
|
xml.id project_commit_url(@project, :id => commit.id)
|
||||||
xml.link :href => 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.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.media :thumbnail, :width => "40", :height => "40", :url => gravatar_icon(commit.author_email)
|
||||||
xml.author do |author|
|
xml.author do |author|
|
||||||
xml.name commit.author_name
|
xml.name commit.author_name
|
||||||
xml.email commit.author_email
|
xml.email commit.author_email
|
||||||
end
|
end
|
||||||
xml.summary commit.safe_message
|
xml.summary commit.description
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
Merge Requests
|
Merge Requests
|
||||||
%small (authored or assigned to you)
|
%small (authored by or assigned to you)
|
||||||
%small.right #{@merge_requests.total_count} merge requests
|
%small.right #{@merge_requests.total_count} merge requests
|
||||||
|
|
||||||
%br
|
%br
|
||||||
|
|
|
@ -1,19 +1,30 @@
|
||||||
.alert-message.block-message.error
|
.alert-message.block-message.error
|
||||||
%h3 Gitolite Error
|
%h3 Gitolite Error
|
||||||
%hr
|
|
||||||
%h4 Application cant get access to your gitolite system.
|
%h4 Application cant get access to your gitolite system.
|
||||||
%ol
|
|
||||||
%li
|
|
||||||
%p
|
|
||||||
Check 'config/gitlab.yml' for correct settings.
|
|
||||||
%li
|
%h4 Tips for Administrator:
|
||||||
%p
|
|
||||||
Make sure web server user has access to gitolite.
|
%ul
|
||||||
%a{:href => "https://github.com/gitlabhq/gitlabhq/wiki/Gitolite"} Setup tutorial
|
%li
|
||||||
%li
|
%p
|
||||||
%p
|
Check git logs in admin area
|
||||||
Try:
|
%li
|
||||||
|
%p
|
||||||
|
Check config/gitlab.yml for correct settings.
|
||||||
|
%li
|
||||||
|
%p
|
||||||
|
Diagnostic tool:
|
||||||
%pre
|
%pre
|
||||||
= preserve do
|
bundle exec rake gitlab:app:status RAILS_ENV=production
|
||||||
sudo chmod -R 770 /home/git/repositories/
|
%li
|
||||||
sudo chown -R git:git /home/git/repositories/
|
%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
|
%li.wll.commit
|
||||||
= link_to project_commit_path(project, :id => commit.id) do
|
%p
|
||||||
%p
|
= link_to commit.short_id(8), project_commit_path(project, :id => commit.id), :class => "commit_short_id"
|
||||||
%code.left= commit.id.to_s[0..10]
|
%strong.cdark= commit.author_name
|
||||||
%strong.cgray= commit.author_name
|
–
|
||||||
–
|
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
||||||
= image_tag gravatar_icon(commit.author_email), :class => "avatar", :width => 16
|
= truncate(commit.title, :length => 50) rescue "--broken encoding"
|
||||||
%span.row_title= truncate(commit.safe_message, :length => 50) rescue "--broken encoding"
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
%h3 API
|
%h3 API
|
||||||
.back_link
|
.back_link
|
||||||
= link_to help_path do
|
= link_to help_path do
|
||||||
← to index
|
← to index
|
||||||
%hr
|
%hr
|
||||||
|
|
||||||
%ol
|
%ol
|
||||||
%li
|
%li
|
||||||
%a{:href => "#README"} README
|
%a{:href => "#README"} README
|
||||||
%li
|
%li
|
||||||
%a{:href => "#projects"} Projects
|
%a{:href => "#projects"} Projects
|
||||||
%li
|
%li
|
||||||
%a{:href => "#users"} Users
|
%a{:href => "#users"} Users
|
||||||
|
%li
|
||||||
|
%a{:href => "#issues"} Issues
|
||||||
|
|
||||||
.file_holder#README
|
.file_holder#README
|
||||||
.file_title
|
.file_title
|
||||||
|
@ -39,3 +41,13 @@
|
||||||
.file_content.wiki
|
.file_content.wiki
|
||||||
= preserve do
|
= preserve do
|
||||||
= markdown File.read(Rails.root.join("doc", "api", "users.md"))
|
= 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 Push to non-protected branches
|
||||||
%li Remove non-protected branches
|
%li Remove non-protected branches
|
||||||
%li Add tags
|
%li Add tags
|
||||||
%li Create new merge request
|
|
||||||
%li Write a wiki
|
%li Write a wiki
|
||||||
|
|
||||||
.ui-box.span3
|
.ui-box.span3
|
||||||
|
@ -55,7 +54,6 @@
|
||||||
%li Push to non-protected branches
|
%li Push to non-protected branches
|
||||||
%li Remove non-protected branches
|
%li Remove non-protected branches
|
||||||
%li Add tags
|
%li Add tags
|
||||||
%li Create new merge request
|
|
||||||
%li Write a wiki
|
%li Write a wiki
|
||||||
%li Add new team members
|
%li Add new team members
|
||||||
%li Push to protected branches
|
%li Push to protected branches
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
- else
|
- else
|
||||||
= image_tag "no_avatar.png", :class => "avatar"
|
= image_tag "no_avatar.png", :class => "avatar"
|
||||||
|
|
||||||
= link_to project_issue_path(issue.project, issue) do
|
%p= link_to truncate(issue.title, :length => 100), project_issue_path(issue.project, issue), :class => "row_title"
|
||||||
%p.row_title= truncate(issue.title, :length => 100)
|
|
||||||
|
|
||||||
%span.update-author
|
%span.update-author
|
||||||
%small.cdark= "##{issue.id}"
|
%small.cdark= "##{issue.id}"
|
||||||
|
|
|
@ -46,9 +46,7 @@
|
||||||
- if @issue.milestone
|
- if @issue.milestone
|
||||||
- milestone = @issue.milestone
|
- milestone = @issue.milestone
|
||||||
%cite.cgray and attached to milestone
|
%cite.cgray and attached to milestone
|
||||||
= link_to project_milestone_path(milestone.project, milestone) do
|
%strong= link_to truncate(milestone.title, :length => 20), project_milestone_path(milestone.project, milestone)
|
||||||
%strong
|
|
||||||
= truncate(milestone.title, :length => 20)
|
|
||||||
|
|
||||||
.right
|
.right
|
||||||
- @issue.labels.each do |label|
|
- @issue.labels.each do |label|
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
= merge_request.target_branch
|
= merge_request.target_branch
|
||||||
= image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
|
= image_tag gravatar_icon(merge_request.author_email), :class => "avatar"
|
||||||
|
|
||||||
= link_to project_merge_request_path(merge_request.project, merge_request) do
|
%p= link_to truncate(merge_request.title, :length => 80), project_merge_request_path(merge_request.project, merge_request), :class => "row_title"
|
||||||
%p.row_title= truncate(merge_request.title, :length => 80)
|
|
||||||
|
|
||||||
%span.update-author
|
%span.update-author
|
||||||
%small.cdark= "##{merge_request.id}"
|
%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"
|
= 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
|
- 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 '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
|
||||||
%h4.row_title
|
= link_to truncate(milestone.title, :length => 100), project_milestone_path(milestone.project, milestone), :class => "row_title"
|
||||||
= truncate(milestone.title, :length => 100)
|
%small
|
||||||
%small
|
= milestone.expires_at
|
||||||
= milestone.expires_at
|
%br
|
||||||
%br
|
.progress.progress-success.span3
|
||||||
.progress.progress-success.span3
|
.bar{:style => "width: #{milestone.percent_complete}%;"}
|
||||||
.bar{:style => "width: #{milestone.percent_complete}%;"}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@
|
||||||
%td
|
%td
|
||||||
= link_to [@project, issue] do
|
= link_to [@project, issue] do
|
||||||
%span.badge.badge-info ##{issue.id}
|
%span.badge.badge-info ##{issue.id}
|
||||||
–
|
–
|
||||||
= truncate issue.title, :length => 60
|
= link_to truncate(issue.title, :length => 60), [@project, issue]
|
||||||
%br
|
%br
|
||||||
= paginate @issues, :theme => "gitlab"
|
= paginate @issues, :theme => "gitlab"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
||||||
%h3 Leave a comment
|
%h3.page_title Leave a comment
|
||||||
-if @note.errors.any?
|
-if @note.errors.any?
|
||||||
.alert-message.block-message.error
|
.alert-message.block-message.error
|
||||||
- @note.errors.full_messages.each do |msg|
|
- @note.errors.full_messages.each do |msg|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
%tr.per_line_form
|
%tr.per_line_form
|
||||||
%td{:colspan => 3 }
|
%td{:colspan => 3 }
|
||||||
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
= form_for [@project, @note], :remote => "true", :multipart => true do |f|
|
||||||
%h3 Leave a note
|
%h3.page_title Leave a note
|
||||||
%div.span10
|
%div.span10
|
||||||
-if @note.errors.any?
|
-if @note.errors.any?
|
||||||
.alert-message.block-message.error
|
.alert-message.block-message.error
|
||||||
|
@ -13,19 +13,21 @@
|
||||||
= f.hidden_field :noteable_type
|
= f.hidden_field :noteable_type
|
||||||
= f.hidden_field :line_code
|
= f.hidden_field :line_code
|
||||||
= f.text_area :note, :size => 255
|
= f.text_area :note, :size => 255
|
||||||
%h5 Notify via email:
|
.note_actions
|
||||||
.clearfix
|
.buttons
|
||||||
= label_tag :notify do
|
= f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
|
||||||
= check_box_tag :notify, 1, @note.noteable_type != "Commit"
|
= link_to "Cancel", "#", :class => "btn hide-button"
|
||||||
%span Project team
|
.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)
|
- if @note.notify_only_author?(current_user)
|
||||||
= label_tag :notify_author do
|
= label_tag :notify_author do
|
||||||
= check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
|
= check_box_tag :notify_author, 1 , @note.noteable_type == "Commit"
|
||||||
%span Commit author
|
%span Commit author
|
||||||
.actions
|
|
||||||
= f.submit 'Add note', :class => "btn primary submit_note", :id => "submit_note"
|
|
||||||
= link_to "Close", "#", :class => "btn hide-button"
|
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(function(){
|
$(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
|
ago
|
||||||
- else
|
- else
|
||||||
.alert-message.block-message
|
.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
|
- if tm
|
||||||
%strong= link_to "[#{tm.user_name}]", project_team_member_path(@project, 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
|
%table
|
||||||
- @blame.each do |commit, lines|
|
- @blame.each do |commit, lines|
|
||||||
- commit = Commit.new(commit)
|
- commit = Commit.new(commit)
|
||||||
|
- commit = CommitDecorator.decorate(commit)
|
||||||
%tr
|
%tr
|
||||||
%td.author
|
%td.author
|
||||||
= image_tag gravatar_icon(commit.author_email, 16)
|
= image_tag gravatar_icon(commit.author_email, 16)
|
||||||
= commit.author_name
|
= commit.author_name
|
||||||
%td.blame_commit
|
%td.blame_commit
|
||||||
|
|
||||||
= link_to project_commit_path(@project, :id => commit.id) do
|
%code= link_to commit.short_id, project_commit_path(@project, :id => commit.id)
|
||||||
%code= commit.id.to_s[0..10]
|
= link_to truncate(commit.title, :length => 30), project_commit_path(@project, :id => commit.id), :class => "row_title" rescue "--broken encoding"
|
||||||
%span.row_title= truncate(commit.safe_message, :length => 30) rescue "--broken encoding"
|
|
||||||
%td.lines
|
%td.lines
|
||||||
= preserve do
|
= preserve do
|
||||||
%pre
|
%pre
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
- commit = Commit.new(branch.commit)
|
||||||
|
- commit = CommitDecorator.decorate(commit)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= link_to project_commits_path(@project, :ref => branch.name) do
|
= link_to project_commits_path(@project, :ref => branch.name) do
|
||||||
|
@ -5,14 +7,14 @@
|
||||||
- if branch.name == @project.root_ref
|
- if branch.name == @project.root_ref
|
||||||
%span.label default
|
%span.label default
|
||||||
%td
|
%td
|
||||||
= link_to project_commit_path(@project, :id => branch.commit.id) do
|
= link_to project_commit_path(@project, :id => commit.id) do
|
||||||
%code= branch.commit.id.to_s[0..10]
|
%code= commit.short_id
|
||||||
|
|
||||||
= image_tag gravatar_icon(Commit.new(branch.commit).author_email), :class => "", :width => 16
|
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||||
= truncate(Commit.new(branch.commit).safe_message, :length => 40)
|
= truncate(commit.title, :length => 40)
|
||||||
%td
|
%td
|
||||||
%span.update-author.right
|
%span.update-author.right
|
||||||
= time_ago_in_words(branch.commit.committed_date)
|
= time_ago_in_words(commit.committed_date)
|
||||||
ago
|
ago
|
||||||
%td
|
%td
|
||||||
- if can? current_user, :download_code, @project
|
- if can? current_user, :download_code, @project
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
- commit = update
|
- commit = update
|
||||||
|
- commit = CommitDecorator.new(commit)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
= link_to project_commits_path(@project, :ref => commit.head.name) do
|
= link_to project_commits_path(@project, :ref => commit.head.name) do
|
||||||
|
@ -10,9 +11,9 @@
|
||||||
%td
|
%td
|
||||||
%div
|
%div
|
||||||
= link_to project_commits_path(@project, commit.id) do
|
= 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
|
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||||
= truncate(commit.safe_message, :length => 40)
|
= truncate(commit.title, :length => 40)
|
||||||
%td
|
%td
|
||||||
%span.right.cgray
|
%span.right.cgray
|
||||||
= time_ago_in_words(commit.committed_date)
|
= time_ago_in_words(commit.committed_date)
|
||||||
|
|
|
@ -9,14 +9,15 @@
|
||||||
%th
|
%th
|
||||||
- @tags.each do |tag|
|
- @tags.each do |tag|
|
||||||
- commit = Commit.new(tag.commit)
|
- commit = Commit.new(tag.commit)
|
||||||
|
- commit = CommitDecorator.decorate(commit)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%strong= link_to tag.name, project_commits_path(@project, :ref => tag.name), :class => ""
|
%strong= link_to tag.name, project_commits_path(@project, :ref => tag.name), :class => ""
|
||||||
%td
|
%td
|
||||||
= link_to project_commit_path(@project, commit.id) do
|
= 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
|
= image_tag gravatar_icon(commit.author_email), :class => "", :width => 16
|
||||||
= truncate(commit.safe_message, :length => 40)
|
= truncate(commit.title, :length => 40)
|
||||||
%td
|
%td
|
||||||
%span.update-author.right
|
%span.update-author.right
|
||||||
= time_ago_in_words(commit.committed_date)
|
= time_ago_in_words(commit.committed_date)
|
||||||
|
|
|
@ -6,19 +6,21 @@
|
||||||
- @wiki.errors.full_messages.each do |msg|
|
- @wiki.errors.full_messages.each do |msg|
|
||||||
%li= msg
|
%li= msg
|
||||||
|
|
||||||
.alert-message.block-message.warning
|
.main_box
|
||||||
%p
|
.top_box_content
|
||||||
Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
|
= f.label :title
|
||||||
%br
|
.input= f.text_field :title, :class => 'span8'
|
||||||
To add link to new page you can just type
|
= f.hidden_field :slug
|
||||||
%code [Link Title](page-slug)
|
.middle_box_content
|
||||||
.clearfix
|
.input
|
||||||
= f.label :title
|
%span.cgray
|
||||||
.input= f.text_field :title, :class => :xxlarge
|
Wiki content is parsed with #{link_to "Markdown", "http://en.wikipedia.org/wiki/Markdown"}.
|
||||||
= f.hidden_field :slug
|
To add link to new page you can just type
|
||||||
.clearfix
|
%code [Link Title](page-slug)
|
||||||
= f.label :content
|
|
||||||
.input= f.text_area :content, :class => :xxlarge
|
.bottom_box_content
|
||||||
|
= f.label :content
|
||||||
|
.input= f.text_area :content, :class => 'span8'
|
||||||
.actions
|
.actions
|
||||||
= f.submit 'Save', :class => "primary btn"
|
= f.submit 'Save', :class => "primary btn"
|
||||||
= link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"
|
= link_to "Cancel", project_wiki_path(@project, :index), :class => "btn"
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
%h3 Editing page
|
%h3.page_title Editing page
|
||||||
%hr
|
%hr
|
||||||
= render 'form'
|
= 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
|
%h3.page_title Versions
|
||||||
%table
|
%br
|
||||||
|
%table.admin-table
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th #
|
%th #
|
||||||
|
|
|
@ -5,13 +5,18 @@
|
||||||
= link_to history_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
= link_to history_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
||||||
History
|
History
|
||||||
= link_to edit_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
= link_to edit_project_wiki_path(@project, @wiki), :class => "btn small grouped" do
|
||||||
|
%i.icon-edit
|
||||||
Edit
|
Edit
|
||||||
%hr
|
%br
|
||||||
.wiki_content
|
.file_holder
|
||||||
= preserve do
|
.file_content.wiki
|
||||||
= markdown @wiki.content
|
= preserve do
|
||||||
|
= markdown @wiki.content
|
||||||
|
|
||||||
%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago
|
%p.time Last edited by #{@wiki.user.name}, #{time_ago_in_words @wiki.created_at} ago
|
||||||
- if can? current_user, :admin_wiki, @project
|
- 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
|
= link_to project_wiki_path(@project, @wiki), :confirm => "Are you sure you want to delete this page?", :method => :delete do
|
||||||
Delete this page
|
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)
|
+ [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
|
||||||
+ [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.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
|
## List projects
|
||||||
|
|
||||||
Get a list of authenticated users' projects.
|
Get a list of authenticated user's projects.
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /projects
|
GET /projects
|
||||||
|
@ -63,7 +63,7 @@ GET /projects/:id
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
+ `id` (required) - The code name of a project
|
+ `id` (required) - The ID or code name of a project
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
@ -91,7 +91,7 @@ Parameters:
|
||||||
|
|
||||||
## Project repository branches
|
## 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
|
GET /projects/:id/repository/branches
|
||||||
|
@ -99,7 +99,7 @@ GET /projects/:id/repository/branches
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
+ `id` (required) - The code name of a project
|
+ `id` (required) - The ID or code name of a project
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
|
@ -131,7 +131,7 @@ Parameters:
|
||||||
|
|
||||||
## Project repository tags
|
## 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
|
GET /projects/:id/repository/tags
|
||||||
|
@ -139,7 +139,7 @@ GET /projects/:id/repository/tags
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
+ `id` (required) - The code name of a project
|
+ `id` (required) - The ID or code name of a project
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
|
@ -183,7 +183,7 @@ GET /projects/:id/snippets/:snippet_id
|
||||||
|
|
||||||
Parameters:
|
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
|
+ `snippet_id` (required) - The ID of a project's snippet
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
@ -214,7 +214,7 @@ GET /projects/:id/snippets/:snippet_id/raw
|
||||||
|
|
||||||
Parameters:
|
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
|
+ `snippet_id` (required) - The ID of a project's snippet
|
||||||
|
|
||||||
## New snippet
|
## New snippet
|
||||||
|
@ -227,7 +227,7 @@ POST /projects/:id/snippets
|
||||||
|
|
||||||
Parameters:
|
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
|
+ `title` (required) - The title of a snippet
|
||||||
+ `file_name` (required) - The name of a snippet file
|
+ `file_name` (required) - The name of a snippet file
|
||||||
+ `lifetime` (optional) - The expiration date of a snippet
|
+ `lifetime` (optional) - The expiration date of a snippet
|
||||||
|
@ -245,7 +245,7 @@ PUT /projects/:id/snippets/:snippet_id
|
||||||
|
|
||||||
Parameters:
|
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
|
+ `snippet_id` (required) - The ID of a project's snippet
|
||||||
+ `title` (optional) - The title of a snippet
|
+ `title` (optional) - The title of a snippet
|
||||||
+ `file_name` (optional) - The name of a snippet file
|
+ `file_name` (optional) - The name of a snippet file
|
||||||
|
@ -264,7 +264,7 @@ DELETE /projects/:id/snippets/:snippet_id
|
||||||
|
|
||||||
Parameters:
|
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
|
+ `snippet_id` (required) - The ID of a project's snippet
|
||||||
|
|
||||||
Status code `200` will be returned on success.
|
Status code `200` will be returned on success.
|
||||||
|
|
|
@ -119,6 +119,7 @@ Permissions:
|
||||||
|
|
||||||
sudo chmod -R g+rwX /home/git/repositories/
|
sudo chmod -R g+rwX /home/git/repositories/
|
||||||
sudo chown -R git:git /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
|
#### CHECK: Logout & login again to apply git group to your user
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ Given /^I click atom feed link$/ do
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I see commits atom feed$/ do
|
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.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("title", :text => "Recent commits to #{@project.name}")
|
||||||
page.body.should have_selector("author email", :text => commit.author_email)
|
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
|
||||||
|
|
||||||
Given /^I click on commit link$/ do
|
Given /^I click on commit link$/ do
|
||||||
|
|
|
@ -15,5 +15,6 @@ module Gitlab
|
||||||
|
|
||||||
mount Users
|
mount Users
|
||||||
mount Projects
|
mount Projects
|
||||||
|
mount Issues
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,11 +16,7 @@ module Gitlab
|
||||||
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
|
expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at
|
||||||
end
|
end
|
||||||
|
|
||||||
class ProjectRepositoryBranches < Grape::Entity
|
class RepoObject < Grape::Entity
|
||||||
expose :name, :commit
|
|
||||||
end
|
|
||||||
|
|
||||||
class ProjectRepositoryTags < Grape::Entity
|
|
||||||
expose :name, :commit
|
expose :name, :commit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -29,5 +25,19 @@ module Gitlab
|
||||||
expose :author, :using => Entities::UserBasic
|
expose :author, :using => Entities::UserBasic
|
||||||
expose :expires_at, :updated_at, :created_at
|
expose :expires_at, :updated_at, :created_at
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,16 @@ module Gitlab
|
||||||
@current_user ||= User.find_by_authentication_token(params[:private_token])
|
@current_user ||= User.find_by_authentication_token(params[:private_token])
|
||||||
end
|
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!
|
def authenticate!
|
||||||
error!({'message' => '401 Unauthorized'}, 401) unless current_user
|
error!({'message' => '401 Unauthorized'}, 401) unless current_user
|
||||||
end
|
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
|
# Get a single project
|
||||||
#
|
#
|
||||||
# Parameters:
|
# Parameters:
|
||||||
# id (required) - The code of a project
|
# id (required) - The ID or code name of a project
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# GET /projects/:id
|
# GET /projects/:id
|
||||||
get ":id" do
|
get ":id" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
present user_project, :with => Entities::Project
|
||||||
present @project, :with => Entities::Project
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a project repository branches
|
# Get a project repository branches
|
||||||
#
|
#
|
||||||
# Parameters:
|
# Parameters:
|
||||||
# id (required) - The code of a project
|
# id (required) - The ID or code name of a project
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# GET /projects/:id/repository/branches
|
# GET /projects/:id/repository/branches
|
||||||
get ":id/repository/branches" do
|
get ":id/repository/branches" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject
|
||||||
present @project.repo.heads.sort_by(&:name), :with => Entities::ProjectRepositoryBranches
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a project repository tags
|
# Get a project repository tags
|
||||||
#
|
#
|
||||||
# Parameters:
|
# Parameters:
|
||||||
# id (required) - The code of a project
|
# id (required) - The ID or code name of a project
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# GET /projects/:id/repository/tags
|
# GET /projects/:id/repository/tags
|
||||||
get ":id/repository/tags" do
|
get ":id/repository/tags" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
present user_project.repo.tags.sort_by(&:name).reverse, :with => Entities::RepoObject
|
||||||
present @project.repo.tags.sort_by(&:name).reverse, :with => Entities::ProjectRepositoryTags
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a project snippet
|
# Get a project snippet
|
||||||
#
|
#
|
||||||
# Parameters:
|
# 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
|
# snippet_id (required) - The ID of a project snippet
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# GET /projects/:id/snippets/:snippet_id
|
# GET /projects/:id/snippets/:snippet_id
|
||||||
get ":id/snippets/:snippet_id" do
|
get ":id/snippets/:snippet_id" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
@snippet = @project.snippets.find(params[:snippet_id])
|
|
||||||
present @snippet, :with => Entities::ProjectSnippet
|
present @snippet, :with => Entities::ProjectSnippet
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create a new project snippet
|
# Create a new project snippet
|
||||||
#
|
#
|
||||||
# Parameters:
|
# 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
|
# title (required) - The title of a snippet
|
||||||
# file_name (required) - The name of a snippet file
|
# file_name (required) - The name of a snippet file
|
||||||
# lifetime (optional) - The expiration date of a snippet
|
# lifetime (optional) - The expiration date of a snippet
|
||||||
|
@ -70,8 +66,7 @@ module Gitlab
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# POST /projects/:id/snippets
|
# POST /projects/:id/snippets
|
||||||
post ":id/snippets" do
|
post ":id/snippets" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
@snippet = user_project.snippets.new(
|
||||||
@snippet = @project.snippets.new(
|
|
||||||
:title => params[:title],
|
:title => params[:title],
|
||||||
:file_name => params[:file_name],
|
:file_name => params[:file_name],
|
||||||
:expires_at => params[:lifetime],
|
:expires_at => params[:lifetime],
|
||||||
|
@ -89,7 +84,7 @@ module Gitlab
|
||||||
# Update an existing project snippet
|
# Update an existing project snippet
|
||||||
#
|
#
|
||||||
# Parameters:
|
# 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
|
# snippet_id (required) - The ID of a project snippet
|
||||||
# title (optional) - The title of a snippet
|
# title (optional) - The title of a snippet
|
||||||
# file_name (optional) - The name of a snippet file
|
# file_name (optional) - The name of a snippet file
|
||||||
|
@ -98,8 +93,7 @@ module Gitlab
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# PUT /projects/:id/snippets/:snippet_id
|
# PUT /projects/:id/snippets/:snippet_id
|
||||||
put ":id/snippets/:snippet_id" do
|
put ":id/snippets/:snippet_id" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
@snippet = @project.snippets.find(params[:snippet_id])
|
|
||||||
parameters = {
|
parameters = {
|
||||||
:title => (params[:title] || @snippet.title),
|
:title => (params[:title] || @snippet.title),
|
||||||
:file_name => (params[:file_name] || @snippet.file_name),
|
:file_name => (params[:file_name] || @snippet.file_name),
|
||||||
|
@ -117,26 +111,24 @@ module Gitlab
|
||||||
# Delete a project snippet
|
# Delete a project snippet
|
||||||
#
|
#
|
||||||
# Parameters:
|
# 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
|
# snippet_id (required) - The ID of a project snippet
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# DELETE /projects/:id/snippets/:snippet_id
|
# DELETE /projects/:id/snippets/:snippet_id
|
||||||
delete ":id/snippets/:snippet_id" do
|
delete ":id/snippets/:snippet_id" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
@snippet = @project.snippets.find(params[:snippet_id])
|
|
||||||
@snippet.destroy
|
@snippet.destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get a raw project snippet
|
# Get a raw project snippet
|
||||||
#
|
#
|
||||||
# Parameters:
|
# 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
|
# snippet_id (required) - The ID of a project snippet
|
||||||
# Example Request:
|
# Example Request:
|
||||||
# GET /projects/:id/snippets/:snippet_id/raw
|
# GET /projects/:id/snippets/:snippet_id/raw
|
||||||
get ":id/snippets/:snippet_id/raw" do
|
get ":id/snippets/:snippet_id/raw" do
|
||||||
@project = current_user.projects.find_by_code(params[:id])
|
@snippet = user_project.snippets.find(params[:snippet_id])
|
||||||
@snippet = @project.snippets.find(params[:snippet_id])
|
|
||||||
present @snippet.content
|
present @snippet.content
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ module Gitlab
|
||||||
|
|
||||||
def self.read_latest
|
def self.read_latest
|
||||||
path = Rails.root.join("log/githost.log")
|
path = Rails.root.join("log/githost.log")
|
||||||
|
self.build unless File.exist?(path)
|
||||||
logs = File.read(path).split("\n")
|
logs = File.read(path).split("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ namespace :gitlab do
|
||||||
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
||||||
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
|
FileUtils.mkdir_p(backup_path_repo) until Dir.exists?(backup_path_repo)
|
||||||
puts "Dumping repositories:"
|
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 << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
|
||||||
project.each do |project|
|
project.each do |project|
|
||||||
print "- Dumping repository #{project.first}... "
|
print "- Dumping repository #{project.first}... "
|
||||||
|
@ -136,12 +136,18 @@ namespace :gitlab do
|
||||||
task :repo_restore => :environment do
|
task :repo_restore => :environment do
|
||||||
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
backup_path_repo = File.join(Gitlab.config.backup_path, "repositories")
|
||||||
puts "Restoring 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 << ["gitolite-admin.git", File.join(File.dirname(project.first.second), "gitolite-admin.git")]
|
||||||
project.each do |project|
|
project.each do |project|
|
||||||
print "- Restoring repository #{project.first}... "
|
print "- Restoring repository #{project.first}... "
|
||||||
FileUtils.rm_rf(project.second) if File.dirname(project.second) # delet old stuff
|
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")
|
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
|
puts "[DONE]".green
|
||||||
else
|
else
|
||||||
puts "[FAILED]".red
|
puts "[FAILED]".red
|
||||||
|
|
|
@ -2,7 +2,7 @@ namespace :gitlab do
|
||||||
namespace :app do
|
namespace :app do
|
||||||
desc "GITLAB | Check gitlab installation status"
|
desc "GITLAB | Check gitlab installation status"
|
||||||
task :status => :environment do
|
task :status => :environment do
|
||||||
puts "Starting diagnostic"
|
puts "Starting diagnostic".yellow
|
||||||
git_base_path = Gitlab.config.git_base_path
|
git_base_path = Gitlab.config.git_base_path
|
||||||
|
|
||||||
print "config/database.yml............"
|
print "config/database.yml............"
|
||||||
|
@ -56,7 +56,28 @@ namespace :gitlab do
|
||||||
return
|
return
|
||||||
end
|
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
|
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
|
describe "GET /projects/:id" do
|
||||||
it "should return a project by 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
|
response.status.should == 200
|
||||||
json_response['name'].should == project.name
|
json_response['name'].should == project.name
|
||||||
json_response['owner']['email'].should == user.email
|
json_response['owner']['email'].should == user.email
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "GET /projects/:id/repository/branches" do
|
describe "GET /projects/:id/repository/branches" do
|
||||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
describe "Commits" do
|
describe "Commits" do
|
||||||
let(:project) { Factory :project }
|
let(:project) { Factory :project }
|
||||||
let!(:commit) { project.commit }
|
let!(:commit) { CommitDecorator.decorate(project.commit) }
|
||||||
before do
|
before do
|
||||||
login_as :user
|
login_as :user
|
||||||
project.add_access(@user, :read)
|
project.add_access(@user, :read)
|
||||||
|
@ -22,8 +22,8 @@ describe "Commits" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should list commits" do
|
it "should list commits" do
|
||||||
page.should have_content(commit.message)
|
page.should have_content(commit.description)
|
||||||
page.should have_content(commit.id.to_s[0..5])
|
page.should have_content(commit.short_id(8))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render atom feed" do
|
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.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("title", :text => "Recent commits to #{project.name}")
|
||||||
page.body.should have_selector("author email", :text => commit.author_email)
|
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
|
||||||
|
|
||||||
it "should render atom feed via private token" do
|
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.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("title", :text => "Recent commits to #{project.name}")
|
||||||
page.body.should have_selector("author email", :text => commit.author_email)
|
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
|
||||||
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