Commit aa616eea authored by Paul Slaughter's avatar Paul Slaughter

Sourcegraph finishing touches

- Reverting project policy change
- Cleaning lints
- Adding specs
- Updating FE to load sourcegraph only on necessary views
parent 0a460e88
......@@ -3,6 +3,7 @@ import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_sta
import BlobViewer from '~/blob/viewer/index';
import initBlob from '~/pages/projects/init_blob';
import GpgBadges from '~/gpg_badges';
import '~/sourcegraph/load';
document.addEventListener('DOMContentLoaded', () => {
new BlobViewer(); // eslint-disable-line no-new
......
......@@ -9,6 +9,7 @@ import initNotes from '~/init_notes';
import initChangesDropdown from '~/init_changes_dropdown';
import initDiffNotes from '~/diff_notes/diff_notes_bundle';
import { fetchCommitMergeRequests } from '~/commit_merge_requests';
import '~/sourcegraph/load';
document.addEventListener('DOMContentLoaded', () => {
const hasPerfBar = document.querySelector('.with-performance-bar');
......
import initSourcegraph from '~/sourcegraph';
import Project from './project';
import ShortcutsNavigation from '../../behaviors/shortcuts/shortcuts_navigation';
import initCreateCluster from '~/create_cluster/init_create_cluster';
......@@ -8,6 +7,4 @@ document.addEventListener('DOMContentLoaded', () => {
new Project(); // eslint-disable-line no-new
new ShortcutsNavigation(); // eslint-disable-line no-new
initSourcegraph();
});
......@@ -5,6 +5,7 @@ import { handleLocationHash } from '~/lib/utils/common_utils';
import howToMerge from '~/how_to_merge';
import initPipelines from '~/commit/pipelines/pipelines_bundle';
import initVueIssuableSidebarApp from '~/issuable_sidebar/sidebar_bundle';
import initSourcegraph from '~/sourcegraph';
import initWidget from '../../../vue_merge_request_widget';
export default function() {
......@@ -19,4 +20,5 @@ export default function() {
handleLocationHash();
howToMerge();
initWidget();
initSourcegraph();
}
......@@ -11,9 +11,9 @@ function loadScript(path) {
* code intelligence.
*/
export default function initSourcegraph() {
const { sourcegraph_url: sourcegraphUrl, sourcegraph_enabled: sourcegraphEnabled } = gon;
const { url } = gon.sourcegraph || {};
if (!sourcegraphEnabled || !sourcegraphUrl) {
if (!url) {
return;
}
......@@ -21,7 +21,7 @@ export default function initSourcegraph() {
const scriptPath = new URL('scripts/integration.bundle.js', assetsUrl).href;
window.SOURCEGRAPH_ASSETS_URL = assetsUrl.href;
window.SOURCEGRAPH_URL = sourcegraphUrl;
window.SOURCEGRAPH_URL = url;
window.SOURCEGRAPH_INTEGRATION = 'gitlab-integration';
loadScript(scriptPath);
......
import initSourcegraph from './index';
/**
* Load sourcegraph in it's own listener so that it's isolated from failures.
*/
document.addEventListener('DOMContentLoaded', initSourcegraph);
# frozen_string_literal: true
module SourcegraphGon
extend ActiveSupport::Concern
included do
before_action :push_sourcegraph_gon, if: :html_request?
end
private
def push_sourcegraph_gon
return unless can?(current_user, :access_sourcegraph, sourcegraph_project)
return unless sourcegraph_enabled?
gon.push({
sourcegraph_enabled: true,
sourcegraph_url: Gitlab::CurrentSettings.sourcegraph_url
sourcegraph: { url: Gitlab::CurrentSettings.sourcegraph_url }
})
end
private
def sourcegraph_enabled?
Gitlab::CurrentSettings.sourcegraph_enabled && sourcegraph_enabled_for_project? && current_user&.sourcegraph_enabled
end
def sourcegraph_enabled_for_project?
return false unless project && Gitlab::Sourcegraph.feature_enabled?(project)
return project.public? if Gitlab::CurrentSettings.sourcegraph_public_only
def sourcegraph_project
@target_project || project
true
end
end
......@@ -4,12 +4,10 @@ class Projects::ApplicationController < ApplicationController
include CookiesHelper
include RoutableActions
include ChecksCollaboration
include SourcegraphGon
skip_before_action :authenticate_user!
before_action :project
before_action :repository
before_action :push_sourcegraph_gon
layout 'project'
helper_method :repository, :can_collaborate_with_project?, :user_access
......
......@@ -8,6 +8,8 @@ class Projects::BlobController < Projects::ApplicationController
include NotesHelper
include ActionView::Helpers::SanitizeHelper
include RedirectsForMissingPathOnTree
include SourcegraphGon
prepend_before_action :authenticate_user!, only: [:edit]
around_action :allow_gitaly_ref_name_caching, only: [:show]
......
......@@ -8,6 +8,7 @@ class Projects::CommitController < Projects::ApplicationController
include CreatesCommit
include DiffForPath
include DiffHelper
include SourcegraphGon
# Authorize
before_action :require_non_empty_project
......
......@@ -9,6 +9,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include ToggleAwardEmoji
include IssuableCollections
include RecordUserLastActivity
include SourcegraphGon
skip_before_action :merge_request, only: [:index, :bulk_update]
before_action :whitelist_query_limiting, only: [:assign_related_issues, :update]
......
# frozen_string_literal: true
module SourcegraphHelper
def sourcegraph_help_message
return unless Gitlab::CurrentSettings.sourcegraph_enabled
def sourcegraph_url_message
link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: Gitlab::CurrentSettings.sourcegraph_url }
link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
message =
if Gitlab::CurrentSettings.sourcegraph_url_is_com?
s_('SourcegraphPreferences|Uses %{link_start}Sourcegraph.com%{link_end}.').html_safe
else
s_('SourcegraphPreferences|Uses a custom %{link_start}Sourcegraph instance%{link_end}.').html_safe
end
message % { link_start: link_start, link_end: link_end }
end
def sourcegraph_experimental_message
if Gitlab::Sourcegraph.feature_conditional?
_("This feature is experimental and has been limited to only certain projects.")
s_("SourcegraphPreferences|This feature is experimental and currently limited to certain projects.")
elsif Gitlab::CurrentSettings.sourcegraph_public_only
_("This feature is experimental and also limited to only public projects.")
s_("SourcegraphPreferences|This feature is experimental and limited to public projects.")
else
_("This feature is experimental.")
s_("SourcegraphPreferences|This feature is experimental.")
end
end
end
......@@ -347,8 +347,8 @@ class ApplicationSetting < ApplicationRecord
end
after_commit :expire_performance_bar_allowed_user_ids_cache, if: -> { previous_changes.key?('performance_bar_allowed_group_id') }
def sourcegraph_enabled
super && Gitlab::Sourcegraph.feature_available?
def sourcegraph_url_is_com?
!!(sourcegraph_url =~ /\Ahttps:\/\/(www\.)?sourcegraph\.com/)
end
def self.create_from_defaults
......
......@@ -24,10 +24,6 @@ class UserPreference < ApplicationRecord
end
end
def sourcegraph_enabled
super && Gitlab::CurrentSettings.sourcegraph_enabled
end
def set_notes_filter(filter_id, issuable)
# No need to update the column if the value is already set.
if filter_id && NOTES_FILTERS.value?(filter_id)
......
......@@ -461,26 +461,6 @@ class ProjectPolicy < BasePolicy
prevent :create_pipeline
end
condition(:user_sourcegraph_enabled?) do
@user&.sourcegraph_enabled
end
condition(:sourcegraph_feature_enabled?) do
Gitlab::CurrentSettings.sourcegraph_enabled && Gitlab::Sourcegraph.feature_enabled?(@subject)
end
condition(:sourcegraph_public_only?) do
public_project? && Gitlab::CurrentSettings.sourcegraph_public_only
end
condition(:sourcegraph_generally_available?) do
can?(:read_project) && !Gitlab::CurrentSettings.sourcegraph_public_only
end
rule do
(user_sourcegraph_enabled? & sourcegraph_feature_enabled? & (sourcegraph_public_only? | sourcegraph_generally_available?))
end.enable :access_sourcegraph
private
def team_member?
......
......@@ -8,7 +8,12 @@
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Enable code intelligence powered by %{link} on your GitLab instance\'s code views and merge requests.').html_safe % { link: link_to('Sourcegraph', 'https://sourcegraph.com/', target: '_blank') }
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://sourcegraph.com/' }
- link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
= s_('SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance\'s code views and merge requests.').html_safe % { link_start: link_start, link_end: link_end }
%span
= link_to s_('SourcegraphAdmin|More information'), help_page_path('integration/sourcegraph.md'), target: '_blank'
.settings-content
= form_for @application_setting, url: integrations_admin_application_settings_path(anchor: 'js-sourcegraph-settings'), html: { class: 'fieldset-form' } do |f|
......@@ -18,18 +23,16 @@
.form-group
.form-check
= f.check_box :sourcegraph_enabled, class: 'form-check-input'
= f.label :sourcegraph_enabled, _('Enable Sourcegraph'), class: 'form-check-label'
= link_to icon('question-circle'),
help_page_path('integration/sourcegraph.md'),
target: '_blank'
= f.label :sourcegraph_enabled, s_('SourcegraphAdmin|Enable Sourcegraph'), class: 'form-check-label'
.form-group
= f.label :sourcegraph_url, _('Sourcegraph URL'), class: 'label-bold'
= f.text_field :sourcegraph_url, class: 'form-control', placeholder: 'e.g. https://sourcegraph.example.com'
.form-text.text-muted
= _('Add %{link} code intelligence to your GitLab instance code views and merge requests.').html_safe % { link: link_to('Sourcegraph', 'https://sourcegraph.com/', target: '_blank') }
.form-check
= f.check_box :sourcegraph_public_only, class: 'form-check-input'
= f.label :sourcegraph_public_only, s_('SourcegraphAdmin|Block on private and internal projects'), class: 'form-check-label'
.form-text.text-muted
= s_('SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph.')
.form-group
= f.label :sourcegraph_public_only, _('Scope'), class: 'label-bold'
= f.select :sourcegraph_public_only, [[_('All projects'), false], [_('Public projects only'), true]], {}, class: 'form-control'
= f.label :sourcegraph_url, s_('SourcegraphAdmin|Sourcegraph URL'), class: 'label-bold'
= f.text_field :sourcegraph_url, class: 'form-control', placeholder: s_('SourcegraphAdmin|e.g. https://sourcegraph.example.com')
.form-text.text-muted
= _('Configure which projects should allow requests to Sourcegraph.')
= f.submit _('Save changes'), class: 'btn btn-success'
= s_('SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects.')
= f.submit s_('SourcegraphAdmin|Save changes'), class: 'btn btn-success'
- return unless Gitlab::CurrentSettings.sourcegraph_enabled
- return unless Gitlab::Sourcegraph::feature_available? && Gitlab::CurrentSettings.sourcegraph_enabled
- sourcegraph_url = Gitlab::CurrentSettings.sourcegraph_url
.col-sm-12
......@@ -6,20 +6,21 @@
.col-lg-4.profile-settings-sidebar
%h4.prepend-top-0
= _('Integrations')
= s_('Preferences|Integrations')
%p
= _('Customize integrations with third party services.')
= s_('Preferences|Customize integrations with third party services.')
= succeed '.' do
= link_to _('Learn more'), help_page_path('user/profile/third-party.md', anchor: 'localization'), target: '_blank'
= link_to _('Learn more'), help_page_path('user/profile/preferences.md', anchor: 'integrations'), target: '_blank'
.col-lg-8
%label.label-bold
= s_('Preferences|Sourcegraph')
= link_to icon('question-circle'), help_page_path('user/profile/sourcegraph.md'), target: '_blank'
= link_to icon('question-circle'), help_page_path('user/profile/preferences.md', anchor: 'sourcegraph'), target: '_blank', class: 'has-tooltip', title: _('More information')
.form-group.form-check
= f.check_box :sourcegraph_enabled, class: 'form-check-input'
= f.label :sourcegraph_enabled, class: 'form-check-label' do
- link_start = '<a href="%{url}">'.html_safe % { url: sourcegraph_url }
- link_end = '</a>'.html_safe
= s_('Preferences|Enable integrated code intelligence on code views, %{link_start}powered by Sourcegraph%{link_end}.').html_safe % { link_start: link_start, link_end: link_end }
= s_('Preferences|Enable integrated code intelligence on code views').html_safe % { link_start: link_start, link_end: link_end }
.form-text.text-muted
= sourcegraph_help_message
= sourcegraph_url_message
= sourcegraph_experimental_message
......@@ -5,10 +5,8 @@ class AddSourcegraphAdminAndUserPreferences < ActiveRecord::Migration[5.2]
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :sourcegraph_public_only, :boolean, default: true)
add_column(:application_settings, :sourcegraph_public_only, :boolean, default: true, null: false)
add_column(:user_preferences, :sourcegraph_enabled, :boolean)
end
......
......@@ -324,8 +324,9 @@ are listed in the descriptions of the relevant settings.
| `snowplow_enabled` | boolean | no | Enable snowplow tracking. |
| `snowplow_app_id` | string | no | The Snowplow site name / application id. (e.g. `gitlab`) |
| `snowplow_iglu_registry_url` | string | no | The Snowplow base Iglu Schema Registry URL to use for custom context and self describing events'|
| `sourcegraph_enabled` | boolean | no | Enables Sourcegraph integration. Default is `false`. **If enabled, requires** `sourcegraph_url`. |
| `sourcegraph_enabled` | boolean | no | Enables Sourcegraph integration. Default is `false`. **If enabled, requires** `sourcegraph_url`. |
| `sourcegraph_url` | string | required by: `sourcegraph_enabled` | The Sourcegraph instance URL for integration. |
| `sourcegraph_public_only` | boolean | no | Blocks Sourcegraph from being loaded on private and internal projects. Defaul is `true`. |
| `terminal_max_session_time` | integer | no | Maximum time for web terminal websocket connection (in seconds). Set to `0` for unlimited time. |
| `terms` | text | required by: `enforce_terms` | (**Required by:** `enforce_terms`) Markdown content for the ToS. |
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (e.g. from crawlers or abusive bots). |
......
......@@ -4,57 +4,64 @@ type: reference, how-to
# Sourcegraph integration
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/16556) in GitLab X.X.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/16556) in GitLab 12.5.
[Sourcegraph](https://sourcegraph.com) provides complete code intelligence functionality,
historically provided by the Sourcegraph browser extension. Sourcegraph provides tooltips on hover with go-to definitions as well as
find references working by default for all users.
[Sourcegraph](https://sourcegraph.com) provides code intelligence features, natively integrated into the GitLab UI.
## Set up for public repositories on GitLab.com
![Sourcegraph demo](img/sourcegraph_demo.png)
With an opt-in setting, this works by default for all public repositories on GitLab.com.
NOTE: **Note:**
This feature requires user opt-in. After Sourcegraph has been enabled for your GitLab instance,
you can choose to enable Sourcegraph [through your user preferences](#enable-sourcegraph-in-user-preferences).
1. In GitLab, click your avatar in the top-right corner, then **Settings**. On the left-hand nav, click **Preferences**.
1. Under **Integrations**, find the **Sourcegraph** section.
1. Check **Enable Sourcegraph**.
## Set up for self-managed GitLab instances **(CORE ONLY)**
## Set up for private repositories on GitLab.com
Before you can enable Sourcegraph code intelligence in GitLab you will need to:
Since [Sourcegraph.com](http://sourcegraph.com/search) does not access private repositories on GitLab.com, you will need to run a private instance of Sourcegraph to generate code intelligence.
- Enable the `sourcegraph` feature flag for your GitLab instance.
- Configure a Sourcegraph instance with your GitLab instance as an external service.
### Set up and configure your Sourcegraph instance
### Enable the Sourcegraph feature flag
Follow the [setup](#set-up-your-sourcegraph-instance) and [configure](#configure-your-sourcegraph-instance-with-gitlab) steps in the self-managed instance section below.
NOTE: **Note:**
If you are running a self-managed instance, the Sourcegraph feature will not be available
unless the feature flag `sourcegraph` is enabled. This can be done from the Rails console
by instance administrators.
### Install the Sourcegraph browser extension
Use these commands to start the Rails console:
To share code intelligence information from your private Sourcegraph instance, you will need to use the Sourcegraph browser extension to reach back to your private Sourcegraph instance from private GitLab repository pages.
```sh
# Omnibus GitLab
gitlab-rails console
1. [Install the Sourcegraph browser extension](https://docs.sourcegraph.com/integration/browser_extension).
1. Right-click the browser extension icon and set the Sourcegraph URL field to your Sourcegraph instance's URL.
1. [Enable the browser extension](https://docs.sourcegraph.com/integration/browser_extension#enabling-the-browser-extension-on-your-code-host) on GitLab.com.
# Installation from source
cd /home/git/gitlab
sudo -u git -H bin/rails console RAILS_ENV=production
```
You should now see code intelligence on any repository indexed by your private Sourcegraph instance.
Then run to enable the feature flag:
## Set up for self-managed GitLab instances **(CORE ONLY)**
```
Feature.enable(:sourcegraph)
```
> Once enabled in your instance, it will become available to all projects (public, internal, and private).
You can also enable the feature flag only for specific projects with:
Before you can enable Sourcegraph code intelligence in GitLab you need to have a
Sourcegraph instance running and configured with your GitLab instance as an external
service.
```
Feature.enable(:sourcegraph, Project.find_by_full_path('my_group/my_project'))
```
### Set up your Sourcegraph instance
### Set up a self-managed Sourcegraph instance
If you are new to Sourcegraph, head over to the [Sourcegraph installation documentation](https://docs.sourcegraph.com/admin) and get your instance up and running.
### Connect your Sourcegraph instance to GitLab
### Connect your Sourcegraph instance to your GitLab instance
1. Navigate to the site admin area in Sourcegraph.
1. [Configure your GitLab external service](https://docs.sourcegraph.com/admin/external_service/gitlab).
You can skip this step if you already have your GitLab repositories searchable in Sourcegraph.
1. Validate that you can search your repositories from GitLab in your Sourcegraph instance by running a test query.
1. Add your GitLab instance URL to the [`corsOrigin` setting](https://docs.sourcegraph.com/admin/config/site_config#corsOrigin) in your site configuration (e.g. `https://sourcegraph.example.com/site-admin/configuration`).
1. Add your GitLab instance URL to the [`corsOrigin` setting](https://docs.sourcegraph.com/admin/config/site_config#corsOrigin) in your site configuration.
### Configure your GitLab instance with Sourcegraph
......@@ -63,5 +70,48 @@ You can skip this step if you already have your GitLab repositories searchable i
1. Check **Enable Sourcegraph**.
1. Set the Sourcegraph URL to your Sourcegraph instance, e.g., `https://sourcegraph.example.com`.
You should now see code intelligence on your files, without needing the browser
extension installed!
![Sourcegraph admin settings](img/sourcegraph_admin.png)
## Enable Sourcegraph in user preferences
If a GitLab administrator has enabled Sourcegraph, you can enable this feature in your user preferences.
1. In GitLab, click your avatar in the top-right corner, then click **Settings**. On the left-hand nav, click **Preferences**.
1. Under **Integrations**, find the **Sourcegraph** section.
1. Check **Enable Sourcegraph**.
![Sourcegraph user preferences](img/sourcegraph_user_preferences.png)
## Using Sourcegraph code intelligence
Once enabled, participating projects will have a code intelligence popover available in
the following code views:
- Merge request diffs
- Commit view
- File view
When visiting one of these views, you can now hover over a code reference to see a popover with:
- Details on how this reference was defined.
- **Go to definition**, which navigates to the line of code where this reference was defined.
- **Find references**, which navigates to the configured Sourcegraph instance, showing a list of references to the hilighted code.
![Sourcegraph demo](img/sourcegraph_popover.png)
## Sourcegraph for GitLab.com
Sourcegraph powered code intelligence will be incrementally rolled out on GitLab.com. It will eventually be
available for all public projects, but for now, it is only available for some specific [`gitlab-org` projects](https://gitlab.com/gitlab-org/gitlab).
If you have a private or internal project and would like integrated code intelligence, please consider
setting up a self-hosted GitLab instance.
## Sourcegraph and Privacy
From Sourcegraph's [extension documentation](https://docs.sourcegraph.com/integration/browser_extension#privacy) which is the
engine behind the native GitLab integration:
> Sourcegraph integrations never send any logs, pings, usage statistics, or telemetry to Sourcegraph.com.
> They will only connect to Sourcegraph.com as required to provide code intelligence or other functionality on public code.
> As a result, no private code, private repository names, usernames, or any other specific data is sent to Sourcegraph.com.
......@@ -128,6 +128,19 @@ You can choose one of the following options as the first day of the week:
If you select **System Default**, the system-wide default setting will be used.
## Integrations
Configure your preferences with third-party services which provide enhancements to your GitLab experience.
### Sourcegraph
NOTE: **Note:**
This setting is only visible if Sourcegraph has been enabled by a GitLab administrator.
Manage the availability of integrated code intelligence features powered by
Sourcegraph. View [the Sourcegraph feature documentation](../../integration/sourcegraph.md#enable-sourcegraph-in-user-preferences)
for more information.
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
......@@ -137,6 +137,7 @@ module API
optional :signin_enabled, type: Boolean, desc: 'Flag indicating if password authentication is enabled for the web interface' # support legacy names, can be removed in v5
optional :signup_enabled, type: Boolean, desc: 'Flag indicating if sign up is enabled'
optional :sourcegraph_enabled, type: Boolean, desc: 'Enable Sourcegraph'
optional :sourcegraph_public_only, type: Boolean, desc: 'Only allow public projects to communicate with Sourcegraph'
given sourcegraph_enabled: ->(val) { val } do
requires :sourcegraph_url, type: String, desc: 'The configured Sourcegraph instance URL'
end
......
......@@ -12,7 +12,7 @@ module Gitlab
!feature.off?
end
def feature_enabled?(thing = true)
def feature_enabled?(thing = nil)
feature.enabled?(thing)
end
......
......@@ -6235,9 +6235,6 @@ msgstr ""
msgid "Enable SAML authentication for this group"
msgstr ""
msgid "Enable Sourcegraph"
msgstr ""
msgid "Enable access to Grafana"
msgstr ""
......@@ -6256,9 +6253,6 @@ msgstr ""
msgid "Enable classification control using an external service"
msgstr ""
msgid "Enable code intelligence powered by %{link} on your GitLab instance's code views and merge requests."
msgstr ""
msgid "Enable error tracking"
msgstr ""
......@@ -12541,6 +12535,9 @@ msgstr ""
msgid "Preferences|Choose what content you want to see on a project’s overview page."
msgstr ""
msgid "Preferences|Customize integrations with third party services."
msgstr ""
msgid "Preferences|Customize the appearance of the application header and navigation sidebar."
msgstr ""
......@@ -12550,9 +12547,15 @@ msgstr ""
msgid "Preferences|Display time in 24-hour format"
msgstr ""
msgid "Preferences|Enable integrated code intelligence on code views"
msgstr ""
msgid "Preferences|For example: 30 mins ago."
msgstr ""
msgid "Preferences|Integrations"
msgstr ""
msgid "Preferences|Layout width"
msgstr ""
......@@ -12565,6 +12568,9 @@ msgstr ""
msgid "Preferences|Show whitespace in diffs"
msgstr ""
msgid "Preferences|Sourcegraph"
msgstr ""
msgid "Preferences|Syntax highlighting theme"
msgstr ""
......@@ -16172,7 +16178,46 @@ msgstr ""
msgid "Sourcegraph"
msgstr ""
msgid "Sourcegraph URL"
msgid "SourcegraphAdmin|Block on private and internal projects"
msgstr ""
msgid "SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects."
msgstr ""
msgid "SourcegraphAdmin|Enable Sourcegraph"
msgstr ""
msgid "SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance's code views and merge requests."
msgstr ""
msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|More information"
msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and limited to public projects."
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental."
msgstr ""
msgid "SourcegraphPreferences|Uses %{link_start}Sourcegraph.com%{link_end}."
msgstr ""
msgid "SourcegraphPreferences|Uses a custom %{link_start}Sourcegraph instance%{link_end}."
msgstr ""
msgid "Spam Logs"
......
# frozen_string_literal: true
require 'spec_helper'
describe SourcegraphGon do
let_it_be(:enabled_user) { create(:user, sourcegraph_enabled: true) }
let_it_be(:disabled_user) { create(:user, sourcegraph_enabled: false) }
let_it_be(:public_project) { create(:project, :public) }
let_it_be(:internal_project) { create(:project, :internal) }
let(:sourcegraph_url) { 'http://sourcegraph.gitlab.com' }
let(:feature_enabled) { true }
let(:sourcegraph_enabled) { true }
let(:sourcegraph_public_only) { false }
let(:format) { :html }
let(:user) { enabled_user }
let(:project) { internal_project }
controller(ApplicationController) do
include SourcegraphGon # rubocop:disable RSpec/DescribedClass
def index
head :ok
end
end
before do
Feature.get(:sourcegraph).enable(feature_enabled)
stub_application_setting(sourcegraph_url: sourcegraph_url, sourcegraph_enabled: sourcegraph_enabled, sourcegraph_public_only: sourcegraph_public_only)
allow(controller).to receive(:project).and_return(project)
Gon.clear
sign_in user if user
end
after do
Feature.get(:sourcegraph).disable
end
subject do
get :index, format: format
Gon.sourcegraph
end
shared_examples 'enabled' do
it { is_expected.to eq({ url: sourcegraph_url }) }
end
shared_examples 'disabled' do
it { is_expected.to be_nil }
end
context 'with feature enabled, application enabled, and user enabled' do
it_behaves_like 'enabled'
end
context 'with feature enabled for specific project' do
let(:feature_enabled) { project }
it_behaves_like 'enabled'
end
context 'with feature enabled for different project' do
let(:feature_enabled) { create(:project) }
it_behaves_like 'disabled'
end
context 'with feature disabled' do
let(:feature_enabled) { false }
it_behaves_like 'disabled'
end
context 'with admin settings disabled' do
let(:sourcegraph_enabled) { false }
it_behaves_like 'disabled'
end
context 'with public only' do
let(:sourcegraph_public_only) { true }
context 'with internal project' do
let(:project) { internal_project }
it_behaves_like 'disabled'
end
context 'with public project' do
let(:project) { public_project }
it_behaves_like 'enabled'
end
end
context 'with user disabled' do
let(:user) { disabled_user }
it_behaves_like 'disabled'
end
context 'with no user' do
let(:user) { nil }
it_behaves_like 'disabled'
end
context 'with non-html format' do
let(:format) { :json }
it_behaves_like 'disabled'
end
end
# frozen_string_literal: true
require 'spec_helper'
describe SourcegraphGon do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
controller(Projects::ApplicationController) do
include SourcegraphGon # rubocop:disable RSpec/DescribedClass
def index; end
end
describe '#push_sourcegraph_gon' do
let(:application_setting_sourcegraph_url) { 'http://gitlab.com' }
let(:sourcegraph_access) { true }
subject { get(:index, params: { namespace_id: project.namespace, project_id: project })}
before do
stub_application_setting(sourcegraph_url: application_setting_sourcegraph_url)
allow(controller).to receive(:current_user).and_return(user)
allow(controller).to receive(:can?).and_return(true)
allow(controller).to receive(:can?).with(user, :access_sourcegraph, project).and_return(sourcegraph_access)
subject
end
context 'with access to use sourcegraph' do
it 'enables sourcegraph' do
expect(Gon.sourcegraph_enabled).to be_truthy
expect(Gon.sourcegraph_url).to eq application_setting_sourcegraph_url
end
end
context 'with no access to use sourcegraph' do
let(:sourcegraph_access) { false }
it 'does not enable sourcegraph' do
expect(Gon.sourcegraph_enabled).to be_nil
expect(Gon.sourcegraph_url).to be_nil
end
end
end
end
......@@ -3,53 +3,62 @@
require 'spec_helper'
describe SourcegraphHelper do
let(:application_setting) { true }
let(:public_only_setting) { true }
let(:feature_conditional) { false }
describe '#sourcegraph_url_message' do
let(:sourcegraph_url) { 'http://sourcegraph.example.com' }
subject { helper.sourcegraph_help_message }
before do
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url)
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url_is_com?).and_return(is_com)
end
before do
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_enabled).and_return(application_setting)
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only_setting)
allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional)
end
subject { helper.sourcegraph_url_message }
context '#sourcegraph_help_message' do
context 'when application setting sourcegraph_enabled is disabled' do
let(:application_setting) { false }
context 'with .com sourcegraph url' do
let(:is_com) { true }
it { is_expected.to be_nil }
it { is_expected.to have_text('Uses Sourcegraph.com') }
it { is_expected.to have_link('Sourcegraph.com', href: sourcegraph_url) }
end
context 'when application setting sourcegraph_enabled is enabled' do
context 'when feature is conditional' do
let(:feature_conditional) { true }
context 'with custom sourcegraph url' do
let(:is_com) { false }
it { is_expected.to have_text('Uses a custom Sourcegraph instance') }
it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) }
context 'with unsafe url' do
let(:sourcegraph_url) { '\" onload=\"alert(1);\"' }
it do
is_expected.to eq "This feature is experimental and has been limited to only certain projects."
end
it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) }
end
end
end
context '#sourcegraph_experimental_message' do
let(:feature_conditional) { false }
let(:public_only) { false }
context 'when feature is enabled globally' do
before do
stub_feature_flags(sourcegraph: true)
end
before do
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only)
allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional)
end
subject { helper.sourcegraph_experimental_message }
context 'when only works with public projects' do
it do
is_expected.to eq "This feature is experimental and also limited to only public projects."
end
end
context 'when not limited by feature or public only' do
it { is_expected.to eq "This feature is experimental." }
end
context 'when it works with all projects' do
let(:public_only_setting) { false }
context 'when limited by feature' do
let(:feature_conditional) { true }
it do
is_expected.to eq "This feature is experimental."
end
end
end
it { is_expected.to eq "This feature is experimental and currently limited to certain projects." }
end
context 'when limited by public only' do
let(:public_only) { true }
it { is_expected.to eq "This feature is experimental and limited to public projects." }
end
end
end
......@@ -4,25 +4,23 @@ require 'spec_helper'
describe Gitlab::Sourcegraph do
let_it_be(:user) { create(:user) }
let(:feature) { :sourcegraph }
let(:feature_scope) { true }
before do
Feature.enable(:sourcegraph, feature_scope)
end
describe '.feature_conditional?' do
subject { described_class.feature_conditional? }
context 'when feature is enabled globally' do
it 'returns false' do
Feature.enable(feature)
is_expected.to be_falsey
end
it { is_expected.to be_falsey }
end
context 'when feature is enabled only to a resource' do
it 'returns true' do
Feature.enable(feature, user)
let(:feature_scope) { user }
is_expected.to be_truthy
end
it { is_expected.to be_truthy }
end
end
......@@ -30,55 +28,38 @@ describe Gitlab::Sourcegraph do
subject { described_class.feature_available? }
context 'when feature is enabled globally' do
it 'returns true' do
Feature.enable(feature)
is_expected.to be_truthy
end
it { is_expected.to be_truthy }
end
context 'when feature is enabled only to a resource' do
it 'returns true' do
Feature.enable(feature, user)
let(:feature_scope) { user }
is_expected.to be_truthy
end
it { is_expected.to be_truthy }
end
end
describe '.feature_enabled?' do
let_it_be(:other_user) { create(:user) }
let(:current_user) { nil }
subject { described_class.feature_enabled?(current_user) }
context 'when feature is enabled globally' do
it 'returns true' do
Feature.enable(feature)
is_expected.to be_truthy
end
it { is_expected.to be_truthy }
end
context 'when feature is enabled only to a resource' do
let(:feature_scope) { user }
context 'for the same resource' do
let(:current_user) { user }
it 'returns true' do
Feature.enable(feature, user)
is_expected.to be_truthy
end
it { is_expected.to be_truthy }
end
context 'for a different resource' do
let(:current_user) { other_user }
it 'returns false' do
Feature.enable(feature, user)
let(:current_user) { create(:user) }
is_expected.to be_falsey
end
it { is_expected.to be_falsey }
end
end
end
......
......@@ -3,6 +3,8 @@
require 'spec_helper'
describe ApplicationSetting do
using RSpec::Parameterized::TableSyntax
subject(:setting) { described_class.create_from_defaults }
it { include(CacheableAttributes) }
......@@ -592,26 +594,21 @@ describe ApplicationSetting do
end
end
context 'sourcegraph_enabled' do
let(:flag_value) { true }
before do
allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(flag_value)
setting.sourcegraph_enabled = true
end
context 'when feature flag sourcegraph is enabled' do
it 'returns the stored value' do
expect(setting.sourcegraph_enabled).to be_truthy
end
describe '#sourcegraph_url_is_com?' do
where(:url, :is_com) do
'https://sourcegraph.com' | true
'https://sourcegraph.com/' | true
'https://www.sourcegraph.com' | true
'shttps://www.sourcegraph.com' | false
'https://sourcegraph.example.com/' | false
'https://sourcegraph.org/' | false
end
context 'when feature flag sourcegraph is disabled' do
let(:flag_value) { false }
with_them do
it 'matches the url with sourcegraph.com' do
setting.sourcegraph_url = url
it 'returns false' do
expect(setting.sourcegraph_enabled).to be_falsey
expect(setting.sourcegraph_url_is_com?).to eq(is_com)
end
end
end
......
......@@ -3,8 +3,7 @@
require 'spec_helper'
describe UserPreference do
let_it_be(:user) { create(:user) }
let(:user_preference) { create(:user_preference, user: user) }
let(:user_preference) { create(:user_preference) }
describe '#set_notes_filter' do
let(:issuable) { build_stubbed(:issue) }
......@@ -80,27 +79,4 @@ describe UserPreference do
expect(user_preference.timezone).to eq(Time.zone.tzinfo.name)
end
end
describe 'sourcegraph_enabled' do
let(:user_preference) { create(:user_preference, sourcegraph_enabled: true, user: user) }
let(:application_setting_sourcegraph_enabled) { true }
before do
stub_application_setting(sourcegraph_enabled: application_setting_sourcegraph_enabled)
end
context 'when sourcegraph_enabled application setting is enabled' do
it 'returns true' do
expect(user_preference.sourcegraph_enabled).to be_truthy
end
end
context 'when sourcegraph_enabled application setting is disabled' do
let(:application_setting_sourcegraph_enabled) { false }
it 'returns false' do
expect(user_preference.sourcegraph_enabled).to be_falsey
end
end
end
end
......@@ -529,88 +529,4 @@ describe ProjectPolicy do
end
end
end
describe 'access_sourcegraph' do
let_it_be(:private_project) { create(:project, :private, namespace: owner.namespace) }
let(:sourcegraph_flag) { true }
let(:application_setting_sourcegraph_enabled) { true }
let(:user_sourcegraph_enabled) { true }
let(:current_user) { owner }
subject { described_class.new(current_user, project) }
before do
stub_feature_flags(sourcegraph: sourcegraph_flag)
stub_application_setting(sourcegraph_enabled: application_setting_sourcegraph_enabled)
stub_application_setting(sourcegraph_public_only: application_setting_sourcegraph_public_only)
allow(Gitlab::Sourcegraph).to receive(:feature_enabled?).and_return(sourcegraph_flag)
allow(current_user).to receive(:sourcegraph_enabled).and_return(user_sourcegraph_enabled) if current_user
end
shared_examples 'disabled setting requirements' do
context 'when feature flag is disabled' do
let(:sourcegraph_flag) { false }
it { expect_disallowed(:access_sourcegraph) }
end
context 'when user setting is disabled' do
let(:user_sourcegraph_enabled) { false }
it { expect_disallowed(:access_sourcegraph) }
end
context 'when application setting is disabled' do
let(:application_setting_sourcegraph_enabled) { false }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when sourcegraph setting is enabled for public projects only' do
let(:application_setting_sourcegraph_public_only) { true }
context 'when the project is public' do
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
context 'when the user is not authenticated' do
let(:current_user) { nil }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when the project is not public' do
let(:project) { private_project }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when sourcegraph setting is enabled for all projects' do
let(:application_setting_sourcegraph_public_only) { false }
context 'when the project is public' do
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
end
context 'when the project is not public' do
let(:project) { private_project }
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
context 'when the user cannot read project' do
let(:current_user) { create(:user) }
it { expect_disallowed(:access_sourcegraph) }
end
end
end
end
end
......@@ -5,7 +5,7 @@ require 'spec_helper'
describe 'profiles/preferences/show' do
using RSpec::Parameterized::TableSyntax
let(:user) { create(:user) }
let_it_be(:user) { build(:user) }
before do
assign(:user, user)
......@@ -24,7 +24,7 @@ describe 'profiles/preferences/show' do
before do
# Can't use stub_feature_flags because we use Feature.get to check if conditinally applied
Feature.get(:sourcegraph).enable sourcegraph_feature
Gitlab::CurrentSettings.sourcegraph_enabled = sourcegraph_enabled
stub_application_setting(sourcegraph_enabled: sourcegraph_enabled)
end
context 'when not fully enabled' do
......@@ -45,7 +45,7 @@ describe 'profiles/preferences/show' do
it 'does not display sourcegraph field' do
expect(rendered).not_to have_sourcegraph_field
end
it 'does not display integrations settings' do
expect(rendered).not_to have_integrations_section
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment