Commit 319f0c30573d1f2158adf52276981b2c7780392f

Authored by Dmitriy Zaporozhets
2 parents e469084c ced242a2

Merge branch 'master' into stable

Conflicts:
	doc/install/installation.md
Showing 510 changed files with 105376 additions and 3191 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 510 files displayed.

.travis.yml
... ... @@ -3,8 +3,11 @@ env:
3 3 - DB=mysql
4 4 before_install:
5 5 - sudo apt-get install libicu-dev -y
6   - - sudo apt-get install libqt4-dev libqtwebkit-dev -y
7   - - gem install charlock_holmes -v="0.6.8"
  6 + - wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2
  7 + - tar -xf /tmp/phantomjs-1.7.0-linux-i686.tar.bz2 -C /tmp/
  8 + - sudo rm -rf /usr/local/phantomjs
  9 + - sudo mv /tmp/phantomjs-1.7.0-linux-i686 /usr/local/phantomjs
  10 + - gem install charlock_holmes -v="0.6.9"
8 11 branches:
9 12 only:
10 13 - 'master'
... ...
CHANGELOG
  1 +v 3.1.0
  2 + - Updated gems
  3 + - Services: Gitlab CI integration
  4 + - Events filter on dashboard
  5 + - Own namespace for redis/resque
  6 + - Optimized commit diff views
  7 + - add alphabetical order for projects admin page
  8 + - Improved web editor
  9 + - Commit stats page
  10 + - Documentation split and cleanup
  11 + - Link to commit authors everywhere
  12 + - Restyled milestones list
  13 + - added Milestone to Merge Request
  14 + - Restyled Top panel
  15 + - Refactored Satellite Code
  16 + - Added file line links
  17 + - moved from capybara-webkit to poltergeist + phantomjs
  18 +
1 19 v 3.0.3
2 20 - Fixed bug with issues list in Chrome
3 21 - New Feature: Import team from another project
... ... @@ -28,7 +46,7 @@ v 3.0.0
28 46 - Reject ssh keys that break gitolite
29 47 - [API] list one project hook
30 48 - [API] edit project hook
31   - - [API] add project snippets list
  49 + - [API] list project snippets
32 50 - [API] allow to authorize using private token in HTTP header
33 51 - [API] add user creation
34 52  
... ...
CONTRIBUTING.md
1   -## Contribute to GitLab
  1 +## Contribute to GitLab
2 2  
3 3 If you want to contribute to GitLab, follow this process:
4 4  
... ... @@ -7,24 +7,20 @@ If you want to contribute to GitLab, follow this process:
7 7 3. Code
8 8 4. Create a pull request
9 9  
10   -We will only accept pull requests if:
  10 +We will only accept pull requests if:
11 11  
12 12 * Your code has proper tests and all tests pass
13   -* Your code can be merged w/o problems
  13 +* Your code can be merged w/o problems
14 14 * It won't break existing functionality
15 15 * It's quality code
16 16 * We like it :)
17 17  
18   -## [You may need a developer VM](https://github.com/gitlabhq/developer-vm)
  18 +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).
19 19  
20   -## Running tests
21   -
22   -To run the specs for GitLab, you need to run seeds for test db.
  20 +## Installation
23 21  
24   - cd gitlabhq
25   - rake db:seed_fu RAILS_ENV=test
  22 +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.
26 23  
27   -Then you can run the test suite with rake:
28   -
29   - rake gitlab:test
  24 +## Running tests
30 25  
  26 +For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md)
... ...
Gemfile
... ... @@ -8,34 +8,35 @@ def linux_only(require_as)
8 8 RUBY_PLATFORM.include?('linux') && require_as
9 9 end
10 10  
11   -gem "rails", "3.2.8"
  11 +gem "rails", "3.2.9"
12 12  
13 13 # Supported DBs
14   -gem "sqlite3", :group => :sqlite
15   -gem "mysql2", :group => :mysql
16   -gem "pg", :group => :postgres
  14 +gem "sqlite3", group: :sqlite
  15 +gem "mysql2", group: :mysql
  16 +gem "pg", group: :postgres
17 17  
18 18 # Auth
19 19 gem "devise", "~> 2.1.0"
20   -gem 'omniauth'
  20 +gem 'omniauth', "~> 1.1.1"
21 21 gem 'omniauth-google-oauth2'
22 22 gem 'omniauth-twitter'
23 23 gem 'omniauth-github'
24 24  
25 25 # GITLAB patched libs
26   -gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837"
27   -gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e"
28   -gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git"
29   -gem 'grack', :git => "https://github.com/gitlabhq/grack.git"
  26 +gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
  27 +gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e'
  28 +gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd'
  29 +gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
  30 +gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10'
30 31  
31 32 # Gitolite client (for work with gitolite-admin repo)
32 33 gem "gitolite", '1.1.0'
33 34  
34 35 # Syntax highlighter
35   -gem "pygments.rb", "0.3.1"
  36 +gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4'
36 37  
37 38 # Language detection
38   -gem "github-linguist", "~> 2.3.4" , :require => "linguist"
  39 +gem "github-linguist", "~> 2.3.4" , require: "linguist"
39 40  
40 41 # API
41 42 gem "grape", "~> 0.2.1"
... ... @@ -45,13 +46,13 @@ gem "grape", "~> 0.2.1"
45 46 gem "stamp"
46 47  
47 48 # Pagination
48   -gem "kaminari"
  49 +gem "kaminari", "~> 0.14.1"
49 50  
50 51 # HAML
51   -gem "haml-rails"
  52 +gem "haml-rails", "~> 0.3.5"
52 53  
53 54 # Files attachments
54   -gem "carrierwave"
  55 +gem "carrierwave", "~> 0.7.1"
55 56  
56 57 # Authorization
57 58 gem "six"
... ... @@ -63,59 +64,57 @@ gem "ffaker"
63 64 gem "seed-fu"
64 65  
65 66 # Markdown to HTML
66   -gem "redcarpet", "~> 2.1.1"
  67 +gem "redcarpet", "~> 2.2.2"
67 68 gem "github-markup", "~> 0.7.4", require: 'github/markup'
68 69  
69 70 # Servers
70   -gem "thin"
71   -gem "unicorn"
  71 +gem "thin", '~> 1.5.0'
  72 +gem "unicorn", "~> 4.4.0"
72 73  
73 74 # Issue tags
74   -gem "acts-as-taggable-on", "2.3.1"
  75 +gem "acts-as-taggable-on", "2.3.3"
75 76  
76 77 # Decorators
77   -gem "draper"
  78 +gem "draper", "~> 0.18.0"
78 79  
79 80 # Background jobs
80   -gem "resque", "~> 1.20.0"
  81 +gem "resque", "~> 1.23.0"
81 82 gem 'resque_mailer'
82 83  
83 84 # HTTP requests
84 85 gem "httparty"
85 86  
86   -# Handle encodings
87   -gem "charlock_holmes"
88   -
89 87 # Colored output to console
90 88 gem "colored"
91 89  
92   -# GITLAB settings
  90 +# GitLab settings
93 91 gem 'settingslogic'
94 92  
95 93 # Misc
96 94 gem "foreman"
97   -gem 'gemoji', require: 'emoji/railtie'
98 95 gem "git"
99 96  
100 97 group :assets do
101   - gem "sass-rails", "3.2.5"
102   - gem "coffee-rails", "3.2.2"
103   - gem "uglifier", "1.0.3"
  98 + gem "sass-rails", "~> 3.2.5"
  99 + gem "coffee-rails", "~> 3.2.2"
  100 + gem "uglifier", "~> 1.3.0"
104 101 gem "therubyracer"
105 102  
106   - gem 'chosen-rails'
107   - gem 'jquery-atwho-rails', '0.1.6'
108   - gem "jquery-rails", "2.0.2"
109   - gem "jquery-ui-rails", "0.5.0"
110   - gem "modernizr", "2.5.3"
111   - gem "raphael-rails", "1.5.2"
112   - gem 'bootstrap-sass', "2.0.4"
  103 + gem 'chosen-rails', "0.9.8"
  104 + gem 'jquery-atwho-rails', "0.1.6"
  105 + gem "jquery-rails", "2.1.3"
  106 + gem "jquery-ui-rails", "2.0.2"
  107 + gem "modernizr", "2.6.2"
  108 + gem "raphael-rails", "2.1.0"
  109 + gem 'bootstrap-sass', "2.2.1.1"
113 110 gem "font-awesome-sass-rails", "~> 2.0.0"
  111 + gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
114 112 end
115 113  
116 114 group :development do
  115 + gem "annotate", git: "https://github.com/ctran/annotate_models.git"
117 116 gem "letter_opener"
118   - gem "annotate", :git => "https://github.com/ctran/annotate_models.git"
  117 + gem 'quiet_assets', '~> 1.0.1'
119 118 gem 'rack-mini-profiler'
120 119 end
121 120  
... ... @@ -124,8 +123,6 @@ group :development, :test do
124 123 gem 'spinach-rails'
125 124 gem "rspec-rails"
126 125 gem "capybara"
127   - gem "capybara-webkit"
128   - gem "headless"
129 126 gem "pry"
130 127 gem "awesome_print"
131 128 gem "database_cleaner"
... ... @@ -137,14 +134,17 @@ group :development, :test do
137 134 gem 'guard-spinach'
138 135  
139 136 # Notification
140   - gem 'rb-fsevent', :require => darwin_only('rb-fsevent')
141   - gem 'growl', :require => darwin_only('growl')
142   - gem 'rb-inotify', :require => linux_only('rb-inotify')
  137 + gem 'rb-fsevent', require: darwin_only('rb-fsevent')
  138 + gem 'growl', require: darwin_only('growl')
  139 + gem 'rb-inotify', require: linux_only('rb-inotify')
  140 +
  141 + # PhantomJS driver for Capybara
  142 + gem 'poltergeist'
143 143 end
144 144  
145 145 group :test do
146   - gem "simplecov", :require => false
147   - gem "shoulda-matchers"
  146 + gem "simplecov", require: false
  147 + gem "shoulda-matchers", "1.3.0"
148 148 gem 'email_spec'
149 149 gem 'resque_spec'
150 150 gem "webmock"
... ... @@ -152,5 +152,5 @@ group :test do
152 152 end
153 153  
154 154 group :production do
155   - gem "gitlab_meta", '3.0'
  155 + gem "gitlab_meta", '3.1'
156 156 end
... ...
Gemfile.lock
1 1 GIT
2 2 remote: https://github.com/ctran/annotate_models.git
3   - revision: 18cd39ad01829deba5aa34634b8540d6675ab978
  3 + revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
4 4 specs:
5   - annotate (2.4.1.beta1)
  5 + annotate (2.6.0.beta1)
  6 + activerecord (>= 2.3.0)
  7 + rake (>= 0.8.7)
6 8  
7 9 GIT
8 10 remote: https://github.com/gitlabhq/grack.git
9 11 revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
  12 + ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
10 13 specs:
11 14 grack (1.0.0)
12 15 rack (~> 1.4.1)
... ... @@ -22,6 +25,14 @@ GIT
22 25 posix-spawn (~> 0.3.6)
23 26  
24 27 GIT
  28 + remote: https://github.com/gitlabhq/grit_ext.git
  29 + revision: 212fd40bea61f3c6a167223768e7295dc32bbc10
  30 + ref: 212fd40bea61f3c6a167223768e7295dc32bbc10
  31 + specs:
  32 + grit_ext (0.6.0)
  33 + charlock_holmes (~> 0.6.9)
  34 +
  35 +GIT
25 36 remote: https://github.com/gitlabhq/omniauth-ldap.git
26 37 revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
27 38 ref: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e
... ... @@ -33,114 +44,125 @@ GIT
33 44 rubyntlm (~> 0.1.1)
34 45  
35 46 GIT
  47 + remote: https://github.com/gitlabhq/pygments.rb.git
  48 + revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
  49 + ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4
  50 + specs:
  51 + pygments.rb (0.3.2)
  52 + posix-spawn (~> 0.3.6)
  53 + yajl-ruby (~> 1.1.0)
  54 +
  55 +GIT
36 56 remote: https://github.com/gitlabhq/yaml_db.git
37 57 revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
  58 + ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd
38 59 specs:
39 60 yaml_db (0.2.2)
40 61  
41 62 GEM
42 63 remote: http://rubygems.org/
43 64 specs:
44   - actionmailer (3.2.8)
45   - actionpack (= 3.2.8)
  65 + actionmailer (3.2.9)
  66 + actionpack (= 3.2.9)
46 67 mail (~> 2.4.4)
47   - actionpack (3.2.8)
48   - activemodel (= 3.2.8)
49   - activesupport (= 3.2.8)
  68 + actionpack (3.2.9)
  69 + activemodel (= 3.2.9)
  70 + activesupport (= 3.2.9)
50 71 builder (~> 3.0.0)
51 72 erubis (~> 2.7.0)
52 73 journey (~> 1.0.4)
53 74 rack (~> 1.4.0)
54 75 rack-cache (~> 1.2)
55 76 rack-test (~> 0.6.1)
56   - sprockets (~> 2.1.3)
57   - activemodel (3.2.8)
58   - activesupport (= 3.2.8)
  77 + sprockets (~> 2.2.1)
  78 + activemodel (3.2.9)
  79 + activesupport (= 3.2.9)
59 80 builder (~> 3.0.0)
60   - activerecord (3.2.8)
61   - activemodel (= 3.2.8)
62   - activesupport (= 3.2.8)
  81 + activerecord (3.2.9)
  82 + activemodel (= 3.2.9)
  83 + activesupport (= 3.2.9)
63 84 arel (~> 3.0.2)
64 85 tzinfo (~> 0.3.29)
65   - activeresource (3.2.8)
66   - activemodel (= 3.2.8)
67   - activesupport (= 3.2.8)
68   - activesupport (3.2.8)
  86 + activeresource (3.2.9)
  87 + activemodel (= 3.2.9)
  88 + activesupport (= 3.2.9)
  89 + activesupport (3.2.9)
69 90 i18n (~> 0.6)
70 91 multi_json (~> 1.0)
71   - acts-as-taggable-on (2.3.1)
  92 + acts-as-taggable-on (2.3.3)
72 93 rails (~> 3.0)
73   - addressable (2.2.8)
  94 + addressable (2.3.2)
74 95 arel (3.0.2)
75   - awesome_print (1.0.2)
  96 + awesome_print (1.1.0)
  97 + backports (2.6.5)
76 98 bcrypt-ruby (3.0.1)
77   - blankslate (2.1.2.4)
78   - bootstrap-sass (2.0.4.0)
79   - builder (3.0.2)
80   - capybara (1.1.2)
  99 + blankslate (3.1.2)
  100 + bootstrap-sass (2.2.1.1)
  101 + sass (~> 3.2)
  102 + builder (3.0.4)
  103 + capybara (1.1.3)
81 104 mime-types (>= 1.16)
82 105 nokogiri (>= 1.3.3)
83 106 rack (>= 1.0.0)
84 107 rack-test (>= 0.5.4)
85 108 selenium-webdriver (~> 2.0)
86 109 xpath (~> 0.1.4)
87   - capybara-webkit (0.12.1)
88   - capybara (>= 1.0.0, < 1.2)
89   - json
90   - carrierwave (0.6.2)
  110 + carrierwave (0.7.1)
91 111 activemodel (>= 3.2.0)
92 112 activesupport (>= 3.2.0)
93   - charlock_holmes (0.6.8)
94   - childprocess (0.3.2)
95   - ffi (~> 1.0.6)
96   - chosen-rails (0.9.8.3)
  113 + charlock_holmes (0.6.9)
  114 + childprocess (0.3.6)
  115 + ffi (~> 1.0, >= 1.0.6)
  116 + chosen-rails (0.9.8)
97 117 railties (~> 3.0)
98 118 thor (~> 0.14)
99   - coderay (1.0.6)
  119 + coderay (1.0.8)
100 120 coffee-rails (3.2.2)
101 121 coffee-script (>= 2.2.0)
102 122 railties (~> 3.2.0)
103 123 coffee-script (2.2.0)
104 124 coffee-script-source
105 125 execjs
106   - coffee-script-source (1.3.3)
  126 + coffee-script-source (1.4.0)
107 127 colored (1.2)
108 128 colorize (0.5.8)
109 129 crack (0.3.1)
110   - daemons (1.1.8)
111   - database_cleaner (0.8.0)
  130 + daemons (1.1.9)
  131 + database_cleaner (0.9.1)
112 132 devise (2.1.2)
113 133 bcrypt-ruby (~> 3.0)
114 134 orm_adapter (~> 0.1)
115 135 railties (~> 3.1)
116 136 warden (~> 1.2.1)
117 137 diff-lcs (1.1.3)
118   - draper (0.17.0)
  138 + draper (0.18.0)
119 139 actionpack (~> 3.2)
120 140 activesupport (~> 3.2)
121   - email_spec (1.2.1)
  141 + email_spec (1.4.0)
  142 + launchy (~> 2.1)
122 143 mail (~> 2.2)
123   - rspec (~> 2.0)
124 144 erubis (2.7.0)
125 145 escape_utils (0.2.4)
126   - eventmachine (0.12.10)
  146 + eventmachine (1.0.0)
127 147 execjs (1.4.0)
128 148 multi_json (~> 1.0)
129   - factory_girl (4.0.0)
  149 + factory_girl (4.1.0)
130 150 activesupport (>= 3.0.0)
131   - factory_girl_rails (4.0.0)
132   - factory_girl (~> 4.0.0)
  151 + factory_girl_rails (4.1.0)
  152 + factory_girl (~> 4.1.0)
133 153 railties (>= 3.0.0)
134 154 faraday (0.8.4)
135 155 multipart-post (~> 1.1)
136   - ffaker (1.14.0)
137   - ffi (1.0.11)
  156 + faye-websocket (0.4.6)
  157 + eventmachine (>= 0.12.0)
  158 + ffaker (1.15.0)
  159 + ffi (1.1.5)
138 160 font-awesome-sass-rails (2.0.0.0)
139 161 railties (>= 3.1.1)
140 162 sass-rails (>= 3.1.1)
141   - foreman (0.47.0)
  163 + foreman (0.60.2)
142 164 thor (>= 0.13.6)
143   - gemoji (1.1.1)
  165 + gemoji (1.2.1)
144 166 gherkin-ruby (0.2.1)
145 167 git (1.2.5)
146 168 github-linguist (2.3.4)
... ... @@ -149,80 +171,87 @@ GEM
149 171 mime-types (~> 1.19)
150 172 pygments.rb (>= 0.2.13)
151 173 github-markup (0.7.4)
152   - gitlab_meta (3.0)
  174 + gitlab_meta (3.1)
153 175 gitolite (1.1.0)
154 176 gratr19 (~> 0.4.4.1)
155 177 grit (~> 2.5.0)
156 178 hashery (~> 1.5.0)
157   - grape (0.2.1)
  179 + grape (0.2.2)
  180 + activesupport
158 181 hashie (~> 1.2)
159   - multi_json
  182 + multi_json (>= 1.3.2)
160 183 multi_xml
161 184 rack
  185 + rack-accept
162 186 rack-mount
  187 + virtus
163 188 gratr19 (0.4.4.1)
164 189 growl (1.0.3)
165   - guard (1.3.2)
  190 + guard (1.5.4)
166 191 listen (>= 0.4.2)
  192 + lumberjack (>= 1.0.2)
  193 + pry (>= 0.9.10)
167 194 thor (>= 0.14.6)
168   - guard-rspec (1.2.1)
  195 + guard-rspec (2.1.2)
169 196 guard (>= 1.1)
  197 + rspec (~> 2.11)
170 198 guard-spinach (0.0.2)
171 199 guard (>= 1.1)
172 200 spinach
173   - haml (3.1.6)
174   - haml-rails (0.3.4)
175   - actionpack (~> 3.0)
176   - activesupport (~> 3.0)
177   - haml (~> 3.0)
178   - railties (~> 3.0)
  201 + haml (3.1.7)
  202 + haml-rails (0.3.5)
  203 + actionpack (>= 3.1, < 4.1)
  204 + activesupport (>= 3.1, < 4.1)
  205 + haml (~> 3.1)
  206 + railties (>= 3.1, < 4.1)
179 207 hashery (1.5.0)
180 208 blankslate
181 209 hashie (1.2.0)
182   - headless (0.3.1)
183 210 hike (1.2.1)
184   - httparty (0.8.3)
  211 + http_parser.rb (0.5.3)
  212 + httparty (0.9.0)
185 213 multi_json (~> 1.0)
186 214 multi_xml
187   - httpauth (0.1)
  215 + httpauth (0.2.0)
188 216 i18n (0.6.1)
189 217 journey (1.0.4)
190 218 jquery-atwho-rails (0.1.6)
191   - jquery-rails (2.0.2)
192   - railties (>= 3.2.0, < 5.0)
  219 + jquery-rails (2.1.3)
  220 + railties (>= 3.1.0, < 5.0)
193 221 thor (~> 0.14)
194   - jquery-ui-rails (0.5.0)
  222 + jquery-ui-rails (2.0.2)
195 223 jquery-rails
196 224 railties (>= 3.1.0)
197 225 json (1.7.5)
198 226 jwt (0.1.5)
199 227 multi_json (>= 1.0)
200   - kaminari (0.14.0)
  228 + kaminari (0.14.1)
201 229 actionpack (>= 3.0.0)
202 230 activesupport (>= 3.0.0)
203 231 kgio (2.7.4)
204   - launchy (2.1.0)
205   - addressable (~> 2.2.6)
206   - letter_opener (0.0.2)
207   - launchy
  232 + launchy (2.1.2)
  233 + addressable (~> 2.3)
  234 + letter_opener (1.0.0)
  235 + launchy (>= 2.0.4)
208 236 libv8 (3.3.10.4)
209   - libwebsocket (0.1.3)
210   - addressable
211   - listen (0.5.0)
  237 + libwebsocket (0.1.6)
  238 + websocket
  239 + listen (0.5.3)
  240 + lumberjack (1.0.2)
212 241 mail (2.4.4)
213 242 i18n (>= 0.4.0)
214 243 mime-types (~> 1.16)
215 244 treetop (~> 1.4.8)
216   - method_source (0.7.1)
  245 + method_source (0.8.1)
217 246 mime-types (1.19)
218   - modernizr (2.5.3)
  247 + modernizr (2.6.2)
219 248 sprockets (~> 2.0)
220   - multi_json (1.3.6)
  249 + multi_json (1.3.7)
221 250 multi_xml (0.5.1)
222 251 multipart-post (1.1.5)
223 252 mysql2 (0.3.11)
224 253 net-ldap (0.2.2)
225   - nokogiri (1.5.3)
  254 + nokogiri (1.5.5)
226 255 oauth (0.4.7)
227 256 oauth2 (0.8.0)
228 257 faraday (~> 0.8)
... ... @@ -230,7 +259,7 @@ GEM
230 259 jwt (~> 0.1.4)
231 260 multi_json (~> 1.0)
232 261 rack (~> 1.2)
233   - omniauth (1.1.0)
  262 + omniauth (1.1.1)
234 263 hashie (~> 1.2)
235 264 rack
236 265 omniauth-github (1.0.3)
... ... @@ -242,28 +271,35 @@ GEM
242 271 omniauth-oauth (1.0.1)
243 272 oauth
244 273 omniauth (~> 1.0)
245   - omniauth-oauth2 (1.1.0)
  274 + omniauth-oauth2 (1.1.1)
246 275 oauth2 (~> 0.8.0)
247 276 omniauth (~> 1.0)
248   - omniauth-twitter (0.0.13)
  277 + omniauth-twitter (0.0.14)
249 278 multi_json (~> 1.3)
250 279 omniauth-oauth (~> 1.0)
251   - orm_adapter (0.3.0)
252   - pg (0.14.0)
  280 + orm_adapter (0.4.0)
  281 + pg (0.14.1)
  282 + poltergeist (1.0.2)
  283 + capybara (~> 1.1)
  284 + childprocess (~> 0.3)
  285 + faye-websocket (~> 0.4, >= 0.4.4)
  286 + http_parser.rb (~> 0.5.3)
  287 + multi_json (~> 1.0)
253 288 polyglot (0.3.3)
254 289 posix-spawn (0.3.6)
255   - pry (0.9.9.6)
  290 + pry (0.9.10)
256 291 coderay (~> 1.0.5)
257   - method_source (~> 0.7.1)
258   - slop (>= 2.4.4, < 3)
259   - pygments.rb (0.3.1)
260   - posix-spawn (~> 0.3.6)
261   - yajl-ruby (~> 1.1.0)
  292 + method_source (~> 0.8)
  293 + slop (~> 3.3.1)
262 294 pyu-ruby-sasl (0.0.3.3)
  295 + quiet_assets (1.0.1)
  296 + railties (~> 3.1)
263 297 rack (1.4.1)
  298 + rack-accept (0.4.5)
  299 + rack (>= 0.4)
264 300 rack-cache (1.2)
265 301 rack (>= 0.4)
266   - rack-mini-profiler (0.1.9)
  302 + rack-mini-profiler (0.1.23)
267 303 rack (>= 1.1.3)
268 304 rack-mount (0.8.3)
269 305 rack (>= 1.0.0)
... ... @@ -271,65 +307,66 @@ GEM
271 307 rack
272 308 rack-ssl (1.3.2)
273 309 rack
274   - rack-test (0.6.1)
  310 + rack-test (0.6.2)
275 311 rack (>= 1.0)
276   - rails (3.2.8)
277   - actionmailer (= 3.2.8)
278   - actionpack (= 3.2.8)
279   - activerecord (= 3.2.8)
280   - activeresource (= 3.2.8)
281   - activesupport (= 3.2.8)
  312 + rails (3.2.9)
  313 + actionmailer (= 3.2.9)
  314 + actionpack (= 3.2.9)
  315 + activerecord (= 3.2.9)
  316 + activeresource (= 3.2.9)
  317 + activesupport (= 3.2.9)
282 318 bundler (~> 1.0)
283   - railties (= 3.2.8)
  319 + railties (= 3.2.9)
284 320 rails-dev-tweaks (0.6.1)
285 321 actionpack (~> 3.1)
286 322 railties (~> 3.1)
287   - railties (3.2.8)
288   - actionpack (= 3.2.8)
289   - activesupport (= 3.2.8)
  323 + railties (3.2.9)
  324 + actionpack (= 3.2.9)
  325 + activesupport (= 3.2.9)
290 326 rack-ssl (~> 1.3.2)
291 327 rake (>= 0.8.7)
292 328 rdoc (~> 3.4)
293 329 thor (>= 0.14.6, < 2.0)
294   - raindrops (0.9.0)
295   - rake (0.9.2.2)
296   - raphael-rails (1.5.2)
297   - rb-fsevent (0.9.1)
  330 + raindrops (0.10.0)
  331 + rake (10.0.1)
  332 + raphael-rails (2.1.0)
  333 + rb-fsevent (0.9.2)
298 334 rb-inotify (0.8.8)
299 335 ffi (>= 0.5.0)
300 336 rdoc (3.12)
301 337 json (~> 1.4)
302   - redcarpet (2.1.1)
303   - redis (2.2.2)
304   - redis-namespace (1.0.3)
305   - redis (< 3.0.0)
306   - resque (1.20.0)
  338 + redcarpet (2.2.2)
  339 + redis (3.0.2)
  340 + redis-namespace (1.2.1)
  341 + redis (~> 3.0.0)
  342 + resque (1.23.0)
307 343 multi_json (~> 1.0)
308   - redis-namespace (~> 1.0.2)
  344 + redis-namespace (~> 1.0)
309 345 sinatra (>= 0.9.2)
310 346 vegas (~> 0.1.2)
311   - resque_mailer (2.0.3)
312   - actionmailer (>= 3.0.0)
313   - resque (>= 1.2.3)
314   - resque_spec (0.11.0)
  347 + resque_mailer (2.1.0)
  348 + actionmailer (~> 3.0)
  349 + resque_spec (0.12.5)
315 350 resque (>= 1.19.0)
316 351 rspec (>= 2.5.0)
317   - rspec (2.10.0)
318   - rspec-core (~> 2.10.0)
319   - rspec-expectations (~> 2.10.0)
320   - rspec-mocks (~> 2.10.0)
321   - rspec-core (2.10.1)
322   - rspec-expectations (2.10.0)
  352 + rspec (2.12.0)
  353 + rspec-core (~> 2.12.0)
  354 + rspec-expectations (~> 2.12.0)
  355 + rspec-mocks (~> 2.12.0)
  356 + rspec-core (2.12.0)
  357 + rspec-expectations (2.12.0)
323 358 diff-lcs (~> 1.1.3)
324   - rspec-mocks (2.10.1)
325   - rspec-rails (2.10.1)
  359 + rspec-mocks (2.12.0)
  360 + rspec-rails (2.12.0)
326 361 actionpack (>= 3.0)
327 362 activesupport (>= 3.0)
328 363 railties (>= 3.0)
329   - rspec (~> 2.10.0)
  364 + rspec-core (~> 2.12.0)
  365 + rspec-expectations (~> 2.12.0)
  366 + rspec-mocks (~> 2.12.0)
330 367 rubyntlm (0.1.1)
331   - rubyzip (0.9.8)
332   - sass (3.1.19)
  368 + rubyzip (0.9.9)
  369 + sass (3.2.3)
333 370 sass-rails (3.2.5)
334 371 railties (~> 3.2.0)
335 372 sass (>= 3.1.10)
... ... @@ -337,25 +374,24 @@ GEM
337 374 seed-fu (2.2.0)
338 375 activerecord (~> 3.1)
339 376 activesupport (~> 3.1)
340   - selenium-webdriver (2.22.2)
  377 + selenium-webdriver (2.26.0)
341 378 childprocess (>= 0.2.5)
342   - ffi (~> 1.0)
343 379 libwebsocket (~> 0.1.3)
344 380 multi_json (~> 1.0)
345 381 rubyzip
346 382 settingslogic (2.0.8)
347 383 shoulda-matchers (1.3.0)
348 384 activesupport (>= 3.0.0)
349   - simplecov (0.6.4)
  385 + simplecov (0.7.1)
350 386 multi_json (~> 1.0)
351   - simplecov-html (~> 0.5.3)
352   - simplecov-html (0.5.3)
353   - sinatra (1.3.2)
  387 + simplecov-html (~> 0.7.1)
  388 + simplecov-html (0.7.1)
  389 + sinatra (1.3.3)
354 390 rack (~> 1.3, >= 1.3.6)
355 391 rack-protection (~> 1.2)
356 392 tilt (~> 1.3, >= 1.3.3)
357 393 six (0.2.0)
358   - slop (2.4.4)
  394 + slop (3.3.3)
359 395 spinach (0.5.2)
360 396 colorize
361 397 gherkin-ruby (~> 0.2.0)
... ... @@ -363,39 +399,43 @@ GEM
363 399 capybara (~> 1)
364 400 railties (>= 3)
365 401 spinach (>= 0.4)
366   - sprockets (2.1.3)
  402 + sprockets (2.2.1)
367 403 hike (~> 1.2)
  404 + multi_json (~> 1.0)
368 405 rack (~> 1.0)
369 406 tilt (~> 1.1, != 1.3.0)
370 407 sqlite3 (1.3.6)
371   - stamp (0.1.6)
  408 + stamp (0.3.0)
372 409 test_after_commit (0.0.1)
373   - therubyracer (0.10.1)
  410 + therubyracer (0.10.2)
374 411 libv8 (~> 3.3.10)
375   - thin (1.3.1)
  412 + thin (1.5.0)
376 413 daemons (>= 1.0.9)
377 414 eventmachine (>= 0.12.6)
378 415 rack (>= 1.0.0)
379 416 thor (0.16.0)
380 417 tilt (1.3.3)
381   - treetop (1.4.10)
  418 + treetop (1.4.12)
382 419 polyglot
383 420 polyglot (>= 0.3.1)
384   - tzinfo (0.3.33)
385   - uglifier (1.0.3)
  421 + tzinfo (0.3.35)
  422 + uglifier (1.3.0)
386 423 execjs (>= 0.3.0)
387   - multi_json (>= 1.0.2)
388   - unicorn (4.3.1)
  424 + multi_json (~> 1.0, >= 1.0.2)
  425 + unicorn (4.4.0)
389 426 kgio (~> 2.6)
390 427 rack
391 428 raindrops (~> 0.7)
392 429 vegas (0.1.11)
393 430 rack (>= 1.0.0)
  431 + virtus (0.5.2)
  432 + backports (~> 2.6.1)
394 433 warden (1.2.1)
395 434 rack (>= 1.0)
396   - webmock (1.8.7)
  435 + webmock (1.9.0)
397 436 addressable (>= 2.2.7)
398 437 crack (>= 0.1.7)
  438 + websocket (1.0.2)
399 439 xpath (0.1.4)
400 440 nokogiri (~> 1.3)
401 441 yajl-ruby (1.1.0)
... ... @@ -404,71 +444,71 @@ PLATFORMS
404 444 ruby
405 445  
406 446 DEPENDENCIES
407   - acts-as-taggable-on (= 2.3.1)
  447 + acts-as-taggable-on (= 2.3.3)
408 448 annotate!
409 449 awesome_print
410   - bootstrap-sass (= 2.0.4)
  450 + bootstrap-sass (= 2.2.1.1)
411 451 capybara
412   - capybara-webkit
413   - carrierwave
414   - charlock_holmes
415   - chosen-rails
416   - coffee-rails (= 3.2.2)
  452 + carrierwave (~> 0.7.1)
  453 + chosen-rails (= 0.9.8)
  454 + coffee-rails (~> 3.2.2)
417 455 colored
418 456 database_cleaner
419 457 devise (~> 2.1.0)
420   - draper
  458 + draper (~> 0.18.0)
421 459 email_spec
422 460 factory_girl_rails
423 461 ffaker
424 462 font-awesome-sass-rails (~> 2.0.0)
425 463 foreman
426   - gemoji
  464 + gemoji (~> 1.2.1)
427 465 git
428 466 github-linguist (~> 2.3.4)
429 467 github-markup (~> 0.7.4)
430   - gitlab_meta (= 3.0)
  468 + gitlab_meta (= 3.1)
431 469 gitolite (= 1.1.0)
432 470 grack!
433 471 grape (~> 0.2.1)
434 472 grit!
  473 + grit_ext!
435 474 growl
436 475 guard-rspec
437 476 guard-spinach
438   - haml-rails
439   - headless
  477 + haml-rails (~> 0.3.5)
440 478 httparty
441 479 jquery-atwho-rails (= 0.1.6)
442   - jquery-rails (= 2.0.2)
443   - jquery-ui-rails (= 0.5.0)
444   - kaminari
  480 + jquery-rails (= 2.1.3)
  481 + jquery-ui-rails (= 2.0.2)
  482 + kaminari (~> 0.14.1)
445 483 launchy
446 484 letter_opener
447   - modernizr (= 2.5.3)
  485 + modernizr (= 2.6.2)
448 486 mysql2
449   - omniauth
  487 + omniauth (~> 1.1.1)
450 488 omniauth-github
451 489 omniauth-google-oauth2
452 490 omniauth-ldap!
453 491 omniauth-twitter
454 492 pg
  493 + poltergeist
455 494 pry
456   - pygments.rb (= 0.3.1)
  495 + pygments.rb!
  496 + quiet_assets (~> 1.0.1)
457 497 rack-mini-profiler
458   - rails (= 3.2.8)
  498 + rails (= 3.2.9)
459 499 rails-dev-tweaks
460   - raphael-rails (= 1.5.2)
  500 + raphael-rails (= 2.1.0)
461 501 rb-fsevent
462 502 rb-inotify
463   - redcarpet (~> 2.1.1)
464   - resque (~> 1.20.0)
  503 + redcarpet (~> 2.2.2)
  504 + resque (~> 1.23.0)
465 505 resque_mailer
466 506 resque_spec
467 507 rspec-rails
468   - sass-rails (= 3.2.5)
  508 + sass-rails (~> 3.2.5)
469 509 seed-fu
470 510 settingslogic
471   - shoulda-matchers
  511 + shoulda-matchers (= 1.3.0)
472 512 simplecov
473 513 six
474 514 spinach-rails
... ... @@ -476,8 +516,8 @@ DEPENDENCIES
476 516 stamp
477 517 test_after_commit
478 518 therubyracer
479   - thin
480   - uglifier (= 1.0.3)
481   - unicorn
  519 + thin (~> 1.5.0)
  520 + uglifier (~> 1.3.0)
  521 + unicorn (~> 4.4.0)
482 522 webmock
483 523 yaml_db!
... ...
Procfile.production
... ... @@ -1,2 +0,0 @@
1   -web: bundle exec rails s -p $PORT -e production
2   -worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=*
README.md
... ... @@ -13,7 +13,7 @@ GitLab is a free project and repository management application
13 13  
14 14 * Ubuntu/Debian
15 15 * ruby 1.9.3+
16   -* mysql or sqlite
  16 +* MySQL
17 17 * git
18 18 * gitolite
19 19 * redis
... ...
ROADMAP.md 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +## GitLab Roadmap
  2 +
  3 +### Common
  4 +
  5 +* Help page for service tasks like repos import, backup etc
  6 +* Hide last push widget after following link
  7 +* Add comment events
  8 +* gitolite namespaces for projects per user/group. It will allow us same project names for different users
  9 +
  10 +### Issues
  11 +
  12 +* labels autocomplete via jquery autocomplete
  13 +* Import/Export issues
  14 +* Form: Assign to me link right to the selectbox
  15 +
  16 +### Merge Request
  17 +
  18 +* Save code fragments with MR comments
  19 +
  20 +### Services
  21 +
  22 +* Campfire integration service
  23 +* Hipchat integration service
  24 +* Travis CI integration service
  25 +* Jenkins CI integration service
... ...
VERSION
1   -3.0.3
  1 +3.1.0
... ...
app/assets/images/event_filter_comments.png 0 → 100644

750 Bytes

app/assets/images/event_filter_merged.png 0 → 100644

463 Bytes

app/assets/images/event_filter_push.png 0 → 100644

632 Bytes

app/assets/images/event_filter_team.png 0 → 100644

1.31 KB

app/assets/images/gitlab_classic.png

2.98 KB

app/assets/images/gitlab_default.png

6.28 KB

app/assets/images/gitlab_modern.png

3.8 KB

app/assets/images/logo_dark.png

2.79 KB | W: | H:

2.53 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
app/assets/images/logo_white.png

1.64 KB | W: | H:

1.48 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
app/assets/images/service-disabled-gitlab-ci.png 0 → 100644

2.13 KB

app/assets/images/service-gitlab-ci.png 0 → 100644

2.34 KB

app/assets/images/trans_bg.gif 0 → 100644

58 Bytes

app/assets/javascripts/application.js
... ... @@ -13,10 +13,13 @@
13 13 //= require jquery.history
14 14 //= require jquery.waitforimages
15 15 //= require jquery.atwho
  16 +//= require jquery.scrollto
16 17 //= require bootstrap
17 18 //= require modernizr
18 19 //= require chosen-jquery
19 20 //= require raphael
  21 +//= require g.raphael-min
  22 +//= require g.bar-min
20 23 //= require branch-graph
21 24 //= require ace-src-noconflict/ace
22 25 //= require_tree .
... ...
app/assets/javascripts/gfm_auto_complete.js.coffee
  1 +# Creates the variables for setting up GFM auto-completion
  2 +
  3 +window.GitLab ?= {}
  4 +GitLab.GfmAutoComplete ?= {}
1 5  
2   -###
3   - Creates the variables for setting up GFM auto-completion
4   -###
5 6 # Emoji
6   -window.autocompleteEmojiData = [];
7   -window.autocompleteEmojiTemplate = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>";
  7 +data = []
  8 +template = "<li data-value='${insert}'>${name} <img alt='${name}' height='20' src='${image}' width='20' /></li>"
  9 +GitLab.GfmAutoComplete.Emoji = {data, template}
8 10  
9 11 # Team Members
10   -window.autocompleteMembersUrl = "";
11   -window.autocompleteMembersParams =
12   - private_token: ""
13   - page: 1
14   -window.autocompleteMembersData = [];
15   -
16   -
17   -
18   -###
19   - Add GFM auto-completion to all input fields, that accept GFM input.
20   -###
21   -window.setupGfmAutoComplete = ->
22   - ###
23   - Emoji
24   - ###
25   - $('.gfm-input').atWho ':',
26   - data: autocompleteEmojiData,
27   - tpl: autocompleteEmojiTemplate
28   -
29   - ###
30   - Team Members
31   - ###
32   - $('.gfm-input').atWho '@', (query, callback) ->
  12 +data = []
  13 +url = '';
  14 +params = {private_token: '', page: 1}
  15 +GitLab.GfmAutoComplete.Members = {data, url, params}
  16 +
  17 +# Add GFM auto-completion to all input fields, that accept GFM input.
  18 +GitLab.GfmAutoComplete.setup = ->
  19 + input = $('.js-gfm-input')
  20 +
  21 + # Emoji
  22 + input.atWho ':',
  23 + data: GitLab.GfmAutoComplete.Emoji.data,
  24 + tpl: GitLab.GfmAutoComplete.Emoji.template
  25 +
  26 + # Team Members
  27 + input.atWho '@', (query, callback) ->
33 28 (getMoreMembers = ->
34   - $.getJSON(autocompleteMembersUrl, autocompleteMembersParams)
  29 + $.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params)
35 30 .success (members) ->
36 31 # pick the data we need
37   - newMembersData = $.map members, (m) -> m.name
  32 + newMembersData = $.map(members, (m) -> m.name )
38 33  
39 34 # add the new page of data to the rest
40   - $.merge autocompleteMembersData, newMembersData
  35 + $.merge(GitLab.GfmAutoComplete.Members.data, newMembersData)
41 36  
42 37 # show the pop-up with a copy of the current data
43   - callback autocompleteMembersData[..]
  38 + callback(GitLab.GfmAutoComplete.Members.data[..])
44 39  
45 40 # are we past the last page?
46   - if newMembersData.length == 0
  41 + if newMembersData.length is 0
47 42 # set static data and stop callbacks
48   - $('.gfm-input').atWho '@',
49   - data: autocompleteMembersData
  43 + input.atWho '@',
  44 + data: GitLab.GfmAutoComplete.Members.data
50 45 callback: null
51 46 else
52 47 # get next page
53 48 getMoreMembers()
54 49  
55 50 # so the next request gets the next page
56   - autocompleteMembersParams.page += 1;
57   - ).call();
58 51 \ No newline at end of file
  52 + GitLab.GfmAutoComplete.Members.params.page += 1
  53 + ).call()
... ...
app/assets/javascripts/graph.js.coffee
... ... @@ -1,10 +0,0 @@
1   -initGraphNav = ->
2   - $('.graph svg').css 'position', 'relative'
3   -
4   - $('body').bind 'keyup', (e) ->
5   - if e.keyCode is 37 # left
6   - $('.graph svg').animate left: '+=400'
7   - else if e.keyCode is 39 # right
8   - $('.graph svg').animate left: '-=400'
9   -
10   -window.initGraphNav = initGraphNav
app/assets/javascripts/issues.js
1   -function switchToNewIssue(form){
  1 +function switchToNewIssue(){
2 2 $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
3   - $(".issues_content").after(form);
4 3 $('select#issue_assignee_id').chosen();
5 4 $('select#issue_milestone_id').chosen();
6 5 $("#new_issue_dialog").show("fade", { direction: "right" }, 150);
7 6 $('.top-tabs .add_new').hide();
8 7 disableButtonIfEmptyField("#issue_title", ".save-btn");
9   - setupGfmAutoComplete();
  8 + GitLab.GfmAutoComplete.setup();
10 9 });
11 10 }
12 11  
13   -function switchToEditIssue(form){
  12 +function switchToEditIssue(){
14 13 $(".issues_content").hide("fade", { direction: "left" }, 150, function(){
15   - $(".issues_content").after(form);
16 14 $('select#issue_assignee_id').chosen();
17 15 $('select#issue_milestone_id').chosen();
18 16 $("#edit_issue_dialog").show("fade", { direction: "right" }, 150);
19 17 $('.add_new').hide();
20 18 disableButtonIfEmptyField("#issue_title", ".save-btn");
21   - setupGfmAutoComplete();
  19 + GitLab.GfmAutoComplete.setup();
22 20 });
23 21 }
24 22  
... ... @@ -33,18 +31,18 @@ function switchFromEditIssue(){
33 31 function backToIssues(){
34 32 $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){
35 33 $(".issues_content").show("fade", { direction: "left" }, 150, function() {
36   - $("#edit_issue_dialog").remove();
37   - $("#new_issue_dialog").remove();
  34 + $("#edit_issue_dialog").html("");
  35 + $("#new_issue_dialog").html("");
38 36 $('.add_new').show();
39 37 });
40 38 });
41 39 }
42 40  
43 41 function initIssuesSearch() {
44   - var href = $('.issue_search').parent().attr('action');
  42 + var href = $('#issue_search_form').attr('action');
45 43 var last_terms = '';
46 44  
47   - $('.issue_search').keyup(function() {
  45 + $('#issue_search').keyup(function() {
48 46 var terms = $(this).val();
49 47 var milestone_id = $('#milestone_id').val();
50 48 var status = $('#status').val();
... ... @@ -59,10 +57,6 @@ function initIssuesSearch() {
59 57 }
60 58 }
61 59 });
62   -
63   - $('.delete-issue').live('ajax:success', function() {
64   - $(this).closest('tr').fadeOut(); updatePage();
65   - });
66 60 }
67 61  
68 62 /**
... ...
app/assets/javascripts/loader.js.coffee
... ... @@ -1,5 +0,0 @@
1   -Loader =
2   - html: (width) ->
3   - $('<img>').attr src: '/assets/ajax-loader.gif', width: width
4   -
5   -window.Loader = Loader
app/assets/javascripts/main.js.coffee
... ... @@ -7,29 +7,36 @@ window.slugify = (text) -&gt;
7 7 window.ajaxGet = (url) ->
8 8 $.ajax({type: "GET", url: url, dataType: "script"})
9 9  
10   - # Disable button if text field is empty
  10 +# Disable button if text field is empty
11 11 window.disableButtonIfEmptyField = (field_selector, button_selector) ->
12 12 field = $(field_selector)
13 13 closest_submit = field.closest("form").find(button_selector)
14 14  
15 15 closest_submit.disable() if field.val() is ""
16 16  
17   - field.on "keyup", ->
18   - if $(this).val() is ""
  17 + field.on "input", ->
  18 + if $(@).val() is ""
19 19 closest_submit.disable()
20 20 else
21 21 closest_submit.enable()
22 22  
23 23 $ ->
24 24 # Click a .one_click_select field, select the contents
25   - $(".one_click_select").live 'click', -> $(this).select()
  25 + $(".one_click_select").on 'click', -> $(@).select()
26 26  
27 27 # Initialize chosen selects
28 28 $('select.chosen').chosen()
29 29  
  30 + # Initialize tooltips
  31 + $('.has_tooltip').tooltip()
  32 +
  33 + # Bottom tooltip
  34 + $('.has_bottom_tooltip').tooltip(placement: 'bottom')
  35 +
  36 +
30 37 # Disable form buttons while a form is submitting
31 38 $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->
32   - buttons = $('[type="submit"]', this)
  39 + buttons = $('[type="submit"]', @)
33 40  
34 41 switch e.type
35 42 when 'ajax:beforeSend', 'submit'
... ... @@ -38,7 +45,7 @@ $ -&gt;
38 45 buttons.enable()
39 46  
40 47 # Show/Hide the profile menu when hovering the account box
41   - $('.account-box').hover -> $(this).toggleClass('hover')
  48 + $('.account-box').hover -> $(@).toggleClass('hover')
42 49  
43 50 # Focus search field by pressing 's' key
44 51 $(document).keypress (e) ->
... ... @@ -52,41 +59,22 @@ $ -&gt;
52 59  
53 60 # Commit show suppressed diff
54 61 $(".supp_diff_link").bind "click", ->
55   - $(this).next('table').show()
56   - $(this).remove()
57   -
58   - # Note markdown preview
59   - $(document).on 'click', '#preview-link', (e) ->
60   - $('#preview-note').text('Loading...')
61   -
62   - previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview'
63   - $(this).text(previewLinkText)
64   -
65   - note = $('#note_note').val()
66   -
67   - if note.trim().length == 0
68   - $('#preview-note').text("Nothing to preview.")
69   - else
70   - $.post $(this).attr('href'), {note: note}, (data) ->
71   - $('#preview-note').html(data)
72   -
73   - $('#preview-note, #note_note').toggle()
74   - e.preventDefault()
75   - false
  62 + $(@).next('table').show()
  63 + $(@).remove()
76 64  
77 65 (($) ->
78 66 _chosen = $.fn.chosen
79 67 $.fn.extend chosen: (options) ->
80 68 default_options = search_contains: "true"
81 69 $.extend default_options, options
82   - _chosen.apply this, [default_options]
  70 + _chosen.apply @, [default_options]
83 71  
84 72 # Disable an element and add the 'disabled' Bootstrap class
85 73 $.fn.extend disable: ->
86   - $(this).attr('disabled', 'disabled').addClass('disabled')
  74 + $(@).attr('disabled', 'disabled').addClass('disabled')
87 75  
88 76 # Enable an element and remove the 'disabled' Bootstrap class
89 77 $.fn.extend enable: ->
90   - $(this).removeAttr('disabled').removeClass('disabled')
  78 + $(@).removeAttr('disabled').removeClass('disabled')
91 79  
92 80 )(jQuery)
... ...
app/assets/javascripts/merge_requests.js
... ... @@ -115,4 +115,15 @@ var MergeRequest = {
115 115 $(".merge_in_progress").hide();
116 116 $(".automerge_widget.already_cannot_be_merged").show();
117 117 }
  118 +};
  119 +
  120 +/*
  121 + * Filter merge requests
  122 + */
  123 +function merge_requestsPage() {
  124 + $("#assignee_id").chosen();
  125 + $("#milestone_id").chosen();
  126 + $("#milestone_id, #assignee_id").on("change", function(){
  127 + $(this).closest("form").submit();
  128 + });
118 129 }
... ...
app/assets/javascripts/milestones.js.coffee
... ... @@ -5,3 +5,10 @@ $ -&gt;
5 5 $('.milestone-issue-filter li').toggleClass('active')
6 6 $('.milestone-issue-filter tr[data-closed]').toggleClass('hide')
7 7 false
  8 +
  9 + $('.milestone-merge-requests-filter tr[data-closed]').addClass('hide')
  10 +
  11 + $('.milestone-merge-requests-filter ul.nav li a').click ->
  12 + $('.milestone-merge-requests-filter li').toggleClass('active')
  13 + $('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide')
  14 + false
... ...
app/assets/javascripts/notes.js
... ... @@ -14,8 +14,8 @@ var NoteList = {
14 14 this.notes_path = path + ".js";
15 15 this.target_id = tid;
16 16 this.target_type = tt;
17   - this.reversed = $("#notes-list").hasClass("reversed");
18   - this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id;
  17 + this.reversed = $("#notes-list").is(".reversed");
  18 + this.target_params = "target_type=" + this.target_type + "&target_id=" + this.target_id;
19 19  
20 20 // get initial set of notes
21 21 this.getContent();
... ... @@ -33,6 +33,8 @@ var NoteList = {
33 33  
34 34 $(".note-form-holder").on("ajax:complete", function(){
35 35 $(".submit_note").enable();
  36 + $('#preview-note').hide();
  37 + $('#note_note').show();
36 38 })
37 39  
38 40 disableButtonIfEmptyField(".note-text", ".submit_note");
... ... @@ -52,6 +54,26 @@ var NoteList = {
52 54 $('.note_advanced_opts').show();
53 55 });
54 56 }
  57 +
  58 + // Setup note preview
  59 + $(document).on('click', '#preview-link', function(e) {
  60 + $('#preview-note').text('Loading...');
  61 +
  62 + $(this).text($(this).text() === "Edit" ? "Preview" : "Edit");
  63 +
  64 + var note_text = $('#note_note').val();
  65 +
  66 + if(note_text.trim().length === 0) {
  67 + $('#preview-note').text('Nothing to preview.');
  68 + } else {
  69 + $.post($(this).attr('href'), {note: note_text}).success(function(data) {
  70 + $('#preview-note').html(data);
  71 + });
  72 + }
  73 +
  74 + $('#preview-note, #note_note').toggle();
  75 + e.preventDefault();
  76 + });
55 77 },
56 78  
57 79  
... ... @@ -69,7 +91,7 @@ var NoteList = {
69 91 $.ajax({
70 92 type: "GET",
71 93 url: this.notes_path,
72   - data: "?" + this.target_params,
  94 + data: this.target_params,
73 95 complete: function(){ $('.notes-status').removeClass("loading")},
74 96 beforeSend: function() { $('.notes-status').addClass("loading") },
75 97 dataType: "script"});
... ... @@ -131,7 +153,7 @@ var NoteList = {
131 153 $.ajax({
132 154 type: "GET",
133 155 url: this.notes_path,
134   - data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params,
  156 + data: this.target_params + "&loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id,
135 157 complete: function(){ $('.notes-status').removeClass("loading")},
136 158 beforeSend: function() { $('.notes-status').addClass("loading") },
137 159 dataType: "script"});
... ... @@ -192,7 +214,7 @@ var NoteList = {
192 214 $.ajax({
193 215 type: "GET",
194 216 url: this.notes_path,
195   - data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params,
  217 + data: this.target_params + "&loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id),
196 218 dataType: "script"});
197 219 },
198 220  
... ... @@ -264,7 +286,7 @@ var PerLineNotes = {
264 286 $(this).closest("tr").after(form);
265 287 form.find("#note_line_code").val($(this).data("lineCode"));
266 288 form.show();
267   - return false;
  289 + e.preventDefault();
268 290 });
269 291  
270 292 disableButtonIfEmptyField(".line-note-text", ".submit_inline_note");
... ... @@ -285,7 +307,7 @@ var PerLineNotes = {
285 307 // elements must really be removed for this to work reliably
286 308 var trLine = trNote.prev();
287 309 var trRpl = trNote.next();
288   - if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) {
  310 + if (trLine.is(".line_holder") && trRpl.is(".reply")) {
289 311 trRpl.fadeOut(function() { $(this).remove(); });
290 312 }
291 313 });
... ...
app/assets/javascripts/profile.js.coffee 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +$ ->
  2 + $('.edit_user .application-theme input, .edit_user .code-preview-theme input').click ->
  3 + # Hide any previous submission feedback
  4 + $('.edit_user .update-feedback').hide()
  5 +
  6 + # Submit the form
  7 + $('.edit_user').submit()
  8 +
  9 + # Go up the hierarchy and show the corresponding submission feedback element
  10 + $(@).closest('fieldset').find('.update-feedback').show('highlight', {color: '#DFF0D8'}, 500)
... ...
app/assets/javascripts/projects.js.coffee
... ... @@ -22,3 +22,10 @@ $ -&gt;
22 22 # Ref switcher
23 23 $('.project-refs-select').on 'change', ->
24 24 $(@).parents('form').submit()
  25 +
  26 +class @GraphNav
  27 + @init: ->
  28 + $('.graph svg').css 'position', 'relative'
  29 + $('body').bind 'keyup', (e) ->
  30 + $('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left
  31 + $('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right
... ...
app/assets/javascripts/snippets.js.coffee
... ... @@ -1,6 +0,0 @@
1   -$ ->
2   - $('#snippets-table .snippet').live 'click', (e) ->
3   - if e.target.nodeName isnt 'A' and e.target.nodeName isnt 'INPUT'
4   - location.href = $(@).attr 'url'
5   - e.stopPropagation()
6   - false
app/assets/javascripts/tree.js.coffee
... ... @@ -17,23 +17,40 @@ $ -&gt;
17 17 "ajax:beforeSend": -> $('.tree_progress').addClass("loading")
18 18 "ajax:complete": -> $('.tree_progress').removeClass("loading")
19 19  
20   -# Maintain forward/back history while browsing the file tree
21   -
22   -((window) ->
23   - History = window.History
24   - $ = window.jQuery
25   - document = window.document
26   -
27   - # Check to see if History.js is enabled for our Browser
28   - unless History.enabled
29   - return false
30   -
31   - $ ->
32   - $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
33   - History.pushState(null, null, $(@).attr('href'))
34   - return false
35   -
36   - History.Adapter.bind window, 'statechange', ->
37   - state = History.getState()
38   - window.ajaxGet(state.url)
39   -)(window)
  20 + # Maintain forward/back history while browsing the file tree
  21 + ((window) ->
  22 + History = window.History
  23 + $ = window.jQuery
  24 + document = window.document
  25 +
  26 + # Check to see if History.js is enabled for our Browser
  27 + unless History.enabled
  28 + return false
  29 +
  30 + $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
  31 + History.pushState(null, null, $(@).attr('href'))
  32 + return false
  33 +
  34 + History.Adapter.bind window, 'statechange', ->
  35 + state = History.getState()
  36 + window.ajaxGet(state.url)
  37 + )(window)
  38 +
  39 + # See if there are lines selected
  40 + # "#L12" and "#L34-56" supported
  41 + highlightBlobLines = ->
  42 + if window.location.hash isnt ""
  43 + matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/)
  44 + first_line = parseInt(matches?[1])
  45 + last_line = parseInt(matches?[3])
  46 +
  47 + unless isNaN first_line
  48 + last_line = first_line if isNaN(last_line)
  49 + $("#tree-content-holder .highlight .line").removeClass("hll")
  50 + $("#LC#{line}").addClass("hll") for line in [first_line..last_line]
  51 + $("#L#{first_line}").ScrollTo()
  52 +
  53 + # Highlight the correct lines on load
  54 + highlightBlobLines()
  55 + # Highlight the correct lines when the hash part of the URL changes
  56 + $(window).on 'hashchange', highlightBlobLines
... ...
app/assets/stylesheets/common.scss
... ... @@ -20,18 +20,6 @@ body {
20 20 float:right;
21 21 }
22 22  
23   -.profile_avatar_holder {
24   - float:left;
25   - width:60px;
26   - height:60px;
27   - margin-right:20px;
28   - img {
29   - width:60px;
30   - height:60px;
31   - background:#eee;
32   - }
33   -}
34   -
35 23  
36 24 .visible_link,
37 25 .author_link {
... ... @@ -596,25 +584,6 @@ li.note {
596 584 }
597 585 }
598 586  
599   -.themes_opts {
600   - padding-left:20px;
601   -
602   - label {
603   - width:175px;
604   - margin-right:40px;
605   -
606   - .prev {
607   - @extend .thumbnail;
608   - height:120px;
609   - width:175px;
610   - margin-bottom:10px;
611   - img {
612   - width:180px;
613   - }
614   - }
615   - }
616   -}
617   -
618 587 .git_error_tips {
619 588 @extend .span6;
620 589 text-align:left;
... ... @@ -628,10 +597,11 @@ li.note {
628 597  
629 598 .error_message {
630 599 @extend .cred;
631   - border-bottom: 1px solid #D21;
632   - padding-bottom:20px;
633   - text-align:center;
634   - margin-bottom:10px;
  600 + border-left: 4px solid #E99;
  601 + padding: 10px;
  602 + margin-bottom: 10px;
  603 + background: #FEE;
  604 + padding-left: 20px;
635 605 }
636 606  
637 607 .oauth_select_holder {
... ... @@ -670,3 +640,16 @@ pre {
670 640 padding:0;
671 641 }
672 642 }
  643 +
  644 +.milestone .progress {
  645 + margin-bottom: 0;
  646 + margin-top:4px;
  647 +}
  648 +
  649 +.float-link {
  650 + float:left;
  651 + margin-right:15px;
  652 + .s16 {
  653 + margin-right:5px;
  654 + }
  655 +}
... ...
app/assets/stylesheets/gitlab_bootstrap/buttons.scss
... ... @@ -94,6 +94,7 @@
94 94 &.very_small {
95 95 font-size:11px;
96 96 padding:2px 6px;
  97 + line-height: 16px;
97 98 margin:2px;
98 99 }
99 100  
... ...
app/assets/stylesheets/gitlab_bootstrap/common.scss
... ... @@ -26,8 +26,10 @@
26 26 .underlined { border-bottom: 1px solid #CCC; }
27 27 .no-borders { border:none; }
28 28 .vlink { color: $link_color !important; }
  29 +.underlined_link { text-decoration: underline; }
29 30 .borders { border: 1px solid #ccc; @include shade; }
30 31 .hint { font-style: italic; color: #999; }
  32 +.light { color: #888 }
31 33  
32 34 /** PILLS & TABS**/
33 35 .nav-pills a:hover { background-color:#888; }
... ... @@ -38,6 +40,7 @@
38 40 > a {
39 41 padding:8px 20px;
40 42 margin-right: 7px;
  43 + line-height: 19px;
41 44 border-color: #EEE;
42 45 color:#888;
43 46 border-bottom: 1px solid #ddd;
... ... @@ -66,11 +69,12 @@
66 69 .alert-message.error { @extend .alert-error; }
67 70  
68 71 /** AVATARS **/
69   -img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; }
70   -img.avatar.s16 { width:16px; height:16px; }
71   -img.avatar.s24 { width:24px; height:24px; }
72   -img.avatar.s32 { width:32px; height:32px; }
  72 +img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; }
  73 +img.avatar.s16 { width:16px; height:16px; margin-right:6px; }
  74 +img.avatar.s24 { width:24px; height:24px; margin-right:8px; }
  75 +img.avatar.s32 { width:32px; height:32px; margin-right:10px; }
73 76 img.lil_av { padding-left: 4px; padding-right:3px; }
  77 +img.small { width: 80px; }
74 78  
75 79 /** HELPERS **/
76 80 .nothing_here_message { text-align:center; padding:20px; color:#777; }
... ... @@ -85,3 +89,5 @@ input[type=&#39;search&#39;].search-text-input {
85 89 @include border-radius(4px);
86 90 border:1px solid #ccc;
87 91 }
  92 +
  93 +fieldset legend { font-size: 17px; }
... ...
app/assets/stylesheets/gitlab_bootstrap/files.scss
... ... @@ -132,35 +132,74 @@
132 132 * Code file
133 133 */
134 134 &.code {
135   - padding:0;
136   - td.code {
137   - width: 100%;
138   - .highlight {
139   - margin-left: 55px;
140   - overflow:auto;
141   - overflow-y:hidden;
142   - }
143   - }
144   - .highlight pre {
145   - white-space: pre;
146   - word-wrap:normal;
147   - }
  135 + padding: 0;
148 136  
149   - table.highlighttable {
  137 + table.lines {
150 138 border: none;
151   - }
152   - body.project-page table.highlighttable td { border: none }
153   - table.highlighttable tr:hover { background:none;}
  139 + box-shadow: none;
  140 + margin: 0px;
  141 + padding: 0px;
  142 + table-layout: fixed;
154 143  
155   - table.highlighttable pre{
156   - line-height:16px !important;
157   - font-size:12px !important;
158   - }
  144 + pre {
  145 + background: none;
  146 + border: none;
  147 + font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  148 + font-size: 12px !important;
  149 + line-height: 16px !important;
  150 + margin: 0;
  151 + padding: 10px 0;
  152 + }
  153 + td {
  154 + border: none;
  155 + margin: 0;
  156 + padding: 0;
  157 + vertical-align: top;
  158 +
  159 + &:first-child {
  160 + background: #eee;
  161 + width: 50px;
  162 + }
  163 + &:last-child {
  164 + }
  165 + }
  166 + tr:hover {
  167 + background: none;
  168 + }
  169 +
  170 + pre.line_numbers {
  171 + color: #666;
  172 + padding: 10px 6px 10px 0;
  173 + text-align: right;
  174 +
  175 + a {
  176 + color: #666;
  177 +
  178 + i {
  179 + display: none;
  180 + font-size: 14px;
  181 + line-height: 14px;
  182 + }
  183 + &:hover i {
  184 + display: inherit;
  185 + }
  186 + }
  187 + }
159 188  
160   - table.highlighttable .linenodiv pre {
161   - text-align: right;
162   - padding-right: 4px;
163   - color:#666;
  189 + .highlight {
  190 + border-left: 1px solid #DEE2E3;
  191 + overflow: auto;
  192 + overflow-y: hidden;
  193 +
  194 + pre {
  195 + white-space: pre;
  196 + word-wrap: normal;
  197 +
  198 + .line {
  199 + padding: 0 10px;
  200 + }
  201 + }
  202 + }
164 203 }
165 204 }
166 205 }
... ...
app/assets/stylesheets/gitlab_bootstrap/lists.scss
... ... @@ -21,7 +21,7 @@ ul {
21 21 .author { color: #999; }
22 22  
23 23 p {
24   - padding-top:5px;
  24 + padding-top: 1px;
25 25 margin:0;
26 26 color:#222;
27 27 img {
... ... @@ -31,3 +31,11 @@ ul {
31 31 }
32 32 }
33 33 }
  34 +
  35 +ol, ul {
  36 + &.styled {
  37 + li {
  38 + padding:2px;
  39 + }
  40 + }
  41 +}
... ...
app/assets/stylesheets/gitlab_bootstrap/tables.scss
... ... @@ -34,6 +34,11 @@ table {
34 34 border-color:#f1f1f1;
35 35 line-height:28px;
36 36  
  37 + .s16 {
  38 + margin-top: 5px;
  39 + margin-right: 5px;
  40 + }
  41 +
37 42 &:first-child {
38 43 border-left:1px solid #bbb;
39 44 }
... ...
app/assets/stylesheets/gitlab_bootstrap/typography.scss
... ... @@ -2,8 +2,11 @@
2 2 * Headers
3 3 *
4 4 */
  5 +
  6 +h1, h2, h3, h4, h5, h6 { margin: 0; }
5 7 h3, h4, h5, h6 { line-height: 36px; }
6 8 h5 { font-size:14px; }
  9 +
7 10 h3.page_title {
8 11 color:#456;
9 12 font-size:20px;
... ... @@ -11,6 +14,11 @@ h3.page_title {
11 14 line-height: 28px;
12 15 }
13 16  
  17 +h6 {
  18 + color: #888;
  19 + text-transform: uppercase;
  20 +}
  21 +
14 22 /** CODE **/
15 23 pre {
16 24 font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
... ...
app/assets/stylesheets/highlight/dark.scss
1   -.black .highlighttable {
2   - td.linenos { border:none; }
3   - pre { color: #eee }
4   - .highlight { background: #333; border-left:1px solid #555; }
  1 +.black .lines .highlight {
  2 + background: #333;
  3 + pre { color: #eee; }
5 4  
6   - .hll { background-color: #ffffff }
  5 + .hll { display: block; background-color: darken($hover, 65%) }
7 6 .c { color: #888888; font-style: italic } /* Comment */
8 7 .err { color: #a61717; background-color: #e3d2d2 } /* Error */
9 8 .k { color: #CDA869; font-weight: bold } /* Keyword */
... ... @@ -22,43 +21,43 @@
22 21 .gs { font-weight: bold } /* Generic.Strong */
23 22 .gu { color: #606060 } /* Generic.Subheading */
24 23 .gt { color: #aa0000 } /* Generic.Traceback */
25   - .highlight .kc{font-weight:bold;} /* Keyword.Constant */
26   - .highlight .kd{font-weight:bold;} /* Keyword.Declaration */
27   - .highlight .kn{font-weight:bold;} /* Keyword.Namespace */
28   - .highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
29   - .highlight .kr{font-weight:bold;} /* Keyword.Reserved */
30   - .highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
  24 + .kc{font-weight:bold;} /* Keyword.Constant */
  25 + .kd{font-weight:bold;} /* Keyword.Declaration */
  26 + .kn{font-weight:bold;} /* Keyword.Namespace */
  27 + .kp{font-weight:bold;} /* Keyword.Pseudo */
  28 + .kr{font-weight:bold;} /* Keyword.Reserved */
  29 + .kt{color:#458;font-weight:bold;} /* Keyword.Type */
31 30 .m { color: #0000DD; font-weight: bold } /* Literal.Number */
32 31 .p { color: #eee; }
33 32 .s { color: #0AD; background-color: transparent } /* Literal.String */
34   - .highlight .na{color:#008080;} /* Name.Attribute */
35   - .highlight .nb{color:#0086B3;} /* Name.Builtin */
36   - .highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */
37   - .highlight .no{color:turquoise;} /* Name.Constant */
38   - .highlight .ni{color:#800080;}
39   - .highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
40   - .highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */
41   - .highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
42   - .highlight .nt{color:#fc5;} /* Name.Tag */
43   - .highlight .nv{color:#FA4;} /* Name.Variable */
  33 + .na{color:#008080;} /* Name.Attribute */
  34 + .nb{color:#0086B3;} /* Name.Builtin */
  35 + .nc{color:#ccc;font-weight:bold;} /* Name.Class */
  36 + .no{color:turquoise;} /* Name.Constant */
  37 + .ni{color:#800080;}
  38 + .ne{color:#900;font-weight:bold;} /* Name.Exception */
  39 + .nf{color:#ccc;font-weight:bold;} /* Name.Function */
  40 + .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */
  41 + .nt{color:#fc5;} /* Name.Tag */
  42 + .nv{color:#FA4;} /* Name.Variable */
44 43 .py { color: #336699; font-weight: bold } /* Name.Property */
45 44 .ow { color: #008800 } /* Operator.Word */
46 45 .w { color: #bbbbbb } /* Text.Whitespace */
47 46 .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */
48 47 .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */
49   - .highlight .mi {color:#099;} /* Literal.Number.Integer */
  48 + .mi {color:#099;} /* Literal.Number.Integer */
50 49 .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
51 50 .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */
52   - .highlight .sc{color:#d14;} /* Literal.String.Char */
  51 + .sc{color:#d14;} /* Literal.String.Char */
53 52 .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */
54   - .highlight .s2{color:orange;} /* Literal.String.Double */
55   - .highlight .se{color:orange;} /* Literal.String.Escape */
56   - .highlight .sh{color:orange;} /* Literal.String.Heredoc */
57   - .highlight .si{color:orange;} /* Literal.String.Interpol */
58   - .highlight .sx{color:orange;} /* Literal.String.Other */
59   - .highlight .sr{color:orange;} /* Literal.String.Regex */
60   - .highlight .s1{color:orange;} /* Literal.String.Single */
61   - .highlight .ss{color:orange;} /* Literal.String.Symbol */
  53 + .s2{color:orange;} /* Literal.String.Double */
  54 + .se{color:orange;} /* Literal.String.Escape */
  55 + .sh{color:orange;} /* Literal.String.Heredoc */
  56 + .si{color:orange;} /* Literal.String.Interpol */
  57 + .sx{color:orange;} /* Literal.String.Other */
  58 + .sr{color:orange;} /* Literal.String.Regex */
  59 + .s1{color:orange;} /* Literal.String.Single */
  60 + .ss{color:orange;} /* Literal.String.Symbol */
62 61 .bp { color: #D58 } /* Name.Builtin.Pseudo */
63 62 .vc { color: #336699 } /* Name.Variable.Class */
64 63 .vg { color: #dd7700 } /* Name.Variable.Global */
... ...
app/assets/stylesheets/highlight/white.scss
1   -table.highlighttable {
2   - margin:0px;
3   - padding:0px;
4   - font-size:12px;
5   - table-layout:fixed;
6   - background: #EEE;
7   - box-shadow: none;
8   - border: none;
9   - td.linenos {
10   - background:#eee;
11   - border-left:none;
12   - }
13   - td.code {
14   - border-right:none;
15   - }
16   -}
17   -
18   -
19   -td.code,
20   -td.linenos{
21   - padding:0;
22   - margin:0;
23   - border-top:0;
24   - vertical-align:top;
25   -}
26   -
27   -.highlighttable .highlight{
28   - background:none;
29   - padding:10px 0px 0px 10px;
30   - margin-left:0px;
31   - border-left: 1px solid #DEE2E3;
  1 +.white .lines .highlight {
32 2 background: white;
33   -}
34   -
35   -.linenodiv pre,
36   -.highlighttable .highlight pre{
37   - margin:0;
38   - padding:0;
39   - background:none;
40   - border:none;
41   -}
  3 + pre { color: #333; }
42 4  
43   -.linenodiv pre {
44   - white-space:pre-line;
  5 + .hll { display: block; background-color: $hover }
  6 + .c { color: #888888; font-style: italic } /* Comment */
  7 + .err { color: #a61717; background-color: #e3d2d2 } /* Error */
  8 + .k { color: #000000; font-weight: bold } /* Keyword */
  9 + .cm { color: #888888 } /* Comment.Multiline */
  10 + .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
  11 + .c1 { color: #888888 } /* Comment.Single */
  12 + .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
  13 + .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
  14 + .ge { font-style: italic } /* Generic.Emph */
  15 + .gr { color: #aa0000 } /* Generic.Error */
  16 + .gh { color: #303030 } /* Generic.Heading */
  17 + .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
  18 + .go { color: #888888 } /* Generic.Output */
  19 + .gp { color: #555555 } /* Generic.Prompt */
  20 + .gs { font-weight: bold } /* Generic.Strong */
  21 + .gu { color: #606060 } /* Generic.Subheading */
  22 + .gt { color: #aa0000 } /* Generic.Traceback */
  23 + .kc{font-weight:bold;} /* Keyword.Constant */
  24 + .kd{font-weight:bold;} /* Keyword.Declaration */
  25 + .kn{font-weight:bold;} /* Keyword.Namespace */
  26 + .kp{font-weight:bold;} /* Keyword.Pseudo */
  27 + .kr{font-weight:bold;} /* Keyword.Reserved */
  28 + .kt{color:#458;font-weight:bold;} /* Keyword.Type */
  29 + .m { color: #0000DD; font-weight: bold } /* Literal.Number */
  30 + .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
  31 + .na{color:#008080;} /* Name.Attribute */
  32 + .nb{color:#0086B3;} /* Name.Builtin */
  33 + .nc{color:#458;font-weight:bold;} /* Name.Class */
  34 + .no{color:#008080;} /* Name.Constant */
  35 + .ni{color:#800080;}
  36 + .ne{color:#900;font-weight:bold;} /* Name.Exception */
  37 + .nf{color:#900;font-weight:bold;} /* Name.Function */
  38 + .nn{color:#005;font-weight:bold;} /* Name.Namespace */
  39 + .nt{color:#000080;} /* Name.Tag */
  40 + .nv{color:#008080;} /* Name.Variable */
  41 + .py { color: #336699; font-weight: bold } /* Name.Property */
  42 + .ow { color: #008800 } /* Operator.Word */
  43 + .w { color: #bbbbbb } /* Text.Whitespace */
  44 + .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
  45 + .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
  46 + .mi {color:#099;} /* Literal.Number.Integer */
  47 + .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
  48 + .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
  49 + .sc{color:#d14;} /* Literal.String.Char */
  50 + .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
  51 + .s2{color:#d14;} /* Literal.String.Double */
  52 + .se{color:#d14;} /* Literal.String.Escape */
  53 + .sh{color:#d14;} /* Literal.String.Heredoc */
  54 + .si{color:#d14;} /* Literal.String.Interpol */
  55 + .sx{color:#d14;} /* Literal.String.Other */
  56 + .sr{color:#d14;} /* Literal.String.Regex */
  57 + .s1{color:#d14;} /* Literal.String.Single */
  58 + .ss{color:#d14;} /* Literal.String.Symbol */
  59 + .bp { color: #003388 } /* Name.Builtin.Pseudo */
  60 + .vc { color: #336699 } /* Name.Variable.Class */
  61 + .vg { color: #dd7700 } /* Name.Variable.Global */
  62 + .vi { color: #3333bb }
45 63 }
46 64  
47   -td.linenos {
48   - /*background:#F7F7F7;*/
49   - color:#666;
50   - padding:10px 0px 0px 10px;
51   - float:left;
52   - width:45px;
53   - border-right: 1px solid #ccc;
54   -
55   -}
56   -
57   -td.code .highlight {
58   - overflow: auto;
59   -}
60   -table.highlighttable pre{
61   - padding:0;
62   - margin:0;
63   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
64   - color: #333;
65   - text-align:left;
66   -}
67   -
68   -.git-empty .highlight {
69   - pre{
70   - padding:15px;
71   - line-height:2.0;
72   - margin:0;
73   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
74   - color: #333;
75   - text-align:left;}
76   - }
77   -
78   -.shadow{
  65 +.shadow {
79 66 -webkit-box-shadow:0 5px 15px #000;
80 67 -moz-box-shadow:0 5px 15px #000;
81 68 box-shadow:0 5px 15px #000;
82 69 }
83   -
84   -.hll { background-color: #ffffff }
85   -.c { color: #888888; font-style: italic } /* Comment */
86   -.err { color: #a61717; background-color: #e3d2d2 } /* Error */
87   -.k { color: #000000; font-weight: bold } /* Keyword */
88   -.cm { color: #888888 } /* Comment.Multiline */
89   -.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
90   -.c1 { color: #888888 } /* Comment.Single */
91   -.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
92   -.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
93   -.ge { font-style: italic } /* Generic.Emph */
94   -.gr { color: #aa0000 } /* Generic.Error */
95   -.gh { color: #303030 } /* Generic.Heading */
96   -.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
97   -.go { color: #888888 } /* Generic.Output */
98   -.gp { color: #555555 } /* Generic.Prompt */
99   -.gs { font-weight: bold } /* Generic.Strong */
100   -.gu { color: #606060 } /* Generic.Subheading */
101   -.gt { color: #aa0000 } /* Generic.Traceback */
102   -.highlight .kc{font-weight:bold;} /* Keyword.Constant */
103   -.highlight .kd{font-weight:bold;} /* Keyword.Declaration */
104   -.highlight .kn{font-weight:bold;} /* Keyword.Namespace */
105   -.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */
106   -.highlight .kr{font-weight:bold;} /* Keyword.Reserved */
107   -.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */
108   -.m { color: #0000DD; font-weight: bold } /* Literal.Number */
109   -.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
110   -.highlight .na{color:#008080;} /* Name.Attribute */
111   -.highlight .nb{color:#0086B3;} /* Name.Builtin */
112   -.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */
113   -.highlight .no{color:#008080;} /* Name.Constant */
114   -.highlight .ni{color:#800080;}
115   -.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */
116   -.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */
117   -.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */
118   -.highlight .nt{color:#000080;} /* Name.Tag */
119   -.highlight .nv{color:#008080;} /* Name.Variable */
120   -.py { color: #336699; font-weight: bold } /* Name.Property */
121   -.ow { color: #008800 } /* Operator.Word */
122   -.w { color: #bbbbbb } /* Text.Whitespace */
123   -.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
124   -.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
125   -.highlight .mi {color:#099;} /* Literal.Number.Integer */
126   -.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
127   -.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
128   -.highlight .sc{color:#d14;} /* Literal.String.Char */
129   -.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
130   -.highlight .s2{color:#d14;} /* Literal.String.Double */
131   -.highlight .se{color:#d14;} /* Literal.String.Escape */
132   -.highlight .sh{color:#d14;} /* Literal.String.Heredoc */
133   -.highlight .si{color:#d14;} /* Literal.String.Interpol */
134   -.highlight .sx{color:#d14;} /* Literal.String.Other */
135   -.highlight .sr{color:#d14;} /* Literal.String.Regex */
136   -.highlight .s1{color:#d14;} /* Literal.String.Single */
137   -.highlight .ss{color:#d14;} /* Literal.String.Symbol */
138   -.bp { color: #003388 } /* Name.Builtin.Pseudo */
139   -.vc { color: #336699 } /* Name.Variable.Class */
140   -.vg { color: #dd7700 } /* Name.Variable.Global */
141   -.vi { color: #3333bb }
... ...
app/assets/stylesheets/main.scss
  1 +/** Override bootstrap variables **/
  2 +$baseFontSize: 13px !default;
  3 +$baseLineHeight: 18px !default;
  4 +
1 5 @import "bootstrap";
2 6 @import "bootstrap-responsive";
3 7 @import 'font-awesome';
4 8  
5 9 /** GitLab colors **/
6   -$link_color:#3A89A3;
7   -$blue_link: #2fa0bb;
8   -$style_color: #474d57;
  10 +$link_color: #3A89A3;
  11 +$blue_link: #2FA0BB;
  12 +$style_color: #474D57;
9 13 $hover: #D9EDF7;
  14 +$hover_border: #ADF;
10 15  
11 16 /** GitLab Fonts **/
12 17 @font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); }
  18 +$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;
13 19  
14 20 /** MIXINS **/
15 21 @mixin shade {
... ... @@ -19,9 +25,9 @@ $hover: #D9EDF7;
19 25 }
20 26  
21 27 @mixin solid_shade {
22   - -moz-box-shadow: 0 0 0 3px #eee;
23   - -webkit-box-shadow: 0 0 0 3px #eee;
24   - box-shadow: 0 0 0 3px #eee;
  28 + -moz-box-shadow: 0 0 0 3px #f1f1f1;
  29 + -webkit-box-shadow: 0 0 0 3px #f1f1f1;
  30 + box-shadow: 0 0 0 3px #f1f1f1;
25 31 }
26 32  
27 33 @mixin border-radius($radius) {
... ... @@ -64,6 +70,14 @@ $hover: #D9EDF7;
64 70 background-image: -o-linear-gradient($from, $to);
65 71 }
66 72  
  73 +@mixin bg-light-gray-gradient {
  74 + background:#f1f1f1;
  75 + background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1));
  76 + background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
  77 + background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
  78 + background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1);
  79 +}
  80 +
67 81 @mixin bg-gray-gradient {
68 82 background:#eee;
69 83 background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
... ... @@ -104,14 +118,12 @@ $hover: #D9EDF7;
104 118 @import "themes/ui_basic.scss";
105 119  
106 120 /**
107   - * UI mars theme
  121 + * UI themes:
108 122 */
109 123 @import "themes/ui_mars.scss";
110   -
111   -/**
112   - * UI Modern theme
113   - */
114 124 @import "themes/ui_modern.scss";
  125 +@import "themes/ui_gray.scss";
  126 +@import "themes/ui_color.scss";
115 127  
116 128 /**
117 129 * GitLab bootstrap.
... ... @@ -145,6 +157,7 @@ $hover: #D9EDF7;
145 157 @import "sections/merge_requests.scss";
146 158 @import "sections/graph.scss";
147 159 @import "sections/events.scss";
  160 +@import "sections/themes.scss";
148 161  
149 162 /**
150 163 * This scss file redefine chozen selectbox styles for
... ...
app/assets/stylesheets/ref_select.scss
... ... @@ -19,31 +19,66 @@
19 19 margin-right: 10px;
20 20  
21 21 .chzn-drop {
22   - margin:7px 0;
23 22 min-width: 400px;
24   - border: 2px solid $blue_link;
25   - @include border-radius(4px);
  23 + .chzn-results {
  24 + max-height:300px;
  25 + }
  26 + .chzn-search input {
  27 + min-width:365px;
  28 + }
  29 + }
  30 +}
  31 +
  32 +/** Fix for Search Dropdown Border **/
  33 +.chzn-container {
  34 + .chzn-search {
  35 + input:focus {
  36 + -webkit-box-shadow: none;
  37 + -moz-box-shadow: none;
  38 + box-shadow: none;
  39 + }
  40 + }
  41 +
  42 + .chzn-drop {
  43 + margin:7px 0;
  44 + min-width: 200px;
  45 + border: 1px solid #bbb;
  46 + border-radius:0;
26 47  
27 48 .chzn-results {
  49 + margin-top: 5px;
28 50 max-height:300px;
29 51  
30 52 .group-result {
31   - color: $blue_link;
  53 + color: $style_color;
  54 + border-bottom: 1px solid #EEE;
  55 + padding: 8px;
32 56 }
33 57 .active-result {
  58 + border-radius: 0;
  59 +
34 60 &.highlighted {
35   - background: $blue_link;
  61 + background: $hover;
  62 + color: $style_color;
  63 + }
  64 + &.result-selected {
  65 + background: #EEE;
  66 + border-left: 4px solid #CCC;
36 67 }
37 68 }
38 69 }
39 70  
40   - .chzn-search input {
41   - min-width:365px;
  71 + .chzn-search {
  72 + @include bg-gray-gradient;
  73 + input {
  74 + min-width:165px;
  75 + border-color: #CCC;
  76 + }
42 77 }
43 78 }
44 79  
45 80 .chzn-single {
46   - @include bg-gray-gradient;
  81 + @include bg-light-gray-gradient;
47 82  
48 83 div {
49 84 background:transparent;
... ... @@ -55,14 +90,3 @@
55 90 }
56 91 }
57 92 }
58   -
59   -/** Fix for Search Dropdown Border **/
60   -.chzn-container {
61   - .chzn-search {
62   - input:focus {
63   - -webkit-box-shadow: none;
64   - -moz-box-shadow: none;
65   - box-shadow: none;
66   - }
67   - }
68   -}
... ...
app/assets/stylesheets/sections/commits.scss
... ... @@ -47,12 +47,15 @@
47 47 padding-left: 32px;
48 48 }
49 49  
50   - .author,
51   - .committer {
  50 + .author a,
  51 + .committer a {
52 52 font-size:14px;
53 53 line-height:22px;
54 54 text-shadow:0 1px 1px #fff;
55 55 color:#777;
  56 + &:hover {
  57 + color: #999;
  58 + }
56 59 }
57 60  
58 61 .avatar {
... ... @@ -71,7 +74,9 @@
71 74 margin-bottom:1em;
72 75  
73 76 .diff_file_header {
74   - padding:7px 5px;
  77 + @extend .clearfix;
  78 + padding: 5px 5px 5px 10px;
  79 + color: #555;
75 80 border-bottom:1px solid #CCC;
76 81 background: #eee;
77 82 background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
... ... @@ -79,8 +84,23 @@
79 84 background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
80 85 background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
81 86  
82   - span {
  87 + > span {
  88 + font-family: $monospace;
83 89 font-size:14px;
  90 + line-height: 30px;
  91 + }
  92 +
  93 + a.view-commit{
  94 + font-weight: bold;
  95 + }
  96 +
  97 + .commit-short-id{
  98 + font-family: $monospace;
  99 + font-size: smaller;
  100 + }
  101 +
  102 + .file-mode{
  103 + font-family: $monospace;
84 104 }
85 105 }
86 106 .diff_file_content {
... ... @@ -89,7 +109,7 @@
89 109 background:#fff;
90 110 color:#333;
91 111 font-size: 12px;
92   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  112 + font-family: $monospace;
93 113 .old{
94 114 span.idiff{
95 115 background-color:#FAA;
... ... @@ -110,22 +130,34 @@
110 130 .diff_file_content_image {
111 131 background:#eee;
112 132 text-align:center;
113   - img {
  133 + .image {
  134 + display: inline-block;
114 135 margin:50px;
115   - padding:1px;
116 136 max-width:400px;
117 137  
118   - &.diff_image_removed {
119   - border: 1px solid #C00;
  138 + img{
  139 + background: url('trans_bg.gif');
  140 + }
  141 +
  142 + &.diff_removed {
  143 + img{
  144 + border: 1px solid #C00;
  145 + }
  146 + }
  147 +
  148 + &.diff_added {
  149 + img{
  150 + border: 1px solid #0C0;
  151 + }
120 152 }
121 153  
122   - &.diff_image_added {
123   - border: 1px solid #0C0;;
  154 + .image-info{
  155 + margin: 5px 0 0 0;
124 156 }
125 157 }
126 158  
127 159 &.img_compared {
128   - img {
  160 + .image {
129 161 max-width:300px;
130 162 }
131 163 }
... ... @@ -222,26 +254,41 @@
222 254 float:left;
223 255 @extend .lined;
224 256 min-width:65px;
225   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  257 + font-family: $monospace;
226 258 }
227 259  
228 260 .commit-author-name {
229 261 color: #777;
  262 + &:hover {
  263 + color: #999;
  264 + }
230 265 }
231 266 }
232 267  
233 268 .diff_file_header a,
234   -.file_stats a {
235   - color:$style_color;
  269 +.file-stats a {
  270 + color: $style_color;
236 271 }
237 272  
238   -.file_stats {
239   - span {
240   - img {
241   - width:14px;
242   - float:left;
243   - margin-right:6px;
244   - padding:2px 0;
  273 +.file-stats {
  274 + .new-file{
  275 + i{
  276 + color: #1BCF00;
  277 + }
  278 + }
  279 + .renamed-file{
  280 + i{
  281 + color: #FE9300;
  282 + }
  283 + }
  284 + .deleted-file{
  285 + i{
  286 + color: #FF0000;
  287 + }
  288 + }
  289 + .edit-file{
  290 + i{
  291 + color: #555;
245 292 }
246 293 }
247 294 }
... ... @@ -253,5 +300,5 @@
253 300 font-size:13px;
254 301 background: #474D57;
255 302 color:#fff;
256   - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace;
  303 + font-family: $monospace;
257 304 }
... ...
app/assets/stylesheets/sections/editor.scss
1 1 .file-editor {
2 2 #editor{
  3 + border: none;
  4 + border-radius: 0;
3 5 height: 500px;
4   - width: 100%;
  6 + margin: 0;
  7 + padding: 0;
5 8 position: relative;
  9 + width: 100%;
6 10 }
7   - .editor-commit-comment {
8   - padding-top:20px;
  11 +
  12 + .cancel-btn {
  13 + color: #B94A48;
  14 + &:hover {
  15 + color: #B94A48;
  16 + }
  17 + }
  18 + .commit-button-annotation {
  19 + @extend .alert;
  20 + @extend .alert-info;
  21 + display: inline-block;
  22 + margin: 0;
  23 + padding: 2px;
  24 +
  25 + > * {
  26 + float: left;
  27 + }
  28 +
  29 + .commit-btn {
  30 + @extend .save-btn;
  31 + }
  32 + .message {
  33 + display: inline-block;
  34 + margin: 5px 8px 0 8px;
  35 + }
  36 + }
  37 + .commit_message-group {
  38 + margin-top: 20px;
  39 +
  40 + label {
  41 + font-size: 16px;
  42 + line-height: 20px;
  43 + }
9 44 textarea {
10   - width: 50%;
11   - margin-left: 20px;
  45 + @extend .span8;
12 46 }
13 47 }
14 48 }
... ...
app/assets/stylesheets/sections/events.scss
... ... @@ -43,6 +43,7 @@
43 43 .event-body {
44 44 p {
45 45 color:#555;
  46 + padding-top: 5px;
46 47 }
47 48 .event-info {
48 49 color:#666;
... ... @@ -115,3 +116,29 @@
115 116 margin: -3px;
116 117 }
117 118 }
  119 +
  120 +/**
  121 + * Event filter
  122 + *
  123 + */
  124 +.event_filter {
  125 + position: absolute;
  126 + width: 40px;
  127 + margin-left: -50px;
  128 +
  129 + .filter_icon {
  130 + float: left;
  131 + border-left: 3px solid #4bc;
  132 + padding: 7px;
  133 + background: #f9f9f9;
  134 + margin-bottom: 10px;
  135 + img {
  136 + width:20px;
  137 + }
  138 +
  139 + &.inactive {
  140 + border-left: 3px solid #EEE;
  141 + opacity: 0.5;
  142 + }
  143 + }
  144 +}
... ...
app/assets/stylesheets/sections/header.scss
... ... @@ -3,18 +3,29 @@
3 3 *
4 4 */
5 5 header {
6   - width:100%;
7   - padding:0;
8   - margin:0;
9   - top:1px;
10   - left:0;
11   - background: #F1F1F1; /* for non-css3 browsers */
12   - border-bottom: 1px solid #ccc;
13   - box-shadow: 0 -1px 0 white inset;
14   - -moz-box-shadow: 0 -1px 0 white inset;
15   - -webkit-box-shadow: 0 -1px 0 white inset;
  6 + &.navbar-gitlab {
  7 + .navbar-inner {
  8 + height:45px;
  9 + padding: 5px;
  10 + background: #F1F1F1;
  11 +
  12 + .nav > li > a {
  13 + color: $style_color;
  14 + text-shadow: 0 1px 0 #fff;
  15 + font-size: 18px;
  16 + padding: 11px;
  17 + }
  18 +
  19 + /** NAV block with links and profile **/
  20 + .nav {
  21 + float: right;
  22 + margin-right: 0;
  23 + }
  24 + }
  25 + }
  26 +
16 27 z-index:10;
17   - height:60px;
  28 + /*height:60px;*/
18 29  
19 30 /**
20 31 *
... ... @@ -22,45 +33,26 @@ header {
22 33 *
23 34 */
24 35 .app_logo {
25   - width:200px;
  36 + width:170px;
26 37 float:left;
27   - position:relative;
28   - top:-5px;
29 38 a {
30 39 float:left;
  40 + padding: 0px;
31 41  
32 42 h1 {
33   - padding-top: 5px;
34 43 width:90px;
35   - background: url('logo_dark.png') no-repeat 0px -3px;
  44 + background: url('logo_dark.png') no-repeat 0px 2px;
36 45 float:left;
37   - margin-left:5px;
38   - font-size:36px;
39   - line-height:36px;
  46 + margin-left:2px;
  47 + font-size:30px;
  48 + line-height:48px;
40 49 font-weight:normal;
41 50 color:$style_color;
42 51 text-shadow: 0 1px 1px #FFF;
43   - padding-left:50px;
  52 + padding-left:45px;
44 53 height:40px;
45 54 font-family: 'Korolev', sans-serif;
46 55 }
47   -
48   - }
49   - .separator {
50   - margin-left:20px;
51   - float: left;
52   - height: 60px;
53   - width: 1px;
54   - background: white;
55   - border-left: 1px solid #DDD;
56   - margin-top: -10px;
57   - }
58   - }
59   - .container {
60   - .top_panel_content {
61   - margin:auto;
62   - position:relative;
63   - padding:15px 0;
64 56 }
65 57 }
66 58  
... ... @@ -74,33 +66,23 @@ header {
74 66 float:left;
75 67 margin:0;
76 68 margin-right:30px;
77   - font-size:36px;
78   - line-height:36px;
  69 + font-size:30px;
  70 + line-height:48px;
79 71 font-weight:normal;
80 72 color:$style_color;
81 73 text-shadow: 0 1px 1px #FFF;
82 74 font-family: 'Korolev', sans-serif;
83 75 }
84 76  
85   - .fbtn {
86   - float: right;
87   - margin-right:10px;
88   - .btn {
89   - margin-left:7px;
90   - background: #F1F1F1;
91   - border: 1px solid #CCC;
92   - }
93   - }
94   -
95   -
96 77 /**
97 78 *
98 79 * Search box
99 80 *
100 81 */
101 82 .search {
102   - float: right;
103 83 margin-right: 45px;
  84 + margin-left:10px;
  85 + margin-top: 2px;
104 86  
105 87 .search-input {
106 88 @extend .span2;
... ... @@ -108,8 +90,13 @@ header {
108 90 background-repeat: no-repeat;
109 91 background-position: 10px;
110 92 padding-left:25px;
111   - @include border-radius(5px);
112   - border:1px solid #ccc;
  93 + font-size: 13px;
  94 + @include border-radius(3px);
  95 + border:1px solid #c6c6c6;
  96 + box-shadow:none;
  97 + &:focus {
  98 + @extend .span3;
  99 + }
113 100 }
114 101 }
115 102  
... ... @@ -121,7 +108,7 @@ header {
121 108 .account-box {
122 109 position: absolute;
123 110 right: 0;
124   - top: 13px;
  111 + top: 6px;
125 112 z-index: 10000;
126 113 width: 128px;
127 114 font-size: 11px;
... ... @@ -129,13 +116,13 @@ header {
129 116 display: block;
130 117 cursor: pointer;
131 118 img {
132   - @include border-radius(4px);
  119 + @include border-radius(3px);
133 120 right: 5px;
134 121 position: absolute;
135 122 width: 28px;
136 123 height: 28px;
137 124 display: block;
138   - top: 2px;
  125 + top:1px;
139 126 &:after {
140 127 content: " ";
141 128 display: block;
... ... @@ -162,12 +149,7 @@ header {
162 149 display: block; } }
163 150  
164 151 .account-links {
165   - background: #79C3E0;
166   - display: none;
167 152 border-radius: 5px;
168   - width: 100px;
169   - margin-top: 0;
170   - float: right;
171 153 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
172 154 position: relative;
173 155 &:before {
... ... @@ -177,32 +159,33 @@ header {
177 159 position: absolute;
178 160 border: 5px solid transparent;
179 161 border-color: rgba(255, 255, 255, 0);
180   - border-bottom-color: #333;
  162 + border-bottom-color: #555;
181 163 text-indent: -9999px;
182 164 top: -10px;
183 165 line-height: 0;
184 166 right: 10px;
185 167 z-index: 10; }
186   - background: #333;
  168 + background: #555;
187 169 display: none;
188 170 z-index: 100000;
189   - border-radius: 5px;
  171 + @include border-radius(4px);
190 172 width: 100px;
191 173 position: absolute;
192   - right: 10px;
193   - top: 42px;
  174 + right: 5px;
  175 + top: 38px;
194 176 margin-top: 0;
195 177 float: right;
196 178 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
197 179 a {
198   - color: #EEE;
199   - padding: 6px 10px;
  180 + color: #fff;
  181 + padding: 7px 10px;
200 182 display: block;
201 183 text-shadow: none;
202   - border-bottom: 1px solid #555;
  184 + border-bottom: 1px solid #666;
  185 + font-size: 12px;
203 186 &:hover {
204   - color:#eee;
205   - background: #444;
  187 + color:#fff;
  188 + background: #333;
206 189 }
207 190 }
208 191 }
... ... @@ -228,5 +211,52 @@ header {
228 211 border-bottom-right-radius: 5px;
229 212 border-bottom-left-radius: 5px;
230 213 border-bottom: 0; } }
  214 +
  215 +
  216 +
  217 + /*
  218 + * Dark header
  219 + *
  220 + */
  221 + &.header-dark {
  222 + &.navbar-gitlab {
  223 + .navbar-inner {
  224 + background: #708090;
  225 + border-bottom: 1px solid #AAA;
  226 +
  227 + .nav > li > a {
  228 + color: #fff;
  229 + text-shadow: 0 1px 0 #111;
  230 + }
  231 + }
  232 + }
  233 +
  234 + .search {
  235 + .search-input {
  236 + background-color: #D2D5DA;
  237 + background-color: rgba(255, 255, 255, 0.5);
  238 +
  239 + &:focus {
  240 + background-color: white;
  241 + }
  242 + }
  243 + }
  244 + .search-input::-webkit-input-placeholder {
  245 + color: #666;
  246 + }
  247 + .app_logo {
  248 + a {
  249 + h1 {
  250 + background: url('logo_white.png') no-repeat 0px 2px;
  251 + color:#fff;
  252 + text-shadow: 0 1px 1px #111;
  253 + }
  254 + }
  255 + }
  256 + .project_name {
  257 + color:#fff;
  258 + text-shadow: 0 1px 1px #111;
  259 + }
  260 + }
231 261 }
232 262  
... ...
app/assets/stylesheets/sections/issues.scss
... ... @@ -44,7 +44,7 @@
44 44  
45 45 img.avatar {
46 46 width:32px;
47   - margin-top:4px;
  47 + margin-top:1px;
48 48 }
49 49 }
50 50 }
... ...
app/assets/stylesheets/sections/merge_requests.scss
... ... @@ -71,7 +71,7 @@ li.merge_request {
71 71 padding:7px 10px;
72 72 img.avatar {
73 73 width: 32px;
74   - margin-top: 4px;
  74 + margin-top: 1px;
75 75 }
76 76 p {
77 77 padding: 0px;
... ... @@ -121,3 +121,25 @@ li.merge_request {
121 121 .mr_direction_tip {
122 122 margin-top:40px
123 123 }
  124 +
  125 +.merge_requests_form_box {
  126 + @extend .main_box;
  127 + .merge_requests_middle_box {
  128 + @extend .middle_box_content;
  129 + height:30px;
  130 + .merge_requests_assignee {
  131 + @extend .span6;
  132 + float:left;
  133 + }
  134 + .merge_requests_milestone {
  135 + @extend .span4;
  136 + float:left;
  137 + }
  138 + }
  139 +}
  140 +
  141 +.status-badge {
  142 + height: 32px;
  143 + width: 100%;
  144 + @include border-radius(5px);
  145 +}
... ...
app/assets/stylesheets/sections/nav.scss
... ... @@ -6,7 +6,7 @@ ul.main_menu {
6 6 border-radius: 4px;
7 7 margin: auto;
8 8 margin:30px 0;
9   - border:1px solid #AAA;
  9 + border:1px solid #BBB;
10 10 height:37px;
11 11 @include bg-gray-gradient;
12 12 position:relative;
... ...
app/assets/stylesheets/sections/profile.scss
... ... @@ -6,3 +6,17 @@
6 6 }
7 7 }
8 8 }
  9 +
  10 +.profile_avatar_holder {
  11 + float:left;
  12 + width:60px;
  13 + height:60px;
  14 + margin-right:20px;
  15 + img {
  16 + width:60px;
  17 + height:60px;
  18 + background:#fff;
  19 + padding: 1px;
  20 + border: 1px solid #ddd;
  21 + }
  22 +}
... ...
app/assets/stylesheets/sections/projects.scss
... ... @@ -85,9 +85,18 @@
85 85 }
86 86  
87 87 .project_clone_holder {
  88 + input[type="text"],
  89 + .btn {
  90 + font-size:12px;
  91 + line-height: 18px;
  92 + margin: 0;
  93 + padding: 3px 10px;
  94 + }
  95 +
88 96 input[type="text"] {
89 97 border: 1px solid #BBB;
90 98 box-shadow: none;
  99 + margin-left: -1px;
91 100 }
92 101 }
93 102  
... ...
app/assets/stylesheets/sections/themes.scss 0 → 100644
... ... @@ -0,0 +1,60 @@
  1 +.application-theme, .code-preview-theme {
  2 + .update-feedback {
  3 + color: #468847;
  4 + float: right;
  5 + }
  6 +}
  7 +
  8 +.themes_opts {
  9 + padding-left:20px;
  10 +
  11 + label {
  12 + width:175px;
  13 + margin-right:40px;
  14 +
  15 + .prev {
  16 + @extend .thumbnail;
  17 + height:30px;
  18 + width:175px;
  19 + margin-bottom:10px;
  20 +
  21 + &.classic {
  22 + background: #31363e;
  23 + }
  24 +
  25 + &.default {
  26 + background: #f1f1f1;
  27 + }
  28 +
  29 + &.modern {
  30 + background: #567;
  31 + }
  32 +
  33 + &.gray {
  34 + background: #708090;
  35 + }
  36 +
  37 + &.violet {
  38 + background: #657;
  39 + }
  40 + }
  41 + }
  42 +}
  43 +
  44 +.code_highlight_opts {
  45 + padding-left:20px;
  46 +
  47 + label {
  48 + width:220px;
  49 + margin-right:40px;
  50 +
  51 + .prev {
  52 + @extend .thumbnail;
  53 + height:151px;
  54 + width:220px;
  55 + margin-bottom:10px;
  56 + }
  57 + }
  58 +}
  59 +
  60 +
... ...
app/assets/stylesheets/sections/tree.scss
... ... @@ -57,10 +57,7 @@
57 57 padding-right: 8px;
58 58  
59 59 img.avatar {
60   - border: 0 none;
61   - float: none;
62   - margin-right: 0;
63   - padding: 0;
  60 + margin-top: 0;
64 61 width: 16px;
65 62 }
66 63 }
... ... @@ -75,6 +72,15 @@
75 72 }
76 73 }
77 74 }
  75 +
  76 + .blame {
  77 + img.avatar {
  78 + border: 0 none;
  79 + float: none;
  80 + margin: 0;
  81 + padding: 0;
  82 + }
  83 + }
78 84 }
79 85  
80 86 .tree-btn-group {
... ...
app/assets/stylesheets/themes/ui_basic.scss
... ... @@ -16,35 +16,21 @@
16 16 }
17 17 }
18 18  
19   - header {
20   - .fbtn {
21   - .btn {
22   - background-color: #F8F8F8;
23   - background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC));
24   - background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC);
25   - background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC);
26   - background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC);
27   - background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC);
28   - background-image: linear-gradient(top,#F8F8F8,#ECECEC);
29   - filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec');
30   - border-color: #C6C6C6;
31   - margin-left:7px;
32   - @include border-radius(3px);
33   - box-shadow:none;
34   - color:#666;
35   - }
36   - }
37   - .search {
38   - .search-input {
39   - @include border-radius(3px);
40   - border-color: #C6C6C6;
41   - box-shadow:none;
42   - }
43   - }
44   - .pic {
45   - img {
46   - @include border-radius(3px);
47   - }
  19 + .app_logo {
  20 + .separator {
  21 + margin-left: 0;
  22 + margin-right: 0;
48 23 }
49 24 }
  25 +
  26 + .separator {
  27 + float: left;
  28 + height: 60px;
  29 + width: 1px;
  30 + background: white;
  31 + border-left: 1px solid #DDD;
  32 + margin-top: -10px;
  33 + margin-left: 10px;
  34 + margin-right: 10px;
  35 + }
50 36 }
... ...
app/assets/stylesheets/themes/ui_color.scss 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +/**
  2 + * This file represent some UI that can be changed
  3 + * during web app restyle or theme select.
  4 + *
  5 + * Next items should be placed there
  6 + * - link colors
  7 + * - header restyles
  8 + *
  9 + */
  10 +.ui_color {
  11 + /*
  12 + * Application Header
  13 + *
  14 + */
  15 + header {
  16 + @extend .header-dark;
  17 + &.navbar-gitlab {
  18 + .navbar-inner {
  19 + background: #657;
  20 + }
  21 + }
  22 + }
  23 +}
... ...
app/assets/stylesheets/themes/ui_gray.scss 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +/**
  2 + * This file represent some UI that can be changed
  3 + * during web app restyle or theme select.
  4 + *
  5 + * Next items should be placed there
  6 + * - link colors
  7 + * - header restyles
  8 + *
  9 + */
  10 +.ui_gray {
  11 + /*
  12 + * Application Header
  13 + *
  14 + */
  15 + header {
  16 + @extend .header-dark;
  17 + &.navbar-gitlab {
  18 + .navbar-inner {
  19 + background: #708090;
  20 + }
  21 + }
  22 + }
  23 +}
... ...
app/assets/stylesheets/themes/ui_mars.scss
... ... @@ -14,45 +14,24 @@
14 14 *
15 15 */
16 16 header {
17   - background: #474D57 url('bg-header.png') repeat-x bottom;
18   - box-shadow:none;
19   - border-bottom: 1px solid #444;
20 17  
21   - .fbtn {
22   - .btn {
23   - i {
24   - position: relative;
25   - top: 1px;
26   - }
27   - margin-left:8px;
28   - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#31363E));
29   - background-image: -webkit-linear-gradient(#595D63 6.6%, #31363E);
30   - background-image: -moz-linear-gradient(#595D63 6.6%, #31363E);
31   - background-image: -o-linear-gradient(#595D63 6.6%, #31363E);
32   - font-size: 12px;
33   - &:hover {
34   - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#2C2F35));
35   - background-image: -webkit-linear-gradient(#595D63 6.6%, #2C2F35);
36   - background-image: -moz-linear-gradient(#595D63 6.6%, #202227);
37   - background-image: -o-linear-gradient(#595D63 6.6%, #202227);
38   - background-position:0 0;
39   - color:#fff;
40   - i {
41   - @extend .icon-white;
42   - }
43   - }
  18 + &.navbar-gitlab {
  19 + .navbar-inner {
  20 + background: #474D57 url('bg-header.png') repeat-x bottom;
  21 + border-bottom: 1px solid #444;
44 22  
45   - border: 1px solid #31363E;
46   - color:#D6DADF;
47   - text-shadow: 0 -1px 0 #000000;
  23 + .nav > li > a {
  24 + color: #eee;
  25 + text-shadow: 0 1px 0 #444;
  26 + }
48 27 }
49 28 }
  29 +
50 30 .search {
51 31 float: right;
52 32 margin-right: 45px;
53 33 .search-input {
54 34 border: 1px solid rgba(0, 0, 0, 0.7);
55   - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
56 35 background-color: #D2D5DA;
57 36 background-color: rgba(255, 255, 255, 0.5);
58 37  
... ... @@ -67,8 +46,8 @@
67 46 .app_logo {
68 47 a {
69 48 h1 {
70   - background: url('logo_white.png') no-repeat 0px -3px;
71   - color:#fff;
  49 + background: url('logo_white.png') no-repeat 0px 2px;
  50 + color:#eee;
72 51 text-shadow: 0 1px 1px #111;
73 52 }
74 53 }
... ... @@ -78,7 +57,7 @@
78 57  
79 58 }
80 59 .project_name {
81   - color:#fff;
  60 + color:#eee;
82 61 text-shadow: 0 1px 1px #111;
83 62 }
84 63 }
... ...
app/assets/stylesheets/themes/ui_modern.scss
... ... @@ -4,8 +4,7 @@
4 4 *
5 5 * Next items should be placed there
6 6 * - link colors
7   - * - header styles
8   - * - main menu styles
  7 + * - header restyles
9 8 *
10 9 */
11 10 .ui_modern {
... ... @@ -14,120 +13,10 @@
14 13 *
15 14 */
16 15 header {
17   - height:40px;
18   - background-image: -moz-linear-gradient(top, #333, #222);
19   - background-image: -ms-linear-gradient(top, #333, #222);
20   - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222));
21   - background-image: -webkit-linear-gradient(top, #333, #222);
22   - background-image: -o-linear-gradient(top, #333, #222);
23   - background-image: linear-gradient(top, #333, #222);
24   - background-repeat: repeat-x;
25   - background-repeat: repeat-x;
26   - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);
27   - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
28   - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
29   - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
30   -
31   - .container .top_panel_content { padding: 5px 0; }
32   -
33   -
34   - /**
35   - *
36   - * Logo holder
37   - *
38   - */
39   - .app_logo {
40   - width:160px;
41   - a {
42   - h1 {
43   - background: none;
44   - color:#DDD;
45   - font-size:30px;
46   - text-shadow: 0 1px 1px #111;
47   - padding-left: 0;
48   - }
49   - }
50   - .separator {
51   - width: 1px;
52   - height: 40px;
53   - margin: 0 10px;
54   - overflow: hidden;
55   - background: #222;
56   - border-left: 1px solid #333;
57   - }
58   - }
59   -
60   - .fbtn {
61   - .btn {
62   - i {
63   - position: relative;
64   - top: 2px;
65   - }
66   - background:none;
67   - margin-left:8px;
68   - font-size: 13px;
69   - line-height: 19px;
70   - color:#ccc;
71   - &:hover {
72   - color:#fff;
73   - i {
74   - @extend .icon-white;
75   - }
76   - }
77   - border: none;
78   - box-shadow:none;
79   - text-shadow: 0 -1px 0 #000000;
80   - border-left: 1px solid #333;
81   - }
82   - }
83   -
84   - /**
85   - *
86   - * Search box
87   - *
88   - */
89   - .search {
90   - float: right;
91   - margin-right: 45px;
92   - .search-input {
93   - border: 1px solid rgba(0, 0, 0, 0.7);
94   - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset;
95   - background-color: #D2D5DA;
96   - background-color: rgba(255, 255, 255, 0.5);
97   -
98   - &:focus {
99   - background-color: white;
100   - }
101   - }
102   - .search-input::-webkit-input-placeholder {
103   - color: #666;
104   - }
105   - }
106   -
107   - /**
108   - *
109   - * Project / Area name
110   - *
111   - */
112   - .project_name {
113   - line-height:36px;
114   - font-size:30px;
115   - color:#DDD;
116   - text-shadow: 0 1px 1px #111;
117   - }
118   -
119   - /**
120   - *
121   - * Account box
122   - *
123   - */
124   - .account-box {
125   - top:6px;
126   - img {
127   - top:1px;
128   - right: 5px;
129   - width: 26px;
130   - height: 26px;
  16 + @extend .header-dark;
  17 + &.navbar-gitlab {
  18 + .navbar-inner {
  19 + background: #567;
131 20 }
132 21 }
133 22 }
... ...
app/contexts/commit_load_context.rb
... ... @@ -21,7 +21,7 @@ class CommitLoadContext &lt; BaseContext
21 21 result[:notes_count] = line_notes.count + project.commit_notes(commit).count
22 22  
23 23 begin
24   - result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
  24 + result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
25 25 rescue Grit::Git::GitTimeout
26 26 result[:suppress_diff] = true
27 27 result[:status] = :huge_commit
... ...
app/contexts/merge_requests_load_context.rb
  1 +# Build collection of Merge Requests
  2 +# based on filtering passed via params for @project
1 3 class MergeRequestsLoadContext < BaseContext
2 4 def execute
3 5 type = params[:f]
... ... @@ -9,8 +11,21 @@ class MergeRequestsLoadContext &lt; BaseContext
9 11 when 'closed' then merge_requests.closed
10 12 when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
11 13 else merge_requests.opened
12   - end.page(params[:page]).per(20)
  14 + end
13 15  
14   - merge_requests.includes(:author, :project).order("closed, created_at desc")
  16 + merge_requests = merge_requests.page(params[:page]).per(20)
  17 + merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc")
  18 +
  19 + # Filter by specific assignee_id (or lack thereof)?
  20 + if params[:assignee_id].present?
  21 + merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
  22 + end
  23 +
  24 + # Filter by specific milestone_id (or lack thereof)?
  25 + if params[:milestone_id].present?
  26 + merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
  27 + end
  28 +
  29 + merge_requests
15 30 end
16 31 end
... ...
app/contexts/search_context.rb
... ... @@ -13,6 +13,7 @@ class SearchContext
13 13 result[:projects] = Project.where(id: project_ids).search(query).limit(10)
14 14 result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
15 15 result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
  16 + result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10)
16 17 result
17 18 end
18 19  
... ... @@ -20,7 +21,8 @@ class SearchContext
20 21 @result ||= {
21 22 projects: [],
22 23 merge_requests: [],
23   - issues: []
  24 + issues: [],
  25 + wiki_pages: []
24 26 }
25 27 end
26 28 end
... ...
app/controllers/admin/dashboard_controller.rb
1 1 class Admin::DashboardController < AdminController
2 2 def index
3   - @workers = Resque.workers
4   - @pending_jobs = Resque.size(:post_receive)
5 3 @projects = Project.order("created_at DESC").limit(10)
6 4 @users = User.order("created_at DESC").limit(10)
  5 +
  6 + @resque_accessible = true
  7 + @workers = Resque.workers
  8 + @pending_jobs = Resque.size(:post_receive)
  9 +
  10 + rescue Redis::InheritedError
  11 + @resque_accessible = false
7 12 end
8 13 end
... ...
app/controllers/admin/projects_controller.rb
... ... @@ -4,7 +4,7 @@ class Admin::ProjectsController &lt; AdminController
4 4 def index
5 5 @admin_projects = Project.scoped
6 6 @admin_projects = @admin_projects.search(params[:name]) if params[:name].present?
7   - @admin_projects = @admin_projects.page(params[:page]).per(20)
  7 + @admin_projects = @admin_projects.order("name ASC").page(params[:page]).per(20)
8 8 end
9 9  
10 10 def show
... ...
app/controllers/admin/users_controller.rb
... ... @@ -98,6 +98,9 @@ class Admin::UsersController &lt; AdminController
98 98  
99 99 def destroy
100 100 @admin_user = User.find(params[:id])
  101 + if @admin_user.my_own_projects.count > 0
  102 + redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return
  103 + end
101 104 @admin_user.destroy
102 105  
103 106 respond_to do |format|
... ...
app/controllers/application_controller.rb
... ... @@ -9,19 +9,28 @@ class ApplicationController &lt; ActionController::Base
9 9 helper_method :abilities, :can?
10 10  
11 11 rescue_from Gitlab::Gitolite::AccessDenied do |exception|
  12 + log_exception(exception)
12 13 render "errors/gitolite", layout: "errors", status: 500
13 14 end
14 15  
15 16 rescue_from Encoding::CompatibilityError do |exception|
  17 + log_exception(exception)
16 18 render "errors/encoding", layout: "errors", status: 500
17 19 end
18 20  
19 21 rescue_from ActiveRecord::RecordNotFound do |exception|
  22 + log_exception(exception)
20 23 render "errors/not_found", layout: "errors", status: 404
21 24 end
22 25  
23 26 protected
24 27  
  28 + def log_exception(exception)
  29 + application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
  30 + application_trace.map!{ |t| " #{t}\n" }
  31 + logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
  32 + end
  33 +
25 34 def reject_blocked!
26 35 if current_user && current_user.blocked
27 36 sign_out current_user
... ...
app/controllers/blob_controller.rb
1 1 # Controller for viewing a file's blame
2 2 class BlobController < ProjectResourceController
3 3 include ExtractsPath
4   - include Gitlab::Encode
5 4  
6 5 # Authorize
7 6 before_filter :authorize_read_project!
... ... @@ -12,16 +11,9 @@ class BlobController &lt; ProjectResourceController
12 11  
13 12 def show
14 13 if @tree.is_blob?
15   - if @tree.text?
16   - encoding = detect_encoding(@tree.data)
17   - mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
18   - else
19   - mime_type = @tree.mime_type
20   - end
21   -
22 14 send_data(
23 15 @tree.data,
24   - type: mime_type,
  16 + type: @tree.mime_type,
25 17 disposition: 'inline',
26 18 filename: @tree.name
27 19 )
... ...
app/controllers/dashboard_controller.rb
1 1 class DashboardController < ApplicationController
2 2 respond_to :html
3 3  
  4 + before_filter :event_filter, only: :index
  5 +
4 6 def index
5 7 @groups = Group.where(id: current_user.projects.pluck(:group_id))
6   - @projects = current_user.projects_with_events
  8 + @projects = current_user.projects_sorted_by_activity
7 9 @projects = @projects.page(params[:page]).per(30)
8 10  
9   - @events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0)
  11 + @events = Event.in_projects(current_user.project_ids)
  12 + @events = @event_filter.apply_filter(@events)
  13 + @events = @events.limit(20).offset(params[:offset] || 0)
  14 +
10 15 @last_push = current_user.recent_push
11 16  
12 17 respond_to do |format|
... ... @@ -34,4 +39,8 @@ class DashboardController &lt; ApplicationController
34 39 format.atom { render layout: false }
35 40 end
36 41 end
  42 +
  43 + def event_filter
  44 + @event_filter ||= EventFilter.new(params[:event_filter])
  45 + end
37 46 end
... ...
app/controllers/groups_controller.rb
... ... @@ -54,7 +54,7 @@ class GroupsController &lt; ApplicationController
54 54 end
55 55  
56 56 def projects
57   - @projects ||= current_user.projects_with_events.where(group_id: @group.id)
  57 + @projects ||= current_user.projects_sorted_by_activity.where(group_id: @group.id)
58 58 end
59 59  
60 60 def project_ids
... ...
app/controllers/milestones_controller.rb
... ... @@ -31,7 +31,8 @@ class MilestonesController &lt; ProjectResourceController
31 31  
32 32 def show
33 33 @issues = @milestone.issues
34   - @users = @milestone.participants
  34 + @users = UserDecorator.decorate(@milestone.participants)
  35 + @merge_requests = @milestone.merge_requests
35 36  
36 37 respond_to do |format|
37 38 format.html
... ...
app/controllers/profile_controller.rb
... ... @@ -9,7 +9,11 @@ class ProfileController &lt; ApplicationController
9 9  
10 10 def update
11 11 @user.update_attributes(params[:user])
12   - redirect_to :back
  12 +
  13 + respond_to do |format|
  14 + format.html { redirect_to :back }
  15 + format.js
  16 + end
13 17 end
14 18  
15 19 def token
... ... @@ -22,7 +26,7 @@ class ProfileController &lt; ApplicationController
22 26 flash[:notice] = "Password was successfully updated. Please login with it"
23 27 redirect_to new_user_session_path
24 28 else
25   - render action: "password"
  29 + render 'account'
26 30 end
27 31 end
28 32  
... ...
app/controllers/projects_controller.rb
1   -require Rails.root.join('lib', 'gitlab', 'graph_commit')
  1 +require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
2 2  
3 3 class ProjectsController < ProjectResourceController
4 4 skip_before_filter :project, only: [:new, :create]
... ... @@ -21,9 +21,10 @@ class ProjectsController &lt; ProjectResourceController
21 21 @project = Project.create_by_user(params[:project], current_user)
22 22  
23 23 respond_to do |format|
  24 + flash[:notice] = 'Project was successfully created.' if @project.saved?
24 25 format.html do
25 26 if @project.saved?
26   - redirect_to(@project, notice: 'Project was successfully created.')
  27 + redirect_to @project
27 28 else
28 29 render action: "new"
29 30 end
... ... @@ -79,7 +80,9 @@ class ProjectsController &lt; ProjectResourceController
79 80 end
80 81  
81 82 def graph
82   - @days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
  83 + graph = Gitlab::Graph::JsonBuilder.new(project)
  84 +
  85 + @days_json, @commits_json = graph.days_json, graph.commits_json
83 86 end
84 87  
85 88 def destroy
... ...
app/controllers/refs_controller.rb
1 1 class RefsController < ProjectResourceController
2   - include Gitlab::Encode
3 2  
4 3 # Authorize
5 4 before_filter :authorize_read_project!
... ...
app/controllers/repositories_controller.rb
... ... @@ -16,9 +16,14 @@ class RepositoriesController &lt; ProjectResourceController
16 16 @tags = @project.tags
17 17 end
18 18  
  19 + def stats
  20 + @stats = Gitlab::GitStats.new(@project.repo, @project.root_ref)
  21 + @graph = @stats.graph
  22 + end
  23 +
19 24 def archive
20 25 unless can?(current_user, :download_code, @project)
21   - render_404 and return
  26 + render_404 and return
22 27 end
23 28  
24 29  
... ...
app/controllers/search_controller.rb
... ... @@ -5,5 +5,6 @@ class SearchController &lt; ApplicationController
5 5 @projects = result[:projects]
6 6 @merge_requests = result[:merge_requests]
7 7 @issues = result[:issues]
  8 + @wiki_pages = result[:wiki_pages]
8 9 end
9 10 end
... ...
app/controllers/services_controller.rb 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +class ServicesController < ProjectResourceController
  2 + # Authorize
  3 + before_filter :authorize_admin_project!
  4 +
  5 + respond_to :html
  6 +
  7 + def index
  8 + @gitlab_ci_service = @project.gitlab_ci_service
  9 + end
  10 +
  11 + def edit
  12 + @service = @project.gitlab_ci_service
  13 +
  14 + # Create if missing
  15 + @service = @project.create_gitlab_ci_service unless @service
  16 + end
  17 +
  18 + def update
  19 + @service = @project.gitlab_ci_service
  20 +
  21 + if @service.update_attributes(params[:service])
  22 + redirect_to edit_project_service_path(@project, :gitlab_ci)
  23 + else
  24 + render 'edit'
  25 + end
  26 + end
  27 +
  28 + def test
  29 + commits = project.commits(project.default_branch, nil, 3)
  30 + data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
  31 +
  32 + @service = project.gitlab_ci_service
  33 + @service.execute(data)
  34 +
  35 + redirect_to :back
  36 + end
  37 +end
... ...
app/controllers/tree_controller.rb
... ... @@ -26,15 +26,14 @@ class TreeController &lt; ProjectResourceController
26 26 end
27 27  
28 28 def update
29   - file_editor = Gitlab::FileEditor.new(current_user, @project, @ref)
30   - update_status = file_editor.update(
31   - @path,
  29 + edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
  30 + updated_successfully = edit_file_action.commit!(
32 31 params[:content],
33 32 params[:commit_message],
34 33 params[:last_commit]
35 34 )
36 35  
37   - if update_status
  36 + if updated_successfully
38 37 redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
39 38 else
40 39 flash[:notice] = "Your changes could not be commited, because the file has been changed"
... ...
app/decorators/commit_decorator.rb
... ... @@ -47,21 +47,15 @@ class CommitDecorator &lt; ApplicationDecorator
47 47 # Otherwise it will link to the author email as specified in the commit.
48 48 #
49 49 # options:
50   - # avatar: true will prepend avatar image
51   - def author_link(options)
52   - text = if options[:avatar]
53   - avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16
54   - "#{avatar} #{author_name}"
55   - else
56   - author_name
57   - end
58   - team_member = @project.try(:team_member_by_name_or_email, author_name, author_email)
  50 + # avatar: true will prepend the avatar image
  51 + # size: size of the avatar image in px
  52 + def author_link(options = {})
  53 + person_link(options.merge source: :author)
  54 + end
59 55  
60   - if team_member.nil?
61   - h.mail_to author_email, text.html_safe, class: "commit-author-link"
62   - else
63   - h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link"
64   - end
  56 + # Just like #author_link but for the committer.
  57 + def committer_link(options = {})
  58 + person_link(options.merge source: :committer)
65 59 end
66 60  
67 61 protected
... ... @@ -69,4 +63,30 @@ class CommitDecorator &lt; ApplicationDecorator
69 63 def no_commit_message
70 64 "--no commit message"
71 65 end
  66 +
  67 + # Private: Returns a link to a person. If the person has a matching user and
  68 + # is a member of the current @project it will link to the team member page.
  69 + # Otherwise it will link to the person email as specified in the commit.
  70 + #
  71 + # options:
  72 + # source: one of :author or :committer
  73 + # avatar: true will prepend the avatar image
  74 + # size: size of the avatar image in px
  75 + def person_link(options = {})
  76 + source_name = send "#{options[:source]}_name".to_sym
  77 + source_email = send "#{options[:source]}_email".to_sym
  78 + text = if options[:avatar]
  79 + avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size]
  80 + %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
  81 + else
  82 + source_name
  83 + end
  84 + team_member = @project.try(:team_member_by_name_or_email, source_name, source_email)
  85 +
  86 + if team_member.nil?
  87 + h.mail_to source_email, text.html_safe, class: "commit-#{options[:source]}-link"
  88 + else
  89 + h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-#{options[:source]}-link"
  90 + end
  91 + end
72 92 end
... ...
app/decorators/tree_decorator.rb
... ... @@ -8,14 +8,14 @@ class TreeDecorator &lt; ApplicationDecorator
8 8  
9 9 #parts = parts[0...-1] if is_blob?
10 10  
11   - yield(h.link_to("..", "#", remote: true)) if parts.count > max_links
  11 + yield(h.link_to("..", "#")) if parts.count > max_links
12 12  
13 13 parts.each do |part|
14 14 part_path = File.join(part_path, part) unless part_path.empty?
15 15 part_path = part if part_path.empty?
16 16  
17 17 next unless parts.last(2).include?(part) if parts.count > max_links
18   - yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true))
  18 + yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path))))
19 19 end
20 20 end
21 21 end
... ...
app/decorators/user_decorator.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class UserDecorator < ApplicationDecorator
  2 + decorates :user
  3 +
  4 + def avatar_image size = 16
  5 + h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size
  6 + end
  7 +
  8 + def tm_of(project)
  9 + project.team_member_by_id(self.id)
  10 + end
  11 +end
... ...
app/helpers/application_helper.rb
... ... @@ -36,7 +36,7 @@ module ApplicationHelper
36 36 else
37 37 gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
38 38 user_email.strip!
39   - "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
  39 + "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm"
40 40 end
41 41 end
42 42  
... ...
app/helpers/commits_helper.rb
... ... @@ -57,12 +57,17 @@ module CommitsHelper
57 57  
58 58 def image_diff_class(diff)
59 59 if diff.deleted_file
60   - "diff_image_removed"
  60 + "diff_removed"
61 61 elsif diff.new_file
62   - "diff_image_added"
  62 + "diff_added"
63 63 else
64 64 nil
65 65 end
66 66 end
67 67  
  68 + def commit_to_html commit
  69 + if commit.model
  70 + escape_javascript(render 'commits/commit', commit: commit)
  71 + end
  72 + end
68 73 end
... ...
app/helpers/events_helper.rb
... ... @@ -33,4 +33,22 @@ module EventsHelper
33 33 image_tag event_image_path
34 34 end
35 35 end
  36 +
  37 + def event_filter_link key, tooltip
  38 + key = key.to_s
  39 +
  40 + filter = @event_filter.options key
  41 +
  42 + inactive = if @event_filter.active? key
  43 + nil
  44 + else
  45 + 'inactive'
  46 + end
  47 +
  48 + content_tag :div, class: "filter_icon #{inactive}" do
  49 + link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do
  50 + image_tag "event_filter_#{key}.png"
  51 + end
  52 + end
  53 + end
36 54 end
... ...
app/helpers/merge_requests_helper.rb
... ... @@ -38,4 +38,8 @@ module MergeRequestsHelper
38 38 classes << " merged" if mr.merged?
39 39 classes
40 40 end
  41 +
  42 + def ci_status_path
  43 + @project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
  44 + end
41 45 end
... ...
app/helpers/projects_helper.rb
... ... @@ -10,5 +10,9 @@ module ProjectsHelper
10 10 def link_to_project project
11 11 link_to project.name, project
12 12 end
  13 +
  14 + def tm_path team_member
  15 + project_team_member_path(@project, team_member)
  16 + end
13 17 end
14 18  
... ...
app/helpers/tree_helper.rb
... ... @@ -67,4 +67,29 @@ module TreeHelper
67 67 can?(current_user, :push_code, @project)
68 68 end
69 69 end
  70 +
  71 + # Breadcrumb links for a Project and, if applicable, a tree path
  72 + def breadcrumbs
  73 + return unless @project && @ref
  74 +
  75 + # Add the root project link and the arrow icon
  76 + crumbs = content_tag(:li) do
  77 + content_tag(:span, nil, class: 'arrow') +
  78 + link_to(@project.name, project_commits_path(@project, @ref))
  79 + end
  80 +
  81 + if @path
  82 + parts = @path.split('/')
  83 +
  84 + parts.each_with_index do |part, i|
  85 + crumbs += content_tag(:span, '/', class: 'divider')
  86 + crumbs += content_tag(:li) do
  87 + # The text is just the individual part, but the link needs all the parts before it
  88 + link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
  89 + end
  90 + end
  91 + end
  92 +
  93 + crumbs.html_safe
  94 + end
70 95 end
... ...
app/models/commit.rb
1 1 class Commit
2 2 include ActiveModel::Conversion
3   - include Gitlab::Encode
4 3 include StaticModel
5 4 extend ActiveModel::Naming
6 5  
  6 + # Safe amount of files with diffs in one commit to render
  7 + # Used to prevent 500 error on huge commits by suppressing diff
  8 + #
  9 + DIFF_SAFE_SIZE = 100
  10 +
7 11 attr_accessor :commit, :head, :refs
8 12  
9 13 delegate :message, :authored_date, :committed_date, :parents, :sha,
... ... @@ -107,7 +111,7 @@ class Commit
107 111 end
108 112  
109 113 def safe_message
110   - @safe_message ||= utf8 message
  114 + @safe_message ||= message
111 115 end
112 116  
113 117 def created_at
... ... @@ -119,7 +123,7 @@ class Commit
119 123 end
120 124  
121 125 def author_name
122   - utf8 author.name
  126 + author.name
123 127 end
124 128  
125 129 # Was this commit committed by a different person than the original author?
... ... @@ -128,7 +132,7 @@ class Commit
128 132 end
129 133  
130 134 def committer_name
131   - utf8 committer.name
  135 + committer.name
132 136 end
133 137  
134 138 def committer_email
... ...
app/models/event.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: events
  4 +#
  5 +# id :integer not null, primary key
  6 +# target_type :string(255)
  7 +# target_id :integer
  8 +# title :string(255)
  9 +# data :text
  10 +# project_id :integer
  11 +# created_at :datetime not null
  12 +# updated_at :datetime not null
  13 +# action :integer
  14 +# author_id :integer
  15 +#
  16 +
1 17 class Event < ActiveRecord::Base
2 18 include PushEvent
3 19  
... ... @@ -144,20 +160,3 @@ class Event &lt; ActiveRecord::Base
144 160 end
145 161 end
146 162 end
147   -
148   -# == Schema Information
149   -#
150   -# Table name: events
151   -#
152   -# id :integer not null, primary key
153   -# target_type :string(255)
154   -# target_id :integer
155   -# title :string(255)
156   -# data :text
157   -# project_id :integer
158   -# created_at :datetime not null
159   -# updated_at :datetime not null
160   -# action :integer
161   -# author_id :integer
162   -#
163   -
... ...
app/models/gitlab_ci_service.rb 0 → 100644
... ... @@ -0,0 +1,39 @@
  1 +# == Schema Information
  2 +#
  3 +# Table name: services
  4 +#
  5 +# id :integer not null, primary key
  6 +# type :string(255)
  7 +# title :string(255)
  8 +# token :string(255)
  9 +# project_id :integer not null
  10 +# created_at :datetime not null
  11 +# updated_at :datetime not null
  12 +# active :boolean default(FALSE), not null
  13 +# project_url :string(255)
  14 +#
  15 +
  16 +class GitlabCiService < Service
  17 + attr_accessible :project_url
  18 +
  19 + validates :project_url, presence: true, if: :activated?
  20 + validates :token, presence: true, if: :activated?
  21 +
  22 + delegate :execute, to: :service_hook, prefix: nil
  23 +
  24 + after_save :compose_service_hook, if: :activated?
  25 +
  26 + def activated?
  27 + active
  28 + end
  29 +
  30 + def compose_service_hook
  31 + hook = service_hook || build_service_hook
  32 + hook.url = [project_url, "/build", "?token=#{token}"].join("")
  33 + hook.save
  34 + end
  35 +
  36 + def commit_badge_path sha
  37 + project_url + "/status?sha=#{sha}"
  38 + end
  39 +end
... ...
app/models/group.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: groups
  4 +#
  5 +# id :integer not null, primary key
  6 +# name :string(255) not null
  7 +# code :string(255) not null
  8 +# owner_id :integer not null
  9 +# created_at :datetime not null
  10 +# updated_at :datetime not null
  11 +#
  12 +
1 13 class Group < ActiveRecord::Base
2 14 attr_accessible :code, :name, :owner_id
3 15  
... ... @@ -22,16 +34,3 @@ class Group &lt; ActiveRecord::Base
22 34 User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq
23 35 end
24 36 end
25   -
26   -# == Schema Information
27   -#
28   -# Table name: groups
29   -#
30   -# id :integer not null, primary key
31   -# name :string(255) not null
32   -# code :string(255) not null
33   -# owner_id :integer not null
34   -# created_at :datetime not null
35   -# updated_at :datetime not null
36   -#
37   -
... ...
app/models/issue.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: issues
  4 +#
  5 +# id :integer not null, primary key
  6 +# title :string(255)
  7 +# assignee_id :integer
  8 +# author_id :integer
  9 +# project_id :integer
  10 +# created_at :datetime not null
  11 +# updated_at :datetime not null
  12 +# closed :boolean default(FALSE), not null
  13 +# position :integer default(0)
  14 +# branch_name :string(255)
  15 +# description :text
  16 +# milestone_id :integer
  17 +#
  18 +
1 19 class Issue < ActiveRecord::Base
2 20 include IssueCommonality
3 21 include Votes
... ... @@ -7,30 +25,9 @@ class Issue &lt; ActiveRecord::Base
7 25  
8 26 acts_as_taggable_on :labels
9 27  
10   - belongs_to :milestone
11   -
12 28 validates :description, length: { within: 0..2000 }
13 29  
14 30 def self.open_for(user)
15 31 opened.assigned(user)
16 32 end
17 33 end
18   -
19   -# == Schema Information
20   -#
21   -# Table name: issues
22   -#
23   -# id :integer not null, primary key
24   -# title :string(255)
25   -# assignee_id :integer
26   -# author_id :integer
27   -# project_id :integer
28   -# created_at :datetime not null
29   -# updated_at :datetime not null
30   -# closed :boolean default(FALSE), not null
31   -# position :integer default(0)
32   -# branch_name :string(255)
33   -# description :text
34   -# milestone_id :integer
35   -#
36   -
... ...
app/models/key.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: keys
  4 +#
  5 +# id :integer not null, primary key
  6 +# user_id :integer
  7 +# created_at :datetime not null
  8 +# updated_at :datetime not null
  9 +# key :text
  10 +# title :string(255)
  11 +# identifier :string(255)
  12 +# project_id :integer
  13 +#
  14 +
1 15 require 'digest/md5'
2 16  
3 17 class Key < ActiveRecord::Base
... ... @@ -67,18 +81,3 @@ class Key &lt; ActiveRecord::Base
67 81 Key.where(identifier: identifier).count == 0
68 82 end
69 83 end
70   -
71   -# == Schema Information
72   -#
73   -# Table name: keys
74   -#
75   -# id :integer not null, primary key
76   -# user_id :integer
77   -# created_at :datetime not null
78   -# updated_at :datetime not null
79   -# key :text
80   -# title :string(255)
81   -# identifier :string(255)
82   -# project_id :integer
83   -#
84   -
... ...
app/models/merge_request.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: merge_requests
  4 +#
  5 +# id :integer not null, primary key
  6 +# target_branch :string(255) not null
  7 +# source_branch :string(255) not null
  8 +# project_id :integer not null
  9 +# author_id :integer
  10 +# assignee_id :integer
  11 +# title :string(255)
  12 +# closed :boolean default(FALSE), not null
  13 +# created_at :datetime not null
  14 +# updated_at :datetime not null
  15 +# st_commits :text(2147483647)
  16 +# st_diffs :text(2147483647)
  17 +# merged :boolean default(FALSE), not null
  18 +# state :integer default(1), not null
  19 +# milestone_id :integer
  20 +#
  21 +
1 22 require Rails.root.join("app/models/commit")
  23 +require Rails.root.join("app/roles/static_model")
2 24  
3 25 class MergeRequest < ActiveRecord::Base
4 26 include IssueCommonality
5 27 include Votes
6 28  
7   - attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch,
  29 + attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id,
8 30 :author_id_of_changes
9 31  
10 32 attr_accessor :should_remove_source_branch
... ... @@ -26,6 +48,10 @@ class MergeRequest &lt; ActiveRecord::Base
26 48 where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
27 49 end
28 50  
  51 + def self.find_all_by_milestone(milestone)
  52 + where("milestone_id = :milestone_id", milestone_id: milestone)
  53 + end
  54 +
29 55 def human_state
30 56 states = {
31 57 CAN_BE_MERGED => "can_be_merged",
... ... @@ -60,7 +86,7 @@ class MergeRequest &lt; ActiveRecord::Base
60 86 end
61 87  
62 88 def check_if_can_be_merged
63   - self.state = if Gitlab::Merge.new(self, self.author).can_be_merged?
  89 + self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
64 90 CAN_BE_MERGED
65 91 else
66 92 CANNOT_BE_MERGED
... ... @@ -167,7 +193,7 @@ class MergeRequest &lt; ActiveRecord::Base
167 193 end
168 194  
169 195 def automerge!(current_user)
170   - if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty?
  196 + if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty?
171 197 self.merge!(current_user.id)
172 198 true
173 199 end
... ... @@ -193,24 +219,3 @@ class MergeRequest &lt; ActiveRecord::Base
193 219 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)
194 220 end
195 221 end
196   -
197   -# == Schema Information
198   -#
199   -# Table name: merge_requests
200   -#
201   -# id :integer not null, primary key
202   -# target_branch :string(255) not null
203   -# source_branch :string(255) not null
204   -# project_id :integer not null
205   -# author_id :integer
206   -# assignee_id :integer
207   -# title :string(255)
208   -# closed :boolean default(FALSE), not null
209   -# created_at :datetime not null
210   -# updated_at :datetime not null
211   -# st_commits :text(4294967295
212   -# st_diffs :text(4294967295
213   -# merged :boolean default(FALSE), not null
214   -# state :integer default(1), not null
215   -#
216   -
... ...
app/models/milestone.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: milestones
  4 +#
  5 +# id :integer not null, primary key
  6 +# title :string(255) not null
  7 +# project_id :integer not null
  8 +# description :text
  9 +# due_date :date
  10 +# closed :boolean default(FALSE), not null
  11 +# created_at :datetime not null
  12 +# updated_at :datetime not null
  13 +#
  14 +
1 15 class Milestone < ActiveRecord::Base
2 16 attr_accessible :title, :description, :due_date, :closed
3 17  
4 18 belongs_to :project
5 19 has_many :issues
  20 + has_many :merge_requests
6 21  
7 22 validates :title, presence: true
8 23 validates :project, presence: true
  24 + validates :closed, inclusion: { in: [true, false] }
9 25  
10 26 def self.active
11 27 where("due_date > ? OR due_date IS NULL", Date.today)
... ... @@ -15,8 +31,20 @@ class Milestone &lt; ActiveRecord::Base
15 31 User.where(id: issues.pluck(:assignee_id))
16 32 end
17 33  
  34 + def open_items_count
  35 + self.issues.opened.count + self.merge_requests.opened.count
  36 + end
  37 +
  38 + def closed_items_count
  39 + self.issues.closed.count + self.merge_requests.closed.count
  40 + end
  41 +
  42 + def total_items_count
  43 + self.issues.count + self.merge_requests.count
  44 + end
  45 +
18 46 def percent_complete
19   - ((self.issues.closed.count * 100) / self.issues.count).abs
  47 + ((closed_items_count * 100) / total_items_count).abs
20 48 rescue ZeroDivisionError
21 49 100
22 50 end
... ... @@ -25,18 +53,3 @@ class Milestone &lt; ActiveRecord::Base
25 53 "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
26 54 end
27 55 end
28   -
29   -# == Schema Information
30   -#
31   -# Table name: milestones
32   -#
33   -# id :integer not null, primary key
34   -# title :string(255) not null
35   -# project_id :integer not null
36   -# description :text
37   -# due_date :date
38   -# closed :boolean default(FALSE), not null
39   -# created_at :datetime not null
40   -# updated_at :datetime not null
41   -#
42   -
... ...
app/models/note.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: notes
  4 +#
  5 +# id :integer not null, primary key
  6 +# note :text
  7 +# noteable_id :string(255)
  8 +# noteable_type :string(255)
  9 +# author_id :integer
  10 +# created_at :datetime not null
  11 +# updated_at :datetime not null
  12 +# project_id :integer
  13 +# attachment :string(255)
  14 +# line_code :string(255)
  15 +#
  16 +
1 17 require 'carrierwave/orm/activerecord'
2 18 require 'file_size_validator'
3 19  
... ... @@ -23,13 +39,13 @@ class Note &lt; ActiveRecord::Base
23 39 mount_uploader :attachment, AttachmentUploader
24 40  
25 41 # Scopes
26   - scope :common, where(noteable_id: nil)
27   - scope :today, where("created_at >= :date", date: Date.today)
28   - scope :last_week, where("created_at >= :date", date: (Date.today - 7.days))
  42 + scope :common, ->{ where(noteable_id: nil) }
  43 + scope :today, ->{ where("created_at >= :date", date: Date.today) }
  44 + scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) }
29 45 scope :since, ->(day) { where("created_at >= :date", date: (day)) }
30   - scope :fresh, order("created_at ASC, id ASC")
31   - scope :inc_author_project, includes(:project, :author)
32   - scope :inc_author, includes(:author)
  46 + scope :fresh, ->{ order("created_at ASC, id ASC") }
  47 + scope :inc_author_project, ->{ includes(:project, :author) }
  48 + scope :inc_author, ->{ includes(:author) }
33 49  
34 50 def self.create_status_change_note(noteable, author, status)
35 51 create({
... ... @@ -107,20 +123,3 @@ class Note &lt; ActiveRecord::Base
107 123 note.start_with?('-1') || note.start_with?(':-1:')
108 124 end
109 125 end
110   -
111   -# == Schema Information
112   -#
113   -# Table name: notes
114   -#
115   -# id :integer not null, primary key
116   -# note :text
117   -# noteable_id :string(255)
118   -# noteable_type :string(255)
119   -# author_id :integer
120   -# created_at :datetime not null
121   -# updated_at :datetime not null
122   -# project_id :integer
123   -# attachment :string(255)
124   -# line_code :string(255)
125   -#
126   -
... ...
app/models/project.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: projects
  4 +#
  5 +# id :integer not null, primary key
  6 +# name :string(255)
  7 +# path :string(255)
  8 +# description :text
  9 +# created_at :datetime not null
  10 +# updated_at :datetime not null
  11 +# private_flag :boolean default(TRUE), not null
  12 +# code :string(255)
  13 +# owner_id :integer
  14 +# default_branch :string(255)
  15 +# issues_enabled :boolean default(TRUE), not null
  16 +# wall_enabled :boolean default(TRUE), not null
  17 +# merge_requests_enabled :boolean default(TRUE), not null
  18 +# wiki_enabled :boolean default(TRUE), not null
  19 +# group_id :integer
  20 +#
  21 +
1 22 require "grit"
2 23  
3 24 class Project < ActiveRecord::Base
... ... @@ -26,6 +47,7 @@ class Project &lt; ActiveRecord::Base
26 47 has_many :wikis, dependent: :destroy
27 48 has_many :protected_branches, dependent: :destroy
28 49 has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
  50 + has_one :gitlab_ci_service, dependent: :destroy
29 51  
30 52 delegate :name, to: :owner, allow_nil: true, prefix: true
31 53  
... ... @@ -104,8 +126,10 @@ class Project &lt; ActiveRecord::Base
104 126 end
105 127  
106 128 def repo_name
107   - if path == "gitolite-admin"
108   - errors.add(:path, " like 'gitolite-admin' is not allowed")
  129 + denied_paths = %w(gitolite-admin groups projects dashboard)
  130 +
  131 + if denied_paths.include?(path)
  132 + errors.add(:path, "like #{path} is not allowed")
109 133 end
110 134 end
111 135  
... ... @@ -160,26 +184,12 @@ class Project &lt; ActiveRecord::Base
160 184 def issues_labels
161 185 issues.tag_counts_on(:labels)
162 186 end
163   -end
164 187  
165   -# == Schema Information
166   -#
167   -# Table name: projects
168   -#
169   -# id :integer not null, primary key
170   -# name :string(255)
171   -# path :string(255)
172   -# description :text
173   -# created_at :datetime not null
174   -# updated_at :datetime not null
175   -# private_flag :boolean default(TRUE), not null
176   -# code :string(255)
177   -# owner_id :integer
178   -# default_branch :string(255)
179   -# issues_enabled :boolean default(TRUE), not null
180   -# wall_enabled :boolean default(TRUE), not null
181   -# merge_requests_enabled :boolean default(TRUE), not null
182   -# wiki_enabled :boolean default(TRUE), not null
183   -# group_id :integer
184   -#
  188 + def services
  189 + [gitlab_ci_service].compact
  190 + end
185 191  
  192 + def gitlab_ci?
  193 + gitlab_ci_service && gitlab_ci_service.active
  194 + end
  195 +end
... ...
app/models/project_hook.rb
1   -class ProjectHook < WebHook
2   - belongs_to :project
3   -end
4   -
5 1 # == Schema Information
6 2 #
7 3 # Table name: web_hooks
8 4 #
9   -# id :integer not null, primary key
  5 +# id :integer not null, primary key
10 6 # url :string(255)
11 7 # project_id :integer
12   -# created_at :datetime not null
13   -# updated_at :datetime not null
14   -# type :string(255) default("ProjectHook")
  8 +# created_at :datetime not null
  9 +# updated_at :datetime not null
  10 +# type :string(255) default("ProjectHook")
  11 +# service_id :integer
15 12 #
16 13  
  14 +class ProjectHook < WebHook
  15 + belongs_to :project
  16 +end
... ...
app/models/protected_branch.rb
  1 +# == Schema Information
  2 +#
  3 +# Table name: protected_branches
  4 +#
  5 +# id :integer not null, primary key
  6 +# project_id :integer not null
  7 +# name :string(255) not null
  8 +# created_at :datetime not null
  9 +# updated_at :datetime not null
  10 +#
  11 +
1 12 class ProtectedBranch < ActiveRecord::Base
2 13 include GitHost
3 14  
... ... @@ -18,15 +29,3 @@ class ProtectedBranch &lt; ActiveRecord::Base
18 29 project.commit(self.name)
19 30 end
20 31 end
21   -
22   -# == Schema Information
23   -#
24   -# Table name: protected_branches
25   -#
26   -# id :integer not null, primary key
27   -# project_id :integer not null
28   -# name :string(255) not null
29   -# created_at :datetime not null
30   -# updated_at :datetime not null
31   -#
32   -
... ...