diff --git a/CHANGELOG b/CHANGELOG index 2ae83d5b3ce..007e47f7446 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,10 +3,12 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.0.0 (unreleased) - Bump rouge to 1.10.1 to remove warning noise and fix other syntax highlighting bugs (Stan Hu) - Gracefully handle errors in syntax highlighting by leaving the block unformatted (Stan Hu) + - Add "replace" and "upload" functionalities to allow user replace existing file and upload new file into current repository - Fix URL construction for merge requests, issues, notes, and commits for relative URL config (Stan Hu) - Fix emoji URLs in Markdown when relative_url_root is used (Stan Hu) - Omit filename in Content-Disposition header in raw file download to avoid RFC 6266 encoding issues (Stan HU) - Fix broken Wiki Page History (Stan Hu) + - Import forked repositories asynchronously to prevent large repositories from timing out (Stan Hu) - Prevent anchors from being hidden by header (Stan Hu) - Fix bug where only the first 15 Bitbucket issues would be imported (Stan Hu) - Sort issues by creation date in Bitbucket importer (Stan Hu) @@ -31,7 +33,7 @@ v 8.0.0 (unreleased) - Fix 500 error when submit project snippet without body - Improve search page usability - Bring more UI consistency in way how projects, snippets and groups lists are rendered - - Make all profiles public + - Make all profiles and group public - Fixed login failure when extern_uid changes (Joel Koglin) - Don't notify users without access to the project when they are (accidentally) mentioned in a note. - Retrieving oauth token with LDAP credentials diff --git a/Gemfile b/Gemfile index 9de460b45c1..1a7af589f6d 100644 --- a/Gemfile +++ b/Gemfile @@ -167,7 +167,7 @@ gem "slack-notifier", "~> 1.0.0" gem 'asana', '~> 0.0.6' # FogBugz integration -gem 'ruby-fogbugz' +gem 'ruby-fogbugz', '~> 0.2.0' # d3 gem 'd3_rails', '~> 3.5.5' diff --git a/Gemfile.lock b/Gemfile.lock index c8a833ea4d0..65050a71c34 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -274,8 +274,7 @@ GEM charlock_holmes (~> 0.6.6) escape_utils (~> 0.2.4) mime-types (~> 1.19) - gitlab_ci_meta (4.0) - gitlab_emoji (0.1.0) + gitlab_emoji (0.1.1) gemojione (~> 2.0) gitlab_git (7.2.15) activesupport (~> 4.0) @@ -597,8 +596,8 @@ GEM powerpack (~> 0.0.6) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) - ruby-fogbugz (0.1.1) - crack + ruby-fogbugz (0.2.0) + crack (~> 0.4) ruby-progressbar (1.7.5) ruby-saml (1.0.0) nokogiri (>= 1.5.10) @@ -888,8 +887,8 @@ DEPENDENCIES rerun (~> 0.10.0) rqrcode-rails3 (~> 0.1.7) rspec-rails (~> 3.3.0) - rubocop (~> 0.28.0) - ruby-fogbugz + rubocop (= 0.28.0) + ruby-fogbugz (~> 0.2.0) sanitize (~> 2.0) sass-rails (~> 4.0.5) sdoc (~> 0.3.20) @@ -930,6 +929,3 @@ DEPENDENCIES webmock (~> 1.21.0) whenever (~> 0.8.4) wikicloth (= 0.8.1) - -BUNDLED WITH - 1.10.6 diff --git a/README.md b/README.md index 52e12bb66ad..99d5bc0b6ca 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![build status](https://ci.gitlab.com/projects/1/status.png?ref=master)](https://ci.gitlab.com/projects/1?ref=master) [![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq) [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq) -[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) +[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) ## Canonical source diff --git a/app/assets/javascripts/blob/blob_file_dropzone.js.coffee b/app/assets/javascripts/blob/blob_file_dropzone.js.coffee new file mode 100644 index 00000000000..090af9bb376 --- /dev/null +++ b/app/assets/javascripts/blob/blob_file_dropzone.js.coffee @@ -0,0 +1,52 @@ +class @BlobFileDropzone + constructor: (form, method) -> + form_dropzone = form.find('.dropzone') + Dropzone.autoDiscover = false + dropzone = form_dropzone.dropzone( + autoDiscover: false + autoProcessQueue: false + url: form.attr('action') + # Rails uses a hidden input field for PUT + # http://stackoverflow.com/questions/21056482/how-to-set-method-put-in-form-tag-in-rails + method: method + clickable: true + uploadMultiple: false + paramName: "file" + maxFilesize: gon.max_file_size or 10 + parallelUploads: 1 + maxFiles: 1 + addRemoveLinks: true + previewsContainer: '.dropzone-previews' + headers: + "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content") + + success: (header, response) -> + window.location.href = response.filePath + return + + error: (temp, errorMessage) -> + stripped = $("
").html(errorMessage).text(); + $('.dropzone-alerts').html('Error uploading file: \"' + stripped + '\"').show() + return + + maxfilesexceeded: (file) -> + @removeFile file + return + + removedfile: (file) -> + $('.dropzone-previews')[0].removeChild(file.previewTemplate) + $('.dropzone-alerts').html('').hide() + return true + + sending: (file, xhr, formData) -> + formData.append('commit_message', form.find('#commit_message').val()) + return + ) + + submitButton = form.find('#submit-all')[0] + submitButton.addEventListener 'click', (e) -> + e.preventDefault() + e.stopPropagation() + alert "Please select a file" if dropzone[0].dropzone.getQueuedFiles().length == 0 + dropzone[0].dropzone.processQueue() + return false diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index 48d9f890f62..ce024272a30 100644 --- a/app/assets/stylesheets/generic/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss @@ -36,6 +36,11 @@ margin-bottom: 0; } + &.clear-block { + margin-bottom: $gl-padding - 1px; + padding-bottom: $gl-padding; + } + &.second-block { margin-top: -1px; margin-bottom: 0; @@ -51,6 +56,6 @@ } .oneline { - line-height: 44px; + line-height: 42px; } } diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss index 5e191d5dd4a..3a237bf3228 100644 --- a/app/assets/stylesheets/generic/common.scss +++ b/app/assets/stylesheets/generic/common.scss @@ -377,4 +377,8 @@ table { height: 56px; margin-top: -$gl-padding; padding-top: $gl-padding; + + &.no-bottom { + margin-bottom: 0; + } } diff --git a/app/assets/stylesheets/generic/sidebar.scss b/app/assets/stylesheets/generic/sidebar.scss index 41ffd358576..3d055f0e66f 100644 --- a/app/assets/stylesheets/generic/sidebar.scss +++ b/app/assets/stylesheets/generic/sidebar.scss @@ -152,7 +152,6 @@ } .collapse-nav a { - left: 0px; width: $sidebar_collapsed_width; } @@ -171,6 +170,7 @@ width: $sidebar_width; position: fixed; bottom: 0; + left: 0; font-size: 13px; background: transparent; height: 40px; diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 759ba6b1c22..1d565477dd4 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -9,6 +9,10 @@ width: 100%; } + .ace_gutter-cell { + background-color: $background-color; + } + .cancel-btn { color: #B94A48; &:hover { @@ -32,14 +36,12 @@ .file-title { @extend .monospace; - font-size: 14px; - padding: 5px; } .editor-ref { background: $background-color; padding: 11px 15px; - border-right: 1px solid #CCC; + border-right: 1px solid $border-color; display: inline-block; margin: -5px -5px; margin-right: 10px; @@ -50,5 +52,15 @@ display: inline-block; width: 200px; } + + .form-control { + margin-top: -3px; + } + } + + .form-actions { + margin: -$gl-padding; + margin-top: 0; + padding: $gl-padding } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 2544356a5f6..2a77f065aed 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -235,8 +235,6 @@ ul.notes { filter: alpha(opacity=0); &:hover { - width: 38px; - font-size: 20px; background: $gl-info; color: #FFF; @include show-add-diff-note; diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index 71ca37c0cd7..df7fab07a57 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -116,3 +116,15 @@ } #modal-remove-blob > .modal-dialog { width: 850px; } + +.blob-upload-dropzone-previews { + text-align: center; + border: 2px; + border-style: dashed; + min-height: 200px; +} + +.upload-link { + font-weight: normal; + color: #0000EE; +} diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index da96171e885..467d0f81aca 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -1,6 +1,21 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController before_action :event_filter + def index + @projects = current_user.authorized_projects.sorted_by_activity.non_archived + @projects = @projects.includes(:namespace) + @last_push = current_user.recent_push + + respond_to do |format| + format.html + format.atom do + event_filter + load_events + render layout: false + end + end + end + def starred @projects = current_user.starred_projects @projects = @projects.includes(:namespace, :forked_from_project, :tags) diff --git a/app/controllers/dashboard/snippets_controller.rb b/app/controllers/dashboard/snippets_controller.rb new file mode 100644 index 00000000000..f4354c6d8ca --- /dev/null +++ b/app/controllers/dashboard/snippets_controller.rb @@ -0,0 +1,10 @@ +class Dashboard::SnippetsController < Dashboard::ApplicationController + def index + @snippets = SnippetsFinder.new.execute(current_user, + filter: :by_user, + user: current_user, + scope: params[:scope] + ) + @snippets = @snippets.page(params[:page]).per(PER_PAGE) + end +end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 2bc2e5e58f5..4ebb3d7276e 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,23 +1,8 @@ class DashboardController < Dashboard::ApplicationController - before_action :load_projects, except: :activity before_action :event_filter, only: :activity respond_to :html - def show - @projects = @projects.includes(:namespace) - @last_push = current_user.recent_push - - respond_to do |format| - format.html - format.atom do - event_filter - load_events - render layout: false - end - end - end - def merge_requests @merge_requests = get_merge_requests_collection @merge_requests = @merge_requests.page(params[:page]).per(PER_PAGE) @@ -50,10 +35,6 @@ class DashboardController < Dashboard::ApplicationController protected - def load_projects - @projects = current_user.authorized_projects.sorted_by_activity.non_archived - end - def load_events project_ids = if params[:filter] == "starred" diff --git a/app/controllers/explore/application_controller.rb b/app/controllers/explore/application_controller.rb index 4b275033d26..461fc059a3c 100644 --- a/app/controllers/explore/application_controller.rb +++ b/app/controllers/explore/application_controller.rb @@ -1,3 +1,5 @@ class Explore::ApplicationController < ApplicationController + skip_before_action :authenticate_user!, :reject_blocked + layout 'explore' end diff --git a/app/controllers/explore/groups_controller.rb b/app/controllers/explore/groups_controller.rb index 55cda0cff17..9575a87ee41 100644 --- a/app/controllers/explore/groups_controller.rb +++ b/app/controllers/explore/groups_controller.rb @@ -1,7 +1,4 @@ class Explore::GroupsController < Explore::ApplicationController - skip_before_action :authenticate_user!, - :reject_blocked, :set_current_user_for_observers - def index @groups = GroupsFinder.new.execute(current_user) @groups = @groups.search(params[:search]) if params[:search].present? diff --git a/app/controllers/explore/projects_controller.rb b/app/controllers/explore/projects_controller.rb index 6c733c1ae4d..a5aeaed66c5 100644 --- a/app/controllers/explore/projects_controller.rb +++ b/app/controllers/explore/projects_controller.rb @@ -1,7 +1,4 @@ class Explore::ProjectsController < Explore::ApplicationController - skip_before_action :authenticate_user!, - :reject_blocked - def index @projects = ProjectsFinder.new.execute(current_user) @tags = @projects.tags_on(:tags) diff --git a/app/controllers/explore/snippets_controller.rb b/app/controllers/explore/snippets_controller.rb new file mode 100644 index 00000000000..b70ac51d06e --- /dev/null +++ b/app/controllers/explore/snippets_controller.rb @@ -0,0 +1,6 @@ +class Explore::SnippetsController < Explore::ApplicationController + def index + @snippets = SnippetsFinder.new.execute(current_user, filter: :all) + @snippets = @snippets.page(params[:page]).per(PER_PAGE) + end +end diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 279c6ef0f4d..524218290c6 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -4,7 +4,7 @@ class GroupsController < Groups::ApplicationController before_action :group, except: [:new, :create] # Authorize - before_action :authorize_read_group!, except: [:new, :create] + before_action :authorize_read_group!, except: [:show, :new, :create] before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects] before_action :authorize_create_group!, only: [:new, :create] @@ -14,6 +14,10 @@ class GroupsController < Groups::ApplicationController layout :determine_layout + def index + redirect_to(current_user ? dashboard_groups_path : explore_groups_path) + end + def new @group = Group.new end diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index 71831c5380d..ad00948da51 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -1,4 +1,6 @@ class HelpController < ApplicationController + skip_before_action :authenticate_user!, :reject_blocked + layout 'help' def index diff --git a/app/controllers/import/fogbugz_controller.rb b/app/controllers/import/fogbugz_controller.rb index bda534fb4de..849646cd665 100644 --- a/app/controllers/import/fogbugz_controller.rb +++ b/app/controllers/import/fogbugz_controller.rb @@ -2,7 +2,6 @@ class Import::FogbugzController < Import::BaseController before_action :verify_fogbugz_import_enabled before_action :user_map, only: [:new_user_map, :create_user_map] - # Doesn't work yet due to bug in ruby-fogbugz, see below rescue_from Fogbugz::AuthenticationException, with: :fogbugz_unauthorized def new @@ -13,8 +12,8 @@ class Import::FogbugzController < Import::BaseController begin res = Gitlab::FogbugzImport::Client.new(import_params.symbolize_keys) rescue - # Needed until https://github.com/firmafon/ruby-fogbugz/pull/9 is merged - return redirect_to :back, alert: 'Could not authenticate with FogBugz, check your URL, email, and password' + # If the URI is invalid various errors can occur + return redirect_to new_import_fogbugz_path, alert: 'Could not connect to FogBugz, check your URL' end session[:fogbugz_token] = res.get_token session[:fogbugz_uri] = params[:uri] @@ -92,8 +91,7 @@ class Import::FogbugzController < Import::BaseController end def fogbugz_unauthorized(exception) - flash[:alert] = exception.message - redirect_to new_import_fogbugz_path + redirect_to new_import_fogbugz_path, alert: exception.message end def import_params diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index eb3c8233530..8ef10a17f55 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -24,7 +24,7 @@ class InvitesController < ApplicationController path = if current_user - dashboard_path + dashboard_projects_path else new_user_session_path end @@ -73,7 +73,7 @@ class InvitesController < ApplicationController path = group_path(group) else label = "who knows what" - path = dashboard_path + path = dashboard_projects_path end [label, path] diff --git a/app/controllers/namespaces_controller.rb b/app/controllers/namespaces_controller.rb index 83eec1bf4a2..282012c60a1 100644 --- a/app/controllers/namespaces_controller.rb +++ b/app/controllers/namespaces_controller.rb @@ -14,7 +14,7 @@ class NamespacesController < ApplicationController if user redirect_to user_path(user) - elsif group && can?(current_user, :read_group, group) + elsif group redirect_to group_path(group) elsif current_user.nil? authenticate_user! diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 100d3d3b317..8776721d243 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -26,10 +26,16 @@ class Projects::BlobController < Projects::ApplicationController if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" - redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) + respond_to do |format| + format.html { redirect_to namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) } + format.json { render json: { message: "success", filePath: namespace_project_blob_path(@project.namespace, @project, File.join(@target_branch, @file_path)) } } + end else flash[:alert] = result[:message] - render :new + respond_to do |format| + format.html { render :new } + format.json { render json: { message: "failed", filePath: namespace_project_new_blob_path(@project.namespace, @project, @id) } } + end end end @@ -45,10 +51,16 @@ class Projects::BlobController < Projects::ApplicationController if result[:status] == :success flash[:notice] = "Your changes have been successfully committed" - redirect_to after_edit_path + respond_to do |format| + format.html { redirect_to after_edit_path } + format.json { render json: { message: "success", filePath: after_edit_path } } + end else flash[:alert] = result[:message] - render :edit + respond_to do |format| + format.html { render :edit } + format.json { render json: { message: "failed", filePath: namespace_project_new_blob_path(@project.namespace, @project, @id) } } + end end end @@ -146,11 +158,19 @@ class Projects::BlobController < Projects::ApplicationController @file_path = if action_name.to_s == 'create' + if params[:file].present? + params[:file_name] = params[:file].original_filename + end File.join(@path, File.basename(params[:file_name])) else @path end + if params[:file].present? + params[:content] = Base64.encode64(params[:file].read) + params[:encoding] = 'base64' + end + @commit_params = { file_path: @file_path, current_branch: @current_branch, diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb index 9e72597ea87..8a785076bb7 100644 --- a/app/controllers/projects/forks_controller.rb +++ b/app/controllers/projects/forks_controller.rb @@ -13,10 +13,14 @@ class Projects::ForksController < Projects::ApplicationController @forked_project = ::Projects::ForkService.new(project, current_user, namespace: namespace).execute if @forked_project.saved? && @forked_project.forked? - redirect_to( - namespace_project_path(@forked_project.namespace, @forked_project), - notice: 'Project was successfully forked.' - ) + if @forked_project.import_in_progress? + redirect_to namespace_project_import_path(@forked_project.namespace, @forked_project) + else + redirect_to( + namespace_project_path(@forked_project.namespace, @forked_project), + notice: 'Project was successfully forked.' + ) + end else render :error end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index b82b6f45d59..cf73bc01c8f 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -78,7 +78,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController @project.project_members.find_by(user_id: current_user).destroy respond_to do |format| - format.html { redirect_to dashboard_path } + format.html { redirect_to dashboard_projects_path } format.js { render nothing: true } end end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index dafc11d0707..f4d1a828aab 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -10,6 +10,10 @@ class ProjectsController < ApplicationController layout :determine_layout + def index + redirect_to(current_user ? root_path : explore_root_path) + end + def new @project = Project.new end @@ -105,7 +109,7 @@ class ProjectsController < ApplicationController if request.referer.include?('/admin') redirect_to admin_namespaces_projects_path else - redirect_to dashboard_path + redirect_to dashboard_projects_path end rescue Projects::DestroyService::DestroyError => ex redirect_to edit_project_path(@project), alert: ex.message diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index fdfe00dc135..54171ff67c5 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -6,10 +6,10 @@ # # For users who haven't customized the setting, we simply delegate to # `DashboardController#show`, which is the default. -class RootController < DashboardController - before_action :redirect_to_custom_dashboard, only: [:show] +class RootController < Dashboard::ProjectsController + before_action :redirect_to_custom_dashboard, only: [:index] - def show + def index super end @@ -20,6 +20,7 @@ class RootController < DashboardController case current_user.dashboard when 'stars' + flash.keep redirect_to starred_dashboard_projects_path else return diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb index 8e7e45c781f..9f9f9a92f11 100644 --- a/app/controllers/snippets_controller.rb +++ b/app/controllers/snippets_controller.rb @@ -24,13 +24,9 @@ class SnippetsController < ApplicationController scope: params[:scope] }). page(params[:page]).per(PER_PAGE) - if @user == current_user - render 'current_user_index' - else - render 'user_index' - end + render 'index' else - @snippets = SnippetsFinder.new.execute(current_user, filter: :all).page(params[:page]).per(PER_PAGE) + redirect_to(current_user ? dashboard_snippets_path : explore_snippets_path) end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a803b66c502..c3da54fd554 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -201,7 +201,7 @@ module ApplicationHelper class: "#{html_class} js-timeago", datetime: time.getutc.iso8601, title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'), - data: { toggle: 'tooltip', placement: placement } + data: { toggle: 'tooltip', placement: placement, container: 'body' } element += javascript_tag "$('.js-timeago').timeago()" unless skip_js diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb index d0fae255a04..e0816f4e714 100644 --- a/app/helpers/gitlab_routing_helper.rb +++ b/app/helpers/gitlab_routing_helper.rb @@ -17,6 +17,14 @@ module GitlabRoutingHelper namespace_project_path(project.namespace, project, *args) end + def project_files_path(project, *args) + namespace_project_tree_path(project.namespace, project, @ref || project.repository.root_ref) + end + + def project_commits_path(project, *args) + namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref) + end + def activity_project_path(project, *args) activity_namespace_project_path(project.namespace, project, *args) end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index ab9b068de05..6a2de0de77c 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -43,24 +43,22 @@ module ProjectsHelper end end - def project_title(project) - if project.group - content_tag :span do - link_to( - simple_sanitize(project.group.name), group_path(project.group) - ) + ' / ' + - link_to(simple_sanitize(project.name), - project_path(project)) - end - else - owner = project.namespace.owner - content_tag :span do - link_to( - simple_sanitize(owner.name), user_path(owner) - ) + ' / ' + - link_to(simple_sanitize(project.name), - project_path(project)) + def project_title(project, name = nil, url = nil) + namespace_link = + if project.group + link_to(simple_sanitize(project.group.name), group_path(project.group)) + else + owner = project.namespace.owner + link_to(simple_sanitize(owner.name), user_path(owner)) end + + project_link = link_to(simple_sanitize(project.name), project_path(project)) + + full_title = namespace_link + ' / ' + project_link + full_title += ' · '.html_safe + link_to(simple_sanitize(name), url) if name + + content_tag :span do + full_title end end @@ -315,6 +313,45 @@ module ProjectsHelper end end + def current_ref + @ref || @repository.try(:root_ref) + end + + def detect_project_title(project) + name, url = + if current_controller? 'wikis' + ['Wiki', get_project_wiki_path(project)] + elsif current_controller? 'project_members' + ['Members', namespace_project_project_members_path(project.namespace, project)] + elsif current_controller? 'labels' + ['Labels', namespace_project_labels_path(project.namespace, project)] + elsif current_controller? 'members' + ['Members', project_files_path(project)] + elsif current_controller? 'commits' + ['Commits', project_commits_path(project)] + elsif current_controller? 'graphs' + ['Graphs', namespace_project_graph_path(project.namespace, project, current_ref)] + elsif current_controller? 'network' + ['Network', namespace_project_network_path(project.namespace, project, current_ref)] + elsif current_controller? 'milestones' + ['Milestones', namespace_project_milestones_path(project.namespace, project)] + elsif current_controller? 'snippets' + ['Snippets', namespace_project_snippets_path(project.namespace, project)] + elsif current_controller? 'issues' + ['Issues', namespace_project_issues_path(project.namespace, project)] + elsif current_controller? 'merge_requests' + ['Merge Requests', namespace_project_merge_requests_path(project.namespace, project)] + elsif current_controller? 'tree', 'blob' + ['Files', project_files_path(project)] + elsif current_path? 'projects#activity' + ['Activity', activity_project_path(project)] + else + [nil, nil] + end + + project_title(project, name, url) + end + private def filename_path(project, filename) diff --git a/app/models/project.rb b/app/models/project.rb index 495a863d93b..81951467d41 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -144,7 +144,7 @@ class Project < ActiveRecord::Base validates_uniqueness_of :path, scope: :namespace_id validates :import_url, format: { with: /\A#{URI.regexp(%w(ssh git http https))}\z/, message: 'should be a valid url' }, - if: :import? + if: :external_import? validates :star_count, numericality: { greater_than_or_equal_to: 0 } validate :check_limit, on: :create validate :avatar_type, @@ -275,7 +275,13 @@ class Project < ActiveRecord::Base end def add_import_job - RepositoryImportWorker.perform_in(2.seconds, id) + if forked? + unless RepositoryForkWorker.perform_async(id, forked_from_project.path_with_namespace, self.namespace.path) + import_fail + end + else + RepositoryImportWorker.perform_in(2.seconds, id) + end end def clear_import_data @@ -283,6 +289,10 @@ class Project < ActiveRecord::Base end def import? + external_import? || forked? + end + + def external_import? import_url.present? end @@ -702,14 +712,8 @@ class Project < ActiveRecord::Base end def create_repository - if forked? - if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path) - true - else - errors.add(:base, 'Failed to fork repository via gitlab-shell') - false - end - else + # Forked import is handled asynchronously + unless forked? if gitlab_shell.add_repository(path_with_namespace) true else diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 36d9874edd3..7cd5e892507 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -34,6 +34,12 @@ class SlackService < Service 'slack' end + def help + 'This service sends notifications to your Slack channel.
+ To setup this Service you need to create a new "Incoming webhook" in your Slack integration panel, + and enter the Webhook URL below.' + end + def fields [ { type: 'text', name: 'webhook', diff --git a/app/services/files/create_service.rb b/app/services/files/create_service.rb index 91d715b2d63..ffbb5993279 100644 --- a/app/services/files/create_service.rb +++ b/app/services/files/create_service.rb @@ -19,10 +19,12 @@ module Files end unless project.empty_repo? + @file_path.slice!(0) if @file_path.start_with?('/') + blob = repository.blob_at_branch(@current_branch, @file_path) if blob - raise_error("Your changes could not be committed, because file with such name exists") + raise_error("Your changes could not be committed because a file with the same name already exists") end end end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index 1bb2462565a..e54a13ed6c5 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -55,9 +55,7 @@ module Projects @project.save if @project.persisted? && !@project.import? - unless @project.create_repository - raise 'Failed to create repository' - end + raise 'Failed to create repository' unless @project.create_repository end end diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml index 1db56542afd..19d919f9b6a 100644 --- a/app/views/dashboard/_activities.html.haml +++ b/app/views/dashboard/_activities.html.haml @@ -5,7 +5,7 @@ - if current_user %ul.nav.nav-pills.event_filter.pull-right %li.pull-right - = link_to dashboard_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do + = link_to dashboard_projects_path(:atom, { private_token: current_user.private_token }), class: 'rss-btn' do %i.fa.fa-rss = render 'shared/event_filter' diff --git a/app/views/dashboard/_groups_head.html.haml b/app/views/dashboard/_groups_head.html.haml index dcd6c97d44d..64bd356f546 100644 --- a/app/views/dashboard/_groups_head.html.haml +++ b/app/views/dashboard/_groups_head.html.haml @@ -1,7 +1,7 @@ %ul.center-top-menu - = nav_link(page: [dashboard_groups_path]) do + = nav_link(page: dashboard_groups_path) do = link_to dashboard_groups_path, title: 'Your groups', data: {placement: 'right'} do Your Groups - = nav_link(page: [explore_groups_path]) do + = nav_link(page: explore_groups_path) do = link_to explore_groups_path, title: 'Explore groups', data: {placement: 'bottom'} do Explore Groups diff --git a/app/views/dashboard/_projects_head.html.haml b/app/views/dashboard/_projects_head.html.haml index 13a5eae3cdc..ed480b8caf8 100644 --- a/app/views/dashboard/_projects_head.html.haml +++ b/app/views/dashboard/_projects_head.html.haml @@ -1,6 +1,6 @@ %ul.center-top-menu - = nav_link(path: ['dashboard#show', 'root#show']) do - = link_to dashboard_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do + = nav_link(path: ['projects#index', 'root#index']) do + = link_to dashboard_projects_path, title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do Your Projects = nav_link(page: starred_dashboard_projects_path) do = link_to starred_dashboard_projects_path, title: 'Starred Projects', data: {placement: 'right'} do diff --git a/app/views/dashboard/_snippets_head.html.haml b/app/views/dashboard/_snippets_head.html.haml new file mode 100644 index 00000000000..0ae62d6f1b6 --- /dev/null +++ b/app/views/dashboard/_snippets_head.html.haml @@ -0,0 +1,7 @@ +%ul.center-top-menu + = nav_link(page: dashboard_snippets_path, html_options: {class: 'home'}) do + = link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do + Your Snippets + = nav_link(page: explore_snippets_path) do + = link_to explore_snippets_path, title: 'Explore snippets', data: {placement: 'right'} do + Explore Snippets diff --git a/app/views/dashboard/activity.html.haml b/app/views/dashboard/activity.html.haml index 3e24338af64..aa57df14c23 100644 --- a/app/views/dashboard/activity.html.haml +++ b/app/views/dashboard/activity.html.haml @@ -1,8 +1,10 @@ = content_for :meta_tags do - if current_user - = auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity") + = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity") +- page_title "Activity" - header_title "Activity", activity_dashboard_path + = render 'dashboard/activity_head' %section.activities diff --git a/app/views/dashboard/_projects.html.haml b/app/views/dashboard/projects/_projects.html.haml similarity index 100% rename from app/views/dashboard/_projects.html.haml rename to app/views/dashboard/projects/_projects.html.haml diff --git a/app/views/dashboard/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml similarity index 100% rename from app/views/dashboard/_zero_authorized_projects.html.haml rename to app/views/dashboard/projects/_zero_authorized_projects.html.haml diff --git a/app/views/dashboard/show.atom.builder b/app/views/dashboard/projects/index.atom.builder similarity index 52% rename from app/views/dashboard/show.atom.builder rename to app/views/dashboard/projects/index.atom.builder index e9a612231d5..d2c51486841 100644 --- a/app/views/dashboard/show.atom.builder +++ b/app/views/dashboard/projects/index.atom.builder @@ -1,9 +1,9 @@ xml.instruct! xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do xml.title "Activity" - xml.link href: dashboard_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" - xml.link href: dashboard_url, rel: "alternate", type: "text/html" - xml.id dashboard_url + xml.link href: dashboard_projects_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml" + xml.link href: dashboard_projects_url, rel: "alternate", type: "text/html" + xml.id dashboard_projects_url xml.updated @events.maximum(:updated_at).strftime("%Y-%m-%dT%H:%M:%SZ") if @events.any? @events.each do |event| diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/projects/index.html.haml similarity index 53% rename from app/views/dashboard/show.html.haml rename to app/views/dashboard/projects/index.html.haml index 1d5324e0d72..7a16b811f6b 100644 --- a/app/views/dashboard/show.html.haml +++ b/app/views/dashboard/projects/index.html.haml @@ -1,8 +1,10 @@ = content_for :meta_tags do - if current_user - = auto_discovery_link_tag(:atom, dashboard_url(format: :atom, private_token: current_user.private_token), title: "All activity") + = auto_discovery_link_tag(:atom, dashboard_projects_url(format: :atom, private_token: current_user.private_token), title: "All activity") + +- page_title "Projects" +- header_title "Projects", root_path -- header_title "Projects", (current_user ? root_path : explore_root_path) = render 'dashboard/projects_head' - if @last_push diff --git a/app/views/dashboard/projects/starred.html.haml b/app/views/dashboard/projects/starred.html.haml index 2fd7a1cf16c..339362701d4 100644 --- a/app/views/dashboard/projects/starred.html.haml +++ b/app/views/dashboard/projects/starred.html.haml @@ -1,9 +1,10 @@ - page_title "Starred Projects" -- header_title "Projects", (current_user ? root_path : explore_root_path) +- header_title "Projects", projects_path + = render 'dashboard/projects_head' - if @projects.any? - = render 'dashboard/projects' + = render 'projects' - else %h3 You don't have starred projects yet %p.slead Visit project page and press on star icon and it will appear on this page. diff --git a/app/views/dashboard/snippets/index.html.haml b/app/views/dashboard/snippets/index.html.haml new file mode 100644 index 00000000000..d3908062f43 --- /dev/null +++ b/app/views/dashboard/snippets/index.html.haml @@ -0,0 +1,38 @@ +- page_title "Snippets" +- header_title "Snippets", dashboard_snippets_path + += render 'dashboard/snippets_head' + +.gray-content-block + .pull-right + = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do + Add new snippet + + .oneline + Share code pastes with others out of git repository + +%ul.nav.nav-tabs.prepend-top-20 + = nav_tab :scope, nil do + = link_to dashboard_snippets_path do + All + %span.badge + = current_user.snippets.count + = nav_tab :scope, 'are_private' do + = link_to dashboard_snippets_path(scope: 'are_private') do + Private + %span.badge + = current_user.snippets.are_private.count + = nav_tab :scope, 'are_internal' do + = link_to dashboard_snippets_path(scope: 'are_internal') do + Internal + %span.badge + = current_user.snippets.are_internal.count + = nav_tab :scope, 'are_public' do + = link_to dashboard_snippets_path(scope: 'are_public') do + Public + %span.badge + = current_user.snippets.are_public.count + +.my-snippets + = render 'snippets/snippets' + diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml index 6a0c6cba41b..ffc37ad6178 100644 --- a/app/views/events/_event_last_push.html.haml +++ b/app/views/events/_event_last_push.html.haml @@ -1,14 +1,14 @@ - if show_last_push_widget?(event) - .event-last-push - .event-last-push-text - %span You pushed to - = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do - %strong= event.ref_name - %span at - %strong= link_to_project event.project - #{time_ago_with_tooltip(event.created_at)} + .gray-content-block.clear-block + .event-last-push + .event-last-push-text + %span You pushed to + = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do + %strong= event.ref_name + %span at + %strong= link_to_project event.project + #{time_ago_with_tooltip(event.created_at)} - .pull-right - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do - Create Merge Request - %hr + .pull-right + = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do + Create Merge Request diff --git a/app/views/explore/_head.html.haml b/app/views/explore/_head.html.haml new file mode 100644 index 00000000000..d8a57560788 --- /dev/null +++ b/app/views/explore/_head.html.haml @@ -0,0 +1,6 @@ +.explore-title + %h3 + Explore GitLab + %p.lead + Discover projects, groups and snippets. Share your projects with others + %br diff --git a/app/views/explore/groups/index.html.haml b/app/views/explore/groups/index.html.haml index e8a6752de8c..83d4d321c83 100644 --- a/app/views/explore/groups/index.html.haml +++ b/app/views/explore/groups/index.html.haml @@ -1,7 +1,11 @@ -- page_title "Groups" -- header_title "Groups", (current_user ? dashboard_groups_path : explore_groups_path) +- page_title "Groups" +- header_title "Groups", dashboard_groups_path + - if current_user = render 'dashboard/groups_head' +- else + = render 'explore/head' + .gray-content-block.clearfix .pull-left = form_tag explore_groups_path, method: :get, class: 'form-inline form-tiny' do |f| diff --git a/app/views/explore/projects/index.html.haml b/app/views/explore/projects/index.html.haml index 9df5b3830a8..67e38ca3127 100644 --- a/app/views/explore/projects/index.html.haml +++ b/app/views/explore/projects/index.html.haml @@ -1,6 +1,11 @@ -- page_title "Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' +- else + = render 'explore/head' + .gray-content-block.clearfix = render 'filter' = render 'projects', projects: @projects diff --git a/app/views/explore/projects/starred.html.haml b/app/views/explore/projects/starred.html.haml index a9df32f3d7d..596cb0a96cd 100644 --- a/app/views/explore/projects/starred.html.haml +++ b/app/views/explore/projects/starred.html.haml @@ -1,6 +1,10 @@ -- page_title "Starred Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' +- else + = render 'explore/head' .explore-trending-block .gray-content-block diff --git a/app/views/explore/projects/trending.html.haml b/app/views/explore/projects/trending.html.haml index c1ef06f6cdb..5ea6d81c5b9 100644 --- a/app/views/explore/projects/trending.html.haml +++ b/app/views/explore/projects/trending.html.haml @@ -1,13 +1,11 @@ -- page_title "Trending Projects" +- page_title "Projects" +- header_title "Projects", root_path + - if current_user = render 'dashboard/projects_head' - else - .explore-title - %h3 - Explore GitLab - %p.lead - Discover projects and groups. Share your projects with others - %br + = render 'explore/head' + .explore-trending-block .gray-content-block .pull-right diff --git a/app/views/explore/snippets/index.html.haml b/app/views/explore/snippets/index.html.haml new file mode 100644 index 00000000000..7e4fa7d4873 --- /dev/null +++ b/app/views/explore/snippets/index.html.haml @@ -0,0 +1,18 @@ +- page_title "Snippets" +- header_title "Snippets", snippets_path + +- if current_user + = render 'dashboard/snippets_head' +- else + = render 'explore/head' + +.gray-content-block + - if current_user + .pull-right + = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do + Add new snippet + + .oneline + Public snippets created by you and other users are listed here + += render 'snippets/snippets' diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index ac7d9ba0f4f..ae8fc9f85f0 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,4 +1,6 @@ +- header_title group_title(@group, "Settings", edit_group_path(@group)) - @blank_container = true + .panel.panel-default .panel-heading %strong= @group.name diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index d06cfa7ff9f..f1d507a50c7 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -1,4 +1,6 @@ - page_title "Projects" +- header_title group_title(@group, "Projects", projects_group_path(@group)) + .panel.panel-default .panel-heading %strong= @group.name diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 0577f4ec142..a9ba9d2ba10 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,3 +1,6 @@ +- unless can?(current_user, :read_group, @group) + - @disable_search_panel = true + = content_for :meta_tags do - if current_user = auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity") @@ -16,22 +19,25 @@ = render 'shared/show_aside' - .row - %section.activities.col-md-7 - .hidden-xs - - if current_user - = render "events/event_last_push", event: @last_push - + - if can?(current_user, :read_group, @group) + .row + %section.activities.col-md-7 + .hidden-xs - if current_user + = render "events/event_last_push", event: @last_push + %ul.nav.nav-pills.event_filter.pull-right %li = link_to group_path(@group, { format: :atom, private_token: current_user.private_token }), title: "Feed", class: 'rss-btn' do %i.fa.fa-rss - = render 'shared/event_filter' - %hr + = render 'shared/event_filter' + %hr - .content_list - = spinner - %aside.side.col-md-5 - = render "projects", projects: @projects + .content_list + = spinner + %aside.side.col-md-5 + = render "projects", projects: @projects + - else + %p + This group does not have public projects diff --git a/app/views/help/show.html.haml b/app/views/help/show.html.haml index 8551496b98a..0398afb4c1d 100644 --- a/app/views/help/show.html.haml +++ b/app/views/help/show.html.haml @@ -1,3 +1,3 @@ - page_title @file.humanize, *@category.split("/").reverse.map(&:humanize) .documentation.wiki - = markdown @markdown.gsub('$your_email', current_user.email) + = markdown @markdown.gsub('$your_email', current_user.try(:email) || "email@example.com") diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml index 707905ee92a..2468687b56d 100644 --- a/app/views/layouts/_page.html.haml +++ b/app/views/layouts/_page.html.haml @@ -6,10 +6,14 @@ = brand_header_logo .gitlab-text-container %h3 GitLab + - if defined?(sidebar) && sidebar = render "layouts/nav/#{sidebar}" - elsif current_user = render 'layouts/nav/dashboard' + - else + = render 'layouts/nav/explore' + .collapse-nav = render partial: 'layouts/collapse_button' - if current_user diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml index 1987bf1592a..95e077c339f 100644 --- a/app/views/layouts/devise.html.haml +++ b/app/views/layouts/devise.html.haml @@ -31,5 +31,5 @@ .container .footer-links = link_to "Explore", explore_root_path - = link_to "Documentation", "http://doc.gitlab.com/" + = link_to "Help", help_path = link_to "About GitLab", "https://about.gitlab.com/" diff --git a/app/views/layouts/explore.html.haml b/app/views/layouts/explore.html.haml index 9098554e6f0..df65792be73 100644 --- a/app/views/layouts/explore.html.haml +++ b/app/views/layouts/explore.html.haml @@ -1,9 +1,5 @@ - page_title "Explore" -- if current_user - - unless @header_title - - header_title "Projects", (current_user ? root_path : explore_root_path) -- else +- unless current_user - header_title "Explore GitLab", explore_root_path -- sidebar "dashboard" = render template: "layouts/application" diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 3892f71c0e3..c31b1cbe9a8 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -7,8 +7,9 @@ .navbar-collapse.collapse %ul.nav.navbar-nav.pull-right - %li.hidden-sm.hidden-xs - = render 'layouts/search' + - unless @disable_search_panel + %li.hidden-sm.hidden-xs + = render 'layouts/search' %li.visible-sm.visible-xs = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom'} do = icon('search') diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml index 7d3764a76a3..c3b07200621 100644 --- a/app/views/layouts/nav/_dashboard.html.haml +++ b/app/views/layouts/nav/_dashboard.html.haml @@ -1,31 +1,30 @@ %ul.nav.nav-sidebar - = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do - = link_to (current_user ? root_path : explore_root_path), title: 'Home', class: 'shortcuts-activity', data: {placement: 'right'} do + = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do + = link_to root_path, title: 'Projects', data: {placement: 'right'} do = icon('home fw') %span Projects = nav_link(path: 'dashboard#activity') do - = link_to activity_dashboard_path, title: 'Activity', data: {placement: 'right'} do + = link_to activity_dashboard_path, class: 'shortcuts-activity', title: 'Activity', data: {placement: 'right'} do = icon('dashboard fw') %span Activity = nav_link(controller: :groups) do - = link_to (current_user ? dashboard_groups_path : explore_groups_path), title: 'Groups', data: {placement: 'right'} do + = link_to dashboard_groups_path, title: 'Groups', data: {placement: 'right'} do = icon('group fw') %span Groups - - if current_user - = nav_link(controller: :milestones) do - = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do - = icon('clock-o fw') - %span - Milestones - = nav_link(path: 'dashboard#issues') do - = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do - = icon('exclamation-circle fw') - %span - Issues - %span.count= current_user.assigned_issues.opened.count + = nav_link(controller: :milestones) do + = link_to dashboard_milestones_path, title: 'Milestones', data: {placement: 'right'} do + = icon('clock-o fw') + %span + Milestones + = nav_link(path: 'dashboard#issues') do + = link_to assigned_issues_dashboard_path, title: 'Issues', class: 'shortcuts-issues', data: {placement: 'right'} do + = icon('exclamation-circle fw') + %span + Issues + %span.count= current_user.assigned_issues.opened.count = nav_link(path: 'dashboard#merge_requests') do = link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'shortcuts-merge_requests', data: {placement: 'right'} do = icon('tasks fw') @@ -33,7 +32,7 @@ Merge Requests %span.count= current_user.assigned_merge_requests.opened.count = nav_link(controller: :snippets) do - = link_to (current_user ? user_snippets_path(current_user) : snippets_path), title: 'Your snippets', data: {placement: 'right'} do + = link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do = icon('clipboard fw') %span Snippets @@ -42,10 +41,8 @@ = icon('question-circle fw') %span Help - - if current_user - %li.separate-item - = nav_link(controller: :profile) do - = link_to profile_path, title: 'Profile settings', data: {toggle: 'tooltip', placement: 'bottom'} do - = icon('user fw') - %span - Profile Settings + = nav_link(controller: :profile) do + = link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do + = icon('user fw') + %span + Profile Settings diff --git a/app/views/layouts/nav/_explore.html.haml b/app/views/layouts/nav/_explore.html.haml new file mode 100644 index 00000000000..21e565972a7 --- /dev/null +++ b/app/views/layouts/nav/_explore.html.haml @@ -0,0 +1,21 @@ +%ul.nav.nav-sidebar + = nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do + = link_to explore_root_path, title: 'Projects', data: {placement: 'right'} do + = icon('home fw') + %span + Projects + = nav_link(controller: :groups) do + = link_to explore_groups_path, title: 'Groups', data: {placement: 'right'} do + = icon('group fw') + %span + Groups + = nav_link(controller: :snippets) do + = link_to explore_snippets_path, title: 'Snippets', data: {placement: 'right'} do + = icon('clipboard fw') + %span + Snippets + = nav_link(controller: :help) do + = link_to help_path, title: 'Help', data: {placement: 'right'} do + = icon('question-circle fw') + %span + Help diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml index 695ce68a201..eb35af22b93 100644 --- a/app/views/layouts/nav/_group.html.haml +++ b/app/views/layouts/nav/_group.html.haml @@ -3,7 +3,7 @@ = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item @@ -12,34 +12,35 @@ = icon('dashboard fw') %span Group - - if current_user - = nav_link(controller: [:group, :milestones]) do - = link_to group_milestones_path(@group), title: 'Milestones', data: {placement: 'right'} do - = icon('clock-o fw') + - if can?(current_user, :read_group, @group) + - if current_user + = nav_link(controller: [:group, :milestones]) do + = link_to group_milestones_path(@group), title: 'Milestones', data: {placement: 'right'} do + = icon('clock-o fw') + %span + Milestones + = nav_link(path: 'groups#issues') do + = link_to issues_group_path(@group), title: 'Issues', data: {placement: 'right'} do + = icon('exclamation-circle fw') %span - Milestones - = nav_link(path: 'groups#issues') do - = link_to issues_group_path(@group), title: 'Issues', data: {placement: 'right'} do - = icon('exclamation-circle fw') - %span - Issues - - if current_user - %span.count= Issue.opened.of_group(@group).count - = nav_link(path: 'groups#merge_requests') do - = link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do - = icon('tasks fw') - %span - Merge Requests - - if current_user - %span.count= MergeRequest.opened.of_group(@group).count - = nav_link(controller: [:group_members]) do - = link_to group_group_members_path(@group), title: 'Members', data: {placement: 'right'} do - = icon('users fw') - %span - Members - - if can?(current_user, :admin_group, @group) - = nav_link(html_options: { class: "separate-item" }) do - = link_to edit_group_path(@group), title: 'Settings', data: {placement: 'right'} do - = icon ('cogs fw') + Issues + - if current_user + %span.count= Issue.opened.of_group(@group).count + = nav_link(path: 'groups#merge_requests') do + = link_to merge_requests_group_path(@group), title: 'Merge Requests', data: {placement: 'right'} do + = icon('tasks fw') %span - Settings + Merge Requests + - if current_user + %span.count= MergeRequest.opened.of_group(@group).count + = nav_link(controller: [:group_members]) do + = link_to group_group_members_path(@group), title: 'Members', data: {placement: 'right'} do + = icon('users fw') + %span + Members + - if can?(current_user, :admin_group, @group) + = nav_link(html_options: { class: "separate-item" }) do + = link_to edit_group_path(@group), title: 'Settings', data: {placement: 'right'} do + = icon ('cogs fw') + %span + Settings diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index abdb7544651..5a47b8e6db2 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -3,7 +3,7 @@ = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index 5e7b902622b..8ce46d4865b 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -4,13 +4,13 @@ = link_to group_path(@project.group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Group + Back to group - else = nav_link do = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = icon('caret-square-o-left fw') %span - Back to Dashboard + Back to dashboard %li.separate-item @@ -26,28 +26,28 @@ Activity - if project_nav_tab? :files = nav_link(controller: %w(tree blob blame edit_tree new_tree)) do - = link_to namespace_project_tree_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Files', class: 'shortcuts-tree', data: {placement: 'right'} do + = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree', data: {placement: 'right'} do = icon('files-o fw') %span Files - if project_nav_tab? :commits = nav_link(controller: %w(commit commits compare repositories tags branches)) do - = link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do + = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do = icon('history fw') %span Commits - if project_nav_tab? :network = nav_link(controller: %w(network)) do - = link_to namespace_project_network_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do + = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do = icon('code-fork fw') %span Network - if project_nav_tab? :graphs = nav_link(controller: %w(graphs)) do - = link_to namespace_project_graph_path(@project.namespace, @project, @ref || @repository.root_ref), title: 'Graphs', class: 'shortcuts-graphs', data: {placement: 'right'} do + = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs', data: {placement: 'right'} do = icon('area-chart fw') %span Graphs diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml index 44afa33dfe5..5c4dd67f0ec 100644 --- a/app/views/layouts/project.html.haml +++ b/app/views/layouts/project.html.haml @@ -1,5 +1,5 @@ - page_title @project.name_with_namespace -- header_title project_title(@project) +- header_title detect_project_title(@project) - sidebar "project" unless sidebar - content_for :scripts_body_top do diff --git a/app/views/layouts/snippets.html.haml b/app/views/layouts/snippets.html.haml index d9c90d4fcef..02ca3ee7a28 100644 --- a/app/views/layouts/snippets.html.haml +++ b/app/views/layouts/snippets.html.haml @@ -1,8 +1,3 @@ -- page_title 'Snippets' -- if current_user - - header_title "Snippets", user_snippets_path(current_user) -- else - - header_title 'Snippets', snippets_path -- sidebar "dashboard" +- header_title "Snippets", snippets_path = render template: "layouts/application" diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml index 30622d8a910..f0a3e416db7 100644 --- a/app/views/projects/_last_push.html.haml +++ b/app/views/projects/_last_push.html.haml @@ -1,14 +1,15 @@ - if event = last_push_event - if show_last_push_widget?(event) - .hidden-xs.center - .slead - %span You pushed to - = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do - %strong= event.ref_name - branch - #{time_ago_with_tooltip(event.created_at)} - %div - = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do - Create Merge Request - %hr + .gray-content-block.top-block.clear-block.hidden-xs + .event-last-push + .event-last-push-text + %span You pushed to + = link_to namespace_project_commits_path(event.project.namespace, event.project, event.ref_name) do + %strong= event.ref_name + branch + #{time_ago_with_tooltip(event.created_at)} + + .pull-right + = link_to new_mr_path_from_push_event(event), title: "New Merge Request", class: "btn btn-info btn-sm" do + Create Merge Request diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml index 65674913bb0..5f6e5f3b644 100644 --- a/app/views/projects/activity.html.haml +++ b/app/views/projects/activity.html.haml @@ -1 +1,2 @@ +- page_title "Activity" = render 'projects/activity' diff --git a/app/views/projects/blob/_actions.html.haml b/app/views/projects/blob/_actions.html.haml index 13f8271b979..5b61846fe6d 100644 --- a/app/views/projects/blob/_actions.html.haml +++ b/app/views/projects/blob/_actions.html.haml @@ -17,6 +17,6 @@ tree_join(@commit.sha, @path)), class: 'btn btn-sm' - if allowed_tree_edit? - = button_tag class: 'remove-blob btn btn-sm btn-remove', - 'data-toggle' => 'modal', 'data-target' => '#modal-remove-blob' do - Remove + .btn-group{:role => "group"} + %button.btn.btn-default{class: 'btn-primary', href: '#modal-replace-blob', 'data-target' => '#modal-replace-blob', 'data-toggle' => 'modal'} Replace + %button.btn.btn-default{class: 'btn-remove', href: '#modal-remove-blob', 'data-target' => '#modal-remove-blob', 'data-toggle' => 'modal'} Remove diff --git a/app/views/projects/blob/_replace.html.haml b/app/views/projects/blob/_replace.html.haml new file mode 100644 index 00000000000..84abf0303d0 --- /dev/null +++ b/app/views/projects/blob/_replace.html.haml @@ -0,0 +1,28 @@ +#modal-replace-blob.modal + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3.page-title Replace #{@blob.name} + %p.light + From branch + %strong= @ref + .modal-body + = form_tag namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'blob-file-upload-form-js form-horizontal' do + .dropzone + .dropzone-previews{class: "blob-upload-dropzone-previews"} + %p.dz-message{class: "hint"}< + Attach files by dragging & dropping or  + %a{href: '#', class: "markdown-selector"}>click to upload + %br + .dropzone-alerts{class: "alert alert-danger data", "data-dismiss" => "alert", style: "display:none"} + = render 'shared/commit_message_container', params: params, + placeholder: 'Replace this file because...' + .form-group + .col-sm-offset-2.col-sm-10 + = button_tag 'Replace file', class: 'btn btn-small btn-primary btn-replace-file', id: 'submit-all' + = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" + +:coffeescript + disableButtonIfEmptyField $('.blob-file-upload-form-js').find('#commit_message'), '.btn-replace-file' + new BlobFileDropzone($('.blob-file-upload-form-js'), 'put') diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml new file mode 100644 index 00000000000..5a6a3358a17 --- /dev/null +++ b/app/views/projects/blob/_upload.html.haml @@ -0,0 +1,28 @@ +#modal-upload-blob.modal + .modal-dialog + .modal-content + .modal-header + %a.close{href: "#", "data-dismiss" => "modal"} × + %h3.page-title Upload + %p.light + From branch + %strong= @ref + .modal-body + = form_tag namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'blob-file-upload-form-js form-horizontal' do + .dropzone + .dropzone-previews{class: "blob-upload-dropzone-previews"} + %p.dz-message{class: "hint"}< + Attach files by dragging & dropping or  + %a{href: '#', class: "markdown-selector"}>click to upload + %br + .dropzone-alerts{class: "alert alert-danger data", "data-dismiss" => "alert", style: "display:none"} + = render 'shared/commit_message_container', params: params, + placeholder: 'Upload this file because...' + .form-group + .col-sm-offset-2.col-sm-10 + = button_tag 'Upload file', class: 'btn btn-small btn-primary btn-upload-file', id: 'submit-all' + = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" + +:coffeescript + disableButtonIfEmptyField $('.blob-file-upload-form-js').find('#commit_message'), '.btn-upload-file' + new BlobFileDropzone($('.blob-file-upload-form-js'), 'post') diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml index a12cd660fc1..648f15418e0 100644 --- a/app/views/projects/blob/edit.html.haml +++ b/app/views/projects/blob/edit.html.haml @@ -1,6 +1,6 @@ - page_title "Edit", @blob.path, @ref .file-editor - %ul.nav.nav-tabs.js-edit-mode + %ul.center-top-menu.no-bottom.js-edit-mode %li.active = link_to '#editor' do %i.fa.fa-edit diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml index 7c2a4fece94..6fb46ea2040 100644 --- a/app/views/projects/blob/new.html.haml +++ b/app/views/projects/blob/new.html.haml @@ -1,5 +1,11 @@ -- page_title "New File", @ref -%h3.page-title New file +%h3.page-title< + Create new file or  + %a.upload-link{href: '#modal-upload-blob', 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal'}>upload existing one + +.file-title + = render 'projects/blob/upload' + %br + .file-editor = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file js-requires-input') do = render 'projects/blob/editor', ref: @ref diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml index bd2fc43633c..19e876ec34c 100644 --- a/app/views/projects/blob/show.html.haml +++ b/app/views/projects/blob/show.html.haml @@ -10,3 +10,4 @@ - if allowed_tree_edit? = render 'projects/blob/remove' + = render 'projects/blob/replace' diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml index 50c0fd6803d..a849bf84698 100644 --- a/app/views/projects/commits/_head.html.haml +++ b/app/views/projects/commits/_head.html.haml @@ -1,10 +1,10 @@ %ul.center-top-menu = nav_link(controller: [:commit, :commits]) do - = link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do + = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do Commits %span.badge= number_with_delimiter(@repository.commit_count) = nav_link(controller: :compare) do - = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: @ref || @repository.root_ref) do + = link_to namespace_project_compare_index_path(@project.namespace, @project, from: @repository.root_ref, to: current_ref) do Compare = nav_link(html_options: {class: branches_tab_class}) do diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index 798f1c47da5..185ebf23934 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -4,7 +4,7 @@ = render "home_panel" -.center.light-well +.gray-content-block.center %h3.page-title The repository for this project is empty %p diff --git a/app/views/projects/imports/show.html.haml b/app/views/projects/imports/show.html.haml index 39fe0fc1c4f..06886d215a3 100644 --- a/app/views/projects/imports/show.html.haml +++ b/app/views/projects/imports/show.html.haml @@ -3,8 +3,12 @@ .center %h2 %i.fa.fa-spinner.fa-spin - Import in progress. - %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)} + - if @project.forked? + Forking in progress. + - else + Import in progress. + - unless @project.forked? + %p.monospace git clone --bare #{hidden_pass_url(@project.import_url)} %p Please wait while we import the repository for you. Refresh at will. :javascript new ProjectImport(); diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml index d44fe486212..284adb40e97 100644 --- a/app/views/projects/labels/index.html.haml +++ b/app/views/projects/labels/index.html.haml @@ -1,14 +1,15 @@ - page_title "Labels" -- if can? current_user, :admin_label, @project - = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do - New label -%h3.page-title - Labels -%hr + +.gray-content-block.top-block + - if can? current_user, :admin_label, @project + = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do + New label + .oneline + Labels can be applied to issues and merge requests. .labels - if @labels.present? - %ul.bordered-list.manage-labels-list + %ul.content-list.manage-labels-list = render @labels = paginate @labels, theme: 'gitlab' - else diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 162583e4b1d..a40d1513671 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -1,30 +1,28 @@ - page_title "Members" -%h3.page-title - Users with access to this project -%p.light +.gray-content-block.top-block + .clearfix.js-toggle-container + = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do + .form-group + = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' } + = button_tag 'Search', class: 'btn' + + - if can?(current_user, :admin_project_member, @project) + %span.pull-right + = button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do + Add members + %i.fa.fa-chevron-down + = link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do + Import members + + .js-toggle-content.hide.new-group-member-holder + = render "new_project_member" + +%p.prepend-top-default.light + Users with access to this project are listed below. Read more about project permissions %strong= link_to "here", help_page_path("permissions", "permissions"), class: "vlink" -%hr - -.clearfix.js-toggle-container - = form_tag namespace_project_project_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do - .form-group - = search_field_tag :search, params[:search], { placeholder: 'Find existing member by name', class: 'form-control search-text-input' } - = button_tag 'Search', class: 'btn' - - - if can?(current_user, :admin_project_member, @project) - %span.pull-right - = button_tag class: 'btn btn-new btn-grouped js-toggle-button', type: 'button' do - Add members - %i.fa.fa-chevron-down - = link_to import_namespace_project_project_members_path(@project.namespace, @project), class: "btn btn-grouped", title: "Import members from another project" do - Import members - - .js-toggle-content.hide.new-group-member-holder - = render "new_project_member" - = render "team", members: @project_members - if @group diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d5c4ee71978..aa5914e3ed9 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -14,7 +14,7 @@ .project-stats.gray-content-block %ul.nav.nav-pills %li - = link_to namespace_project_commits_path(@project.namespace, @project, @ref || @repository.root_ref) do + = link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do = pluralize(number_with_delimiter(@project.commit_count), 'commit') %li = link_to namespace_project_branches_path(@project.namespace, @project) do diff --git a/app/views/snippets/_head.html.haml b/app/views/snippets/_head.html.haml deleted file mode 100644 index 0adf6b91f2c..00000000000 --- a/app/views/snippets/_head.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -%ul.center-top-menu - = nav_link(page: user_snippets_path(current_user), html_options: {class: 'home'}) do - = link_to user_snippets_path(current_user), title: 'Your snippets', data: {placement: 'right'} do - Your Snippets - = nav_link(page: snippets_path) do - = link_to snippets_path, title: 'Explore snippets', data: {placement: 'right'} do - Explore Snippets diff --git a/app/views/snippets/current_user_index.html.haml b/app/views/snippets/current_user_index.html.haml deleted file mode 100644 index d704407c4dd..00000000000 --- a/app/views/snippets/current_user_index.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -- page_title "Your Snippets" -= render 'head' - -.gray-content-block - .pull-right - = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do - Add new snippet - - .oneline - Share code pastes with others out of git repository - -%ul.nav.nav-tabs.prepend-top-20 - = nav_tab :scope, nil do - = link_to user_snippets_path(@user) do - All - %span.badge - = @user.snippets.count - = nav_tab :scope, 'are_private' do - = link_to user_snippets_path(@user, scope: 'are_private') do - Private - %span.badge - = @user.snippets.are_private.count - = nav_tab :scope, 'are_internal' do - = link_to user_snippets_path(@user, scope: 'are_internal') do - Internal - %span.badge - = @user.snippets.are_internal.count - = nav_tab :scope, 'are_public' do - = link_to user_snippets_path(@user, scope: 'are_public') do - Public - %span.badge - = @user.snippets.are_public.count - -.my-snippets - = render 'snippets' - diff --git a/app/views/snippets/index.html.haml b/app/views/snippets/index.html.haml index 3b62dd2a6e1..7e4918a6085 100644 --- a/app/views/snippets/index.html.haml +++ b/app/views/snippets/index.html.haml @@ -1,15 +1,13 @@ -- page_title "Public Snippets" -- if current_user - = render 'head' +- page_title "By #{@user.name}", "Snippets" -.gray-content-block - - if current_user - .pull-right - = link_to new_snippet_path, class: "btn btn-new", title: "New Snippet" do - Add new snippet - - .oneline - Public snippets created by you and other users are listed here +%ol.breadcrumb + %li + = link_to snippets_path do + Snippets + %li + = @user.name + .pull-right.hidden-xs + = link_to user_path(@user) do + #{@user.name} profile page = render 'snippets' - diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index aed00f9caeb..97374e073dc 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -20,10 +20,10 @@ .back-link - if @snippet.author == current_user - = link_to user_snippets_path(current_user) do + = link_to dashboard_snippets_path do ← your snippets - else - = link_to snippets_path do + = link_to explore_snippets_path do ← explore snippets .file-holder diff --git a/app/views/snippets/user_index.html.haml b/app/views/snippets/user_index.html.haml deleted file mode 100644 index 7af5352da34..00000000000 --- a/app/views/snippets/user_index.html.haml +++ /dev/null @@ -1,13 +0,0 @@ -- page_title "Snippets", @user.name - -%ol.breadcrumb - %li - = link_to snippets_path do - Snippets - %li - = @user.name - .pull-right.hidden-xs - = link_to user_path(@user) do - #{@user.name} profile page - -= render 'snippets' diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index aa4e8722fb1..37d5dba0330 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -16,8 +16,8 @@ - if @user == current_user .pull-right.hidden-xs = link_to profile_path, class: 'btn btn-sm' do - %i.fa.fa-pencil-square-o - Edit Profile settings + = icon('user') + Profile settings - elsif current_user .pull-right %span.dropdown diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb new file mode 100644 index 00000000000..acd1c43f06b --- /dev/null +++ b/app/workers/repository_fork_worker.rb @@ -0,0 +1,34 @@ +class RepositoryForkWorker + include Sidekiq::Worker + include Gitlab::ShellAdapter + + sidekiq_options queue: :gitlab_shell + + def perform(project_id, source_path, target_path) + project = Project.find_by_id(project_id) + + unless project.present? + logger.error("Project #{project_id} no longer exists!") + return + end + + result = gitlab_shell.fork_repository(source_path, target_path) + + unless result + logger.error("Unable to fork project #{project_id} for repository #{source_path} -> #{target_path}") + project.import_fail + project.save + return + end + + if project.valid_repo? + ProjectCacheWorker.perform_async(project.id) + project.import_finish + else + project.import_fail + logger.error("Project #{id} had an invalid repository after fork") + end + + project.save + end +end diff --git a/config/routes.rb b/config/routes.rb index d484db559df..41970d2af8a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -242,6 +242,7 @@ Gitlab::Application.routes.draw do end resources :groups, only: [:index] + resources :snippets, only: [:index] root to: 'projects#trending' end @@ -362,24 +363,25 @@ Gitlab::Application.routes.draw do # # Dashboard Area # - resource :dashboard, controller: 'dashboard', only: [:show] do - member do - get :issues - get :merge_requests - get :activity - end + resource :dashboard, controller: 'dashboard', only: [] do + get :issues + get :merge_requests + get :activity scope module: :dashboard do resources :milestones, only: [:index, :show] resources :groups, only: [:index] + resources :snippets, only: [:index] - resources :projects, only: [] do + resources :projects, only: [:index] do collection do get :starred end end end + + root to: "dashboard/projects#index" end # @@ -403,7 +405,7 @@ Gitlab::Application.routes.draw do end end - resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create] + resources :projects, constraints: { id: /[^\/]+/ }, only: [:index, :new, :create] devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords, sessions: :sessions, confirmations: :confirmations } @@ -411,7 +413,7 @@ Gitlab::Application.routes.draw do get '/users/auth/:provider/omniauth_error' => 'omniauth_callbacks#omniauth_error', as: :omniauth_error end - root to: "root#show" + root to: "root#index" # # Project Area @@ -455,6 +457,16 @@ Gitlab::Application.routes.draw do to: 'blob#destroy', constraints: { id: /.+/, format: false } ) + put( + '/blob/*id', + to: 'blob#update', + constraints: { id: /.+/, format: false } + ) + post( + '/blob/*id', + to: 'blob#create', + constraints: { id: /.+/, format: false } + ) end scope do diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md index 6a68c8e8286..4ff5e74d438 100644 --- a/doc/raketasks/backup_restore.md +++ b/doc/raketasks/backup_restore.md @@ -369,4 +369,7 @@ For more information see similar questions on postgresql issue tracker[here](htt ## Note This documentation is for GitLab CE. -We backup GitLab.com and make sure your data is secure, but you can't use these methods to export / backup your data yourself from GitLab.com. +We backup GitLab.com and make sure your data is secure, but you can't use these methods +to export / backup your data yourself from GitLab.com. + +Issues are stored in the database. They can't be stored in Git itself. diff --git a/doc/update/7.14-to-8.0.md b/doc/update/7.14-to-8.0.md index 29a38d07b3d..3ae0f9616ac 100644 --- a/doc/update/7.14-to-8.0.md +++ b/doc/update/7.14-to-8.0.md @@ -10,9 +10,9 @@ months after this vulnerability became known the GitLab installation guide still contained instructions that would install the outdated, 'vulnerable' Git version 2.1.2. -Run the following command to get your current Git version. +Run the following command to get your current Git version: -``` +```sh /usr/local/bin/git --version ``` @@ -63,39 +63,44 @@ sudo -u git -H git checkout 8-0-stable-ee ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v2.6.4 +sudo -u git -H git checkout v2.6.5 ``` ### 5. Install gitlab-git-http-server -First we download Go 1.5 and install it into /usr/local/go. +First we download Go 1.5 and install it into `/usr/local/go`: - curl -O --progress https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz - echo '5817fa4b2252afdb02e11e8b9dc1d9173ef3bd5a go1.5.linux-amd64.tar.gz' | shasum -c - && \ - sudo tar -C /usr/local -xzf go1.5.linux-amd64.tar.gz - sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ - rm go1.5.linux-amd64.tar.gz +```bash +curl -O --progress https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz +echo '5817fa4b2252afdb02e11e8b9dc1d9173ef3bd5a go1.5.linux-amd64.tar.gz' | shasum -c - && \ + sudo tar -C /usr/local -xzf go1.5.linux-amd64.tar.gz +sudo ln -sf /usr/local/go/bin/{go,godoc,gofmt} /usr/local/bin/ +rm go1.5.linux-amd64.tar.gz +``` -Now we download gitlab-git-http-server and install it in /home/git/gitlab-git-http-server. +Now we download `gitlab-git-http-server` and install it in `/home/git/gitlab-git-http-server`: - cd /home/git - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-git-http-server.git - cd gitlab-git-http-server - sudo -u git -H make +```bash +cd /home/git +sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-git-http-server.git +cd gitlab-git-http-server +sudo -u git -H make +``` -If you put your Git repositories in a directory different from /home/git/repositories, you need to tell gitlab-git-http-server about it via /etc/gitlab/default. -See lib/support/init.d/gitlab.default.example for the options. +If your Git repositories are in a directory other than `/home/git/repositories`, +you need to tell `gitlab-git-http-server` about it via `/etc/gitlab/default`. +See `lib/support/init.d/gitlab.default.example` for the options. ### 6. Install libs, migrations, etc. ```bash cd /home/git/gitlab -# MySQL installations (note: the line below states '--without ... postgres') -sudo -u git -H bundle install --without development test postgres --deployment +# MySQL installations (note: the line below states '--without postgres') +sudo -u git -H bundle install --without postgres development test --deployment -# PostgreSQL installations (note: the line below states '--without ... mysql') -sudo -u git -H bundle install --without development test mysql --deployment +# PostgreSQL installations (note: the line below states '--without mysql') +sudo -u git -H bundle install --without mysql development test --deployment # Run database migrations sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production @@ -111,20 +116,27 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab #### New configuration options for `gitlab.yml` -There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`. +There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`: -``` +```sh git diff origin/7-14-stable:config/gitlab.yml.example origin/8-0-stable:config/gitlab.yml.example -`````` - -#### New NGINX configuration - -Because of the new gitlab-git-http-server you need to update your NGINX configuration. -If you skip this step 'git clone' and 'git push' over HTTP(S) will stop working. - ``` -# Remove '-ssl' twice in the diff command below if you use HTTP instead of HTTPS + +#### New Nginx configuration + +Because of the new `gitlab-git-http-server` you need to update your Nginx +configuration. If you skip this step 'git clone' and 'git push' over HTTP(S) +will stop working. + +View changes between the previous recommended Nginx configuration and the +current one: + +```sh +# For HTTPS configurations git diff origin/7-14-stable:lib/support/nginx/gitlab-ssl origin/8-0-stable:lib/support/nginx/gitlab-ssl + +# For HTTP configurations +git diff origin/7-14-stable:lib/support/nginx/gitlab origin/8-0-stable:lib/support/nginx/gitlab ``` ### 8. Start application @@ -138,7 +150,7 @@ Check if GitLab and its environment are configured correctly: sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production -To make sure you didn't miss anything run a more thorough check with: +To make sure you didn't miss anything run a more thorough check: sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production @@ -147,13 +159,15 @@ If all items are green, then congratulations, the upgrade is complete! ## Things went south? Revert to previous version (7.14) ### 1. Revert the code to the previous version + Follow the [upgrade guide from 7.13 to 7.14](7.13-to-7.14.md), except for the database migration (The backup is already migrated to the previous version) -### 2. Restore from the backup: +### 2. Restore from the backup ```bash cd /home/git/gitlab sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production ``` -If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above. + +If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above. diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md index 22b9be059d6..a66a863f6c4 100644 --- a/doc/update/patch_versions.md +++ b/doc/update/patch_versions.md @@ -1,7 +1,7 @@ # Universal update guide for patch versions *Make sure you view this [upgrade guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/patch_versions.md) from the `master` branch for the most up to date instructions.* -For example from 6.2.0 to 6.2.1, also see the [semantic versioning specification](http://semver.org/). +For example from 7.14.0 to 7.14.3, also see the [semantic versioning specification](http://semver.org/). ### 0. Backup @@ -23,17 +23,16 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production cd /home/git/gitlab sudo -u git -H git fetch --all sudo -u git -H git checkout -- Gemfile.lock db/schema.rb -sudo -u git -H git checkout LATEST_TAG +LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) +sudo -u git -H git checkout $LATEST_TAG -b $LATEST_TAG ``` -Replace LATEST_TAG with the latest GitLab tag you want to upgrade to, for example `v6.6.3`. - ### 3. Update gitlab-shell to the corresponding version ```bash cd /home/git/gitlab-shell sudo -u git -H git fetch -sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` +sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -b v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` ``` ### 4. Install libs, migrations, etc. diff --git a/features/explore/groups.feature b/features/explore/groups.feature index c11634bd74a..a42e59c98f2 100644 --- a/features/explore/groups.feature +++ b/features/explore/groups.feature @@ -3,20 +3,6 @@ Feature: Explore Groups Background: Given group "TestGroup" has private project "Enterprise" - Scenario: I should not see group with private projects as visitor - When I visit group "TestGroup" page - Then I should be redirected to sign in page - - Scenario: I should not see group with private projects group as user - When I sign in as a user - And I visit group "TestGroup" page - Then page status code should be 404 - - Scenario: I should not see group with private and internal projects as visitor - Given group "TestGroup" has internal project "Internal" - When I visit group "TestGroup" page - Then I should be redirected to sign in page - Scenario: I should see group with private and internal projects as user Given group "TestGroup" has internal project "Internal" When I sign in as a user diff --git a/features/groups.feature b/features/groups.feature index d5272fdddcf..db37fa3b375 100644 --- a/features/groups.feature +++ b/features/groups.feature @@ -159,3 +159,14 @@ Feature: Groups When I visit group "Owned" projects page Then I should see group "Owned" projects list And I should see "archived" label + + # Public group + @javascript + Scenario: Signed out user should see group + Given "Mary Jane" is owner of group "Owned" + And I am a signed out user + And Group "Owned" has a public project "Public-project" + When I visit group "Owned" page + Then I should see group "Owned" + Then I should see project "Public-project" + diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature index d3a77466a35..b5b6abe6aff 100644 --- a/features/project/source/browse_files.feature +++ b/features/project/source/browse_files.feature @@ -33,6 +33,29 @@ Feature: Project Source Browse Files And I click on "Commit Changes" Then I am redirected to the new file And I should see its new content + + @javascript + Scenario: I can upload file and commit + Given I click on "new file" link in repo + Then I can see new file page + And I can see "upload existing one" + And I click on "upload existing one" + And I upload a new text file + And I fill the upload file commit message + And I click on "Upload file" + Then I can see the new text file + And I can see the new commit message + + @javascript + Scenario: I can replace file and commit + Given I click on ".gitignore" file in repo + And I see the ".gitignore" + And I click on "Replace" + And I replace it with a text file + And I fill the replace file commit message + And I click on "Replace file" + Then I can see the new text file + And I can see the replacement commit message @javascript Scenario: I can create and commit file and specify new branch diff --git a/features/steps/groups.rb b/features/steps/groups.rb index 18a1c4d32ce..95bc9baf8d8 100644 --- a/features/steps/groups.rb +++ b/features/steps/groups.rb @@ -6,7 +6,7 @@ class Spinach::Features::Groups < Spinach::FeatureSteps include Select2Helper step 'I should see back to dashboard button' do - expect(page).to have_content 'Back to Dashboard' + expect(page).to have_content 'Back to dashboard' end step 'gitlab user "Mike"' do @@ -17,6 +17,26 @@ class Spinach::Features::Groups < Spinach::FeatureSteps find(:css, 'button.btn-new').click end + step 'I should see group "Owned"' do + expect(page).to have_content '@owned' + end + + step 'I am a signed out user' do + logout + end + + step 'Group "Owned" has a public project "Public-project"' do + group = Group.find_by(name: "Owned") + + @project = create :empty_project, :public, + group: group, + name: "Public-project" + end + + step 'I should see project "Public-project"' do + expect(page).to have_content 'Public-project' + end + step 'I select "Mike" as "Reporter"' do user = User.find_by(name: "Mike") diff --git a/features/steps/invites.rb b/features/steps/invites.rb index 5e8feff5095..dac972172aa 100644 --- a/features/steps/invites.rb +++ b/features/steps/invites.rb @@ -63,7 +63,7 @@ class Spinach::Features::Invites < Spinach::FeatureSteps end step 'I should be redirected to the dashboard' do - expect(current_path).to eq(dashboard_path) + expect(current_path).to eq(dashboard_projects_path) end step 'I should see a notice telling me I have declined' do diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb index 0e433781d7a..370960845cc 100644 --- a/features/steps/project/fork.rb +++ b/features/steps/project/fork.rb @@ -15,7 +15,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps end step 'I should see the forked project page' do - expect(page).to have_content "Project was successfully forked." + expect(page).to have_content "Forked from" end step 'I already have a project named "Shop" in my namespace' do diff --git a/features/steps/project/project.rb b/features/steps/project/project.rb index 0404fd5e594..079a190e356 100644 --- a/features/steps/project/project.rb +++ b/features/steps/project/project.rb @@ -124,10 +124,10 @@ class Spinach::Features::Project < Spinach::FeatureSteps end step 'I should see back to dashboard button' do - expect(page).to have_content 'Back to Dashboard' + expect(page).to have_content 'Back to dashboard' end step 'I should see back to group button' do - expect(page).to have_content 'Back to Group' + expect(page).to have_content 'Back to group' end end diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb index 5cb085db207..7a0ee4df45e 100644 --- a/features/steps/project/source/browse_files.rb +++ b/features/steps/project/source/browse_files.rb @@ -1,3 +1,4 @@ +# coding: utf-8 class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps include SharedAuthentication include SharedProject @@ -78,7 +79,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I fill the commit message' do - fill_in :commit_message, with: 'Not yet a commit message.' + fill_in :commit_message, with: 'Not yet a commit message.', visible: true end step 'I click link "Diff"' do @@ -97,6 +98,14 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps click_button 'Remove file' end + step 'I click on "Replace"' do + click_button "Replace" + end + + step 'I click on "Replace file"' do + click_button 'Replace file' + end + step 'I see diff' do expect(page).to have_css '.line_holder.new' end @@ -106,10 +115,55 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps end step 'I can see new file page' do - expect(page).to have_content "New file" + expect(page).to have_content "new file" expect(page).to have_content "Commit message" end + step 'I can see "upload existing one"' do + expect(page).to have_content "upload existing one" + end + + step 'I click on "upload existing one"' do + click_link 'upload existing one' + end + + step 'I click on "Upload file"' do + click_button 'Upload file' + end + + step 'I can see the new commit message' do + expect(page).to have_content "New upload commit message" + end + + step 'I upload a new text file' do + drop_in_dropzone test_text_file + end + + step 'I fill the upload file commit message' do + page.within('#modal-upload-blob') do + fill_in :commit_message, with: 'New upload commit message' + end + end + + step 'I replace it with a text file' do + drop_in_dropzone test_text_file + end + + step 'I fill the replace file commit message' do + page.within('#modal-replace-blob') do + fill_in :commit_message, with: 'Replacement file commit message' + end + end + + step 'I can see the replacement commit message' do + expect(page).to have_content "Replacement file commit message" + end + + step 'I can see the new text file' do + expect(page).to have_content "Lorem ipsum dolor sit amet" + expect(page).to have_content "Sed ut perspiciatis unde omnis" + end + step 'I click on files directory' do click_link 'files' end @@ -232,4 +286,29 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps def new_file_name 'not_a_file.md' end + + def drop_in_dropzone(file_path) + # Generate a fake input selector + page.execute_script <<-JS + var fakeFileInput = window.$('').attr( + {id: 'fakeFileInput', type: 'file'} + ).appendTo('body'); + JS + # Attach the file to the fake input selector with Capybara + attach_file("fakeFileInput", file_path) + # Add the file to a fileList array and trigger the fake drop event + page.execute_script <<-JS + var fileList = [$('#fakeFileInput')[0].files[0]]; + var e = jQuery.Event('drop', { dataTransfer : { files : fileList } }); + $('.dropzone')[0].dropzone.listeners[0].events.drop(e); + JS + end + + def test_text_file + File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt') + end + + def test_image_file + File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif') + end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index b4deccb6520..eb978620da6 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -68,7 +68,7 @@ module SharedPaths # ---------------------------------------- step 'I visit dashboard page' do - visit dashboard_path + visit dashboard_projects_path end step 'I visit dashboard activity page' do @@ -460,7 +460,7 @@ module SharedPaths end step 'I visit snippets page' do - visit snippets_path + visit explore_snippets_path end step 'I visit new snippet page' do diff --git a/features/steps/snippets/user.rb b/features/steps/snippets/user.rb index 007fcb2893f..dea3256229f 100644 --- a/features/steps/snippets/user.rb +++ b/features/steps/snippets/user.rb @@ -4,7 +4,7 @@ class Spinach::Features::SnippetsUser < Spinach::FeatureSteps include SharedSnippet step 'I visit my snippets page' do - visit user_snippets_path(current_user) + visit dashboard_snippets_path end step 'I should see "Personal snippet one" in snippets' do diff --git a/spec/controllers/namespaces_controller_spec.rb b/spec/controllers/namespaces_controller_spec.rb index 9c8619722cd..77436958711 100644 --- a/spec/controllers/namespaces_controller_spec.rb +++ b/spec/controllers/namespaces_controller_spec.rb @@ -46,13 +46,11 @@ describe NamespacesController do context "when the project doesn't have public projects" do context "when not signed in" do - it "redirects to the sign in page" do + it "does not redirect to the sign in page" do get :show, id: group.path - - expect(response).to redirect_to(new_user_session_path) + expect(response).not_to redirect_to(new_user_session_path) end end - context "when signed in" do before do sign_in(user) @@ -86,10 +84,10 @@ describe NamespacesController do end context "when the user doesn't have access to the project" do - it "responds with status 404" do + it "redirects to the group's page" do get :show, id: group.path - expect(response.status).to eq(404) + expect(response).to redirect_to(group_path(group)) end end end diff --git a/spec/controllers/root_controller_spec.rb b/spec/controllers/root_controller_spec.rb index abbbf6855fc..64dfe8f34e3 100644 --- a/spec/controllers/root_controller_spec.rb +++ b/spec/controllers/root_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe RootController do - describe 'GET show' do + describe 'GET index' do context 'with a user' do let(:user) { create(:user) } @@ -16,15 +16,15 @@ describe RootController do end it 'redirects to their specified dashboard' do - get :show + get :index expect(response).to redirect_to starred_dashboard_projects_path end end context 'who uses the default dashboard setting' do it 'renders the default dashboard' do - get :show - expect(response).to render_template 'dashboard/show' + get :index + expect(response).to render_template 'dashboard/projects/index' end end end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 0f9780356b1..af5d043cf02 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -156,14 +156,6 @@ describe UploadsController do end context "when the project doesn't have public projects" do - context "when not signed in" do - it "redirects to the sign in page" do - get :show, model: "group", mounted_as: "avatar", id: group.id, filename: "image.png" - - expect(response).to redirect_to(new_user_session_path) - end - end - context "when signed in" do before do sign_in(user) diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index ad157d742ff..f81a3c117ff 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -6,7 +6,7 @@ describe "Dashboard Feed", feature: true do context "projects atom feed via private token" do it "should render projects atom feed" do - visit dashboard_path(:atom, private_token: user.private_token) + visit dashboard_projects_path(:atom, private_token: user.private_token) expect(body).to have_selector('feed title') end end @@ -20,7 +20,7 @@ describe "Dashboard Feed", feature: true do project.team << [user, :master] issue_event(issue, user) note_event(note, user) - visit dashboard_path(:atom, private_token: user.private_token) + visit dashboard_projects_path(:atom, private_token: user.private_token) end it "should have issue opened event" do diff --git a/spec/features/profiles/preferences_spec.rb b/spec/features/profiles/preferences_spec.rb index 9bc6145dda4..8f645438cff 100644 --- a/spec/features/profiles/preferences_spec.rb +++ b/spec/features/profiles/preferences_spec.rb @@ -70,7 +70,7 @@ describe 'Profile > Preferences', feature: true do expect(page.current_path).to eq starred_dashboard_projects_path click_link 'Your Projects' - expect(page.current_path).to eq dashboard_path + expect(page.current_path).to eq dashboard_projects_path end end diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb index c38cddbb904..788581a26cb 100644 --- a/spec/features/security/dashboard_access_spec.rb +++ b/spec/features/security/dashboard_access_spec.rb @@ -4,7 +4,7 @@ describe "Dashboard access", feature: true do include AccessMatchers describe "GET /dashboard" do - subject { dashboard_path } + subject { dashboard_projects_path } it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } @@ -40,7 +40,7 @@ describe "Dashboard access", feature: true do it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_allowed_for :visitor } end describe "GET /projects/new" do diff --git a/spec/features/security/group_access_spec.rb b/spec/features/security/group_access_spec.rb index 8ce15388605..4b78e3a61f0 100644 --- a/spec/features/security/group_access_spec.rb +++ b/spec/features/security/group_access_spec.rb @@ -68,7 +68,7 @@ describe 'Group access', feature: true do it { is_expected.to be_allowed_for group_member(:guest) } it { is_expected.to be_allowed_for :admin } it { is_expected.to be_allowed_for :user } - it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_allowed_for :visitor } end context 'with no projects' do @@ -77,8 +77,8 @@ describe 'Group access', feature: true do it { is_expected.to be_allowed_for group_member(:reporter) } it { is_expected.to be_allowed_for group_member(:guest) } it { is_expected.to be_allowed_for :admin } - it { is_expected.to be_denied_for :user } - it { is_expected.to be_denied_for :visitor } + it { is_expected.to be_allowed_for :user } + it { is_expected.to be_allowed_for :visitor } end end diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb index dd045826692..dfa18f69e05 100644 --- a/spec/routing/routing_spec.rb +++ b/spec/routing/routing_spec.rb @@ -206,7 +206,7 @@ end # dashboard_merge_requests GET /dashboard/merge_requests(.:format) dashboard#merge_requests describe DashboardController, "routing" do it "to #index" do - expect(get("/dashboard")).to route_to('dashboard#show') + expect(get("/dashboard")).to route_to('dashboard/projects#index') end it "to #issues" do @@ -220,8 +220,8 @@ end # root / root#show describe RootController, 'routing' do - it 'to #show' do - expect(get('/')).to route_to('root#show') + it 'to #index' do + expect(get('/')).to route_to('root#index') end end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index ff4ed2dd484..25277f07482 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -96,6 +96,17 @@ describe Projects::CreateService do expect(project.saved?).to be(true) end end + + context 'repository creation' do + it 'should synchronously create the repository' do + expect_any_instance_of(Project).to receive(:create_repository) + + project = create_project(@user, @opts) + expect(project).to be_valid + expect(project.owner).to eq(@user) + expect(project.namespace).to eq(@user.namespace) + end + end end def create_project(user, opts) diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index c04e842c67e..7c4bb74b77f 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -28,8 +28,7 @@ describe Projects::ForkService do context 'fork project failure' do it "fails due to transaction failure" do @to_project = fork_project(@from_project, @to_user, false) - expect(@to_project.errors).not_to be_empty - expect(@to_project.errors[:base]).to include("Failed to fork repository via gitlab-shell") + expect(@to_project.import_failed?) end end @@ -100,7 +99,7 @@ describe Projects::ForkService do end def fork_project(from_project, user, fork_success = true, params = {}) - allow_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(fork_success) + allow(RepositoryForkWorker).to receive(:perform_async).and_return(fork_success) Projects::ForkService.new(from_project, user, params).execute end end diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb new file mode 100644 index 00000000000..aa031106968 --- /dev/null +++ b/spec/workers/repository_fork_worker_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe RepositoryForkWorker do + let(:project) { create(:project) } + let(:fork_project) { create(:project, forked_from_project: project) } + + subject { RepositoryForkWorker.new } + + describe "#perform" do + it "creates a new repository from a fork" do + expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).with( + project.path_with_namespace, + fork_project.namespace.path). + and_return(true) + expect(ProjectCacheWorker).to receive(:perform_async) + + subject.perform(project.id, + project.path_with_namespace, + fork_project.namespace.path) + end + + it "handles bad fork" do + expect_any_instance_of(Gitlab::Shell).to receive(:fork_repository).and_return(false) + subject.perform(project.id, + project.path_with_namespace, + fork_project.namespace.path) + end + end +end