summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.babelrc.js6
-rw-r--r--.eslintignore1
-rw-r--r--.gitignore4
-rw-r--r--.gitlab-ci.yml50
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js12
-rw-r--r--app/controllers/groups/clusters_controller.rb8
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb7
-rw-r--r--app/controllers/projects/pipelines_controller.rb10
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/finders/pipelines_finder.rb2
-rw-r--r--app/helpers/groups_helper.rb2
-rw-r--r--app/helpers/sorting_helper.rb12
-rw-r--r--app/models/ci/pipeline.rb31
-rw-r--r--app/models/ci/pipeline_enums.rb3
-rw-r--r--app/models/ci/runner.rb3
-rw-r--r--app/models/clusters/cluster.rb40
-rw-r--r--app/models/commit.rb4
-rw-r--r--app/models/commit_collection.rb2
-rw-r--r--app/models/concerns/chronic_duration_attribute.rb2
-rw-r--r--app/models/concerns/deployment_platform.rb13
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/merge_request.rb16
-rw-r--r--app/models/namespace.rb6
-rw-r--r--app/models/project.rb42
-rw-r--r--app/models/project_services/pipelines_email_service.rb4
-rw-r--r--app/serializers/pipeline_entity.rb1
-rw-r--r--app/services/ci/create_pipeline_service.rb5
-rw-r--r--app/services/clusters/refresh_service.rb40
-rw-r--r--app/services/merge_requests/base_service.rb18
-rw-r--r--app/services/merge_requests/create_service.rb7
-rw-r--r--app/services/merge_requests/refresh_service.rb1
-rw-r--r--app/services/projects/auto_devops/disable_service.rb2
-rw-r--r--app/services/projects/create_service.rb6
-rw-r--r--app/services/projects/transfer_service.rb5
-rw-r--r--app/services/test_hooks/project_service.rb2
-rw-r--r--app/validators/duration_validator.rb6
-rw-r--r--app/views/admin/users/index.html.haml24
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/shared/runners/_form.html.haml2
-rw-r--r--app/workers/all_queues.yml1
-rw-r--r--app/workers/cluster_platform_configure_worker.rb12
-rw-r--r--app/workers/cluster_project_configure_worker.rb12
-rw-r--r--app/workers/update_head_pipeline_for_merge_request_worker.rb6
-rw-r--r--changelogs/unreleased/34758-deployment-cluster.yml5
-rw-r--r--changelogs/unreleased/50626-searching-users-by-the-admin-panel-wipes-query-when-using-sort.yml5
-rw-r--r--changelogs/unreleased/54826-use-read_repository-scope-on-read-only-files-endpoints.yml5
-rw-r--r--changelogs/unreleased/fix-gb-improve-timeout-inputs-help-sections.yml5
-rw-r--r--changelogs/unreleased/mr-pipelines-2.yml5
-rw-r--r--changelogs/unreleased/multiple-diff-line-discussions-fix.yml5
-rw-r--r--changelogs/unreleased/osw-fix-grouping-by-file-path.yml5
-rw-r--r--config/jest.config.js27
-rw-r--r--danger/changelog/Dangerfile2
-rw-r--r--db/fixtures/development/14_pipelines.rb2
-rw-r--r--db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb13
-rw-r--r--db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb22
-rw-r--r--db/schema.rb3
-rw-r--r--doc/api/repository_files.md10
-rw-r--r--doc/development/new_fe_guide/development/testing.md8
-rw-r--r--doc/install/docker.md7
-rw-r--r--doc/security/two_factor_authentication.md2
-rw-r--r--lib/api/commit_statuses.rb4
-rw-r--r--lib/api/files.rb4
-rw-r--r--lib/api/jobs.rb2
-rw-r--r--lib/api/pipelines.rb2
-rw-r--r--lib/gitlab/badge/coverage/report.rb2
-rw-r--r--lib/gitlab/badge/pipeline/status.rb2
-rw-r--r--lib/gitlab/ci/charts.rb4
-rw-r--r--lib/gitlab/ci/pipeline/chain/build.rb1
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb2
-rw-r--r--lib/gitlab/diff/file_collection/base.rb10
-rw-r--r--lib/gitlab/diff/file_collection/compare.rb4
-rw-r--r--lib/gitlab/group_hierarchy.rb29
-rw-r--r--lib/gitlab/import_export/import_export.yml2
-rw-r--r--lib/gitlab/import_export/project_tree_restorer.rb4
-rw-r--r--lib/gitlab/import_export/project_tree_saver.rb2
-rw-r--r--lib/gitlab/import_export/relation_factory.rb1
-rw-r--r--lib/gitlab/import_export/relation_rename_service.rb48
-rw-r--r--lib/gitlab/usage_data.rb4
-rw-r--r--lib/system_check/gitaly_check.rb19
-rw-r--r--lib/system_check/gitlab_shell_check.rb56
-rw-r--r--lib/system_check/incoming_email_check.rb27
-rw-r--r--lib/system_check/ldap_check.rb60
-rw-r--r--lib/system_check/orphans/repository_check.rb1
-rw-r--r--lib/system_check/rake_task/app_task.rb38
-rw-r--r--lib/system_check/rake_task/gitaly_task.rb18
-rw-r--r--lib/system_check/rake_task/gitlab_shell_task.rb18
-rw-r--r--lib/system_check/rake_task/gitlab_task.rb33
-rw-r--r--lib/system_check/rake_task/incoming_email_task.rb18
-rw-r--r--lib/system_check/rake_task/ldap_task.rb18
-rw-r--r--lib/system_check/rake_task/orphans/namespace_task.rb20
-rw-r--r--lib/system_check/rake_task/orphans/repository_task.rb20
-rw-r--r--lib/system_check/rake_task/orphans_task.rb21
-rw-r--r--lib/system_check/rake_task/rake_task_helpers.rb32
-rw-r--r--lib/system_check/rake_task/sidekiq_task.rb18
-rw-r--r--lib/system_check/sidekiq_check.rb58
-rw-r--r--lib/tasks/gitlab/check.rake259
-rw-r--r--locale/gitlab.pot8
-rw-r--r--package.json9
-rwxr-xr-xscripts/merge-train73
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb12
-rw-r--r--spec/features/admin/admin_users_spec.rb53
-rw-r--r--spec/features/groups/members/list_members_spec.rb9
-rw-r--r--spec/features/groups/members/manage_members_spec.rb9
-rw-r--r--spec/features/ide_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb333
-rw-r--r--spec/features/projects/commit/builds_spec.rb2
-rw-r--r--spec/features/projects/members/list_spec.rb9
-rw-r--r--spec/features/projects/pages_spec.rb2
-rw-r--r--spec/features/projects_spec.rb2
-rw-r--r--spec/frontend/.eslintrc.yml9
-rw-r--r--spec/frontend/dummy_spec.js1
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js78
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/build_spec.rb29
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb30
-rw-r--r--spec/lib/gitlab/diff/file_collection/commit_spec.rb4
-rw-r--r--spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb27
-rw-r--r--spec/lib/gitlab/group_hierarchy_spec.rb22
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml8
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/project_tree_saver_spec.rb10
-rw-r--r--spec/lib/gitlab/import_export/relation_rename_service_spec.rb111
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb16
-rw-r--r--spec/models/ci/pipeline_spec.rb245
-rw-r--r--spec/models/clusters/cluster_spec.rb120
-rw-r--r--spec/models/concerns/chronic_duration_attribute_spec.rb3
-rw-r--r--spec/models/concerns/deployment_platform_spec.rb75
-rw-r--r--spec/models/group_spec.rb29
-rw-r--r--spec/models/merge_request_spec.rb113
-rw-r--r--spec/models/namespace_spec.rb2
-rw-r--r--spec/models/project_spec.rb104
-rw-r--r--spec/requests/api/commit_statuses_spec.rb4
-rw-r--r--spec/requests/api/commits_spec.rb2
-rw-r--r--spec/requests/api/files_spec.rb47
-rw-r--r--spec/requests/api/pipelines_spec.rb12
-rw-r--r--spec/requests/api/triggers_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service_spec.rb225
-rw-r--r--spec/services/clusters/refresh_service_spec.rb107
-rw-r--r--spec/services/merge_requests/create_service_spec.rb72
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb88
-rw-r--r--spec/services/projects/create_service_spec.rb26
-rw-r--r--spec/services/projects/transfer_service_spec.rb26
-rw-r--r--spec/support/helpers/features/list_rows_helpers.rb28
-rw-r--r--spec/support/shared_examples/diff_file_collections.rb16
-rw-r--r--spec/tasks/gitlab/check_rake_spec.rb108
-rw-r--r--spec/views/layouts/nav/sidebar/_admin.html.haml_spec.rb (renamed from spec/features/admin/admin_active_tab_spec.rb)34
-rw-r--r--spec/workers/cluster_platform_configure_worker_spec.rb52
-rw-r--r--spec/workers/pipeline_schedule_worker_spec.rb12
-rw-r--r--spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb28
-rw-r--r--yarn.lock1729
151 files changed, 4962 insertions, 652 deletions
diff --git a/.babelrc.js b/.babelrc.js
index 27caf378b99..bfcc7d96634 100644
--- a/.babelrc.js
+++ b/.babelrc.js
@@ -35,4 +35,10 @@ if (BABEL_ENV === 'karma' || BABEL_ENV === 'coverage') {
plugins.push('babel-plugin-rewire');
}
+// Jest is running in node environment
+if (BABEL_ENV === 'jest') {
+ plugins.push('transform-es2015-modules-commonjs');
+ plugins.push('dynamic-import-node');
+}
+
module.exports = { presets, plugins };
diff --git a/.eslintignore b/.eslintignore
index 33a8186fade..f78840e67be 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,6 +2,7 @@
/config/
/builds/
/coverage/
+/coverage-frontend/
/coverage-javascript/
/node_modules/
/public/
diff --git a/.gitignore b/.gitignore
index aecaae95b8c..65f61e1fade 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,5 +78,5 @@ eslint-report.html
/plugins/*
/.gitlab_pages_secret
package-lock.json
-/junit_rspec.xml
-/junit_karma.xml
+/junit_*.xml
+/coverage-frontend/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9eac37df74b..a97414cbba8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -699,6 +699,32 @@ karma:
reports:
junit: junit_karma.xml
+jest:
+ <<: *dedicated-no-docs-and-no-qa-pull-cache-job
+ <<: *use-pg
+ dependencies:
+ - compile-assets
+ - setup-test-env
+ script:
+ - scripts/gitaly-test-spawn
+ - date
+ - bundle exec rake karma:fixtures
+ - date
+ - yarn jest --ci --coverage
+ artifacts:
+ name: coverage-frontend
+ expire_in: 31d
+ when: always
+ paths:
+ - coverage-frontend/
+ - junit_jest.xml
+ reports:
+ junit: junit_jest.xml
+ cache:
+ key: jest
+ paths:
+ - tmp/jest/jest/
+
code_quality:
<<: *dedicated-no-docs-no-db-pull-cache-job
image: docker:stable
@@ -1027,27 +1053,3 @@ schedule:review-cleanup:
- gem install gitlab --no-document
script:
- ruby -rrubygems scripts/review_apps/automated_cleanup.rb
-
-merge:master:
- image: registry.gitlab.com/gitlab-org/merge-train
- stage: merge
- # The global before_script/after_script blocks break this job, or aren't
- # necessary. These two lines result in them being ignored.
- before_script: []
- after_script: []
- only:
- refs:
- - master
- - schedules
- variables:
- - $CI_PROJECT_PATH == "gitlab-org/gitlab-ce"
- - $MERGE_TRAIN_SSH_PUBLIC_KEY
- - $MERGE_TRAIN_SSH_PRIVATE_KEY
- - $MERGE_TRAIN_API_TOKEN
- - $MERGE_FORCE_ENABLE
- script:
- - scripts/merge-train
- cache:
- paths:
- - gitlab-ee
- key: "merge:master"
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index f0895661bf2..331fb052371 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -130,7 +130,7 @@ export default {
if (file.highlighted_diff_lines) {
file.highlighted_diff_lines = file.highlighted_diff_lines.map(line => {
- if (lineCheck(line)) {
+ if (!line.discussions.some(({ id }) => discussion.id === id) && lineCheck(line)) {
return {
...line,
discussions: line.discussions.concat(discussion),
@@ -150,11 +150,17 @@ export default {
return {
left: {
...line.left,
- discussions: left ? line.left.discussions.concat(discussion) : [],
+ discussions:
+ left && !line.left.discussions.some(({ id }) => id === discussion.id)
+ ? line.left.discussions.concat(discussion)
+ : (line.left && line.left.discussions) || [],
},
right: {
...line.right,
- discussions: right && !left ? line.right.discussions.concat(discussion) : [],
+ discussions:
+ right && !left && !line.right.discussions.some(({ id }) => id === discussion.id)
+ ? line.right.discussions.concat(discussion)
+ : (line.right && line.right.discussions) || [],
},
};
}
diff --git a/app/controllers/groups/clusters_controller.rb b/app/controllers/groups/clusters_controller.rb
index 50c44b7a58b..b846fb21266 100644
--- a/app/controllers/groups/clusters_controller.rb
+++ b/app/controllers/groups/clusters_controller.rb
@@ -3,8 +3,8 @@
class Groups::ClustersController < Clusters::ClustersController
include ControllerWithCrossProjectAccessCheck
- prepend_before_action :check_group_clusters_feature_flag!
prepend_before_action :group
+ prepend_before_action :check_group_clusters_feature_flag!
requires_cross_project_access
layout 'group'
@@ -20,6 +20,10 @@ class Groups::ClustersController < Clusters::ClustersController
end
def check_group_clusters_feature_flag!
- render_404 unless Feature.enabled?(:group_clusters)
+ render_404 unless group_clusters_enabled?
+ end
+
+ def group_clusters_enabled?
+ group.group_clusters_enabled?
end
end
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 95a014d24da..a6bfb913900 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -22,7 +22,7 @@ class Projects::BranchesController < Projects::ApplicationController
# Fetch branches for the specified mode
fetch_branches_by_mode
- @refs_pipelines = @project.pipelines.latest_successful_for_refs(@branches.map(&:name))
+ @refs_pipelines = @project.ci_pipelines.latest_successful_for_refs(@branches.map(&:name))
@merged_branch_names = repository.merged_branch_names(@branches.map(&:name))
# n+1: https://gitlab.com/gitlab-org/gitaly/issues/992
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index b3d77335c2a..ddffbb17ace 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -22,12 +22,9 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
def render_diffs
@environment = @merge_request.environments_for(current_user).last
- notes_grouped_by_path = renderable_notes.group_by { |note| note.position.file_path }
- @diffs.diff_files.each do |diff_file|
- notes = notes_grouped_by_path.fetch(diff_file.file_path, [])
- notes.each { |note| diff_file.unfold_diff_lines(note.position) }
- end
+ note_positions = renderable_notes.map(&:position).compact
+ @diffs.unfold_diff_files(note_positions)
@diffs.write_cache
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 53b29d4146e..67827b1d3bb 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -46,7 +46,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def new
- @pipeline = project.pipelines.new(ref: @project.default_branch)
+ @pipeline = project.all_pipelines.new(ref: @project.default_branch)
end
def create
@@ -142,9 +142,9 @@ class Projects::PipelinesController < Projects::ApplicationController
@charts[:pipeline_times] = Gitlab::Ci::Charts::PipelineTime.new(project)
@counts = {}
- @counts[:total] = @project.pipelines.count(:all)
- @counts[:success] = @project.pipelines.success.count(:all)
- @counts[:failed] = @project.pipelines.failed.count(:all)
+ @counts[:total] = @project.all_pipelines.count(:all)
+ @counts[:success] = @project.all_pipelines.success.count(:all)
+ @counts[:failed] = @project.all_pipelines.failed.count(:all)
end
private
@@ -164,7 +164,7 @@ class Projects::PipelinesController < Projects::ApplicationController
# rubocop: disable CodeReuse/ActiveRecord
def pipeline
@pipeline ||= project
- .pipelines
+ .all_pipelines
.includes(user: :status)
.find_by!(id: params[:id])
.present(current_user: current_user)
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 2b28670a49b..686d66b10a3 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -20,7 +20,7 @@ class Projects::TagsController < Projects::ApplicationController
@tags = Kaminari.paginate_array(@tags).page(params[:page])
tag_names = @tags.map(&:name)
- @tags_pipelines = @project.pipelines.latest_successful_for_refs(tag_names)
+ @tags_pipelines = @project.ci_pipelines.latest_successful_for_refs(tag_names)
@releases = project.releases.where(tag: tag_names)
respond_to do |format|
diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb
index 35d0e1acce5..f5aadc42ff0 100644
--- a/app/finders/pipelines_finder.rb
+++ b/app/finders/pipelines_finder.rb
@@ -8,7 +8,7 @@ class PipelinesFinder
def initialize(project, current_user, params = {})
@project = project
@current_user = current_user
- @pipelines = project.pipelines
+ @pipelines = project.all_pipelines
@params = params
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index e9b9b9b7721..866fc555856 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -140,7 +140,7 @@ module GroupsHelper
can?(current_user, "read_group_#{resource}".to_sym, @group)
end
- if can?(current_user, :read_cluster, @group) && Feature.enabled?(:group_clusters)
+ if can?(current_user, :read_cluster, @group) && @group.group_clusters_enabled?
links << :kubernetes
end
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 8ed2a2ec9f4..74113aee89d 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -120,6 +120,18 @@ module SortingHelper
}
end
+ def users_sort_options_hash
+ {
+ sort_value_name => sort_title_name,
+ sort_value_recently_signin => sort_title_recently_signin,
+ sort_value_oldest_signin => sort_title_oldest_signin,
+ sort_value_recently_created => sort_title_recently_created,
+ sort_value_oldest_created => sort_title_oldest_created,
+ sort_value_recently_updated => sort_title_recently_updated,
+ sort_value_oldest_updated => sort_title_oldest_updated
+ }
+ end
+
def sortable_item(item, path, sorted_by)
link_to item, path, class: sorted_by == item ? 'is-active' : ''
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index a0b2acd502b..60ff2181a95 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -12,13 +12,14 @@ module Ci
include AtomicInternalId
include EnumWithNil
- belongs_to :project, inverse_of: :pipelines
+ belongs_to :project, inverse_of: :all_pipelines
belongs_to :user
belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline'
belongs_to :pipeline_schedule, class_name: 'Ci::PipelineSchedule'
+ belongs_to :merge_request, class_name: 'MergeRequest'
has_internal_id :iid, scope: :project, presence: false, init: ->(s) do
- s&.project&.pipelines&.maximum(:iid) || s&.project&.pipelines&.count
+ s&.project&.all_pipelines&.maximum(:iid) || s&.project&.all_pipelines&.count
end
has_many :stages, -> { order(position: :asc) }, inverse_of: :pipeline
@@ -50,6 +51,9 @@ module Ci
validates :sha, presence: { unless: :importing? }
validates :ref, presence: { unless: :importing? }
+ validates :merge_request, presence: { if: :merge_request? }
+ validates :merge_request, absence: { unless: :merge_request? }
+ validates :tag, inclusion: { in: [false], if: :merge_request? }
validates :status, presence: { unless: :importing? }
validate :valid_commit_sha, unless: :importing?
@@ -170,6 +174,14 @@ module Ci
end
scope :internal, -> { where(source: internal_sources) }
+ scope :ci_sources, -> { where(config_source: ci_sources_values) }
+
+ scope :sort_by_merge_request_pipelines, -> do
+ sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC'
+ query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, sources[:merge_request]]) # rubocop:disable GitlabSecurity/PublicSend
+
+ order(query)
+ end
scope :for_user, -> (user) { where(user: user) }
@@ -260,6 +272,10 @@ module Ci
sources.reject { |source| source == "external" }.values
end
+ def self.ci_sources_values
+ config_sources.values_at(:repository_source, :auto_devops_source, :unknown_source)
+ end
+
def stages_count
statuses.select(:stage).distinct.count
end
@@ -372,7 +388,7 @@ module Ci
end
def branch?
- !tag?
+ !tag? && !merge_request?
end
def stuck?
@@ -619,7 +635,12 @@ module Ci
# All the merge requests for which the current pipeline runs/ran against
def all_merge_requests
- @all_merge_requests ||= project.merge_requests.where(source_branch: ref)
+ @all_merge_requests ||=
+ if merge_request?
+ project.merge_requests.where(id: merge_request.id)
+ else
+ project.merge_requests.where(source_branch: ref)
+ end
end
def detailed_status(current_user)
@@ -696,6 +717,8 @@ module Ci
def git_ref
if branch?
Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
+ elsif merge_request?
+ Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
elsif tag?
Gitlab::Git::TAG_REF_PREFIX + ref.to_s
else
diff --git a/app/models/ci/pipeline_enums.rb b/app/models/ci/pipeline_enums.rb
index 8d8d16e2ec1..c0f16066e0b 100644
--- a/app/models/ci/pipeline_enums.rb
+++ b/app/models/ci/pipeline_enums.rb
@@ -21,7 +21,8 @@ module Ci
trigger: 3,
schedule: 4,
api: 5,
- external: 6
+ external: 6,
+ merge_request: 10
}
end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 260348c97b2..2693386443a 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -114,7 +114,8 @@ module Ci
cached_attr_reader :version, :revision, :platform, :architecture, :ip_address, :contacted_at
- chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout
+ chronic_duration_attr :maximum_timeout_human_readable, :maximum_timeout,
+ error_message: 'Maximum job timeout has a value which could not be accepted'
validates :maximum_timeout, allow_nil: true,
numericality: { greater_than_or_equal_to: 600,
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 13906c903b9..c9bd1728dbd 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -4,6 +4,7 @@ module Clusters
class Cluster < ActiveRecord::Base
include Presentable
include Gitlab::Utils::StrongMemoize
+ include FromUnion
self.table_name = 'clusters'
@@ -86,6 +87,19 @@ module Clusters
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
+ scope :missing_kubernetes_namespace, -> (kubernetes_namespaces) do
+ subquery = kubernetes_namespaces.select('1').where('clusters_kubernetes_namespaces.cluster_id = clusters.id')
+
+ where('NOT EXISTS (?)', subquery)
+ end
+
+ def self.ancestor_clusters_for_clusterable(clusterable, hierarchy_order: :asc)
+ hierarchy_groups = clusterable.ancestors_upto(hierarchy_order: hierarchy_order).eager_load(:clusters)
+ hierarchy_groups = hierarchy_groups.merge(current_scope) if current_scope
+
+ hierarchy_groups.flat_map(&:clusters)
+ end
+
def status_name
if provider
provider.status_name
@@ -122,6 +136,16 @@ module Clusters
!user?
end
+ def all_projects
+ if project_type?
+ projects
+ elsif group_type?
+ first_group.all_projects
+ else
+ Project.none
+ end
+ end
+
def first_project
strong_memoize(:first_project) do
projects.first
@@ -140,11 +164,17 @@ module Clusters
platform_kubernetes.kubeclient if kubernetes?
end
- def find_or_initialize_kubernetes_namespace(cluster_project)
- kubernetes_namespaces.find_or_initialize_by(
- project: cluster_project.project,
- cluster_project: cluster_project
- )
+ def find_or_initialize_kubernetes_namespace_for_project(project)
+ if project_type?
+ kubernetes_namespaces.find_or_initialize_by(
+ project: project,
+ cluster_project: cluster_project
+ )
+ else
+ kubernetes_namespaces.find_or_initialize_by(
+ project: project
+ )
+ end
end
def allow_user_defined_namespace?
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 546fcc54a15..2c89da88b9b 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -298,7 +298,7 @@ class Commit
end
def pipelines
- project.pipelines.where(sha: sha)
+ project.ci_pipelines.where(sha: sha)
end
def last_pipeline
@@ -312,7 +312,7 @@ class Commit
end
def status_for_project(ref, pipeline_project)
- pipeline_project.pipelines.latest_status_per_commit(id, ref)[id]
+ pipeline_project.ci_pipelines.latest_status_per_commit(id, ref)[id]
end
def set_status_for_ref(ref, status)
diff --git a/app/models/commit_collection.rb b/app/models/commit_collection.rb
index dd93af9df64..e349f0fe971 100644
--- a/app/models/commit_collection.rb
+++ b/app/models/commit_collection.rb
@@ -24,7 +24,7 @@ class CommitCollection
# Setting this status ahead of time removes the need for running a query for
# every commit we're displaying.
def with_pipeline_status
- statuses = project.pipelines.latest_status_per_commit(map(&:id), ref)
+ statuses = project.ci_pipelines.latest_status_per_commit(map(&:id), ref)
each do |commit|
commit.set_status_for_ref(ref, statuses[commit.id])
diff --git a/app/models/concerns/chronic_duration_attribute.rb b/app/models/concerns/chronic_duration_attribute.rb
index edf6ac96730..af4905115b1 100644
--- a/app/models/concerns/chronic_duration_attribute.rb
+++ b/app/models/concerns/chronic_duration_attribute.rb
@@ -24,7 +24,7 @@ module ChronicDurationAttribute
end
end
- validates virtual_attribute, allow_nil: true, duration: true
+ validates virtual_attribute, allow_nil: true, duration: { message: parameters[:error_message] }
end
alias_method :chronic_duration_attr, :chronic_duration_attr_writer
diff --git a/app/models/concerns/deployment_platform.rb b/app/models/concerns/deployment_platform.rb
index e57a3383544..0107af5f8ec 100644
--- a/app/models/concerns/deployment_platform.rb
+++ b/app/models/concerns/deployment_platform.rb
@@ -13,6 +13,7 @@ module DeploymentPlatform
def find_deployment_platform(environment)
find_cluster_platform_kubernetes(environment: environment) ||
+ find_group_cluster_platform_kubernetes_with_feature_guard(environment: environment) ||
find_kubernetes_service_integration ||
build_cluster_and_deployment_platform
end
@@ -23,6 +24,18 @@ module DeploymentPlatform
.last&.platform_kubernetes
end
+ def find_group_cluster_platform_kubernetes_with_feature_guard(environment: nil)
+ return unless group_clusters_enabled?
+
+ find_group_cluster_platform_kubernetes(environment: environment)
+ end
+
+ # EE would override this and utilize environment argument
+ def find_group_cluster_platform_kubernetes(environment: nil)
+ Clusters::Cluster.enabled.default_environment.ancestor_clusters_for_clusterable(self)
+ .first&.platform_kubernetes
+ end
+
def find_kubernetes_service_integration
services.deployment.reorder(nil).find_by(active: true)
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 02ddc8762af..233747cc2c2 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -400,6 +400,10 @@ class Group < Namespace
ensure_runners_token!
end
+ def group_clusters_enabled?
+ Feature.enabled?(:group_clusters, root_ancestor, default_enabled: true)
+ end
+
private
def update_two_factor_requirement
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 92add079a02..f40dff7c1bd 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -63,6 +63,7 @@ class MergeRequest < ActiveRecord::Base
dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :cached_closes_issues, through: :merge_requests_closing_issues, source: :issue
+ has_many :merge_request_pipelines, foreign_key: 'merge_request_id', class_name: 'Ci::Pipeline'
belongs_to :assignee, class_name: "User"
@@ -1052,12 +1053,17 @@ class MergeRequest < ActiveRecord::Base
diverged_commits_count > 0
end
- def all_pipelines
+ def all_pipelines(shas: all_commit_shas)
return Ci::Pipeline.none unless source_project
- @all_pipelines ||= source_project.pipelines
- .where(sha: all_commit_shas, ref: source_branch)
- .order(id: :desc)
+ @all_pipelines ||= source_project.ci_pipelines
+ .where(sha: shas, ref: source_branch)
+ .where(merge_request: [nil, self])
+ .sort_by_merge_request_pipelines
+ end
+
+ def merge_request_pipeline_exists?
+ merge_request_pipelines.exists?(sha: diff_head_sha)
end
def has_test_reports?
@@ -1214,7 +1220,7 @@ class MergeRequest < ActiveRecord::Base
end
def base_pipeline
- @base_pipeline ||= project.pipelines
+ @base_pipeline ||= project.ci_pipelines
.order(id: :desc)
.find_by(sha: diff_base_sha)
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 11b03846f0b..8865c164b11 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -192,9 +192,9 @@ class Namespace < ActiveRecord::Base
# returns all ancestors upto but excluding the given namespace
# when no namespace is given, all ancestors upto the top are returned
- def ancestors_upto(top = nil)
+ def ancestors_upto(top = nil, hierarchy_order: nil)
Gitlab::GroupHierarchy.new(self.class.where(id: id))
- .ancestors(upto: top)
+ .ancestors(upto: top, hierarchy_order: hierarchy_order)
end
def self_and_ancestors
@@ -243,7 +243,7 @@ class Namespace < ActiveRecord::Base
end
def root_ancestor
- ancestors.reorder(nil).find_by(parent_id: nil)
+ self_and_ancestors.reorder(nil).find_by(parent_id: nil)
end
def subgroup?
diff --git a/app/models/project.rb b/app/models/project.rb
index 6ec323b58c2..587bada469e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -238,6 +238,7 @@ class Project < ActiveRecord::Base
has_one :cluster_project, class_name: 'Clusters::Project'
has_many :clusters, through: :cluster_project, class_name: 'Clusters::Cluster'
has_many :cluster_ingresses, through: :clusters, source: :application_ingress, class_name: 'Clusters::Applications::Ingress'
+ has_many :kubernetes_namespaces, class_name: 'Clusters::KubernetesNamespace'
has_many :prometheus_metrics
@@ -247,7 +248,17 @@ class Project < ActiveRecord::Base
has_many :container_repositories, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :commit_statuses
- has_many :pipelines, class_name: 'Ci::Pipeline', inverse_of: :project
+ # The relation :all_pipelines is intented to be used when we want to get the
+ # whole list of pipelines associated to the project
+ has_many :all_pipelines, class_name: 'Ci::Pipeline', inverse_of: :project
+ # The relation :ci_pipelines is intented to be used when we want to get only
+ # those pipeline which are directly related to CI. There are
+ # other pipelines, like webide ones, that we won't retrieve
+ # if we use this relation.
+ has_many :ci_pipelines,
+ -> { Feature.enabled?(:pipeline_ci_sources_only, default_enabled: true) ? ci_sources : all },
+ class_name: 'Ci::Pipeline',
+ inverse_of: :project
has_many :stages, class_name: 'Ci::Stage', inverse_of: :project
# Ci::Build objects store data on the file system such as artifact files and
@@ -290,6 +301,8 @@ class Project < ActiveRecord::Base
delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_role, to: :team
delegate :add_master, to: :team # @deprecated
delegate :group_runners_enabled, :group_runners_enabled=, :group_runners_enabled?, to: :ci_cd_settings
+ delegate :group_clusters_enabled?, to: :group, allow_nil: true
+ delegate :root_ancestor, to: :namespace, allow_nil: true
# Validations
validates :creator, presence: true, on: :create
@@ -382,9 +395,16 @@ class Project < ActiveRecord::Base
.where(project_ci_cd_settings: { group_runners_enabled: true })
end
+ scope :missing_kubernetes_namespace, -> (kubernetes_namespaces) do
+ subquery = kubernetes_namespaces.select('1').where('clusters_kubernetes_namespaces.project_id = projects.id')
+
+ where('NOT EXISTS (?)', subquery)
+ end
+
enum auto_cancel_pending_pipelines: { disabled: 0, enabled: 1 }
- chronic_duration_attr :build_timeout_human_readable, :build_timeout, default: 3600
+ chronic_duration_attr :build_timeout_human_readable, :build_timeout,
+ default: 3600, error_message: 'Maximum job timeout has a value which could not be accepted'
validates :build_timeout, allow_nil: true,
numericality: { greater_than_or_equal_to: 10.minutes,
@@ -545,9 +565,9 @@ class Project < ActiveRecord::Base
# returns all ancestor-groups upto but excluding the given namespace
# when no namespace is given, all ancestors upto the top are returned
- def ancestors_upto(top = nil)
+ def ancestors_upto(top = nil, hierarchy_order: nil)
Gitlab::GroupHierarchy.new(Group.where(id: namespace_id))
- .base_and_ancestors(upto: top)
+ .base_and_ancestors(upto: top, hierarchy_order: hierarchy_order)
end
def lfs_enabled?
@@ -620,7 +640,7 @@ class Project < ActiveRecord::Base
# ref can't be HEAD, can only be branch/tag name or SHA
def latest_successful_builds_for(ref = default_branch)
- latest_pipeline = pipelines.latest_successful_for(ref)
+ latest_pipeline = ci_pipelines.latest_successful_for(ref)
if latest_pipeline
latest_pipeline.builds.latest.with_artifacts_archive
@@ -1060,6 +1080,12 @@ class Project < ActiveRecord::Base
path
end
+ def all_clusters
+ group_clusters = Clusters::Cluster.joins(:groups).where(cluster_groups: { group_id: ancestors_upto } )
+
+ Clusters::Cluster.from_union([clusters, group_clusters])
+ end
+
def items_for(entity)
case entity
when 'issue' then
@@ -1375,7 +1401,7 @@ class Project < ActiveRecord::Base
return unless sha
- pipelines.order(id: :desc).find_by(sha: sha, ref: ref)
+ ci_pipelines.order(id: :desc).find_by(sha: sha, ref: ref)
end
def latest_successful_pipeline_for_default_branch
@@ -1384,12 +1410,12 @@ class Project < ActiveRecord::Base
end
@latest_successful_pipeline_for_default_branch =
- pipelines.latest_successful_for(default_branch)
+ ci_pipelines.latest_successful_for(default_branch)
end
def latest_successful_pipeline_for(ref = nil)
if ref && ref != default_branch
- pipelines.latest_successful_for(ref)
+ ci_pipelines.latest_successful_for(ref)
else
latest_successful_pipeline_for_default_branch
end
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index 6f39a5e6e83..d60a6a7efa3 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -38,11 +38,11 @@ class PipelinesEmailService < Service
end
def can_test?
- project.pipelines.any?
+ project.ci_pipelines.any?
end
def test_data(project, user)
- data = Gitlab::DataBuilder::Pipeline.build(project.pipelines.last)
+ data = Gitlab::DataBuilder::Pipeline.build(project.ci_pipelines.last)
data[:user] = user.hook_attrs
data
end
diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb
index aef838409e0..477b6710168 100644
--- a/app/serializers/pipeline_entity.rb
+++ b/app/serializers/pipeline_entity.rb
@@ -48,6 +48,7 @@ class PipelineEntity < Grape::Entity
expose :tag?, as: :tag
expose :branch?, as: :branch
+ expose :merge_request?, as: :merge_request
end
expose :commit, using: CommitEntity
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 46a82377c10..19b5552887f 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -14,7 +14,7 @@ module Ci
Gitlab::Ci::Pipeline::Chain::Populate,
Gitlab::Ci::Pipeline::Chain::Create].freeze
- def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, &block)
+ def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, merge_request: nil, &block)
@pipeline = Ci::Pipeline.new
command = Gitlab::Ci::Pipeline::Chain::Command.new(
@@ -25,6 +25,7 @@ module Ci
before_sha: params[:before],
trigger_request: trigger_request,
schedule: schedule,
+ merge_request: merge_request,
ignore_skip_ci: ignore_skip_ci,
save_incompleted: save_on_errors,
seeds_block: block,
@@ -77,7 +78,7 @@ module Ci
# rubocop: disable CodeReuse/ActiveRecord
def auto_cancelable_pipelines
- project.pipelines
+ project.ci_pipelines
.where(ref: pipeline.ref)
.where.not(id: pipeline.id)
.where.not(sha: project.commit(pipeline.ref).try(:id))
diff --git a/app/services/clusters/refresh_service.rb b/app/services/clusters/refresh_service.rb
new file mode 100644
index 00000000000..7c82b98a33f
--- /dev/null
+++ b/app/services/clusters/refresh_service.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Clusters
+ class RefreshService
+ def self.create_or_update_namespaces_for_cluster(cluster)
+ projects_with_missing_kubernetes_namespaces_for_cluster(cluster).each do |project|
+ create_or_update_namespace(cluster, project)
+ end
+ end
+
+ def self.create_or_update_namespaces_for_project(project)
+ clusters_with_missing_kubernetes_namespaces_for_project(project).each do |cluster|
+ create_or_update_namespace(cluster, project)
+ end
+ end
+
+ def self.projects_with_missing_kubernetes_namespaces_for_cluster(cluster)
+ cluster.all_projects.missing_kubernetes_namespace(cluster.kubernetes_namespaces)
+ end
+
+ private_class_method :projects_with_missing_kubernetes_namespaces_for_cluster
+
+ def self.clusters_with_missing_kubernetes_namespaces_for_project(project)
+ project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces)
+ end
+
+ private_class_method :clusters_with_missing_kubernetes_namespaces_for_project
+
+ def self.create_or_update_namespace(cluster, project)
+ kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project)
+
+ ::Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
+ cluster: cluster,
+ kubernetes_namespace: kubernetes_namespace
+ ).execute
+ end
+
+ private_class_method :create_or_update_namespace
+ end
+end
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 28c3219b37b..fe19abf50f6 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -54,6 +54,24 @@ module MergeRequests
merge_request, merge_request.project, current_user, merge_request.assignee)
end
+ def create_merge_request_pipeline(merge_request, user)
+ return unless Feature.enabled?(:ci_merge_request_pipeline,
+ merge_request.source_project,
+ default_enabled: true)
+
+ ##
+ # UpdateMergeRequestsWorker could be retried by an exception.
+ # MR pipelines should not be recreated in such case.
+ return if merge_request.merge_request_pipeline_exists?
+
+ Ci::CreatePipelineService
+ .new(merge_request.source_project, user, ref: merge_request.source_branch)
+ .execute(:merge_request,
+ ignore_skip_ci: true,
+ save_on_errors: false,
+ merge_request: merge_request)
+ end
+
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.
# rubocop: disable CodeReuse/ActiveRecord
def merge_requests_for(source_branch, mr_states: [:opened])
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index 6081a7d1de0..7bb9fa60515 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -25,6 +25,7 @@ module MergeRequests
def after_create(issuable)
todo_service.new_merge_request(issuable, current_user)
issuable.cache_merge_request_closes_issues!(current_user)
+ create_merge_request_pipeline(issuable, current_user)
update_merge_requests_head_pipeline(issuable)
super
@@ -49,18 +50,14 @@ module MergeRequests
merge_request.update(head_pipeline_id: pipeline.id) if pipeline
end
- # rubocop: disable CodeReuse/ActiveRecord
def head_pipeline_for(merge_request)
return unless merge_request.source_project
sha = merge_request.source_branch_sha
return unless sha
- pipelines = merge_request.source_project.pipelines.where(ref: merge_request.source_branch, sha: sha)
-
- pipelines.order(id: :desc).first
+ merge_request.all_pipelines(shas: sha).first
end
- # rubocop: enable CodeReuse/ActiveRecord
def set_projects!
# @project is used to determine whether the user can set the merge request's
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index 5fe48da1cd6..667b5916f38 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -92,6 +92,7 @@ module MergeRequests
end
merge_request.mark_as_unchecked
+ create_merge_request_pipeline(merge_request, current_user)
UpdateHeadPipelineForMergeRequestWorker.perform_async(merge_request.id)
end
diff --git a/app/services/projects/auto_devops/disable_service.rb b/app/services/projects/auto_devops/disable_service.rb
index 1b578a3c5ce..6608b3da1a8 100644
--- a/app/services/projects/auto_devops/disable_service.rb
+++ b/app/services/projects/auto_devops/disable_service.rb
@@ -34,7 +34,7 @@ module Projects
end
def auto_devops_pipelines
- @auto_devops_pipelines ||= project.pipelines.auto_devops_source
+ @auto_devops_pipelines ||= project.ci_pipelines.auto_devops_source
end
end
end
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 9e77a3237e3..d03137b63b2 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -96,6 +96,8 @@ module Projects
current_user.invalidate_personal_projects_count
create_readme if @initialize_with_readme
+
+ configure_group_clusters_for_project
end
# Refresh the current user's authorizations inline (so they can access the
@@ -121,6 +123,10 @@ module Projects
Files::CreateService.new(@project, current_user, commit_attrs).execute
end
+ def configure_group_clusters_for_project
+ ClusterProjectConfigureWorker.perform_async(@project.id)
+ end
+
def skip_wiki?
!@project.feature_available?(:wiki, current_user) || @skip_wiki
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 9d40ab166ff..9db3fd9cf17 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -54,6 +54,7 @@ module Projects
end
attempt_transfer_transaction
+ configure_group_clusters_for_project
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -162,5 +163,9 @@ module Projects
@new_namespace.full_path
)
end
+
+ def configure_group_clusters_for_project
+ ClusterProjectConfigureWorker.perform_async(project.id)
+ end
end
end
diff --git a/app/services/test_hooks/project_service.rb b/app/services/test_hooks/project_service.rb
index 45e0e61e5c4..7e14ddcd017 100644
--- a/app/services/test_hooks/project_service.rb
+++ b/app/services/test_hooks/project_service.rb
@@ -49,7 +49,7 @@ module TestHooks
end
def pipeline_events_data
- pipeline = project.pipelines.first
+ pipeline = project.ci_pipelines.first
throw(:validation_error, 'Ensure the project has CI pipelines.') unless pipeline.present?
Gitlab::DataBuilder::Pipeline.build(pipeline)
diff --git a/app/validators/duration_validator.rb b/app/validators/duration_validator.rb
index 811828169ca..defd28d7d3b 100644
--- a/app/validators/duration_validator.rb
+++ b/app/validators/duration_validator.rb
@@ -14,6 +14,10 @@ class DurationValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
ChronicDuration.parse(value)
rescue ChronicDuration::DurationParseError
- record.errors.add(attribute, "is not a correct duration")
+ if options[:message]
+ record.errors.add(:base, options[:message])
+ else
+ record.errors.add(attribute, "is not a correct duration")
+ end
end
end
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index f910e90d6ca..600120c4f05 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -9,28 +9,20 @@
.search-holder
.search-field-holder
= search_field_tag :search_query, params[:search_query], placeholder: 'Search by name, email or username', class: 'form-control search-text-input js-search-input', spellcheck: false
+ - if @sort.present?
+ = hidden_field_tag :sort, @sort
= icon("search", class: "search-icon")
- .dropdown
- - toggle_text = if @sort.present? then sort_options_hash[@sort] else sort_title_name end
+ = button_tag 'Search users' if Rails.env.test?
+ .dropdown.user-sort-dropdown
+ - toggle_text = if @sort.present? then users_sort_options_hash[@sort] else sort_title_name end
= dropdown_toggle(toggle_text, { toggle: 'dropdown' })
%ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header
Sort by
%li
- = link_to admin_users_path(sort: sort_value_name, filter: params[:filter]) do
- = sort_title_name
- = link_to admin_users_path(sort: sort_value_recently_signin, filter: params[:filter]) do
- = sort_title_recently_signin
- = link_to admin_users_path(sort: sort_value_oldest_signin, filter: params[:filter]) do
- = sort_title_oldest_signin
- = link_to admin_users_path(sort: sort_value_recently_created, filter: params[:filter]) do
- = sort_title_recently_created
- = link_to admin_users_path(sort: sort_value_oldest_created, filter: params[:filter]) do
- = sort_title_oldest_created
- = link_to admin_users_path(sort: sort_value_recently_updated, filter: params[:filter]) do
- = sort_title_recently_updated
- = link_to admin_users_path(sort: sort_value_oldest_updated, filter: params[:filter]) do
- = sort_title_oldest_updated
+ - users_sort_options_hash.each do |value, title|
+ = link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do
+ = title
= link_to 'New user', new_admin_user_path, class: 'btn btn-success btn-search'
.top-area.scrolling-tabs-container.inner-page-scroll-tabs
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index 621b7922072..bb328f5344c 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -29,7 +29,7 @@
= f.label :build_timeout_human_readable, _('Timeout'), class: 'label-bold'
= f.text_field :build_timeout_human_readable, class: 'form-control'
%p.form-text.text-muted
- = _("Per job. If a job passes this threshold, it will be marked as failed")
+ = _('If any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like "1 hour". Values without specification represent seconds.')
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'timeout'), target: '_blank'
%hr
diff --git a/app/views/shared/runners/_form.html.haml b/app/views/shared/runners/_form.html.haml
index daf08d9bb2c..559b5aa9c1e 100644
--- a/app/views/shared/runners/_form.html.haml
+++ b/app/views/shared/runners/_form.html.haml
@@ -45,7 +45,7 @@
= _('Maximum job timeout')
.col-sm-10
= f.text_field :maximum_timeout_human_readable, class: 'form-control'
- .form-text.text-muted= _('This timeout will take precedence when lower than Project-defined timeout')
+ .form-text.text-muted= _('This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like "1 hour". Values without specification represent seconds.')
.form-group.row
= label_tag :tag_list, class: 'col-form-label col-sm-2' do
= _('Tags')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index c0b410472eb..e51da79c6b5 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -29,6 +29,7 @@
- gcp_cluster:wait_for_cluster_creation
- gcp_cluster:cluster_wait_for_ingress_ip_address
- gcp_cluster:cluster_platform_configure
+- gcp_cluster:cluster_project_configure
- github_import_advance_stage
- github_importer:github_import_import_diff_note
diff --git a/app/workers/cluster_platform_configure_worker.rb b/app/workers/cluster_platform_configure_worker.rb
index 8f3689f0166..aa7570caa79 100644
--- a/app/workers/cluster_platform_configure_worker.rb
+++ b/app/workers/cluster_platform_configure_worker.rb
@@ -6,17 +6,7 @@ class ClusterPlatformConfigureWorker
def perform(cluster_id)
Clusters::Cluster.find_by_id(cluster_id).try do |cluster|
- next unless cluster.cluster_project
-
- kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace(cluster.cluster_project)
-
- Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
- cluster: cluster,
- kubernetes_namespace: kubernetes_namespace
- ).execute
+ Clusters::RefreshService.create_or_update_namespaces_for_cluster(cluster)
end
-
- rescue ::Kubeclient::HttpError => err
- Rails.logger.error "Failed to create/update Kubernetes namespace for cluster_id: #{cluster_id} with error: #{err.message}"
end
end
diff --git a/app/workers/cluster_project_configure_worker.rb b/app/workers/cluster_project_configure_worker.rb
new file mode 100644
index 00000000000..497e57c0d0b
--- /dev/null
+++ b/app/workers/cluster_project_configure_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class ClusterProjectConfigureWorker
+ include ApplicationWorker
+ include ClusterQueue
+
+ def perform(project_id)
+ project = Project.find(project_id)
+
+ ::Clusters::RefreshService.create_or_update_namespaces_for_project(project)
+ end
+end
diff --git a/app/workers/update_head_pipeline_for_merge_request_worker.rb b/app/workers/update_head_pipeline_for_merge_request_worker.rb
index 9ce51662969..e8494ffa002 100644
--- a/app/workers/update_head_pipeline_for_merge_request_worker.rb
+++ b/app/workers/update_head_pipeline_for_merge_request_worker.rb
@@ -6,10 +6,11 @@ class UpdateHeadPipelineForMergeRequestWorker
queue_namespace :pipeline_processing
- # rubocop: disable CodeReuse/ActiveRecord
def perform(merge_request_id)
merge_request = MergeRequest.find(merge_request_id)
- pipeline = Ci::Pipeline.where(project: merge_request.source_project, ref: merge_request.source_branch).last
+
+ sha = merge_request.diff_head_sha
+ pipeline = merge_request.all_pipelines(shas: sha).first
return unless pipeline && pipeline.latest?
@@ -21,7 +22,6 @@ class UpdateHeadPipelineForMergeRequestWorker
merge_request.update_attribute(:head_pipeline_id, pipeline.id)
end
- # rubocop: enable CodeReuse/ActiveRecord
def log_error_message_for(merge_request)
Rails.logger.error(
diff --git a/changelogs/unreleased/34758-deployment-cluster.yml b/changelogs/unreleased/34758-deployment-cluster.yml
new file mode 100644
index 00000000000..06374098343
--- /dev/null
+++ b/changelogs/unreleased/34758-deployment-cluster.yml
@@ -0,0 +1,5 @@
+---
+title: Use group clusters when deploying (DeploymentPlatform)
+merge_request: 22308
+author:
+type: changed
diff --git a/changelogs/unreleased/50626-searching-users-by-the-admin-panel-wipes-query-when-using-sort.yml b/changelogs/unreleased/50626-searching-users-by-the-admin-panel-wipes-query-when-using-sort.yml
new file mode 100644
index 00000000000..c3251fea54d
--- /dev/null
+++ b/changelogs/unreleased/50626-searching-users-by-the-admin-panel-wipes-query-when-using-sort.yml
@@ -0,0 +1,5 @@
+---
+title: Allow search and sort users at same time on admin users page
+merge_request: 23439
+author:
+type: fixed
diff --git a/changelogs/unreleased/54826-use-read_repository-scope-on-read-only-files-endpoints.yml b/changelogs/unreleased/54826-use-read_repository-scope-on-read-only-files-endpoints.yml
new file mode 100644
index 00000000000..ef8e93fca43
--- /dev/null
+++ b/changelogs/unreleased/54826-use-read_repository-scope-on-read-only-files-endpoints.yml
@@ -0,0 +1,5 @@
+---
+title: Use read_repository scope on read-only files API
+merge_request: 23534
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-gb-improve-timeout-inputs-help-sections.yml b/changelogs/unreleased/fix-gb-improve-timeout-inputs-help-sections.yml
new file mode 100644
index 00000000000..52b431edf2c
--- /dev/null
+++ b/changelogs/unreleased/fix-gb-improve-timeout-inputs-help-sections.yml
@@ -0,0 +1,5 @@
+---
+title: Improve help and validation sections of maximum build timeout inputs
+merge_request: 23586
+author:
+type: fixed
diff --git a/changelogs/unreleased/mr-pipelines-2.yml b/changelogs/unreleased/mr-pipelines-2.yml
new file mode 100644
index 00000000000..683c626c3ce
--- /dev/null
+++ b/changelogs/unreleased/mr-pipelines-2.yml
@@ -0,0 +1,5 @@
+---
+title: Merge request pipelines
+merge_request: 23217
+author:
+type: added
diff --git a/changelogs/unreleased/multiple-diff-line-discussions-fix.yml b/changelogs/unreleased/multiple-diff-line-discussions-fix.yml
new file mode 100644
index 00000000000..870a8ab3815
--- /dev/null
+++ b/changelogs/unreleased/multiple-diff-line-discussions-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Fixed duplicate discussions getting added to diff lines
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/osw-fix-grouping-by-file-path.yml b/changelogs/unreleased/osw-fix-grouping-by-file-path.yml
new file mode 100644
index 00000000000..dff3116e7c6
--- /dev/null
+++ b/changelogs/unreleased/osw-fix-grouping-by-file-path.yml
@@ -0,0 +1,5 @@
+---
+title: Avoid 500's when serializing legacy diff notes
+merge_request: 23544
+author:
+type: fixed
diff --git a/config/jest.config.js b/config/jest.config.js
new file mode 100644
index 00000000000..23e62f49be1
--- /dev/null
+++ b/config/jest.config.js
@@ -0,0 +1,27 @@
+/* eslint-disable filenames/match-regex */
+
+const reporters = ['default'];
+
+if (process.env.CI) {
+ reporters.push([
+ 'jest-junit',
+ {
+ output: './junit_jest.xml',
+ },
+ ]);
+}
+
+// eslint-disable-next-line import/no-commonjs
+module.exports = {
+ testMatch: ['<rootDir>/spec/frontend/**/*_spec.js'],
+ moduleNameMapper: {
+ '^~(.*)$': '<rootDir>/app/assets/javascripts$1',
+ },
+ collectCoverageFrom: ['<rootDir>/app/assets/javascripts/**/*.{js,vue}'],
+ coverageDirectory: '<rootDir>/coverage-frontend/',
+ coverageReporters: ['json', 'lcov', 'text-summary', 'clover'],
+ cacheDirectory: '<rootDir>/tmp/cache/jest',
+ modulePathIgnorePatterns: ['<rootDir>/.yarn-cache/'],
+ reporters,
+ rootDir: '..', // necessary because this file is in the config/ subdirectory
+};
diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile
index 713ed95a04c..530c6638653 100644
--- a/danger/changelog/Dangerfile
+++ b/danger/changelog/Dangerfile
@@ -2,7 +2,7 @@
require 'yaml'
-NO_CHANGELOG_LABELS = %w[backstage Documentation QA test].freeze
+NO_CHANGELOG_LABELS = %w[backstage ci-build Documentation meta QA test].freeze
SEE_DOC = "See [the documentation](https://docs.gitlab.com/ce/development/changelog.html).".freeze
CREATE_CHANGELOG_MESSAGE = <<~MSG.freeze
You can create one with:
diff --git a/db/fixtures/development/14_pipelines.rb b/db/fixtures/development/14_pipelines.rb
index 5af77c49913..bdc0a2db7db 100644
--- a/db/fixtures/development/14_pipelines.rb
+++ b/db/fixtures/development/14_pipelines.rb
@@ -104,7 +104,7 @@ class Gitlab::Seeder::Pipelines
def create_pipeline!(project, ref, commit)
- project.pipelines.create!(sha: commit.id, ref: ref, source: :push)
+ project.ci_pipelines.create!(sha: commit.id, ref: ref, source: :push)
end
def build_create!(pipeline, opts = {})
diff --git a/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb b/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
new file mode 100644
index 00000000000..65476109c61
--- /dev/null
+++ b/db/migrate/20181119081539_add_merge_request_id_to_ci_pipelines.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddMergeRequestIdToCiPipelines < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def up
+ add_column :ci_pipelines, :merge_request_id, :integer
+ end
+
+ def down
+ remove_column :ci_pipelines, :merge_request_id, :integer
+ end
+end
diff --git a/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb b/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
new file mode 100644
index 00000000000..c2b5b239279
--- /dev/null
+++ b/db/migrate/20181120091639_add_foreign_key_to_ci_pipelines_merge_requests.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToCiPipelinesMergeRequests < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_pipelines, :merge_request_id
+ add_concurrent_foreign_key :ci_pipelines, :merge_requests, column: :merge_request_id, on_delete: :cascade
+ end
+
+ def down
+ if foreign_key_exists?(:ci_pipelines, :merge_requests, column: :merge_request_id)
+ remove_foreign_key :ci_pipelines, :merge_requests
+ end
+
+ remove_concurrent_index :ci_pipelines, :merge_request_id
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d048be08d77..65a69c2850c 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -474,7 +474,9 @@ ActiveRecord::Schema.define(version: 20181126153547) do
t.boolean "protected"
t.integer "failure_reason"
t.integer "iid"
+ t.integer "merge_request_id"
t.index ["auto_canceled_by_id"], name: "index_ci_pipelines_on_auto_canceled_by_id", using: :btree
+ t.index ["merge_request_id"], name: "index_ci_pipelines_on_merge_request_id", using: :btree
t.index ["pipeline_schedule_id"], name: "index_ci_pipelines_on_pipeline_schedule_id", using: :btree
t.index ["project_id", "iid"], name: "index_ci_pipelines_on_project_id_and_iid", unique: true, where: "(iid IS NOT NULL)", using: :btree
t.index ["project_id", "ref", "status", "id"], name: "index_ci_pipelines_on_project_id_and_ref_and_status_and_id", using: :btree
@@ -2292,6 +2294,7 @@ ActiveRecord::Schema.define(version: 20181126153547) do
add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
+ add_foreign_key "ci_pipelines", "merge_requests", name: "fk_a23be95014", on_delete: :cascade
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
add_foreign_key "ci_runner_namespaces", "ci_runners", column: "runner_id", on_delete: :cascade
add_foreign_key "ci_runner_namespaces", "namespaces", on_delete: :cascade
diff --git a/doc/api/repository_files.md b/doc/api/repository_files.md
index c3624f1a535..5f587f480b6 100644
--- a/doc/api/repository_files.md
+++ b/doc/api/repository_files.md
@@ -4,6 +4,16 @@
**Create, read, update and delete repository files using this API**
+The different scopes available using [personal access tokens](../user/profile/personal_access_tokens.md) are depicted
+in the following table.
+
+| Scope | Description |
+| ----- | ----------- |
+| `read_repository` | Allows read-access to the repository files. |
+| `api` | Allows read-write access to the repository files. |
+
+> `read_repository` scope was [introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/23534) in GitLab 11.6.
+
## Get file from repository
Allows you to receive information about file in repository like name, size,
diff --git a/doc/development/new_fe_guide/development/testing.md b/doc/development/new_fe_guide/development/testing.md
index 082acbedcd2..0d98180add0 100644
--- a/doc/development/new_fe_guide/development/testing.md
+++ b/doc/development/new_fe_guide/development/testing.md
@@ -6,9 +6,15 @@ Tests relevant for frontend development can be found at two places:
- [frontend unit tests](#frontend-unit-tests)
- [frontend component tests](#frontend-component-tests)
- [frontend integration tests](#frontend-integration-tests)
+- `spec/frontend/` which are run by Jest and contain
+ - [frontend unit tests](#frontend-unit-tests)
+ - [frontend component tests](#frontend-component-tests)
+ - [frontend integration tests](#frontend-integration-tests)
- `spec/features/` which are run by RSpec and contain
- [feature tests](#feature-tests)
+All tests in `spec/javascripts/` will eventually be migrated to `spec/frontend/` (see also [#53757]).
+
In addition there were feature tests in `features/` run by Spinach in the past.
These have been removed from our codebase in May 2018 ([#23036](https://gitlab.com/gitlab-org/gitlab-ce/issues/23036)).
@@ -17,6 +23,8 @@ See also:
- [old testing guide](../../testing_guide/frontend_testing.html)
- [notes on testing Vue components](../../fe_guide/vue.html#testing-vue-components)
+[#53757]: https://gitlab.com/gitlab-org/gitlab-ce/issues/53757
+
## Frontend unit tests
Unit tests are on the lowest abstraction level and typically test functionality that is not directly perceivable by a user.
diff --git a/doc/install/docker.md b/doc/install/docker.md
index c7dc9db70c5..e90f6645b0c 100644
--- a/doc/install/docker.md
+++ b/doc/install/docker.md
@@ -7,9 +7,10 @@ GitLab provides official Docker images to allowing you to easily take advantage
## Omnibus GitLab based images
GitLab maintains a set of [official Docker images](https://hub.docker.com/r/gitlab) based on our [Omnibus GitLab package](https://docs.gitlab.com/omnibus/README.html). These images include:
-* [GitLab Community Edition](https://hub.docker.com/r/gitlab/gitlab-ce/)
-* [GitLab Enterprise Edition](https://hub.docker.com/r/gitlab/gitlab-ee/)
-* [GitLab Runner](https://hub.docker.com/r/gitlab/gitlab-runner/)
+
+- [GitLab Community Edition](https://hub.docker.com/r/gitlab/gitlab-ce/).
+- [GitLab Enterprise Edition](https://hub.docker.com/r/gitlab/gitlab-ee/).
+- [GitLab Runner](https://hub.docker.com/r/gitlab/gitlab-runner/).
A [complete usage guide](https://docs.gitlab.com/omnibus/docker/) to these images is available, as well as the [Dockerfile used for building the images](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/docker).
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index b770f2544d2..4b65b901487 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -6,7 +6,7 @@ password to login, they'll be prompted for a code generated by an application on
their phone.
You can read more about it here:
-[Two-factor Authentication (2FA)](../profile/two_factor_authentication.md)
+[Two-factor Authentication (2FA)](../user/profile/account/two_factor_authentication.md)
## Enforcing 2FA for all users
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index 1ba2c150cb4..62c966e06b4 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -29,7 +29,7 @@ module API
not_found!('Commit') unless user_project.commit(params[:sha])
- pipelines = user_project.pipelines.where(sha: params[:sha])
+ pipelines = user_project.ci_pipelines.where(sha: params[:sha])
statuses = ::CommitStatus.where(pipeline: pipelines)
statuses = statuses.latest unless to_boolean(params[:all])
statuses = statuses.where(ref: params[:ref]) if params[:ref].present?
@@ -75,7 +75,7 @@ module API
pipeline = @project.pipeline_for(ref, commit.sha)
unless pipeline
- pipeline = @project.pipelines.create!(
+ pipeline = @project.ci_pipelines.create!(
source: :external,
sha: commit.sha,
ref: ref,
diff --git a/lib/api/files.rb b/lib/api/files.rb
index becf66d1467..ca59d330e1c 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -2,6 +2,8 @@
module API
class Files < Grape::API
+ include APIGuard
+
FILE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(file_path: API::NO_SLASH_URL_PART_REGEX)
# Prevents returning plain/text responses for files with .txt extension
@@ -79,6 +81,8 @@ module API
requires :id, type: String, desc: 'The project ID'
end
resource :projects, requirements: FILE_ENDPOINT_REQUIREMENTS do
+ allow_access_with_scope :read_repository, if: -> (request) { request.get? || request.head? }
+
desc 'Get raw file metadata from repository'
params do
requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index c3f8a84d742..80a5cbd6b19 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -56,7 +56,7 @@ module API
end
# rubocop: disable CodeReuse/ActiveRecord
get ':id/pipelines/:pipeline_id/jobs' do
- pipeline = user_project.pipelines.find(params[:pipeline_id])
+ pipeline = user_project.ci_pipelines.find(params[:pipeline_id])
builds = pipeline.builds
builds = filter_builds(builds, params[:scope])
builds = builds.preload(:job_artifacts_archive, :job_artifacts, project: [:namespace])
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index 62d07d945e2..7a7b23d2bbb 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -130,7 +130,7 @@ module API
helpers do
def pipeline
- @pipeline ||= user_project.pipelines.find(params[:pipeline_id])
+ @pipeline ||= user_project.ci_pipelines.find(params[:pipeline_id])
end
end
end
diff --git a/lib/gitlab/badge/coverage/report.rb b/lib/gitlab/badge/coverage/report.rb
index a7fcb6b0fca..7f7cc62c8ef 100644
--- a/lib/gitlab/badge/coverage/report.rb
+++ b/lib/gitlab/badge/coverage/report.rb
@@ -14,7 +14,7 @@ module Gitlab
@ref = ref
@job = job
- @pipeline = @project.pipelines.latest_successful_for(@ref)
+ @pipeline = @project.ci_pipelines.latest_successful_for(@ref)
end
def entity
diff --git a/lib/gitlab/badge/pipeline/status.rb b/lib/gitlab/badge/pipeline/status.rb
index 37e61f07e5b..a403d839517 100644
--- a/lib/gitlab/badge/pipeline/status.rb
+++ b/lib/gitlab/badge/pipeline/status.rb
@@ -22,7 +22,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def status
- @project.pipelines
+ @project.ci_pipelines
.where(sha: @sha)
.latest_status(@ref) || 'unknown'
end
diff --git a/lib/gitlab/ci/charts.rb b/lib/gitlab/ci/charts.rb
index a4f01468e8e..7cabaadb122 100644
--- a/lib/gitlab/ci/charts.rb
+++ b/lib/gitlab/ci/charts.rb
@@ -54,7 +54,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def collect
- query = project.pipelines
+ query = project.all_pipelines
.where("? > #{::Ci::Pipeline.table_name}.created_at AND #{::Ci::Pipeline.table_name}.created_at > ?", @to, @from) # rubocop:disable GitlabSecurity/SqlInjection
totals_count = grouped_count(query)
@@ -115,7 +115,7 @@ module Gitlab
class PipelineTime < Chart
def collect
- commits = project.pipelines.last(30)
+ commits = project.all_pipelines.last(30)
commits.each do |commit|
@labels << commit.short_sha
diff --git a/lib/gitlab/ci/pipeline/chain/build.rb b/lib/gitlab/ci/pipeline/chain/build.rb
index b445a872b3d..d33d1edfe35 100644
--- a/lib/gitlab/ci/pipeline/chain/build.rb
+++ b/lib/gitlab/ci/pipeline/chain/build.rb
@@ -16,6 +16,7 @@ module Gitlab
trigger_requests: Array(@command.trigger_request),
user: @command.current_user,
pipeline_schedule: @command.schedule,
+ merge_request: @command.merge_request,
protected: @command.protected_ref?,
variables_attributes: Array(@command.variables_attributes)
)
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 05978804d92..100b9521412 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -8,7 +8,7 @@ module Gitlab
Command = Struct.new(
:source, :project, :current_user,
:origin_ref, :checkout_sha, :after_sha, :before_sha,
- :trigger_request, :schedule,
+ :trigger_request, :schedule, :merge_request,
:ignore_skip_ci, :save_incompleted,
:seeds_block, :variables_attributes
) do
diff --git a/lib/gitlab/diff/file_collection/base.rb b/lib/gitlab/diff/file_collection/base.rb
index 10df037a0dd..c5bbf522f7c 100644
--- a/lib/gitlab/diff/file_collection/base.rb
+++ b/lib/gitlab/diff/file_collection/base.rb
@@ -34,6 +34,16 @@ module Gitlab
@diff_files ||= diffs.decorate! { |diff| decorate_diff!(diff) }
end
+ # This mutates `diff_files` lines.
+ def unfold_diff_files(positions)
+ positions_grouped_by_path = positions.group_by { |position| position.file_path }
+
+ diff_files.each do |diff_file|
+ positions = positions_grouped_by_path.fetch(diff_file.file_path, [])
+ positions.each { |position| diff_file.unfold_diff_lines(position) }
+ end
+ end
+
def diff_file_with_old_path(old_path)
diff_files.find { |diff_file| diff_file.old_path == old_path }
end
diff --git a/lib/gitlab/diff/file_collection/compare.rb b/lib/gitlab/diff/file_collection/compare.rb
index 586c5cf87af..663bad95db7 100644
--- a/lib/gitlab/diff/file_collection/compare.rb
+++ b/lib/gitlab/diff/file_collection/compare.rb
@@ -10,6 +10,10 @@ module Gitlab
diff_options: diff_options,
diff_refs: diff_refs)
end
+
+ def unfold_diff_lines(positions)
+ # no-op
+ end
end
end
end
diff --git a/lib/gitlab/group_hierarchy.rb b/lib/gitlab/group_hierarchy.rb
index c940ea7305e..97cbdc6cb39 100644
--- a/lib/gitlab/group_hierarchy.rb
+++ b/lib/gitlab/group_hierarchy.rb
@@ -34,8 +34,8 @@ module Gitlab
# reached. So all ancestors *lower* than the specified ancestor will be
# included.
# rubocop: disable CodeReuse/ActiveRecord
- def ancestors(upto: nil)
- base_and_ancestors(upto: upto).where.not(id: ancestors_base.select(:id))
+ def ancestors(upto: nil, hierarchy_order: nil)
+ base_and_ancestors(upto: upto, hierarchy_order: hierarchy_order).where.not(id: ancestors_base.select(:id))
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -45,11 +45,22 @@ module Gitlab
# Passing an `upto` will stop the recursion once the specified parent_id is
# reached. So all ancestors *lower* than the specified acestor will be
# included.
- def base_and_ancestors(upto: nil)
+ #
+ # Passing a `hierarchy_order` with either `:asc` or `:desc` will cause the
+ # recursive query order from most nested group to root or from the root
+ # ancestor to most nested group respectively. This uses a `depth` column
+ # where `1` is defined as the depth for the base and increment as we go up
+ # each parent.
+ # rubocop: disable CodeReuse/ActiveRecord
+ def base_and_ancestors(upto: nil, hierarchy_order: nil)
return ancestors_base unless Group.supports_nested_groups?
- read_only(base_and_ancestors_cte(upto).apply_to(model.all))
+ recursive_query = base_and_ancestors_cte(upto, hierarchy_order).apply_to(model.all)
+ recursive_query = recursive_query.order(depth: hierarchy_order) if hierarchy_order
+
+ read_only(recursive_query)
end
+ # rubocop: enable CodeReuse/ActiveRecord
# Returns a relation that includes the descendants_base set of groups
# and all their descendants (recursively).
@@ -107,16 +118,22 @@ module Gitlab
private
# rubocop: disable CodeReuse/ActiveRecord
- def base_and_ancestors_cte(stop_id = nil)
+ def base_and_ancestors_cte(stop_id = nil, hierarchy_order = nil)
cte = SQL::RecursiveCTE.new(:base_and_ancestors)
+ depth_column = :depth
+
+ base_query = ancestors_base.except(:order)
+ base_query = base_query.select("1 as #{depth_column}", groups_table[Arel.star]) if hierarchy_order
- cte << ancestors_base.except(:order)
+ cte << base_query
# Recursively get all the ancestors of the base set.
parent_query = model
.from([groups_table, cte.table])
.where(groups_table[:id].eq(cte.table[:parent_id]))
.except(:order)
+
+ parent_query = parent_query.select(cte.table[depth_column] + 1, groups_table[Arel.star]) if hierarchy_order
parent_query = parent_query.where(cte.table[:parent_id].not_eq(stop_id)) if stop_id
cte << parent_query
diff --git a/lib/gitlab/import_export/import_export.yml b/lib/gitlab/import_export/import_export.yml
index 4f3298812a8..93065879ec6 100644
--- a/lib/gitlab/import_export/import_export.yml
+++ b/lib/gitlab/import_export/import_export.yml
@@ -51,7 +51,7 @@ project_tree:
- resource_label_events:
- label:
:priorities
- - pipelines:
+ - ci_pipelines:
- notes:
- :author
- events:
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index 8cd4efd91cc..a56ec65b9f1 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -26,6 +26,8 @@ module Gitlab
@project_members = @tree_hash.delete('project_members')
+ RelationRenameService.rename(@tree_hash)
+
ActiveRecord::Base.uncached do
ActiveRecord::Base.no_touching do
create_relations
@@ -214,7 +216,7 @@ module Gitlab
end
def nil_iid_pipeline?(relation_key, relation_item)
- relation_key == 'pipelines' && relation_item['iid'].nil?
+ relation_key == 'ci_pipelines' && relation_item['iid'].nil?
end
end
end
diff --git a/lib/gitlab/import_export/project_tree_saver.rb b/lib/gitlab/import_export/project_tree_saver.rb
index 29f2dc80813..2255635acdf 100644
--- a/lib/gitlab/import_export/project_tree_saver.rb
+++ b/lib/gitlab/import_export/project_tree_saver.rb
@@ -34,6 +34,8 @@ module Gitlab
project_json['project_members'] += group_members_json
+ RelationRenameService.add_new_associations(project_json)
+
project_json.to_json
end
diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb
index 9cc781ddf8d..a4902e2104f 100644
--- a/lib/gitlab/import_export/relation_factory.rb
+++ b/lib/gitlab/import_export/relation_factory.rb
@@ -4,6 +4,7 @@ module Gitlab
module ImportExport
class RelationFactory
OVERRIDES = { snippets: :project_snippets,
+ ci_pipelines: 'Ci::Pipeline',
pipelines: 'Ci::Pipeline',
stages: 'Ci::Stage',
statuses: 'commit_status',
diff --git a/lib/gitlab/import_export/relation_rename_service.rb b/lib/gitlab/import_export/relation_rename_service.rb
new file mode 100644
index 00000000000..179bde5e21e
--- /dev/null
+++ b/lib/gitlab/import_export/relation_rename_service.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+# This class is intended to help with relation renames within Gitlab versions
+# and allow compatibility between versions.
+# If you have to change one relationship name that is imported/exported,
+# you should add it to the RENAMES constant indicating the old name and the
+# new one.
+# The behavior of these renamed relationships should be transient and it should
+# only last one release until you completely remove the renaming from the list.
+#
+# When importing, this class will check the project hash and:
+# - if only the old relationship name is found, it will rename it with the new one
+# - if only the new relationship name is found, it will do nothing
+# - if it finds both, it will use the new relationship data
+#
+# When exporting, this class will duplicate the keys in the resulting file.
+# This way, if we open the file in an old version of the exporter it will work
+# and also it will with the newer versions.
+module Gitlab
+ module ImportExport
+ class RelationRenameService
+ RENAMES = {
+ 'pipelines' => 'ci_pipelines' # Added in 11.6, remove in 11.7
+ }.freeze
+
+ def self.rename(tree_hash)
+ return unless tree_hash&.present?
+
+ RENAMES.each do |old_name, new_name|
+ old_entry = tree_hash.delete(old_name)
+
+ next if tree_hash[new_name]
+ next unless old_entry
+
+ tree_hash[new_name] = old_entry
+ end
+ end
+
+ def self.add_new_associations(tree_hash)
+ RENAMES.each do |old_name, new_name|
+ next if tree_hash.key?(old_name)
+
+ tree_hash[old_name] = tree_hash[new_name]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 9bceec749fc..bfcc8efdc96 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -55,7 +55,11 @@ module Gitlab
environments: count(::Environment),
clusters: count(::Clusters::Cluster),
clusters_enabled: count(::Clusters::Cluster.enabled),
+ project_clusters_enabled: count(::Clusters::Cluster.enabled.project_type),
+ group_clusters_enabled: count(::Clusters::Cluster.enabled.group_type),
clusters_disabled: count(::Clusters::Cluster.disabled),
+ project_clusters_disabled: count(::Clusters::Cluster.disabled.project_type),
+ group_clusters_disabled: count(::Clusters::Cluster.disabled.group_type),
clusters_platforms_gke: count(::Clusters::Cluster.gcp_installed.enabled),
clusters_platforms_user: count(::Clusters::Cluster.user_provided.enabled),
clusters_applications_helm: count(::Clusters::Applications::Helm.installed),
diff --git a/lib/system_check/gitaly_check.rb b/lib/system_check/gitaly_check.rb
new file mode 100644
index 00000000000..3d2517a7aca
--- /dev/null
+++ b/lib/system_check/gitaly_check.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ class GitalyCheck < BaseCheck
+ set_name 'Gitaly:'
+
+ def multi_check
+ Gitlab::HealthChecks::GitalyCheck.readiness.each do |result|
+ $stdout.print "#{result.labels[:shard]} ... "
+
+ if result.success
+ $stdout.puts 'OK'.color(:green)
+ else
+ $stdout.puts "FAIL: #{result.message}".color(:red)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/system_check/gitlab_shell_check.rb b/lib/system_check/gitlab_shell_check.rb
new file mode 100644
index 00000000000..31c4ec33247
--- /dev/null
+++ b/lib/system_check/gitlab_shell_check.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ # Used by gitlab:gitlab_shell:check rake task
+ class GitlabShellCheck < BaseCheck
+ set_name 'GitLab Shell:'
+
+ def multi_check
+ check_gitlab_shell
+ check_gitlab_shell_self_test
+ end
+
+ private
+
+ def check_gitlab_shell
+ required_version = Gitlab::VersionInfo.parse(Gitlab::Shell.version_required)
+ current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
+
+ $stdout.print "GitLab Shell version >= #{required_version} ? ... "
+ if current_version.valid? && required_version <= current_version
+ $stdout.puts "OK (#{current_version})".color(:green)
+ else
+ $stdout.puts "FAIL. Please update gitlab-shell to #{required_version} from #{current_version}".color(:red)
+ end
+ end
+
+ def check_gitlab_shell_self_test
+ gitlab_shell_repo_base = gitlab_shell_path
+ check_cmd = File.expand_path('bin/check', gitlab_shell_repo_base)
+ $stdout.puts "Running #{check_cmd}"
+
+ if system(check_cmd, chdir: gitlab_shell_repo_base)
+ $stdout.puts 'gitlab-shell self-check successful'.color(:green)
+ else
+ $stdout.puts 'gitlab-shell self-check failed'.color(:red)
+ try_fixing_it(
+ 'Make sure GitLab is running;',
+ 'Check the gitlab-shell configuration file:',
+ sudo_gitlab("editor #{File.expand_path('config.yml', gitlab_shell_repo_base)}")
+ )
+ fix_and_rerun
+ end
+ end
+
+ # Helper methods
+ ########################
+
+ def gitlab_shell_path
+ Gitlab.config.gitlab_shell.path
+ end
+
+ def gitlab_shell_version
+ Gitlab::Shell.new.version
+ end
+ end
+end
diff --git a/lib/system_check/incoming_email_check.rb b/lib/system_check/incoming_email_check.rb
new file mode 100644
index 00000000000..155b6547595
--- /dev/null
+++ b/lib/system_check/incoming_email_check.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ # Used by gitlab:incoming_email:check rake task
+ class IncomingEmailCheck < BaseCheck
+ set_name 'Incoming Email:'
+
+ def multi_check
+ if Gitlab.config.incoming_email.enabled
+ checks = [
+ SystemCheck::IncomingEmail::ImapAuthenticationCheck
+ ]
+
+ if Rails.env.production?
+ checks << SystemCheck::IncomingEmail::InitdConfiguredCheck
+ checks << SystemCheck::IncomingEmail::MailRoomRunningCheck
+ else
+ checks << SystemCheck::IncomingEmail::ForemanConfiguredCheck
+ end
+
+ SystemCheck.run('Reply by email', checks)
+ else
+ $stdout.puts 'Reply by email is disabled in config/gitlab.yml'
+ end
+ end
+ end
+end
diff --git a/lib/system_check/ldap_check.rb b/lib/system_check/ldap_check.rb
new file mode 100644
index 00000000000..619fb3cccb8
--- /dev/null
+++ b/lib/system_check/ldap_check.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ # Used by gitlab:ldap:check rake task
+ class LdapCheck < BaseCheck
+ set_name 'LDAP:'
+
+ def multi_check
+ if Gitlab::Auth::LDAP::Config.enabled?
+ # Only show up to 100 results because LDAP directories can be very big.
+ # This setting only affects the `rake gitlab:check` script.
+ limit = ENV['LDAP_CHECK_LIMIT']
+ limit = 100 if limit.blank?
+
+ check_ldap(limit)
+ else
+ $stdout.puts 'LDAP is disabled in config/gitlab.yml'
+ end
+ end
+
+ private
+
+ def check_ldap(limit)
+ servers = Gitlab::Auth::LDAP::Config.providers
+
+ servers.each do |server|
+ $stdout.puts "Server: #{server}"
+
+ begin
+ Gitlab::Auth::LDAP::Adapter.open(server) do |adapter|
+ check_ldap_auth(adapter)
+
+ $stdout.puts "LDAP users with access to your GitLab server (only showing the first #{limit} results)"
+
+ users = adapter.users(adapter.config.uid, '*', limit)
+ users.each do |user|
+ $stdout.puts "\tDN: #{user.dn}\t #{adapter.config.uid}: #{user.uid}"
+ end
+ end
+ rescue Net::LDAP::ConnectionRefusedError, Errno::ECONNREFUSED => e
+ $stdout.puts "Could not connect to the LDAP server: #{e.message}".color(:red)
+ end
+ end
+ end
+
+ def check_ldap_auth(adapter)
+ auth = adapter.config.has_auth?
+
+ message = if auth && adapter.ldap.bind
+ 'Success'.color(:green)
+ elsif auth
+ 'Failed. Check `bind_dn` and `password` configuration values'.color(:red)
+ else
+ 'Anonymous. No `bind_dn` or `password` configured'.color(:yellow)
+ end
+
+ $stdout.puts "LDAP authentication... #{message}"
+ end
+ end
+end
diff --git a/lib/system_check/orphans/repository_check.rb b/lib/system_check/orphans/repository_check.rb
index ef8fe945f61..33020417e95 100644
--- a/lib/system_check/orphans/repository_check.rb
+++ b/lib/system_check/orphans/repository_check.rb
@@ -4,7 +4,6 @@ module SystemCheck
module Orphans
class RepositoryCheck < SystemCheck::BaseCheck
set_name 'Orphaned repositories:'
- attr_accessor :orphans
def multi_check
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
diff --git a/lib/system_check/rake_task/app_task.rb b/lib/system_check/rake_task/app_task.rb
new file mode 100644
index 00000000000..cc32feb8604
--- /dev/null
+++ b/lib/system_check/rake_task/app_task.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:app:check rake task
+ module AppTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'GitLab App'
+ end
+
+ def self.checks
+ [
+ SystemCheck::App::GitConfigCheck,
+ SystemCheck::App::DatabaseConfigExistsCheck,
+ SystemCheck::App::MigrationsAreUpCheck,
+ SystemCheck::App::OrphanedGroupMembersCheck,
+ SystemCheck::App::GitlabConfigExistsCheck,
+ SystemCheck::App::GitlabConfigUpToDateCheck,
+ SystemCheck::App::LogWritableCheck,
+ SystemCheck::App::TmpWritableCheck,
+ SystemCheck::App::UploadsDirectoryExistsCheck,
+ SystemCheck::App::UploadsPathPermissionCheck,
+ SystemCheck::App::UploadsPathTmpPermissionCheck,
+ SystemCheck::App::InitScriptExistsCheck,
+ SystemCheck::App::InitScriptUpToDateCheck,
+ SystemCheck::App::ProjectsHaveNamespaceCheck,
+ SystemCheck::App::RedisVersionCheck,
+ SystemCheck::App::RubyVersionCheck,
+ SystemCheck::App::GitVersionCheck,
+ SystemCheck::App::GitUserDefaultSSHConfigCheck,
+ SystemCheck::App::ActiveUsersCheck
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/gitaly_task.rb b/lib/system_check/rake_task/gitaly_task.rb
new file mode 100644
index 00000000000..0c3f694f98a
--- /dev/null
+++ b/lib/system_check/rake_task/gitaly_task.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:gitaly:check rake task
+ class GitalyTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Gitaly'
+ end
+
+ def self.checks
+ [SystemCheck::GitalyCheck]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/gitlab_shell_task.rb b/lib/system_check/rake_task/gitlab_shell_task.rb
new file mode 100644
index 00000000000..120e984c68b
--- /dev/null
+++ b/lib/system_check/rake_task/gitlab_shell_task.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:gitlab_shell:check rake task
+ class GitlabShellTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'GitLab Shell'
+ end
+
+ def self.checks
+ [SystemCheck::GitlabShellCheck]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/gitlab_task.rb b/lib/system_check/rake_task/gitlab_task.rb
new file mode 100644
index 00000000000..7ff36fd6eb5
--- /dev/null
+++ b/lib/system_check/rake_task/gitlab_task.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:check rake task
+ class GitlabTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'GitLab'
+ end
+
+ def self.manual_run_checks!
+ start_checking("#{name} subtasks")
+
+ subtasks.each(&:run_checks!)
+
+ finished_checking("#{name} subtasks")
+ end
+
+ def self.subtasks
+ [
+ SystemCheck::RakeTask::GitlabShellTask,
+ SystemCheck::RakeTask::GitalyTask,
+ SystemCheck::RakeTask::SidekiqTask,
+ SystemCheck::RakeTask::IncomingEmailTask,
+ SystemCheck::RakeTask::LdapTask,
+ SystemCheck::RakeTask::AppTask
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/incoming_email_task.rb b/lib/system_check/rake_task/incoming_email_task.rb
new file mode 100644
index 00000000000..c296c46feab
--- /dev/null
+++ b/lib/system_check/rake_task/incoming_email_task.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:incoming_email:check rake task
+ class IncomingEmailTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Incoming Email'
+ end
+
+ def self.checks
+ [SystemCheck::IncomingEmailCheck]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/ldap_task.rb b/lib/system_check/rake_task/ldap_task.rb
new file mode 100644
index 00000000000..03a180b9dfb
--- /dev/null
+++ b/lib/system_check/rake_task/ldap_task.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:ldap:check rake task
+ class LdapTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'LDAP'
+ end
+
+ def self.checks
+ [SystemCheck::LdapCheck]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/orphans/namespace_task.rb b/lib/system_check/rake_task/orphans/namespace_task.rb
new file mode 100644
index 00000000000..2822da45bc1
--- /dev/null
+++ b/lib/system_check/rake_task/orphans/namespace_task.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ module Orphans
+ # Used by gitlab:orphans:check_namespaces rake task
+ class NamespaceTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Orphans'
+ end
+
+ def self.checks
+ [SystemCheck::Orphans::NamespaceCheck]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/orphans/repository_task.rb b/lib/system_check/rake_task/orphans/repository_task.rb
new file mode 100644
index 00000000000..f14b3af22e8
--- /dev/null
+++ b/lib/system_check/rake_task/orphans/repository_task.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ module Orphans
+ # Used by gitlab:orphans:check_repositories rake task
+ class RepositoryTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Orphans'
+ end
+
+ def self.checks
+ [SystemCheck::Orphans::RepositoryCheck]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/orphans_task.rb b/lib/system_check/rake_task/orphans_task.rb
new file mode 100644
index 00000000000..31f8ede25e0
--- /dev/null
+++ b/lib/system_check/rake_task/orphans_task.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:orphans:check rake task
+ class OrphansTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Orphans'
+ end
+
+ def self.checks
+ [
+ SystemCheck::Orphans::NamespaceCheck,
+ SystemCheck::Orphans::RepositoryCheck
+ ]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/rake_task_helpers.rb b/lib/system_check/rake_task/rake_task_helpers.rb
new file mode 100644
index 00000000000..95f2a34a719
--- /dev/null
+++ b/lib/system_check/rake_task/rake_task_helpers.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Provides the run! method intended to be called from system check rake tasks
+ module RakeTaskHelpers
+ include ::SystemCheck::Helpers
+
+ def run!
+ warn_user_is_not_gitlab
+
+ if self.respond_to?(:manual_run_checks!)
+ manual_run_checks!
+ else
+ run_checks!
+ end
+ end
+
+ def run_checks!
+ SystemCheck.run(name, checks)
+ end
+
+ def name
+ raise NotImplementedError
+ end
+
+ def checks
+ raise NotImplementedError
+ end
+ end
+ end
+end
diff --git a/lib/system_check/rake_task/sidekiq_task.rb b/lib/system_check/rake_task/sidekiq_task.rb
new file mode 100644
index 00000000000..3ccf009d4b9
--- /dev/null
+++ b/lib/system_check/rake_task/sidekiq_task.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ module RakeTask
+ # Used by gitlab:sidekiq:check rake task
+ class SidekiqTask
+ extend RakeTaskHelpers
+
+ def self.name
+ 'Sidekiq'
+ end
+
+ def self.checks
+ [SystemCheck::SidekiqCheck]
+ end
+ end
+ end
+end
diff --git a/lib/system_check/sidekiq_check.rb b/lib/system_check/sidekiq_check.rb
new file mode 100644
index 00000000000..2f5fc2cea89
--- /dev/null
+++ b/lib/system_check/sidekiq_check.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module SystemCheck
+ # Used by gitlab:sidekiq:check rake task
+ class SidekiqCheck < BaseCheck
+ set_name 'Sidekiq:'
+
+ def multi_check
+ check_sidekiq_running
+ only_one_sidekiq_running
+ end
+
+ private
+
+ def check_sidekiq_running
+ $stdout.print "Running? ... "
+
+ if sidekiq_process_count > 0
+ $stdout.puts "yes".color(:green)
+ else
+ $stdout.puts "no".color(:red)
+ try_fixing_it(
+ sudo_gitlab("RAILS_ENV=production bin/background_jobs start")
+ )
+ for_more_information(
+ see_installation_guide_section("Install Init Script"),
+ "see log/sidekiq.log for possible errors"
+ )
+ fix_and_rerun
+ end
+ end
+
+ def only_one_sidekiq_running
+ process_count = sidekiq_process_count
+ return if process_count.zero?
+
+ $stdout.print 'Number of Sidekiq processes ... '
+
+ if process_count == 1
+ $stdout.puts '1'.color(:green)
+ else
+ $stdout.puts "#{process_count}".color(:red)
+ try_fixing_it(
+ 'sudo service gitlab stop',
+ "sudo pkill -u #{gitlab_user} -f sidekiq",
+ "sleep 10 && sudo pkill -9 -u #{gitlab_user} -f sidekiq",
+ 'sudo service gitlab start'
+ )
+ fix_and_rerun
+ end
+ end
+
+ def sidekiq_process_count
+ ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww))
+ ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index a2c3e32948f..b594f150c3b 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -1,299 +1,66 @@
namespace :gitlab do
desc 'GitLab | Check the configuration of GitLab and its environment'
- task check: %w{gitlab:gitlab_shell:check
- gitlab:gitaly:check
- gitlab:sidekiq:check
- gitlab:incoming_email:check
- gitlab:ldap:check
- gitlab:app:check}
+ task check: :gitlab_environment do
+ SystemCheck::RakeTask::GitlabTask.run!
+ end
namespace :app do
desc 'GitLab | Check the configuration of the GitLab Rails app'
task check: :gitlab_environment do
- warn_user_is_not_gitlab
-
- checks = [
- SystemCheck::App::GitConfigCheck,
- SystemCheck::App::DatabaseConfigExistsCheck,
- SystemCheck::App::MigrationsAreUpCheck,
- SystemCheck::App::OrphanedGroupMembersCheck,
- SystemCheck::App::GitlabConfigExistsCheck,
- SystemCheck::App::GitlabConfigUpToDateCheck,
- SystemCheck::App::LogWritableCheck,
- SystemCheck::App::TmpWritableCheck,
- SystemCheck::App::UploadsDirectoryExistsCheck,
- SystemCheck::App::UploadsPathPermissionCheck,
- SystemCheck::App::UploadsPathTmpPermissionCheck,
- SystemCheck::App::InitScriptExistsCheck,
- SystemCheck::App::InitScriptUpToDateCheck,
- SystemCheck::App::ProjectsHaveNamespaceCheck,
- SystemCheck::App::RedisVersionCheck,
- SystemCheck::App::RubyVersionCheck,
- SystemCheck::App::GitVersionCheck,
- SystemCheck::App::GitUserDefaultSSHConfigCheck,
- SystemCheck::App::ActiveUsersCheck
- ]
-
- SystemCheck.run('GitLab', checks)
+ SystemCheck::RakeTask::AppTask.run!
end
end
namespace :gitlab_shell do
desc "GitLab | Check the configuration of GitLab Shell"
task check: :gitlab_environment do
- warn_user_is_not_gitlab
- start_checking "GitLab Shell"
-
- check_gitlab_shell
- check_gitlab_shell_self_test
-
- finished_checking "GitLab Shell"
- end
-
- # Checks
- ########################
-
- def check_gitlab_shell_self_test
- gitlab_shell_repo_base = gitlab_shell_path
- check_cmd = File.expand_path('bin/check', gitlab_shell_repo_base)
- puts "Running #{check_cmd}"
-
- if system(check_cmd, chdir: gitlab_shell_repo_base)
- puts 'gitlab-shell self-check successful'.color(:green)
- else
- puts 'gitlab-shell self-check failed'.color(:red)
- try_fixing_it(
- 'Make sure GitLab is running;',
- 'Check the gitlab-shell configuration file:',
- sudo_gitlab("editor #{File.expand_path('config.yml', gitlab_shell_repo_base)}")
- )
- fix_and_rerun
- end
- end
-
- # Helper methods
- ########################
-
- def gitlab_shell_path
- Gitlab.config.gitlab_shell.path
- end
-
- def gitlab_shell_version
- Gitlab::Shell.new.version
- end
-
- def gitlab_shell_major_version
- Gitlab::Shell.version_required.split('.')[0].to_i
- end
-
- def gitlab_shell_minor_version
- Gitlab::Shell.version_required.split('.')[1].to_i
- end
-
- def gitlab_shell_patch_version
- Gitlab::Shell.version_required.split('.')[2].to_i
+ SystemCheck::RakeTask::GitlabShellTask.run!
end
end
namespace :gitaly do
desc 'GitLab | Check the health of Gitaly'
task check: :gitlab_environment do
- warn_user_is_not_gitlab
- start_checking 'Gitaly'
-
- Gitlab::HealthChecks::GitalyCheck.readiness.each do |result|
- print "#{result.labels[:shard]} ... "
-
- if result.success
- puts 'OK'.color(:green)
- else
- puts "FAIL: #{result.message}".color(:red)
- end
- end
-
- finished_checking 'Gitaly'
+ SystemCheck::RakeTask::GitalyTask.run!
end
end
namespace :sidekiq do
desc "GitLab | Check the configuration of Sidekiq"
task check: :gitlab_environment do
- warn_user_is_not_gitlab
- start_checking "Sidekiq"
-
- check_sidekiq_running
- only_one_sidekiq_running
-
- finished_checking "Sidekiq"
- end
-
- # Checks
- ########################
-
- def check_sidekiq_running
- print "Running? ... "
-
- if sidekiq_process_count > 0
- puts "yes".color(:green)
- else
- puts "no".color(:red)
- try_fixing_it(
- sudo_gitlab("RAILS_ENV=production bin/background_jobs start")
- )
- for_more_information(
- see_installation_guide_section("Install Init Script"),
- "see log/sidekiq.log for possible errors"
- )
- fix_and_rerun
- end
- end
-
- def only_one_sidekiq_running
- process_count = sidekiq_process_count
- return if process_count.zero?
-
- print 'Number of Sidekiq processes ... '
-
- if process_count == 1
- puts '1'.color(:green)
- else
- puts "#{process_count}".color(:red)
- try_fixing_it(
- 'sudo service gitlab stop',
- "sudo pkill -u #{gitlab_user} -f sidekiq",
- "sleep 10 && sudo pkill -9 -u #{gitlab_user} -f sidekiq",
- 'sudo service gitlab start'
- )
- fix_and_rerun
- end
- end
-
- def sidekiq_process_count
- ps_ux, _ = Gitlab::Popen.popen(%w(ps uxww))
- ps_ux.scan(/sidekiq \d+\.\d+\.\d+/).count
+ SystemCheck::RakeTask::SidekiqTask.run!
end
end
namespace :incoming_email do
desc "GitLab | Check the configuration of Reply by email"
task check: :gitlab_environment do
- warn_user_is_not_gitlab
-
- if Gitlab.config.incoming_email.enabled
- checks = [
- SystemCheck::IncomingEmail::ImapAuthenticationCheck
- ]
-
- if Rails.env.production?
- checks << SystemCheck::IncomingEmail::InitdConfiguredCheck
- checks << SystemCheck::IncomingEmail::MailRoomRunningCheck
- else
- checks << SystemCheck::IncomingEmail::ForemanConfiguredCheck
- end
-
- SystemCheck.run('Reply by email', checks)
- else
- puts 'Reply by email is disabled in config/gitlab.yml'
- end
+ SystemCheck::RakeTask::IncomingEmailTask.run!
end
end
namespace :ldap do
task :check, [:limit] => :gitlab_environment do |_, args|
- # Only show up to 100 results because LDAP directories can be very big.
- # This setting only affects the `rake gitlab:check` script.
- args.with_defaults(limit: 100)
- warn_user_is_not_gitlab
- start_checking "LDAP"
-
- if Gitlab::Auth::LDAP::Config.enabled?
- check_ldap(args.limit)
- else
- puts 'LDAP is disabled in config/gitlab.yml'
- end
-
- finished_checking "LDAP"
- end
-
- def check_ldap(limit)
- servers = Gitlab::Auth::LDAP::Config.providers
-
- servers.each do |server|
- puts "Server: #{server}"
+ ENV['LDAP_CHECK_LIMIT'] = args.limit if args.limit.present?
- begin
- Gitlab::Auth::LDAP::Adapter.open(server) do |adapter|
- check_ldap_auth(adapter)
-
- puts "LDAP users with access to your GitLab server (only showing the first #{limit} results)"
-
- users = adapter.users(adapter.config.uid, '*', limit)
- users.each do |user|
- puts "\tDN: #{user.dn}\t #{adapter.config.uid}: #{user.uid}"
- end
- end
- rescue Net::LDAP::ConnectionRefusedError, Errno::ECONNREFUSED => e
- puts "Could not connect to the LDAP server: #{e.message}".color(:red)
- end
- end
- end
-
- def check_ldap_auth(adapter)
- auth = adapter.config.has_auth?
-
- message = if auth && adapter.ldap.bind
- 'Success'.color(:green)
- elsif auth
- 'Failed. Check `bind_dn` and `password` configuration values'.color(:red)
- else
- 'Anonymous. No `bind_dn` or `password` configured'.color(:yellow)
- end
-
- puts "LDAP authentication... #{message}"
+ SystemCheck::RakeTask::LdapTask.run!
end
end
namespace :orphans do
desc 'Gitlab | Check for orphaned namespaces and repositories'
task check: :gitlab_environment do
- warn_user_is_not_gitlab
- checks = [
- SystemCheck::Orphans::NamespaceCheck,
- SystemCheck::Orphans::RepositoryCheck
- ]
-
- SystemCheck.run('Orphans', checks)
+ SystemCheck::RakeTask::OrphansTask.run!
end
desc 'GitLab | Check for orphaned namespaces in the repositories path'
task check_namespaces: :gitlab_environment do
- warn_user_is_not_gitlab
- checks = [SystemCheck::Orphans::NamespaceCheck]
-
- SystemCheck.run('Orphans', checks)
+ SystemCheck::RakeTask::Orphans::NamespaceTask.run!
end
desc 'GitLab | Check for orphaned repositories in the repositories path'
task check_repositories: :gitlab_environment do
- warn_user_is_not_gitlab
- checks = [SystemCheck::Orphans::RepositoryCheck]
-
- SystemCheck.run('Orphans', checks)
- end
- end
-
- # Helper methods
- ##########################
-
- def check_gitlab_shell
- required_version = Gitlab::VersionInfo.new(gitlab_shell_major_version, gitlab_shell_minor_version, gitlab_shell_patch_version)
- current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
-
- print "GitLab Shell version >= #{required_version} ? ... "
- if current_version.valid? && required_version <= current_version
- puts "OK (#{current_version})".color(:green)
- else
- puts "FAIL. Please update gitlab-shell to #{required_version} from #{current_version}".color(:red)
+ SystemCheck::RakeTask::Orphans::RepositoryTask.run!
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8289434fd30..38e7ff740c7 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3436,6 +3436,9 @@ msgstr ""
msgid "Identities"
msgstr ""
+msgid "If any job surpasses this timeout threshold, it will be marked as failed. Human readable time input language is accepted like \"1 hour\". Values without specification represent seconds."
+msgstr ""
+
msgid "If disabled, the access level will depend on the user's permissions in the project."
msgstr ""
@@ -4614,9 +4617,6 @@ msgstr ""
msgid "People without permission will never get a notification and won't be able to comment."
msgstr ""
-msgid "Per job. If a job passes this threshold, it will be marked as failed"
-msgstr ""
-
msgid "Perform advanced options such as changing path, transferring, or removing the group."
msgstr ""
@@ -6632,7 +6632,7 @@ msgstr ""
msgid "This source diff could not be displayed because it is too large."
msgstr ""
-msgid "This timeout will take precedence when lower than Project-defined timeout"
+msgid "This timeout will take precedence when lower than project-defined timeout and accepts a human readable time input language like \"1 hour\". Values without specification represent seconds."
msgstr ""
msgid "This user has no identities"
diff --git a/package.json b/package.json
index 520d7c620c2..680a5bb1cde 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"eslint": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue .",
"eslint-fix": "eslint --max-warnings 0 --report-unused-disable-directives --ext .js,.vue --fix .",
"eslint-report": "eslint --max-warnings 0 --ext .js,.vue --format html --output-file ./eslint-report.html --no-inline-config .",
+ "jest": "BABEL_ENV=jest jest --config=config/jest.config.js",
"karma": "BABEL_ENV=${BABEL_ENV:=karma} karma start --single-run true config/karma.config.js",
"karma-coverage": "BABEL_ENV=coverage karma start --single-run true config/karma.config.js",
"karma-start": "BABEL_ENV=karma karma start config/karma.config.js",
@@ -118,17 +119,23 @@
"@gitlab/eslint-config": "^1.2.0",
"@vue/test-utils": "^1.0.0-beta.25",
"axios-mock-adapter": "^1.15.0",
+ "babel-core": "^7.0.0-bridge",
+ "babel-jest": "^23.6.0",
+ "babel-plugin-dynamic-import-node": "^2.2.0",
"babel-plugin-istanbul": "^5.1.0",
"babel-plugin-rewire": "^1.2.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"babel-template": "^6.26.0",
"babel-types": "^6.26.0",
"chalk": "^2.4.1",
"commander": "^2.18.0",
"eslint": "~5.6.0",
+ "eslint-import-resolver-jest": "^2.1.1",
"eslint-import-resolver-webpack": "^0.10.1",
"eslint-plugin-html": "4.0.5",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jasmine": "^2.10.1",
+ "eslint-plugin-jest": "^22.1.0",
"gettext-extractor": "^3.3.2",
"gettext-extractor-vue": "^4.0.1",
"graphql-tag": "^2.10.0",
@@ -136,6 +143,8 @@
"jasmine-core": "^2.9.0",
"jasmine-diff": "^0.1.3",
"jasmine-jquery": "^2.1.1",
+ "jest": "^23.6.0",
+ "jest-junit": "^5.2.0",
"karma": "^3.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage-istanbul-reporter": "^2.0.4",
diff --git a/scripts/merge-train b/scripts/merge-train
deleted file mode 100755
index a934971b869..00000000000
--- a/scripts/merge-train
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-
-set -e
-
-# The name (including namespace) of the EE repository to merge commits into.
-EE_PROJECT='gitlab-org/gitlab-ee'
-
-# The directory to clone GitLab EE into.
-EE_DIRECTORY="$CI_PROJECT_DIR/gitlab-ee"
-
-# The EE branch to merge the changes into.
-EE_BRANCH='master'
-
-# Runs an incremental or periodic merge of CE to EE. This script should be run
-# from a container built using https://gitlab.com/gitlab-org/merge-train.
-
-# Merges (or reverts) commits in a batch (based on CI_COMMIT_BEFORE_SHA and
-# CI_COMMIT_SHA), or since a specific commit.
-#
-# The optional first argument of this function should be a SHA of a commit. When
-# specified, all commits since this commit will be processed.
-merge() {
- # We need to source the configure-ssh script instead of running it with
- # `sh`, since it uses `eval` for SSH agent and we want the result of that to
- # persist.
- #
- # shellcheck disable=SC1091
- . /app/bin/configure-ssh
-
- # We can not perform a shallow clone, as this results in Git sometimes
- # refusing to fetch from CE. To work around this, we perform a full clone
- # but cache the repository in CI. If a cached repository exists, we simply
- # just pull from `master`.
- if [ -d "$EE_DIRECTORY" ]
- then
- echo "Updating existing clone of $EE_PROJECT"
-
- git -C "$EE_DIRECTORY" pull --quiet origin "$EE_BRANCH"
- else
- echo "Cloning $EE_PROJECT"
-
- git clone --quiet --single-branch --branch "$EE_BRANCH" \
- "git@gitlab.com:$EE_PROJECT.git" "$EE_DIRECTORY"
- fi
-
- cd /app
-
- env GITLAB_TOKEN="$MERGE_TRAIN_API_TOKEN" \
- bundle exec /app/bin/merge-train "$CI_PROJECT_DIR" "$EE_DIRECTORY" \
- --source-name "$CI_PROJECT_PATH" \
- --target-branch "$EE_BRANCH" \
- ${1:+--before "$1"}
-}
-
-# Merges (or reverts) all commits since a point in time as supported by `git log
-# --since`, such as "12 hours ago".
-merge_since() {
- commit="$(git log --since="$MERGE_SINCE" --reverse --format=%H | head -n1)"
-
- if [ "$commit" = '' ]
- then
- echo "There are no commits to merge since $MERGE_SINCE"
- else
- merge "$commit"
- fi
-}
-
-if [ "$MERGE_SINCE" ]
-then
- merge_since
-else
- merge
-fi
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 9dc06436c72..8fc5d302af6 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -36,6 +36,18 @@ describe Projects::MergeRequests::DiffsController do
end
end
+ context 'when note has no position' do
+ before do
+ create(:legacy_diff_note_on_merge_request, project: project, noteable: merge_request, position: nil)
+ end
+
+ it 'serializes merge request diff collection' do
+ expect_any_instance_of(DiffsSerializer).to receive(:represent).with(an_instance_of(Gitlab::Diff::FileCollection::MergeRequestDiff), an_instance_of(Hash))
+
+ go
+ end
+ end
+
context 'with forked projects with submodules' do
render_views
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index d5516b334b9..931095936a6 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe "Admin::Users" do
+ include Spec::Support::Helpers::Features::ListRowsHelpers
+
let!(:user) do
create(:omniauth_user, provider: 'twitter', extern_uid: '123456')
end
@@ -30,6 +32,51 @@ describe "Admin::Users" do
expect(page).to have_button('Delete user and contributions')
end
+ describe 'search and sort' do
+ before do
+ create(:user, name: 'Foo Bar')
+ create(:user, name: 'Foo Baz')
+ create(:user, name: 'Dmitriy')
+ end
+
+ it 'searches users by name' do
+ visit admin_users_path(search_query: 'Foo')
+
+ expect(page).to have_content('Foo Bar')
+ expect(page).to have_content('Foo Baz')
+ expect(page).not_to have_content('Dmitriy')
+ end
+
+ it 'sorts users by name' do
+ visit admin_users_path
+
+ sort_by('Name')
+
+ expect(first_row.text).to include('Dmitriy')
+ expect(second_row.text).to include('Foo Bar')
+ end
+
+ it 'sorts search results only' do
+ visit admin_users_path(search_query: 'Foo')
+
+ sort_by('Name')
+
+ expect(page).not_to have_content('Dmitriy')
+ expect(first_row.text).to include('Foo Bar')
+ expect(second_row.text).to include('Foo Baz')
+ end
+
+ it 'searches with respect of sorting' do
+ visit admin_users_path(sort: 'Name')
+
+ fill_in :search_query, with: 'Foo'
+ click_button('Search users')
+
+ expect(first_row.text).to include('Foo Bar')
+ expect(second_row.text).to include('Foo Baz')
+ end
+ end
+
describe 'Two-factor Authentication filters' do
it 'counts users who have enabled 2FA' do
create(:user, :two_factor)
@@ -566,4 +613,10 @@ describe "Admin::Users" do
def check_breadcrumb(content)
expect(find('.breadcrumbs-sub-title')).to have_content(content)
end
+
+ def sort_by(text)
+ page.within('.user-sort-dropdown') do
+ click_link text
+ end
+ end
end
diff --git a/spec/features/groups/members/list_members_spec.rb b/spec/features/groups/members/list_members_spec.rb
index e1587a8b6a5..4ba7161601e 100644
--- a/spec/features/groups/members/list_members_spec.rb
+++ b/spec/features/groups/members/list_members_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe 'Groups > Members > List members' do
include Select2Helper
+ include Spec::Support::Helpers::Features::ListRowsHelpers
let(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') }
@@ -43,12 +44,4 @@ describe 'Groups > Members > List members' do
let(:user_with_status) { user2 }
end
end
-
- def first_row
- page.all('ul.content-list > li')[0]
- end
-
- def second_row
- page.all('ul.content-list > li')[1]
- end
end
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index 0eda2c7f26d..e2b4a491a13 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe 'Groups > Members > Manage members' do
include Select2Helper
+ include Spec::Support::Helpers::Features::ListRowsHelpers
let(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') }
@@ -119,14 +120,6 @@ describe 'Groups > Members > Manage members' do
end
end
- def first_row
- page.all('ul.content-list > li')[0]
- end
-
- def second_row
- page.all('ul.content-list > li')[1]
- end
-
def add_user(id, role)
page.within ".users-group-form" do
select2(id, from: "#user_ids", multiple: true)
diff --git a/spec/features/ide_spec.rb b/spec/features/ide_spec.rb
index 65989c36c1e..6eb59ef72c2 100644
--- a/spec/features/ide_spec.rb
+++ b/spec/features/ide_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe 'IDE', :js do
- describe 'sub-groups' do
+ describe 'sub-groups', :nested_groups do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
diff --git a/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
new file mode 100644
index 00000000000..ae1313cf117
--- /dev/null
+++ b/spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb
@@ -0,0 +1,333 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Merge request > User sees merge request pipelines', :js do
+ include ProjectForksHelper
+ include TestReportsHelper
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:user) { project.creator }
+
+ let(:config) do
+ {
+ build: {
+ script: 'build'
+ },
+ test: {
+ script: 'test',
+ only: ['merge_requests']
+ },
+ deploy: {
+ script: 'deploy',
+ except: ['merge_requests']
+ }
+ }
+ end
+
+ before do
+ stub_application_setting(auto_devops_enabled: false)
+ stub_feature_flags(ci_merge_request_pipeline: true)
+ stub_ci_pipeline_yaml_file(YAML.dump(config))
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ context 'when a user created a merge request in the parent project' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ target_project: project,
+ source_branch: 'feature',
+ target_branch: 'master')
+ end
+
+ let!(:push_pipeline) do
+ Ci::CreatePipelineService.new(project, user, ref: 'feature')
+ .execute(:push)
+ end
+
+ let!(:merge_request_pipeline) do
+ Ci::CreatePipelineService.new(project, user, ref: 'feature')
+ .execute(:merge_request, merge_request: merge_request)
+ end
+
+ before do
+ visit project_merge_request_path(project, merge_request)
+
+ page.within('.merge-request-tabs') do
+ click_link('Pipelines')
+ end
+ end
+
+ it 'sees branch pipelines and merge request pipelines in correct order' do
+ page.within('.ci-table') do
+ expect(page).to have_selector('.ci-pending', count: 2)
+ expect(first('.js-pipeline-url-link')).to have_content("##{merge_request_pipeline.id}")
+ end
+ end
+
+ it 'sees the latest merge request pipeline as the head pipeline' do
+ page.within('.ci-widget-content') do
+ expect(page).to have_content("##{merge_request_pipeline.id}")
+ end
+ end
+
+ context 'when a user updated a merge request in the parent project' do
+ let!(:push_pipeline_2) do
+ Ci::CreatePipelineService.new(project, user, ref: 'feature')
+ .execute(:push)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ Ci::CreatePipelineService.new(project, user, ref: 'feature')
+ .execute(:merge_request, merge_request: merge_request)
+ end
+
+ before do
+ visit project_merge_request_path(project, merge_request)
+
+ page.within('.merge-request-tabs') do
+ click_link('Pipelines')
+ end
+ end
+
+ it 'sees branch pipelines and merge request pipelines in correct order' do
+ page.within('.ci-table') do
+ expect(page).to have_selector('.ci-pending', count: 4)
+
+ expect(all('.js-pipeline-url-link')[0])
+ .to have_content("##{merge_request_pipeline_2.id}")
+
+ expect(all('.js-pipeline-url-link')[1])
+ .to have_content("##{merge_request_pipeline.id}")
+
+ expect(all('.js-pipeline-url-link')[2])
+ .to have_content("##{push_pipeline_2.id}")
+
+ expect(all('.js-pipeline-url-link')[3])
+ .to have_content("##{push_pipeline.id}")
+ end
+ end
+
+ it 'sees the latest merge request pipeline as the head pipeline' do
+ page.within('.ci-widget-content') do
+ expect(page).to have_content("##{merge_request_pipeline_2.id}")
+ end
+ end
+ end
+
+ context 'when a user merges a merge request in the parent project' do
+ before do
+ click_button 'Merge when pipeline succeeds'
+
+ wait_for_requests
+ end
+
+ context 'when merge request pipeline is pending' do
+ it 'waits the head pipeline' do
+ expect(page).to have_content('to be merged automatically when the pipeline succeeds')
+ expect(page).to have_link('Cancel automatic merge')
+ end
+ end
+
+ context 'when merge request pipeline succeeds' do
+ before do
+ merge_request_pipeline.succeed!
+
+ wait_for_requests
+ end
+
+ it 'merges the merge request' do
+ expect(page).to have_content('Merged by')
+ expect(page).to have_link('Revert')
+ end
+ end
+
+ context 'when branch pipeline succeeds' do
+ before do
+ push_pipeline.succeed!
+
+ wait_for_requests
+ end
+
+ it 'waits the head pipeline' do
+ expect(page).to have_content('to be merged automatically when the pipeline succeeds')
+ expect(page).to have_link('Cancel automatic merge')
+ end
+ end
+ end
+
+ context 'when there are no `merge_requests` keyword in .gitlab-ci.yml' do
+ let(:config) do
+ {
+ build: {
+ script: 'build'
+ },
+ test: {
+ script: 'test'
+ },
+ deploy: {
+ script: 'deploy'
+ }
+ }
+ end
+
+ it 'sees a branch pipeline in pipeline tab' do
+ page.within('.ci-table') do
+ expect(page).to have_selector('.ci-pending', count: 1)
+ expect(first('.js-pipeline-url-link')).to have_content("##{push_pipeline.id}")
+ end
+ end
+
+ it 'sees the latest branch pipeline as the head pipeline' do
+ page.within('.ci-widget-content') do
+ expect(page).to have_content("##{push_pipeline.id}")
+ end
+ end
+ end
+ end
+
+ context 'when a user created a merge request from a forked project to the parent project' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: forked_project,
+ target_project: project,
+ source_branch: 'feature',
+ target_branch: 'master')
+ end
+
+ let!(:push_pipeline) do
+ Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
+ .execute(:push)
+ end
+
+ let!(:merge_request_pipeline) do
+ Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
+ .execute(:merge_request, merge_request: merge_request)
+ end
+
+ let(:forked_project) { fork_project(project, user2, repository: true) }
+ let(:user2) { create(:user) }
+
+ before do
+ forked_project.add_maintainer(user2)
+
+ visit project_merge_request_path(project, merge_request)
+
+ page.within('.merge-request-tabs') do
+ click_link('Pipelines')
+ end
+ end
+
+ it 'sees branch pipelines and merge request pipelines in correct order' do
+ page.within('.ci-table') do
+ expect(page).to have_selector('.ci-pending', count: 2)
+ expect(first('.js-pipeline-url-link')).to have_content("##{merge_request_pipeline.id}")
+ end
+ end
+
+ it 'sees the latest merge request pipeline as the head pipeline' do
+ page.within('.ci-widget-content') do
+ expect(page).to have_content("##{merge_request_pipeline.id}")
+ end
+ end
+
+ it 'sees pipeline list in forked project' do
+ visit project_pipelines_path(forked_project)
+
+ expect(page).to have_selector('.ci-pending', count: 2)
+ end
+
+ context 'when a user updated a merge request from a forked project to the parent project' do
+ let!(:push_pipeline_2) do
+ Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
+ .execute(:push)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ Ci::CreatePipelineService.new(forked_project, user2, ref: 'feature')
+ .execute(:merge_request, merge_request: merge_request)
+ end
+
+ before do
+ visit project_merge_request_path(project, merge_request)
+
+ page.within('.merge-request-tabs') do
+ click_link('Pipelines')
+ end
+ end
+
+ it 'sees branch pipelines and merge request pipelines in correct order' do
+ page.within('.ci-table') do
+ expect(page).to have_selector('.ci-pending', count: 4)
+
+ expect(all('.js-pipeline-url-link')[0])
+ .to have_content("##{merge_request_pipeline_2.id}")
+
+ expect(all('.js-pipeline-url-link')[1])
+ .to have_content("##{merge_request_pipeline.id}")
+
+ expect(all('.js-pipeline-url-link')[2])
+ .to have_content("##{push_pipeline_2.id}")
+
+ expect(all('.js-pipeline-url-link')[3])
+ .to have_content("##{push_pipeline.id}")
+ end
+ end
+
+ it 'sees the latest merge request pipeline as the head pipeline' do
+ page.within('.ci-widget-content') do
+ expect(page).to have_content("##{merge_request_pipeline_2.id}")
+ end
+ end
+
+ it 'sees pipeline list in forked project' do
+ visit project_pipelines_path(forked_project)
+
+ expect(page).to have_selector('.ci-pending', count: 4)
+ end
+ end
+
+ context 'when a user merges a merge request from a forked project to the parent project' do
+ before do
+ click_button 'Merge when pipeline succeeds'
+
+ wait_for_requests
+ end
+
+ context 'when merge request pipeline is pending' do
+ it 'waits the head pipeline' do
+ expect(page).to have_content('to be merged automatically when the pipeline succeeds')
+ expect(page).to have_link('Cancel automatic merge')
+ end
+ end
+
+ context 'when merge request pipeline succeeds' do
+ before do
+ merge_request_pipeline.succeed!
+
+ wait_for_requests
+ end
+
+ it 'merges the merge request' do
+ expect(page).to have_content('Merged by')
+ expect(page).to have_link('Revert')
+ end
+ end
+
+ context 'when branch pipeline succeeds' do
+ before do
+ push_pipeline.succeed!
+
+ wait_for_requests
+ end
+
+ it 'waits the head pipeline' do
+ expect(page).to have_content('to be merged automatically when the pipeline succeeds')
+ expect(page).to have_link('Cancel automatic merge')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb
index bd254caddfb..caf69796d52 100644
--- a/spec/features/projects/commit/builds_spec.rb
+++ b/spec/features/projects/commit/builds_spec.rb
@@ -20,7 +20,7 @@ describe 'project commit pipelines', :js do
visit pipelines_project_commit_path(project, project.commit.sha)
page.within('.table-holder') do
- expect(page).to have_content project.pipelines[0].id # pipeline ids
+ expect(page).to have_content project.ci_pipelines[0].id # pipeline ids
end
end
end
diff --git a/spec/features/projects/members/list_spec.rb b/spec/features/projects/members/list_spec.rb
index c2e980e75b8..cf309492808 100644
--- a/spec/features/projects/members/list_spec.rb
+++ b/spec/features/projects/members/list_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe 'Project members list' do
include Select2Helper
+ include Spec::Support::Helpers::Features::ListRowsHelpers
let(:user1) { create(:user, name: 'John Doe') }
let(:user2) { create(:user, name: 'Mary Jane') }
@@ -83,14 +84,6 @@ describe 'Project members list' do
end
end
- def first_row
- page.all('ul.content-list > li')[0]
- end
-
- def second_row
- page.all('ul.content-list > li')[1]
- end
-
def add_user(id, role)
page.within ".users-project-form" do
select2(id, from: "#user_ids", multiple: true)
diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb
index 831f22a0e69..435fb229b69 100644
--- a/spec/features/projects/pages_spec.rb
+++ b/spec/features/projects/pages_spec.rb
@@ -300,7 +300,7 @@ describe 'Pages' do
let(:pipeline) do
commit_sha = project.commit('HEAD').sha
- project.pipelines.create(
+ project.ci_pipelines.create(
ref: 'HEAD',
sha: commit_sha,
source: :push,
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 0add129dde2..b56bb272b46 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -277,7 +277,7 @@ describe 'Project' do
end
end
- context 'for subgroups', :js do
+ context 'for subgroups', :js, :nested_groups do
let(:group) { create(:group) }
let(:subgroup) { create(:group, parent: group) }
let(:project) { create(:project, :repository, group: subgroup) }
diff --git a/spec/frontend/.eslintrc.yml b/spec/frontend/.eslintrc.yml
new file mode 100644
index 00000000000..6d73977a891
--- /dev/null
+++ b/spec/frontend/.eslintrc.yml
@@ -0,0 +1,9 @@
+---
+env:
+ jest/globals: true
+plugins:
+- jest
+settings:
+ import/resolver:
+ jest:
+ jestConfigFile: "config/jest.config.js"
diff --git a/spec/frontend/dummy_spec.js b/spec/frontend/dummy_spec.js
new file mode 100644
index 00000000000..2bfef25e9c6
--- /dev/null
+++ b/spec/frontend/dummy_spec.js
@@ -0,0 +1 @@
+it('does nothing', () => {});
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 7a06c178f0b..23e8761bc55 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -199,6 +199,84 @@ describe('DiffsStoreMutations', () => {
expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].id).toEqual(1);
});
+ it('should not duplicate discussions on line', () => {
+ const diffPosition = {
+ base_sha: 'ed13df29948c41ba367caa757ab3ec4892509910',
+ head_sha: 'b921914f9a834ac47e6fd9420f78db0f83559130',
+ new_line: null,
+ new_path: '500-lines-4.txt',
+ old_line: 5,
+ old_path: '500-lines-4.txt',
+ start_sha: 'ed13df29948c41ba367caa757ab3ec4892509910',
+ };
+
+ const state = {
+ latestDiff: true,
+ diffFiles: [
+ {
+ file_hash: 'ABC',
+ parallel_diff_lines: [
+ {
+ left: {
+ line_code: 'ABC_1',
+ discussions: [],
+ },
+ right: {
+ line_code: 'ABC_1',
+ discussions: [],
+ },
+ },
+ ],
+ highlighted_diff_lines: [
+ {
+ line_code: 'ABC_1',
+ discussions: [],
+ },
+ ],
+ },
+ ],
+ };
+ const discussion = {
+ id: 1,
+ line_code: 'ABC_1',
+ diff_discussion: true,
+ resolvable: true,
+ original_position: diffPosition,
+ position: diffPosition,
+ diff_file: {
+ file_hash: state.diffFiles[0].file_hash,
+ },
+ };
+
+ const diffPositionByLineCode = {
+ ABC_1: diffPosition,
+ };
+
+ mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, {
+ discussion,
+ diffPositionByLineCode,
+ });
+
+ expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions.length).toEqual(1);
+ expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions[0].id).toEqual(1);
+ expect(state.diffFiles[0].parallel_diff_lines[0].right.discussions).toEqual([]);
+
+ expect(state.diffFiles[0].highlighted_diff_lines[0].discussions.length).toEqual(1);
+ expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].id).toEqual(1);
+
+ mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, {
+ discussion,
+ diffPositionByLineCode,
+ });
+
+ expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions.length).toEqual(1);
+ expect(state.diffFiles[0].parallel_diff_lines[0].left.discussions[0].id).toEqual(1);
+ expect(state.diffFiles[0].parallel_diff_lines[0].right.discussions).toEqual([]);
+
+ expect(state.diffFiles[0].highlighted_diff_lines[0].discussions.length).toEqual(1);
+ expect(state.diffFiles[0].highlighted_diff_lines[0].discussions[0].id).toEqual(1);
+ });
+
it('should add legacy discussions to the given line', () => {
const diffPosition = {
base_sha: 'ed13df29948c41ba367caa757ab3ec4892509910',
diff --git a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
index 85d73e5c382..fab071405df 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/build_spec.rb
@@ -18,6 +18,7 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
before_sha: nil,
trigger_request: nil,
schedule: nil,
+ merge_request: nil,
project: project,
current_user: user,
variables_attributes: variables_attributes)
@@ -76,6 +77,7 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
before_sha: nil,
trigger_request: nil,
schedule: nil,
+ merge_request: nil,
project: project,
current_user: user)
end
@@ -90,4 +92,31 @@ describe Gitlab::Ci::Pipeline::Chain::Build do
expect(pipeline).to be_tag
end
end
+
+ context 'when pipeline is running for a merge request' do
+ let(:command) do
+ Gitlab::Ci::Pipeline::Chain::Command.new(
+ source: :merge_request,
+ origin_ref: 'feature',
+ checkout_sha: project.commit.id,
+ after_sha: nil,
+ before_sha: nil,
+ trigger_request: nil,
+ schedule: nil,
+ merge_request: merge_request,
+ project: project,
+ current_user: user)
+ end
+
+ let(:merge_request) { build(:merge_request, target_project: project) }
+
+ before do
+ step.perform!
+ end
+
+ it 'correctly indicated that this is a merge request pipeline' do
+ expect(pipeline).to be_merge_request
+ expect(pipeline.merge_request).to eq(merge_request)
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
index a8dc5356413..053bc421649 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/config_spec.rb
@@ -106,4 +106,34 @@ describe Gitlab::Ci::Pipeline::Chain::Validate::Config do
expect(step.break?).to be false
end
end
+
+ context 'when pipeline source is merge request' do
+ before do
+ stub_ci_pipeline_yaml_file(YAML.dump(config))
+ end
+
+ let(:pipeline) { build_stubbed(:ci_pipeline, project: project) }
+
+ let(:merge_request_pipeline) do
+ build(:ci_pipeline, source: :merge_request, project: project)
+ end
+
+ let(:chain) { described_class.new(merge_request_pipeline, command).tap(&:perform!) }
+
+ context "when config contains 'merge_requests' keyword" do
+ let(:config) { { rspec: { script: 'echo', only: ['merge_requests'] } } }
+
+ it 'does not break the chain' do
+ expect(chain).not_to be_break
+ end
+ end
+
+ context "when config contains 'merge_request' keyword" do
+ let(:config) { { rspec: { script: 'echo', only: ['merge_request'] } } }
+
+ it 'does not break the chain' do
+ expect(chain).not_to be_break
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/diff/file_collection/commit_spec.rb b/spec/lib/gitlab/diff/file_collection/commit_spec.rb
index 6d1b66deb6a..34ed22b8941 100644
--- a/spec/lib/gitlab/diff/file_collection/commit_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/commit_spec.rb
@@ -12,4 +12,8 @@ describe Gitlab::Diff::FileCollection::Commit do
let(:diffable) { project.commit }
let(:stub_path) { 'bar/branch-test.txt' }
end
+
+ it_behaves_like 'unfoldable diff' do
+ let(:diffable) { project.commit }
+ end
end
diff --git a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
index fbcf515281e..256166dbad3 100644
--- a/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/merge_request_diff_spec.rb
@@ -2,22 +2,29 @@ require 'spec_helper'
describe Gitlab::Diff::FileCollection::MergeRequestDiff do
let(:merge_request) { create(:merge_request) }
- let(:diff_files) { described_class.new(merge_request.merge_request_diff, diff_options: nil).diff_files }
+ let(:subject) { described_class.new(merge_request.merge_request_diff, diff_options: nil) }
+ let(:diff_files) { subject.diff_files }
- it 'does not highlight binary files' do
- allow_any_instance_of(Gitlab::Diff::File).to receive(:text?).and_return(false)
+ describe '#diff_files' do
+ it 'does not highlight binary files' do
+ allow_any_instance_of(Gitlab::Diff::File).to receive(:text?).and_return(false)
- expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines)
+ expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines)
- diff_files
- end
+ diff_files
+ end
+
+ it 'does not highlight files marked as undiffable in .gitattributes' do
+ allow_any_instance_of(Gitlab::Diff::File).to receive(:diffable?).and_return(false)
- it 'does not highlight files marked as undiffable in .gitattributes' do
- allow_any_instance_of(Gitlab::Diff::File).to receive(:diffable?).and_return(false)
+ expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines)
- expect_any_instance_of(Gitlab::Diff::File).not_to receive(:highlighted_diff_lines)
+ diff_files
+ end
+ end
- diff_files
+ it_behaves_like 'unfoldable diff' do
+ let(:diffable) { merge_request.merge_request_diff }
end
it 'it uses a different cache key if diff line keys change' do
diff --git a/spec/lib/gitlab/group_hierarchy_spec.rb b/spec/lib/gitlab/group_hierarchy_spec.rb
index 30686634af4..f3de7adcec7 100644
--- a/spec/lib/gitlab/group_hierarchy_spec.rb
+++ b/spec/lib/gitlab/group_hierarchy_spec.rb
@@ -34,6 +34,28 @@ describe Gitlab::GroupHierarchy, :postgresql do
expect { relation.update_all(share_with_group_lock: false) }
.to raise_error(ActiveRecord::ReadOnlyRecord)
end
+
+ describe 'hierarchy_order option' do
+ let(:relation) do
+ described_class.new(Group.where(id: child2.id)).base_and_ancestors(hierarchy_order: hierarchy_order)
+ end
+
+ context ':asc' do
+ let(:hierarchy_order) { :asc }
+
+ it 'orders by child to parent' do
+ expect(relation).to eq([child2, child1, parent])
+ end
+ end
+
+ context ':desc' do
+ let(:hierarchy_order) { :desc }
+
+ it 'orders by parent to child' do
+ expect(relation).to eq([parent, child1, child2])
+ end
+ end
+ end
end
describe '#base_and_descendants' do
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 31ab11bbf8d..7df129da95a 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -94,6 +94,7 @@ merge_requests:
- timelogs
- head_pipeline
- latest_merge_request_diff
+- merge_request_pipelines
merge_request_diff:
- merge_request
- merge_request_diff_commits
@@ -102,7 +103,7 @@ merge_request_diff_commits:
- merge_request_diff
merge_request_diff_files:
- merge_request_diff
-pipelines:
+ci_pipelines:
- project
- user
- stages
@@ -121,6 +122,7 @@ pipelines:
- artifacts
- pipeline_schedule
- merge_requests
+- merge_request
- deployments
- environments
pipeline_variables:
@@ -263,7 +265,8 @@ project:
- notification_settings
- import_data
- commit_statuses
-- pipelines
+- ci_pipelines
+- all_pipelines
- stages
- builds
- runner_projects
@@ -304,6 +307,7 @@ project:
- import_export_upload
- repository_languages
- pool_repository
+- kubernetes_namespaces
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index 7171e12a849..242c16c4bdc 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -197,9 +197,9 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
end
it 'has the correct number of pipelines and statuses' do
- expect(@project.pipelines.size).to eq(5)
+ expect(@project.ci_pipelines.size).to eq(5)
- @project.pipelines.zip([2, 2, 2, 2, 2])
+ @project.ci_pipelines.zip([2, 2, 2, 2, 2])
.each do |(pipeline, expected_status_size)|
expect(pipeline.statuses.size).to eq(expected_status_size)
end
diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
index 5dc372263ad..46fdfba953b 100644
--- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb
@@ -119,16 +119,16 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
end
it 'has pipeline stages' do
- expect(saved_project_json.dig('pipelines', 0, 'stages')).not_to be_empty
+ expect(saved_project_json.dig('ci_pipelines', 0, 'stages')).not_to be_empty
end
it 'has pipeline statuses' do
- expect(saved_project_json.dig('pipelines', 0, 'stages', 0, 'statuses')).not_to be_empty
+ expect(saved_project_json.dig('ci_pipelines', 0, 'stages', 0, 'statuses')).not_to be_empty
end
it 'has pipeline builds' do
builds_count = saved_project_json
- .dig('pipelines', 0, 'stages', 0, 'statuses')
+ .dig('ci_pipelines', 0, 'stages', 0, 'statuses')
.count { |hash| hash['type'] == 'Ci::Build' }
expect(builds_count).to eq(1)
@@ -142,11 +142,11 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
end
it 'has pipeline commits' do
- expect(saved_project_json['pipelines']).not_to be_empty
+ expect(saved_project_json['ci_pipelines']).not_to be_empty
end
it 'has ci pipeline notes' do
- expect(saved_project_json['pipelines'].first['notes']).not_to be_empty
+ expect(saved_project_json['ci_pipelines'].first['notes']).not_to be_empty
end
it 'has labels with no associations' do
diff --git a/spec/lib/gitlab/import_export/relation_rename_service_spec.rb b/spec/lib/gitlab/import_export/relation_rename_service_spec.rb
new file mode 100644
index 00000000000..a20a844a492
--- /dev/null
+++ b/spec/lib/gitlab/import_export/relation_rename_service_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ImportExport::RelationRenameService do
+ let(:renames) do
+ {
+ 'example_relation1' => 'new_example_relation1',
+ 'example_relation2' => 'new_example_relation2'
+ }
+ end
+
+ let(:user) { create(:admin) }
+ let(:group) { create(:group, :nested) }
+ let!(:project) { create(:project, :builds_disabled, :issues_disabled, name: 'project', path: 'project') }
+ let(:shared) { project.import_export_shared }
+
+ before do
+ stub_const("#{described_class}::RENAMES", renames)
+ end
+
+ context 'when importing' do
+ let(:project_tree_restorer) { Gitlab::ImportExport::ProjectTreeRestorer.new(user: user, shared: shared, project: project) }
+ let(:import_path) { 'spec/lib/gitlab/import_export' }
+ let(:file_content) { IO.read("#{import_path}/project.json") }
+ let!(:json_file) { ActiveSupport::JSON.decode(file_content) }
+ let(:tree_hash) { project_tree_restorer.instance_variable_get(:@tree_hash) }
+
+ before do
+ allow(shared).to receive(:export_path).and_return(import_path)
+ allow(ActiveSupport::JSON).to receive(:decode).with(file_content).and_return(json_file)
+ end
+
+ context 'when the file has only old relationship names' do
+ # Configuring the json as an old version exported file, with only
+ # the previous association with the old name
+ before do
+ renames.each do |old_name, _|
+ json_file[old_name.to_s] = []
+ end
+ end
+
+ it 'renames old relationships to the new name' do
+ expect(json_file.keys).to include(*renames.keys)
+
+ project_tree_restorer.restore
+
+ expect(json_file.keys).to include(*renames.values)
+ expect(json_file.keys).not_to include(*renames.keys)
+ end
+ end
+
+ context 'when the file has both the old and new relationships' do
+ # Configuring the json as the new version exported file, with both
+ # the old association name and the new one
+ before do
+ renames.each do |old_name, new_name|
+ json_file[old_name.to_s] = [1]
+ json_file[new_name.to_s] = [2]
+ end
+ end
+
+ it 'uses the new relationships and removes the old ones from the hash' do
+ expect(json_file.keys).to include(*renames.keys)
+
+ project_tree_restorer.restore
+
+ expect(json_file.keys).to include(*renames.values)
+ expect(json_file.values_at(*renames.values).flatten.uniq.first).to eq 2
+ expect(json_file.keys).not_to include(*renames.keys)
+ end
+ end
+
+ context 'when the file has only new relationship names' do
+ # Configuring the json as the future version exported file, with only
+ # the new association name
+ before do
+ renames.each do |_, new_name|
+ json_file[new_name.to_s] = []
+ end
+ end
+
+ it 'uses the new relationships' do
+ expect(json_file.keys).not_to include(*renames.keys)
+
+ project_tree_restorer.restore
+
+ expect(json_file.keys).to include(*renames.values)
+ end
+ end
+ end
+
+ context 'when exporting' do
+ let(:project_tree_saver) { Gitlab::ImportExport::ProjectTreeSaver.new(project: project, current_user: user, shared: shared) }
+ let(:project_tree) { project_tree_saver.send(:project_json) }
+
+ it 'adds old relationships to the exported file' do
+ project_tree.merge!(renames.values.map { |new_name| [new_name, []] }.to_h)
+
+ allow(project_tree_saver).to receive(:save) do |arg|
+ project_tree_saver.send(:project_json_tree)
+ end
+
+ result = project_tree_saver.save
+
+ saved_data = ActiveSupport::JSON.decode(result)
+
+ expect(saved_data.keys).to include(*(renames.keys + renames.values))
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index f7935149b23..d3bfde181bc 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -243,6 +243,7 @@ Ci::Pipeline:
- failure_reason
- protected
- iid
+- merge_request_id
Ci::Stage:
- id
- name
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 5390f237073..e2de612ff46 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -17,6 +17,9 @@ describe Gitlab::UsageData do
gcp_cluster = create(:cluster, :provided_by_gcp)
create(:cluster, :provided_by_user)
create(:cluster, :provided_by_user, :disabled)
+ create(:cluster, :group)
+ create(:cluster, :group, :disabled)
+ create(:cluster, :group, :disabled)
create(:clusters_applications_helm, :installed, cluster: gcp_cluster)
create(:clusters_applications_ingress, :installed, cluster: gcp_cluster)
create(:clusters_applications_cert_managers, :installed, cluster: gcp_cluster)
@@ -77,7 +80,11 @@ describe Gitlab::UsageData do
environments
clusters
clusters_enabled
+ project_clusters_enabled
+ group_clusters_enabled
clusters_disabled
+ project_clusters_disabled
+ group_clusters_disabled
clusters_platforms_gke
clusters_platforms_user
clusters_applications_helm
@@ -127,8 +134,13 @@ describe Gitlab::UsageData do
expect(count_data[:projects_slack_notifications_active]).to eq(2)
expect(count_data[:projects_slack_slash_active]).to eq(1)
- expect(count_data[:clusters_enabled]).to eq(6)
- expect(count_data[:clusters_disabled]).to eq(1)
+ expect(count_data[:clusters_enabled]).to eq(7)
+ expect(count_data[:project_clusters_enabled]).to eq(6)
+ expect(count_data[:group_clusters_enabled]).to eq(1)
+ expect(count_data[:clusters_disabled]).to eq(3)
+ expect(count_data[:project_clusters_disabled]).to eq(1)
+ expect(count_data[:group_clusters_disabled]).to eq(2)
+ expect(count_data[:group_clusters_enabled]).to eq(1)
expect(count_data[:clusters_platforms_gke]).to eq(1)
expect(count_data[:clusters_platforms_user]).to eq(1)
expect(count_data[:clusters_applications_helm]).to eq(1)
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 3076a882445..ba9540c84d4 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -14,6 +14,7 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:auto_canceled_by) }
it { is_expected.to belong_to(:pipeline_schedule) }
+ it { is_expected.to belong_to(:merge_request) }
it { is_expected.to have_many(:statuses) }
it { is_expected.to have_many(:trigger_requests) }
@@ -32,8 +33,131 @@ describe Ci::Pipeline, :mailer do
describe 'associations' do
it 'has a bidirectional relationship with projects' do
- expect(described_class.reflect_on_association(:project).has_inverse?).to eq(:pipelines)
- expect(Project.reflect_on_association(:pipelines).has_inverse?).to eq(:project)
+ expect(described_class.reflect_on_association(:project).has_inverse?).to eq(:all_pipelines)
+ expect(Project.reflect_on_association(:all_pipelines).has_inverse?).to eq(:project)
+ expect(Project.reflect_on_association(:ci_pipelines).has_inverse?).to eq(:project)
+ end
+ end
+
+ describe '.sort_by_merge_request_pipelines' do
+ subject { described_class.sort_by_merge_request_pipelines }
+
+ context 'when branch pipelines exist' do
+ let!(:branch_pipeline_1) { create(:ci_pipeline, source: :push) }
+ let!(:branch_pipeline_2) { create(:ci_pipeline, source: :push) }
+
+ it 'returns pipelines order by id' do
+ expect(subject).to eq([branch_pipeline_2,
+ branch_pipeline_1])
+ end
+ end
+
+ context 'when merge request pipelines exist' do
+ let!(:merge_request_pipeline_1) do
+ create(:ci_pipeline, source: :merge_request, merge_request: merge_request)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ create(:ci_pipeline, source: :merge_request, merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: 'feature',
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'returns pipelines order by id' do
+ expect(subject).to eq([merge_request_pipeline_2,
+ merge_request_pipeline_1])
+ end
+ end
+
+ context 'when both branch pipeline and merge request pipeline exist' do
+ let!(:branch_pipeline_1) { create(:ci_pipeline, source: :push) }
+ let!(:branch_pipeline_2) { create(:ci_pipeline, source: :push) }
+
+ let!(:merge_request_pipeline_1) do
+ create(:ci_pipeline, source: :merge_request, merge_request: merge_request)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ create(:ci_pipeline, source: :merge_request, merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: 'feature',
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'returns merge request pipeline first' do
+ expect(subject).to eq([merge_request_pipeline_2,
+ merge_request_pipeline_1,
+ branch_pipeline_2,
+ branch_pipeline_1])
+ end
+ end
+ end
+
+ describe '.merge_request' do
+ subject { described_class.merge_request }
+
+ context 'when there is a merge request pipeline' do
+ let!(:pipeline) { create(:ci_pipeline, source: :merge_request, merge_request: merge_request) }
+ let(:merge_request) { create(:merge_request) }
+
+ it 'returns merge request pipeline first' do
+ expect(subject).to eq([pipeline])
+ end
+ end
+
+ context 'when there are no merge request pipelines' do
+ let!(:pipeline) { create(:ci_pipeline, source: :push) }
+
+ it 'returns empty array' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+
+ describe 'Validations for merge request pipelines' do
+ let(:pipeline) { build(:ci_pipeline, source: source, merge_request: merge_request) }
+
+ context 'when source is merge request' do
+ let(:source) { :merge_request }
+
+ context 'when merge request is specified' do
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_project: project, target_branch: 'master') }
+
+ it { expect(pipeline).to be_valid }
+ end
+
+ context 'when merge request is empty' do
+ let(:merge_request) { nil }
+
+ it { expect(pipeline).not_to be_valid }
+ end
+ end
+
+ context 'when source is web' do
+ let(:source) { :web }
+
+ context 'when merge request is specified' do
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_project: project, target_branch: 'master') }
+
+ it { expect(pipeline).not_to be_valid }
+ end
+
+ context 'when merge request is empty' do
+ let(:merge_request) { nil }
+
+ it { expect(pipeline).to be_valid }
+ end
end
end
@@ -760,27 +884,85 @@ describe Ci::Pipeline, :mailer do
describe '#branch?' do
subject { pipeline.branch? }
- context 'is not a tag' do
+ context 'when ref is not a tag' do
before do
pipeline.tag = false
end
- it 'return true when tag is set to false' do
+ it 'return true' do
is_expected.to be_truthy
end
+
+ context 'when source is merge request' do
+ let(:pipeline) do
+ create(:ci_pipeline, source: :merge_request, merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: 'feature',
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'returns false' do
+ is_expected.to be_falsey
+ end
+ end
end
- context 'is not a tag' do
+ context 'when ref is a tag' do
before do
pipeline.tag = true
end
- it 'return false when tag is set to true' do
+ it 'return false' do
is_expected.to be_falsey
end
end
end
+ describe '#git_ref' do
+ subject { pipeline.send(:git_ref) }
+
+ context 'when ref is branch' do
+ let(:pipeline) { create(:ci_pipeline, tag: false) }
+
+ it 'returns branch ref' do
+ is_expected.to eq(Gitlab::Git::BRANCH_REF_PREFIX + pipeline.ref.to_s)
+ end
+ end
+
+ context 'when ref is tag' do
+ let(:pipeline) { create(:ci_pipeline, tag: true) }
+
+ it 'returns branch ref' do
+ is_expected.to eq(Gitlab::Git::TAG_REF_PREFIX + pipeline.ref.to_s)
+ end
+ end
+
+ context 'when ref is merge request' do
+ let(:pipeline) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: 'feature',
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'returns branch ref' do
+ is_expected.to eq(Gitlab::Git::BRANCH_REF_PREFIX + pipeline.ref.to_s)
+ end
+ end
+ end
+
describe 'ref_exists?' do
context 'when repository exists' do
using RSpec::Parameterized::TableSyntax
@@ -1005,7 +1187,7 @@ describe Ci::Pipeline, :mailer do
create(:ci_build, :allowed_to_fail, :failed, pipeline: pipeline, name: 'rubocop')
create(:ci_build, :allowed_to_fail, :failed, pipeline: pipeline2, name: 'rubocop')
- pipelines = project.pipelines.to_a
+ pipelines = project.ci_pipelines.to_a
pipelines.each(&:number_of_warnings)
@@ -1855,6 +2037,55 @@ describe Ci::Pipeline, :mailer do
expect(pipeline.all_merge_requests).to be_empty
end
+
+ context 'when there is a merge request pipeline' do
+ let(:source_branch) { 'feature' }
+ let(:target_branch) { 'master' }
+
+ let!(:pipeline) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ project: project,
+ ref: source_branch,
+ merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: source_branch,
+ target_project: project,
+ target_branch: target_branch)
+ end
+
+ it 'returns an associated merge request' do
+ expect(pipeline.all_merge_requests).to eq([merge_request])
+ end
+
+ context 'when there is another merge request pipeline that targets a different branch' do
+ let(:target_branch_2) { 'merge-test' }
+
+ let!(:pipeline_2) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ project: project,
+ ref: source_branch,
+ merge_request: merge_request_2)
+ end
+
+ let(:merge_request_2) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: source_branch,
+ target_project: project,
+ target_branch: target_branch_2)
+ end
+
+ it 'does not return an associated merge request' do
+ expect(pipeline.all_merge_requests).not_to include(merge_request_2)
+ end
+ end
+ end
end
describe '#stuck?' do
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 7dcf97276b2..840f74c9890 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -92,6 +92,26 @@ describe Clusters::Cluster do
it { is_expected.to contain_exactly(cluster) }
end
+ describe '.missing_kubernetes_namespace' do
+ let!(:cluster) { create(:cluster, :provided_by_gcp, :project) }
+ let(:project) { cluster.project }
+ let(:kubernetes_namespaces) { project.kubernetes_namespaces }
+
+ subject do
+ described_class.joins(:projects).where(projects: { id: project.id }).missing_kubernetes_namespace(kubernetes_namespaces)
+ end
+
+ it { is_expected.to contain_exactly(cluster) }
+
+ context 'kubernetes namespace exists' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ it { is_expected.to be_empty }
+ end
+ end
+
describe 'validation' do
subject { cluster.valid? }
@@ -233,6 +253,81 @@ describe Clusters::Cluster do
end
end
+ describe '.ancestor_clusters_for_clusterable' do
+ let(:group_cluster) { create(:cluster, :provided_by_gcp, :group) }
+ let(:group) { group_cluster.group }
+ let(:hierarchy_order) { :desc }
+ let(:clusterable) { project }
+
+ subject do
+ described_class.ancestor_clusters_for_clusterable(clusterable, hierarchy_order: hierarchy_order)
+ end
+
+ context 'when project does not belong to this group' do
+ let(:project) { create(:project, group: create(:group)) }
+
+ it 'returns nothing' do
+ is_expected.to be_empty
+ end
+ end
+
+ context 'when group has a configured kubernetes cluster' do
+ let(:project) { create(:project, group: group) }
+
+ it 'returns the group cluster' do
+ is_expected.to eq([group_cluster])
+ end
+ end
+
+ context 'when sub-group has configured kubernetes cluster', :nested_groups do
+ let(:sub_group_cluster) { create(:cluster, :provided_by_gcp, :group) }
+ let(:sub_group) { sub_group_cluster.group }
+ let(:project) { create(:project, group: sub_group) }
+
+ before do
+ sub_group.update!(parent: group)
+ end
+
+ it 'returns clusters in order, descending the hierachy' do
+ is_expected.to eq([group_cluster, sub_group_cluster])
+ end
+
+ it 'avoids N+1 queries' do
+ another_project = create(:project)
+ control_count = ActiveRecord::QueryRecorder.new do
+ described_class.ancestor_clusters_for_clusterable(another_project, hierarchy_order: hierarchy_order)
+ end.count
+
+ cluster2 = create(:cluster, :provided_by_gcp, :group)
+ child2 = cluster2.group
+ child2.update!(parent: sub_group)
+ project = create(:project, group: child2)
+
+ expect do
+ described_class.ancestor_clusters_for_clusterable(project, hierarchy_order: hierarchy_order)
+ end.not_to exceed_query_limit(control_count)
+ end
+
+ context 'for a group' do
+ let(:clusterable) { sub_group }
+
+ it 'returns clusters in order for a group' do
+ is_expected.to eq([group_cluster])
+ end
+ end
+ end
+
+ context 'scope chaining' do
+ let(:project) { create(:project, group: group) }
+
+ subject { described_class.none.ancestor_clusters_for_clusterable(project) }
+
+ it 'returns nothing' do
+ is_expected.to be_empty
+ end
+ end
+ end
+
describe '#provider' do
subject { cluster.provider }
@@ -265,6 +360,31 @@ describe Clusters::Cluster do
end
end
+ describe '#all_projects' do
+ let(:project) { create(:project) }
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ subject { cluster.all_projects }
+
+ context 'project cluster' do
+ it 'returns project' do
+ is_expected.to eq([project])
+ end
+ end
+
+ context 'group cluster' do
+ let(:cluster) { create(:cluster, :group) }
+ let(:group) { cluster.group }
+ let(:project) { create(:project, group: group) }
+ let(:subgroup) { create(:group, parent: group) }
+ let(:subproject) { create(:project, group: subgroup) }
+
+ it 'returns all projects for group' do
+ is_expected.to contain_exactly(project, subproject)
+ end
+ end
+ end
+
describe '#first_project' do
subject { cluster.first_project }
diff --git a/spec/models/concerns/chronic_duration_attribute_spec.rb b/spec/models/concerns/chronic_duration_attribute_spec.rb
index 8847623f705..b14b773b653 100644
--- a/spec/models/concerns/chronic_duration_attribute_spec.rb
+++ b/spec/models/concerns/chronic_duration_attribute_spec.rb
@@ -54,7 +54,8 @@ shared_examples 'ChronicDurationAttribute writer' do
subject.send("#{virtual_field}=", '-10m')
expect(subject.valid?).to be_falsey
- expect(subject.errors&.messages).to include(virtual_field => ['is not a correct duration'])
+ expect(subject.errors&.messages)
+ .to include(base: ['Maximum job timeout has a value which could not be accepted'])
end
end
diff --git a/spec/models/concerns/deployment_platform_spec.rb b/spec/models/concerns/deployment_platform_spec.rb
index 7bb89fe41dc..19ab4382b53 100644
--- a/spec/models/concerns/deployment_platform_spec.rb
+++ b/spec/models/concerns/deployment_platform_spec.rb
@@ -43,13 +43,86 @@ describe DeploymentPlatform do
it { is_expected.to be_nil }
end
- context 'when user configured kubernetes from CI/CD > Clusters' do
+ context 'when project has configured kubernetes from CI/CD > Clusters' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:platform_kubernetes) { cluster.platform_kubernetes }
it 'returns the Kubernetes platform' do
expect(subject).to eq(platform_kubernetes)
end
+
+ context 'with a group level kubernetes cluster' do
+ let(:group_cluster) { create(:cluster, :provided_by_gcp, :group) }
+
+ before do
+ project.update!(group: group_cluster.group)
+ end
+
+ it 'returns the Kubernetes platform from the project cluster' do
+ expect(subject).to eq(platform_kubernetes)
+ end
+ end
+ end
+
+ context 'when group has configured kubernetes cluster' do
+ let!(:group_cluster) { create(:cluster, :provided_by_gcp, :group) }
+ let(:group) { group_cluster.group }
+
+ before do
+ project.update!(group: group)
+ end
+
+ it 'returns the Kubernetes platform' do
+ is_expected.to eq(group_cluster.platform_kubernetes)
+ end
+
+ context 'when child group has configured kubernetes cluster', :nested_groups do
+ let!(:child_group1_cluster) { create(:cluster, :provided_by_gcp, :group) }
+ let(:child_group1) { child_group1_cluster.group }
+
+ before do
+ project.update!(group: child_group1)
+ child_group1.update!(parent: group)
+ end
+
+ it 'returns the Kubernetes platform for the child group' do
+ is_expected.to eq(child_group1_cluster.platform_kubernetes)
+ end
+
+ context 'deeply nested group' do
+ let!(:child_group2_cluster) { create(:cluster, :provided_by_gcp, :group) }
+ let(:child_group2) { child_group2_cluster.group }
+
+ before do
+ child_group2.update!(parent: child_group1)
+ project.update!(group: child_group2)
+ end
+
+ it 'returns most nested group cluster Kubernetes platform' do
+ is_expected.to eq(child_group2_cluster.platform_kubernetes)
+ end
+
+ context 'cluster in the middle of hierarchy is disabled' do
+ before do
+ child_group2_cluster.update!(enabled: false)
+ end
+
+ it 'returns closest enabled Kubenetes platform' do
+ is_expected.to eq(child_group1_cluster.platform_kubernetes)
+ end
+ end
+ end
+ end
+
+ context 'feature flag disabled' do
+ before do
+ stub_feature_flags(group_clusters: false)
+ end
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
end
context 'when user configured kubernetes integration from project services' do
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index ada00f03928..0c3a49cd0f2 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -745,4 +745,33 @@ describe Group do
let(:uploader_class) { AttachmentUploader }
end
end
+
+ describe '#group_clusters_enabled?' do
+ before do
+ # Override global stub in spec/spec_helper.rb
+ expect(Feature).to receive(:enabled?).and_call_original
+ end
+
+ subject { group.group_clusters_enabled? }
+
+ it { is_expected.to be_truthy }
+
+ context 'explicitly disabled for root ancestor' do
+ before do
+ feature = Feature.get(:group_clusters)
+ feature.disable(group.root_ancestor)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'explicitly disabled for root ancestor' do
+ before do
+ feature = Feature.get(:group_clusters)
+ feature.enable(group.root_ancestor)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index ad55c280399..9b60054e14a 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -1206,6 +1206,119 @@ describe MergeRequest do
expect(subject.all_pipelines).to contain_exactly(pipeline)
end
end
+
+ context 'when pipelines exist for the branch and merge request' do
+ let(:source_ref) { 'feature' }
+ let(:target_ref) { 'master' }
+
+ let!(:branch_pipeline) do
+ create(:ci_pipeline,
+ source: :push,
+ project: project,
+ ref: source_ref,
+ sha: shas.second)
+ end
+
+ let!(:merge_request_pipeline) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ project: project,
+ ref: source_ref,
+ sha: shas.second,
+ merge_request: merge_request)
+ end
+
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: source_ref,
+ target_project: project,
+ target_branch: target_ref)
+ end
+
+ let(:project) { create(:project, :repository) }
+ let(:shas) { project.repository.commits(source_ref, limit: 2).map(&:id) }
+
+ before do
+ allow(merge_request).to receive(:all_commit_shas) { shas }
+ end
+
+ it 'returns merge request pipeline first' do
+ expect(merge_request.all_pipelines)
+ .to eq([merge_request_pipeline,
+ branch_pipeline])
+ end
+
+ context 'when there are a branch pipeline and a merge request pipeline' do
+ let!(:branch_pipeline_2) do
+ create(:ci_pipeline,
+ source: :push,
+ project: project,
+ ref: source_ref,
+ sha: shas.first)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ project: project,
+ ref: source_ref,
+ sha: shas.first,
+ merge_request: merge_request)
+ end
+
+ it 'returns merge request pipelines first' do
+ expect(merge_request.all_pipelines)
+ .to eq([merge_request_pipeline_2,
+ merge_request_pipeline,
+ branch_pipeline_2,
+ branch_pipeline])
+ end
+ end
+
+ context 'when there are multiple merge request pipelines from the same branch' do
+ let!(:branch_pipeline_2) do
+ create(:ci_pipeline,
+ source: :push,
+ project: project,
+ ref: source_ref,
+ sha: shas.first)
+ end
+
+ let!(:merge_request_pipeline_2) do
+ create(:ci_pipeline,
+ source: :merge_request,
+ project: project,
+ ref: source_ref,
+ sha: shas.first,
+ merge_request: merge_request_2)
+ end
+
+ let(:merge_request_2) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: source_ref,
+ target_project: project,
+ target_branch: 'stable')
+ end
+
+ before do
+ allow(merge_request_2).to receive(:all_commit_shas) { shas }
+ end
+
+ it 'returns only related merge request pipelines' do
+ expect(merge_request.all_pipelines)
+ .to eq([merge_request_pipeline,
+ branch_pipeline_2,
+ branch_pipeline])
+
+ expect(merge_request_2.all_pipelines)
+ .to eq([merge_request_pipeline_2,
+ branch_pipeline_2,
+ branch_pipeline])
+ end
+ end
+ end
end
describe '#has_test_reports?' do
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 2db42fe802a..6ee19c0ddf4 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -560,6 +560,7 @@ describe Namespace do
let!(:project2) { create(:project_empty_repo, namespace: child) }
it { expect(group.all_projects.to_a).to match_array([project2, project1]) }
+ it { expect(child.all_projects.to_a).to match_array([project2]) }
end
describe '#all_pipelines' do
@@ -720,6 +721,7 @@ describe Namespace do
deep_nested_group = create(:group, parent: nested_group)
very_deep_nested_group = create(:group, parent: deep_nested_group)
+ expect(root_group.root_ancestor).to eq(root_group)
expect(nested_group.root_ancestor).to eq(root_group)
expect(deep_nested_group.root_ancestor).to eq(root_group)
expect(very_deep_nested_group.root_ancestor).to eq(root_group)
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 54ad3c858d5..50920d9d1fc 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -63,7 +63,7 @@ describe Project do
it { is_expected.to have_one(:forked_from_project).through(:fork_network_member) }
it { is_expected.to have_one(:auto_devops).class_name('ProjectAutoDevops') }
it { is_expected.to have_many(:commit_statuses) }
- it { is_expected.to have_many(:pipelines) }
+ it { is_expected.to have_many(:ci_pipelines) }
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:build_trace_section_names)}
it { is_expected.to have_many(:runner_projects) }
@@ -87,6 +87,7 @@ describe Project do
it { is_expected.to have_many(:pipeline_schedules) }
it { is_expected.to have_many(:members_and_requesters) }
it { is_expected.to have_many(:clusters) }
+ it { is_expected.to have_many(:kubernetes_namespaces) }
it { is_expected.to have_many(:custom_attributes).class_name('ProjectCustomAttribute') }
it { is_expected.to have_many(:project_badges).class_name('ProjectBadge') }
it { is_expected.to have_many(:lfs_file_locks) }
@@ -142,6 +143,29 @@ describe Project do
expect(subject.boards.size).to eq 1
end
end
+
+ describe 'ci_pipelines association' do
+ context 'when feature flag pipeline_ci_sources_only is enabled' do
+ it 'returns only pipelines from ci_sources' do
+ stub_feature_flags(pipeline_ci_sources_only: true)
+
+ expect(Ci::Pipeline).to receive(:ci_sources).and_call_original
+
+ subject.ci_pipelines
+ end
+ end
+
+ context 'when feature flag pipeline_ci_sources_only is disabled' do
+ it 'returns all pipelines' do
+ stub_feature_flags(pipeline_ci_sources_only: false)
+
+ expect(Ci::Pipeline).not_to receive(:ci_sources).and_call_original
+ expect(Ci::Pipeline).to receive(:all).and_call_original.at_least(:once)
+
+ subject.ci_pipelines
+ end
+ end
+ end
end
describe 'modules' do
@@ -154,6 +178,24 @@ describe Project do
it { is_expected.to include_module(Sortable) }
end
+ describe '.missing_kubernetes_namespace' do
+ let!(:project) { create(:project) }
+ let!(:cluster) { create(:cluster, :provided_by_user, :group) }
+ let(:kubernetes_namespaces) { project.kubernetes_namespaces }
+
+ subject { described_class.missing_kubernetes_namespace(kubernetes_namespaces) }
+
+ it { is_expected.to contain_exactly(project) }
+
+ context 'kubernetes namespace exists' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ it { is_expected.to be_empty }
+ end
+ end
+
describe 'validation' do
let!(:project) { create(:project) }
@@ -393,6 +435,8 @@ describe Project do
it { is_expected.to delegate_method(:members).to(:team).with_prefix(true) }
it { is_expected.to delegate_method(:name).to(:owner).with_prefix(true).with_arguments(allow_nil: true) }
+ it { is_expected.to delegate_method(:group_clusters_enabled?).to(:group).with_arguments(allow_nil: true) }
+ it { is_expected.to delegate_method(:root_ancestor).to(:namespace).with_arguments(allow_nil: true) }
end
describe '#to_reference_with_postfix' do
@@ -2098,6 +2142,39 @@ describe Project do
it 'includes ancestors upto but excluding the given ancestor' do
expect(project.ancestors_upto(parent)).to contain_exactly(child2, child)
end
+
+ describe 'with hierarchy_order' do
+ it 'returns ancestors ordered by descending hierarchy' do
+ expect(project.ancestors_upto(hierarchy_order: :desc)).to eq([parent, child, child2])
+ end
+
+ it 'can be used with upto option' do
+ expect(project.ancestors_upto(parent, hierarchy_order: :desc)).to eq([child, child2])
+ end
+ end
+ end
+
+ describe '#root_ancestor' do
+ let(:project) { create(:project) }
+
+ subject { project.root_ancestor }
+
+ it { is_expected.to eq(project.namespace) }
+
+ context 'in a group' do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
+
+ it { is_expected.to eq(group) }
+ end
+
+ context 'in a nested group', :nested_groups do
+ let(:root) { create(:group) }
+ let(:child) { create(:group, parent: root) }
+ let(:project) { create(:project, group: child) }
+
+ it { is_expected.to eq(root) }
+ end
end
describe '#lfs_enabled?' do
@@ -3373,7 +3450,7 @@ describe Project do
context 'with a ref that is not the default branch' do
it 'returns the latest successful pipeline for the given ref' do
- expect(project.pipelines).to receive(:latest_successful_for).with('foo')
+ expect(project.ci_pipelines).to receive(:latest_successful_for).with('foo')
project.latest_successful_pipeline_for('foo')
end
@@ -3401,7 +3478,7 @@ describe Project do
it 'memoizes and returns the latest successful pipeline for the default branch' do
pipeline = double(:pipeline)
- expect(project.pipelines).to receive(:latest_successful_for)
+ expect(project.ci_pipelines).to receive(:latest_successful_for)
.with(project.default_branch)
.and_return(pipeline)
.once
@@ -3994,6 +4071,27 @@ describe Project do
end
end
+ describe '#all_clusters' do
+ let(:project) { create(:project) }
+ let(:cluster) { create(:cluster, cluster_type: :project_type, projects: [project]) }
+
+ subject { project.all_clusters }
+
+ it 'returns project level cluster' do
+ expect(subject).to eq([cluster])
+ end
+
+ context 'project belongs to a group' do
+ let(:group_cluster) { create(:cluster, :group) }
+ let(:group) { group_cluster.group }
+ let(:project) { create(:project, group: group) }
+
+ it 'returns clusters for groups of this project' do
+ expect(subject).to contain_exactly(cluster, group_cluster)
+ end
+ end
+ end
+
def rugged_config
rugged_repo(project.repository).config
end
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index cd43bec35df..a43304c9b83 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -16,8 +16,8 @@ describe API::CommitStatuses do
let(:get_url) { "/projects/#{project.id}/repository/commits/#{sha}/statuses" }
context 'ci commit exists' do
- let!(:master) { project.pipelines.create(source: :push, sha: commit.id, ref: 'master', protected: false) }
- let!(:develop) { project.pipelines.create(source: :push, sha: commit.id, ref: 'develop', protected: false) }
+ let!(:master) { project.ci_pipelines.create(source: :push, sha: commit.id, ref: 'master', protected: false) }
+ let!(:develop) { project.ci_pipelines.create(source: :push, sha: commit.id, ref: 'develop', protected: false) }
context "reporter user" do
let(:statuses_id) { json_response.map { |status| status['id'] } }
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 329d069ef3d..9e599c2175f 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -818,7 +818,7 @@ describe API::Commits do
end
context 'when the ref has a pipeline' do
- let!(:pipeline) { project.pipelines.create(source: :push, ref: 'master', sha: commit.sha, protected: false) }
+ let!(:pipeline) { project.ci_pipelines.create(source: :push, ref: 'master', sha: commit.sha, protected: false) }
it 'includes a "created" status' do
get api(route, current_user)
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 334dbb1c34c..620f9f5e1d6 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -121,6 +121,13 @@ describe API::Files do
end
end
+ context 'when PATs are used' do
+ it_behaves_like 'repository files' do
+ let(:token) { create(:personal_access_token, scopes: ['read_repository'], user: user) }
+ let(:current_user) { { personal_access_token: token } }
+ end
+ end
+
context 'when authenticated', 'as a developer' do
it_behaves_like 'repository files' do
let(:current_user) { user }
@@ -217,6 +224,13 @@ describe API::Files do
end
end
+ context 'when PATs are used' do
+ it_behaves_like 'repository files' do
+ let(:token) { create(:personal_access_token, scopes: ['read_repository'], user: user) }
+ let(:current_user) { { personal_access_token: token } }
+ end
+ end
+
context 'when unauthenticated', 'and project is private' do
it_behaves_like '404 response' do
let(:request) { get api(route(file_path)), params }
@@ -317,6 +331,21 @@ describe API::Files do
let(:request) { get api(route(file_path), guest), params }
end
end
+
+ context 'when PATs are used' do
+ it 'returns file by commit sha' do
+ token = create(:personal_access_token, scopes: ['read_repository'], user: user)
+
+ # This file is deleted on HEAD
+ file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
+ params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"
+ expect(Gitlab::Workhorse).to receive(:send_git_blob)
+
+ get api(route(file_path) + "/raw", personal_access_token: token), params
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
end
describe "POST /projects/:id/repository/files/:file_path" do
@@ -362,6 +391,24 @@ describe API::Files do
expect(response).to have_gitlab_http_status(400)
end
+ context 'with PATs' do
+ it 'returns 403 with `read_repository` scope' do
+ token = create(:personal_access_token, scopes: ['read_repository'], user: user)
+
+ post api(route(file_path), personal_access_token: token), params
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+
+ it 'returns 201 with `api` scope' do
+ token = create(:personal_access_token, scopes: ['api'], user: user)
+
+ post api(route(file_path), personal_access_token: token), params
+
+ expect(response).to have_gitlab_http_status(201)
+ end
+ end
+
context "when specifying an author" do
it "creates a new file with the specified author" do
params.merge!(author_email: author_email, author_name: author_name)
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 638cc9767d4..2e4fa0f9e16 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -304,7 +304,7 @@ describe API::Pipelines do
it 'creates and returns a new pipeline' do
expect do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
- end.to change { project.pipelines.count }.by(1)
+ end.to change { project.ci_pipelines.count }.by(1)
expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
@@ -317,8 +317,8 @@ describe API::Pipelines do
it 'creates and returns a new pipeline using the given variables' do
expect do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables
- end.to change { project.pipelines.count }.by(1)
- expect_variables(project.pipelines.last.variables, variables)
+ end.to change { project.ci_pipelines.count }.by(1)
+ expect_variables(project.ci_pipelines.last.variables, variables)
expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
@@ -338,8 +338,8 @@ describe API::Pipelines do
it 'creates and returns a new pipeline using the given variables' do
expect do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables
- end.to change { project.pipelines.count }.by(1)
- expect_variables(project.pipelines.last.variables, variables)
+ end.to change { project.ci_pipelines.count }.by(1)
+ expect_variables(project.ci_pipelines.last.variables, variables)
expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
@@ -353,7 +353,7 @@ describe API::Pipelines do
it "doesn't create a job" do
expect do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
- end.not_to change { project.pipelines.count }
+ end.not_to change { project.ci_pipelines.count }
expect(response).to have_gitlab_http_status(400)
end
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index 0ae6796d1e4..658df6945d2 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -39,7 +39,7 @@ describe API::Triggers do
end
context 'Have a commit' do
- let(:pipeline) { project.pipelines.last }
+ let(:pipeline) { project.ci_pipelines.last }
it 'creates pipeline' do
post api("/projects/#{project.id}/trigger/pipeline"), options.merge(ref: 'master')
diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb
index a4582d1bc64..ccc6b0ef1c7 100644
--- a/spec/services/ci/create_pipeline_service_spec.rb
+++ b/spec/services/ci/create_pipeline_service_spec.rb
@@ -18,7 +18,8 @@ describe Ci::CreatePipelineService do
message: 'Message',
ref: ref_name,
trigger_request: nil,
- variables_attributes: nil)
+ variables_attributes: nil,
+ merge_request: nil)
params = { ref: ref,
before: '00000000',
after: after,
@@ -26,7 +27,7 @@ describe Ci::CreatePipelineService do
variables_attributes: variables_attributes }
described_class.new(project, user, params).execute(
- source, trigger_request: trigger_request)
+ source, trigger_request: trigger_request, merge_request: merge_request)
end
context 'valid params' do
@@ -43,7 +44,7 @@ describe Ci::CreatePipelineService do
expect(pipeline).to be_valid
expect(pipeline).to be_persisted
expect(pipeline).to be_push
- expect(pipeline).to eq(project.pipelines.last)
+ expect(pipeline).to eq(project.ci_pipelines.last)
expect(pipeline).to have_attributes(user: user)
expect(pipeline).to have_attributes(status: 'pending')
expect(pipeline.repository_source?).to be true
@@ -60,10 +61,10 @@ describe Ci::CreatePipelineService do
context 'when merge requests already exist for this source branch' do
let(:merge_request_1) do
- create(:merge_request, source_branch: 'master', target_branch: "branch_1", source_project: project)
+ create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
end
let(:merge_request_2) do
- create(:merge_request, source_branch: 'master', target_branch: "branch_2", source_project: project)
+ create(:merge_request, source_branch: 'feature', target_branch: "v1.1.0", source_project: project)
end
context 'when related merge request is already merged' do
@@ -83,7 +84,7 @@ describe Ci::CreatePipelineService do
merge_request_1
merge_request_2
- head_pipeline = execute_service
+ head_pipeline = execute_service(ref: 'feature', after: nil)
expect(merge_request_1.reload.head_pipeline).to eq(head_pipeline)
expect(merge_request_2.reload.head_pipeline).to eq(head_pipeline)
@@ -123,12 +124,12 @@ describe Ci::CreatePipelineService do
let!(:target_project) { create(:project, :repository) }
it 'updates head pipeline for merge request' do
- merge_request = create(:merge_request, source_branch: 'master',
- target_branch: "branch_1",
+ merge_request = create(:merge_request, source_branch: 'feature',
+ target_branch: "master",
source_project: project,
target_project: target_project)
- head_pipeline = execute_service
+ head_pipeline = execute_service(ref: 'feature', after: nil)
expect(merge_request.reload.head_pipeline).to eq(head_pipeline)
end
@@ -656,6 +657,212 @@ describe Ci::CreatePipelineService do
end
end
end
+
+ describe 'Merge request pipelines' do
+ let(:pipeline) do
+ execute_service(source: source, merge_request: merge_request, ref: ref_name)
+ end
+
+ before do
+ stub_ci_pipeline_yaml_file(YAML.dump(config))
+ end
+
+ let(:ref_name) { 'feature' }
+
+ context 'when source is merge request' do
+ let(:source) { :merge_request }
+
+ context "when config has merge_requests keywords" do
+ let(:config) do
+ {
+ build: {
+ stage: 'build',
+ script: 'echo'
+ },
+ test: {
+ stage: 'test',
+ script: 'echo',
+ only: ['merge_requests']
+ },
+ pages: {
+ stage: 'deploy',
+ script: 'echo',
+ except: ['merge_requests']
+ }
+ }
+ end
+
+ context 'when merge request is specified' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: ref_name,
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'creates a merge request pipeline' do
+ expect(pipeline).to be_persisted
+ expect(pipeline).to be_merge_request
+ expect(pipeline.merge_request).to eq(merge_request)
+ expect(pipeline.builds.order(:stage_id).map(&:name)).to eq(%w[test])
+ end
+
+ context 'when ref is tag' do
+ let(:ref_name) { 'v1.1.0' }
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+ expect(pipeline.errors[:tag]).to eq(["is not included in the list"])
+ end
+ end
+
+ context 'when merge request is created from a forked project' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: ref_name,
+ target_project: target_project,
+ target_branch: 'master')
+ end
+
+ let!(:project) { fork_project(target_project, nil, repository: true) }
+ let!(:target_project) { create(:project, :repository) }
+
+ it 'creates a merge request pipeline in the forked project' do
+ expect(pipeline).to be_persisted
+ expect(project.ci_pipelines).to eq([pipeline])
+ expect(target_project.ci_pipelines).to be_empty
+ end
+ end
+
+ context "when there are no matched jobs" do
+ let(:config) do
+ {
+ test: {
+ stage: 'test',
+ script: 'echo',
+ except: ['merge_requests']
+ }
+ }
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+ expect(pipeline.errors[:base]).to eq(["No stages / jobs for this pipeline."])
+ end
+ end
+ end
+
+ context 'when merge request is not specified' do
+ let(:merge_request) { nil }
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+ expect(pipeline.errors[:merge_request]).to eq(["can't be blank"])
+ end
+ end
+ end
+
+ context "when config does not have merge_requests keywords" do
+ let(:config) do
+ {
+ build: {
+ stage: 'build',
+ script: 'echo'
+ },
+ test: {
+ stage: 'test',
+ script: 'echo'
+ },
+ pages: {
+ stage: 'deploy',
+ script: 'echo'
+ }
+ }
+ end
+
+ context 'when merge request is specified' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: ref_name,
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+
+ expect(pipeline.errors[:base])
+ .to eq(['No stages / jobs for this pipeline.'])
+ end
+ end
+
+ context 'when merge request is not specified' do
+ let(:merge_request) { nil }
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+
+ expect(pipeline.errors[:base])
+ .to eq(['No stages / jobs for this pipeline.'])
+ end
+ end
+ end
+ end
+
+ context 'when source is web' do
+ let(:source) { :web }
+
+ context "when config has merge_requests keywords" do
+ let(:config) do
+ {
+ build: {
+ stage: 'build',
+ script: 'echo'
+ },
+ test: {
+ stage: 'test',
+ script: 'echo',
+ only: ['merge_requests']
+ },
+ pages: {
+ stage: 'deploy',
+ script: 'echo',
+ except: ['merge_requests']
+ }
+ }
+ end
+
+ context 'when merge request is specified' do
+ let(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ source_branch: ref_name,
+ target_project: project,
+ target_branch: 'master')
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect(pipeline).not_to be_persisted
+ expect(pipeline.errors[:merge_request]).to eq(["must be blank"])
+ end
+ end
+
+ context 'when merge request is not specified' do
+ let(:merge_request) { nil }
+
+ it 'creates a branch pipeline' do
+ expect(pipeline).to be_persisted
+ expect(pipeline).to be_web
+ expect(pipeline.merge_request).to be_nil
+ expect(pipeline.builds.order(:stage_id).map(&:name)).to eq(%w[build pages])
+ end
+ end
+ end
+ end
+ end
end
describe '#execute!' do
diff --git a/spec/services/clusters/refresh_service_spec.rb b/spec/services/clusters/refresh_service_spec.rb
new file mode 100644
index 00000000000..58ab3c3cf73
--- /dev/null
+++ b/spec/services/clusters/refresh_service_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Clusters::RefreshService do
+ shared_examples 'creates a kubernetes namespace' do
+ let(:token) { 'aaaaaa' }
+ let(:service_account_creator) { double(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService, execute: true) }
+ let(:secrets_fetcher) { double(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService, execute: token) }
+
+ it 'creates a kubernetes namespace' do
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:namespace_creator).and_return(service_account_creator)
+ expect(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService).to receive(:new).and_return(secrets_fetcher)
+
+ expect { subject }.to change(project.kubernetes_namespaces, :count)
+
+ kubernetes_namespace = cluster.kubernetes_namespaces.first
+ expect(kubernetes_namespace).to be_present
+ expect(kubernetes_namespace.project).to eq(project)
+ end
+ end
+
+ shared_examples 'does not create a kubernetes namespace' do
+ it 'does not create a new kubernetes namespace' do
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).not_to receive(:namespace_creator)
+ expect(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService).not_to receive(:new)
+
+ expect { subject }.not_to change(Clusters::KubernetesNamespace, :count)
+ end
+ end
+
+ describe '.create_or_update_namespaces_for_cluster' do
+ let(:cluster) { create(:cluster, :provided_by_user, :project) }
+ let(:project) { cluster.project }
+
+ subject { described_class.create_or_update_namespaces_for_cluster(cluster) }
+
+ context 'cluster is project level' do
+ include_examples 'creates a kubernetes namespace'
+
+ context 'when project already has kubernetes namespace' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ include_examples 'does not create a kubernetes namespace'
+ end
+ end
+
+ context 'cluster is group level' do
+ let(:cluster) { create(:cluster, :provided_by_user, :group) }
+ let(:group) { cluster.group }
+ let(:project) { create(:project, group: group) }
+
+ include_examples 'creates a kubernetes namespace'
+
+ context 'when project already has kubernetes namespace' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ include_examples 'does not create a kubernetes namespace'
+ end
+ end
+ end
+
+ describe '.create_or_update_namespaces_for_project' do
+ let(:project) { create(:project) }
+
+ subject { described_class.create_or_update_namespaces_for_project(project) }
+
+ it 'creates no kubernetes namespaces' do
+ expect { subject }.not_to change(project.kubernetes_namespaces, :count)
+ end
+
+ context 'project has a project cluster' do
+ let!(:cluster) { create(:cluster, :provided_by_gcp, cluster_type: :project_type, projects: [project]) }
+
+ include_examples 'creates a kubernetes namespace'
+
+ context 'when project already has kubernetes namespace' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ include_examples 'does not create a kubernetes namespace'
+ end
+ end
+
+ context 'project belongs to a group cluster' do
+ let!(:cluster) { create(:cluster, :provided_by_gcp, :group) }
+
+ let(:group) { cluster.group }
+ let(:project) { create(:project, group: group) }
+
+ include_examples 'creates a kubernetes namespace'
+
+ context 'when project already has kubernetes namespace' do
+ before do
+ create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
+ end
+
+ include_examples 'does not create a kubernetes namespace'
+ end
+ end
+ end
+end
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index 74bcc15f912..5a3ecb1019b 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -159,6 +159,78 @@ describe MergeRequests::CreateService do
end
end
end
+
+ describe 'Merge request pipelines' do
+ before do
+ stub_ci_pipeline_yaml_file(YAML.dump(config))
+ end
+
+ context "when .gitlab-ci.yml has merge_requests keywords" do
+ let(:config) do
+ {
+ test: {
+ stage: 'test',
+ script: 'echo',
+ only: ['merge_requests']
+ }
+ }
+ end
+
+ it 'creates a merge request pipeline and sets it as a head pipeline' do
+ expect(merge_request).to be_persisted
+
+ merge_request.reload
+ expect(merge_request.merge_request_pipelines.count).to eq(1)
+ expect(merge_request.actual_head_pipeline).to be_merge_request
+ end
+
+ context "when branch pipeline was created before a merge request pipline has been created" do
+ before do
+ create(:ci_pipeline, project: merge_request.source_project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch,
+ tag: false)
+
+ merge_request
+ end
+
+ it 'sets the latest merge request pipeline as the head pipeline' do
+ expect(merge_request.actual_head_pipeline).to be_merge_request
+ end
+ end
+
+ context "when the 'ci_merge_request_pipeline' feature flag is disabled" do
+ before do
+ stub_feature_flags(ci_merge_request_pipeline: false)
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect(merge_request).to be_persisted
+
+ merge_request.reload
+ expect(merge_request.merge_request_pipelines.count).to eq(0)
+ end
+ end
+ end
+
+ context "when .gitlab-ci.yml does not have merge_requests keywords" do
+ let(:config) do
+ {
+ test: {
+ stage: 'test',
+ script: 'echo'
+ }
+ }
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect(merge_request).to be_persisted
+
+ merge_request.reload
+ expect(merge_request.merge_request_pipelines.count).to eq(0)
+ end
+ end
+ end
end
it_behaves_like 'new issuable record that supports quick actions' do
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index 61c6ba7d550..d29a1091d95 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -132,6 +132,94 @@ describe MergeRequests::RefreshService do
end
end
+ describe 'Merge request pipelines' do
+ before do
+ stub_ci_pipeline_yaml_file(YAML.dump(config))
+ end
+
+ subject { service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master') }
+
+ context "when .gitlab-ci.yml has merge_requests keywords" do
+ let(:config) do
+ {
+ test: {
+ stage: 'test',
+ script: 'echo',
+ only: ['merge_requests']
+ }
+ }
+ end
+
+ it 'create merge request pipeline' do
+ expect { subject }
+ .to change { @merge_request.merge_request_pipelines.count }.by(1)
+ .and change { @fork_merge_request.merge_request_pipelines.count }.by(1)
+ .and change { @another_merge_request.merge_request_pipelines.count }.by(1)
+ end
+
+ context "when branch pipeline was created before a merge request pipline has been created" do
+ before do
+ create(:ci_pipeline, project: @merge_request.source_project,
+ sha: @merge_request.diff_head_sha,
+ ref: @merge_request.source_branch,
+ tag: false)
+
+ subject
+ end
+
+ it 'sets the latest merge request pipeline as a head pipeline' do
+ @merge_request.reload
+ expect(@merge_request.actual_head_pipeline).to be_merge_request
+ end
+
+ it 'returns pipelines in correct order' do
+ @merge_request.reload
+ expect(@merge_request.all_pipelines.first).to be_merge_request
+ expect(@merge_request.all_pipelines.second).to be_push
+ end
+ end
+
+ context "when MergeRequestUpdateWorker is retried by an exception" do
+ it 'does not re-create a duplicate merge request pipeline' do
+ expect do
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
+ end.to change { @merge_request.merge_request_pipelines.count }.by(1)
+
+ expect do
+ service.new(@project, @user).execute(@oldrev, @newrev, 'refs/heads/master')
+ end.not_to change { @merge_request.merge_request_pipelines.count }
+ end
+ end
+
+ context "when the 'ci_merge_request_pipeline' feature flag is disabled" do
+ before do
+ stub_feature_flags(ci_merge_request_pipeline: false)
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect { subject }
+ .not_to change { @merge_request.merge_request_pipelines.count }
+ end
+ end
+ end
+
+ context "when .gitlab-ci.yml does not have merge_requests keywords" do
+ let(:config) do
+ {
+ test: {
+ stage: 'test',
+ script: 'echo'
+ }
+ }
+ end
+
+ it 'does not create a merge request pipeline' do
+ expect { subject }
+ .not_to change { @merge_request.merge_request_pipelines.count }
+ end
+ end
+ end
+
context 'push to origin repo source branch when an MR was reopened' do
let(:refresh_service) { service.new(@project, @user) }
let(:notification_service) { spy('notification_service') }
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 08de27ca44a..f71e2b4bc24 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -261,6 +261,32 @@ describe Projects::CreateService, '#execute' do
end
end
+ context 'when group has kubernetes cluster' do
+ let(:group_cluster) { create(:cluster, :group, :provided_by_gcp) }
+ let(:group) { group_cluster.group }
+
+ let(:token) { 'aaaa' }
+ let(:service_account_creator) { double(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService, execute: true) }
+ let(:secrets_fetcher) { double(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService, execute: token) }
+
+ before do
+ group.add_owner(user)
+
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:namespace_creator).and_return(service_account_creator)
+ expect(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService).to receive(:new).and_return(secrets_fetcher)
+ end
+
+ it 'creates kubernetes namespace for the project' do
+ project = create_project(user, opts.merge!(namespace_id: group.id))
+
+ expect(project).to be_valid
+
+ kubernetes_namespace = group_cluster.kubernetes_namespaces.first
+ expect(kubernetes_namespace).to be_present
+ expect(kubernetes_namespace.project).to eq(project)
+ end
+ end
+
context 'when there is an active service template' do
before do
create(:service, project: nil, template: true, active: true)
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 2e07d4f8013..132ad9a2646 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -62,6 +62,32 @@ describe Projects::TransferService do
expect(rugged_config['gitlab.fullpath']).to eq "#{group.full_path}/#{project.path}"
end
+
+ context 'new group has a kubernetes cluster' do
+ let(:group_cluster) { create(:cluster, :group, :provided_by_gcp) }
+ let(:group) { group_cluster.group }
+
+ let(:token) { 'aaaa' }
+ let(:service_account_creator) { double(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService, execute: true) }
+ let(:secrets_fetcher) { double(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService, execute: token) }
+
+ subject { transfer_project(project, user, group) }
+
+ before do
+ expect(Clusters::Gcp::Kubernetes::CreateOrUpdateServiceAccountService).to receive(:namespace_creator).and_return(service_account_creator)
+ expect(Clusters::Gcp::Kubernetes::FetchKubernetesTokenService).to receive(:new).and_return(secrets_fetcher)
+ end
+
+ it 'creates kubernetes namespace for the project' do
+ subject
+
+ expect(project.kubernetes_namespaces.count).to eq(1)
+
+ kubernetes_namespace = group_cluster.kubernetes_namespaces.first
+ expect(kubernetes_namespace).to be_present
+ expect(kubernetes_namespace.project).to eq(project)
+ end
+ end
end
context 'when transfer fails' do
diff --git a/spec/support/helpers/features/list_rows_helpers.rb b/spec/support/helpers/features/list_rows_helpers.rb
new file mode 100644
index 00000000000..0626415361c
--- /dev/null
+++ b/spec/support/helpers/features/list_rows_helpers.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+# These helpers allow you to access rows in the list
+#
+# Usage:
+# describe "..." do
+# include Spec::Support::Helpers::Features::ListRowsHelpers
+# ...
+#
+# expect(first_row.text).to include("John Doe")
+# expect(second_row.text).to include("John Smith")
+#
+module Spec
+ module Support
+ module Helpers
+ module Features
+ module ListRowsHelpers
+ def first_row
+ page.all('ul.content-list > li')[0]
+ end
+
+ def second_row
+ page.all('ul.content-list > li')[1]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/diff_file_collections.rb b/spec/support/shared_examples/diff_file_collections.rb
index 55ce160add0..367ddf06c28 100644
--- a/spec/support/shared_examples/diff_file_collections.rb
+++ b/spec/support/shared_examples/diff_file_collections.rb
@@ -45,3 +45,19 @@ shared_examples 'diff statistics' do |test_include_stats_flag: true|
end
end
end
+
+shared_examples 'unfoldable diff' do
+ let(:subject) { described_class.new(diffable, diff_options: nil) }
+
+ it 'calls Gitlab::Diff::File#unfold_diff_lines with correct position' do
+ position = instance_double(Gitlab::Diff::Position, file_path: 'README')
+ readme_file = instance_double(Gitlab::Diff::File, file_path: 'README')
+ other_file = instance_double(Gitlab::Diff::File, file_path: 'foo.rb')
+ nil_path_file = instance_double(Gitlab::Diff::File, file_path: nil)
+
+ allow(subject).to receive(:diff_files) { [readme_file, other_file, nil_path_file] }
+ expect(readme_file).to receive(:unfold_diff_lines).with(position)
+
+ subject.unfold_diff_files([position])
+ end
+end
diff --git a/spec/tasks/gitlab/check_rake_spec.rb b/spec/tasks/gitlab/check_rake_spec.rb
index 4eda618b6d6..06525e3c771 100644
--- a/spec/tasks/gitlab/check_rake_spec.rb
+++ b/spec/tasks/gitlab/check_rake_spec.rb
@@ -1,51 +1,101 @@
require 'rake_helper'
-describe 'gitlab:ldap:check rake task' do
- include LdapHelpers
-
+describe 'check.rake' do
before do
Rake.application.rake_require 'tasks/gitlab/check'
stub_warn_user_is_not_gitlab
end
- context 'when LDAP is not enabled' do
- it 'does not attempt to bind or search for users' do
- expect(Gitlab::Auth::LDAP::Config).not_to receive(:providers)
- expect(Gitlab::Auth::LDAP::Adapter).not_to receive(:open)
-
- run_rake_task('gitlab:ldap:check')
+ shared_examples_for 'system check rake task' do
+ it 'runs the check' do
+ expect do
+ subject
+ end.to output(/Checking #{name} ... Finished/).to_stdout
end
end
- context 'when LDAP is enabled' do
- let(:ldap) { double(:ldap) }
- let(:adapter) { ldap_adapter('ldapmain', ldap) }
+ describe 'gitlab:check rake task' do
+ subject { run_rake_task('gitlab:check') }
+ let(:name) { 'GitLab subtasks' }
- before do
- allow(Gitlab::Auth::LDAP::Config)
- .to receive_messages(
- enabled?: true,
- providers: ['ldapmain']
- )
- allow(Gitlab::Auth::LDAP::Adapter).to receive(:open).and_yield(adapter)
- allow(adapter).to receive(:users).and_return([])
- end
+ it_behaves_like 'system check rake task'
+ end
+
+ describe 'gitlab:gitlab_shell:check rake task' do
+ subject { run_rake_task('gitlab:gitlab_shell:check') }
+ let(:name) { 'GitLab Shell' }
+
+ it_behaves_like 'system check rake task'
+ end
+
+ describe 'gitlab:gitaly:check rake task' do
+ subject { run_rake_task('gitlab:gitaly:check') }
+ let(:name) { 'Gitaly' }
+
+ it_behaves_like 'system check rake task'
+ end
+
+ describe 'gitlab:sidekiq:check rake task' do
+ subject { run_rake_task('gitlab:sidekiq:check') }
+ let(:name) { 'Sidekiq' }
- it 'attempts to bind using credentials' do
- stub_ldap_config(has_auth?: true)
+ it_behaves_like 'system check rake task'
+ end
- expect(ldap).to receive(:bind)
+ describe 'gitlab:incoming_email:check rake task' do
+ subject { run_rake_task('gitlab:incoming_email:check') }
+ let(:name) { 'Incoming Email' }
- run_rake_task('gitlab:ldap:check')
+ it_behaves_like 'system check rake task'
+ end
+
+ describe 'gitlab:ldap:check rake task' do
+ include LdapHelpers
+
+ subject { run_rake_task('gitlab:ldap:check') }
+ let(:name) { 'LDAP' }
+
+ it_behaves_like 'system check rake task'
+
+ context 'when LDAP is not enabled' do
+ it 'does not attempt to bind or search for users' do
+ expect(Gitlab::Auth::LDAP::Config).not_to receive(:providers)
+ expect(Gitlab::Auth::LDAP::Adapter).not_to receive(:open)
+
+ subject
+ end
end
- it 'searches for 100 LDAP users' do
- stub_ldap_config(uid: 'uid')
+ context 'when LDAP is enabled' do
+ let(:ldap) { double(:ldap) }
+ let(:adapter) { ldap_adapter('ldapmain', ldap) }
+
+ before do
+ allow(Gitlab::Auth::LDAP::Config)
+ .to receive_messages(
+ enabled?: true,
+ providers: ['ldapmain']
+ )
+ allow(Gitlab::Auth::LDAP::Adapter).to receive(:open).and_yield(adapter)
+ allow(adapter).to receive(:users).and_return([])
+ end
+
+ it 'attempts to bind using credentials' do
+ stub_ldap_config(has_auth?: true)
+
+ expect(ldap).to receive(:bind)
+
+ subject
+ end
+
+ it 'searches for 100 LDAP users' do
+ stub_ldap_config(uid: 'uid')
- expect(adapter).to receive(:users).with('uid', '*', 100)
+ expect(adapter).to receive(:users).with('uid', '*', 100)
- run_rake_task('gitlab:ldap:check')
+ subject
+ end
end
end
end
diff --git a/spec/features/admin/admin_active_tab_spec.rb b/spec/views/layouts/nav/sidebar/_admin.html.haml_spec.rb
index 1215908f5ea..05c2f61a606 100644
--- a/spec/features/admin/admin_active_tab_spec.rb
+++ b/spec/views/layouts/nav/sidebar/_admin.html.haml_spec.rb
@@ -1,27 +1,26 @@
require 'spec_helper'
-RSpec.describe 'admin active tab' do
- before do
- sign_in(create(:admin))
- end
-
+describe 'layouts/nav/sidebar/_admin' do
shared_examples 'page has active tab' do |title|
it "activates #{title} tab" do
- expect(page).to have_selector('.nav-sidebar .sidebar-top-level-items > li.active', count: 1)
- expect(page.find('.nav-sidebar .sidebar-top-level-items > li.active')).to have_content(title)
+ render
+
+ expect(rendered).to have_selector('.nav-sidebar .sidebar-top-level-items > li.active', count: 1)
+ expect(rendered).to have_css('.nav-sidebar .sidebar-top-level-items > li.active', text: title)
end
end
shared_examples 'page has active sub tab' do |title|
it "activates #{title} sub tab" do
- expect(page).to have_selector('.sidebar-sub-level-items > li.active', count: 2)
- expect(page.all('.sidebar-sub-level-items > li.active')[1]).to have_content(title)
+ render
+
+ expect(rendered).to have_css('.sidebar-sub-level-items > li.active', text: title)
end
end
context 'on home page' do
before do
- visit admin_root_path
+ allow(controller).to receive(:controller_name).and_return('dashboard')
end
it_behaves_like 'page has active tab', 'Overview'
@@ -29,7 +28,8 @@ RSpec.describe 'admin active tab' do
context 'on projects' do
before do
- visit admin_projects_path
+ allow(controller).to receive(:controller_name).and_return('projects')
+ allow(controller).to receive(:controller_path).and_return('admin/projects')
end
it_behaves_like 'page has active tab', 'Overview'
@@ -38,7 +38,7 @@ RSpec.describe 'admin active tab' do
context 'on groups' do
before do
- visit admin_groups_path
+ allow(controller).to receive(:controller_name).and_return('groups')
end
it_behaves_like 'page has active tab', 'Overview'
@@ -47,7 +47,7 @@ RSpec.describe 'admin active tab' do
context 'on users' do
before do
- visit admin_users_path
+ allow(controller).to receive(:controller_name).and_return('users')
end
it_behaves_like 'page has active tab', 'Overview'
@@ -56,7 +56,7 @@ RSpec.describe 'admin active tab' do
context 'on logs' do
before do
- visit admin_logs_path
+ allow(controller).to receive(:controller_name).and_return('logs')
end
it_behaves_like 'page has active tab', 'Monitoring'
@@ -65,7 +65,7 @@ RSpec.describe 'admin active tab' do
context 'on messages' do
before do
- visit admin_broadcast_messages_path
+ allow(controller).to receive(:controller_name).and_return('broadcast_messages')
end
it_behaves_like 'page has active tab', 'Messages'
@@ -73,7 +73,7 @@ RSpec.describe 'admin active tab' do
context 'on hooks' do
before do
- visit admin_hooks_path
+ allow(controller).to receive(:controller_name).and_return('hooks')
end
it_behaves_like 'page has active tab', 'Hooks'
@@ -81,7 +81,7 @@ RSpec.describe 'admin active tab' do
context 'on background jobs' do
before do
- visit admin_background_jobs_path
+ allow(controller).to receive(:controller_name).and_return('background_jobs')
end
it_behaves_like 'page has active tab', 'Monitoring'
diff --git a/spec/workers/cluster_platform_configure_worker_spec.rb b/spec/workers/cluster_platform_configure_worker_spec.rb
index b51f6e07c6a..0eead0ab13d 100644
--- a/spec/workers/cluster_platform_configure_worker_spec.rb
+++ b/spec/workers/cluster_platform_configure_worker_spec.rb
@@ -2,7 +2,43 @@
require 'spec_helper'
-describe ClusterPlatformConfigureWorker, '#execute' do
+describe ClusterPlatformConfigureWorker, '#perform' do
+ let(:worker) { described_class.new }
+
+ context 'when group cluster' do
+ let(:cluster) { create(:cluster, :group, :provided_by_gcp) }
+ let(:group) { cluster.group }
+
+ context 'when group has no projects' do
+ it 'does not create a namespace' do
+ expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:execute)
+
+ worker.perform(cluster.id)
+ end
+ end
+
+ context 'when group has a project' do
+ let!(:project) { create(:project, group: group) }
+
+ it 'creates a namespace for the project' do
+ expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once
+
+ worker.perform(cluster.id)
+ end
+ end
+
+ context 'when group has project in a sub-group' do
+ let!(:subgroup) { create(:group, parent: group) }
+ let!(:project) { create(:project, group: subgroup) }
+
+ it 'creates a namespace for the project' do
+ expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once
+
+ worker.perform(cluster.id)
+ end
+ end
+ end
+
context 'when provider type is gcp' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
@@ -30,18 +66,4 @@ describe ClusterPlatformConfigureWorker, '#execute' do
described_class.new.perform(123)
end
end
-
- context 'when kubeclient raises error' do
- let(:cluster) { create(:cluster, :project) }
-
- it 'rescues and logs the error' do
- allow_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).and_raise(::Kubeclient::HttpError.new(500, 'something baaaad happened', ''))
-
- expect(Rails.logger)
- .to receive(:error)
- .with("Failed to create/update Kubernetes namespace for cluster_id: #{cluster.id} with error: something baaaad happened")
-
- described_class.new.perform(cluster.id)
- end
- end
end
diff --git a/spec/workers/pipeline_schedule_worker_spec.rb b/spec/workers/pipeline_schedule_worker_spec.rb
index bebcbe01009..ff408427926 100644
--- a/spec/workers/pipeline_schedule_worker_spec.rb
+++ b/spec/workers/pipeline_schedule_worker_spec.rb
@@ -25,12 +25,12 @@ describe PipelineScheduleWorker do
context 'when there is a scheduled pipeline within next_run_at' do
shared_examples 'successful scheduling' do
it 'creates a new pipeline' do
- expect { subject }.to change { project.pipelines.count }.by(1)
+ expect { subject }.to change { project.ci_pipelines.count }.by(1)
expect(Ci::Pipeline.last).to be_schedule
pipeline_schedule.reload
expect(pipeline_schedule.next_run_at).to be > Time.now
- expect(pipeline_schedule).to eq(project.pipelines.last.pipeline_schedule)
+ expect(pipeline_schedule).to eq(project.ci_pipelines.last.pipeline_schedule)
expect(pipeline_schedule).to be_active
end
end
@@ -54,7 +54,7 @@ describe PipelineScheduleWorker do
end
it 'does not creates a new pipeline' do
- expect { subject }.not_to change { project.pipelines.count }
+ expect { subject }.not_to change { project.ci_pipelines.count }
end
end
@@ -64,7 +64,7 @@ describe PipelineScheduleWorker do
end
it 'creates a failed pipeline with the reason' do
- expect { subject }.to change { project.pipelines.count }.by(1)
+ expect { subject }.to change { project.ci_pipelines.count }.by(1)
expect(Ci::Pipeline.last).to be_config_error
expect(Ci::Pipeline.last.yaml_errors).not_to be_nil
end
@@ -105,7 +105,7 @@ describe PipelineScheduleWorker do
end
it 'does not create a pipeline' do
- expect { subject }.not_to change { project.pipelines.count }
+ expect { subject }.not_to change { project.ci_pipelines.count }
end
it 'does not raise an exception' do
@@ -135,7 +135,7 @@ describe PipelineScheduleWorker do
end
it 'does not create a pipeline' do
- expect { subject }.not_to change { project.pipelines.count }
+ expect { subject }.not_to change { project.ci_pipelines.count }
end
it 'does not raise an exception' do
diff --git a/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb b/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
index 9adde5fc21a..a2bc264b0f6 100644
--- a/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
+++ b/spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
@@ -34,5 +34,33 @@ describe UpdateHeadPipelineForMergeRequestWorker do
expect { subject.perform(merge_request.id) }.not_to change { merge_request.reload.head_pipeline_id }
end
end
+
+ context 'when a merge request pipeline exists' do
+ let!(:merge_request_pipeline) do
+ create(:ci_pipeline,
+ project: project,
+ source: :merge_request,
+ sha: latest_sha,
+ merge_request: merge_request)
+ end
+
+ it 'sets the merge request pipeline as the head pipeline' do
+ expect { subject.perform(merge_request.id) }
+ .to change { merge_request.reload.head_pipeline_id }
+ .from(nil).to(merge_request_pipeline.id)
+ end
+
+ context 'when branch pipeline exists' do
+ let!(:branch_pipeline) do
+ create(:ci_pipeline, project: project, source: :push, sha: latest_sha)
+ end
+
+ it 'prioritizes the merge request pipeline as the head pipeline' do
+ expect { subject.perform(merge_request.id) }
+ .to change { merge_request.reload.head_pipeline_id }
+ .from(nil).to(merge_request_pipeline.id)
+ end
+ end
+ end
end
end
diff --git a/yarn.lock b/yarn.lock
index 0da5e26ebd5..d4906a6a212 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,7 +2,7 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0":
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
@@ -882,6 +882,11 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8"
integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==
+abab@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f"
+ integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==
+
abbrev@1, abbrev@1.0.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
@@ -902,6 +907,14 @@ acorn-dynamic-import@^3.0.0:
dependencies:
acorn "^5.0.0"
+acorn-globals@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103"
+ integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==
+ dependencies:
+ acorn "^6.0.1"
+ acorn-walk "^6.0.1"
+
acorn-jsx@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e"
@@ -909,11 +922,21 @@ acorn-jsx@^4.1.1:
dependencies:
acorn "^5.0.3"
-acorn@^5.0.0, acorn@^5.0.3, acorn@^5.6.0, acorn@^5.6.2, acorn@^5.7.3:
+acorn-walk@^6.0.1:
+ version "6.1.1"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913"
+ integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==
+
+acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.3, acorn@^5.6.0, acorn@^5.6.2, acorn@^5.7.3:
version "5.7.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
+acorn@^6.0.1:
+ version "6.0.4"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754"
+ integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==
+
after@0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
@@ -939,6 +962,16 @@ ajv@^6.0.1, ajv@^6.1.0, ajv@^6.5.3:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+ajv@^6.5.5:
+ version "6.5.5"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1"
+ integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==
+ dependencies:
+ fast-deep-equal "^2.0.1"
+ fast-json-stable-stringify "^2.0.0"
+ json-schema-traverse "^0.4.1"
+ uri-js "^4.2.2"
+
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
@@ -986,7 +1019,7 @@ ansi-styles@^2.2.1:
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-ansi-styles@^3.2.1:
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@@ -1098,6 +1131,13 @@ apollo-utilities@1.0.25, apollo-utilities@^1.0.0, apollo-utilities@^1.0.25, apol
dependencies:
fast-json-stable-stringify "^2.0.0"
+append-transform@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991"
+ integrity sha1-126/jKlNJ24keja61EpLdKthGZE=
+ dependencies:
+ default-require-extensions "^1.0.0"
+
append-transform@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab"
@@ -1125,12 +1165,19 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+arr-diff@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+ integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=
+ dependencies:
+ arr-flatten "^1.0.1"
+
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
-arr-flatten@^1.1.0:
+arr-flatten@^1.0.1, arr-flatten@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==
@@ -1140,6 +1187,11 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
+array-equal@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
+ integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
+
array-find@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8"
@@ -1201,6 +1253,18 @@ asn1.js@^4.0.0:
inherits "^2.0.1"
minimalistic-assert "^1.0.0"
+asn1@~0.2.3:
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
+ integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
+ dependencies:
+ safer-buffer "~2.1.0"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+ integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
+
assert@^1.1.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91"
@@ -1213,6 +1277,11 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
+astral-regex@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
+ integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
+
async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
@@ -1228,13 +1297,18 @@ async@1.x, async@^1.5.2:
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-async@^2.0.0, async@^2.5.0, async@^2.6.1:
+async@^2.0.0, async@^2.1.4, async@^2.5.0, async@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==
dependencies:
lodash "^4.17.10"
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
+
atob@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
@@ -1245,6 +1319,16 @@ autosize@^4.0.0:
resolved "https://registry.yarnpkg.com/autosize/-/autosize-4.0.0.tgz#7a0599b1ba84d73bd7589b0d9da3870152c69237"
integrity sha1-egWZsbqE1zvXWJsNnaOHAVLGkjc=
+aws-sign2@~0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
+ integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
+
+aws4@^1.8.0:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
+ integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
+
axios-mock-adapter@^1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.15.0.tgz#fbc06825d8302c95c3334d21023bba996255d45d"
@@ -1269,6 +1353,36 @@ babel-code-frame@^6.26.0:
esutils "^2.0.2"
js-tokens "^3.0.2"
+babel-core@^6.0.0, babel-core@^6.26.0:
+ version "6.26.3"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207"
+ integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==
+ dependencies:
+ babel-code-frame "^6.26.0"
+ babel-generator "^6.26.0"
+ babel-helpers "^6.24.1"
+ babel-messages "^6.23.0"
+ babel-register "^6.26.0"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ convert-source-map "^1.5.1"
+ debug "^2.6.9"
+ json5 "^0.5.1"
+ lodash "^4.17.4"
+ minimatch "^3.0.4"
+ path-is-absolute "^1.0.1"
+ private "^0.1.8"
+ slash "^1.0.0"
+ source-map "^0.5.7"
+
+babel-core@^7.0.0-bridge:
+ version "7.0.0-bridge.0"
+ resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece"
+ integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==
+
babel-eslint@^10.0.1:
version "10.0.1"
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed"
@@ -1281,6 +1395,36 @@ babel-eslint@^10.0.1:
eslint-scope "3.7.1"
eslint-visitor-keys "^1.0.0"
+babel-generator@^6.18.0, babel-generator@^6.26.0:
+ version "6.26.1"
+ resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90"
+ integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==
+ dependencies:
+ babel-messages "^6.23.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ detect-indent "^4.0.0"
+ jsesc "^1.3.0"
+ lodash "^4.17.4"
+ source-map "^0.5.7"
+ trim-right "^1.0.1"
+
+babel-helpers@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+ integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-jest@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1"
+ integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew==
+ dependencies:
+ babel-plugin-istanbul "^4.1.6"
+ babel-preset-jest "^23.2.0"
+
babel-loader@^8.0.4:
version "8.0.4"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.4.tgz#7bbf20cbe4560629e2e41534147692d3fecbdce6"
@@ -1298,6 +1442,23 @@ babel-messages@^6.23.0:
dependencies:
babel-runtime "^6.22.0"
+babel-plugin-dynamic-import-node@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.2.0.tgz#c0adfb07d95f4a4495e9aaac6ec386c4d7c2524e"
+ integrity sha512-fP899ELUnTaBcIzmrW7nniyqqdYWrWuJUyPWHxFa/c7r7hS6KC8FscNfLlBNIoPSc55kYMGEEKjPjJGCLbE1qA==
+ dependencies:
+ object.assign "^4.1.0"
+
+babel-plugin-istanbul@^4.1.6:
+ version "4.1.6"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45"
+ integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==
+ dependencies:
+ babel-plugin-syntax-object-rest-spread "^6.13.0"
+ find-up "^2.1.0"
+ istanbul-lib-instrument "^1.10.1"
+ test-exclude "^4.2.1"
+
babel-plugin-istanbul@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.0.tgz#6892f529eff65a3e2d33d87dc5888ffa2ecd4a30"
@@ -1307,11 +1468,39 @@ babel-plugin-istanbul@^5.1.0:
istanbul-lib-instrument "^3.0.0"
test-exclude "^5.0.0"
+babel-plugin-jest-hoist@^23.2.0:
+ version "23.2.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167"
+ integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc=
+
babel-plugin-rewire@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-rewire/-/babel-plugin-rewire-1.2.0.tgz#822562d72ed2c84e47c0f95ee232c920853e9d89"
integrity sha512-JBZxczHw3tScS+djy6JPLMjblchGhLI89ep15H3SyjujIzlxo5nr6Yjo7AXotdeVczeBmWs0tF8PgJWDdgzAkQ==
+babel-plugin-syntax-object-rest-spread@^6.13.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
+ integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=
+
+babel-plugin-transform-es2015-modules-commonjs@^6.26.2:
+ version "6.26.2"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3"
+ integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==
+ dependencies:
+ babel-plugin-transform-strict-mode "^6.24.1"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-types "^6.26.0"
+
+babel-plugin-transform-strict-mode@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
+ integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
babel-polyfill@6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
@@ -1321,6 +1510,27 @@ babel-polyfill@6.23.0:
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
+babel-preset-jest@^23.2.0:
+ version "23.2.0"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46"
+ integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY=
+ dependencies:
+ babel-plugin-jest-hoist "^23.2.0"
+ babel-plugin-syntax-object-rest-spread "^6.13.0"
+
+babel-register@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
+ integrity sha1-btAhFz4vy0htestFxgCahW9kcHE=
+ dependencies:
+ babel-core "^6.26.0"
+ babel-runtime "^6.26.0"
+ core-js "^2.5.0"
+ home-or-tmp "^2.0.0"
+ lodash "^4.17.4"
+ mkdirp "^0.5.1"
+ source-map-support "^0.4.15"
+
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
@@ -1334,7 +1544,7 @@ babel-standalone@^6.26.0:
resolved "https://registry.yarnpkg.com/babel-standalone/-/babel-standalone-6.26.0.tgz#15fb3d35f2c456695815ebf1ed96fe7f015b6886"
integrity sha1-Ffs9NfLEVmlYFevx7Zb+fwFbaIY=
-babel-template@^6.26.0:
+babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=
@@ -1345,7 +1555,7 @@ babel-template@^6.26.0:
babylon "^6.18.0"
lodash "^4.17.4"
-babel-traverse@^6.26.0:
+babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=
@@ -1360,7 +1570,7 @@ babel-traverse@^6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"
-babel-types@^6.26.0:
+babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.24.1, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
@@ -1418,6 +1628,13 @@ batch@0.6.1:
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
+bcrypt-pbkdf@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
+ integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
+ dependencies:
+ tweetnacl "^0.14.3"
+
better-assert@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/better-assert/-/better-assert-1.0.2.tgz#40866b9e1b9e0b55b481894311e68faffaebc522"
@@ -1538,6 +1755,15 @@ braces@^0.1.2:
dependencies:
expand-range "^0.1.0"
+braces@^1.8.2:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+ integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=
+ dependencies:
+ expand-range "^1.8.1"
+ preserve "^0.2.0"
+ repeat-element "^1.1.2"
+
braces@^2.3.0, braces@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb"
@@ -1561,6 +1787,18 @@ brorand@^1.0.1:
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+browser-process-hrtime@^0.1.2:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4"
+ integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==
+
+browser-resolve@^1.11.3:
+ version "1.11.3"
+ resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6"
+ integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==
+ dependencies:
+ resolve "1.1.7"
+
browserify-aes@^1.0.0, browserify-aes@^1.0.4:
version "1.1.1"
resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.1.1.tgz#38b7ab55edb806ff2dcda1a7f1620773a477c49f"
@@ -1628,6 +1866,13 @@ browserslist@^4.1.0:
electron-to-chromium "^1.3.62"
node-releases "^1.0.0-alpha.11"
+bser@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
+ integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=
+ dependencies:
+ node-int64 "^0.4.0"
+
buffer-from@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531"
@@ -1761,6 +2006,11 @@ callsites@^0.2.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
+callsites@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
+ integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
+
camelcase@^4.0.0, camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
@@ -1771,11 +2021,23 @@ caniuse-lite@^1.0.30000884:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000888.tgz#22edb50d91dd70612b5898e3b36f460600c6492f"
integrity sha512-vftg+5p/lPsQGpnhSo/yBuYL36ai/cyjLvU3dOPJY1kkKrekLWIy8SLm+wzjX0hpCUdFTasC4/ZT7uqw4rKOnQ==
+capture-exit@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f"
+ integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=
+ dependencies:
+ rsvp "^3.3.3"
+
capture-stack-trace@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d"
integrity sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=
+caseless@~0.12.0:
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+ integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -1853,6 +2115,11 @@ chrome-trace-event@^1.0.0:
dependencies:
tslib "^1.9.0"
+ci-info@^1.5.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
+ integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
+
cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -1928,6 +2195,11 @@ clone-response@1.0.2:
dependencies:
mimic-response "^1.0.0"
+co@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+ integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
+
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
@@ -1984,6 +2256,13 @@ combine-lists@^1.0.0:
dependencies:
lodash "^4.5.0"
+combined-stream@^1.0.6, combined-stream@~1.0.6:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
+ integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
+ dependencies:
+ delayed-stream "~1.0.0"
+
commander@2, commander@^2.18.0, commander@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
@@ -2145,7 +2424,7 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
-convert-source-map@^1.1.0:
+convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
@@ -2186,7 +2465,7 @@ copy-to-clipboard@^3.0.8:
dependencies:
toggle-selection "^1.0.3"
-core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1:
+core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0:
version "2.5.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==
@@ -2196,7 +2475,7 @@ core-js@~2.3.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
integrity sha1-+rg/uwstjchfpjbEudNMdUIMbWU=
-core-util-is@~1.0.0:
+core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
@@ -2329,6 +2608,18 @@ cssesc@^0.1.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4"
integrity sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=
+cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0":
+ version "0.3.4"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797"
+ integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==
+
+cssstyle@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb"
+ integrity sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog==
+ dependencies:
+ cssom "0.3.x"
+
custom-event@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425"
@@ -2596,6 +2887,22 @@ dagre-layout@^0.8.8:
graphlibrary "^2.2.0"
lodash "^4.17.5"
+dashdash@^1.12.0:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+ integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
+ dependencies:
+ assert-plus "^1.0.0"
+
+data-urls@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
+ integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==
+ dependencies:
+ abab "^2.0.0"
+ whatwg-mimetype "^2.2.0"
+ whatwg-url "^7.0.0"
+
date-format@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-1.2.0.tgz#615e828e233dd1ab9bb9ae0950e0ceccfa6ecad8"
@@ -2637,6 +2944,11 @@ debug@~3.1.0:
dependencies:
ms "2.0.0"
+decamelize@^1.1.1:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
+ integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+
decamelize@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-2.0.0.tgz#656d7bbc8094c4c788ea53c5840908c9c7d063c7"
@@ -2684,6 +2996,13 @@ default-gateway@^2.6.0:
execa "^0.10.0"
ip-regex "^2.1.0"
+default-require-extensions@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8"
+ integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=
+ dependencies:
+ strip-bom "^2.0.0"
+
default-require-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7"
@@ -2745,6 +3064,11 @@ del@^3.0.0:
pify "^3.0.0"
rimraf "^2.2.8"
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
+
delegate@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.1.2.tgz#1e1bc6f5cadda6cb6cbf7e6d05d0bcdd5712aebe"
@@ -2778,11 +3102,23 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
+detect-indent@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
+ integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg=
+ dependencies:
+ repeating "^2.0.0"
+
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
+detect-newline@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2"
+ integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=
+
detect-node@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.3.tgz#a2033c09cc8e158d37748fbde7507832bd6ce127"
@@ -2880,6 +3216,13 @@ domelementtype@~1.1.1:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b"
integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=
+domexception@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90"
+ integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==
+ dependencies:
+ webidl-conversions "^4.0.2"
+
domhandler@^2.3.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.1.tgz#892e47000a99be55bbf3774ffea0561d8879c259"
@@ -2927,6 +3270,14 @@ duplexify@^3.4.2, duplexify@^3.5.3:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
+ecc-jsbn@~0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
+ integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
+ dependencies:
+ jsbn "~0.1.0"
+ safer-buffer "^2.1.0"
+
editions@^1.3.3:
version "1.3.4"
resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b"
@@ -3135,6 +3486,18 @@ escodegen@1.8.x:
optionalDependencies:
source-map "~0.2.0"
+escodegen@^1.9.1:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589"
+ integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==
+ dependencies:
+ esprima "^3.1.3"
+ estraverse "^4.2.0"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.6.1"
+
eslint-config-airbnb-base@^13.1.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c"
@@ -3151,6 +3514,15 @@ eslint-config-prettier@^3.1.0:
dependencies:
get-stdin "^6.0.0"
+eslint-import-resolver-jest@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-jest/-/eslint-import-resolver-jest-2.1.1.tgz#78c1934e3b5b77283326f036e089cc3b9fae6346"
+ integrity sha512-yzzZFN37CaMaCjmUZ4Zo7Pw5qCG/hDklVzxIeHYJZkbcdg0sL5MeLaOG8s3ndVBvv1PSdSq4jfkY0QXt/KPbTg==
+ dependencies:
+ find-root "^1.0.0"
+ micromatch "^3.1.6"
+ resolve "^1.5.0"
+
eslint-import-resolver-node@^0.3.1:
version "0.3.2"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a"
@@ -3221,6 +3593,11 @@ eslint-plugin-jasmine@^2.10.1:
resolved "https://registry.yarnpkg.com/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.10.1.tgz#5733b709e751f4bc40e31e1c16989bd2cdfbec97"
integrity sha1-VzO3CedR9LxA4x4cFpib0s377Jc=
+eslint-plugin-jest@^22.1.0:
+ version "22.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.0.tgz#9a4dfa3367563e8301560a7fb92ec309096dbca3"
+ integrity sha512-WcQd5LxEoAS20zuWEAd8CX0pVC+gGInZPcsoYvK5w7BrEJNmltyTxYYh1r0ct4GsahD2GvNySlcTcLtK2amFZA==
+
eslint-plugin-promise@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2"
@@ -3321,6 +3698,11 @@ esprima@2.7.x, esprima@^2.7.1:
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=
+esprima@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+ integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
+
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@@ -3345,7 +3727,7 @@ estraverse@^1.9.1:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
+estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
@@ -3403,6 +3785,13 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
+exec-sh@^0.2.0:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36"
+ integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==
+ dependencies:
+ merge "^1.2.0"
+
execa@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
@@ -3429,6 +3818,11 @@ execa@^0.7.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
+exit@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+ integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=
+
expand-braces@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
@@ -3438,6 +3832,13 @@ expand-braces@^0.1.1:
array-unique "^0.2.1"
braces "^0.1.2"
+expand-brackets@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+ integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=
+ dependencies:
+ is-posix-bracket "^0.1.0"
+
expand-brackets@^2.1.4:
version "2.1.4"
resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
@@ -3459,6 +3860,25 @@ expand-range@^0.1.0:
is-number "^0.1.1"
repeat-string "^0.2.2"
+expand-range@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+ integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=
+ dependencies:
+ fill-range "^2.1.0"
+
+expect@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98"
+ integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w==
+ dependencies:
+ ansi-styles "^3.2.0"
+ jest-diff "^23.6.0"
+ jest-get-type "^22.1.0"
+ jest-matcher-utils "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-regex-util "^23.3.0"
+
exports-loader@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.7.0.tgz#84881c784dea6036b8e1cd1dac3da9b6409e21a5"
@@ -3518,7 +3938,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
-extend@^3.0.0:
+extend@^3.0.0, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -3541,6 +3961,13 @@ external-editor@^3.0.0:
iconv-lite "^0.4.22"
tmp "^0.0.33"
+extglob@^0.3.1:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+ integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=
+ dependencies:
+ is-extglob "^1.0.0"
+
extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
@@ -3555,6 +3982,16 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
+extsprintf@1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
+ integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
+
+extsprintf@^1.2.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
+ integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
+
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
@@ -3589,6 +4026,13 @@ faye-websocket@~0.11.1:
dependencies:
websocket-driver ">=0.5.1"
+fb-watchman@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58"
+ integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=
+ dependencies:
+ bser "^2.0.0"
+
figgy-pudding@^3.1.0, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -3617,7 +4061,12 @@ file-loader@^2.0.0:
loader-utils "^1.0.2"
schema-utils "^1.0.0"
-fileset@^2.0.3:
+filename-regex@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
+ integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=
+
+fileset@^2.0.2, fileset@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0"
integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=
@@ -3630,6 +4079,17 @@ filesize@^3.6.1:
resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
integrity sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==
+fill-range@^2.1.0:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565"
+ integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==
+ dependencies:
+ is-number "^2.1.0"
+ isobject "^2.0.0"
+ randomatic "^3.0.0"
+ repeat-element "^1.1.2"
+ repeat-string "^1.5.2"
+
fill-range@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
@@ -3684,7 +4144,7 @@ find-cache-dir@^2.0.0:
make-dir "^1.0.0"
pkg-dir "^3.0.0"
-find-root@^1.1.0:
+find-root@^1.0.0, find-root@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
@@ -3736,11 +4196,32 @@ follow-redirects@^1.2.5:
dependencies:
debug "^3.1.0"
-for-in@^1.0.2:
+for-in@^1.0.1, for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
+for-own@^0.1.4:
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
+ integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=
+ dependencies:
+ for-in "^1.0.1"
+
+forever-agent@~0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+ integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
+
+form-data@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
+ integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.6"
+ mime-types "^2.1.12"
+
formdata-polyfill@^3.0.11:
version "3.0.11"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-3.0.11.tgz#c82b4b4bea3356c0a6752219e54ce1edb2a7fb5b"
@@ -3805,7 +4286,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-fsevents@^1.2.2:
+fsevents@^1.2.2, fsevents@^1.2.3:
version "1.2.4"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426"
integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==
@@ -3862,6 +4343,13 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
+getpass@^0.1.1:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+ integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
+ dependencies:
+ assert-plus "^1.0.0"
+
gettext-extractor-vue@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/gettext-extractor-vue/-/gettext-extractor-vue-4.0.1.tgz#69d2737eb8f1938803ffcf9317133ed59fb2372f"
@@ -3884,6 +4372,21 @@ gettext-extractor@^3.3.2:
pofile "^1"
typescript "^2"
+glob-base@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+ integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=
+ dependencies:
+ glob-parent "^2.0.0"
+ is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+ integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=
+ dependencies:
+ is-glob "^2.0.0"
+
glob-parent@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae"
@@ -4038,6 +4541,11 @@ graphql@^14.0.2:
dependencies:
iterall "^1.2.2"
+growly@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
+ integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=
+
gzip-size@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.0.0.tgz#a55ecd99222f4c48fd8c01c625ce3b349d0a0e80"
@@ -4051,7 +4559,7 @@ handle-thing@^1.2.5:
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=
-handlebars@^4.0.1, handlebars@^4.0.11:
+handlebars@^4.0.1, handlebars@^4.0.11, handlebars@^4.0.3:
version "4.0.12"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5"
integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==
@@ -4062,6 +4570,19 @@ handlebars@^4.0.1, handlebars@^4.0.11:
optionalDependencies:
uglify-js "^3.1.4"
+har-schema@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
+ integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
+
+har-validator@~5.1.0:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
+ integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
+ dependencies:
+ ajv "^6.5.5"
+ har-schema "^2.0.0"
+
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
@@ -4198,6 +4719,14 @@ hmac-drbg@^1.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
+home-or-tmp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
+ integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg=
+ dependencies:
+ os-homedir "^1.0.0"
+ os-tmpdir "^1.0.1"
+
hoopy@^0.1.2:
version "0.1.4"
resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d"
@@ -4218,6 +4747,13 @@ hpack.js@^2.1.6:
readable-stream "^2.0.1"
wbuf "^1.1.0"
+html-encoding-sniffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8"
+ integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==
+ dependencies:
+ whatwg-encoding "^1.0.1"
+
html-entities@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.0.tgz#41948caf85ce82fed36e4e6a0ed371a6664379e2"
@@ -4273,6 +4809,15 @@ http-proxy@^1.13.0, http-proxy@^1.16.2:
eventemitter3 "1.x.x"
requires-port "1.x.x"
+http-signature@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
+ integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
+ dependencies:
+ assert-plus "^1.0.0"
+ jsprim "^1.2.2"
+ sshpk "^1.7.0"
+
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -4290,6 +4835,13 @@ iconv-lite@0.4.19:
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==
+iconv-lite@0.4.24:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
+ integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
icss-replace-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded"
@@ -4465,13 +5017,18 @@ into-stream@^3.1.0:
from2 "^2.1.1"
p-is-promise "^1.1.0"
-invariant@^2.2.2:
+invariant@^2.2.2, invariant@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
dependencies:
loose-envify "^1.0.0"
+invert-kv@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
+ integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
+
invert-kv@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
@@ -4535,6 +5092,13 @@ is-callable@^1.1.1, is-callable@^1.1.3:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
+is-ci@^1.0.10:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
+ integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==
+ dependencies:
+ ci-info "^1.5.0"
+
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -4572,6 +5136,18 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
is-data-descriptor "^1.0.0"
kind-of "^6.0.2"
+is-dotfile@^1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
+ integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=
+
+is-equal-shallow@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+ integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=
+ dependencies:
+ is-primitive "^2.0.0"
+
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -4584,11 +5160,23 @@ is-extendable@^1.0.1:
dependencies:
is-plain-object "^2.0.4"
+is-extglob@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+ integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=
+
is-extglob@^2.1.0, is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+is-finite@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+ integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=
+ dependencies:
+ number-is-nan "^1.0.0"
+
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -4601,6 +5189,18 @@ is-fullwidth-code-point@^2.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+is-generator-fn@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a"
+ integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+ integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=
+ dependencies:
+ is-extglob "^1.0.0"
+
is-glob@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
@@ -4633,6 +5233,13 @@ is-number@^0.1.1:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-0.1.1.tgz#69a7af116963d47206ec9bd9b48a14216f1e3806"
integrity sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=
+is-number@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=
+ dependencies:
+ kind-of "^3.0.2"
+
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -4693,6 +5300,16 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-posix-bracket@^0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+ integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=
+
+is-primitive@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+ integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
+
is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
@@ -4737,6 +5354,16 @@ is-symbol@^1.0.1:
dependencies:
has-symbols "^1.0.0"
+is-typedarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+ integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+
+is-utf8@^0.2.0:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
+ integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
+
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -4779,6 +5406,28 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
+isstream@~0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+ integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+
+istanbul-api@^1.3.1:
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa"
+ integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==
+ dependencies:
+ async "^2.1.4"
+ fileset "^2.0.2"
+ istanbul-lib-coverage "^1.2.1"
+ istanbul-lib-hook "^1.2.2"
+ istanbul-lib-instrument "^1.10.2"
+ istanbul-lib-report "^1.1.5"
+ istanbul-lib-source-maps "^1.2.6"
+ istanbul-reports "^1.5.1"
+ js-yaml "^3.7.0"
+ mkdirp "^0.5.1"
+ once "^1.4.0"
+
istanbul-api@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-2.0.6.tgz#cd7b33ee678f6c01531d05f5e567ebbcd25f8ecc"
@@ -4797,11 +5446,23 @@ istanbul-api@^2.0.5:
make-dir "^1.3.0"
once "^1.4.0"
+istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0"
+ integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==
+
istanbul-lib-coverage@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#2aee0e073ad8c5f6a0b00e0dfbf52b4667472eda"
integrity sha512-nPvSZsVlbG9aLhZYaC3Oi1gT/tpyo3Yt5fNyf6NmcKIayz4VV/txxJFFKAK/gU4dcNn8ehsanBbVHVl0+amOLA==
+istanbul-lib-hook@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86"
+ integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==
+ dependencies:
+ append-transform "^0.4.0"
+
istanbul-lib-hook@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.1.tgz#918a57b75a0f951d552a08487ca1fa5336433d72"
@@ -4809,6 +5470,19 @@ istanbul-lib-hook@^2.0.1:
dependencies:
append-transform "^1.0.0"
+istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2:
+ version "1.10.2"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca"
+ integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==
+ dependencies:
+ babel-generator "^6.18.0"
+ babel-template "^6.16.0"
+ babel-traverse "^6.18.0"
+ babel-types "^6.18.0"
+ babylon "^6.18.0"
+ istanbul-lib-coverage "^1.2.1"
+ semver "^5.3.0"
+
istanbul-lib-instrument@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.0.0.tgz#b5f066b2a161f75788be17a9d556f40a0cf2afc9"
@@ -4822,6 +5496,16 @@ istanbul-lib-instrument@^3.0.0:
istanbul-lib-coverage "^2.0.1"
semver "^5.5.0"
+istanbul-lib-report@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c"
+ integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==
+ dependencies:
+ istanbul-lib-coverage "^1.2.1"
+ mkdirp "^0.5.1"
+ path-parse "^1.0.5"
+ supports-color "^3.1.2"
+
istanbul-lib-report@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.2.tgz#430a2598519113e1da7af274ba861bd42dd97535"
@@ -4831,6 +5515,17 @@ istanbul-lib-report@^2.0.2:
make-dir "^1.3.0"
supports-color "^5.4.0"
+istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f"
+ integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==
+ dependencies:
+ debug "^3.1.0"
+ istanbul-lib-coverage "^1.2.1"
+ mkdirp "^0.5.1"
+ rimraf "^2.6.1"
+ source-map "^0.5.3"
+
istanbul-lib-source-maps@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-2.0.1.tgz#ce8b45131d8293fdeaa732f4faf1852d13d0a97e"
@@ -4842,6 +5537,13 @@ istanbul-lib-source-maps@^2.0.1:
rimraf "^2.6.2"
source-map "^0.6.1"
+istanbul-reports@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a"
+ integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==
+ dependencies:
+ handlebars "^4.0.3"
+
istanbul-reports@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.0.1.tgz#fb8d6ea850701a3984350b977a969e9a556116a7"
@@ -4913,6 +5615,334 @@ jed@^1.1.1:
resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"
integrity sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=
+jest-changed-files@^23.4.2:
+ version "23.4.2"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83"
+ integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA==
+ dependencies:
+ throat "^4.0.0"
+
+jest-cli@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4"
+ integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ==
+ dependencies:
+ ansi-escapes "^3.0.0"
+ chalk "^2.0.1"
+ exit "^0.1.2"
+ glob "^7.1.2"
+ graceful-fs "^4.1.11"
+ import-local "^1.0.0"
+ is-ci "^1.0.10"
+ istanbul-api "^1.3.1"
+ istanbul-lib-coverage "^1.2.0"
+ istanbul-lib-instrument "^1.10.1"
+ istanbul-lib-source-maps "^1.2.4"
+ jest-changed-files "^23.4.2"
+ jest-config "^23.6.0"
+ jest-environment-jsdom "^23.4.0"
+ jest-get-type "^22.1.0"
+ jest-haste-map "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-regex-util "^23.3.0"
+ jest-resolve-dependencies "^23.6.0"
+ jest-runner "^23.6.0"
+ jest-runtime "^23.6.0"
+ jest-snapshot "^23.6.0"
+ jest-util "^23.4.0"
+ jest-validate "^23.6.0"
+ jest-watcher "^23.4.0"
+ jest-worker "^23.2.0"
+ micromatch "^2.3.11"
+ node-notifier "^5.2.1"
+ prompts "^0.1.9"
+ realpath-native "^1.0.0"
+ rimraf "^2.5.4"
+ slash "^1.0.0"
+ string-length "^2.0.0"
+ strip-ansi "^4.0.0"
+ which "^1.2.12"
+ yargs "^11.0.0"
+
+jest-config@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d"
+ integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ==
+ dependencies:
+ babel-core "^6.0.0"
+ babel-jest "^23.6.0"
+ chalk "^2.0.1"
+ glob "^7.1.1"
+ jest-environment-jsdom "^23.4.0"
+ jest-environment-node "^23.4.0"
+ jest-get-type "^22.1.0"
+ jest-jasmine2 "^23.6.0"
+ jest-regex-util "^23.3.0"
+ jest-resolve "^23.6.0"
+ jest-util "^23.4.0"
+ jest-validate "^23.6.0"
+ micromatch "^2.3.11"
+ pretty-format "^23.6.0"
+
+jest-diff@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d"
+ integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g==
+ dependencies:
+ chalk "^2.0.1"
+ diff "^3.2.0"
+ jest-get-type "^22.1.0"
+ pretty-format "^23.6.0"
+
+jest-docblock@^23.2.0:
+ version "23.2.0"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7"
+ integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c=
+ dependencies:
+ detect-newline "^2.1.0"
+
+jest-each@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575"
+ integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg==
+ dependencies:
+ chalk "^2.0.1"
+ pretty-format "^23.6.0"
+
+jest-environment-jsdom@^23.4.0:
+ version "23.4.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023"
+ integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM=
+ dependencies:
+ jest-mock "^23.2.0"
+ jest-util "^23.4.0"
+ jsdom "^11.5.1"
+
+jest-environment-node@^23.4.0:
+ version "23.4.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10"
+ integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA=
+ dependencies:
+ jest-mock "^23.2.0"
+ jest-util "^23.4.0"
+
+jest-get-type@^22.1.0:
+ version "22.4.3"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4"
+ integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==
+
+jest-haste-map@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16"
+ integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg==
+ dependencies:
+ fb-watchman "^2.0.0"
+ graceful-fs "^4.1.11"
+ invariant "^2.2.4"
+ jest-docblock "^23.2.0"
+ jest-serializer "^23.0.1"
+ jest-worker "^23.2.0"
+ micromatch "^2.3.11"
+ sane "^2.0.0"
+
+jest-jasmine2@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0"
+ integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ==
+ dependencies:
+ babel-traverse "^6.0.0"
+ chalk "^2.0.1"
+ co "^4.6.0"
+ expect "^23.6.0"
+ is-generator-fn "^1.0.0"
+ jest-diff "^23.6.0"
+ jest-each "^23.6.0"
+ jest-matcher-utils "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-snapshot "^23.6.0"
+ jest-util "^23.4.0"
+ pretty-format "^23.6.0"
+
+jest-junit@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-5.2.0.tgz#980401db7aa69999cf117c6d740a8135c22ae379"
+ integrity sha512-Mdg0Qpdh1Xm/FA1B/mcLlmEmlr3XzH5pZg7MvcAwZhjHijPRd1z/UwYwkwNHmCV7o4ZOWCf77nLu7ZkhHHrtJg==
+ dependencies:
+ jest-config "^23.6.0"
+ jest-validate "^23.0.1"
+ mkdirp "^0.5.1"
+ strip-ansi "^4.0.0"
+ xml "^1.0.1"
+
+jest-leak-detector@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de"
+ integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg==
+ dependencies:
+ pretty-format "^23.6.0"
+
+jest-matcher-utils@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80"
+ integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog==
+ dependencies:
+ chalk "^2.0.1"
+ jest-get-type "^22.1.0"
+ pretty-format "^23.6.0"
+
+jest-message-util@^23.4.0:
+ version "23.4.0"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f"
+ integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8=
+ dependencies:
+ "@babel/code-frame" "^7.0.0-beta.35"
+ chalk "^2.0.1"
+ micromatch "^2.3.11"
+ slash "^1.0.0"
+ stack-utils "^1.0.1"
+
+jest-mock@^23.2.0:
+ version "23.2.0"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134"
+ integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ=
+
+jest-regex-util@^23.3.0:
+ version "23.3.0"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5"
+ integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U=
+
+jest-resolve-dependencies@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d"
+ integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA==
+ dependencies:
+ jest-regex-util "^23.3.0"
+ jest-snapshot "^23.6.0"
+
+jest-resolve@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae"
+ integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA==
+ dependencies:
+ browser-resolve "^1.11.3"
+ chalk "^2.0.1"
+ realpath-native "^1.0.0"
+
+jest-runner@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38"
+ integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA==
+ dependencies:
+ exit "^0.1.2"
+ graceful-fs "^4.1.11"
+ jest-config "^23.6.0"
+ jest-docblock "^23.2.0"
+ jest-haste-map "^23.6.0"
+ jest-jasmine2 "^23.6.0"
+ jest-leak-detector "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-runtime "^23.6.0"
+ jest-util "^23.4.0"
+ jest-worker "^23.2.0"
+ source-map-support "^0.5.6"
+ throat "^4.0.0"
+
+jest-runtime@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082"
+ integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw==
+ dependencies:
+ babel-core "^6.0.0"
+ babel-plugin-istanbul "^4.1.6"
+ chalk "^2.0.1"
+ convert-source-map "^1.4.0"
+ exit "^0.1.2"
+ fast-json-stable-stringify "^2.0.0"
+ graceful-fs "^4.1.11"
+ jest-config "^23.6.0"
+ jest-haste-map "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-regex-util "^23.3.0"
+ jest-resolve "^23.6.0"
+ jest-snapshot "^23.6.0"
+ jest-util "^23.4.0"
+ jest-validate "^23.6.0"
+ micromatch "^2.3.11"
+ realpath-native "^1.0.0"
+ slash "^1.0.0"
+ strip-bom "3.0.0"
+ write-file-atomic "^2.1.0"
+ yargs "^11.0.0"
+
+jest-serializer@^23.0.1:
+ version "23.0.1"
+ resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165"
+ integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU=
+
+jest-snapshot@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a"
+ integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg==
+ dependencies:
+ babel-types "^6.0.0"
+ chalk "^2.0.1"
+ jest-diff "^23.6.0"
+ jest-matcher-utils "^23.6.0"
+ jest-message-util "^23.4.0"
+ jest-resolve "^23.6.0"
+ mkdirp "^0.5.1"
+ natural-compare "^1.4.0"
+ pretty-format "^23.6.0"
+ semver "^5.5.0"
+
+jest-util@^23.4.0:
+ version "23.4.0"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561"
+ integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE=
+ dependencies:
+ callsites "^2.0.0"
+ chalk "^2.0.1"
+ graceful-fs "^4.1.11"
+ is-ci "^1.0.10"
+ jest-message-util "^23.4.0"
+ mkdirp "^0.5.1"
+ slash "^1.0.0"
+ source-map "^0.6.0"
+
+jest-validate@^23.0.1, jest-validate@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474"
+ integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==
+ dependencies:
+ chalk "^2.0.1"
+ jest-get-type "^22.1.0"
+ leven "^2.1.0"
+ pretty-format "^23.6.0"
+
+jest-watcher@^23.4.0:
+ version "23.4.0"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c"
+ integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw=
+ dependencies:
+ ansi-escapes "^3.0.0"
+ chalk "^2.0.1"
+ string-length "^2.0.0"
+
+jest-worker@^23.2.0:
+ version "23.2.0"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9"
+ integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk=
+ dependencies:
+ merge-stream "^1.0.1"
+
+jest@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d"
+ integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw==
+ dependencies:
+ import-local "^1.0.0"
+ jest-cli "^23.6.0"
+
jquery-ujs@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/jquery-ujs/-/jquery-ujs-1.2.2.tgz#6a8ef1020e6b6dda385b90a4bddc128c21c56397"
@@ -4960,7 +5990,7 @@ js-tokens@^3.0.2:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-js-yaml@3.x, js-yaml@^3.12.0:
+js-yaml@3.x, js-yaml@^3.12.0, js-yaml@^3.7.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
@@ -4968,6 +5998,48 @@ js-yaml@3.x, js-yaml@^3.12.0:
argparse "^1.0.7"
esprima "^4.0.0"
+jsbn@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+ integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+
+jsdom@^11.5.1:
+ version "11.12.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
+ integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==
+ dependencies:
+ abab "^2.0.0"
+ acorn "^5.5.3"
+ acorn-globals "^4.1.0"
+ array-equal "^1.0.0"
+ cssom ">= 0.3.2 < 0.4.0"
+ cssstyle "^1.0.0"
+ data-urls "^1.0.0"
+ domexception "^1.0.1"
+ escodegen "^1.9.1"
+ html-encoding-sniffer "^1.0.2"
+ left-pad "^1.3.0"
+ nwsapi "^2.0.7"
+ parse5 "4.0.0"
+ pn "^1.1.0"
+ request "^2.87.0"
+ request-promise-native "^1.0.5"
+ sax "^1.2.4"
+ symbol-tree "^3.2.2"
+ tough-cookie "^2.3.4"
+ w3c-hr-time "^1.0.1"
+ webidl-conversions "^4.0.2"
+ whatwg-encoding "^1.0.3"
+ whatwg-mimetype "^2.1.0"
+ whatwg-url "^6.4.1"
+ ws "^5.2.0"
+ xml-name-validator "^3.0.0"
+
+jsesc@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+ integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s=
+
jsesc@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe"
@@ -4993,21 +6065,41 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+json-schema@0.2.3:
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+ integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
+
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+json-stringify-safe@~5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+ integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
+
json3@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
-json5@^0.5.0:
+json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
+jsprim@^1.2.2:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
+ integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
+ dependencies:
+ assert-plus "1.0.0"
+ extsprintf "1.3.0"
+ json-schema "0.2.3"
+ verror "1.10.0"
+
jszip-utils@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/jszip-utils/-/jszip-utils-0.0.2.tgz#457d5cbca60a1c2e0706e9da2b544e8e7bc50bf8"
@@ -5156,6 +6248,11 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
+kleur@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300"
+ integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==
+
latest-version@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15"
@@ -5170,6 +6267,13 @@ lazy-cache@^2.0.2:
dependencies:
set-getter "^0.1.0"
+lcid@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
+ integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
+ dependencies:
+ invert-kv "^1.0.0"
+
lcid@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
@@ -5177,6 +6281,16 @@ lcid@^2.0.0:
dependencies:
invert-kv "^2.0.0"
+left-pad@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
+ integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
+
+leven@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580"
+ integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA=
+
levn@^0.3.0, levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
@@ -5192,6 +6306,17 @@ lie@~3.1.0:
dependencies:
immediate "~3.0.5"
+load-json-file@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
+ integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+ strip-bom "^2.0.0"
+
load-json-file@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
@@ -5287,6 +6412,11 @@ lodash.snakecase@4.1.1:
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=
+lodash.sortby@^4.7.0:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
+ integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
+
lodash.startcase@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8"
@@ -5297,7 +6427,7 @@ lodash.upperfirst@4.3.1:
resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce"
integrity sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=
-lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.5.0:
+lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@^4.5.0:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
@@ -5362,6 +6492,13 @@ make-dir@^1.0.0, make-dir@^1.3.0:
dependencies:
pify "^3.0.0"
+makeerror@1.0.x:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
+ integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=
+ dependencies:
+ tmpl "1.0.x"
+
mamacro@^0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4"
@@ -5401,6 +6538,11 @@ match-at@^0.1.1:
resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540"
integrity sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q==
+math-random@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac"
+ integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w=
+
md5.js@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
@@ -5414,6 +6556,13 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
+mem@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76"
+ integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
+ dependencies:
+ mimic-fn "^1.0.0"
+
mem@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf"
@@ -5448,6 +6597,18 @@ merge-source-map@^1.1.0:
dependencies:
source-map "^0.6.1"
+merge-stream@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1"
+ integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=
+ dependencies:
+ readable-stream "^2.0.1"
+
+merge@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
+ integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
+
mermaid@^8.0.0-rc.8:
version "8.0.0-rc.8"
resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.0.0-rc.8.tgz#74ed54d0d46e9ee71c4db2730b2d83d516a21e72"
@@ -5467,7 +6628,26 @@ methods@~1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
-micromatch@^3.1.4, micromatch@^3.1.8, micromatch@^3.1.9:
+micromatch@^2.3.11:
+ version "2.3.11"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+ integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=
+ dependencies:
+ arr-diff "^2.0.0"
+ array-unique "^0.2.1"
+ braces "^1.8.2"
+ expand-brackets "^0.1.4"
+ extglob "^0.3.1"
+ filename-regex "^2.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.1"
+ kind-of "^3.0.2"
+ normalize-path "^2.0.1"
+ object.omit "^2.0.0"
+ parse-glob "^3.0.4"
+ regex-cache "^0.4.2"
+
+micromatch@^3.1.4, micromatch@^3.1.6, micromatch@^3.1.8, micromatch@^3.1.9:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -5499,7 +6679,7 @@ miller-rabin@^4.0.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8"
integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==
-mime-types@~2.1.17, mime-types@~2.1.18:
+mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.19:
version "2.1.21"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96"
integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==
@@ -5548,7 +6728,7 @@ minimist@0.0.8:
resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-minimist@1.2.0, minimist@^1.2.0:
+minimist@1.2.0, minimist@^1.1.1, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
@@ -5745,6 +6925,11 @@ node-forge@0.6.33:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.6.33.tgz#463811879f573d45155ad6a9f43dc296e8e85ebc"
integrity sha1-RjgRh59XPUUVWtap9D3ClujoXrw=
+node-int64@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
+ integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
+
"node-libs-browser@^1.0.0 || ^2.0.0", node-libs-browser@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df"
@@ -5774,6 +6959,16 @@ node-forge@0.6.33:
util "^0.10.3"
vm-browserify "0.0.4"
+node-notifier@^5.2.1:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01"
+ integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==
+ dependencies:
+ growly "^1.3.0"
+ semver "^5.5.0"
+ shellwords "^0.1.1"
+ which "^1.3.0"
+
node-pre-gyp@^0.10.0:
version "0.10.3"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc"
@@ -5845,7 +7040,7 @@ normalize-package-data@^2.3.2:
semver "2 || 3 || 4 || 5"
validate-npm-package-license "^3.0.1"
-normalize-path@^2.1.1:
+normalize-path@^2.0.1, normalize-path@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=
@@ -5901,6 +7096,16 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
+nwsapi@^2.0.7:
+ version "2.0.9"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016"
+ integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ==
+
+oauth-sign@~0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
+ integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
+
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -5960,6 +7165,14 @@ object.getownpropertydescriptors@^2.0.3:
define-properties "^1.1.2"
es-abstract "^1.5.1"
+object.omit@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
+ integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=
+ dependencies:
+ for-own "^0.1.4"
+ is-extendable "^0.1.1"
+
object.pick@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
@@ -6074,6 +7287,15 @@ os-homedir@^1.0.0:
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
+os-locale@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
+ integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==
+ dependencies:
+ execa "^0.7.0"
+ lcid "^1.0.0"
+ mem "^1.1.0"
+
os-locale@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620"
@@ -6083,7 +7305,7 @@ os-locale@^3.0.0:
lcid "^2.0.0"
mem "^4.0.0"
-os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
+os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
@@ -6201,6 +7423,16 @@ parse-asn1@^5.0.0:
evp_bytestokey "^1.0.0"
pbkdf2 "^3.0.3"
+parse-glob@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+ integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw=
+ dependencies:
+ glob-base "^0.3.0"
+ is-dotfile "^1.0.0"
+ is-extglob "^1.0.0"
+ is-glob "^2.0.0"
+
parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
@@ -6216,6 +7448,11 @@ parse-json@^4.0.0:
error-ex "^1.3.1"
json-parse-better-errors "^1.0.1"
+parse5@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
+ integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
+
parse5@^5:
version "5.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.0.0.tgz#4d02710d44f3c3846197a11e205d4ef17842b81a"
@@ -6267,7 +7504,7 @@ path-exists@^3.0.0:
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
-path-is-absolute@^1.0.0:
+path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
@@ -6292,6 +7529,15 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
+path-type@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
+ integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
+ dependencies:
+ graceful-fs "^4.1.2"
+ pify "^2.0.0"
+ pinkie-promise "^2.0.0"
+
path-type@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73"
@@ -6324,6 +7570,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
+performance-now@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
+ integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -6379,6 +7630,11 @@ pluralize@^7.0.0:
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
+pn@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb"
+ integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==
+
pofile@^1:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.0.11.tgz#35aff58c17491d127a07336d5522ebc9df57c954"
@@ -6472,6 +7728,11 @@ prepend-http@^2.0.0:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
+preserve@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+ integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
+
prettier@1.13.7:
version "1.13.7"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281"
@@ -6482,6 +7743,14 @@ prettier@1.15.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e"
integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug==
+pretty-format@^23.6.0:
+ version "23.6.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760"
+ integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==
+ dependencies:
+ ansi-regex "^3.0.0"
+ ansi-styles "^3.2.0"
+
prismjs@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.6.0.tgz#118d95fb7a66dba2272e343b345f5236659db365"
@@ -6489,7 +7758,7 @@ prismjs@^1.6.0:
optionalDependencies:
clipboard "^1.5.5"
-private@^0.1.6:
+private@^0.1.6, private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
@@ -6519,6 +7788,14 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
+prompts@^0.1.9:
+ version "0.1.14"
+ resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2"
+ integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w==
+ dependencies:
+ kleur "^2.0.1"
+ sisteransi "^0.1.1"
+
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
@@ -6549,6 +7826,11 @@ pseudomap@^1.0.2:
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
+psl@^1.1.24, psl@^1.1.28:
+ version "1.1.29"
+ resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
+ integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
+
pstree.remy@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.0.tgz#f2af27265bd3e5b32bbfcc10e80bac55ba78688b"
@@ -6597,7 +7879,12 @@ punycode@1.3.2, punycode@^1.2.4:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-punycode@^2.1.0:
+punycode@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+ integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
+
+punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@@ -6612,6 +7899,11 @@ qs@6.5.1:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==
+qs@~6.5.2:
+ version "6.5.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
+ integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
+
query-string@^5.0.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb"
@@ -6636,6 +7928,15 @@ querystringify@^2.0.0:
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef"
integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==
+randomatic@^3.0.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
+ integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==
+ dependencies:
+ is-number "^4.0.0"
+ kind-of "^6.0.0"
+ math-random "^1.0.1"
+
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80"
@@ -6693,6 +7994,14 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
+read-pkg-up@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
+ integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
+ dependencies:
+ find-up "^1.0.0"
+ read-pkg "^1.0.0"
+
read-pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
@@ -6709,6 +8018,15 @@ read-pkg-up@^4.0.0:
find-up "^3.0.0"
read-pkg "^3.0.0"
+read-pkg@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
+ integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
+ dependencies:
+ load-json-file "^1.0.0"
+ normalize-package-data "^2.3.2"
+ path-type "^1.0.0"
+
read-pkg@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8"
@@ -6762,6 +8080,13 @@ readdirp@^2.0.0:
readable-stream "^2.0.2"
set-immediate-shim "^1.0.1"
+realpath-native@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560"
+ integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g==
+ dependencies:
+ util.promisify "^1.0.0"
+
regenerate-unicode-properties@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c"
@@ -6791,6 +8116,13 @@ regenerator-transform@^0.13.3:
dependencies:
private "^0.1.6"
+regex-cache@^0.4.2:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
+ integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==
+ dependencies:
+ is-equal-shallow "^0.1.3"
+
regex-not@^1.0.0, regex-not@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
@@ -6879,11 +8211,60 @@ repeat-string@^0.2.2:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-0.2.2.tgz#c7a8d3236068362059a7e4651fc6884e8b1fb4ae"
integrity sha1-x6jTI2BoNiBZp+RlH8aITosftK4=
-repeat-string@^1.6.1:
+repeat-string@^1.5.2, repeat-string@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
+repeating@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+ integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
+ dependencies:
+ is-finite "^1.0.0"
+
+request-promise-core@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6"
+ integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=
+ dependencies:
+ lodash "^4.13.1"
+
+request-promise-native@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5"
+ integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=
+ dependencies:
+ request-promise-core "1.1.1"
+ stealthy-require "^1.1.0"
+ tough-cookie ">=2.3.3"
+
+request@^2.87.0:
+ version "2.88.0"
+ resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
+ integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
+ dependencies:
+ aws-sign2 "~0.7.0"
+ aws4 "^1.8.0"
+ caseless "~0.12.0"
+ combined-stream "~1.0.6"
+ extend "~3.0.2"
+ forever-agent "~0.6.1"
+ form-data "~2.3.2"
+ har-validator "~5.1.0"
+ http-signature "~1.2.0"
+ is-typedarray "~1.0.0"
+ isstream "~0.1.2"
+ json-stringify-safe "~5.0.1"
+ mime-types "~2.1.19"
+ oauth-sign "~0.9.0"
+ performance-now "^2.1.0"
+ qs "~6.5.2"
+ safe-buffer "^5.1.2"
+ tough-cookie "~2.4.3"
+ tunnel-agent "^0.6.0"
+ uuid "^3.3.2"
+
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -6929,7 +8310,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
-resolve@1.1.x:
+resolve@1.1.7, resolve@1.1.x:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
@@ -6981,6 +8362,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^2.0.0"
inherits "^2.0.1"
+rsvp@^3.3.3:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a"
+ integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==
+
run-async@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
@@ -7029,11 +8415,27 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
-"safer-buffer@>= 2.1.2 < 3":
+"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+sane@^2.0.0:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa"
+ integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o=
+ dependencies:
+ anymatch "^2.0.0"
+ capture-exit "^1.2.0"
+ exec-sh "^0.2.0"
+ fb-watchman "^2.0.0"
+ micromatch "^3.1.4"
+ minimist "^1.1.1"
+ walker "~1.0.5"
+ watch "~0.18.0"
+ optionalDependencies:
+ fsevents "^1.2.3"
+
sanitize-html@^1.16.1:
version "1.16.3"
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.16.3.tgz#96c1b44a36ff7312e1c22a14b05274370ac8bd56"
@@ -7239,6 +8641,11 @@ shebang-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
+shellwords@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
+ integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
+
sigmund@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
@@ -7249,6 +8656,16 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
+sisteransi@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce"
+ integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g==
+
+slash@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+ integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
+
slice-ansi@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
@@ -7394,6 +8811,21 @@ source-map-resolve@^0.5.0:
source-map-url "^0.4.0"
urix "^0.1.0"
+source-map-support@^0.4.15:
+ version "0.4.18"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f"
+ integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==
+ dependencies:
+ source-map "^0.5.6"
+
+source-map-support@^0.5.6:
+ version "0.5.9"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f"
+ integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==
+ dependencies:
+ buffer-from "^1.0.0"
+ source-map "^0.6.0"
+
source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
@@ -7404,12 +8836,12 @@ source-map@0.5.0:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.0.tgz#0fe96503ac86a5adb5de63f4e412ae4872cdbe86"
integrity sha1-D+llA6yGpa213mP05BKuSHLNvoY=
-source-map@^0.5.0, source-map@^0.5.6:
+source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-source-map@^0.6.1, source-map@~0.6.1:
+source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -7495,6 +8927,21 @@ srcset@^1.0.0:
array-uniq "^1.0.2"
number-is-nan "^1.0.0"
+sshpk@^1.7.0:
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629"
+ integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==
+ dependencies:
+ asn1 "~0.2.3"
+ assert-plus "^1.0.0"
+ bcrypt-pbkdf "^1.0.0"
+ dashdash "^1.12.0"
+ ecc-jsbn "~0.1.1"
+ getpass "^0.1.1"
+ jsbn "~0.1.0"
+ safer-buffer "^2.0.2"
+ tweetnacl "~0.14.0"
+
ssri@^5.2.4:
version "5.2.4"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.2.4.tgz#9985e14041e65fc397af96542be35724ac11da52"
@@ -7509,6 +8956,11 @@ ssri@^6.0.0:
dependencies:
figgy-pudding "^3.5.1"
+stack-utils@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
+ integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==
+
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
@@ -7527,6 +8979,11 @@ statuses@~1.3.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=
+stealthy-require@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
+ integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
+
stickyfilljs@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/stickyfilljs/-/stickyfilljs-2.0.5.tgz#d229e372d2199ddf5d283bbe34ac1f7d2529c2fc"
@@ -7586,6 +9043,14 @@ strict-uri-encode@^1.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
+string-length@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"
+ integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=
+ dependencies:
+ astral-regex "^1.0.0"
+ strip-ansi "^4.0.0"
+
string-width@^1.0.1, string-width@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -7629,11 +9094,18 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
-strip-bom@^3.0.0:
+strip-bom@3.0.0, strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
+strip-bom@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
+ integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
+ dependencies:
+ is-utf8 "^0.2.0"
+
strip-css-comments@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-css-comments/-/strip-css-comments-3.0.0.tgz#7a5625eff8a2b226cf8947a11254da96e13dae89"
@@ -7664,7 +9136,7 @@ supports-color@^2.0.0:
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-supports-color@^3.1.0:
+supports-color@^3.1.0, supports-color@^3.1.2:
version "3.2.3"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
@@ -7688,6 +9160,11 @@ symbol-observable@^1.0.2:
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
+symbol-tree@^3.2.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
+ integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=
+
table@^4.0.3:
version "4.0.3"
resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc"
@@ -7730,6 +9207,17 @@ term-size@^1.2.0:
dependencies:
execa "^0.7.0"
+test-exclude@^4.2.1:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20"
+ integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA==
+ dependencies:
+ arrify "^1.0.1"
+ micromatch "^2.3.11"
+ object-assign "^4.1.0"
+ read-pkg-up "^1.0.1"
+ require-main-filename "^1.0.1"
+
test-exclude@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.0.0.tgz#cdce7cece785e0e829cd5c2b27baf18bc583cfb7"
@@ -7765,6 +9253,11 @@ three@^0.84.0:
resolved "https://registry.yarnpkg.com/three/-/three-0.84.0.tgz#95be85a55a0fa002aa625ed559130957dcffd918"
integrity sha1-lb6FpVoPoAKqYl7VWRMJV9z/2Rg=
+throat@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a"
+ integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=
+
throttle-debounce@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.0.1.tgz#7307ddd6cd9acadb349132fbf6c18d78c88a5e62"
@@ -7819,6 +9312,11 @@ tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
+tmpl@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
+ integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
+
to-array@0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
@@ -7876,6 +9374,29 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
+tough-cookie@>=2.3.3, tough-cookie@^2.3.4:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
+ integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
+ dependencies:
+ psl "^1.1.28"
+ punycode "^2.1.1"
+
+tough-cookie@~2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
+ integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
+ dependencies:
+ psl "^1.1.24"
+ punycode "^1.4.1"
+
+tr46@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
+ integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=
+ dependencies:
+ punycode "^2.1.0"
+
trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
@@ -7896,6 +9417,18 @@ tty-browserify@0.0.0:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
+tunnel-agent@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+ integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
+ dependencies:
+ safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+ version "0.14.5"
+ resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+ integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
+
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
@@ -8191,6 +9724,15 @@ vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
+verror@1.10.0:
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
+ integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
+ dependencies:
+ assert-plus "^1.0.0"
+ core-util-is "1.0.2"
+ extsprintf "^1.2.0"
+
visibilityjs@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/visibilityjs/-/visibilityjs-1.2.4.tgz#bff8663da62c8c10ad4ee5ae6a1ae6fac4259d63"
@@ -8297,6 +9839,28 @@ vuex@^3.0.1:
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"
integrity sha512-wLoqz0B7DSZtgbWL1ShIBBCjv22GV5U+vcBFox658g6V0s4wZV9P4YjCNyoHSyIBpj1f29JBoNQIqD82cR4O3w==
+w3c-hr-time@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045"
+ integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=
+ dependencies:
+ browser-process-hrtime "^0.1.2"
+
+walker@~1.0.5:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
+ integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
+ dependencies:
+ makeerror "1.0.x"
+
+watch@~0.18.0:
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986"
+ integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY=
+ dependencies:
+ exec-sh "^0.2.0"
+ minimist "^1.2.0"
+
watchpack@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.5.0.tgz#231e783af830a22f8966f65c4c4bacc814072eed"
@@ -8313,6 +9877,11 @@ wbuf@^1.1.0, wbuf@^1.7.2:
dependencies:
minimalistic-assert "^1.0.0"
+webidl-conversions@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
+ integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
+
webpack-bundle-analyzer@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.2.tgz#22f19ea6d1b5a15fd7a90baae0bc0f39bd1e4d48"
@@ -8455,6 +10024,36 @@ websocket-extensions@>=0.1.1:
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7"
integrity sha1-domUmcGEtu91Q3fC27DNbLVdKec=
+whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
+ integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
+ dependencies:
+ iconv-lite "0.4.24"
+
+whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
+ integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+
+whatwg-url@^6.4.1:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
+ integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==
+ dependencies:
+ lodash.sortby "^4.7.0"
+ tr46 "^1.0.1"
+ webidl-conversions "^4.0.2"
+
+whatwg-url@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd"
+ integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==
+ dependencies:
+ lodash.sortby "^4.7.0"
+ tr46 "^1.0.1"
+ webidl-conversions "^4.0.2"
+
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
@@ -8467,6 +10066,13 @@ which@^1.1.1, which@^1.2.1, which@^1.2.9:
dependencies:
isexe "^2.0.0"
+which@^1.2.12, which@^1.3.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
+ integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
+ dependencies:
+ isexe "^2.0.0"
+
wide-align@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710"
@@ -8520,7 +10126,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-write-file-atomic@^2.0.0:
+write-file-atomic@^2.0.0, write-file-atomic@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab"
integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==
@@ -8536,6 +10142,13 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"
+ws@^5.2.0:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f"
+ integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==
+ dependencies:
+ async-limiter "~1.0.0"
+
ws@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.0.0.tgz#eaa494aded00ac4289d455bac8d84c7c651cef35"
@@ -8557,6 +10170,16 @@ xdg-basedir@^3.0.0:
resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4"
integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=
+xml-name-validator@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
+ integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+
+xml@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
+ integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
+
xmlbuilder@8.2.2:
version "8.2.2"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"
@@ -8587,6 +10210,11 @@ xterm@^3.5.0:
resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.5.0.tgz#ba3f464bc5730c9d259ebe62131862224db9ddcc"
integrity sha512-IpG3P3gkT0/xDPS0j3igpk92JYlUajaEHk3/EQSUeIRJmPiF2lyham3Xt/GD3o98uOrRluvowjNj0AFeYK+AXQ==
+y18n@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
+ integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
+
"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
@@ -8609,6 +10237,13 @@ yargs-parser@^10.1.0:
dependencies:
camelcase "^4.1.0"
+yargs-parser@^9.0.2:
+ version "9.0.2"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
+ integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=
+ dependencies:
+ camelcase "^4.1.0"
+
yargs@12.0.2, yargs@^12.0.1:
version "12.0.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.2.tgz#fe58234369392af33ecbef53819171eff0f5aadc"
@@ -8627,6 +10262,24 @@ yargs@12.0.2, yargs@^12.0.1:
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"
+yargs@^11.0.0:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77"
+ integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==
+ dependencies:
+ cliui "^4.0.0"
+ decamelize "^1.1.1"
+ find-up "^2.1.0"
+ get-caller-file "^1.0.1"
+ os-locale "^2.0.0"
+ require-directory "^2.1.1"
+ require-main-filename "^1.0.1"
+ set-blocking "^2.0.0"
+ string-width "^2.0.0"
+ which-module "^2.0.0"
+ y18n "^3.2.1"
+ yargs-parser "^9.0.2"
+
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"