Compare commits

..

11 Commits

Author SHA1 Message Date
Dmitriy Zaporozhets c90a98c55c Merge pull request #3168 from jojosch/owner-link-admin-4.2
Fix link to owner of group and team in admin interface (4.2)
2013-03-07 08:28:10 -08:00
Johannes Schleifenbaum c9556c6b60 Fix link to owner of group and team in admin interface 2013-03-07 13:10:02 +01:00
Dmitriy Zaporozhets d67117b5a1 fix team events show up 2013-02-21 09:03:07 +02:00
Dmitriy Zaporozhets 26e340fc6c Merge pull request #3001 from nafu/4-2/repo_patch
Fix file_name for archive
2013-02-18 07:13:44 -08:00
Fumiya Nakamura dc1d4eab22 Fix repository.rb archive 2013-02-15 06:03:22 -08:00
Fumiya Nakamura 24a7c0f63d Fix file_name for archive 2013-02-15 04:59:34 -08:00
Dmitriy Zaporozhets e5080755a8 Merge pull request #2947 from nafu/4.2/doc_patch
Update command to execute as git user
2013-02-13 09:25:21 -08:00
Dmitriy Zaporozhets 27975fda5d Merge pull request #2962 from donnykurnia/patch-1
Update recipe_content url to same branch
2013-02-11 22:50:11 -08:00
Donny Kurnia 4d2660777b Update recipe_content url to same branch
When checking the init.d/gitlab file, it should be using the same branch with the gitlabhq
2013-02-12 12:23:18 +07:00
Fumiya Nakamura 6ce2ff6697 Update command to execute as git user 2013-02-08 09:58:27 -08:00
Dmitriy Zaporozhets 970f86077a Up to 4.2 2013-02-08 09:02:30 +02:00
1043 changed files with 84457 additions and 12747 deletions

4
.gitignore vendored
View File

@ -2,7 +2,7 @@
.rbx/
db/*.sqlite3
db/*.sqlite3-journal
log/*.log*
log/*.log
tmp/
.sass-cache/
coverage/*
@ -20,11 +20,9 @@ config/database.yml
config/initializers/omniauth.rb
config/unicorn.rb
config/resque.yml
config/aws.yml
db/data.yml
.idea
.DS_Store
.chef
vendor/bundle/*
rails_best_practices_output.html
doc/code/*

2
.rspec
View File

@ -1 +1 @@
--colour --drb
--colour

View File

@ -1,6 +1,7 @@
language: ruby
env:
- DB=mysql TRAVIS=true
- DB=postgresql
- DB=mysql
before_install:
- sudo apt-get install libicu-dev -y
- gem install charlock_holmes -v="0.6.9"
@ -8,7 +9,7 @@ branches:
only:
- 'master'
rvm:
- 1.9.3-p392
- 1.9.3-p327
services:
- mysql
- postgresql

View File

@ -1,53 +1,13 @@
v 5.1.0
- You can login with email or username now
- Corrected project transfer rollback when repository cannot be moved
- Move both repo and wiki when project transfer requrested
- Admin area: project editing was removed from admin namespace
- Access: admin user has now access to any project.
v 5.0.0
- Replaced gitolite with gitlab-shell
- Removed gitolite-related libraries
- State machine added
- Setup gitlab as git user
- Internal API
- Show team tab for empty projects
- Import repository feature
- Updated rails
- Use lambda for scopes
- Redesign admin area -> users
- Redesign admin area -> user
- Secure link to file attachments
- Add validations for Group and Team names
- Restyle team page for project
- Update capybara, rspec-rails, poltergeist to recent versions
- Wiki on git using Gollum
- Added Solarized Dark theme for code review
- Dont show user emails in autocomplete lists, profile pages
- Added settings tab for group, team, project
- Replace user popup with icons in header
- Handle project moving with gitlab-shell
- Added select2-rails for selectboxes with ajax data load
- Fixed search field on projects page
- Added teams to search autocomplete
- Move groups and teams on dashboard sidebar to sub-tabs
- API: improved return codes and docs. (Felix Gilcher, Sebastian Ziebell)
- Redesign wall to be more like chat
- Snippets, Wall features are disabled by default for new projects
v 4.2.0
- Async gitolite calls
- Teams
- Project listing page
- Improved search
- Groups API
- Improved Network Graph
- Edit page for group
- User show page. Via /u/username
- Show help contents on pages for better navigation
- Async gitolite calls
- added satellites logs
- can_create_group, can_create_team booleans for User
- Process web hooks async
- GFM: Fix images escaped inside links
- Network graph improved
- Switchable branches for network graph
- API: Groups
- Fixed project download
v 4.1.0
- Optional Sign-Up
@ -63,7 +23,7 @@ v 4.1.0
- cleanup rake tasks
- fix backup/restore
- scss cleanup
- show preview for note images
- show preview for note images
- improved network-graph
- get rid of app/roles/
- added new classes Team, Repository
@ -77,7 +37,7 @@ v 4.1.0
v 4.0.0
- Remove project code and path from API. Use id instead
- Return valid clonable url to repo for web hook
- Fixed backup issue
- Fixed backup issue
- Reorganized settings
- Fixed commits compare
- Refactored scss

View File

@ -1,53 +1,26 @@
# Contact & support
If you want quick help, head over to our [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq).
Otherwise you can follow our [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) for a more systematic and thorough guide to solving your issues.
# Contribute to GitLab
This guide details how to use pull requests and the issues to improve GitLab.
## Recipes
## Closing policy for pull requests and issues
We collect user submitted installation scripts and config file templates for platforms we don't support officially.
We believe there is merit in allowing a certain amount of diversity.
You can get and submit your solution to running/configuring GitLab with your favorite OS/distro, database, web server, cloud hoster, configuration management tool, etc.
Pull requests and issues not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
Help us improve the collection of [GitLab Recipes](https://github.com/gitlabhq/gitlab-recipes/)
## Pull requests
We welcome pull request with improvements to GitLab code and/or documentation. The issues we would really like a pull request for are listed with the [status 'accepting merge/pull requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome.
## Feature suggestions
### Pull request guidelines
Follow the [Issue Submission Guide](https://github.com/gitlabhq/gitlabhq/wiki/Issue-Submission-Guide) and support other peoples ideas or propose your own.
If you can please submit a pull request with the fix including tests. The workflow to make a pull request is as follows:
1. Fork the project on GitHub
1. Create a feature branch
1. Write tests and code
1. If you have multiple commits please combine them into one commit by [squashing them](http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
1. Push the commit to your fork
1. Submit a pull request
## Code
We will accept pull requests if:
* The code has proper tests and all tests pass
* It can be merged without problems (if not please use: git rebase master)
* It doesn't break any existing functionality
* It's quality code that conforms to the [Rails style guide](https://github.com/bbatsov/rails-style-guide) and best practices
* The description includes a motive for your change and the method you used to achieve it
* It keeps the GitLab code base clean and well structured
* We think other users will need the same functionality
* If it makes changes to the UI the pull request should include screenshots
For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
## Issue tracker
The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
### Issue tracker guidelines
**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
* Describe your issue in detail
* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
* Add the last commit sha1 of the GitLab version you used to replicate the issue
* Add logs or screen shots when possible
* Link to the line of code that might be responsible for the problem
* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
Follow our [Developer Guide](https://github.com/gitlabhq/gitlabhq/wiki/Developer-Guide) to set you up for hacking on GitLab.

View File

@ -1,4 +0,0 @@
load 'deploy'
load 'deploy/assets'
require 'bundler/capistrano'
load 'config/deploy'

66
Gemfile
View File

@ -1,4 +1,4 @@
source "https://rubygems.org"
source "http://rubygems.org"
def darwin_only(require_as)
RUBY_PLATFORM.include?('darwin') && require_as
@ -8,26 +8,23 @@ def linux_only(require_as)
RUBY_PLATFORM.include?('linux') && require_as
end
gem "rails", "3.2.13"
gem "rails", "3.2.11"
# Supported DBs
gem "mysql2", group: :mysql
gem "pg", group: :postgres
# Auth
gem "devise"
gem 'omniauth', "~> 1.1.3"
gem "devise", "~> 2.1.0"
gem 'omniauth', "~> 1.1.1"
gem 'omniauth-google-oauth2'
gem 'omniauth-twitter'
gem 'omniauth-github'
# Extracting information from a git repository
# Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: '42297cdcee16284d2e4eff23d41377f52fc28b9d'
gem 'grit_ext', '~> 0.8.1'
# Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 1.0.0', require: 'grack'
# GITLAB patched libs
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e'
# LDAP Auth
gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap"
@ -35,31 +32,30 @@ gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap"
# Dump db to yml file. Mostly used to migrate from sqlite to mysql
gem 'gitlab_yaml_db', '1.0.0', require: "yaml_db"
# Gitolite client (for work with gitolite-admin repo)
gem "gitolite", '1.1.0'
# Syntax highlighter
gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", branch: "master"
# Language detection
gem "github-linguist", "~> 2.3.4" , require: "linguist"
# API
gem "grape", "~> 0.3.1"
gem "grape-entity", "~> 0.2.0"
gem "grape", "~> 0.2.1"
# Format dates and times
# based on human-friendly examples
gem "stamp"
# Enumeration fields
gem 'enumerize'
# Pagination
gem "kaminari", "~> 0.14.1"
# HAML
gem "haml-rails"
gem "haml-rails", "~> 0.3.5"
# Files attachments
gem "carrierwave"
gem "carrierwave", "~> 0.7.1"
# Authorization
gem "six"
@ -75,21 +71,18 @@ gem "redcarpet", "~> 2.2.2"
gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers
gem "unicorn"
# State machine
gem "state_machine"
gem "unicorn", "~> 4.4.0"
# Issue tags
gem "acts-as-taggable-on", "2.3.3"
# Decorators
gem "draper"
gem "draper", "~> 0.18.0"
# Background jobs
gem 'slim'
gem 'sinatra', require: nil
gem 'sidekiq'
gem 'sinatra', :require => nil
gem 'sidekiq', '2.6.4'
# HTTP requests
gem "httparty"
@ -100,20 +93,10 @@ gem "colored"
# GitLab settings
gem 'settingslogic'
# Wiki
# - Use latest master to resolve Gem dependency with Pygemnts
# github-linquist needs pygments 0.4.2 but Gollum 2.4.11
# requires pygments 0.3.2. The latest master Gollum has been updated
# to use pygments 0.4.2. Change this after next Gollum release.
gem "gollum", "~> 2.4.0", git: "https://github.com/gollum/gollum.git", ref: "5dcd3c8c8f"
# Misc
gem "foreman"
gem "git"
# Cache
gem "redis-rails"
group :assets do
gem "sass-rails", "~> 3.2.5"
gem "coffee-rails", "~> 3.2.2"
@ -121,7 +104,6 @@ group :assets do
gem "therubyracer"
gem 'chosen-rails', "0.9.8"
gem 'select2-rails'
gem 'jquery-atwho-rails', "0.1.7"
gem "jquery-rails", "2.1.3"
gem "jquery-ui-rails", "2.0.2"
@ -130,7 +112,6 @@ group :assets do
gem 'bootstrap-sass', "2.2.1.1"
gem "font-awesome-sass-rails", "~> 3.0.0"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
gem "gon"
end
group :development do
@ -152,14 +133,13 @@ group :development do
end
group :development, :test do
gem 'coveralls', require: false
gem 'rails-dev-tweaks'
gem 'spinach-rails'
gem "rspec-rails"
gem "capybara"
gem "pry"
gem "awesome_print"
gem "database_cleaner"
gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git"
gem "launchy"
gem 'factory_girl_rails'
@ -173,9 +153,7 @@ group :development, :test do
gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara
gem 'poltergeist', '1.1.0'
gem 'spork', '~> 1.0rc'
gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '5c2e092001074a8cf09f332d3714e9ba150bc8ca'
end
group :test do
@ -187,5 +165,5 @@ group :test do
end
group :production do
gem "gitlab_meta", '5.0'
gem "gitlab_meta", '4.0'
end

View File

@ -1,3 +1,10 @@
GIT
remote: https://github.com/bmabey/database_cleaner.git
revision: f89c34300e114be99532f14c115b2799a3380ac6
ref: f89c34300e114be99532f14c115b2799a3380ac6
specs:
database_cleaner (0.9.1)
GIT
remote: https://github.com/ctran/annotate_models.git
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
@ -6,16 +13,41 @@ GIT
activerecord (>= 2.3.0)
rake (>= 0.8.7)
GIT
remote: https://github.com/gitlabhq/grack.git
revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8
specs:
grack (1.0.0)
rack (~> 1.4.1)
GIT
remote: https://github.com/gitlabhq/grit.git
revision: 42297cdcee16284d2e4eff23d41377f52fc28b9d
ref: 42297cdcee16284d2e4eff23d41377f52fc28b9d
revision: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
ref: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
specs:
grit (2.5.0)
diff-lcs (~> 1.1)
mime-types (~> 1.15)
posix-spawn (~> 0.3.6)
GIT
remote: https://github.com/gitlabhq/grit_ext.git
revision: 8e6afc2da821354774aa4d1ee8a1aa2082f84a3e
ref: 8e6afc2da821354774aa4d1ee8a1aa2082f84a3e
specs:
grit_ext (0.6.1)
charlock_holmes (~> 0.6.9)
GIT
remote: https://github.com/gitlabhq/pygments.rb.git
revision: db1da0343adf86b49bdc3add04d02d2e80438d38
branch: master
specs:
pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
GIT
remote: https://github.com/gitlabhq/raphael-rails.git
revision: cb2c92a040b9b941a5f1aa1ea866cc26e944fe58
@ -23,89 +55,84 @@ GIT
raphael-rails (2.1.0)
GIT
remote: https://github.com/gollum/gollum.git
revision: 5dcd3c8c8f68158e43ff79861279088ee56d0ebe
ref: 5dcd3c8c8f
remote: https://github.com/jonleighton/poltergeist.git
revision: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
ref: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
specs:
gollum (2.4.11)
github-markdown (~> 0.5.3)
github-markup (>= 0.7.5, < 1.0.0)
grit (~> 2.5.0)
mustache (>= 0.99.4, < 1.0.0)
nokogiri (~> 1.5.6)
pygments.rb (~> 0.4.2)
sanitize (~> 2.0.3)
sinatra (~> 1.3.5)
stringex (~> 1.5.1)
useragent (~> 0.4.16)
poltergeist (1.0.2)
capybara (~> 1.1)
childprocess (~> 0.3)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
multi_json (~> 1.0)
GEM
remote: https://rubygems.org/
remote: http://rubygems.org/
specs:
actionmailer (3.2.13)
actionpack (= 3.2.13)
mail (~> 2.5.3)
actionpack (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
actionmailer (3.2.11)
actionpack (= 3.2.11)
mail (~> 2.4.4)
actionpack (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.4)
rack (~> 1.4.5)
rack (~> 1.4.0)
rack-cache (~> 1.2)
rack-test (~> 0.6.1)
sprockets (~> 2.2.1)
activemodel (3.2.13)
activesupport (= 3.2.13)
activemodel (3.2.11)
activesupport (= 3.2.11)
builder (~> 3.0.0)
activerecord (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activerecord (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activesupport (3.2.13)
i18n (= 0.6.1)
activeresource (3.2.11)
activemodel (= 3.2.11)
activesupport (= 3.2.11)
activesupport (3.2.11)
i18n (~> 0.6)
multi_json (~> 1.0)
acts-as-taggable-on (2.3.3)
rails (~> 3.0)
addressable (2.3.2)
arel (3.0.2)
awesome_print (1.1.0)
backports (2.6.7)
backports (2.6.5)
bcrypt-ruby (3.0.1)
better_errors (0.3.2)
coderay (>= 1.0.0)
erubis (>= 2.7.0)
binding_of_caller (0.7.1)
debug_inspector (>= 0.0.1)
binding_of_caller (0.6.8)
blankslate (3.1.2)
bootstrap-sass (2.2.1.1)
sass (~> 3.2)
builder (3.0.4)
capybara (2.0.2)
capybara (1.1.3)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 1.0.0)
carrierwave (0.8.0)
xpath (~> 0.1.4)
carrierwave (0.7.1)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
celluloid (0.12.4)
facter (>= 1.6.12)
timers (>= 1.0.0)
charlock_holmes (0.6.9)
childprocess (0.3.8)
ffi (~> 1.0, >= 1.0.11)
childprocess (0.3.6)
ffi (~> 1.0, >= 1.0.6)
chosen-rails (0.9.8)
railties (~> 3.0)
thor (~> 0.14)
code_analyzer (0.3.1)
sexp_processor
coderay (1.0.9)
coderay (1.0.8)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
@ -116,53 +143,41 @@ GEM
colored (1.2)
colorize (0.5.8)
connection_pool (1.0.0)
coveralls (0.6.2)
colorize
multi_json (~> 1.3)
rest-client
simplecov (>= 0.7)
thor
crack (0.3.2)
crack (0.3.1)
daemons (1.1.9)
database_cleaner (0.9.1)
debug_inspector (0.0.2)
descendants_tracker (0.0.1)
devise (2.2.3)
devise (2.1.2)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
diff-lcs (1.2.1)
draper (1.1.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
request_store (~> 1.0.3)
diff-lcs (1.1.3)
draper (0.18.0)
actionpack (~> 3.2)
activesupport (~> 3.2)
email_spec (1.4.0)
launchy (~> 2.1)
mail (~> 2.2)
enumerize (0.5.1)
activesupport (>= 3.2)
erubis (2.7.0)
escape_utils (0.2.4)
eventmachine (1.0.0)
execjs (1.4.0)
multi_json (~> 1.0)
facter (1.6.18)
facter (1.6.17)
factory_girl (4.1.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.1.0)
factory_girl (~> 4.1.0)
railties (>= 3.0.0)
faraday (0.8.6)
faraday (0.8.4)
multipart-post (~> 1.1)
faye-websocket (0.4.7)
faye-websocket (0.4.6)
eventmachine (>= 0.12.0)
ffaker (1.15.0)
ffi (1.4.0)
ffi (1.1.5)
font-awesome-sass-rails (3.0.0.1)
railties (>= 3.1.1)
sass-rails (>= 3.1.1)
foreman (0.61.0)
foreman (0.60.2)
thor (>= 0.13.6)
gemoji (1.2.1)
gherkin-ruby (0.2.1)
@ -172,62 +187,54 @@ GEM
escape_utils (~> 0.2.3)
mime-types (~> 1.19)
pygments.rb (>= 0.2.13)
github-markdown (0.5.3)
github-markup (0.7.5)
gitlab-grack (1.0.0)
rack (~> 1.4.1)
gitlab-pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
gitlab_meta (5.0)
github-markup (0.7.4)
gitlab_meta (4.0)
gitlab_omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
omniauth (~> 1.0)
pyu-ruby-sasl (~> 0.0.3.1)
rubyntlm (~> 0.1.1)
gitlab_yaml_db (1.0.0)
gon (4.0.2)
grape (0.3.2)
gitolite (1.1.0)
gratr19 (~> 0.4.4.1)
grit (~> 2.5.0)
hashery (~> 1.5.0)
grape (0.2.2)
activesupport
builder
hashie (>= 1.2.0)
hashie (~> 1.2)
multi_json (>= 1.3.2)
multi_xml (>= 0.5.2)
multi_xml
rack
rack-accept
rack-mount
virtus
grape-entity (0.2.0)
activesupport
multi_json (>= 1.3.2)
grit_ext (0.8.1)
charlock_holmes (~> 0.6.9)
gratr19 (0.4.4.1)
growl (1.0.3)
guard (1.6.2)
listen (>= 0.6.0)
guard (1.5.4)
listen (>= 0.4.2)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
terminal-table (>= 1.4.3)
thor (>= 0.14.6)
guard-rspec (2.5.1)
guard-rspec (2.1.2)
guard (>= 1.1)
rspec (~> 2.11)
guard-spinach (0.0.2)
guard (>= 1.1)
spinach
haml (4.0.0)
tilt
haml-rails (0.4)
haml (3.1.7)
haml-rails (0.3.5)
actionpack (>= 3.1, < 4.1)
activesupport (>= 3.1, < 4.1)
haml (>= 3.1, < 4.1)
haml (~> 3.1)
railties (>= 3.1, < 4.1)
hashery (1.5.0)
blankslate
hashie (1.2.0)
hike (1.2.1)
http_parser.rb (0.5.3)
httparty (0.10.2)
httparty (0.9.0)
multi_json (~> 1.0)
multi_xml (>= 0.5.2)
multi_xml
httpauth (0.2.0)
i18n (0.6.1)
journey (1.0.4)
@ -238,46 +245,47 @@ GEM
jquery-ui-rails (2.0.2)
jquery-rails
railties (>= 3.1.0)
json (1.7.7)
json (1.7.6)
jwt (0.1.5)
multi_json (>= 1.0)
kaminari (0.14.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.8.0)
kgio (2.7.4)
launchy (2.1.2)
addressable (~> 2.3)
letter_opener (1.0.0)
launchy (>= 2.0.4)
libv8 (3.11.8.17)
listen (0.7.3)
lumberjack (1.0.3)
mail (2.5.3)
libv8 (3.3.10.4)
libwebsocket (0.1.6)
websocket
listen (0.5.3)
lumberjack (1.0.2)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.8.1)
mime-types (1.21)
mime-types (1.19)
modernizr (2.6.2)
sprockets (~> 2.0)
multi_json (1.7.2)
multi_xml (0.5.3)
multi_json (1.5.0)
multi_xml (0.5.1)
multipart-post (1.1.5)
mustache (0.99.4)
mysql2 (0.3.11)
net-ldap (0.2.2)
nokogiri (1.5.6)
nokogiri (1.5.5)
oauth (0.4.7)
oauth2 (0.8.1)
oauth2 (0.8.0)
faraday (~> 0.8)
httpauth (~> 0.1)
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
omniauth (1.1.3)
omniauth (1.1.1)
hashie (~> 1.2)
rack
omniauth-github (1.1.0)
omniauth-github (1.0.3)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
omniauth-google-oauth2 (0.1.13)
@ -294,23 +302,17 @@ GEM
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
pg (0.14.1)
poltergeist (1.1.0)
capybara (~> 2.0, >= 2.0.1)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
polyglot (0.3.3)
posix-spawn (0.3.6)
pry (0.9.12)
progressbar (0.12.0)
pry (0.9.10)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
pygments.rb (0.4.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
slop (~> 3.3.1)
pyu-ruby-sasl (0.0.3.3)
quiet_assets (1.0.1)
railties (~> 3.1)
rack (1.4.5)
rack (1.4.3)
rack-accept (0.4.5)
rack (>= 0.4)
rack-cache (1.2)
@ -319,91 +321,68 @@ GEM
rack (>= 1.1.3)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-protection (1.4.0)
rack-protection (1.3.2)
rack
rack-ssl (1.3.3)
rack-ssl (1.3.2)
rack
rack-test (0.6.2)
rack (>= 1.0)
rails (3.2.13)
actionmailer (= 3.2.13)
actionpack (= 3.2.13)
activerecord (= 3.2.13)
activeresource (= 3.2.13)
activesupport (= 3.2.13)
rails (3.2.11)
actionmailer (= 3.2.11)
actionpack (= 3.2.11)
activerecord (= 3.2.11)
activeresource (= 3.2.11)
activesupport (= 3.2.11)
bundler (~> 1.0)
railties (= 3.2.13)
railties (= 3.2.11)
rails-dev-tweaks (0.6.1)
actionpack (~> 3.1)
railties (~> 3.1)
rails_best_practices (1.13.4)
rails_best_practices (1.13.2)
activesupport
awesome_print
code_analyzer
colored
erubis
i18n
ruby-progressbar
railties (3.2.13)
actionpack (= 3.2.13)
activesupport (= 3.2.13)
progressbar
railties (3.2.11)
actionpack (= 3.2.11)
activesupport (= 3.2.11)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
raindrops (0.10.0)
rake (10.0.4)
rake (10.0.3)
rb-fsevent (0.9.2)
rb-inotify (0.8.8)
ffi (>= 0.5.0)
rdoc (3.12.2)
rdoc (3.12)
json (~> 1.4)
redcarpet (2.2.2)
redis (3.0.3)
redis-actionpack (3.2.3)
actionpack (~> 3.2.3)
redis-rack (~> 1.4.0)
redis-store (~> 1.1.0)
redis-activesupport (3.2.3)
activesupport (~> 3.2.3)
redis-store (~> 1.1.0)
redis (3.0.2)
redis-namespace (1.2.1)
redis (~> 3.0.0)
redis-rack (1.4.2)
rack (~> 1.4.1)
redis-store (~> 1.1.0)
redis-rails (3.2.3)
redis-actionpack (~> 3.2.3)
redis-activesupport (~> 3.2.3)
redis-store (~> 1.1.0)
redis-store (1.1.3)
redis (>= 2.2.0)
ref (1.0.4)
request_store (1.0.5)
rest-client (1.6.7)
mime-types (>= 1.16)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.0)
rspec-rails (2.13.0)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rspec-core (2.12.0)
rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.0)
rspec-rails (2.12.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
ruby-progressbar (1.0.2)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
rspec-mocks (~> 2.12.0)
rubyntlm (0.1.1)
rubyzip (0.9.9)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
sass (3.2.7)
sass-rails (3.2.6)
sass (3.2.5)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
@ -413,19 +392,16 @@ GEM
seed-fu (2.2.0)
activerecord (~> 3.1)
activesupport (~> 3.1)
select2-rails (3.3.1)
sass-rails (>= 3.2)
thor (~> 0.14)
selenium-webdriver (2.30.0)
selenium-webdriver (2.26.0)
childprocess (>= 0.2.5)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0)
rubyzip
websocket (~> 1.0.4)
settingslogic (2.0.9)
sexp_processor (4.2.0)
settingslogic (2.0.8)
sexp_processor (4.1.3)
shoulda-matchers (1.3.0)
activesupport (>= 3.0.0)
sidekiq (2.8.0)
sidekiq (2.6.4)
celluloid (~> 0.12.0)
connection_pool (~> 1.0)
multi_json (~> 1)
@ -435,66 +411,59 @@ GEM
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
simplecov-html (0.7.1)
sinatra (1.3.5)
rack (~> 1.4)
rack-protection (~> 1.3)
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
slim (1.3.6)
temple (~> 0.5.5)
tilt (~> 1.3.3)
slop (3.4.4)
spinach (0.7.0)
slop (3.3.3)
spinach (0.5.2)
colorize
gherkin-ruby (~> 0.2.0)
spinach-rails (0.2.0)
capybara (~> 2.0.0)
spinach-rails (0.1.8)
capybara (~> 1)
railties (>= 3)
spinach (>= 0.4)
spork (1.0.0rc3)
sprockets (2.2.2)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
stamp (0.5.0)
state_machine (1.1.2)
stringex (1.5.1)
stamp (0.3.0)
temple (0.5.5)
terminal-table (1.4.5)
test_after_commit (0.0.1)
therubyracer (0.11.4)
libv8 (~> 3.11.8.12)
ref
therubyracer (0.10.2)
libv8 (~> 3.3.10)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.18.0)
tilt (1.3.6)
timers (1.1.0)
thor (0.16.0)
tilt (1.3.3)
timers (1.0.2)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.37)
tzinfo (0.3.35)
uglifier (1.3.0)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
unicorn (4.6.2)
unicorn (4.4.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
useragent (0.4.16)
virtus (0.5.4)
virtus (0.5.2)
backports (~> 2.6.1)
descendants_tracker (~> 0.0.1)
warden (1.2.1)
rack (>= 1.0)
webmock (1.9.0)
addressable (>= 2.2.7)
crack (>= 0.1.7)
websocket (1.0.7)
xpath (1.0.0)
websocket (1.0.2)
xpath (0.1.4)
nokogiri (~> 1.3)
yajl-ruby (1.1.0)
@ -509,16 +478,14 @@ DEPENDENCIES
binding_of_caller
bootstrap-sass (= 2.2.1.1)
capybara
carrierwave
carrierwave (~> 0.7.1)
chosen-rails (= 0.9.8)
coffee-rails (~> 3.2.2)
colored
coveralls
database_cleaner
devise
draper
database_cleaner!
devise (~> 2.1.0)
draper (~> 0.18.0)
email_spec
enumerize
factory_girl_rails
ffaker
font-awesome-sass-rails (~> 3.0.0)
@ -527,21 +494,18 @@ DEPENDENCIES
git
github-linguist (~> 2.3.4)
github-markup (~> 0.7.4)
gitlab-grack (~> 1.0.0)
gitlab-pygments.rb (~> 0.3.2)
gitlab_meta (= 5.0)
gitlab_meta (= 4.0)
gitlab_omniauth-ldap (= 1.0.2)
gitlab_yaml_db (= 1.0.0)
gollum (~> 2.4.0)!
gon
grape (~> 0.3.1)
grape-entity (~> 0.2.0)
grit (~> 2.5.0)!
grit_ext (~> 0.8.1)
gitolite (= 1.1.0)
grack!
grape (~> 0.2.1)
grit!
grit_ext!
growl
guard-rspec
guard-spinach
haml-rails
haml-rails (~> 0.3.5)
httparty
jquery-atwho-rails (= 0.1.7)
jquery-rails (= 2.1.3)
@ -551,42 +515,39 @@ DEPENDENCIES
letter_opener
modernizr (= 2.6.2)
mysql2
omniauth (~> 1.1.3)
omniauth (~> 1.1.1)
omniauth-github
omniauth-google-oauth2
omniauth-twitter
pg
poltergeist (= 1.1.0)
poltergeist!
pry
pygments.rb!
quiet_assets (~> 1.0.1)
rack-mini-profiler
rails (= 3.2.13)
rails (= 3.2.11)
rails-dev-tweaks
rails_best_practices
raphael-rails!
rb-fsevent
rb-inotify
redcarpet (~> 2.2.2)
redis-rails
rspec-rails
sass-rails (~> 3.2.5)
sdoc
seed-fu
select2-rails
settingslogic
shoulda-matchers (= 1.3.0)
sidekiq
sidekiq (= 2.6.4)
simplecov
sinatra
six
slim
spinach-rails
spork (~> 1.0rc)
stamp
state_machine
test_after_commit
therubyracer
thin
uglifier (~> 1.3.0)
unicorn
unicorn (~> 4.4.0)
webmock

View File

@ -1,2 +1,2 @@
web: bundle exec unicorn_rails -p $PORT
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitolite

166
README.md
View File

@ -1,161 +1,45 @@
## GitLab: self hosted Git management software
# Welcome to GitLab [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) [![build status](https://secure.travis-ci.org/gitlabhq/grit.png)](https://travis-ci.org/gitlabhq/grit) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png)
GitLab is a free project and repository management application
### GitLab allows you to
* keep your code secure on your own server
* manage repositories, users and access permissions
* communicate through issues, line-comments and wiki pages
* perform code review with merge requests
[![CI](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master)
### GitLab is
## Application details
* powered by Ruby on Rails
* completely free and open source (MIT license)
* used by more than 10.000 organizations to keep their code secure
* based on Ruby on Rails
* distributed under the MIT License
* works with gitolite
### Code status
## Requirements
* [![build status](http://ci.gitlab.org/projects/1/status?ref=master)](http://ci.gitlab.org/projects/1?ref=master) ci.gitlab.org (master branch)
* [![build status](https://secure.travis-ci.org/gitlabhq/gitlabhq.png)](https://travis-ci.org/gitlabhq/gitlabhq) travis-ci.org (master branch)
* [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq)
* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq)
* [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq)
### Resources
* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) [Subscription](http://www.gitlab.com/subscription/) [Consultancy](http://www.gitlab.com/consultancy/) [GitLab Cloud](http://www.gitlab.com/cloud/) [Blog](http://blog.gitlab.com/)
* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
### Requirements
* Ubuntu/Debian**
* ruby 1.9.3
* Ubuntu/Debian
* ruby 1.9.3+
* MySQL
* git
* gitlab-shell
* gitolite
* redis
** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
## Install
### Installation
Checkout wiki pages for installation information, migration, etc.
#### Official production installation
## Community
Follow the installation guide for production server.
[Google Group](https://groups.google.com/group/gitlabhq)
* [Installation guide for latest stable release (5.0)](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) - **Recommended**
## Contacts
* [Installation guide for the current master branch (5.1)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
Twitter:
* @gitlabhq
* @dzaporozhets
#### Official development installation
Email
If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working with all dependencies.
* m@gitlabhq.com
* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
## Contribute
#### Unsupported production installation
* [GitLab recipes](https://github.com/gitlabhq/gitlab-recipes) for setup on different platforms
* [Unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides)
* [BitNami one-click installers](http://bitnami.com/stack/gitlab)
* [TurnKey Linux virtual appliance](http://www.turnkeylinux.org/gitlab)
### New versions and upgrading
Each month on the 22th a new version is released together with an upgrade guide.
* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
* [Changelog](https://github.com/gitlabhq/gitlabhq/blob/master/CHANGELOG)
* [Roadmap](https://github.com/gitlabhq/gitlabhq/blob/master/ROADMAP.md)
### Getting started
1. The Installation guide contains instructions to download an init script and run that on boot. With the init script you can also start GitLab
sudo service gitlab start
or
sudo /etc/init.d/gitlab restart
2. Start it with [Foreman](https://github.com/ddollar/foreman) in development mode
bundle exec foreman start -p 3000
or start it manually
bundle exec rails s
bundle exec rake sidekiq:start
### Running the tests
* Seed the database
bundle exec rake db:setup RAILS_ENV=test
bundle exec rake db:seed_fu RAILS_ENV=test
* Run all tests
bundle exec rake gitlab:test
* Rspec unit and functional tests
bundle exec rake spec
* Spinach integration tests
bundle exec rake spinach
### GitLab interfaces
* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
* [Directory structure](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/structure.md)
* [Databases](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/databases.md)
### Getting help
* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems.
* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq) is the best place to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and had it resolved. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general) is the place to propose and discuss new features for GitLab.
* [Support subscription](http://www.gitlab.com/subscription/) connect you to the knowledge of GitLab experts that will resolve your issues and answer your questions.
* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab exports for installations, upgrades and customizations.
* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed without comment.
### Getting in touch
* [Core team](https://github.com/gitlabhq?tab=members)
* [Contributors](https://github.com/gitlabhq/gitlabhq/graphs/contributors)
* [Leader](https://github.com/randx)
* [Contact page](http://gitlab.org/contact/)
[Developer Guide](https://github.com/gitlabhq/gitlabhq/wiki/Developer-Guide)
Want to help - send a pull request.
We'll accept good pull requests.

View File

@ -1,5 +1,12 @@
## GitLab Roadmap
### v5.1 April 22
### v5.0 March 22
* Replace gitolite with gitlab-shell
* Usability improvements
* Notification improvements
### v4.2 February 22
* Teams
* Not decided yet.

View File

@ -1 +1 @@
5.1.0pre
4.2.0

92
app/assets/fonts/OFL.txt Normal file
View File

@ -0,0 +1,92 @@
Copyright (c) 2010, Jan Gerner (post@yanone.de)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,53 +0,0 @@
@Api =
users_path: "/api/:version/users.json"
user_path: "/api/:version/users/:id.json"
notes_path: "/api/:version/projects/:id/notes.json"
# Get 20 (depends on api) recent notes
# and sort the ascending from oldest to newest
notes: (project_id, callback) ->
url = Api.buildUrl(Api.notes_path)
url = url.replace(':id', project_id)
$.ajax(
url: url,
data:
private_token: gon.api_token
gfm: true
recent: true
dataType: "json"
).done (notes) ->
notes.sort (a, b) ->
return a.id - b.id
callback(notes)
user: (user_id, callback) ->
url = Api.buildUrl(Api.user_path)
url = url.replace(':id', user_id)
$.ajax(
url: url
data:
private_token: gon.api_token
dataType: "json"
).done (user) ->
callback(user)
# Return users list. Filtered by query
# Only active users retrieved
users: (query, callback) ->
url = Api.buildUrl(Api.users_path)
$.ajax(
url: url
data:
private_token: gon.api_token
search: query
per_page: 20
active: true
dataType: "json"
).done (users) ->
callback(users)
buildUrl: (url) ->
return url.replace(':version', gon.api_version)

View File

@ -17,7 +17,6 @@
//= require bootstrap
//= require modernizr
//= require chosen-jquery
//= require select2
//= require raphael
//= require g.raphael-min
//= require g.bar-min

View File

@ -3,11 +3,3 @@ $ ->
container = $(@).closest(".js-toggler-container")
container.toggleClass("on")
$("body").on "click", ".js-toggle-visibility-link", (e) ->
$(@).find('i').
toggleClass('icon-chevron-down').
toggleClass('icon-chevron-up')
container = $(".js-toggle-visibility-container")
container.toggleClass("hide")
e.preventDefault()

View File

@ -1,309 +0,0 @@
class BranchGraph
constructor: (@element, @options) ->
@preparedCommits = {}
@mtime = 0
@mspace = 0
@parents = {}
@colors = ["#000"]
@offsetX = 120
@offsetY = 20
@unitTime = 30
@unitSpace = 10
@load()
load: ->
$.ajax
url: @options.url
method: "get"
dataType: "json"
success: $.proxy((data) ->
$(".loading", @element).hide()
@prepareData data.days, data.commits
@buildGraph()
, this)
prepareData: (@days, @commits) ->
@collectParents()
for c in @commits
c.isParent = true if c.id of @parents
@preparedCommits[c.id] = c
@collectColors()
collectParents: ->
for c in @commits
@mtime = Math.max(@mtime, c.time)
@mspace = Math.max(@mspace, c.space)
for p in c.parents
@parents[p[0]] = true
@mspace = Math.max(@mspace, p[1])
collectColors: ->
k = 0
while k < @mspace
@colors.push Raphael.getColor(.8)
# Skipping a few colors in the spectrum to get more contrast between colors
Raphael.getColor()
Raphael.getColor()
k++
buildGraph: ->
graphHeight = $(@element).height()
graphWidth = $(@element).width()
ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
@r = r = Raphael(@element.get(0), cw, ch)
top = r.set()
cuday = 0
cumonth = ""
barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
r.rect(0, 0, 26, barHeight).attr fill: "#222"
r.rect(26, 0, 20, barHeight).attr fill: "#444"
for day, mm in @days
if cuday isnt day[0]
# Dates
r.text(36, @offsetY + @unitTime * mm, day[0])
.attr(
font: "12px Monaco, monospace"
fill: "#DDD"
)
cuday = day[0]
if cumonth isnt day[1]
# Months
r.text(13, @offsetY + @unitTime * mm, day[1])
.attr(
font: "12px Monaco, monospace"
fill: "#EEE"
)
cumonth = day[1]
for commit in @commits
x = @offsetX + @unitSpace * (@mspace - commit.space)
y = @offsetY + @unitTime * commit.time
@drawDot(x, y, commit)
@drawLines(x, y, commit)
@appendLabel(x, y, commit.refs) if commit.refs
@appendAnchor(top, commit, x, y)
@markCommit(x, y, commit, graphHeight)
top.toFront()
@bindEvents()
bindEvents: ->
drag = {}
element = @element
dragger = (event) ->
element.scrollLeft drag.sl - (event.clientX - drag.x)
element.scrollTop drag.st - (event.clientY - drag.y)
element.on mousedown: (event) ->
drag =
x: event.clientX
y: event.clientY
st: element.scrollTop()
sl: element.scrollLeft()
$(window).on "mousemove", dragger
$(window).on
mouseup: ->
$(window).off "mousemove", dragger
keydown: (event) ->
# left
element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37
# top
element.scrollTop element.scrollTop() - 50 if event.keyCode is 38
# right
element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39
# bottom
element.scrollTop element.scrollTop() + 50 if event.keyCode is 40
appendLabel: (x, y, refs) ->
r = @r
shortrefs = refs
# Truncate if longer than 15 chars
shortrefs = shortrefs.substr(0, 15) + "" if shortrefs.length > 17
text = r.text(x + 4, y, shortrefs).attr(
"text-anchor": "start"
font: "10px Monaco, monospace"
fill: "#FFF"
title: refs
)
textbox = text.getBBox()
# Create rectangle based on the size of the textbox
rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
label = r.set(rect, text)
label.transform(["t", -rect.getBBox().width - 15, 0])
# Set text to front
text.toFront()
appendAnchor: (top, commit, x, y) ->
r = @r
options = @options
anchor = r.circle(x, y, 10).attr(
fill: "#000"
opacity: 0
cursor: "pointer"
).click(->
window.open options.commit_url.replace("%s", commit.id), "_blank"
).hover(->
@tooltip = r.commitTooltip(x + 5, y, commit)
top.push @tooltip.insertBefore(this)
, ->
@tooltip and @tooltip.remove() and delete @tooltip
)
top.push anchor
drawDot: (x, y, commit) ->
r = @r
r.circle(x, y, 3).attr(
fill: @colors[commit.space]
stroke: "none"
)
r.rect(@offsetX + @unitSpace * @mspace + 10, y - 10, 20, 20).attr(
fill: "url(#{commit.author.icon})"
stroke: @colors[commit.space]
"stroke-width": 2
)
r.text(@offsetX + @unitSpace * @mspace + 35, y, commit.message.split("\n")[0]).attr(
"text-anchor": "start"
font: "14px Monaco, monospace"
)
drawLines: (x, y, commit) ->
r = @r
for parent, i in commit.parents
parentCommit = @preparedCommits[parent[0]]
parentY = @offsetY + @unitTime * parentCommit.time
parentX1 = @offsetX + @unitSpace * (@mspace - parentCommit.space)
parentX2 = @offsetX + @unitSpace * (@mspace - parent[1])
# Set line color
if parentCommit.space <= commit.space
color = @colors[commit.space]
else
color = @colors[parentCommit.space]
# Build line shape
if parent[1] is commit.space
offset = [0, 5]
arrow = "l-2,5,4,0,-2,-5,0,5"
else if parent[1] < commit.space
offset = [3, 3]
arrow = "l5,0,-2,4,-3,-4,4,2"
else
offset = [-3, 3]
arrow = "l-5,0,2,4,3,-4,-4,2"
# Start point
route = ["M", x + offset[0], y + offset[1]]
# Add arrow if not first parent
if i > 0
route.push(arrow)
# Circumvent if overlap
if commit.space isnt parentCommit.space or commit.space isnt parent[1]
route.push(
"L", parentX2, y + 10,
"L", parentX2, parentY - 5,
)
# End point
route.push("L", parentX1, parentY)
r
.path(route)
.attr(
stroke: color
"stroke-width": 2)
markCommit: (x, y, commit, graphHeight) ->
if commit.id is @options.commit_id
r = @r
r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
# Displayed in the center
@element.scrollTop(y - graphHeight / 2)
Raphael::commitTooltip = (x, y, commit) ->
boxWidth = 300
boxHeight = 200
icon = @image(commit.author.icon, x, y, 20, 20)
nameText = @text(x + 25, y + 10, commit.author.name)
idText = @text(x, y + 35, commit.id)
messageText = @text(x, y + 50, commit.message)
textSet = @set(icon, nameText, idText, messageText).attr(
"text-anchor": "start"
font: "12px Monaco, monospace"
)
nameText.attr(
font: "14px Arial"
"font-weight": "bold"
)
idText.attr fill: "#AAA"
@textWrap messageText, boxWidth - 50
rect = @rect(x - 10, y - 10, boxWidth, 100, 4).attr(
fill: "#FFF"
stroke: "#000"
"stroke-linecap": "round"
"stroke-width": 2
)
tooltip = @set(rect, textSet)
rect.attr(
height: tooltip.getBBox().height + 10
width: tooltip.getBBox().width + 10
)
tooltip.transform ["t", 20, 20]
tooltip
Raphael::textWrap = (t, width) ->
content = t.attr("text")
abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
t.attr text: abc
letterWidth = t.getBBox().width / abc.length
t.attr text: content
words = content.split(" ")
x = 0
s = []
for word in words
if x + (word.length * letterWidth) > width
s.push "\n"
x = 0
x += word.length * letterWidth
s.push word + " "
t.attr text: s.join("")
b = t.getBBox()
h = Math.abs(b.y2) - Math.abs(b.y) + 1
t.attr y: b.y + h
@BranchGraph = BranchGraph

View File

@ -1,6 +1,5 @@
window.dashboardPage = ->
Pager.init 20, true
initSidebarTab()
$(".event_filter_link").bind "click", (event) ->
event.preventDefault()
toggleFilter $(this)
@ -26,14 +25,3 @@ toggleFilter = (sender) ->
event_filters.splice index, 1
$.cookie "event_filter", event_filters.join(",")
initSidebarTab = ->
key = "dashboard_sidebar_filter"
# store selection in cookie
$('.dash-sidebar-tabs a').on 'click', (e) ->
$.cookie(key, $(e.target).attr('id'))
# show tab from cookie
sidebar_filter = $.cookie(key)
$("#" + sidebar_filter).tab('show') if sidebar_filter

View File

@ -1,9 +0,0 @@
$.fn.showAndHide = ->
$(@).show().
delay(3000).
fadeOut()
$.fn.enableButton = ->
$(@).removeAttr('disabled').
removeClass('disabled')

View File

@ -1,181 +0,0 @@
/**
* Timeago is a jQuery plugin that makes it easy to support automatically
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
*
* @name timeago
* @version 1.1.0
* @requires jQuery v1.2.3+
* @author Ryan McGeary
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
*
* For usage and examples, visit:
* http://timeago.yarp.com/
*
* Copyright (c) 2008-2013, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
$.timeago = function(timestamp) {
if (timestamp instanceof Date) {
return inWords(timestamp);
} else if (typeof timestamp === "string") {
return inWords($.timeago.parse(timestamp));
} else if (typeof timestamp === "number") {
return inWords(new Date(timestamp));
} else {
return inWords($.timeago.datetime(timestamp));
}
};
var $t = $.timeago;
$.extend($.timeago, {
settings: {
refreshMillis: 60000,
allowFuture: false,
strings: {
prefixAgo: null,
prefixFromNow: null,
suffixAgo: "ago",
suffixFromNow: "from now",
seconds: "less than a minute",
minute: "about a minute",
minutes: "%d minutes",
hour: "about an hour",
hours: "about %d hours",
day: "a day",
days: "%d days",
month: "about a month",
months: "%d months",
year: "about a year",
years: "%d years",
wordSeparator: " ",
numbers: []
}
},
inWords: function(distanceMillis) {
var $l = this.settings.strings;
var prefix = $l.prefixAgo;
var suffix = $l.suffixAgo;
if (this.settings.allowFuture) {
if (distanceMillis < 0) {
prefix = $l.prefixFromNow;
suffix = $l.suffixFromNow;
}
}
var seconds = Math.abs(distanceMillis) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
var years = days / 365;
function substitute(stringOrFunction, number) {
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
var value = ($l.numbers && $l.numbers[number]) || number;
return string.replace(/%d/i, value);
}
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
seconds < 90 && substitute($l.minute, 1) ||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
minutes < 90 && substitute($l.hour, 1) ||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
hours < 42 && substitute($l.day, 1) ||
days < 30 && substitute($l.days, Math.round(days)) ||
days < 45 && substitute($l.month, 1) ||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
years < 1.5 && substitute($l.year, 1) ||
substitute($l.years, Math.round(years));
var separator = $l.wordSeparator || "";
if ($l.wordSeparator === undefined) { separator = " "; }
return $.trim([prefix, words, suffix].join(separator));
},
parse: function(iso8601) {
var s = $.trim(iso8601);
s = s.replace(/\.\d+/,""); // remove milliseconds
s = s.replace(/-/,"/").replace(/-/,"/");
s = s.replace(/T/," ").replace(/Z/," UTC");
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
return new Date(s);
},
datetime: function(elem) {
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
return $t.parse(iso8601);
},
isTime: function(elem) {
// jQuery's `is()` doesn't play well with HTML5 in IE
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
}
});
// functions that can be called via $(el).timeago('action')
// init is default when no action is given
// functions are called with context of a single element
var functions = {
init: function(){
var refresh_el = $.proxy(refresh, this);
refresh_el();
var $s = $t.settings;
if ($s.refreshMillis > 0) {
setInterval(refresh_el, $s.refreshMillis);
}
},
update: function(time){
$(this).data('timeago', { datetime: $t.parse(time) });
refresh.apply(this);
}
};
$.fn.timeago = function(action, options) {
var fn = action ? functions[action] : functions.init;
if(!fn){
throw new Error("Unknown function name '"+ action +"' for timeago");
}
// each over objects here and call the requested function
this.each(function(){
fn.call(this, options);
});
return this;
};
function refresh() {
var data = prepareData(this);
if (!isNaN(data.datetime)) {
$(this).text(inWords(data.datetime));
}
return this;
}
function prepareData(element) {
element = $(element);
if (!element.data("timeago")) {
element.data("timeago", { datetime: $t.datetime(element) });
var text = $.trim(element.text());
if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
element.attr("title", text);
}
}
return element.data("timeago");
}
function inWords(date) {
return $t.inWords(distance(date));
}
function distance(date) {
return (new Date().getTime() - date.getTime());
}
// fix for IE6 suckage
document.createElement("abbr");
document.createElement("time");
}));

View File

@ -1,211 +0,0 @@
function md5 (str) {
// http://kevin.vanzonneveld.net
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
// + namespaced by: Michael White (http://getsprink.com)
// + tweaked by: Jack
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// - depends on: utf8_encode
// * example 1: md5('Kevin van Zonneveld');
// * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
var xl;
var rotateLeft = function (lValue, iShiftBits) {
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
};
var addUnsigned = function (lX, lY) {
var lX4, lY4, lX8, lY8, lResult;
lX8 = (lX & 0x80000000);
lY8 = (lY & 0x80000000);
lX4 = (lX & 0x40000000);
lY4 = (lY & 0x40000000);
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
if (lX4 & lY4) {
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
}
if (lX4 | lY4) {
if (lResult & 0x40000000) {
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
} else {
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
}
} else {
return (lResult ^ lX8 ^ lY8);
}
};
var _F = function (x, y, z) {
return (x & y) | ((~x) & z);
};
var _G = function (x, y, z) {
return (x & z) | (y & (~z));
};
var _H = function (x, y, z) {
return (x ^ y ^ z);
};
var _I = function (x, y, z) {
return (y ^ (x | (~z)));
};
var _FF = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _GG = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _HH = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var _II = function (a, b, c, d, x, s, ac) {
a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
return addUnsigned(rotateLeft(a, s), b);
};
var convertToWordArray = function (str) {
var lWordCount;
var lMessageLength = str.length;
var lNumberOfWords_temp1 = lMessageLength + 8;
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
var lWordArray = new Array(lNumberOfWords - 1);
var lBytePosition = 0;
var lByteCount = 0;
while (lByteCount < lMessageLength) {
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
lByteCount++;
}
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
lBytePosition = (lByteCount % 4) * 8;
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
return lWordArray;
};
var wordToHex = function (lValue) {
var wordToHexValue = "",
wordToHexValue_temp = "",
lByte, lCount;
for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255;
wordToHexValue_temp = "0" + lByte.toString(16);
wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
}
return wordToHexValue;
};
var x = [],
k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
S12 = 12,
S13 = 17,
S14 = 22,
S21 = 5,
S22 = 9,
S23 = 14,
S24 = 20,
S31 = 4,
S32 = 11,
S33 = 16,
S34 = 23,
S41 = 6,
S42 = 10,
S43 = 15,
S44 = 21;
str = this.utf8_encode(str);
x = convertToWordArray(str);
a = 0x67452301;
b = 0xEFCDAB89;
c = 0x98BADCFE;
d = 0x10325476;
xl = x.length;
for (k = 0; k < xl; k += 16) {
AA = a;
BB = b;
CC = c;
DD = d;
a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
a = addUnsigned(a, AA);
b = addUnsigned(b, BB);
c = addUnsigned(c, CC);
d = addUnsigned(d, DD);
}
var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
return temp.toLowerCase();
}

View File

@ -1,70 +0,0 @@
function utf8_encode (argString) {
// http://kevin.vanzonneveld.net
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: sowberry
// + tweaked by: Jack
// + bugfixed by: Onno Marsman
// + improved by: Yves Sucaet
// + bugfixed by: Onno Marsman
// + bugfixed by: Ulrich
// + bugfixed by: Rafal Kukawski
// + improved by: kirilloid
// + bugfixed by: kirilloid
// * example 1: utf8_encode('Kevin van Zonneveld');
// * returns 1: 'Kevin van Zonneveld'
if (argString === null || typeof argString === "undefined") {
return "";
}
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
var utftext = '',
start, end, stringl = 0;
start = end = 0;
stringl = string.length;
for (var n = 0; n < stringl; n++) {
var c1 = string.charCodeAt(n);
var enc = null;
if (c1 < 128) {
end++;
} else if (c1 > 127 && c1 < 2048) {
enc = String.fromCharCode(
(c1 >> 6) | 192,
( c1 & 63) | 128
);
} else if (c1 & 0xF800 != 0xD800) {
enc = String.fromCharCode(
(c1 >> 12) | 224,
((c1 >> 6) & 63) | 128,
( c1 & 63) | 128
);
} else { // surrogate pairs
if (c1 & 0xFC00 != 0xD800) { throw new RangeError("Unmatched trail surrogate at " + n); }
var c2 = string.charCodeAt(++n);
if (c2 & 0xFC00 != 0xDC00) { throw new RangeError("Unmatched lead surrogate at " + (n-1)); }
c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
enc = String.fromCharCode(
(c1 >> 18) | 240,
((c1 >> 12) & 63) | 128,
((c1 >> 6) & 63) | 128,
( c1 & 63) | 128
);
}
if (enc !== null) {
if (end > start) {
utftext += string.slice(start, end);
}
utftext += enc;
start = end = n + 1;
}
}
if (end > start) {
utftext += string.slice(start, stringl);
}
return utftext;
}

View File

@ -7,8 +7,6 @@ window.slugify = (text) ->
window.ajaxGet = (url) ->
$.ajax({type: "GET", url: url, dataType: "script"})
window.showAndHide = (selector) ->
window.errorMessage = (message) ->
ehtml = $("<p>")
ehtml.addClass("error_message")
@ -34,22 +32,10 @@ window.disableButtonIfEmptyField = (field_selector, button_selector) ->
else
closest_submit.enable()
window.sanitize = (str) ->
return str.replace(/<(?:.|\n)*?>/gm, '')
window.linkify = (str) ->
exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
return str.replace(exp,"<a href='$1'>$1</a>")
$ ->
# Click a .one_click_select field, select the contents
$(".one_click_select").on 'click', -> $(@).select()
# Click a .appear-link, appear-data fadeout
$(".appear-link").on 'click', ->
$('.appear-data').fadeIn()
# Initialize chosen selects
$('select.chosen').chosen()
@ -59,17 +45,11 @@ $ ->
# Bottom tooltip
$('.has_bottom_tooltip').tooltip(placement: 'bottom')
# Form submitter
$('.trigger-submit').on 'change', ->
$(@).parents('form').submit()
$("abbr.timeago").timeago()
# Flash
if (flash = $(".flash-container")).length > 0
flash.click -> $(@).fadeOut()
flash.show()
setTimeout (-> flash.fadeOut()), 3000
if (flash = $("#flash-container")).length > 0
flash.click -> $(@).slideUp("slow")
flash.slideDown "slow"
setTimeout (-> flash.slideUp("slow")), 3000
# Disable form buttons while a form is submitting
$('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) ->

View File

@ -27,11 +27,11 @@ class MergeRequest
this.$el.find(selector)
initMergeWidget: ->
this.showState( @opts.current_status )
this.showState( @opts.current_state )
if this.$('.automerge_widget').length and @opts.check_enable
$.get @opts.url_to_automerge_check, (data) =>
this.showState( data.merge_status )
this.showState( data.state )
, 'json'
if @opts.ci_enable

View File

@ -4,15 +4,31 @@ var NoteList = {
target_params: null,
target_id: 0,
target_type: null,
top_id: 0,
bottom_id: 0,
loading_more_disabled: false,
reversed: false,
init: function(tid, tt, path) {
NoteList.notes_path = path + ".js";
NoteList.target_id = tid;
NoteList.target_type = tt;
NoteList.reversed = $("#notes-list").is(".reversed");
NoteList.target_params = "target_type=" + NoteList.target_type + "&target_id=" + NoteList.target_id;
NoteList.setupMainTargetNoteForm();
if(NoteList.reversed) {
var form = $(".js-main-target-form");
form.find(".note-form-actions").hide();
var textarea = form.find(".js-note-text");
textarea.css("height", "40px");
textarea.on("focus", function(){
textarea.css("height", "80px");
form.find(".note-form-actions").show();
});
}
// get initial set of notes
NoteList.getContent();
@ -311,7 +327,7 @@ var NoteList = {
/**
* Gets an initial set of notes.
* Gets an inital set of notes.
*/
getContent: function() {
$.ajax({
@ -328,10 +344,127 @@ var NoteList = {
* Replaces the content of #notes-list with the given html.
*/
setContent: function(newNoteIds, html) {
NoteList.top_id = newNoteIds.first();
NoteList.bottom_id = newNoteIds.last();
$("#notes-list").html(html);
// for the wall
if (NoteList.reversed) {
// init infinite scrolling
NoteList.initLoadMore();
// init getting new notes
NoteList.initRefreshNew();
}
},
/**
* Handle loading more notes when scrolling to the bottom of the page.
* The id of the last note in the list is in NoteList.bottom_id.
*
* Set up refreshing only new notes after all notes have been loaded.
*/
/**
* Initializes loading more notes when scrolling to the bottom of the page.
*/
initLoadMore: function() {
$(document).endlessScroll({
bottomPixels: 400,
fireDelay: 1000,
fireOnce:true,
ceaseFire: function() {
return NoteList.loading_more_disabled;
},
callback: function(i) {
NoteList.getMore();
}
});
},
/**
* Gets an additional set of notes.
*/
getMore: function() {
// only load more notes if there are no "new" notes
$('.loading').show();
$.ajax({
url: NoteList.notes_path,
data: NoteList.target_params + "&loading_more=1&" + (NoteList.reversed ? "before_id" : "after_id") + "=" + NoteList.bottom_id,
complete: function(){ $('.js-notes-busy').removeClass("loading")},
beforeSend: function() { $('.js-notes-busy').addClass("loading") },
dataType: "script"
});
},
/**
* Called in response to getMore().
* Append notes to #notes-list.
*/
appendMoreNotes: function(newNoteIds, html) {
var lastNewNoteId = newNoteIds.last();
if(lastNewNoteId != NoteList.bottom_id) {
NoteList.bottom_id = lastNewNoteId;
$("#notes-list").append(html);
}
},
/**
* Called in response to getMore().
* Disables loading more notes when scrolling to the bottom of the page.
*/
finishedLoadingMore: function() {
NoteList.loading_more_disabled = true;
// make sure we are up to date
NoteList.updateVotes();
},
/**
* Handle refreshing and adding of new notes.
*
* New notes are all notes that are created after the site has been loaded.
* The "old" notes are in #notes-list the "new" ones will be in #new-notes-list.
* The id of the last "old" note is in NoteList.bottom_id.
*/
/**
* Initializes getting new notes every n seconds.
*
* Note: only used on wall.
*/
initRefreshNew: function() {
setInterval("NoteList.getNew()", 10000);
},
/**
* Gets the new set of notes.
*
* Note: only used on wall.
*/
getNew: function() {
$.ajax({
url: NoteList.notes_path,
data: NoteList.target_params + "&loading_new=1&after_id=" + (NoteList.reversed ? NoteList.top_id : NoteList.bottom_id),
dataType: "script"
});
},
/**
* Called in response to getNew().
* Replaces the content of #new-notes-list with the given html.
*
* Note: only used on wall.
*/
replaceNewNotes: function(newNoteIds, html) {
$("#new-notes-list").html(html);
NoteList.updateVotes();
},
/**
* Adds a single common note to #notes-list.
*/
@ -364,6 +497,15 @@ var NoteList = {
$.proxy(NoteList.removeDiscussionNoteForm, form).call();
},
/**
* Adds a single wall note to #new-notes-list.
*
* Note: only used on wall.
*/
appendNewWallNote: function(id, html) {
$("#new-notes-list").prepend(html);
},
/**
* Called in response the main target form has been successfully submitted.
*

View File

@ -15,8 +15,6 @@ $ ->
$(this).find('.update-failed').hide()
$('.update-username form').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton()
$(this).find('.save-btn').removeAttr('disabled')
$(this).find('.save-btn').removeClass('disabled')
$(this).find('.loading-gif').hide()
$('.update-notifications').on 'ajax:complete', ->
$(this).find('.btn-save').enableButton()

View File

@ -18,18 +18,3 @@ $ ->
# Ref switcher
$('.project-refs-select').on 'change', ->
$(@).parents('form').submit()
$('#project_issues_enabled').change ->
if ($(this).is(':checked') == true)
$('#project_issues_tracker').removeAttr('disabled')
else
$('#project_issues_tracker').attr('disabled', 'disabled')
$('#project_issues_tracker').change()
$('#project_issues_tracker').change ->
if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
$('#project_issues_tracker_id').attr('disabled', 'disabled')
else
$('#project_issues_tracker_id').removeAttr('disabled')

View File

@ -6,12 +6,17 @@ $ ->
$('span.log_loading:first').removeClass('hide')
$('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live "click", ->
$("#tree-content-holder").hide("slide", { direction: "left" }, 400)
$("#tree-content-holder").hide("slide", { direction: "left" }, 150)
# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$("#tree-slider .tree-item").live 'click', (e) ->
$('.tree-item-file-name a', this).trigger('click') if (e.target.nodeName != "A")
# Show/Hide the loading spinner
$('#tree-slider .tree-item-file-name a, .breadcrumb a, .project-refs-form').live
"ajax:beforeSend": -> $('.tree_progress').addClass("loading")
"ajax:complete": -> $('.tree_progress').removeClass("loading")
# Maintain forward/back history while browsing the file tree
((window) ->
History = window.History
@ -28,12 +33,7 @@ $ ->
History.Adapter.bind window, 'statechange', ->
state = History.getState()
$.ajax({
url: state.url,
dataType: 'script',
beforeSend: -> $('.tree_progress').addClass("loading"),
complete: -> $('.tree_progress').removeClass("loading")
})
window.ajaxGet(state.url)
)(window)
# See if there are lines selected

View File

@ -1,36 +0,0 @@
$ ->
userFormatResult = (user) ->
avatar = gon.gravatar_url
avatar = avatar.replace('%{hash}', md5(user.email))
avatar = avatar.replace('%{size}', '24')
markup = "<div class='user-result'>"
markup += "<div class='user-image'><img class='avatar s24' src='" + avatar + "'></div>"
markup += "<div class='user-name'>" + user.name + "</div>"
markup += "<div class='user-username'>" + user.username + "</div>"
markup += "</div>"
markup
userFormatSelection = (user) ->
user.name
$('.ajax-users-select').select2
placeholder: "Search for a user"
multiple: $('.ajax-users-select').hasClass('multiselect')
minimumInputLength: 0
query: (query) ->
Api.users query.term, (users) ->
data = { results: users }
query.callback(data)
initSelection: (element, callback) ->
id = $(element).val()
if id isnt ""
Api.user(id, callback)
formatResult: userFormatResult
formatSelection: userFormatSelection
dropdownCssClass: "ajax-users-dropdown"
escapeMarkup: (m) -> # we do not want to escape markup since we are displaying html in results
m

View File

@ -1,83 +0,0 @@
@Wall =
note_ids: []
project_id: null
init: (project_id) ->
Wall.project_id = project_id
Wall.getContent()
Wall.initRefresh()
Wall.initForm()
#
# Gets an initial set of notes.
#
getContent: ->
Api.notes Wall.project_id, (notes) ->
$.each notes, (i, note) ->
# render note if it not present in loaded list
# or skip if rendered
if $.inArray(note.id, Wall.note_ids) == -1
Wall.note_ids.push(note.id)
Wall.renderNote(note)
Wall.scrollDown()
$("abbr.timeago").timeago()
initRefresh: ->
setInterval("Wall.refresh()", 10000)
refresh: ->
Wall.getContent()
scrollDown: ->
notes = $('ul.notes')
$('body, html').scrollTop(notes.height())
initForm: ->
form = $('.wall-note-form')
form.find("#target_type").val('wall')
form.on 'ajax:success', ->
Wall.refresh()
form.find(".js-note-text").val("").trigger("input")
form.on 'ajax:complete', ->
form.find(".js-comment-button").removeAttr('disabled')
form.find(".js-comment-button").removeClass('disabled')
form.on "click", ".js-choose-note-attachment-button", ->
form.find(".js-note-attachment-input").click()
form.on "change", ".js-note-attachment-input", ->
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-attachment-filename").text(filename)
form.find('.note_text').keydown (e) ->
if e.ctrlKey && e.keyCode == 13
form.find('.js-comment-button').submit()
form.show()
renderNote: (note) ->
template = Wall.noteTemplate()
template = template.replace('{{author_name}}', note.author.name)
template = template.replace('{{created_at}}', note.created_at)
template = template.replace('{{text}}', linkify(sanitize(note.body)))
if note.attachment
file = '<i class="icon-paper-clip"/><a href="/files/note/' + note.id + '/' + note.attachment + '">' + note.attachment + '</a>'
else
file = ''
template = template.replace('{{file}}', file)
$('ul.notes').append(template)
noteTemplate: ->
return '<li>
<strong class="wall-author">{{author_name}}</strong>
<span class="wall-text">
{{text}}
<span class="wall-file">{{file}}</span>
</span>
<abbr class="timeago" title="{{created_at}}">{{created_at}}</abbr>
</li>'

View File

@ -5,7 +5,6 @@
*= require jquery.ui.gitlab
*= require jquery.atwho
*= require chosen
*= require select2
*= require_self
*/
@ -15,7 +14,7 @@
@import "gitlab_bootstrap.scss";
@import "common.scss";
@import "selects.scss";
@import "ref_select.scss";
@import "sections/header.scss";
@import "sections/nav.scss";
@ -34,12 +33,9 @@
@import "sections/login.scss";
@import "sections/editor.scss";
@import "sections/admin.scss";
@import "sections/wiki.scss";
@import "sections/wall.scss";
@import "highlight/white.scss";
@import "highlight/dark.scss";
@import "highlight/solarized_dark.scss";
/**
* UI themes:

View File

@ -67,17 +67,27 @@ table a code {
}
/** FLASH message **/
.flash-container {
#flash-container {
height: 50px;
position: fixed;
z-index: 10001;
top: 0px;
width: 100%;
margin-bottom: 15px;
overflow: hidden;
background: white;
cursor: pointer;
border-bottom: 1px solid #ccc;
text-align: center;
display: none;
.alert {
cursor: pointer;
margin: 0;
text-align: center;
border-radius: 0;
span {
font-size: 14px;
}
h4 {
color: #666;
font-size: 18px;
line-height: 38px;
padding-top: 5px;
margin: 2px;
font-weight: normal;
}
}
@ -173,6 +183,17 @@ ul.breadcrumb {
font-weight: bold;
font-size: 14px;
}
.arrow {
background: url("images.png") no-repeat -85px -77px;
width: 19px;
height: 16px;
float: left;
position: relative;
left: -10px;
padding: 0;
margin: 0;
}
}
input[type=text] {
@ -182,6 +203,10 @@ input[type=text] {
}
}
input.git_clone_url {
width: 325px;
}
.merge-request-form-holder {
select {
width: 300px;
@ -539,19 +564,3 @@ img.emoji {
vertical-align: middle;
width: 20px;
}
.appear-data {
display: none;
}
.label-branch {
@include border-radius(4px);
padding: 2px 4px;
border: none;
font-size: 14px;
background: #474D57;
color: #fff;
font-family: $monospace_font;
text-shadow: 0 1px 1px #111;
font-weight: normal;
}

View File

@ -20,15 +20,6 @@
background: #FFF;
}
&.ui-box-danger {
.title {
@include linear-gradient(#F26E5E, #bd362f);
color: #fff;
text-shadow: 0 1px 1px #900;
font-weight: bold;
}
}
img { max-width: 100%; }
pre {
@ -43,6 +34,13 @@
padding: 15px;
word-wrap: break-word;
pre {
background: none !important;
margin: 0;
border: none;
padding: 0;
}
.clearfix {
margin: 0;
}
@ -100,9 +98,8 @@
margin-top: 0;
}
.btn {
position: relative;
top: -2px;
.btn-tiny {
@include box-shadow(0 0px 0px 1px #f1f1f1);
}
.nav-pills {
@ -151,23 +148,4 @@
text-decoration: underline;
}
}
.form-holder {
padding-top: 20px;
form {
margin-bottom: 0;
legend {
text-indent: 10px;
}
.form-actions {
margin-bottom: 0;
}
}
}
}
.tab-pane {
.ui-box {
margin: 3px 3px 25px 3px;
}
}

View File

@ -2,7 +2,6 @@
.cgray { color:gray }
.cred { color:#D12F19 }
.cgreen { color:#4a2 }
.cblue { color:#29A }
.cblack { color:#111 }
.cdark { color:#444 }
.cwhite { color:#fff!important }
@ -21,7 +20,6 @@
.hint { font-style: italic; color: #999; }
.light { color: #888 }
.tiny { font-weight: normal }
.vtop { vertical-align: top; }
/** ALERT MESSAGES **/
@ -31,8 +29,6 @@
border-color: #DDD;
}
.well { padding: 15px; }
/** HELPERS **/
.nothing_here_message {
text-align: center;
@ -73,7 +69,3 @@ fieldset legend { font-size: 17px; }
border-bottom: 2px solid $style_color;
}
}
.tab-content {
overflow: visible;
}

View File

@ -162,7 +162,6 @@
color: #666;
padding: 10px 6px 10px 0;
text-align: right;
background: #EEE;
a {
color: #666;

View File

@ -1,2 +1,7 @@
@font-face{
font-family: Yanone;
src: font-url('YanoneKaffeesatz-Light.ttf');
}
/** Typo **/
$monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace;

View File

@ -24,14 +24,6 @@
background-image: -o-linear-gradient($from, $to);
}
@mixin transition($transition) {
-webkit-transition: $transition;
-moz-transition: $transition;
-ms-transition: $transition;
-o-transition: $transition;
transition: $transition;
}
/**
* Prefilled mixins
* Mixins with fixed values
@ -70,19 +62,8 @@
@mixin header-font {
color: $style_color;
text-shadow: 0 1px 1px #FFF;
font-size: 18px;
line-height: 40px;
font-family: 'Yanone', sans-serif;
font-size: 26px;
line-height: 42px;
font-weight: normal;
letter-spacing: -1px;
}
@mixin md-typography {
code { padding: 0 4px; }
p { font-size: 13px; }
h1 { font-size: 26px; line-height: 40px; margin: 10px 0;}
h2 { font-size: 22px; line-height: 40px; margin: 10px 0;}
h3 { font-size: 18px; line-height: 40px; margin: 10px 0;}
h4 { font-size: 16px; line-height: 20px; margin: 10px 0;}
h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
}

View File

@ -11,12 +11,6 @@ table {
}
}
&.headless {
tr:first-child td{
border-top: 1px solid #CCC;
}
}
th {
font-weight: bold;
vertical-align: middle;

View File

@ -87,15 +87,16 @@ a:focus {
*
*/
.wiki {
@include md-typography;
font-size: 13px;
line-height: 20px;
code { padding: 0 4px; }
p { font-size: 13px; }
h1 { font-size: 32px; line-height: 40px; margin: 10px 0;}
h2 { font-size: 26px; line-height: 40px; margin: 10px 0;}
h3 { font-size: 22px; line-height: 40px; margin: 10px 0;}
h4 { font-size: 18px; line-height: 20px; margin: 10px 0;}
h5 { font-size: 14px; line-height: 20px; margin: 10px 0;}
h6 { font-size: 12px; line-height: 20px; margin: 10px 0;}
.white .highlight pre { background: #f5f5f5; }
ul { margin: 0 0 9px 25px !important; }
}
.md {
@include md-typography;
}

View File

@ -1,7 +1,8 @@
.black .highlight {
background-color: #333;
pre {
background-color: #333;
color: #eee;
background: inherit;
}
.hll { display: block; background-color: darken($hover, 65%) }

View File

@ -1,77 +0,0 @@
.solarized-dark .highlight {
pre {
background-color: #002B36;
color: #eee;
}
.hll { background-color: #073642 }
.c { color: #586E75 } /* Comment */
.err { color: #93A1A1 } /* Error */
.g { color: #93A1A1 } /* Generic */
.k { color: #859900 } /* Keyword */
.l { color: #93A1A1 } /* Literal */
.n { color: #93A1A1 } /* Name */
.o { color: #859900 } /* Operator */
.x { color: #CB4B16 } /* Other */
.p { color: #93A1A1 } /* Punctuation */
.cm { color: #586E75 } /* Comment.Multiline */
.cp { color: #859900 } /* Comment.Preproc */
.c1 { color: #586E75 } /* Comment.Single */
.cs { color: #859900 } /* Comment.Special */
.gd { color: #2AA198 } /* Generic.Deleted */
.ge { color: #93A1A1; font-style: italic } /* Generic.Emph */
.gr { color: #DC322F } /* Generic.Error */
.gh { color: #CB4B16 } /* Generic.Heading */
.gi { color: #859900 } /* Generic.Inserted */
.go { color: #93A1A1 } /* Generic.Output */
.gp { color: #93A1A1 } /* Generic.Prompt */
.gs { color: #93A1A1; font-weight: bold } /* Generic.Strong */
.gu { color: #CB4B16 } /* Generic.Subheading */
.gt { color: #93A1A1 } /* Generic.Traceback */
.kc { color: #CB4B16 } /* Keyword.Constant */
.kd { color: #268BD2 } /* Keyword.Declaration */
.kn { color: #859900 } /* Keyword.Namespace */
.kp { color: #859900 } /* Keyword.Pseudo */
.kr { color: #268BD2 } /* Keyword.Reserved */
.kt { color: #DC322F } /* Keyword.Type */
.ld { color: #93A1A1 } /* Literal.Date */
.m { color: #2AA198 } /* Literal.Number */
.s { color: #2AA198 } /* Literal.String */
.na { color: #93A1A1 } /* Name.Attribute */
.nb { color: #B58900 } /* Name.Builtin */
.nc { color: #268BD2 } /* Name.Class */
.no { color: #CB4B16 } /* Name.Constant */
.nd { color: #268BD2 } /* Name.Decorator */
.ni { color: #CB4B16 } /* Name.Entity */
.ne { color: #CB4B16 } /* Name.Exception */
.nf { color: #268BD2 } /* Name.Function */
.nl { color: #93A1A1 } /* Name.Label */
.nn { color: #93A1A1 } /* Name.Namespace */
.nx { color: #93A1A1 } /* Name.Other */
.py { color: #93A1A1 } /* Name.Property */
.nt { color: #268BD2 } /* Name.Tag */
.nv { color: #268BD2 } /* Name.Variable */
.ow { color: #859900 } /* Operator.Word */
.w { color: #93A1A1 } /* Text.Whitespace */
.mf { color: #2AA198 } /* Literal.Number.Float */
.mh { color: #2AA198 } /* Literal.Number.Hex */
.mi { color: #2AA198 } /* Literal.Number.Integer */
.mo { color: #2AA198 } /* Literal.Number.Oct */
.sb { color: #586E75 } /* Literal.String.Backtick */
.sc { color: #2AA198 } /* Literal.String.Char */
.sd { color: #93A1A1 } /* Literal.String.Doc */
.s2 { color: #2AA198 } /* Literal.String.Double */
.se { color: #CB4B16 } /* Literal.String.Escape */
.sh { color: #93A1A1 } /* Literal.String.Heredoc */
.si { color: #2AA198 } /* Literal.String.Interpol */
.sx { color: #2AA198 } /* Literal.String.Other */
.sr { color: #DC322F } /* Literal.String.Regex */
.s1 { color: #2AA198 } /* Literal.String.Single */
.ss { color: #2AA198 } /* Literal.String.Symbol */
.bp { color: #268BD2 } /* Name.Builtin.Pseudo */
.vc { color: #268BD2 } /* Name.Variable.Class */
.vg { color: #268BD2 } /* Name.Variable.Global */
.vi { color: #268BD2 } /* Name.Variable.Instance */
.il { color: #2AA198 } /* Literal.Number.Integer.Long */
}

View File

@ -1,18 +1,3 @@
.ajax-users-select {
width: 400px;
}
.user-result {
.user-image {
float: left;
}
.user-name {
}
.user-username {
color: #999;
}
}
/** Branch/tag selector **/
.project-refs-form {
margin: 0;
@ -103,26 +88,3 @@
}
}
}
/** Select2 styling **/
.select2-container .select2-choice {
background: #f1f1f1;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, whitesmoke), to(#e1e1e1));
background-image: -webkit-linear-gradient(whitesmoke 6.6%, #e1e1e1);
background-image: -moz-linear-gradient(whitesmoke 6.6%, #e1e1e1);
background-image: -o-linear-gradient(whitesmoke 6.6%, #e1e1e1);
}
.select2-container .select2-choice div {
border: none;
background: none;
}
.select2-drop {
padding-top: 8px;
}
.select2-no-results, .select2-searching {
padding: 7px;
color: #666;
}

View File

@ -29,7 +29,7 @@
a{
color: $style_color;
}
> span {
font-family: $monospace_font;
font-size: 14px;
@ -100,9 +100,8 @@
}
}
.line_content {
display: block;
white-space: pre;
height: 18px;
height: 14px;
margin: 0px;
padding: 0px;
border: none;
@ -125,7 +124,7 @@
.wrap{
display: inline-block;
}
.frame {
display: inline-block;
background-color: #fff;
@ -150,7 +149,7 @@
.view.swipe{
position: relative;
.swipe-frame{
display: block;
margin: auto;
@ -229,7 +228,7 @@
bottom: 0px;
left: 50%;
margin-left: -150px;
.drag-track{
display: block;
position: absolute;
@ -238,7 +237,7 @@
width: 276px;
background: url('onion_skin_sprites.gif') -4px -20px repeat-x;
}
.dragger {
display: block;
position: absolute;
@ -249,7 +248,7 @@
background: url('onion_skin_sprites.gif') 0px -34px repeat-x;
cursor: pointer;
}
.transparent {
display: block;
position: absolute;
@ -259,7 +258,7 @@
width: 10px;
background: url('onion_skin_sprites.gif') -2px 0px no-repeat;
}
.opaque {
display: block;
position: absolute;
@ -276,19 +275,19 @@
padding: 10px;
text-align: center;
background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf));
background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf);
background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf);
ul, li{
list-style: none;
margin: 0;
padding: 0;
display: inline-block;
}
li{
color: grey;
border-left: 1px solid #c1c1c1;
@ -323,12 +322,12 @@
}
.commit-author, .commit-committer{
display: block;
color: #999;
font-weight: normal;
color: #999;
font-weight: normal;
font-style: italic;
}
.commit-author strong, .commit-committer strong{
font-weight: bold;
font-weight: bold;
font-style: normal;
}
@ -338,6 +337,7 @@
*/
.commit {
.browse_code_link_holder {
@extend .span2;
float: right;
}
@ -413,9 +413,3 @@
padding: 4px;
background-color: #EEE;
}
.commit-description {
background: none;
border: none;
margin: 0;
}

View File

@ -48,24 +48,17 @@
color: #666;
}
.event-note {
padding-top: 5px;
padding-left: 5px;
display: inline-block;
color: #555;
margin-top: 5px;
margin-left: 40px;
.note-file-attach {
.note-image-attach {
margin-top: 4px;
margin-left: 0px;
max-width: 200px;
}
}
}
.event-note-icon {
color: #777;
float: left;
font-size: 16px;
line-height: 16px;
margin-right: 5px;
line-height: 18px;
margin: 5px;
}
}
.avatar {

View File

@ -12,7 +12,7 @@
.graph {
background: #f1f1f1;
cursor: move;
height: 500px;
height: 70%;
overflow: hidden;
}
}

View File

@ -5,16 +5,15 @@
header {
&.navbar-gitlab {
.navbar-inner {
height: 40px;
padding: 3px;
height: 45px;
padding: 5px;
background: #F1F1F1;
filter: none;
.nav > li > a {
color: $style_color;
text-shadow: 0 1px 0 #fff;
font-size: 16px;
padding: 10px;
font-size: 18px;
padding: 12px;
}
/** NAV block with links and profile **/
@ -26,6 +25,7 @@ header {
}
z-index: 10;
/*height: 60px;*/
/**
*
@ -34,7 +34,7 @@ header {
*/
.app_logo {
float: left;
margin-right: 9px;
margin-right: 15px;
position: relative;
top: -5px;
padding-top: 5px;
@ -42,11 +42,10 @@ header {
a {
float: left;
padding: 0px;
margin: 0 6px;
margin: 0 10px;
h1 {
background: url('logo-black.png') no-repeat center 1px;
background-size: 38px;
background: url('logo_dark.png') no-repeat 0px 2px;
float: left;
height: 40px;
width: 40px;
@ -68,27 +67,19 @@ header {
position: relative;
float: left;
margin: 0;
margin-left: 10px;
margin-left: 15px;
@include header-font;
}
.profile-pic {
position: relative;
top: -4px;
img {
width: 26px;
@include border-radius(4px);
}
}
/**
*
* Search box
*
*/
.search {
margin-right: 10px;
margin-right: 45px;
margin-left: 10px;
margin-top: 2px;
.search-input {
@extend .span2;
@ -100,13 +91,121 @@ header {
@include border-radius(3px);
border: 1px solid #c6c6c6;
box-shadow: none;
@include transition(all 0.15s ease-in 0s);
&:focus {
@extend .span3;
}
}
}
/**
*
* Account box
*
*/
.account-box {
position: absolute;
right: 0;
top: 6px;
z-index: 10000;
width: 128px;
font-size: 11px;
float: right;
display: block;
cursor: pointer;
img {
@include border-radius(3px);
right: 5px;
position: absolute;
width: 28px;
height: 28px;
display: block;
top: 1px;
&:after {
content: " ";
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
float: right;
@include border-radius(5px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-bottom: 0;
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(rgba(255, 255, 255, 0.15)), to(rgba(0, 0, 0, 0.25))),
-webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 0)), color-stop(0.5, rgba(255, 255, 255, 0.1)), color-stop(0.501, rgba(255, 255, 255, 0)), color-stop(1, rgba(255, 255, 255, 0)));
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)),
-moz-linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
background: linear-gradient(top, rgba(255, 255, 255, 0.15), rgba(0, 0, 0, 0.25)),
linear-gradient(left top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0) 50%, rgba(255, 255, 255, 0));
-webkit-background-origin: border-box;
-moz-background-origin: border;
background-origin: border-box; } } }
.account-box {
&.hover {
height: 138px; }
&:hover > .account-links {
display: block; } }
.account-links {
@include border-radius(5px);
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
position: relative;
&:before {
content: ".";
width: 0;
height: 0;
position: absolute;
border: 5px solid transparent;
border-color: rgba(255, 255, 255, 0);
border-bottom-color: #555;
text-indent: -9999px;
top: -10px;
line-height: 0;
right: 10px;
z-index: 10; }
background: #555;
display: none;
z-index: 100000;
@include border-radius(4px);
width: 130px;
position: absolute;
right: 5px;
top: 38px;
margin-top: 0;
float: right;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
a {
color: #fff;
padding: 12px 15px;
display: block;
text-shadow: none;
border-bottom: 1px solid #666;
font-size: 12px;
&:hover {
color: #fff;
background: #333;
}
}
}
.account-box.hover .arrow-up {
top: 41px;
right: 6px;
position: absolute; }
.account-links a {
&:first-child {
@include border-radius(5px 5px 0 0);
}
&:last-child {
@include border-radius(0 0 5px 5px);
border-bottom: 0;
}
}
/*
* Dark header
@ -129,7 +228,6 @@ header {
.search-input {
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
border: 1px solid #AAA;
&:focus {
background-color: white;
@ -142,17 +240,13 @@ header {
.app_logo {
a {
h1 {
background: url('logo-white.png') no-repeat center 1px;
background-size: 38px;
background: url('logo_white.png') no-repeat center center;
color: #fff;
text-shadow: 0 1px 1px #111;
}
}
}
.project_name {
a {
color: #FFF;
}
color: #fff;
text-shadow: 0 1px 1px #111;
}
@ -167,11 +261,11 @@ header {
.separator {
float: left;
height: 46px;
height: 60px;
width: 1px;
background: white;
border-left: 1px solid #DDD;
margin-top: -3px;
margin-top: -10px;
margin-left: 10px;
margin-right: 10px;
}

View File

@ -1,7 +1,7 @@
/* Login Page */
body.login-page{
background: #EEE;
.container .content { padding-top: 5%; }
body.login-page{
padding-top: 10%;
background: #f1f1f1;
}
.login-box{

View File

@ -70,6 +70,16 @@ li.merge_request {
@extend .append-bottom-10;
}
.label_branch {
@include border-radius(4px);
padding: 2px 4px;
border: none;
font-size: 14px;
background: #474D57;
color: #fff;
font-family: $monospace_font;
}
.mr_source_commit,
.mr_target_commit {
.commit {

View File

@ -1,64 +1,68 @@
.main-nav {
/*
* Main Menu of Application
*
*/
ul.main_menu {
margin: auto;
margin: 30px 0;
margin-top: 10px;
border-bottom: 1px solid #E1E1E1;
ul {
margin: auto;
height: 39px;
height: 38px;
position: relative;
overflow: hidden;
.count {
position: relative;
top: 3px;
overflow: hidden;
.count {
position: relative;
top: -1px;
display: inline-block;
height: 15px;
margin: 0 0 0 5px;
padding: 0 8px 1px 8px;
height: auto;
font-size: 0.82em;
line-height: 14px;
text-align: center;
color: #777;
}
.label {
background: $hover;
text-shadow: none;
color: $style_color;
}
li {
list-style-type: none;
margin: 0;
display: table-cell;
width: 1%;
&.active {
border-bottom: 3px solid #777;
a {
color: $style_color;
font-weight: bolder;
}
top: -1px;
display: inline-block;
height: 15px;
margin: 0 0 0 5px;
padding: 0 8px 1px 8px;
height: auto;
font-size: 0.82em;
line-height: 14px;
text-align: center;
color: #777;
}
.label {
background: $hover;
text-shadow: none;
color: $style_color;
}
li {
list-style-type: none;
margin: 0;
display: table-cell;
width: 1%;
border-bottom: 2px solid #EEE;
&.active {
border-bottom: 2px solid #474D57;
a {
color: $style_color;
}
}
&.home {
a {
i {
font-size: 20px;
position: relative;
top: 4px;
}
&.home {
a {
i {
font-size: 20px;
position: relative;
top: 4px;
}
}
}
a {
display: block;
text-align: center;
font-weight: normal;
height: 36px;
line-height: 34px;
color: #777;
text-shadow: 0 1px 1px white;
padding: 0 10px;
}
}
a {
display: block;
text-align: center;
font-weight: normal;
height: 36px;
line-height: 36px;
color: #777;
text-shadow: 0 1px 1px white;
padding: 0 10px;
}
}
/*
* End of Main Menu
*
*/

View File

@ -83,7 +83,6 @@ ul.notes {
margin-top: -20px;
}
.note-body {
@include md-typography;
margin-left: 45px;
}
.note-header {
@ -192,7 +191,7 @@ ul.notes {
}
}
// "show" the icon also if we just hover somewhere over the line
// "show" the icon also if we just hover somwhere over the line
&:hover > td {
background: $hover !important;
@ -274,28 +273,15 @@ ul.notes {
}
.common-note-form {
margin: 0;
height: 140px;
background: #F9F9F9;
padding: 3px;
padding-bottom: 25px;
border: 1px solid #DDD;
}
.note-form-actions {
background: #F9F9F9;
height: 45px;
padding: 0 5px;
.note-form-option {
margin-top: 10px;
margin-left: 30px;
margin-top: 8px;
margin-left: 15px;
@extend .pull-left;
}
.js-notify-commit-author {
float: left;
@extend .span4;
}
}

View File

@ -6,8 +6,7 @@
.side {
@extend .pull-right;
.ui-box {
margin: 3px;
.projects_box {
> .title {
padding: 2px 15px;
}
@ -81,7 +80,6 @@
border: 1px solid #BBB;
box-shadow: none;
margin-left: -1px;
background: #FFF;
}
}
@ -117,20 +115,3 @@ ul.nav.nav-projects-tabs {
}
}
}
.team_member_row form {
margin: 0px;
}
.public-projects {
li {
margin-top: 8px;
margin-bottom: 5px;
border-bottom: 1px solid #eee;
.description {
margin-left: 22px;
color: #aaa;
}
}
}

View File

@ -102,7 +102,3 @@
}
}
.tree-ref-holder {
float: left;
margin-top: 5px;
}

View File

@ -1,55 +0,0 @@
.wall-page {
.wall-note-form {
@extend .span12;
margin: 0;
height: 140px;
background: #F9F9F9;
position: fixed;
bottom: 0px;
padding: 3px;
padding-bottom: 25px;
border: 1px solid #DDD;
}
.notes {
margin-bottom: 160px;
background: #FFE;
border: 1px solid #EED;
> li {
@extend .clearfix;
border-bottom: 1px solid #EED;
padding: 10px;
}
.wall-author {
color: #666;
float: left;
font-size: 12px;
width: 120px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.wall-text {
border-left: 1px solid #CCC;
margin-left: 10px;
padding-left: 10px;
float: left;
width: 75%;
}
.wall-file {
margin-left: 8px;
background: #EEE;
}
abbr {
float: right;
color: #AAA;
border: none;
}
}
}

View File

@ -1,6 +0,0 @@
h3.page_title .edit-wiki-header {
width: 780px;
margin-left: auto;
margin-right: auto;
padding-right: 7px;
}

View File

@ -8,27 +8,66 @@
*
*/
.ui_mars {
/*
* Application Header
*
*/
header {
@extend .header-dark;
&.navbar-gitlab {
.navbar-inner {
background: #474D57;
border-bottom: 1px solid #373D47;
.app_logo {
&:hover {
background-color: #373D47;
}
background: #474D57 url('bg-header.png') repeat-x bottom;
border-bottom: 1px solid #444;
.nav > li > a {
color: #eee;
text-shadow: 0 1px 0 #444;
}
}
}
.separator {
background: #31363E;
border-left: 1px solid #666;
.search {
float: right;
margin-right: 45px;
.search-input {
border: 1px solid rgba(0, 0, 0, 0.7);
background-color: #D2D5DA;
background-color: rgba(255, 255, 255, 0.5);
&:focus {
background-color: white;
}
}
}
.search-input::-webkit-input-placeholder {
color: #666;
}
.app_logo {
a {
h1 {
background: url('logo_white.png') no-repeat center center;
color: #eee;
text-shadow: 0 1px 1px #111;
}
}
&:hover {
background-color: #41464e;
}
}
.project_name {
color: #eee;
text-shadow: 0 1px 1px #111;
}
}
.separator {
background: #31363E;
border-left: 1px solid #666;
}
/*
* End of Application Header
*
*/
}

View File

@ -12,6 +12,7 @@ class CommitLoadContext < BaseContext
commit = project.repository.commit(params[:id])
if commit
commit = CommitDecorator.decorate(commit)
line_notes = project.notes.for_commit_id(commit.id).inline
result[:commit] = commit

View File

@ -7,13 +7,12 @@ class IssuesListContext < BaseContext
@issues = case params[:status]
when issues_filter[:all] then @project.issues
when issues_filter[:closed] then @project.issues.closed
when issues_filter[:to_me] then @project.issues.assigned(current_user)
when issues_filter[:by_me] then @project.issues.authored(current_user)
when issues_filter[:to_me] then @project.issues.opened.assigned(current_user)
else @project.issues.opened
end
@issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present?
@issues = @issues.includes(:author, :project)
@issues = @issues.includes(:author, :project).order("updated_at")
# Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present?

View File

@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext
end
merge_requests = merge_requests.page(params[:page]).per(20)
merge_requests = merge_requests.includes(:author, :project).order("created_at desc")
merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc")
# Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present?

View File

@ -3,6 +3,8 @@ module Notes
def execute
note = project.notes.new(params[:note])
note.author = current_user
note.notify = params[:notify].present?
note.notify_author = params[:notify_author].present?
note.save
note
end

View File

@ -3,6 +3,8 @@ module Notes
def execute
target_type = params[:target_type]
target_id = params[:target_id]
after_id = params[:after_id]
before_id = params[:before_id]
@notes = case target_type
@ -14,6 +16,17 @@ module Notes
project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh
when "snippet"
project.snippets.find(target_id).notes.fresh
when "wall"
# this is the only case, where the order is DESC
project.notes.common.inc_author_project.order("created_at DESC, id DESC").limit(50)
end
@notes = if after_id
@notes.where("id > ?", after_id)
elsif before_id
@notes.where("id < ?", before_id)
else
@notes
end
end
end

View File

@ -32,24 +32,8 @@ module Projects
@project.namespace_id = current_user.namespace_id
end
# Disable less important features by default
@project.wall_enabled = false
@project.snippets_enabled = false
@project.creator = current_user
# Import project from cloneable resource
if @project.valid? && @project.import_url.present?
shell = Gitlab::Shell.new
if shell.import_repository(@project.path_with_namespace, @project.import_url)
# We should create satellite for imported repo
@project.satellite.create unless @project.satellite.exists?
true
else
@project.errors.add(:import_url, 'cannot clone repo')
end
end
if @project.save
@project.users_projects.create(project_access: UsersProject::MASTER, user: current_user)
end

View File

@ -1,27 +0,0 @@
module Projects
class TransferContext < BaseContext
def execute(role = :default)
namespace_id = params[:project].delete(:namespace_id)
allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
if allowed_transfer && namespace_id.present?
if namespace_id == Namespace.global_id
if project.namespace.present?
# Transfer to global namespace from anyone
project.transfer(nil)
end
elsif namespace_id.to_i != project.namespace_id
# Transfer to someone namespace
namespace = Namespace.find(namespace_id)
project.transfer(namespace)
end
end
rescue ProjectTransferService::TransferError => ex
project.reload
project.errors.add(:namespace_id, ex.message)
false
end
end
end

View File

@ -1,8 +1,24 @@
module Projects
class UpdateContext < BaseContext
def execute(role = :default)
params[:project].delete(:namespace_id)
namespace_id = params[:project].delete(:namespace_id)
params[:project].delete(:public) unless can?(current_user, :change_public_mode, project)
allowed_transfer = can?(current_user, :change_namespace, project) || role == :admin
if allowed_transfer && namespace_id.present?
if namespace_id == Namespace.global_id
if project.namespace.present?
# Transfer to global namespace from anyone
project.transfer(nil)
end
elsif namespace_id.to_i != project.namespace_id
# Transfer to someone namespace
namespace = Namespace.find(namespace_id)
project.transfer(namespace)
end
end
project.update_attributes(params[:project], as: role)
end
end

View File

@ -1,7 +1,8 @@
class TestHookContext < BaseContext
def execute
hook = project.hooks.find(params[:id])
data = GitPushService.new.sample_data(project, current_user)
commits = project.repository.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
hook.execute(data)
end
end

View File

@ -19,6 +19,36 @@ class Admin::ProjectsController < Admin::ApplicationController
@users = @users.all
end
def edit
end
def team_update
@project.team.add_users_ids(params[:user_ids], params[:project_access])
redirect_to [:admin, @project], notice: 'Project was successfully updated.'
end
def update
project.creator = current_user unless project.creator
status = ::Projects::UpdateContext.new(project, current_user, params).execute(:admin)
if status
redirect_to [:admin, @project], notice: 'Project was successfully updated.'
else
render action: "edit"
end
end
def destroy
# Delete team first in order to prevent multiple gitolite calls
@project.team.truncate
@project.destroy
redirect_to admin_projects_path, notice: 'Project was successfully deleted.'
end
protected
def project

View File

@ -1,7 +1,7 @@
class Admin::Teams::MembersController < Admin::Teams::ApplicationController
def new
@users = User.potential_team_members(user_team)
@users = UserDecorator.decorate_collection @users
@users = UserDecorator.decorate @users
end
def create

View File

@ -9,12 +9,8 @@ class Admin::UsersController < Admin::ApplicationController
end
def show
# Projects user can be added to
@not_in_projects = Project.scoped
@not_in_projects = @not_in_projects.without_user(admin_user) if admin_user.authorized_projects.present?
# Projects he already own or joined
@projects = admin_user.authorized_projects.where('projects.id in (?)', admin_user.authorized_projects.map(&:id))
@projects = Project.scoped
@projects = @projects.without_user(admin_user) if admin_user.authorized_projects.present?
end
def team_update
@ -45,7 +41,7 @@ class Admin::UsersController < Admin::ApplicationController
end
def unblock
if admin_user.activate
if admin_user.update_attribute(:blocked, false)
redirect_to :back, alert: "Successfully unblocked"
else
redirect_to :back, alert: "Error occured. User was not unblocked"
@ -84,8 +80,6 @@ class Admin::UsersController < Admin::ApplicationController
format.html { redirect_to [:admin, admin_user], notice: 'User was successfully updated.' }
format.json { head :ok }
else
# restore username to keep form action url.
admin_user.username = params[:id]
format.html { render action: "edit" }
format.json { render json: admin_user.errors, status: :unprocessable_entity }
end

View File

@ -5,12 +5,16 @@ class ApplicationController < ActionController::Base
before_filter :add_abilities
before_filter :dev_tools if Rails.env == 'development'
before_filter :default_headers
before_filter :add_gon_variables
protect_from_forgery
helper_method :abilities, :can?
rescue_from Gitlab::Gitolite::AccessDenied do |exception|
log_exception(exception)
render "errors/gitolite", layout: "errors", status: 500
end
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
render "errors/encoding", layout: "errors", status: 500
@ -30,7 +34,7 @@ class ApplicationController < ActionController::Base
end
def reject_blocked!
if current_user && current_user.blocked?
if current_user && current_user.blocked
sign_out current_user
flash[:alert] = "Your account is blocked. Retry when an admin unblock it."
redirect_to new_user_session_path
@ -38,7 +42,7 @@ class ApplicationController < ActionController::Base
end
def after_sign_in_path_for resource
if resource.is_a?(User) && resource.respond_to?(:blocked?) && resource.blocked?
if resource.is_a?(User) && resource.respond_to?(:blocked) && resource.blocked
sign_out resource
flash[:alert] = "Your account is blocked. Retry when an admin unblock it."
new_user_session_path
@ -149,11 +153,4 @@ class ApplicationController < ActionController::Base
headers['X-Frame-Options'] = 'DENY'
headers['X-XSS-Protection'] = '1; mode=block'
end
def add_gon_variables
gon.default_issues_tracker = Project.issues_tracker.default_value
gon.api_version = Gitlab::API.version
gon.api_token = current_user.private_token if current_user
gon.gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
end
end

View File

@ -7,7 +7,10 @@ class BlameController < ProjectResourceController
before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :assign_ref_vars
def show
@blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path)
@repo = @project.repo
@blame = Grit::Blob.blame(@repo, @commit.id, @path)
end
end

View File

@ -7,6 +7,8 @@ class BlobController < ProjectResourceController
before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :assign_ref_vars
def show
if @tree.is_blob?
send_data(

View File

@ -13,6 +13,7 @@ class CommitsController < ProjectResourceController
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
@commits = @repo.commits(@ref, @path, @limit, @offset)
@commits = CommitDecorator.decorate(@commits)
respond_to do |format|
format.html # index.html.erb

View File

@ -8,13 +8,15 @@ class CompareController < ProjectResourceController
end
def show
compare = Gitlab::Git::Compare.new(project.repository, params[:from], params[:to])
result = Commit.compare(project, params[:from], params[:to])
@commits = compare.commits
@commit = compare.commit
@diffs = compare.diffs
@refs_are_same = compare.same
@commits = result[:commits]
@commit = result[:commit]
@diffs = result[:diffs]
@refs_are_same = result[:same]
@line_notes = []
@commits = CommitDecorator.decorate(@commits)
end
def create

View File

@ -5,7 +5,7 @@ class DashboardController < ApplicationController
before_filter :event_filter, only: :show
def show
@groups = current_user.authorized_groups.sort_by(&:human_name)
@groups = current_user.authorized_groups
@has_authorized_projects = @projects.count > 0
@teams = current_user.authorized_teams
@projects_count = @projects.count
@ -34,7 +34,6 @@ class DashboardController < ApplicationController
@projects
end
@projects = @projects.search(params[:search]) if params[:search].present?
@projects = @projects.page(params[:page]).per(30)
end

View File

@ -1,47 +0,0 @@
# Controller for edit a repository's file
class EditTreeController < ProjectResourceController
include ExtractsPath
# Authorize
before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :edit_requirements, only: [:edit, :update]
def show
@last_commit = @project.repository.last_commit_for(@ref, @path).sha
end
def update
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
updated_successfully = edit_file_action.commit!(
params[:content],
params[:commit_message],
params[:last_commit]
)
if updated_successfully
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
else
flash[:notice] = "Your changes could not be commited, because the file has been changed"
render :edit
end
end
private
def edit_requirements
unless @tree.is_blob? && @tree.text?
redirect_to project_tree_path(@project, @id), notice: "You can only edit text files"
end
allowed = if project.protected_branch? @ref
can?(current_user, :push_code_to_protected_branches, project)
else
can?(current_user, :push_code, project)
end
return access_denied! unless allowed
end
end

View File

@ -1,2 +1,5 @@
class ErrorsController < ApplicationController
def githost
render "errors/gitolite"
end
end

View File

@ -1,13 +0,0 @@
class FilesController < ApplicationController
def download
note = Note.find(params[:id])
if can?(current_user, :read_project, note.project)
uploader = note.attachment
send_file uploader.file.path, disposition: 'attachment'
else
not_found!
end
end
end

View File

@ -1,6 +1,5 @@
class GraphController < ProjectResourceController
include ExtractsPath
include ApplicationHelper
# Authorize
before_filter :authorize_read_project!
@ -8,21 +7,11 @@ class GraphController < ProjectResourceController
before_filter :require_non_empty_project
def show
if params.has_key?(:q)
if params[:q].blank?
redirect_to project_graph_path(@project, params[:id])
return
end
@q = params[:q]
@commit = @project.repository.commit(@q) || @commit
end
respond_to do |format|
format.html
format.json do
@graph = Network::Graph.new(project, @ref, @commit)
graph = Gitlab::Graph::JsonBuilder.new(project, @ref)
render :json => graph.to_json
end
end
end

View File

@ -59,6 +59,15 @@ class GroupsController < ApplicationController
end
end
def search
result = SearchContext.new(project_ids, params).execute
@projects = result[:projects]
@merge_requests = result[:merge_requests]
@issues = result[:issues]
@wiki_pages = result[:wiki_pages]
end
def people
@project = group.projects.find(params[:project_id]) if params[:project_id]
@users = @project ? @project.users : group.users
@ -85,7 +94,6 @@ class GroupsController < ApplicationController
if owner_id
@group.owner = User.find(owner_id)
@group.save
end
if @group.update_attributes(group_params)

View File

@ -1,5 +1,3 @@
require 'gitlab/satellite/satellite'
class MergeRequestsController < ProjectResourceController
before_filter :module_enabled
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
@ -75,15 +73,14 @@ class MergeRequestsController < ProjectResourceController
if @merge_request.unchecked?
@merge_request.check_if_can_be_merged
end
render json: {merge_status: @merge_request.merge_status_name}
render json: {state: @merge_request.human_state}
rescue Gitlab::SatelliteNotExistError
render json: {merge_status: :no_satellite}
render json: {state: :no_satellite}
end
def automerge
return access_denied! unless allowed_to_merge?
if @merge_request.opened? && @merge_request.can_be_merged?
return access_denied! unless can?(current_user, :accept_mr, @project)
if @merge_request.open? && @merge_request.can_be_merged?
@merge_request.should_remove_source_branch = params[:should_remove_source_branch]
@merge_request.automerge!(current_user)
@status = true
@ -94,10 +91,12 @@ class MergeRequestsController < ProjectResourceController
def branch_from
@commit = @repository.commit(params[:ref])
@commit = CommitDecorator.decorate(@commit)
end
def branch_to
@commit = @repository.commit(params[:ref])
@commit = CommitDecorator.decorate(@commit)
end
def ci_status
@ -126,12 +125,12 @@ class MergeRequestsController < ProjectResourceController
end
def validates_merge_request
# Show git not found page if target branch doesn't exist
return invalid_mr unless @project.repository.branch_names.include?(@merge_request.target_branch)
# Show git not found page if target branch doesnt exist
return git_not_found! unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch)
# Show git not found page if source branch doesn't exist
# Show git not found page if source branch doesnt exist
# and there is no saved commits between source & target branch
return invalid_mr if !@project.repository.branch_names.include?(@merge_request.source_branch) && @merge_request.commits.blank?
return git_not_found! if !@project.repo.heads.map(&:name).include?(@merge_request.source_branch) && @merge_request.commits.blank?
end
def define_show_vars
@ -141,23 +140,6 @@ class MergeRequestsController < ProjectResourceController
# Get commits from repository
# or from cache if already merged
@commits = @merge_request.commits
@allowed_to_merge = allowed_to_merge?
@show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
end
def allowed_to_merge?
action = if project.protected_branch?(@merge_request.target_branch)
:push_code_to_protected_branches
else
:push_code
end
can?(current_user, action, @project)
end
def invalid_mr
# Render special view for MR with removed source or target branch
render 'invalid'
@commits = CommitDecorator.decorate(@commits)
end
end

View File

@ -12,7 +12,7 @@ class MilestonesController < ProjectResourceController
def index
@milestones = case params[:f]
when 'all'; @project.milestones.order("state, due_date DESC")
when 'all'; @project.milestones.order("closed, due_date DESC")
when 'closed'; @project.milestones.closed.order("due_date DESC")
else @project.milestones.active.order("due_date ASC")
end
@ -32,7 +32,7 @@ class MilestonesController < ProjectResourceController
def show
@issues = @milestone.issues
@users = UserDecorator.decorate_collection(@milestone.participants)
@users = UserDecorator.decorate(@milestone.participants)
@merge_requests = @milestone.merge_requests
respond_to do |format|

View File

@ -1,13 +0,0 @@
class NotificationsController < ApplicationController
layout 'profile'
def show
@notification = current_user.notification
@projects = current_user.authorized_projects
end
def update
current_user.notification_level = params[:notification_level]
@saved = current_user.save
end
end

View File

@ -1,6 +1,4 @@
class ProfilesController < ApplicationController
include ActionView::Helpers::SanitizeHelper
before_filter :user
layout 'profile'
@ -14,7 +12,7 @@ class ProfilesController < ApplicationController
end
def update
if @user.update_attributes(user_attributes)
if @user.update_attributes(params[:user])
flash[:notice] = "Profile was successfully updated"
else
flash[:alert] = "Failed to update profile"
@ -53,9 +51,7 @@ class ProfilesController < ApplicationController
end
def update_username
if @user.can_change_username?
@user.update_attributes(username: params[:user][:username])
end
@user.update_attributes(username: params[:user][:username])
respond_to do |format|
format.js
@ -67,17 +63,4 @@ class ProfilesController < ApplicationController
def user
@user = current_user
end
def user_attributes
user_attributes = params[:user]
# Sanitize user input because we dont have strict
# validation for this fields
%w(name skype linkedin twitter bio).each do |attr|
value = user_attributes[attr]
user_attributes[attr] = sanitize(value) if value.present?
end
user_attributes
end
end

View File

@ -4,7 +4,7 @@ class Projects::TeamsController < Projects::ApplicationController
@teams = current_user.is_admin? ? UserTeam.scoped : current_user.user_teams
@teams = @teams.without_project(project)
unless @teams.any?
redirect_to project_team_index_path(project), notice: "No available teams for assigment."
redirect_to project_team_index_path(project), notice: "No avaliable teams for assigment."
end
end

View File

@ -1,10 +1,12 @@
require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder')
class ProjectsController < ProjectResourceController
skip_before_filter :project, only: [:new, :create]
skip_before_filter :repository, only: [:new, :create]
# Authorize
before_filter :authorize_read_project!, except: [:index, :new, :create]
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer]
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy]
before_filter :require_non_empty_project, only: [:blob, :tree, :graph]
layout 'application', only: [:new, :create]
@ -45,10 +47,10 @@ class ProjectsController < ProjectResourceController
format.js
end
end
end
def transfer
::Projects::TransferContext.new(project, current_user, params).execute
rescue Project::TransferError => ex
@error = ex
render :update_failed
end
def show
@ -57,21 +59,43 @@ class ProjectsController < ProjectResourceController
respond_to do |format|
format.html do
if @project.empty_repo?
render "projects/empty"
else
if @project.repository && !@project.repository.empty?
@last_push = current_user.recent_push(@project.id)
render :show
else
render "projects/empty"
end
end
format.js
end
end
def files
@notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100)
end
#
# Wall
#
def wall
return render_404 unless @project.wall_enabled
@target_type = :wall
@target_id = nil
@note = @project.notes.new
respond_to do |format|
format.html
end
end
def destroy
return access_denied! unless can?(current_user, :remove_project, project)
# Delete team first in order to prevent multiple gitolite calls
project.team.truncate
project.destroy
respond_to do |format|

View File

@ -6,7 +6,7 @@ class Public::ProjectsController < ApplicationController
layout 'public'
def index
@projects = Project.public_only
@projects = Project.public
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page]).per(20)
end
end

View File

@ -34,6 +34,7 @@ class RefsController < ProjectResourceController
@logs = contents.map do |content|
file = params[:path] ? File.join(params[:path], content.name) : content.name
last_commit = @repo.commits(@commit.id, file, 1).last
last_commit = CommitDecorator.decorate(last_commit)
{
file_name: content.name,
commit: last_commit
@ -48,7 +49,9 @@ class RefsController < ProjectResourceController
@repo = project.repository
@commit = @repo.commit(@ref)
@commit = CommitDecorator.decorate(@commit)
@tree = Tree.new(@commit.tree, @ref, params[:path])
@tree = TreeDecorator.new(@tree)
@hex_path = Digest::SHA1.hexdigest(params[:path] || "")
if params[:path]

View File

@ -1,28 +1,9 @@
class RegistrationsController < Devise::RegistrationsController
before_filter :signup_enabled?
def destroy
if current_user.owned_projects.count > 0
redirect_to account_profile_path, alert: "Remove projects and groups before removing account." and return
end
current_user.destroy
respond_to do |format|
format.html { redirect_to new_user_session_path, notice: "Account successfully removed." }
end
end
protected
def build_resource(hash=nil)
super
self.resource.projects_limit = Gitlab.config.gitlab.default_projects_limit
self.resource
end
private
def signup_enabled?
redirect_to new_user_session_path unless Gitlab.config.gitlab.signup_enabled
end
end
end

View File

@ -26,7 +26,8 @@ class ServicesController < ProjectResourceController
end
def test
data = GitPushService.new.sample_data(project, current_user)
commits = project.repository.commits(project.default_branch, nil, 3)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
@service = project.gitlab_ci_service
@service.execute(data)

View File

@ -1,5 +1,4 @@
class SnippetsController < ProjectResourceController
before_filter :module_enabled
before_filter :snippet, only: [:show, :edit, :destroy, :update, :raw]
# Allow read any snippet
@ -85,8 +84,4 @@ class SnippetsController < ProjectResourceController
def authorize_admin_snippet!
return render_404 unless can?(current_user, :admin_snippet, @snippet)
end
def module_enabled
return render_404 unless @project.snippets_enabled
end
end

View File

@ -4,11 +4,12 @@ class TeamMembersController < ProjectResourceController
before_filter :authorize_admin_project!, except: [:index, :show]
def index
@team = @project.users_projects.scoped
@team = @team.send(params[:type]) if %w(masters developers reporters guests).include?(params[:type])
@team = @team.sort_by(&:project_access).reverse.group_by(&:project_access)
@teams = UserTeam.scoped
end
@assigned_teams = @project.user_team_project_relationships
def show
@user_project_relation = project.users_projects.find_by_user_id(member)
@events = member.recent_events.in_projects(project).limit(7)
end
def new
@ -16,7 +17,7 @@ class TeamMembersController < ProjectResourceController
end
def create
users = User.where(id: params[:user_ids].split(','))
users = User.where(id: params[:user_ids])
@project.team << [users, params[:project_access]]

View File

@ -8,12 +8,12 @@ class Teams::MembersController < Teams::ApplicationController
def new
@users = User.potential_team_members(user_team)
@users = UserDecorator.decorate_collection @users
@users = UserDecorator.decorate @users
end
def create
unless params[:user_ids].blank?
user_ids = params[:user_ids].split(',')
user_ids = params[:user_ids]
access = params[:default_project_access]
is_admin = params[:group_admin]
user_team.add_members(user_ids, access, is_admin)
@ -27,13 +27,7 @@ class Teams::MembersController < Teams::ApplicationController
end
def update
member_params = params[:team_member]
options = {
default_projects_access: member_params[:permission],
group_admin: member_params[:group_admin]
}
options = {default_projects_access: params[:default_project_access], group_admin: params[:group_admin]}
if user_team.update_membership(team_member, options)
redirect_to team_members_path(user_team), notice: "Membership for #{team_member.name} was successfully updated in Team of users."
else
@ -51,4 +45,5 @@ class Teams::MembersController < Teams::ApplicationController
def team_member
@member ||= user_team.members.find_by_username(params[:id])
end
end

View File

@ -1,4 +1,20 @@
class Teams::ProjectsController < Teams::ApplicationController
skip_before_filter :authorize_manage_user_team!, only: [:index]
def index
@projects = user_team.projects
@avaliable_projects = current_user.admin? ? Project.without_team(user_team) : current_user.owned_projects.without_team(user_team)
end
def new
user_team
@avaliable_projects = current_user.owned_projects.scoped
@avaliable_projects = @avaliable_projects.without_team(user_team) if user_team.projects.any?
redirect_to team_projects_path(user_team), notice: "No avalible projects." unless @avaliable_projects.any?
end
def create
redirect_to :back if params[:project_ids].blank?
@ -12,7 +28,7 @@ class Teams::ProjectsController < Teams::ApplicationController
# Assign projects to team
user_team.assign_to_projects(project_ids, access)
redirect_to edit_team_path(user_team), notice: 'Team of users was successfully assigned to projects.'
redirect_to team_projects_path(user_team), notice: 'Team of users was successfully assigned to projects.'
end
def edit
@ -21,7 +37,7 @@ class Teams::ProjectsController < Teams::ApplicationController
def update
if user_team.update_project_access(team_project, params[:greatest_project_access])
redirect_to edit_team_path(user_team), notice: 'Access was successfully updated.'
redirect_to team_projects_path(user_team), notice: 'Access was successfully updated.'
else
render :edit
end
@ -37,4 +53,5 @@ class Teams::ProjectsController < Teams::ApplicationController
def team_project
@project ||= user_team.projects.find_with_namespace(params[:id])
end
end

View File

@ -9,13 +9,13 @@ class TeamsController < ApplicationController
layout 'user_team', except: [:new, :create]
def show
user_team
projects
@events = Event.in_projects(user_team.project_ids).limit(20).offset(params[:offset] || 0)
end
def edit
projects
@avaliable_projects = current_user.admin? ? Project.without_team(user_team) : current_user.owned_projects.without_team(user_team)
user_team
end
def update
@ -41,9 +41,6 @@ class TeamsController < ApplicationController
@team.path = @team.name.dup.parameterize if @team.name
if @team.save
# Add current user as Master to the team
@team.add_members([current_user.id], UsersProject::MASTER, true)
redirect_to team_path(@team)
else
render action: :new

View File

@ -7,6 +7,9 @@ class TreeController < ProjectResourceController
before_filter :authorize_code_access!
before_filter :require_non_empty_project
before_filter :assign_ref_vars
before_filter :edit_requirements, only: [:edit, :update]
def show
@hex_path = Digest::SHA1.hexdigest(@path)
@logs_path = logs_file_project_ref_path(@project, @ref, @path)
@ -17,4 +20,40 @@ class TreeController < ProjectResourceController
format.js { no_cache_headers }
end
end
def edit
@last_commit = @project.repository.last_commit_for(@ref, @path).sha
end
def update
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path)
updated_successfully = edit_file_action.commit!(
params[:content],
params[:commit_message],
params[:last_commit]
)
if updated_successfully
redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
else
flash[:notice] = "Your changes could not be commited, because the file has been changed"
render :edit
end
end
private
def edit_requirements
unless @tree.is_blob? && @tree.text?
redirect_to project_tree_path(@project, @id), notice: "You can only edit text files"
end
allowed = if project.protected_branch? @ref
can?(current_user, :push_code_to_protected_branches, project)
else
can?(current_user, :push_code, project)
end
return access_denied! unless allowed
end
end

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