Merge branch 'master' into stable

Conflicts:
	doc/install/installation.md
3-1-stable
Dmitriy Zaporozhets 2012-11-22 12:52:08 +02:00
commit 319f0c3057
508 changed files with 105205 additions and 3020 deletions

View File

@ -3,8 +3,11 @@ env:
- DB=mysql
before_install:
- sudo apt-get install libicu-dev -y
- sudo apt-get install libqt4-dev libqtwebkit-dev -y
- gem install charlock_holmes -v="0.6.8"
- wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2
- tar -xf /tmp/phantomjs-1.7.0-linux-i686.tar.bz2 -C /tmp/
- sudo rm -rf /usr/local/phantomjs
- sudo mv /tmp/phantomjs-1.7.0-linux-i686 /usr/local/phantomjs
- gem install charlock_holmes -v="0.6.9"
branches:
only:
- 'master'

View File

@ -1,3 +1,21 @@
v 3.1.0
- Updated gems
- Services: Gitlab CI integration
- Events filter on dashboard
- Own namespace for redis/resque
- Optimized commit diff views
- add alphabetical order for projects admin page
- Improved web editor
- Commit stats page
- Documentation split and cleanup
- Link to commit authors everywhere
- Restyled milestones list
- added Milestone to Merge Request
- Restyled Top panel
- Refactored Satellite Code
- Added file line links
- moved from capybara-webkit to poltergeist + phantomjs
v 3.0.3
- Fixed bug with issues list in Chrome
- New Feature: Import team from another project
@ -28,7 +46,7 @@ v 3.0.0
- Reject ssh keys that break gitolite
- [API] list one project hook
- [API] edit project hook
- [API] add project snippets list
- [API] list project snippets
- [API] allow to authorize using private token in HTTP header
- [API] add user creation

View File

@ -1,4 +1,4 @@
## Contribute to GitLab
## Contribute to GitLab
If you want to contribute to GitLab, follow this process:
@ -7,24 +7,20 @@ If you want to contribute to GitLab, follow this process:
3. Code
4. Create a pull request
We will only accept pull requests if:
We will only accept pull requests if:
* Your code has proper tests and all tests pass
* Your code can be merged w/o problems
* Your code can be merged w/o problems
* It won't break existing functionality
* It's quality code
* We like it :)
## [You may need a developer VM](https://github.com/gitlabhq/developer-vm)
For examples of feedback on pull requests please look at the [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
## Installation
Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing.
## Running tests
To run the specs for GitLab, you need to run seeds for test db.
cd gitlabhq
rake db:seed_fu RAILS_ENV=test
Then you can run the test suite with rake:
rake gitlab:test
For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)

88
Gemfile
View File

@ -8,34 +8,35 @@ def linux_only(require_as)
RUBY_PLATFORM.include?('linux') && require_as
end
gem "rails", "3.2.8"
gem "rails", "3.2.9"
# Supported DBs
gem "sqlite3", :group => :sqlite
gem "mysql2", :group => :mysql
gem "pg", :group => :postgres
gem "sqlite3", group: :sqlite
gem "mysql2", group: :mysql
gem "pg", group: :postgres
# Auth
gem "devise", "~> 2.1.0"
gem 'omniauth'
gem 'omniauth', "~> 1.1.1"
gem 'omniauth-google-oauth2'
gem 'omniauth-twitter'
gem 'omniauth-github'
# GITLAB patched libs
gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
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 "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e'
gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10'
# Gitolite client (for work with gitolite-admin repo)
gem "gitolite", '1.1.0'
# Syntax highlighter
gem "pygments.rb", "0.3.1"
gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4'
# Language detection
gem "github-linguist", "~> 2.3.4" , :require => "linguist"
gem "github-linguist", "~> 2.3.4" , require: "linguist"
# API
gem "grape", "~> 0.2.1"
@ -45,13 +46,13 @@ gem "grape", "~> 0.2.1"
gem "stamp"
# Pagination
gem "kaminari"
gem "kaminari", "~> 0.14.1"
# HAML
gem "haml-rails"
gem "haml-rails", "~> 0.3.5"
# Files attachments
gem "carrierwave"
gem "carrierwave", "~> 0.7.1"
# Authorization
gem "six"
@ -63,59 +64,57 @@ gem "ffaker"
gem "seed-fu"
# Markdown to HTML
gem "redcarpet", "~> 2.1.1"
gem "redcarpet", "~> 2.2.2"
gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers
gem "thin"
gem "unicorn"
gem "thin", '~> 1.5.0'
gem "unicorn", "~> 4.4.0"
# Issue tags
gem "acts-as-taggable-on", "2.3.1"
gem "acts-as-taggable-on", "2.3.3"
# Decorators
gem "draper"
gem "draper", "~> 0.18.0"
# Background jobs
gem "resque", "~> 1.20.0"
gem "resque", "~> 1.23.0"
gem 'resque_mailer'
# HTTP requests
gem "httparty"
# Handle encodings
gem "charlock_holmes"
# Colored output to console
gem "colored"
# GITLAB settings
# GitLab settings
gem 'settingslogic'
# Misc
gem "foreman"
gem 'gemoji', require: 'emoji/railtie'
gem "git"
group :assets do
gem "sass-rails", "3.2.5"
gem "coffee-rails", "3.2.2"
gem "uglifier", "1.0.3"
gem "sass-rails", "~> 3.2.5"
gem "coffee-rails", "~> 3.2.2"
gem "uglifier", "~> 1.3.0"
gem "therubyracer"
gem 'chosen-rails'
gem 'jquery-atwho-rails', '0.1.6'
gem "jquery-rails", "2.0.2"
gem "jquery-ui-rails", "0.5.0"
gem "modernizr", "2.5.3"
gem "raphael-rails", "1.5.2"
gem 'bootstrap-sass', "2.0.4"
gem 'chosen-rails', "0.9.8"
gem 'jquery-atwho-rails', "0.1.6"
gem "jquery-rails", "2.1.3"
gem "jquery-ui-rails", "2.0.2"
gem "modernizr", "2.6.2"
gem "raphael-rails", "2.1.0"
gem 'bootstrap-sass', "2.2.1.1"
gem "font-awesome-sass-rails", "~> 2.0.0"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
end
group :development do
gem "annotate", git: "https://github.com/ctran/annotate_models.git"
gem "letter_opener"
gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
gem 'quiet_assets', '~> 1.0.1'
gem 'rack-mini-profiler'
end
@ -124,8 +123,6 @@ group :development, :test do
gem 'spinach-rails'
gem "rspec-rails"
gem "capybara"
gem "capybara-webkit"
gem "headless"
gem "pry"
gem "awesome_print"
gem "database_cleaner"
@ -137,14 +134,17 @@ group :development, :test do
gem 'guard-spinach'
# Notification
gem 'rb-fsevent', :require => darwin_only('rb-fsevent')
gem 'growl', :require => darwin_only('growl')
gem 'rb-inotify', :require => linux_only('rb-inotify')
gem 'rb-fsevent', require: darwin_only('rb-fsevent')
gem 'growl', require: darwin_only('growl')
gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara
gem 'poltergeist'
end
group :test do
gem "simplecov", :require => false
gem "shoulda-matchers"
gem "simplecov", require: false
gem "shoulda-matchers", "1.3.0"
gem 'email_spec'
gem 'resque_spec'
gem "webmock"
@ -152,5 +152,5 @@ group :test do
end
group :production do
gem "gitlab_meta", '3.0'
gem "gitlab_meta", '3.1'
end

View File

@ -1,12 +1,15 @@
GIT
remote: https://github.com/ctran/annotate_models.git
revision: 18cd39ad01829deba5aa34634b8540d6675ab978
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
specs:
annotate (2.4.1.beta1)
annotate (2.6.0.beta1)
activerecord (>= 2.3.0)
rake (>= 0.8.7)
GIT
remote: https://github.com/gitlabhq/grack.git
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
specs:
grack (1.0.0)
rack (~> 1.4.1)
@ -21,6 +24,14 @@ GIT
mime-types (~> 1.15)
posix-spawn (~> 0.3.6)
GIT
remote: https://github.com/gitlabhq/grit_ext.git
revision: 212fd40bea61f3c6a167223768e7295dc32bbc10
ref: 212fd40bea61f3c6a167223768e7295dc32bbc10
specs:
grit_ext (0.6.0)
charlock_holmes (~> 0.6.9)
GIT
remote: https://github.com/gitlabhq/omniauth-ldap.git
revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
@ -32,115 +43,126 @@ GIT
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1)
GIT
remote: https://github.com/gitlabhq/pygments.rb.git
revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
specs:
pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
GIT
remote: https://github.com/gitlabhq/yaml_db.git
revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
specs:
yaml_db (0.2.2)
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.2.8)
actionpack (= 3.2.8)
actionmailer (3.2.9)
actionpack (= 3.2.9)
mail (~> 2.4.4)
actionpack (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
actionpack (3.2.9)
activemodel (= 3.2.9)
activesupport (= 3.2.9)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.1.3)
activemodel (3.2.8)
activesupport (= 3.2.8)
sprockets (~> 2.2.1)
activemodel (3.2.9)
activesupport (= 3.2.9)
builder (~> 3.0.0)
activerecord (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
activerecord (3.2.9)
activemodel (= 3.2.9)
activesupport (= 3.2.9)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.8)
activemodel (= 3.2.8)
activesupport (= 3.2.8)
activesupport (3.2.8)
activeresource (3.2.9)
activemodel (= 3.2.9)
activesupport (= 3.2.9)
activesupport (3.2.9)
i18n (~> 0.6)
multi_json (~> 1.0)
acts-as-taggable-on (2.3.1)
acts-as-taggable-on (2.3.3)
rails (~> 3.0)
addressable (2.2.8)
addressable (2.3.2)
arel (3.0.2)
awesome_print (1.0.2)
awesome_print (1.1.0)
backports (2.6.5)
bcrypt-ruby (3.0.1)
blankslate (2.1.2.4)
bootstrap-sass (2.0.4.0)
builder (3.0.2)
capybara (1.1.2)
blankslate (3.1.2)
bootstrap-sass (2.2.1.1)
sass (~> 3.2)
builder (3.0.4)
capybara (1.1.3)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
capybara-webkit (0.12.1)
capybara (>= 1.0.0, < 1.2)
json
carrierwave (0.6.2)
carrierwave (0.7.1)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
charlock_holmes (0.6.8)
childprocess (0.3.2)
ffi (~> 1.0.6)
chosen-rails (0.9.8.3)
charlock_holmes (0.6.9)
childprocess (0.3.6)
ffi (~> 1.0, >= 1.0.6)
chosen-rails (0.9.8)
railties (~> 3.0)
thor (~> 0.14)
coderay (1.0.6)
coderay (1.0.8)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.3.3)
coffee-script-source (1.4.0)
colored (1.2)
colorize (0.5.8)
crack (0.3.1)
daemons (1.1.8)
database_cleaner (0.8.0)
daemons (1.1.9)
database_cleaner (0.9.1)
devise (2.1.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
diff-lcs (1.1.3)
draper (0.17.0)
draper (0.18.0)
actionpack (~> 3.2)
activesupport (~> 3.2)
email_spec (1.2.1)
email_spec (1.4.0)
launchy (~> 2.1)
mail (~> 2.2)
rspec (~> 2.0)
erubis (2.7.0)
escape_utils (0.2.4)
eventmachine (0.12.10)
eventmachine (1.0.0)
execjs (1.4.0)
multi_json (~> 1.0)
factory_girl (4.0.0)
factory_girl (4.1.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.0.0)
factory_girl (~> 4.0.0)
factory_girl_rails (4.1.0)
factory_girl (~> 4.1.0)
railties (>= 3.0.0)
faraday (0.8.4)
multipart-post (~> 1.1)
ffaker (1.14.0)
ffi (1.0.11)
faye-websocket (0.4.6)
eventmachine (>= 0.12.0)
ffaker (1.15.0)
ffi (1.1.5)
font-awesome-sass-rails (2.0.0.0)
railties (>= 3.1.1)
sass-rails (>= 3.1.1)
foreman (0.47.0)
foreman (0.60.2)
thor (>= 0.13.6)
gemoji (1.1.1)
gemoji (1.2.1)
gherkin-ruby (0.2.1)
git (1.2.5)
github-linguist (2.3.4)
@ -149,80 +171,87 @@ GEM
mime-types (~> 1.19)
pygments.rb (>= 0.2.13)
github-markup (0.7.4)
gitlab_meta (3.0)
gitlab_meta (3.1)
gitolite (1.1.0)
gratr19 (~> 0.4.4.1)
grit (~> 2.5.0)
hashery (~> 1.5.0)
grape (0.2.1)
grape (0.2.2)
activesupport
hashie (~> 1.2)
multi_json
multi_json (>= 1.3.2)
multi_xml
rack
rack-accept
rack-mount
virtus
gratr19 (0.4.4.1)
growl (1.0.3)
guard (1.3.2)
guard (1.5.4)
listen (>= 0.4.2)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
thor (>= 0.14.6)
guard-rspec (1.2.1)
guard-rspec (2.1.2)
guard (>= 1.1)
rspec (~> 2.11)
guard-spinach (0.0.2)
guard (>= 1.1)
spinach
haml (3.1.6)
haml-rails (0.3.4)
actionpack (~> 3.0)
activesupport (~> 3.0)
haml (~> 3.0)
railties (~> 3.0)
haml (3.1.7)
haml-rails (0.3.5)
actionpack (>= 3.1, < 4.1)
activesupport (>= 3.1, < 4.1)
haml (~> 3.1)
railties (>= 3.1, < 4.1)
hashery (1.5.0)
blankslate
hashie (1.2.0)
headless (0.3.1)
hike (1.2.1)
httparty (0.8.3)
http_parser.rb (0.5.3)
httparty (0.9.0)
multi_json (~> 1.0)
multi_xml
httpauth (0.1)
httpauth (0.2.0)
i18n (0.6.1)
journey (1.0.4)
jquery-atwho-rails (0.1.6)
jquery-rails (2.0.2)
railties (>= 3.2.0, < 5.0)
jquery-rails (2.1.3)
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
jquery-ui-rails (0.5.0)
jquery-ui-rails (2.0.2)
jquery-rails
railties (>= 3.1.0)
json (1.7.5)
jwt (0.1.5)
multi_json (>= 1.0)
kaminari (0.14.0)
kaminari (0.14.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.7.4)
launchy (2.1.0)
addressable (~> 2.2.6)
letter_opener (0.0.2)
launchy
launchy (2.1.2)
addressable (~> 2.3)
letter_opener (1.0.0)
launchy (>= 2.0.4)
libv8 (3.3.10.4)
libwebsocket (0.1.3)
addressable
listen (0.5.0)
libwebsocket (0.1.6)
websocket
listen (0.5.3)
lumberjack (1.0.2)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.7.1)
method_source (0.8.1)
mime-types (1.19)
modernizr (2.5.3)
modernizr (2.6.2)
sprockets (~> 2.0)
multi_json (1.3.6)
multi_json (1.3.7)
multi_xml (0.5.1)
multipart-post (1.1.5)
mysql2 (0.3.11)
net-ldap (0.2.2)
nokogiri (1.5.3)
nokogiri (1.5.5)
oauth (0.4.7)
oauth2 (0.8.0)
faraday (~> 0.8)
@ -230,7 +259,7 @@ GEM
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.1.0)
omniauth (1.1.1)
hashie (~> 1.2)
rack
omniauth-github (1.0.3)
@ -242,28 +271,35 @@ GEM
omniauth-oauth (1.0.1)
oauth
omniauth (~> 1.0)
omniauth-oauth2 (1.1.0)
omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
omniauth-twitter (0.0.13)
omniauth-twitter (0.0.14)
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
orm_adapter (0.3.0)
pg (0.14.0)
orm_adapter (0.4.0)
pg (0.14.1)
poltergeist (1.0.2)
capybara (~> 1.1)
childprocess (~> 0.3)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
multi_json (~> 1.0)
polyglot (0.3.3)
posix-spawn (0.3.6)
pry (0.9.9.6)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.7.1)
slop (>= 2.4.4, < 3)
pygments.rb (0.3.1)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
method_source (~> 0.8)
slop (~> 3.3.1)
pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.1)
railties (~> 3.1)
rack (1.4.1)
rack-accept (0.4.5)
rack (>= 0.4)
rack-cache (1.2)
rack (>= 0.4)
rack-mini-profiler (0.1.9)
rack-mini-profiler (0.1.23)
rack (>= 1.1.3)
rack-mount (0.8.3)
rack (>= 1.0.0)
@ -271,65 +307,66 @@ GEM
rack
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.8)
actionmailer (= 3.2.8)
actionpack (= 3.2.8)
activerecord (= 3.2.8)
activeresource (= 3.2.8)
activesupport (= 3.2.8)
rails (3.2.9)
actionmailer (= 3.2.9)
actionpack (= 3.2.9)
activerecord (= 3.2.9)
activeresource (= 3.2.9)
activesupport (= 3.2.9)
bundler (~> 1.0)
railties (= 3.2.8)
railties (= 3.2.9)
rails-dev-tweaks (0.6.1)
actionpack (~> 3.1)
railties (~> 3.1)
railties (3.2.8)
actionpack (= 3.2.8)
activesupport (= 3.2.8)
railties (3.2.9)
actionpack (= 3.2.9)
activesupport (= 3.2.9)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.9.0)
rake (0.9.2.2)
raphael-rails (1.5.2)
rb-fsevent (0.9.1)
raindrops (0.10.0)
rake (10.0.1)
raphael-rails (2.1.0)
rb-fsevent (0.9.2)
rb-inotify (0.8.8)
ffi (>= 0.5.0)
rdoc (3.12)
json (~> 1.4)
redcarpet (2.1.1)
redis (2.2.2)
redis-namespace (1.0.3)
redis (< 3.0.0)
resque (1.20.0)
redcarpet (2.2.2)
redis (3.0.2)
redis-namespace (1.2.1)
redis (~> 3.0.0)
resque (1.23.0)
multi_json (~> 1.0)
redis-namespace (~> 1.0.2)
redis-namespace (~> 1.0)
sinatra (>= 0.9.2)
vegas (~> 0.1.2)
resque_mailer (2.0.3)
actionmailer (>= 3.0.0)
resque (>= 1.2.3)
resque_spec (0.11.0)
resque_mailer (2.1.0)
actionmailer (~> 3.0)
resque_spec (0.12.5)
resque (>= 1.19.0)
rspec (>= 2.5.0)
rspec (2.10.0)
rspec-core (~> 2.10.0)
rspec-expectations (~> 2.10.0)
rspec-mocks (~> 2.10.0)
rspec-core (2.10.1)
rspec-expectations (2.10.0)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rspec-core (2.12.0)
rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.10.1)
rspec-rails (2.10.1)
rspec-mocks (2.12.0)
rspec-rails (2.12.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec (~> 2.10.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rubyntlm (0.1.1)
rubyzip (0.9.8)
sass (3.1.19)
rubyzip (0.9.9)
sass (3.2.3)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
@ -337,25 +374,24 @@ GEM
seed-fu (2.2.0)
activerecord (~> 3.1)
activesupport (~> 3.1)
selenium-webdriver (2.22.2)
selenium-webdriver (2.26.0)
childprocess (>= 0.2.5)
ffi (~> 1.0)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
settingslogic (2.0.8)
shoulda-matchers (1.3.0)
activesupport (>= 3.0.0)
simplecov (0.6.4)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
sinatra (1.3.2)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
slop (2.4.4)
slop (3.3.3)
spinach (0.5.2)
colorize
gherkin-ruby (~> 0.2.0)
@ -363,39 +399,43 @@ GEM
capybara (~> 1)
railties (>= 3)
spinach (>= 0.4)
sprockets (2.1.3)
sprockets (2.2.1)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.6)
stamp (0.1.6)
stamp (0.3.0)
test_after_commit (0.0.1)
therubyracer (0.10.1)
therubyracer (0.10.2)
libv8 (~> 3.3.10)
thin (1.3.1)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.16.0)
tilt (1.3.3)
treetop (1.4.10)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.33)
uglifier (1.0.3)
tzinfo (0.3.35)
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)
unicorn (4.3.1)
multi_json (~> 1.0, >= 1.0.2)
unicorn (4.4.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
vegas (0.1.11)
rack (>= 1.0.0)
virtus (0.5.2)
backports (~> 2.6.1)
warden (1.2.1)
rack (>= 1.0)
webmock (1.8.7)
webmock (1.9.0)
addressable (>= 2.2.7)
crack (>= 0.1.7)
websocket (1.0.2)
xpath (0.1.4)
nokogiri (~> 1.3)
yajl-ruby (1.1.0)
@ -404,71 +444,71 @@ PLATFORMS
ruby
DEPENDENCIES
acts-as-taggable-on (= 2.3.1)
acts-as-taggable-on (= 2.3.3)
annotate!
awesome_print
bootstrap-sass (= 2.0.4)
bootstrap-sass (= 2.2.1.1)
capybara
capybara-webkit
carrierwave
charlock_holmes
chosen-rails
coffee-rails (= 3.2.2)
carrierwave (~> 0.7.1)
chosen-rails (= 0.9.8)
coffee-rails (~> 3.2.2)
colored
database_cleaner
devise (~> 2.1.0)
draper
draper (~> 0.18.0)
email_spec
factory_girl_rails
ffaker
font-awesome-sass-rails (~> 2.0.0)
foreman
gemoji
gemoji (~> 1.2.1)
git
github-linguist (~> 2.3.4)
github-markup (~> 0.7.4)
gitlab_meta (= 3.0)
gitlab_meta (= 3.1)
gitolite (= 1.1.0)
grack!
grape (~> 0.2.1)
grit!
grit_ext!
growl
guard-rspec
guard-spinach
haml-rails
headless
haml-rails (~> 0.3.5)
httparty
jquery-atwho-rails (= 0.1.6)
jquery-rails (= 2.0.2)
jquery-ui-rails (= 0.5.0)
kaminari
jquery-rails (= 2.1.3)
jquery-ui-rails (= 2.0.2)
kaminari (~> 0.14.1)
launchy
letter_opener
modernizr (= 2.5.3)
modernizr (= 2.6.2)
mysql2
omniauth
omniauth (~> 1.1.1)
omniauth-github
omniauth-google-oauth2
omniauth-ldap!
omniauth-twitter
pg
poltergeist
pry
pygments.rb (= 0.3.1)
pygments.rb!
quiet_assets (~> 1.0.1)
rack-mini-profiler
rails (= 3.2.8)
rails (= 3.2.9)
rails-dev-tweaks
raphael-rails (= 1.5.2)
raphael-rails (= 2.1.0)
rb-fsevent
rb-inotify
redcarpet (~> 2.1.1)
resque (~> 1.20.0)
redcarpet (~> 2.2.2)
resque (~> 1.23.0)
resque_mailer
resque_spec
rspec-rails
sass-rails (= 3.2.5)
sass-rails (~> 3.2.5)
seed-fu
settingslogic
shoulda-matchers
shoulda-matchers (= 1.3.0)
simplecov
six
spinach-rails
@ -476,8 +516,8 @@ DEPENDENCIES
stamp
test_after_commit
therubyracer
thin
uglifier (= 1.0.3)
unicorn
thin (~> 1.5.0)
uglifier (~> 1.3.0)
unicorn (~> 4.4.0)
webmock
yaml_db!

View File

@ -1,2 +0,0 @@
web: bundle exec rails s -p $PORT -e production
worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=*

View File

@ -13,7 +13,7 @@ GitLab is a free project and repository management application
* Ubuntu/Debian
* ruby 1.9.3+
* mysql or sqlite
* MySQL
* git
* gitolite
* redis

25
ROADMAP.md Normal file
View File

@ -0,0 +1,25 @@
## GitLab Roadmap
### Common
* Help page for service tasks like repos import, backup etc
* Hide last push widget after following link
* Add comment events
* gitolite namespaces for projects per user/group. It will allow us same project names for different users
### Issues
* labels autocomplete via jquery autocomplete
* Import/Export issues
* Form: Assign to me link right to the selectbox
### Merge Request
* Save code fragments with MR comments
### Services
* Campfire integration service
* Hipchat integration service
* Travis CI integration service
* Jenkins CI integration service

View File

@ -1 +1 @@
3.0.3
3.1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 B

View File

@ -13,10 +13,13 @@
//= require jquery.history
//= require jquery.waitforimages
//= require jquery.atwho
//= require jquery.scrollto
//= require bootstrap
//= require modernizr
//= require chosen-jquery
//= require raphael
//= require g.raphael-min
//= require g.bar-min
//= require branch-graph
//= require ace-src-noconflict/ace
//= require_tree .

View File

@ -1,57 +1,52 @@
# Creates the variables for setting up GFM auto-completion
window.GitLab ?= {}
GitLab.GfmAutoComplete ?= {}
###
Creates the variables for setting up GFM auto-completion
###
# Emoji
window.autocompleteEmojiData = [];
window.autocompleteEmojiTemplate = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>";
data = []
template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
GitLab.GfmAutoComplete.Emoji = {data, template}
# Team Members
window.autocompleteMembersUrl = "";
window.autocompleteMembersParams =
private_token: ""
page: 1
window.autocompleteMembersData = [];
data = []
url = '';
params = {private_token: '', page: 1}
GitLab.GfmAutoComplete.Members = {data, url, params}
# Add GFM auto-completion to all input fields, that accept GFM input.
GitLab.GfmAutoComplete.setup = ->
input = $('.js-gfm-input')
# Emoji
input.atWho ':',
data: GitLab.GfmAutoComplete.Emoji.data,
tpl: GitLab.GfmAutoComplete.Emoji.template
###
Add GFM auto-completion to all input fields, that accept GFM input.
###
window.setupGfmAutoComplete = ->
###
Emoji
###
$('.gfm-input').atWho ':',
data: autocompleteEmojiData,
tpl: autocompleteEmojiTemplate
###
Team Members
###
$('.gfm-input').atWho '@', (query, callback) ->
# Team Members
input.atWho '@', (query, callback) ->
(getMoreMembers = ->
$.getJSON(autocompleteMembersUrl, autocompleteMembersParams)
$.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params)
.success (members) ->
# pick the data we need
newMembersData = $.map members, (m) -> m.name
newMembersData = $.map(members, (m) -> m.name )
# add the new page of data to the rest
$.merge autocompleteMembersData, newMembersData
$.merge(GitLab.GfmAutoComplete.Members.data, newMembersData)
# show the pop-up with a copy of the current data
callback autocompleteMembersData[..]
callback(GitLab.GfmAutoComplete.Members.data[..])
# are we past the last page?
if newMembersData.length == 0
if newMembersData.length is 0
# set static data and stop callbacks
$('.gfm-input').atWho '@',
data: autocompleteMembersData
input.atWho '@',
data: GitLab.GfmAutoComplete.Members.data
callback: null
else
# get next page
getMoreMembers()
# so the next request gets the next page
autocompleteMembersParams.page += 1;
).call();
GitLab.GfmAutoComplete.Members.params.page += 1
).call()

View File

@ -1,10 +0,0 @@
initGraphNav = ->
$('.graph svg').css 'position', 'relative'
$('body').bind 'keyup', (e) ->
if e.keyCode is 37 # left
$('.graph svg').animate left: '+=400'
else if e.keyCode is 39 # right
$('.graph svg').animate left: '-=400'
window.initGraphNav = initGraphNav

View File

@ -1,24 +1,22 @@
function switchToNewIssue(form){
function switchToNewIssue(){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
$('select#issue_milestone_id').chosen();
$("#new_issue_dialog").show("fade", { direction: "right" }, 150);
$('.top-tabs .add_new').hide();
disableButtonIfEmptyField("#issue_title", ".save-btn");
setupGfmAutoComplete();
GitLab.GfmAutoComplete.setup();
});
}
function switchToEditIssue(form){
function switchToEditIssue(){
$(".issues_content").hide("fade", { direction: "left" }, 150, function(){
$(".issues_content").after(form);
$('select#issue_assignee_id').chosen();
$('select#issue_milestone_id').chosen();
$("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
$('.add_new').hide();
disableButtonIfEmptyField("#issue_title", ".save-btn");
setupGfmAutoComplete();
GitLab.GfmAutoComplete.setup();
});
}
@ -33,18 +31,18 @@ function switchFromEditIssue(){
function backToIssues(){
$("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
$(".issues_content").show("fade", { direction: "left" }, 150, function() {
$("#edit_issue_dialog").remove();
$("#new_issue_dialog").remove();
$("#edit_issue_dialog").html("");
$("#new_issue_dialog").html("");
$('.add_new').show();
});
});
}
function initIssuesSearch() {
var href = $('.issue_search').parent().attr('action');
var href = $('#issue_search_form').attr('action');
var last_terms = '';
$('.issue_search').keyup(function() {
$('#issue_search').keyup(function() {
var terms = $(this).val();
var milestone_id = $('#milestone_id').val();
var status = $('#status').val();
@ -59,10 +57,6 @@ function initIssuesSearch() {
}
}
});
$('.delete-issue').live('ajax:success', function() {
$(this).closest('tr').fadeOut(); updatePage();
});
}
/**

View File

@ -1,5 +0,0 @@
Loader =
html: (width) ->
$('<img>').attr src: '/assets/ajax-loader.gif', width: width
window.Loader = Loader

View File

@ -7,29 +7,36 @@ window.slugify = (text) ->
window.ajaxGet = (url) ->
$.ajax({type: "GET", url: url, dataType: "script"})
# Disable button if text field is empty
# Disable button if text field is empty
window.disableButtonIfEmptyField = (field_selector, button_selector) ->
field = $(field_selector)
closest_submit = field.closest("form").find(button_selector)
closest_submit.disable() if field.val() is ""
field.on "keyup", ->
if $(this).val() is ""
field.on "input", ->
if $(@).val() is ""
closest_submit.disable()
else
closest_submit.enable()
$ ->
# Click a .one_click_select field, select the contents
$(".one_click_select").live 'click', -> $(this).select()
$(".one_click_select").on 'click', -> $(@).select()
# Initialize chosen selects
$('select.chosen').chosen()
# Initialize tooltips
$('.has_tooltip').tooltip()
# Bottom tooltip
$('.has_bottom_tooltip').tooltip(placement: 'bottom')
# Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
buttons = $('[type="submit"]', this)
buttons = $('[type="submit"]', @)
switch e.type
when 'ajax:beforeSend', 'submit'
@ -38,7 +45,7 @@ $ ->
buttons.enable()
# Show/Hide the profile menu when hovering the account box
$('.account-box').hover -> $(this).toggleClass('hover')
$('.account-box').hover -> $(@).toggleClass('hover')
# Focus search field by pressing 's' key
$(document).keypress (e) ->
@ -52,41 +59,22 @@ $ ->
# Commit show suppressed diff
$(".supp_diff_link").bind "click", ->
$(this).next('table').show()
$(this).remove()
# Note markdown preview
$(document).on 'click', '#preview-link', (e) ->
$('#preview-note').text('Loading...')
previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview'
$(this).text(previewLinkText)
note = $('#note_note').val()
if note.trim().length == 0
$('#preview-note').text("Nothing to preview.")
else
$.post $(this).attr('href'), {note: note}, (data) ->
$('#preview-note').html(data)
$('#preview-note, #note_note').toggle()
e.preventDefault()
false
$(@).next('table').show()
$(@).remove()
(($) ->
_chosen = $.fn.chosen
$.fn.extend chosen: (options) ->
default_options = search_contains: "true"
$.extend default_options, options
_chosen.apply this, [default_options]
_chosen.apply @, [default_options]
# Disable an element and add the 'disabled' Bootstrap class
$.fn.extend disable: ->
$(this).attr('disabled', 'disabled').addClass('disabled')
$(@).attr('disabled', 'disabled').addClass('disabled')
# Enable an element and remove the 'disabled' Bootstrap class
$.fn.extend enable: ->
$(this).removeAttr('disabled').removeClass('disabled')
$(@).removeAttr('disabled').removeClass('disabled')
)(jQuery)

View File

@ -115,4 +115,15 @@ var MergeRequest = {
$(".merge_in_progress").hide();
$(".automerge_widget.already_cannot_be_merged").show();
}
};
/*
* Filter merge requests
*/
function merge_requestsPage() {
$("#assignee_id").chosen();
$("#milestone_id").chosen();
$("#milestone_id, #assignee_id").on("change", function(){
$(this).closest("form").submit();
});
}

View File

@ -5,3 +5,10 @@ $ ->
$('.milestone-issue-filter li').toggleClass('active')
$('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
false
$('.milestone-merge-requests-filter tr[data-closed]').addClass('hide')
$('.milestone-merge-requests-filter ul.nav li a').click ->
$('.milestone-merge-requests-filter li').toggleClass('active')
$('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
false

View File

@ -14,8 +14,8 @@ var NoteList = {
this.notes_path = path + ".js";
this.target_id = tid;
this.target_type = tt;
this.reversed = $("#notes-list").hasClass("reversed");
this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
this.reversed = $("#notes-list").is(".reversed");
this.target_params = "target_type=" + this.target_type + "&target_id=" + this.target_id;
// get initial set of notes
this.getContent();
@ -33,6 +33,8 @@ var NoteList = {
$(".note-form-holder").on("ajax:complete", function(){
$(".submit_note").enable();
$('#preview-note').hide();
$('#note_note').show();
})
disableButtonIfEmptyField(".note-text", ".submit_note");
@ -52,6 +54,26 @@ var NoteList = {
$('.note_advanced_opts').show();
});
}
// Setup note preview
$(document).on('click', '#preview-link', function(e) {
$('#preview-note').text('Loading...');
$(this).text($(this).text() === "Edit" ? "Preview" : "Edit");
var note_text = $('#note_note').val();
if(note_text.trim().length === 0) {
$('#preview-note').text('Nothing to preview.');
} else {
$.post($(this).attr('href'), {note: note_text}).success(function(data) {
$('#preview-note').html(data);
});
}
$('#preview-note, #note_note').toggle();
e.preventDefault();
});
},
@ -69,7 +91,7 @@ var NoteList = {
$.ajax({
type: "GET",
url: this.notes_path,
data: "?" + this.target_params,
data: this.target_params,
complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"});
@ -131,7 +153,7 @@ var NoteList = {
$.ajax({
type: "GET",
url: this.notes_path,
data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params,
data: this.target_params + "&loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id,
complete: function(){ $('.notes-status').removeClass("loading")},
beforeSend: function() { $('.notes-status').addClass("loading") },
dataType: "script"});
@ -192,7 +214,7 @@ var NoteList = {
$.ajax({
type: "GET",
url: this.notes_path,
data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params,
data: this.target_params + "&loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id),
dataType: "script"});
},
@ -264,7 +286,7 @@ var PerLineNotes = {
$(this).closest("tr").after(form);
form.find("#note_line_code").val($(this).data("lineCode"));
form.show();
return false;
e.preventDefault();
});
disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
@ -285,7 +307,7 @@ var PerLineNotes = {
// elements must really be removed for this to work reliably
var trLine = trNote.prev();
var trRpl = trNote.next();
if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) {
if (trLine.is(".line_holder") && trRpl.is(".reply")) {
trRpl.fadeOut(function() { $(this).remove(); });
}
});

View File

@ -0,0 +1,10 @@
$ ->
$('.edit_user .application-theme input, .edit_user .code-preview-theme input').click ->
# Hide any previous submission feedback
$('.edit_user .update-feedback').hide()
# Submit the form
$('.edit_user').submit()
# Go up the hierarchy and show the corresponding submission feedback element
$(@).closest('fieldset').find('.update-feedback').show('highlight', {color: '#DFF0D8'}, 500)

View File

@ -22,3 +22,10 @@ $ ->
# Ref switcher
$('.project-refs-select').on 'change', ->
$(@).parents('form').submit()
class @GraphNav
@init: ->
$('.graph svg').css 'position', 'relative'
$('body').bind 'keyup', (e) ->
$('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left
$('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right

View File

@ -1,6 +0,0 @@
$ ->
$('#snippets-table .snippet').live 'click', (e) ->
if e.target.nodeName isnt 'A' and e.target.nodeName isnt 'INPUT'
location.href = $(@).attr 'url'
e.stopPropagation()
false

View File

@ -17,23 +17,40 @@ $ ->
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
"ajax:complete": -> $('.tree_progress').removeClass("loading")
# Maintain forward/back history while browsing the file tree
# Maintain forward/back history while browsing the file tree
((window) ->
History = window.History
$ = window.jQuery
document = window.document
((window) ->
History = window.History
$ = window.jQuery
document = window.document
# Check to see if History.js is enabled for our Browser
unless History.enabled
return false
# Check to see if History.js is enabled for our Browser
unless History.enabled
return false
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
History.pushState(null, null, $(@).attr('href'))
return false
$ ->
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
History.pushState(null, null, $(@).attr('href'))
return false
History.Adapter.bind window, 'statechange', ->
state = History.getState()
window.ajaxGet(state.url)
)(window)
History.Adapter.bind window, 'statechange', ->
state = History.getState()
window.ajaxGet(state.url)
)(window)
# See if there are lines selected
# "#L12" and "#L34-56" supported
highlightBlobLines = ->
if window.location.hash isnt ""
matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
first_line = parseInt(matches?[1])
last_line = parseInt(matches?[3])
unless isNaN first_line
last_line = first_line if isNaN(last_line)
$("#tree-content-holder .highlight .line").removeClass("hll")
$("#LC#{line}").addClass("hll") for line in [first_line..last_line]
$("#L#{first_line}").ScrollTo()
# Highlight the correct lines on load
highlightBlobLines()
# Highlight the correct lines when the hash part of the URL changes
$(window).on 'hashchange', highlightBlobLines

View File

@ -20,18 +20,6 @@ body {
float:right;
}
.profile_avatar_holder {
float:left;
width:60px;
height:60px;
margin-right:20px;
img {
width:60px;
height:60px;
background:#eee;
}
}
.visible_link,
.author_link {
@ -596,25 +584,6 @@ li.note {
}
}
.themes_opts {
padding-left:20px;
label {
width:175px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:120px;
width:175px;
margin-bottom:10px;
img {
width:180px;
}
}
}
}
.git_error_tips {
@extend .span6;
text-align:left;
@ -628,10 +597,11 @@ li.note {
.error_message {
@extend .cred;
border-bottom: 1px solid #D21;
padding-bottom:20px;
text-align:center;
margin-bottom:10px;
border-left: 4px solid #E99;
padding: 10px;
margin-bottom: 10px;
background: #FEE;
padding-left: 20px;
}
.oauth_select_holder {
@ -670,3 +640,16 @@ pre {
padding:0;
}
}
.milestone .progress {
margin-bottom: 0;
margin-top:4px;
}
.float-link {
float:left;
margin-right:15px;
.s16 {
margin-right:5px;
}
}

View File

@ -94,6 +94,7 @@
&.very_small {
font-size:11px;
padding:2px 6px;
line-height: 16px;
margin:2px;
}

View File

@ -26,8 +26,10 @@
.underlined { border-bottom: 1px solid #CCC; }
.no-borders { border:none; }
.vlink { color: $link_color !important; }
.underlined_link { text-decoration: underline; }
.borders { border: 1px solid #ccc; @include shade; }
.hint { font-style: italic; color: #999; }
.light { color: #888 }
/** PILLS & TABS**/
.nav-pills a:hover { background-color:#888; }
@ -38,6 +40,7 @@
> a {
padding:8px 20px;
margin-right: 7px;
line-height: 19px;
border-color: #EEE;
color:#888;
border-bottom: 1px solid #ddd;
@ -66,11 +69,12 @@
.alert-message.error { @extend .alert-error; }
/** AVATARS **/
img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; }
img.avatar.s16 { width:16px; height:16px; }
img.avatar.s24 { width:24px; height:24px; }
img.avatar.s32 { width:32px; height:32px; }
img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; }
img.avatar.s16 { width:16px; height:16px; margin-right:6px; }
img.avatar.s24 { width:24px; height:24px; margin-right:8px; }
img.avatar.s32 { width:32px; height:32px; margin-right:10px; }
img.lil_av { padding-left: 4px; padding-right:3px; }
img.small { width: 80px; }
/** HELPERS **/
.nothing_here_message { text-align:center; padding:20px; color:#777; }
@ -85,3 +89,5 @@ input[type='search'].search-text-input {
@include border-radius(4px);
border:1px solid #ccc;
}
fieldset legend { font-size: 17px; }

View File

@ -132,35 +132,74 @@
* Code file
*/
&.code {
padding:0;
td.code {
width: 100%;
.highlight {
margin-left: 55px;
overflow:auto;
overflow-y:hidden;
}
}
.highlight pre {
white-space: pre;
word-wrap:normal;
}
padding: 0;
table.highlighttable {
table.lines {
border: none;
}
body.project-page table.highlighttable td { border: none }
table.highlighttable tr:hover { background:none;}
box-shadow: none;
margin: 0px;
padding: 0px;
table-layout: fixed;
table.highlighttable pre{
line-height:16px !important;
font-size:12px !important;
}
pre {
background: none;
border: none;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-size: 12px !important;
line-height: 16px !important;
margin: 0;
padding: 10px 0;
}
td {
border: none;
margin: 0;
padding: 0;
vertical-align: top;
table.highlighttable .linenodiv pre {
text-align: right;
padding-right: 4px;
color:#666;
&:first-child {
background: #eee;
width: 50px;
}
&:last-child {
}
}
tr:hover {
background: none;
}
pre.line_numbers {
color: #666;
padding: 10px 6px 10px 0;
text-align: right;
a {
color: #666;
i {
display: none;
font-size: 14px;
line-height: 14px;
}
&:hover i {
display: inherit;
}
}
}
.highlight {
border-left: 1px solid #DEE2E3;
overflow: auto;
overflow-y: hidden;
pre {
white-space: pre;
word-wrap: normal;
.line {
padding: 0 10px;
}
}
}
}
}
}

View File

@ -21,7 +21,7 @@ ul {
.author { color: #999; }
p {
padding-top:5px;
padding-top: 1px;
margin:0;
color:#222;
img {
@ -31,3 +31,11 @@ ul {
}
}
}
ol, ul {
&.styled {
li {
padding:2px;
}
}
}

View File

@ -34,6 +34,11 @@ table {
border-color:#f1f1f1;
line-height:28px;
.s16 {
margin-top: 5px;
margin-right: 5px;
}
&:first-child {
border-left:1px solid #bbb;
}

View File

@ -2,8 +2,11 @@
* Headers
*
*/
h1, h2, h3, h4, h5, h6 { margin: 0; }
h3, h4, h5, h6 { line-height: 36px; }
h5 { font-size:14px; }
h3.page_title {
color:#456;
font-size:20px;
@ -11,6 +14,11 @@ h3.page_title {
line-height: 28px;
}
h6 {
color: #888;
text-transform: uppercase;
}
/** CODE **/
pre {
font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;

View File

@ -1,9 +1,8 @@
.black .highlighttable {
td.linenos { border:none; }
pre { color: #eee }
.highlight { background: #333; border-left:1px solid #555; }
.black .lines .highlight {
background: #333;
pre { color: #eee; }
.hll { background-color: #ffffff }
.hll { display: block; background-color: darken($hover, 65%) }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #CDA869; font-weight: bold } /* Keyword */
@ -22,43 +21,43 @@
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc{font-weight:bold;} /* Keyword.Constant */
.highlight .kd{font-weight:bold;} /* Keyword.Declaration */
.highlight .kn{font-weight:bold;} /* Keyword.Namespace */
.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
.highlight .kr{font-weight:bold;} /* Keyword.Reserved */
.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
.kc{font-weight:bold;} /* Keyword.Constant */
.kd{font-weight:bold;} /* Keyword.Declaration */
.kn{font-weight:bold;} /* Keyword.Namespace */
.kp{font-weight:bold;} /* Keyword.Pseudo */
.kr{font-weight:bold;} /* Keyword.Reserved */
.kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.p { color: #eee; }
.s { color: #0AD; background-color: transparent } /* Literal.String */
.highlight .na{color:#008080;} /* Name.Attribute */
.highlight .nb{color:#0086B3;} /* Name.Builtin */
.highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */
.highlight .no{color:turquoise;} /* Name.Constant */
.highlight .ni{color:#800080;}
.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
.highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */
.highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
.highlight .nt{color:#fc5;} /* Name.Tag */
.highlight .nv{color:#FA4;} /* Name.Variable */
.na{color:#008080;} /* Name.Attribute */
.nb{color:#0086B3;} /* Name.Builtin */
.nc{color:#ccc;font-weight:bold;} /* Name.Class */
.no{color:turquoise;} /* Name.Constant */
.ni{color:#800080;}
.ne{color:#900;font-weight:bold;} /* Name.Exception */
.nf{color:#ccc;font-weight:bold;} /* Name.Function */
.nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
.nt{color:#fc5;} /* Name.Tag */
.nv{color:#FA4;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */
.mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi {color:#099;} /* Literal.Number.Integer */
.mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */
.highlight .sc{color:#d14;} /* Literal.String.Char */
.sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */
.highlight .s2{color:orange;} /* Literal.String.Double */
.highlight .se{color:orange;} /* Literal.String.Escape */
.highlight .sh{color:orange;} /* Literal.String.Heredoc */
.highlight .si{color:orange;} /* Literal.String.Interpol */
.highlight .sx{color:orange;} /* Literal.String.Other */
.highlight .sr{color:orange;} /* Literal.String.Regex */
.highlight .s1{color:orange;} /* Literal.String.Single */
.highlight .ss{color:orange;} /* Literal.String.Symbol */
.s2{color:orange;} /* Literal.String.Double */
.se{color:orange;} /* Literal.String.Escape */
.sh{color:orange;} /* Literal.String.Heredoc */
.si{color:orange;} /* Literal.String.Interpol */
.sx{color:orange;} /* Literal.String.Other */
.sr{color:orange;} /* Literal.String.Regex */
.s1{color:orange;} /* Literal.String.Single */
.ss{color:orange;} /* Literal.String.Symbol */
.bp { color: #D58 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */

View File

@ -1,141 +1,69 @@
table.highlighttable {
margin:0px;
padding:0px;
font-size:12px;
table-layout:fixed;
background: #EEE;
box-shadow: none;
border: none;
td.linenos {
background:#eee;
border-left:none;
}
td.code {
border-right:none;
}
}
td.code,
td.linenos{
padding:0;
margin:0;
border-top:0;
vertical-align:top;
}
.highlighttable .highlight{
background:none;
padding:10px 0px 0px 10px;
margin-left:0px;
border-left: 1px solid #DEE2E3;
.white .lines .highlight {
background: white;
pre { color: #333; }
.hll { display: block; background-color: $hover }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #303030 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc{font-weight:bold;} /* Keyword.Constant */
.kd{font-weight:bold;} /* Keyword.Declaration */
.kn{font-weight:bold;} /* Keyword.Namespace */
.kp{font-weight:bold;} /* Keyword.Pseudo */
.kr{font-weight:bold;} /* Keyword.Reserved */
.kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.na{color:#008080;} /* Name.Attribute */
.nb{color:#0086B3;} /* Name.Builtin */
.nc{color:#458;font-weight:bold;} /* Name.Class */
.no{color:#008080;} /* Name.Constant */
.ni{color:#800080;}
.ne{color:#900;font-weight:bold;} /* Name.Exception */
.nf{color:#900;font-weight:bold;} /* Name.Function */
.nn{color:#005;font-weight:bold;} /* Name.Namespace */
.nt{color:#000080;} /* Name.Tag */
.nv{color:#008080;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.s2{color:#d14;} /* Literal.String.Double */
.se{color:#d14;} /* Literal.String.Escape */
.sh{color:#d14;} /* Literal.String.Heredoc */
.si{color:#d14;} /* Literal.String.Interpol */
.sx{color:#d14;} /* Literal.String.Other */
.sr{color:#d14;} /* Literal.String.Regex */
.s1{color:#d14;} /* Literal.String.Single */
.ss{color:#d14;} /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb }
}
.linenodiv pre,
.highlighttable .highlight pre{
margin:0;
padding:0;
background:none;
border:none;
}
.linenodiv pre {
white-space:pre-line;
}
td.linenos {
/*background:#F7F7F7;*/
color:#666;
padding:10px 0px 0px 10px;
float:left;
width:45px;
border-right: 1px solid #ccc;
}
td.code .highlight {
overflow: auto;
}
table.highlighttable pre{
padding:0;
margin:0;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;
}
.git-empty .highlight {
pre{
padding:15px;
line-height:2.0;
margin:0;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
color: #333;
text-align:left;}
}
.shadow{
.shadow {
-webkit-box-shadow:0 5px 15px #000;
-moz-box-shadow:0 5px 15px #000;
box-shadow:0 5px 15px #000;
}
.hll { background-color: #ffffff }
.c { color: #888888; font-style: italic } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #000000; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #303030 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #606060 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc{font-weight:bold;} /* Keyword.Constant */
.highlight .kd{font-weight:bold;} /* Keyword.Declaration */
.highlight .kn{font-weight:bold;} /* Keyword.Namespace */
.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
.highlight .kr{font-weight:bold;} /* Keyword.Reserved */
.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na{color:#008080;} /* Name.Attribute */
.highlight .nb{color:#0086B3;} /* Name.Builtin */
.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */
.highlight .no{color:#008080;} /* Name.Constant */
.highlight .ni{color:#800080;}
.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */
.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */
.highlight .nt{color:#000080;} /* Name.Tag */
.highlight .nv{color:#008080;} /* Name.Variable */
.py { color: #336699; font-weight: bold } /* Name.Property */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi {color:#099;} /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc{color:#d14;} /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2{color:#d14;} /* Literal.String.Double */
.highlight .se{color:#d14;} /* Literal.String.Escape */
.highlight .sh{color:#d14;} /* Literal.String.Heredoc */
.highlight .si{color:#d14;} /* Literal.String.Interpol */
.highlight .sx{color:#d14;} /* Literal.String.Other */
.highlight .sr{color:#d14;} /* Literal.String.Regex */
.highlight .s1{color:#d14;} /* Literal.String.Single */
.highlight .ss{color:#d14;} /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb }

View File

@ -1,15 +1,21 @@
/** Override bootstrap variables **/
$baseFontSize: 13px !default;
$baseLineHeight: 18px !default;
@import "bootstrap";
@import "bootstrap-responsive";
@import 'font-awesome';
/** GitLab colors **/
$link_color:#3A89A3;
$blue_link: #2fa0bb;
$style_color: #474d57;
$link_color: #3A89A3;
$blue_link: #2FA0BB;
$style_color: #474D57;
$hover: #D9EDF7;
$hover_border: #ADF;
/** GitLab Fonts **/
@font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
/** MIXINS **/
@mixin shade {
@ -19,9 +25,9 @@ $hover: #D9EDF7;
}
@mixin solid_shade {
-moz-box-shadow: 0 0 0 3px #eee;
-webkit-box-shadow: 0 0 0 3px #eee;
box-shadow: 0 0 0 3px #eee;
-moz-box-shadow: 0 0 0 3px #f1f1f1;
-webkit-box-shadow: 0 0 0 3px #f1f1f1;
box-shadow: 0 0 0 3px #f1f1f1;
}
@mixin border-radius($radius) {
@ -64,6 +70,14 @@ $hover: #D9EDF7;
background-image: -o-linear-gradient($from, $to);
}
@mixin bg-light-gray-gradient {
background:#f1f1f1;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));
background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
}
@mixin bg-gray-gradient {
background:#eee;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
@ -104,14 +118,12 @@ $hover: #D9EDF7;
@import "themes/ui_basic.scss";
/**
* UI mars theme
* UI themes:
*/
@import "themes/ui_mars.scss";
/**
* UI Modern theme
*/
@import "themes/ui_modern.scss";
@import "themes/ui_gray.scss";
@import "themes/ui_color.scss";
/**
* GitLab bootstrap.
@ -145,6 +157,7 @@ $hover: #D9EDF7;
@import "sections/merge_requests.scss";
@import "sections/graph.scss";
@import "sections/events.scss";
@import "sections/themes.scss";
/**
* This scss file redefine chozen selectbox styles for

View File

@ -19,41 +19,14 @@
margin-right: 10px;
.chzn-drop {
margin:7px 0;
min-width: 400px;
border: 2px solid $blue_link;
@include border-radius(4px);
.chzn-results {
max-height:300px;
.group-result {
color: $blue_link;
}
.active-result {
&.highlighted {
background: $blue_link;
}
}
}
.chzn-search input {
min-width:365px;
}
}
.chzn-single {
@include bg-gray-gradient;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
}
/** Fix for Search Dropdown Border **/
@ -65,4 +38,55 @@
box-shadow: none;
}
}
.chzn-drop {
margin:7px 0;
min-width: 200px;
border: 1px solid #bbb;
border-radius:0;
.chzn-results {
margin-top: 5px;
max-height:300px;
.group-result {
color: $style_color;
border-bottom: 1px solid #EEE;
padding: 8px;
}
.active-result {
border-radius: 0;
&.highlighted {
background: $hover;
color: $style_color;
}
&.result-selected {
background: #EEE;
border-left: 4px solid #CCC;
}
}
}
.chzn-search {
@include bg-gray-gradient;
input {
min-width:165px;
border-color: #CCC;
}
}
}
.chzn-single {
@include bg-light-gray-gradient;
div {
background:transparent;
border-left:none;
}
span {
font-weight: normal;
}
}
}

View File

@ -47,12 +47,15 @@
padding-left: 32px;
}
.author,
.committer {
.author a,
.committer a {
font-size:14px;
line-height:22px;
text-shadow:0 1px 1px #fff;
color:#777;
&:hover {
color: #999;
}
}
.avatar {
@ -71,7 +74,9 @@
margin-bottom:1em;
.diff_file_header {
padding:7px 5px;
@extend .clearfix;
padding: 5px 5px 5px 10px;
color: #555;
border-bottom:1px solid #CCC;
background: #eee;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
@ -79,8 +84,23 @@
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
span {
> span {
font-family: $monospace;
font-size:14px;
line-height: 30px;
}
a.view-commit{
font-weight: bold;
}
.commit-short-id{
font-family: $monospace;
font-size: smaller;
}
.file-mode{
font-family: $monospace;
}
}
.diff_file_content {
@ -89,7 +109,7 @@
background:#fff;
color:#333;
font-size: 12px;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-family: $monospace;
.old{
span.idiff{
background-color:#FAA;
@ -110,22 +130,34 @@
.diff_file_content_image {
background:#eee;
text-align:center;
img {
.image {
display: inline-block;
margin:50px;
padding:1px;
max-width:400px;
&.diff_image_removed {
border: 1px solid #C00;
img{
background: url('trans_bg.gif');
}
&.diff_image_added {
border: 1px solid #0C0;;
&.diff_removed {
img{
border: 1px solid #C00;
}
}
&.diff_added {
img{
border: 1px solid #0C0;
}
}
.image-info{
margin: 5px 0 0 0;
}
}
&.img_compared {
img {
.image {
max-width:300px;
}
}
@ -222,26 +254,41 @@
float:left;
@extend .lined;
min-width:65px;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-family: $monospace;
}
.commit-author-name {
color: #777;
&:hover {
color: #999;
}
}
}
.diff_file_header a,
.file_stats a {
color:$style_color;
.file-stats a {
color: $style_color;
}
.file_stats {
span {
img {
width:14px;
float:left;
margin-right:6px;
padding:2px 0;
.file-stats {
.new-file{
i{
color: #1BCF00;
}
}
.renamed-file{
i{
color: #FE9300;
}
}
.deleted-file{
i{
color: #FF0000;
}
}
.edit-file{
i{
color: #555;
}
}
}
@ -253,5 +300,5 @@
font-size:13px;
background: #474D57;
color:#fff;
font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
font-family: $monospace;
}

View File

@ -1,14 +1,48 @@
.file-editor {
#editor{
border: none;
border-radius: 0;
height: 500px;
width: 100%;
margin: 0;
padding: 0;
position: relative;
width: 100%;
}
.editor-commit-comment {
padding-top:20px;
.cancel-btn {
color: #B94A48;
&:hover {
color: #B94A48;
}
}
.commit-button-annotation {
@extend .alert;
@extend .alert-info;
display: inline-block;
margin: 0;
padding: 2px;
> * {
float: left;
}
.commit-btn {
@extend .save-btn;
}
.message {
display: inline-block;
margin: 5px 8px 0 8px;
}
}
.commit_message-group {
margin-top: 20px;
label {
font-size: 16px;
line-height: 20px;
}
textarea {
width: 50%;
margin-left: 20px;
@extend .span8;
}
}
}

View File

@ -43,6 +43,7 @@
.event-body {
p {
color:#555;
padding-top: 5px;
}
.event-info {
color:#666;
@ -115,3 +116,29 @@
margin: -3px;
}
}
/**
* Event filter
*
*/
.event_filter {
position: absolute;
width: 40px;
margin-left: -50px;
.filter_icon {
float: left;
border-left: 3px solid #4bc;
padding: 7px;
background: #f9f9f9;
margin-bottom: 10px;
img {
width:20px;
}
&.inactive {
border-left: 3px solid #EEE;
opacity: 0.5;
}
}
}

View File

@ -3,18 +3,29 @@
*
*/
header {
width:100%;
padding:0;
margin:0;
top:1px;
left:0;
background: #F1F1F1; /* for non-css3 browsers */
border-bottom: 1px solid #ccc;
box-shadow: 0 -1px 0 white inset;
-moz-box-shadow: 0 -1px 0 white inset;
-webkit-box-shadow: 0 -1px 0 white inset;
&.navbar-gitlab {
.navbar-inner {
height:45px;
padding: 5px;
background: #F1F1F1;
.nav > li > a {
color: $style_color;
text-shadow: 0 1px 0 #fff;
font-size: 18px;
padding: 11px;
}
/** NAV block with links and profile **/
.nav {
float: right;
margin-right: 0;
}
}
}
z-index:10;
height:60px;
/*height:60px;*/
/**
*
@ -22,45 +33,26 @@ header {
*
*/
.app_logo {
width:200px;
width:170px;
float:left;
position:relative;
top:-5px;
a {
float:left;
padding: 0px;
h1 {
padding-top: 5px;
width:90px;
background: url('logo_dark.png') no-repeat 0px -3px;
background: url('logo_dark.png') no-repeat 0px 2px;
float:left;
margin-left:5px;
font-size:36px;
line-height:36px;
margin-left:2px;
font-size:30px;
line-height:48px;
font-weight:normal;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
padding-left:50px;
padding-left:45px;
height:40px;
font-family: 'Korolev', sans-serif;
}
}
.separator {
margin-left:20px;
float: left;
height: 60px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -10px;
}
}
.container {
.top_panel_content {
margin:auto;
position:relative;
padding:15px 0;
}
}
@ -74,33 +66,23 @@ header {
float:left;
margin:0;
margin-right:30px;
font-size:36px;
line-height:36px;
font-size:30px;
line-height:48px;
font-weight:normal;
color:$style_color;
text-shadow: 0 1px 1px #FFF;
font-family: 'Korolev', sans-serif;
}
.fbtn {
float: right;
margin-right:10px;
.btn {
margin-left:7px;
background: #F1F1F1;
border: 1px solid #CCC;
}
}
/**
*
* Search box
*
*/
.search {
float: right;
margin-right: 45px;
margin-left:10px;
margin-top: 2px;
.search-input {
@extend .span2;
@ -108,8 +90,13 @@ header {
background-repeat: no-repeat;
background-position: 10px;
padding-left:25px;
@include border-radius(5px);
border:1px solid #ccc;
font-size: 13px;
@include border-radius(3px);
border:1px solid #c6c6c6;
box-shadow:none;
&:focus {
@extend .span3;
}
}
}
@ -121,7 +108,7 @@ header {
.account-box {
position: absolute;
right: 0;
top: 13px;
top: 6px;
z-index: 10000;
width: 128px;
font-size: 11px;
@ -129,13 +116,13 @@ header {
display: block;
cursor: pointer;
img {
@include border-radius(4px);
@include border-radius(3px);
right: 5px;
position: absolute;
width: 28px;
height: 28px;
display: block;
top: 2px;
top:1px;
&:after {
content: " ";
display: block;
@ -162,12 +149,7 @@ header {
display: block; } }
.account-links {
background: #79C3E0;
display: none;
border-radius: 5px;
width: 100px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative;
&:before {
@ -177,32 +159,33 @@ header {
position: absolute;
border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #333;
border-bottom-color: #555;
text-indent: -9999px;
top: -10px;
line-height: 0;
right: 10px;
z-index: 10; }
background: #333;
background: #555;
display: none;
z-index: 100000;
border-radius: 5px;
@include border-radius(4px);
width: 100px;
position: absolute;
right: 10px;
top: 42px;
right: 5px;
top: 38px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a {
color: #EEE;
padding: 6px 10px;
color: #fff;
padding: 7px 10px;
display: block;
text-shadow: none;
border-bottom: 1px solid #555;
border-bottom: 1px solid #666;
font-size: 12px;
&:hover {
color:#eee;
background: #444;
color:#fff;
background: #333;
}
}
}
@ -228,5 +211,52 @@ header {
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
border-bottom: 0; } }
/*
* Dark header
*
*/
&.header-dark {
&.navbar-gitlab {
.navbar-inner {
background: #708090;
border-bottom: 1px solid #AAA;
.nav > li > a {
color: #fff;
text-shadow: 0 1px 0 #111;
}
}
}
.search {
.search-input {
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
&:focus {
background-color: white;
}
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.app_logo {
a {
h1 {
background: url('logo_white.png') no-repeat 0px 2px;
color:#fff;
text-shadow: 0 1px 1px #111;
}
}
}
.project_name {
color:#fff;
text-shadow: 0 1px 1px #111;
}
}
}

View File

@ -44,7 +44,7 @@
img.avatar {
width:32px;
margin-top:4px;
margin-top:1px;
}
}
}

View File

@ -71,7 +71,7 @@ li.merge_request {
padding:7px 10px;
img.avatar {
width: 32px;
margin-top: 4px;
margin-top: 1px;
}
p {
padding: 0px;
@ -121,3 +121,25 @@ li.merge_request {
.mr_direction_tip {
margin-top:40px
}
.merge_requests_form_box {
@extend .main_box;
.merge_requests_middle_box {
@extend .middle_box_content;
height:30px;
.merge_requests_assignee {
@extend .span6;
float:left;
}
.merge_requests_milestone {
@extend .span4;
float:left;
}
}
}
.status-badge {
height: 32px;
width: 100%;
@include border-radius(5px);
}

View File

@ -6,7 +6,7 @@ ul.main_menu {
border-radius: 4px;
margin: auto;
margin:30px 0;
border:1px solid #AAA;
border:1px solid #BBB;
height:37px;
@include bg-gray-gradient;
position:relative;

View File

@ -6,3 +6,17 @@
}
}
}
.profile_avatar_holder {
float:left;
width:60px;
height:60px;
margin-right:20px;
img {
width:60px;
height:60px;
background:#fff;
padding: 1px;
border: 1px solid #ddd;
}
}

View File

@ -85,9 +85,18 @@
}
.project_clone_holder {
input[type="text"],
.btn {
font-size:12px;
line-height: 18px;
margin: 0;
padding: 3px 10px;
}
input[type="text"] {
border: 1px solid #BBB;
box-shadow: none;
margin-left: -1px;
}
}

View File

@ -0,0 +1,60 @@
.application-theme, .code-preview-theme {
.update-feedback {
color: #468847;
float: right;
}
}
.themes_opts {
padding-left:20px;
label {
width:175px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:30px;
width:175px;
margin-bottom:10px;
&.classic {
background: #31363e;
}
&.default {
background: #f1f1f1;
}
&.modern {
background: #567;
}
&.gray {
background: #708090;
}
&.violet {
background: #657;
}
}
}
}
.code_highlight_opts {
padding-left:20px;
label {
width:220px;
margin-right:40px;
.prev {
@extend .thumbnail;
height:151px;
width:220px;
margin-bottom:10px;
}
}
}

View File

@ -57,10 +57,7 @@
padding-right: 8px;
img.avatar {
border: 0 none;
float: none;
margin-right: 0;
padding: 0;
margin-top: 0;
width: 16px;
}
}
@ -75,6 +72,15 @@
}
}
}
.blame {
img.avatar {
border: 0 none;
float: none;
margin: 0;
padding: 0;
}
}
}
.tree-btn-group {

View File

@ -16,35 +16,21 @@
}
}
header {
.fbtn {
.btn {
background-color: #F8F8F8;
background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC));
background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC);
background-image: linear-gradient(top,#F8F8F8,#ECECEC);
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec');
border-color: #C6C6C6;
margin-left:7px;
@include border-radius(3px);
box-shadow:none;
color:#666;
}
}
.search {
.search-input {
@include border-radius(3px);
border-color: #C6C6C6;
box-shadow:none;
}
}
.pic {
img {
@include border-radius(3px);
}
.app_logo {
.separator {
margin-left: 0;
margin-right: 0;
}
}
.separator {
float: left;
height: 60px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -10px;
margin-left: 10px;
margin-right: 10px;
}
}

View File

@ -0,0 +1,23 @@
/**
* This file represent some UI that can be changed
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/
.ui_color {
/*
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #657;
}
}
}
}

View File

@ -0,0 +1,23 @@
/**
* This file represent some UI that can be changed
* during web app restyle or theme select.
*
* Next items should be placed there
* - link colors
* - header restyles
*
*/
.ui_gray {
/*
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #708090;
}
}
}
}

View File

@ -14,45 +14,24 @@
*
*/
header {
background: #474D57 url('bg-header.png') repeat-x bottom;
box-shadow:none;
border-bottom: 1px solid #444;
.fbtn {
.btn {
i {
position: relative;
top: 1px;
}
margin-left:8px;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#31363E));
background-image: -webkit-linear-gradient(#595D63 6.6%, #31363E);
background-image: -moz-linear-gradient(#595D63 6.6%, #31363E);
background-image: -o-linear-gradient(#595D63 6.6%, #31363E);
font-size: 12px;
&:hover {
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#2C2F35));
background-image: -webkit-linear-gradient(#595D63 6.6%, #2C2F35);
background-image: -moz-linear-gradient(#595D63 6.6%, #202227);
background-image: -o-linear-gradient(#595D63 6.6%, #202227);
background-position:0 0;
color:#fff;
i {
@extend .icon-white;
}
}
&.navbar-gitlab {
.navbar-inner {
background: #474D57 url('bg-header.png') repeat-x bottom;
border-bottom: 1px solid #444;
border: 1px solid #31363E;
color:#D6DADF;
text-shadow: 0 -1px 0 #000000;
.nav > li > a {
color: #eee;
text-shadow: 0 1px 0 #444;
}
}
}
.search {
float: right;
margin-right: 45px;
.search-input {
border: 1px solid rgba(0, 0, 0, 0.7);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
@ -67,8 +46,8 @@
.app_logo {
a {
h1 {
background: url('logo_white.png') no-repeat 0px -3px;
color:#fff;
background: url('logo_white.png') no-repeat 0px 2px;
color:#eee;
text-shadow: 0 1px 1px #111;
}
}
@ -78,7 +57,7 @@
}
.project_name {
color:#fff;
color:#eee;
text-shadow: 0 1px 1px #111;
}
}

View File

@ -4,8 +4,7 @@
*
* Next items should be placed there
* - link colors
* - header styles
* - main menu styles
* - header restyles
*
*/
.ui_modern {
@ -14,120 +13,10 @@
*
*/
header {
height:40px;
background-image: -moz-linear-gradient(top, #333, #222);
background-image: -ms-linear-gradient(top, #333, #222);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222));
background-image: -webkit-linear-gradient(top, #333, #222);
background-image: -o-linear-gradient(top, #333, #222);
background-image: linear-gradient(top, #333, #222);
background-repeat: repeat-x;
background-repeat: repeat-x;
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
.container .top_panel_content { padding: 5px 0; }
/**
*
* Logo holder
*
*/
.app_logo {
width:160px;
a {
h1 {
background: none;
color:#DDD;
font-size:30px;
text-shadow: 0 1px 1px #111;
padding-left: 0;
}
}
.separator {
width: 1px;
height: 40px;
margin: 0 10px;
overflow: hidden;
background: #222;
border-left: 1px solid #333;
}
}
.fbtn {
.btn {
i {
position: relative;
top: 2px;
}
background:none;
margin-left:8px;
font-size: 13px;
line-height: 19px;
color:#ccc;
&:hover {
color:#fff;
i {
@extend .icon-white;
}
}
border: none;
box-shadow:none;
text-shadow: 0 -1px 0 #000000;
border-left: 1px solid #333;
}
}
/**
*
* Search box
*
*/
.search {
float: right;
margin-right: 45px;
.search-input {
border: 1px solid rgba(0, 0, 0, 0.7);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
&:focus {
background-color: white;
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
}
/**
*
* Project / Area name
*
*/
.project_name {
line-height:36px;
font-size:30px;
color:#DDD;
text-shadow: 0 1px 1px #111;
}
/**
*
* Account box
*
*/
.account-box {
top:6px;
img {
top:1px;
right: 5px;
width: 26px;
height: 26px;
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #567;
}
}
}

View File

@ -21,7 +21,7 @@ class CommitLoadContext < BaseContext
result[:notes_count] = line_notes.count + project.commit_notes(commit).count
begin
result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
rescue Grit::Git::GitTimeout
result[:suppress_diff] = true
result[:status] = :huge_commit

View File

@ -1,3 +1,5 @@
# Build collection of Merge Requests
# based on filtering passed via params for @project
class MergeRequestsLoadContext < BaseContext
def execute
type = params[:f]
@ -9,8 +11,21 @@ class MergeRequestsLoadContext < BaseContext
when 'closed' then merge_requests.closed
when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
else merge_requests.opened
end.page(params[:page]).per(20)
end
merge_requests.includes(:author, :project).order("closed, created_at desc")
merge_requests = merge_requests.page(params[:page]).per(20)
merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc")
# Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present?
merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
end
# Filter by specific milestone_id (or lack thereof)?
if params[:milestone_id].present?
merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
end
merge_requests
end
end

View File

@ -13,6 +13,7 @@ class SearchContext
result[:projects] = Project.where(id: project_ids).search(query).limit(10)
result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10)
result
end
@ -20,7 +21,8 @@ class SearchContext
@result ||= {
projects: [],
merge_requests: [],
issues: []
issues: [],
wiki_pages: []
}
end
end

View File

@ -1,8 +1,13 @@
class Admin::DashboardController < AdminController
def index
@workers = Resque.workers
@pending_jobs = Resque.size(:post_receive)
@projects = Project.order("created_at DESC").limit(10)
@users = User.order("created_at DESC").limit(10)
@resque_accessible = true
@workers = Resque.workers
@pending_jobs = Resque.size(:post_receive)
rescue Redis::InheritedError
@resque_accessible = false
end
end

View File

@ -4,7 +4,7 @@ class Admin::ProjectsController < AdminController
def index
@admin_projects = Project.scoped
@admin_projects = @admin_projects.search(params[:name]) if params[:name].present?
@admin_projects = @admin_projects.page(params[:page]).per(20)
@admin_projects = @admin_projects.order("name ASC").page(params[:page]).per(20)
end
def show

View File

@ -98,6 +98,9 @@ class Admin::UsersController < AdminController
def destroy
@admin_user = User.find(params[:id])
if @admin_user.my_own_projects.count > 0
redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return
end
@admin_user.destroy
respond_to do |format|

View File

@ -9,19 +9,28 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can?
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
log_exception(exception)
render "errors/gitolite", layout: "errors", status: 500
end
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
render "errors/encoding", layout: "errors", status: 500
end
rescue_from ActiveRecord::RecordNotFound do |exception|
log_exception(exception)
render "errors/not_found", layout: "errors", status: 404
end
protected
def log_exception(exception)
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
application_trace.map!{ |t| " #{t}\n" }
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
end
def reject_blocked!
if current_user && current_user.blocked
sign_out current_user

View File

@ -1,7 +1,6 @@
# Controller for viewing a file's blame
class BlobController < ProjectResourceController
include ExtractsPath
include Gitlab::Encode
# Authorize
before_filter :authorize_read_project!
@ -12,16 +11,9 @@ class BlobController < ProjectResourceController
def show
if @tree.is_blob?
if @tree.text?
encoding = detect_encoding(@tree.data)
mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
else
mime_type = @tree.mime_type
end
send_data(
@tree.data,
type: mime_type,
type: @tree.mime_type,
disposition: 'inline',
filename: @tree.name
)

View File

@ -1,12 +1,17 @@
class DashboardController < ApplicationController
respond_to :html
before_filter :event_filter, only: :index
def index
@groups = Group.where(id: current_user.projects.pluck(:group_id))
@projects = current_user.projects_with_events
@projects = current_user.projects_sorted_by_activity
@projects = @projects.page(params[:page]).per(30)
@events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0)
@events = Event.in_projects(current_user.project_ids)
@events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push
respond_to do |format|
@ -34,4 +39,8 @@ class DashboardController < ApplicationController
format.atom { render layout: false }
end
end
def event_filter
@event_filter ||= EventFilter.new(params[:event_filter])
end
end

View File

@ -54,7 +54,7 @@ class GroupsController < ApplicationController
end
def projects
@projects ||= current_user.projects_with_events.where(group_id: @group.id)
@projects ||= current_user.projects_sorted_by_activity.where(group_id: @group.id)
end
def project_ids

View File

@ -31,7 +31,8 @@ class MilestonesController < ProjectResourceController
def show
@issues = @milestone.issues
@users = @milestone.participants
@users = UserDecorator.decorate(@milestone.participants)
@merge_requests = @milestone.merge_requests
respond_to do |format|
format.html

View File

@ -9,7 +9,11 @@ class ProfileController < ApplicationController
def update
@user.update_attributes(params[:user])
redirect_to :back
respond_to do |format|
format.html { redirect_to :back }
format.js
end
end
def token
@ -22,7 +26,7 @@ class ProfileController < ApplicationController
flash[:notice] = "Password was successfully updated. Please login with it"
redirect_to new_user_session_path
else
render action: "password"
render 'account'
end
end

View File

@ -1,4 +1,4 @@
require Rails.root.join('lib', 'gitlab', 'graph_commit')
require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
class ProjectsController < ProjectResourceController
skip_before_filter :project, only: [:new, :create]
@ -21,9 +21,10 @@ class ProjectsController < ProjectResourceController
@project = Project.create_by_user(params[:project], current_user)
respond_to do |format|
flash[:notice] = 'Project was successfully created.' if @project.saved?
format.html do
if @project.saved?
redirect_to(@project, notice: 'Project was successfully created.')
redirect_to @project
else
render action: "new"
end
@ -79,7 +80,9 @@ class ProjectsController < ProjectResourceController
end
def graph
@days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
graph = Gitlab::Graph::JsonBuilder.new(project)
@days_json, @commits_json = graph.days_json, graph.commits_json
end
def destroy

View File

@ -1,5 +1,4 @@
class RefsController < ProjectResourceController
include Gitlab::Encode
# Authorize
before_filter :authorize_read_project!

View File

@ -16,9 +16,14 @@ class RepositoriesController < ProjectResourceController
@tags = @project.tags
end
def stats
@stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
@graph = @stats.graph
end
def archive
unless can?(current_user, :download_code, @project)
render_404 and return
render_404 and return
end

View File

@ -5,5 +5,6 @@ class SearchController < ApplicationController
@projects = result[:projects]
@merge_requests = result[:merge_requests]
@issues = result[:issues]
@wiki_pages = result[:wiki_pages]
end
end

View File

@ -0,0 +1,37 @@
class ServicesController < ProjectResourceController
# Authorize
before_filter :authorize_admin_project!
respond_to :html
def index
@gitlab_ci_service = @project.gitlab_ci_service
end
def edit
@service = @project.gitlab_ci_service
# Create if missing
@service = @project.create_gitlab_ci_service unless @service
end
def update
@service = @project.gitlab_ci_service
if @service.update_attributes(params[:service])
redirect_to edit_project_service_path(@project, :gitlab_ci)
else
render 'edit'
end
end
def test
commits = project.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
@service = project.gitlab_ci_service
@service.execute(data)
redirect_to :back
end
end

View File

@ -26,15 +26,14 @@ class TreeController < ProjectResourceController
end
def update
file_editor = Gitlab::FileEditor.new(current_user, @project, @ref)
update_status = file_editor.update(
@path,
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
updated_successfully = edit_file_action.commit!(
params[:content],
params[:commit_message],
params[:last_commit]
)
if update_status
if updated_successfully
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
else
flash[:notice] = "Your changes could not be commited, because the file has been changed"

View File

@ -47,21 +47,15 @@ class CommitDecorator < ApplicationDecorator
# Otherwise it will link to the author email as specified in the commit.
#
# options:
# avatar: true will prepend avatar image
def author_link(options)
text = if options[:avatar]
avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16
"#{avatar} #{author_name}"
else
author_name
end
team_member = @project.try(:team_member_by_name_or_email, author_name, author_email)
# avatar: true will prepend the avatar image
# size: size of the avatar image in px
def author_link(options = {})
person_link(options.merge source: :author)
end
if team_member.nil?
h.mail_to author_email, text.html_safe, class: "commit-author-link"
else
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link"
end
# Just like #author_link but for the committer.
def committer_link(options = {})
person_link(options.merge source: :committer)
end
protected
@ -69,4 +63,30 @@ class CommitDecorator < ApplicationDecorator
def no_commit_message
"--no commit message"
end
# Private: Returns a link to a person. If the person has a matching user and
# is a member of the current @project it will link to the team member page.
# Otherwise it will link to the person email as specified in the commit.
#
# options:
# source: one of :author or :committer
# avatar: true will prepend the avatar image
# size: size of the avatar image in px
def person_link(options = {})
source_name = send "#{options[:source]}_name".to_sym
source_email = send "#{options[:source]}_email".to_sym
text = if options[:avatar]
avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size]
%Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
else
source_name
end
team_member = @project.try(:team_member_by_name_or_email, source_name, source_email)
if team_member.nil?
h.mail_to source_email, text.html_safe, class: "commit-#{options[:source]}-link"
else
h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-#{options[:source]}-link"
end
end
end

View File

@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator
#parts = parts[0...-1] if is_blob?
yield(h.link_to("..", "#", remote: true)) if parts.count > max_links
yield(h.link_to("..", "#")) if parts.count > max_links
parts.each do |part|
part_path = File.join(part_path, part) unless part_path.empty?
part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true))
yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
end
end
end

View File

@ -0,0 +1,11 @@
class UserDecorator < ApplicationDecorator
decorates :user
def avatar_image size = 16
h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size
end
def tm_of(project)
project.team_member_by_id(self.id)
end
end

View File

@ -36,7 +36,7 @@ module ApplicationHelper
else
gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
user_email.strip!
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
"#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm"
end
end

View File

@ -57,12 +57,17 @@ module CommitsHelper
def image_diff_class(diff)
if diff.deleted_file
"diff_image_removed"
"diff_removed"
elsif diff.new_file
"diff_image_added"
"diff_added"
else
nil
end
end
def commit_to_html commit
if commit.model
escape_javascript(render 'commits/commit', commit: commit)
end
end
end

View File

@ -33,4 +33,22 @@ module EventsHelper
image_tag event_image_path
end
end
def event_filter_link key, tooltip
key = key.to_s
filter = @event_filter.options key
inactive = if @event_filter.active? key
nil
else
'inactive'
end
content_tag :div, class: "filter_icon #{inactive}" do
link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do
image_tag "event_filter_#{key}.png"
end
end
end
end

View File

@ -38,4 +38,8 @@ module MergeRequestsHelper
classes << " merged" if mr.merged?
classes
end
def ci_status_path
@project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
end
end

View File

@ -10,5 +10,9 @@ module ProjectsHelper
def link_to_project project
link_to project.name, project
end
def tm_path team_member
project_team_member_path(@project, team_member)
end
end

View File

@ -67,4 +67,29 @@ module TreeHelper
can?(current_user, :push_code, @project)
end
end
# Breadcrumb links for a Project and, if applicable, a tree path
def breadcrumbs
return unless @project && @ref
# Add the root project link and the arrow icon
crumbs = content_tag(:li) do
content_tag(:span, nil, class: 'arrow') +
link_to(@project.name, project_commits_path(@project, @ref))
end
if @path
parts = @path.split('/')
parts.each_with_index do |part, i|
crumbs += content_tag(:span, '/', class: 'divider')
crumbs += content_tag(:li) do
# The text is just the individual part, but the link needs all the parts before it
link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
end
end
end
crumbs.html_safe
end
end

View File

@ -1,9 +1,13 @@
class Commit
include ActiveModel::Conversion
include Gitlab::Encode
include StaticModel
extend ActiveModel::Naming
# Safe amount of files with diffs in one commit to render
# Used to prevent 500 error on huge commits by suppressing diff
#
DIFF_SAFE_SIZE = 100
attr_accessor :commit, :head, :refs
delegate :message, :authored_date, :committed_date, :parents, :sha,
@ -107,7 +111,7 @@ class Commit
end
def safe_message
@safe_message ||= utf8 message
@safe_message ||= message
end
def created_at
@ -119,7 +123,7 @@ class Commit
end
def author_name
utf8 author.name
author.name
end
# Was this commit committed by a different person than the original author?
@ -128,7 +132,7 @@ class Commit
end
def committer_name
utf8 committer.name
committer.name
end
def committer_email

View File

@ -1,3 +1,19 @@
# == Schema Information
#
# Table name: events
#
# id :integer not null, primary key
# target_type :string(255)
# target_id :integer
# title :string(255)
# data :text
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# action :integer
# author_id :integer
#
class Event < ActiveRecord::Base
include PushEvent
@ -144,20 +160,3 @@ class Event < ActiveRecord::Base
end
end
end
# == Schema Information
#
# Table name: events
#
# id :integer not null, primary key
# target_type :string(255)
# target_id :integer
# title :string(255)
# data :text
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# action :integer
# author_id :integer
#

View File

@ -0,0 +1,39 @@
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# token :string(255)
# project_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
# active :boolean default(FALSE), not null
# project_url :string(255)
#
class GitlabCiService < Service
attr_accessible :project_url
validates :project_url, presence: true, if: :activated?
validates :token, presence: true, if: :activated?
delegate :execute, to: :service_hook, prefix: nil
after_save :compose_service_hook, if: :activated?
def activated?
active
end
def compose_service_hook
hook = service_hook || build_service_hook
hook.url = [project_url, "/build", "?token=#{token}"].join("")
hook.save
end
def commit_badge_path sha
project_url + "/status?sha=#{sha}"
end
end

View File

@ -1,3 +1,15 @@
# == Schema Information
#
# Table name: groups
#
# id :integer not null, primary key
# name :string(255) not null
# code :string(255) not null
# owner_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Group < ActiveRecord::Base
attr_accessible :code, :name, :owner_id
@ -22,16 +34,3 @@ class Group < ActiveRecord::Base
User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq
end
end
# == Schema Information
#
# Table name: groups
#
# id :integer not null, primary key
# name :string(255) not null
# code :string(255) not null
# owner_id :integer not null
# created_at :datetime not null
# updated_at :datetime not null
#

View File

@ -1,3 +1,21 @@
# == Schema Information
#
# Table name: issues
#
# id :integer not null, primary key
# title :string(255)
# assignee_id :integer
# author_id :integer
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# closed :boolean default(FALSE), not null
# position :integer default(0)
# branch_name :string(255)
# description :text
# milestone_id :integer
#
class Issue < ActiveRecord::Base
include IssueCommonality
include Votes
@ -7,30 +25,9 @@ class Issue < ActiveRecord::Base
acts_as_taggable_on :labels
belongs_to :milestone
validates :description, length: { within: 0..2000 }
def self.open_for(user)
opened.assigned(user)
end
end
# == Schema Information
#
# Table name: issues
#
# id :integer not null, primary key
# title :string(255)
# assignee_id :integer
# author_id :integer
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# closed :boolean default(FALSE), not null
# position :integer default(0)
# branch_name :string(255)
# description :text
# milestone_id :integer
#

View File

@ -1,3 +1,17 @@
# == Schema Information
#
# Table name: keys
#
# id :integer not null, primary key
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# key :text
# title :string(255)
# identifier :string(255)
# project_id :integer
#
require 'digest/md5'
class Key < ActiveRecord::Base
@ -67,18 +81,3 @@ class Key < ActiveRecord::Base
Key.where(identifier: identifier).count == 0
end
end
# == Schema Information
#
# Table name: keys
#
# id :integer not null, primary key
# user_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# key :text
# title :string(255)
# identifier :string(255)
# project_id :integer
#

View File

@ -1,10 +1,32 @@
# == Schema Information
#
# Table name: merge_requests
#
# id :integer not null, primary key
# target_branch :string(255) not null
# source_branch :string(255) not null
# project_id :integer not null
# author_id :integer
# assignee_id :integer
# title :string(255)
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
# st_commits :text(2147483647)
# st_diffs :text(2147483647)
# merged :boolean default(FALSE), not null
# state :integer default(1), not null
# milestone_id :integer
#
require Rails.root.join("app/models/commit")
require Rails.root.join("app/roles/static_model")
class MergeRequest < ActiveRecord::Base
include IssueCommonality
include Votes
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch,
attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id,
:author_id_of_changes
attr_accessor :should_remove_source_branch
@ -26,6 +48,10 @@ class MergeRequest < ActiveRecord::Base
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
end
def self.find_all_by_milestone(milestone)
where("milestone_id = :milestone_id", milestone_id: milestone)
end
def human_state
states = {
CAN_BE_MERGED => "can_be_merged",
@ -60,7 +86,7 @@ class MergeRequest < ActiveRecord::Base
end
def check_if_can_be_merged
self.state = if Gitlab::Merge.new(self, self.author).can_be_merged?
self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
CAN_BE_MERGED
else
CANNOT_BE_MERGED
@ -167,7 +193,7 @@ class MergeRequest < ActiveRecord::Base
end
def automerge!(current_user)
if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty?
if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty?
self.merge!(current_user.id)
true
end
@ -193,24 +219,3 @@ class MergeRequest < ActiveRecord::Base
Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
end
end
# == Schema Information
#
# Table name: merge_requests
#
# id :integer not null, primary key
# target_branch :string(255) not null
# source_branch :string(255) not null
# project_id :integer not null
# author_id :integer
# assignee_id :integer
# title :string(255)
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
# st_commits :text(4294967295
# st_diffs :text(4294967295
# merged :boolean default(FALSE), not null
# state :integer default(1), not null
#

View File

@ -1,11 +1,27 @@
# == Schema Information
#
# Table name: milestones
#
# id :integer not null, primary key
# title :string(255) not null
# project_id :integer not null
# description :text
# due_date :date
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Milestone < ActiveRecord::Base
attr_accessible :title, :description, :due_date, :closed
belongs_to :project
has_many :issues
has_many :merge_requests
validates :title, presence: true
validates :project, presence: true
validates :closed, inclusion: { in: [true, false] }
def self.active
where("due_date > ? OR due_date IS NULL", Date.today)
@ -15,8 +31,20 @@ class Milestone < ActiveRecord::Base
User.where(id: issues.pluck(:assignee_id))
end
def open_items_count
self.issues.opened.count + self.merge_requests.opened.count
end
def closed_items_count
self.issues.closed.count + self.merge_requests.closed.count
end
def total_items_count
self.issues.count + self.merge_requests.count
end
def percent_complete
((self.issues.closed.count * 100) / self.issues.count).abs
((closed_items_count * 100) / total_items_count).abs
rescue ZeroDivisionError
100
end
@ -25,18 +53,3 @@ class Milestone < ActiveRecord::Base
"expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
end
end
# == Schema Information
#
# Table name: milestones
#
# id :integer not null, primary key
# title :string(255) not null
# project_id :integer not null
# description :text
# due_date :date
# closed :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#

View File

@ -1,3 +1,19 @@
# == Schema Information
#
# Table name: notes
#
# id :integer not null, primary key
# note :text
# noteable_id :string(255)
# noteable_type :string(255)
# author_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# project_id :integer
# attachment :string(255)
# line_code :string(255)
#
require 'carrierwave/orm/activerecord'
require 'file_size_validator'
@ -23,13 +39,13 @@ class Note < ActiveRecord::Base
mount_uploader :attachment, AttachmentUploader
# Scopes
scope :common, where(noteable_id: nil)
scope :today, where("created_at >= :date", date: Date.today)
scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
scope :common, ->{ where(noteable_id: nil) }
scope :today, ->{ where("created_at >= :date", date: Date.today) }
scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
scope :since, ->(day) { where("created_at >= :date", date: (day)) }
scope :fresh, order("created_at ASC, id ASC")
scope :inc_author_project, includes(:project, :author)
scope :inc_author, includes(:author)
scope :fresh, ->{ order("created_at ASC, id ASC") }
scope :inc_author_project, ->{ includes(:project, :author) }
scope :inc_author, ->{ includes(:author) }
def self.create_status_change_note(noteable, author, status)
create({
@ -107,20 +123,3 @@ class Note < ActiveRecord::Base
note.start_with?('-1') || note.start_with?(':-1:')
end
end
# == Schema Information
#
# Table name: notes
#
# id :integer not null, primary key
# note :text
# noteable_id :string(255)
# noteable_type :string(255)
# author_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# project_id :integer
# attachment :string(255)
# line_code :string(255)
#

View File

@ -1,3 +1,24 @@
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
# created_at :datetime not null
# updated_at :datetime not null
# private_flag :boolean default(TRUE), not null
# code :string(255)
# owner_id :integer
# default_branch :string(255)
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# group_id :integer
#
require "grit"
class Project < ActiveRecord::Base
@ -26,6 +47,7 @@ class Project < ActiveRecord::Base
has_many :wikis, dependent: :destroy
has_many :protected_branches, dependent: :destroy
has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
has_one :gitlab_ci_service, dependent: :destroy
delegate :name, to: :owner, allow_nil: true, prefix: true
@ -104,8 +126,10 @@ class Project < ActiveRecord::Base
end
def repo_name
if path == "gitolite-admin"
errors.add(:path, " like 'gitolite-admin' is not allowed")
denied_paths = %w(gitolite-admin groups projects dashboard)
if denied_paths.include?(path)
errors.add(:path, "like #{path} is not allowed")
end
end
@ -160,26 +184,12 @@ class Project < ActiveRecord::Base
def issues_labels
issues.tag_counts_on(:labels)
end
def services
[gitlab_ci_service].compact
end
def gitlab_ci?
gitlab_ci_service && gitlab_ci_service.active
end
end
# == Schema Information
#
# Table name: projects
#
# id :integer not null, primary key
# name :string(255)
# path :string(255)
# description :text
# created_at :datetime not null
# updated_at :datetime not null
# private_flag :boolean default(TRUE), not null
# code :string(255)
# owner_id :integer
# default_branch :string(255)
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# group_id :integer
#

View File

@ -1,16 +1,16 @@
class ProjectHook < WebHook
belongs_to :project
end
# == Schema Information
#
# Table name: web_hooks
#
# id :integer not null, primary key
# id :integer not null, primary key
# url :string(255)
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# type :string(255) default("ProjectHook")
# created_at :datetime not null
# updated_at :datetime not null
# type :string(255) default("ProjectHook")
# service_id :integer
#
class ProjectHook < WebHook
belongs_to :project
end

View File

@ -1,3 +1,14 @@
# == Schema Information
#
# Table name: protected_branches
#
# id :integer not null, primary key
# project_id :integer not null
# name :string(255) not null
# created_at :datetime not null
# updated_at :datetime not null
#
class ProtectedBranch < ActiveRecord::Base
include GitHost
@ -18,15 +29,3 @@ class ProtectedBranch < ActiveRecord::Base
project.commit(self.name)
end
end
# == Schema Information
#
# Table name: protected_branches
#
# id :integer not null, primary key
# project_id :integer not null
# name :string(255) not null
# created_at :datetime not null
# updated_at :datetime not null
#

Some files were not shown because too many files have changed in this diff Show More