Commit 4bcec743 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'master' into 'patch-28'

# Conflicts:
#   doc/development/i18n/proofreader.md
parents 8c94d245 77f215b3

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

{
"presets": [["latest", { "es2015": { "modules": false } }], "stage-2"],
"env": {
"karma": {
"plugins": ["rewire"]
},
"coverage": {
"plugins": [
[
"istanbul",
{
"exclude": ["spec/javascripts/**/*", "app/assets/javascripts/locale/**/app.js"]
}
],
[
"transform-define",
{
"process.env.BABEL_ENV": "coverage"
}
],
"rewire"
]
}
}
}
const BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV || null;
const presets = [
[
'@babel/preset-env',
{
modules: false,
targets: {
ie: '11',
},
},
],
];
// include stage 3 proposals
const plugins = [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-json-strings',
];
// add code coverage tooling if necessary
if (BABEL_ENV === 'coverage') {
plugins.push([
'babel-plugin-istanbul',
{
exclude: ['spec/javascripts/**/*', 'app/assets/javascripts/locale/**/app.js'],
},
]);
}
// add rewire support when running tests
if (BABEL_ENV === 'karma' || BABEL_ENV === 'coverage') {
plugins.push('babel-plugin-rewire');
}
module.exports = { presets, plugins };
---
env:
browser: true
es6: true
extends:
- airbnb-base
- plugin:vue/recommended
- '@gitlab'
globals:
__webpack_public_path__: true
gl: false
gon: false
localStorage: false
parserOptions:
parser: babel-eslint
plugins:
- filenames
- import
- html
- promise
settings:
html/html-extensions:
- ".html"
- ".html.raw"
- '.html'
- '.html.raw'
import/resolver:
webpack:
config: "./config/webpack.config.js"
config: './config/webpack.config.js'
rules:
filenames/match-regex:
- error
- "^[a-z0-9_]+$"
import/no-commonjs: error
no-multiple-empty-lines:
- error
- max: 1
promise/catch-or-return: error
no-param-reassign:
- error
- props: true
ignorePropertyModificationsFor:
- "acc" # for reduce accumulators
- "accumulator" # for reduce accumulators
- "el" # for DOM elements
- "element" # for DOM elements
- "state" # for Vuex mutations
no-underscore-dangle:
- error
- allow:
- __
- _links
no-mixed-operators: off
vue/html-self-closing:
- error
- html:
void: always
normal: never
component: always
svg: always
math: always
## Conflicting rules with prettier:
space-before-function-paren: off
curly: off
arrow-parens: off
function-paren-newline: off
object-curly-newline: off
padded-blocks: off
# Disabled for now, to make the eslint 3 -> eslint 4 update smoother
## Indent rule. We are using the old for now: https://eslint.org/docs/user-guide/migrating-to-4.0.0#indent-rewrite
indent: off
indent-legacy:
- __
- _links
# Disabled for now, to make the airbnb-base 12.1.0 -> 13.1.0 update smoother
no-else-return:
- error
- 2
- SwitchCase: 1
VariableDeclarator: 1
outerIIFEBody: 1
FunctionDeclaration:
parameters: 1
body: 1
FunctionExpression:
parameters: 1
body: 1
- allowElseIf: true
import/no-useless-path-segments: off
lines-between-class-members: off
# Disabled for now, to make the plugin-vue 4.5 -> 5.0 update smoother
vue/no-confusing-v-for-v-if: error
vue/no-unused-components: off
vue/no-use-v-if-with-v-for: off
vue/no-v-html: off
Dangerfile gitlab-language=ruby
db/schema.rb merge=merge_db_schema
......@@ -40,6 +40,7 @@ eslint-report.html
/config/redis.queues.yml
/config/redis.shared_state.yml
/config/unicorn.rb
/config/puma.rb
/config/secrets.yml
/config/sidekiq.yml
/config/registry.key
......
This diff is collapsed.
# Backend Maintainers are the default for all ruby files
*.rb @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
*.rake @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
# Technical writing team are the default reviewers for everything in `doc/`
/doc/ @axil @marcia
# Frontend maintainers should see everything in `app/assets/`
app/assets/ @annabeldunstone @ClemMakesApps @fatihacet @filipa @iamphill @mikegreiling @timzallmann
# Someone from the database team should review changes in `db/`
db/ @abrandl @NikolayS
# Feature specific owners
/ee/lib/gitlab/code_owners/ @reprazent
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/auth/ldap/ @dblessing @mkozono
# Backend Maintainers are the default for all ruby files
*.rb @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
*.rake @ayufan @DouweM @dzaporozhets @grzesiek @nick.thomas @rspeicher @rymai @smcgivern
# Technical writing team are the default reviewers for everything in `doc/`
/doc/ @axil @marcia
# Frontend maintainers should see everything in `app/assets/`
app/assets/ @ClemMakesApps @fatihacet @filipa @iamphill @mikegreiling @timzallmann
*.scss @annabeldunstone @ClemMakesApps @fatihacet @filipa @iamphill @mikegreiling @timzallmann
# Someone from the database team should review changes in `db/`
db/ @abrandl @NikolayS
# Feature specific owners
/ee/lib/gitlab/code_owners/ @reprazent
/ee/lib/ee/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/auth/ldap/ @dblessing @mkozono
/lib/gitlab/ci/templates/ @nolith @zj
/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml @DylanGriffith @mayra-cabrera @tkuah
### Background:
(Include problem, use cases, benefits, and/or goals)
**What questions are you trying to answer?**
**Are you looking to verify an existing hypothesis or uncover new issues you should be exploring?**
**What is the backstory of this project and how does it impact the approach?**
**What do you already know about the areas you are exploring?**
**What does success look like at the end of the project?**
### Links / references:
/label ~"UX research"
......@@ -16,7 +16,7 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Add a link to the MR to the [links section](#links)
- [ ] Add a link to an EE MR if required
- [ ] Make sure the MR remains in-progress and gets approved after the review cycle, **but never merged**.
- [ ] Assign the MR to a RM once is reviewed and ready to be merged. Check the [RM list] to see who to ping.
- [ ] Add a link to this issue on the original security issue.
#### Backports
......@@ -26,7 +26,8 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Create the branch `security-X-Y` from `X-Y-stable` if it doesn't exist (and make sure it's up to date with stable)
- [ ] Create each MR targetting the security branch `security-X-Y`
- [ ] Add the ~security label and prefix with the version `WIP: [X.Y]` the title of the MR
- [ ] Make sure all MRs have a link in the [links section](#links) and are assigned to a Release Manager.
- [ ] Add the ~"Merge into Security" label to all of the MRs.
- [ ] Make sure all MRs have a link in the [links section](#links)
[secpick documentation]: https://gitlab.com/gitlab-org/release/docs/blob/master/general/security/developer.md#secpick-script
......@@ -37,6 +38,7 @@ Set the title to: `[Security] Description of the original issue`
- [ ] Fill in any upgrade notes that users may need to take into account in the [details section](#details)
- [ ] Add Yes/No and further details if needed to the migration and settings columns in the [details section](#details)
- [ ] Add the nickname of the external user who found the issue (and/or HackerOne profile) to the Thanks row in the [details section](#details)
- [ ] Once your `master` MR is merged, comment on the original security issue with a link to that MR indicating the issue is fixed.
### Summary
......
......@@ -38,22 +38,22 @@ test plan](https://testing.googleblog.com/2011/09/10-minute-test-plan.html) and
[this wiki page from an open-source tool that implements the ACC
model](https://code.google.com/archive/p/test-analytics/wikis/AccExplained.wiki). -->
| | Simple | Secure | Responsive | Obvious | Stable |
|------------|:------:|:------:|:----------:|:-------:|:------:|
| Admin | | | | | |
| Groups | | | | | |
| Project | | | | | |
| Repository | | | | | |
| Issues | | | | | |
| MRs | | | | | |
| CI/CD | | | | | |
| Ops | | | | | |
| Registry | | | | | |
| Wiki | | | | | |
| Snippets | | | | | |
| Settings | | | | | |
| Tracking | | | | | |
| API | | | | | |
| | Secure | Responsive | Intuitive | Reliable |
|------------|:------:|:----------:|:---------:|:--------:|
| Admin | | | | |
| Groups | | | | |
| Project | | | | |
| Repository | | | | |
| Issues | | | | |
| MRs | | | | |
| CI/CD | | | | |
| Ops | | | | |
| Registry | | | | |
| Wiki | | | | |
| Snippets | | | | |
| Settings | | | | |
| Tracking | | | | |
| API | | | | |
## Capabilities
......@@ -64,8 +64,8 @@ Some features might be simple enough that they only involve one Component, while
more complex features could involve multiple or even all.
Example (from https://gitlab.com/gitlab-org/gitlab-ce/issues/50353):
* Respository is
* Simple
* Repository is
* Intuitive
* It's easy to select the desired file template
* It doesn't require unnecessary actions to save the change
* It's easy to undo the change after selecting a template
......@@ -93,4 +93,4 @@ When adding new automated tests, please keep [testing levels](https://docs.gitla
in mind.
-->
/label ~Quality
\ No newline at end of file
/label ~Quality ~"test plan"
Add a description of your merge request here. Merge requests without an adequate
description will not be reviewed until one is added.
## What does this MR do?
<!--
Describe in detail what your merge request does, why it does that, etc. Merge
requests without an adequate description will not be reviewed until one is
added.
Please also keep this description up-to-date with any discussion that takes
place so that reviewers can understand your intent. This is especially
important if they didn't participate in the discussion.
Make sure to remove this comment when you are done.
-->
Add a description of your merge request here.
## Database checklist
- [ ] Conforms to the [database guides](https://docs.gitlab.com/ee/development/README.html#databases-guides)
When adding migrations:
- [ ] Updated `db/schema.rb`
......@@ -35,16 +50,9 @@ When removing columns, tables, indexes or other structures:
- [ ] [Changelog entry](https://docs.gitlab.com/ee/development/changelog.html) added, if necessary
- [ ] [Documentation created/updated](https://docs.gitlab.com/ee/development/documentation/index.html#contributing-to-docs)
- [ ] [API support added](https://docs.gitlab.com/ee/development/api_styleguide.html)
- [ ] [Tests added for this feature/bug](https://docs.gitlab.com/ee/development/testing_guide/index.html)
- Conforms to the [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
- [ ] Has been reviewed by a Backend [maintainer](https://about.gitlab.com/handbook/engineering/#maintainer)
- [ ] Has been reviewed by a Database [specialist](https://about.gitlab.com/team/structure/#specialist)
- [ ] Conforms to the [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html)
- [ ] Conforms to the [merge request performance guidelines](https://docs.gitlab.com/ee/development/merge_request_performance_guidelines.html)
- [ ] Conforms to the [style guides](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/CONTRIBUTING.md#style-guides)
- [ ] If you have multiple commits, please combine them into a few logically organized commits by [squashing them](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
- [ ] [Internationalization required/considered](https://docs.gitlab.com/ee/development/i18n/index.html)
- [ ] For a paid feature, have we considered GitLab.com plans, how it works for groups, and is there a design for promoting it to users who aren't on the correct plan?
- [ ] [End-to-end tests](https://docs.gitlab.com/ee/development/testing_guide/end_to_end_tests.html#testing-code-in-merge-requests) pass (`package-and-qa` manual pipeline job)
/label ~database
......@@ -19,6 +19,7 @@ Closes
- [ ] [Apply the correct labels and milestone](https://docs.gitlab.com/ee/development/documentation/workflow.html#2-developer-s-role-in-the-documentation-process)
- [ ] Crosslink the document from the higher-level index
- [ ] Crosslink the document from other subject-related docs
- [ ] Feature moving tiers? Make sure the change is also reflected in [`features.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml)
- [ ] Correctly apply the product [badges](https://docs.gitlab.com/ee/development/documentation/styleguide.html#product-badges) and [tiers](https://docs.gitlab.com/ee/development/documentation/styleguide.html#gitlab-versions-and-tiers)
- [ ] [Port the MR to EE (or backport from CE)](https://docs.gitlab.com/ee/development/documentation/index.html#cherry-picking-from-ce-to-ee): _always recommended, required when the `ee-compat-check` job fails_
......
......@@ -3,3 +3,7 @@
/public/
/vendor/
/tmp/
# ignore stylesheets for now as this clashes with our linter
*.css
*.scss
......@@ -3,7 +3,9 @@ inherit_gem:
- rubocop-default.yml
inherit_from: .rubocop_todo.yml
require: ./rubocop/rubocop
require:
- ./rubocop/rubocop
- rubocop-rspec
AllCops:
TargetRailsVersion: 4.2
......@@ -35,6 +37,32 @@ Style/MutableConstant:
Style/SafeNavigation:
Enabled: false
# Frozen String Literal
Style/FrozenStringLiteralComment:
Enabled: true
Exclude:
- 'config.ru'
- 'Dangerfile'
- 'Gemfile'
- 'Rakefile'
- 'app/views/**/*'
- 'config/**/*'
- 'danger/**/*'
- 'db/**/*'
- 'ee/**/*'
- 'lib/tasks/**/*'
- 'qa/**/*'
- 'rubocop/**/*'
- 'scripts/**/*'
- 'spec/**/*'
RSpec/FilePath:
Exclude:
- 'qa/**/*'
- 'spec/javascripts/fixtures/*'
- 'ee/spec/javascripts/fixtures/*'
- 'spec/requests/api/v3/*'
Naming/FileName:
ExpectMatchingDefinition: true
Exclude:
......@@ -47,15 +75,20 @@ Naming/FileName:
- 'qa/qa/specs/**/*'
- 'qa/bin/*'
- 'config/**/*'
- 'ee/config/**/*'
- 'lib/generators/**/*'
- 'locale/unfound_translations.rb'
- 'ee/locale/unfound_translations.rb'
- 'ee/lib/generators/**/*'
- 'qa/qa/scenario/test/integration/ldap_no_tls.rb'
- 'qa/qa/scenario/test/integration/ldap_tls.rb'
IgnoreExecutableScripts: true
AllowedAcronyms:
- EE
- JSON
- LDAP
- SAML
- IO
- HMAC
- QA
......
......@@ -10,24 +10,6 @@
Capybara/CurrentPathExpectation:
Enabled: false
# Offense count: 23
FactoryBot/DynamicAttributeDefinedStatically:
Exclude:
- 'spec/factories/broadcast_messages.rb'
- 'spec/factories/ci/builds.rb'
- 'spec/factories/ci/runners.rb'
- 'spec/factories/clusters/applications/helm.rb'
- 'spec/factories/clusters/platforms/kubernetes.rb'
- 'spec/factories/emails.rb'
- 'spec/factories/gpg_keys.rb'
- 'spec/factories/group_members.rb'
- 'spec/factories/merge_requests.rb'
- 'spec/factories/notes.rb'
- 'spec/factories/oauth_access_grants.rb'
- 'spec/factories/project_members.rb'
- 'spec/factories/todos.rb'
- 'spec/factories/uploads.rb'
# Offense count: 167
# Cop supports --auto-correct.
Layout/EmptyLinesAroundArguments:
......@@ -53,20 +35,6 @@ Layout/IndentArray:
Layout/IndentHash:
Enabled: false
# Offense count: 11
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
Layout/SpaceBeforeFirstArg:
Exclude:
- 'config/routes/project.rb'
- 'db/migrate/20170506185517_add_foreign_key_pipeline_schedules_and_pipelines.rb'
- 'features/steps/project/source/browse_files.rb'
- 'features/steps/project/source/markdown_render.rb'
- 'lib/api/runners.rb'
- 'spec/features/search/user_uses_search_filters_spec.rb'
- 'spec/routing/project_routing_spec.rb'
- 'spec/services/system_note_service_spec.rb'
# Offense count: 93
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle.
......@@ -74,15 +42,6 @@ Layout/SpaceBeforeFirstArg:
Layout/SpaceInLambdaLiteral:
Enabled: false
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBrackets.
# SupportedStyles: space, no_space, compact
# SupportedStylesForEmptyBrackets: space, no_space
Layout/SpaceInsideArrayLiteralBrackets:
Exclude:
- 'spec/lib/gitlab/import_export/relation_factory_spec.rb'
# Offense count: 327
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
......@@ -96,14 +55,6 @@ Layout/SpaceInsideBlockBraces:
Layout/SpaceInsideParens:
Enabled: false
# Offense count: 14
# Cop supports --auto-correct.
Layout/SpaceInsidePercentLiteralDelimiters:
Exclude:
- 'lib/gitlab/git_access.rb'
- 'lib/gitlab/health_checks/fs_shards_check.rb'
- 'spec/lib/gitlab/health_checks/fs_shards_check_spec.rb'
# Offense count: 26
Lint/DuplicateMethods:
Exclude:
......@@ -135,31 +86,11 @@ Lint/InterpolationCheck:
Lint/MissingCopEnableDirective:
Enabled: false
# Offense count: 2
Lint/NestedPercentLiteral:
Exclude:
- 'lib/gitlab/git/repository.rb'
- 'spec/support/shared_examples/email_format_shared_examples.rb'
# Offense count: 1
Lint/ReturnInVoidContext:
Exclude:
- 'app/models/project.rb'
# Offense count: 1
# Configuration parameters: IgnoreImplicitReferences.
Lint/ShadowedArgument:
Exclude:
- 'lib/gitlab/database/sha_attribute.rb'
# Offense count: 3
# Cop supports --auto-correct.
Lint/UnneededRequireStatement:
Exclude:
- 'db/post_migrate/20161221153951_rename_reserved_project_names.rb'
- 'db/post_migrate/20170313133418_rename_more_reserved_project_names.rb'
- 'lib/declarative_policy.rb'
# Offense count: 9
Lint/UriEscapeUnescape:
Exclude:
......@@ -199,16 +130,6 @@ Naming/HeredocDelimiterCase:
Naming/HeredocDelimiterNaming:
Enabled: false
# Offense count: 1
Performance/UnfreezeString:
Exclude:
- 'features/steps/project/commits/commits.rb'
# Offense count: 1
# Cop supports --auto-correct.
Performance/UriDefaultParser:
Exclude:
- 'lib/gitlab/url_sanitizer.rb'
# Offense count: 3821
# Configuration parameters: Prefixes.
......@@ -445,7 +366,6 @@ Style/Dir:
# Cop supports --auto-correct.
Style/EachWithObject:
Exclude:
- 'config/initializers/gollum.rb'
- 'lib/expand_variables.rb'
- 'lib/gitlab/ci/ansi2html.rb'
- 'lib/gitlab/ee_compat_check.rb'
......
This diff is collapsed.
This diff is collapsed.
danger.import_plugin('danger/plugins/helper.rb')
danger.import_dangerfile(path: 'danger/metadata')
danger.import_dangerfile(path: 'danger/changes_size')
danger.import_dangerfile(path: 'danger/changelog')
......@@ -7,3 +8,5 @@ danger.import_dangerfile(path: 'danger/database')
danger.import_dangerfile(path: 'danger/documentation')
danger.import_dangerfile(path: 'danger/frozen_string')
danger.import_dangerfile(path: 'danger/commit_messages')
danger.import_dangerfile(path: 'danger/prettier')
danger.import_dangerfile(path: 'danger/eslint')
# Simple container to store assets for later use
FROM scratch
ADD public/assets /assets/
CMD /bin/true
# --- Special code for migrating to Rails 5.0 ---
def rails5?
%w[1 true].include?(ENV["RAILS5"])
!%w[0 false].include?(ENV["RAILS5"])
end
gem_versions = {}
gem_versions['activerecord_sane_schema_dumper'] = rails5? ? '1.0' : '0.2'
gem_versions['default_value_for'] = rails5? ? '~> 3.0.5' : '~> 3.0.0'
gem_versions['rails'] = rails5? ? '5.0.7' : '4.2.10'
gem_versions['rails-i18n'] = rails5? ? '~> 5.1' : '~> 4.0.9'
gem_versions['activerecord_sane_schema_dumper'] = rails5? ? '1.0' : '0.2'
gem_versions['rails'] = rails5? ? '5.0.7' : '4.2.10'
gem_versions['rails-i18n'] = rails5? ? '~> 5.1' : '~> 4.0.9'
# The 2.0.6 version of rack requires monkeypatch to be present in
# `config.ru`. This can be removed once a new update for Rack
# is available that contains https://github.com/rack/rack/pull/1201.
gem_versions['rack'] = rails5? ? '2.0.6' : '1.6.11'
# --- The end of special code for migrating to Rails 5.0 ---
source 'https://rubygems.org'
......@@ -15,13 +19,20 @@ source 'https://rubygems.org'
gem 'rails', gem_versions['rails']
gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Improves copy-on-write performance for MRI
gem 'nakayoshi_fork', '~> 0.0.4'
# Responders respond_to and respond_with
gem 'responders', '~> 2.0'
gem 'sprockets', '~> 3.7.0'
# Default values for AR models
gem 'default_value_for', gem_versions['default_value_for']
if rails5?
gem 'gitlab-default_value_for', '~> 3.1.1', require: 'default_value_for'
else
gem 'default_value_for', '~> 3.0.0'
end
# Supported DBs
gem 'mysql2', '~> 0.4.10', group: :mysql
......@@ -71,7 +82,7 @@ gem 'validates_hostname', '~> 1.0.6'
gem 'browser', '~> 2.5'
# GPG
gem 'gpgme'
gem 'gpgme', '~> 2.0.18'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
......@@ -79,17 +90,8 @@ gem 'gpgme'
gem 'gitlab_omniauth-ldap', '~> 2.0.4', require: 'omniauth-ldap'
gem 'net-ldap'
# Git Wiki
# Required manually in config/initializers/gollum.rb to control load order
gem 'gitlab-gollum-lib', '~> 4.2', require: false
gem 'gitlab-gollum-rugged_adapter', '~> 0.4.4', require: false
# Language detection
gem 'github-linguist', '~> 5.3.3', require: 'linguist'
# API
gem 'grape', '~> 1.0'
gem 'grape', '~> 1.1.0'
gem 'grape-entity', '~> 0.7.1'
gem 'rack-cors', '~> 1.0.0', require: 'rack/cors'
......@@ -112,9 +114,6 @@ gem 'hamlit', '~> 2.8.8'
gem 'carrierwave', '= 1.2.3'
gem 'mini_magick'
# Drag and Drop UI
gem 'dropzonejs-rails', '~> 0.7.1'
# for backups
gem 'fog-aws', '~> 2.0.1'
gem 'fog-core', '~> 1.44'
......@@ -136,7 +135,8 @@ gem 'seed-fu', '~> 2.3.7'
# Markdown and HTML processing
gem 'html-pipeline', '~> 2.8'
gem 'deckar01-task_list', '2.0.0'
gem 'gitlab-markup', '~> 1.6.4'
gem 'gitlab-markup', '~> 1.6.5'
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
gem 'redcarpet', '~> 3.4'
gem 'commonmarker', '~> 0.17'
gem 'RedCloth', '~> 4.3.2'
......@@ -144,12 +144,13 @@ gem 'rdoc', '~> 6.0'
gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.6'
gem 'asciidoctor', '~> 1.5.8'
gem 'asciidoctor-plantuml', '0.0.8'
gem 'rouge', '~> 3.1'
gem 'truncato', '~> 0.7.9'
gem 'bootstrap_form', '~> 2.7.0'
gem 'nokogiri', '~> 1.8.2'
gem 'escape_utils', '~> 1.1'
# Calendar rendering
gem 'icalendar'
......@@ -158,11 +159,18 @@ gem 'icalendar'
gem 'diffy', '~> 3.1.0'
# Application server
gem 'rack', gem_versions['rack']
group :unicorn do
gem 'unicorn', '~> 5.1.0'
gem 'unicorn-worker-killer', '~> 0.4.4'
end
group :puma do
gem 'puma', '~> 3.12', require: false
gem 'puma_worker_killer', require: false
end
# State machine
gem 'state_machines-activerecord', '~> 0.5.1'
......@@ -173,7 +181,6 @@ gem 'acts-as-taggable-on', '~> 5.0'
gem 'sidekiq', '~> 5.2.1'
gem 'sidekiq-cron', '~> 0.6.0'
gem 'redis-namespace', '~> 1.6.0'
gem 'sidekiq-limit_fetch', '~> 3.4', require: false
# Cron Parser
gem 'rufus-scheduler', '~> 3.4'
......@@ -210,6 +217,9 @@ gem 'redis-rails', '~> 5.0.2'
gem 'redis', '~> 3.2'
gem 'connection_pool', '~> 2.0'
# Discord integration
gem 'discordrb-webhooks-blackst0ne', '~> 3.3', require: false
# HipChat integration
gem 'hipchat', '~> 1.5.0'
......@@ -217,7 +227,7 @@ gem 'hipchat', '~> 1.5.0'
gem 'jira-ruby', '~> 1.4'
# Flowdock integration
gem 'gitlab-flowdock-git-hook', '~> 1.0.1'
gem 'flowdock', '~> 0.7'
# Slack integration
gem 'slack-notifier', '~> 1.5.1'
......@@ -226,13 +236,13 @@ gem 'slack-notifier', '~> 1.5.1'
gem 'hangouts-chat', '~> 0.0.5'
# Asana integration
gem 'asana', '~> 0.6.0'
gem 'asana', '~> 0.8.1'
# FogBugz integration
gem 'ruby-fogbugz', '~> 0.2.1'
# Kubernetes integration
gem 'kubeclient', '~> 3.1.0'
gem 'kubeclient', '~> 4.0.0'
# Sanitize user input
gem 'sanitize', '~> 4.6'
......@@ -250,9 +260,6 @@ gem 'rack-attack', '~> 4.4.1'
# Ace editor
gem 'ace-rails-ap', '~> 4.1.0'
# Keyboard shortcuts
gem 'mousetrap-rails', '~> 1.4.6'
# Detect and convert string character encoding
gem 'charlock_holmes', '~> 0.7.5'
......@@ -300,6 +307,7 @@ gem 'peek-mysql2', '~> 1.1.0', group: :mysql
gem 'peek-pg', '~> 1.3.0', group: :postgres
gem 'peek-rblineprof', '~> 0.2.0'
gem 'peek-redis', '~> 1.2.0'
gem 'gitlab-sidekiq-fetcher', require: 'sidekiq-reliable-fetch'
# Metrics
group :metrics do
......@@ -319,8 +327,8 @@ group :development do
gem 'rblineprof', '~> 0.3.6', platform: :mri, require: false
# Better errors handler
gem 'better_errors', '~> 2.1.0'
gem 'binding_of_caller', '~> 0.7.2'
gem 'better_errors', '~> 2.5.0'
gem 'binding_of_caller', '~> 0.8.0'
# thin instead webrick
gem 'thin', '~> 1.7.0'
......@@ -347,7 +355,7 @@ group :development, :test do
gem 'minitest', '~> 5.7.0'
# Generate Fake data
gem 'ffaker', '~> 2.4'
gem 'ffaker', '~> 2.10'
gem 'capybara', '~> 2.15'
gem 'capybara-screenshot', '~> 1.0.0'
......@@ -362,14 +370,14 @@ group :development, :test do
gem 'rubocop-rspec', '~> 1.22.1'
gem 'scss_lint', '~> 0.56.0', require: false
gem 'haml_lint', '~> 0.26.0', require: false
gem 'haml_lint', '~> 0.28.0', require: false
gem 'simplecov', '~> 0.14.0', require: false
gem 'bundler-audit', '~> 0.5.0', require: false
gem 'benchmark-ips', '~> 2.3.0', require: false
gem 'license_finder', '~> 5.4', require: false
gem 'knapsack', '~> 1.16'
gem 'knapsack', '~> 1.17'
gem 'activerecord_sane_schema_dumper', gem_versions['activerecord_sane_schema_dumper']
......@@ -388,7 +396,7 @@ group :test do
gem 'rails-controller-testing' if rails5? # Rails5 only gem.
gem 'test_after_commit', '~> 1.1' unless rails5? # Remove this gem when migrated to rails 5.0. It's been integrated to rails 5.0.
gem 'sham_rack', '~> 1.3.6'
gem 'concurrent-ruby', '~> 1.0.5'
gem 'concurrent-ruby', '~> 1.1'
gem 'test-prof', '~> 0.2.5'
gem 'rspec_junit_formatter'
end
......@@ -424,11 +432,10 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly-proto', '~> 0.117.0', require: 'gitaly'
gem 'grpc', '~> 1.11.0'
gem 'gitaly-proto', '~> 1.2.0', require: 'gitaly'
gem 'grpc', '~> 1.15.0'
# Locked until https://github.com/google/protobuf/issues/4210 is closed
gem 'google-protobuf', '= 3.5.1'
gem 'google-protobuf', '~> 3.6'
gem 'toml-rb', '~> 1.0.0', require: false
......@@ -440,6 +447,3 @@ gem 'flipper-active_support_cache_store', '~> 0.13.0'
# Structured logging
gem 'lograge', '~> 0.5'
gem 'grape_logging', '~> 1.7'
# Asset synchronization
gem 'asset_sync', '~> 2.4'
This diff is collapsed.
# BUNDLE_GEMFILE=Gemfile.rails4 bundle install
ENV["RAILS5"] = "false"
gemfile = File.expand_path("../Gemfile", __FILE__)
eval(File.read(gemfile), nil, gemfile)
This diff is collapsed.
# BUNDLE_GEMFILE=Gemfile.rails5 bundle install
ENV["RAILS5"] = "true"
gemfile = File.expand_path("../Gemfile", __FILE__)
eval(File.read(gemfile), nil, gemfile)
This diff is collapsed.
This document is intended to communicate the product philosophy GitLab uses in creating GitLab Community Edition. The principles can be found in the [Product Section of the GitLab Handbook](https://about.gitlab.com/handbook/product/#product-at-gitlab).
\ No newline at end of file
......@@ -95,6 +95,12 @@ picked into the stable branches) up to the 19th of the month. Such merge
requests should have the ~"feature flag" label assigned, and don't require a
corresponding exception request to be created.
In order to build the final package and present the feature for self-hosted
customers, the feature flag should be removed. This should happen before the
22nd, ideally _at least_ 2 days before. That means MRs with feature
flags being picked at the 19th would have a quite tight schedule, so picking
these _earlier_ is preferable.
While rare, release managers may decide to reject picking a change into a stable
branch, even when feature flags are used. This might be necessary if the changes
are deemed problematic, too invasive, or there simply isn't enough time to
......@@ -208,6 +214,7 @@ the stable branch are:
* Fixes or improvements to automated QA scenarios
* [Documentation updates](https://docs.gitlab.com/ee/development/documentation/workflow.html#documentation-shipped-late) for changes in the same release
* New or updated translations (as long as they do not touch application code)
* Changes that are behind a feature flag and have the ~"feature flag" label
During the feature freeze all merge requests that are meant to go into the
upcoming release should have the correct milestone assigned _and_ the
......
......@@ -83,7 +83,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL/OpenSUSE
- Ruby (MRI) 2.3
- Ruby (MRI) 2.4
- Git 2.8.4+
- Redis 2.8+
- PostgreSQL (preferred) or MySQL
......
11.4.0-pre
11.6.0-pre
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 14">
<g fill="#d6d7d9">
<path d="M8.7 0L5.3.3l3.2 6.8-3.2 6.6 3.5.3L12 6.9z"/>
<ellipse cx="1.7" cy="11.1" rx="1.7" ry="1.7"/>
<ellipse cx="1.7" cy="5.6" rx="1.7" ry="1.7"/>
</g>
</svg>
\ No newline at end of file
......@@ -6,10 +6,12 @@ import Pager from './pager';
import { localTimeAgo } from './lib/utils/datetime_utility';
export default class Activities {
constructor() {
Pager.init(20, true, false, data => data, this.updateTooltips);
constructor(container = '') {
this.container = container;
$('.event-filter-link').on('click', (e) => {
Pager.init(20, true, false, data => data, this.updateTooltips, this.container);
$('.event-filter-link').on('click', e => {
e.preventDefault();
this.toggleFilter(e.currentTarget);
this.reloadActivities();
......@@ -22,7 +24,7 @@ export default class Activities {
reloadActivities() {
$('.content_list').html('');
Pager.init(20, true, false, data => data, this.updateTooltips);
Pager.init(20, true, false, data => data, this.updateTooltips, this.container);
}
toggleFilter(sender) {
......
......@@ -5,23 +5,22 @@ import axios from './lib/utils/axios_utils';
const Api = {
groupsPath: '/api/:version/groups.json',
groupPath: '/api/:version/groups/:id',
subgroupsPath: '/api/:version/groups/:id/subgroups',
namespacesPath: '/api/:version/namespaces.json',
groupProjectsPath: '/api/:version/groups/:id/projects.json',
projectsPath: '/api/:version/projects.json',
projectPath: '/api/:version/projects/:id',
projectLabelsPath: '/:namespace_path/:project_path/labels',
mergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid',
projectMergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid',
projectMergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes',
projectMergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions',
mergeRequestsPath: '/api/:version/merge_requests',
mergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes',
mergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions',
groupLabelsPath: '/groups/:namespace_path/-/labels',
templatesPath: '/api/:version/templates/:key',
licensePath: '/api/:version/templates/licenses/:key',
gitignorePath: '/api/:version/templates/gitignores/:key',
gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key',
dockerfilePath: '/api/:version/templates/dockerfiles/:key',
issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
projectTemplatePath: '/api/:version/projects/:id/templates/:type/:key',
projectTemplatesPath: '/api/:version/projects/:id/templates/:type',
usersPath: '/api/:version/users.json',
userStatusPath: '/api/:version/user/status',
commitPath: '/api/:version/projects/:id/repository/commits',
commitPipelinesPath: '/:project_id/commit/:sha/pipelines',
branchSinglePath: '/api/:version/projects/:id/repository/branches/:branch',
......@@ -101,36 +100,36 @@ const Api = {
},
// Return Merge Request for project
mergeRequest(projectPath, mergeRequestId, params = {}) {
const url = Api.buildUrl(Api.mergeRequestPath)
projectMergeRequest(projectPath, mergeRequestId, params = {}) {
const url = Api.buildUrl(Api.projectMergeRequestPath)
.replace(':id', encodeURIComponent(projectPath))
.replace(':mrid', mergeRequestId);
return axios.get(url, { params });
},
mergeRequests(params = {}) {
const url = Api.buildUrl(Api.mergeRequestsPath);
return axios.get(url, { params });
},
mergeRequestChanges(projectPath, mergeRequestId) {
const url = Api.buildUrl(Api.mergeRequestChangesPath)
projectMergeRequestChanges(projectPath, mergeRequestId) {
const url = Api.buildUrl(Api.projectMergeRequestChangesPath)
.replace(':id', encodeURIComponent(projectPath))
.replace(':mrid', mergeRequestId);
return axios.get(url);
},
mergeRequestVersions(projectPath, mergeRequestId) {
const url = Api.buildUrl(Api.mergeRequestVersionsPath)
projectMergeRequestVersions(projectPath, mergeRequestId) {
const url = Api.buildUrl(Api.projectMergeRequestVersionsPath)
.replace(':id', encodeURIComponent(projectPath))
.replace(':mrid', mergeRequestId);
return axios.get(url);
},
mergeRequests(params = {}) {
const url = Api.buildUrl(Api.mergeRequestsPath);
return axios.get(url, { params });
},
newLabel(namespacePath, projectPath, data, callback) {
let url;
......@@ -195,29 +194,29 @@ const Api = {
return axios.get(url);
},
// Return text for a specific license
licenseText(key, data, callback) {
const url = Api.buildUrl(Api.licensePath).replace(':key', key);
return axios
.get(url, {
params: data,
})
.then(res => callback(res.data));
},
projectTemplate(id, type, key, options, callback) {
const url = Api.buildUrl(this.projectTemplatePath)
.replace(':id', encodeURIComponent(id))
.replace(':type', type)
.replace(':key', encodeURIComponent(key));
gitignoreText(key, callback) {
const url = Api.buildUrl(Api.gitignorePath).replace(':key', key);
return axios.get(url).then(({ data }) => callback(data));
},
return axios.get(url, { params: options }).then(res => {
if (callback) callback(res.data);
gitlabCiYml(key, callback) {
const url = Api.buildUrl(Api.gitlabCiYmlPath).replace(':key', key);
return axios.get(url).then(({ data }) => callback(data));
return res;
});
},
dockerfileYml(key, callback) {
const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key);
return axios.get(url).then(({ data }) => callback(data));
projectTemplates(id, type, params = {}, callback) {
const url = Api.buildUrl(this.projectTemplatesPath)
.replace(':id', encodeURIComponent(id))
.replace(':type', type);
return axios.get(url, { params }).then(res => {
if (callback) callback(res.data);
return res;
});
},
issueTemplate(namespacePath, projectPath, key, type, callback) {
......@@ -266,10 +265,13 @@ const Api = {
});
},
templates(key, params = {}) {
const url = Api.buildUrl(this.templatesPath).replace(':key', key);
postUserStatus({ emoji, message }) {
const url = Api.buildUrl(this.userStatusPath);
return axios.get(url, { params });
return axios.put(url, {
emoji,
message,
});
},
buildUrl(url) {
......
......@@ -42,10 +42,11 @@ export class AwardsHandler {
}
bindEvents() {
const $parentEl = this.targetContainerEl ? $(this.targetContainerEl) : $(document);
// If the user shows intent let's pre-build the menu
this.registerEventListener(
'one',
$(document),
$parentEl,
'mouseenter focus',
this.toggleButtonSelector,
'mouseenter focus',
......@@ -58,7 +59,7 @@ export class AwardsHandler {
}
},
);
this.registerEventListener('on', $(document), 'click', this.toggleButtonSelector, e => {
this.registerEventListener('on', $parentEl, 'click', this.toggleButtonSelector, e => {
e.stopPropagation();
e.preventDefault();
this.showEmojiMenu($(e.currentTarget));
......@@ -76,7 +77,7 @@ export class AwardsHandler {
});
const emojiButtonSelector = `.js-awards-block .js-emoji-btn, .${this.menuClass} .js-emoji-btn`;
this.registerEventListener('on', $(document), 'click', emojiButtonSelector, e => {
this.registerEventListener('on', $parentEl, 'click', emojiButtonSelector, e => {
e.preventDefault();
const $target = $(e.currentTarget);
const $glEmojiElement = $target.find('gl-emoji');
......@@ -168,7 +169,8 @@ export class AwardsHandler {
</div>
`;
document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup);
const targetEl = this.targetContainerEl ? this.targetContainerEl : document.body;
targetEl.insertAdjacentHTML('beforeend', emojiMenuMarkup);
this.addRemainingEmojiMenuCategories();
this.setupSearch();
......@@ -250,6 +252,12 @@ export class AwardsHandler {
}
positionMenu($menu, $addBtn) {
if (this.targetContainerEl) {
return $menu.css({
top: `${$addBtn.outerHeight()}px`,
});
}
const position = $addBtn.data('position');
// The menu could potentially be off-screen or in a hidden overflow element
// So we position the element absolute in the body
......@@ -424,9 +432,7 @@ export class AwardsHandler {
users = origTitle.trim().split(FROM_SENTENCE_REGEX);
}
users.unshift('You');
return awardBlock
.attr('title', this.toSentence(users))
.tooltip('_fixTitle');
return awardBlock.attr('title', this.toSentence(users)).tooltip('_fixTitle');
}
createAwardButtonForVotesBlock(votesBlock, emojiName) {
......@@ -609,13 +615,11 @@ export class AwardsHandler {
let awardsHandlerPromise = null;
export default function loadAwardsHandler(reload = false) {
if (!awardsHandlerPromise || reload) {
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(
Emoji => {
const awardsHandler = new AwardsHandler(Emoji);
awardsHandler.bindEvents();
return awardsHandler;
},
);
awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(Emoji => {
const awardsHandler = new AwardsHandler(Emoji);
awardsHandler.bindEvents();
return awardsHandler;
});
}
return awardsHandlerPromise;
}
<script>
import Icon from '~/vue_shared/components/icon.vue';
import Tooltip from '~/vue_shared/directives/tooltip';
import { GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
export default {
name: 'Badge',
components: {
Icon,
Tooltip,
GlLoadingIcon,
},
directives: {
Tooltip,
GlTooltip: GlTooltipDirective,
},
props: {
imageUrl: {
......@@ -63,12 +63,7 @@ export default {
<template>
<div>
<a
v-show="!isLoading && !hasError"
:href="linkUrl"
target="_blank"
rel="noopener noreferrer"
>
<a v-show="!isLoading && !hasError" :href="linkUrl" target="_blank" rel="noopener noreferrer">
<img
:src="imageUrlWithRetries"
class="project-badge"
......@@ -78,15 +73,9 @@ export default {
/>
</a>
<gl-loading-icon
v-show="isLoading"
:inline="true"
/>
<gl-loading-icon v-show="isLoading" :inline="true" />
<div
v-show="hasError"
class="btn-group"
>
<div v-show="hasError" class="btn-group">
<div class="btn btn-default btn-sm disabled">
<icon
:size="16"
......@@ -95,25 +84,20 @@ export default {
aria-hidden="true"
/>
</div>
<div
class="btn btn-default btn-sm disabled"
>
<div class="btn btn-default btn-sm disabled">
<span class="prepend-left-8 append-right-8">{{ s__('Badges|No badge image') }}</span>
</div>
</div>
<button
v-tooltip
v-show="hasError"
v-gl-tooltip.hover
:title="s__('Badges|Reload badge image')"
class="btn btn-transparent btn-sm text-primary"
type="button"
@click="reloadImage"
>
<icon
:size="16"
name="retry"
/>
<icon :size="16" name="retry" />
</button>
</div>
</template>
......@@ -4,6 +4,7 @@ import { mapActions, mapState } from 'vuex';
import createFlash from '~/flash';
import { s__, sprintf } from '~/locale';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
import { GlLoadingIcon } from '@gitlab/ui';
import createEmptyBadge from '../empty_badge';
import Badge from './badge.vue';
......@@ -14,6 +15,7 @@ export default {
components: {
Badge,
LoadingButton,
GlLoadingIcon,
},
props: {
isEditing: {
......@@ -153,10 +155,7 @@ export default {
@submit.prevent.stop="onSubmit"
>
<div class="form-group">
<label
for="badge-link-url"
class="label-bold"
>{{ s__('Badges|Link') }}</label>
<label for="badge-link-url" class="label-bold">{{ s__('Badges|Link') }}</label>
<p v-html="helpText"></p>
<input
id="badge-link-url"
......@@ -166,19 +165,12 @@ export default {
required
@input="debouncedPreview"
/>
<div class="invalid-feedback">
{{ s__('Badges|Please fill in a valid URL') }}
</div>
<span class="form-text text-muted">
{{ badgeLinkUrlExample }}
</span>
<div class="invalid-feedback">{{ s__('Badges|Please fill in a valid URL') }}</div>
<span class="form-text text-muted"> {{ badgeLinkUrlExample }} </span>
</div>
<div class="form-group">
<label
for="badge-image-url"
class="label-bold"
>{{ s__('Badges|Badge image URL') }}</label>
<label for="badge-image-url" class="label-bold">{{ s__('Badges|Badge image URL') }}</label>
<p v-html="helpText"></p>
<input
id="badge-image-url"
......@@ -188,12 +180,8 @@ export default {
required
@input="debouncedPreview"
/>
<div class="invalid-feedback">
{{ s__('Badges|Please fill in a valid URL') }}
</div>
<span class="form-text text-muted">
{{ badgeImageUrlExample }}
</span>
<div class="invalid-feedback">{{ s__('Badges|Please fill in a valid URL') }}</div>
<span class="form-text text-muted"> {{ badgeImageUrlExample }} </span>
</div>
<div class="form-group">
......@@ -204,37 +192,22 @@ export default {
:image-url="renderedImageUrl"
:link-url="renderedLinkUrl"
/>
<p v-show="isRendering">
<gl-loading-icon
:inline="true"
/>
<p v-show="isRendering"><gl-loading-icon :inline="true" /></p>
<p v-show="!renderedBadge && !isRendering" class="disabled-content">
{{ s__('Badges|No image to preview') }}
</p>
<p
v-show="!renderedBadge && !isRendering"
class="disabled-content"
>{{ s__('Badges|No image to preview') }}</p>
</div>
<div
v-if="isEditing"
class="row-content-block"
>
<div v-if="isEditing" class="row-content-block">
<loading-button
:loading="isSaving"
:label="s__('Badges|Save changes')"
type="submit"
container-class="btn btn-success"
/>
<button
class="btn btn-cancel"
type="button"
@click="onCancel"
>{{ __('Cancel') }}</button>
<button class="btn btn-cancel" type="button" @click="onCancel">{{ __('Cancel') }}</button>
</div>
<div
v-else
class="form-group"
>
<div v-else class="form-group">
<loading-button
:loading="isSaving"
:label="s__('Badges|Add badge')"
......
......@@ -46,7 +46,8 @@ export default {
:header-title-text="s__('Badges|Delete badge?')"
:footer-primary-button-text="s__('Badges|Delete badge')"
footer-primary-button-variant="danger"
@submit="onSubmitModal">
@submit="onSubmitModal"
>
<div class="well">
<badge
:image-url="badgeInModal ? badgeInModal.renderedImageUrl : ''"
......@@ -56,15 +57,9 @@ export default {
<p v-html="deleteModalText"></p>
</gl-modal>
<badge-form
v-show="isEditing"
:is-editing="true"
/>
<badge-form v-show="isEditing" :is-editing="true" />
<badge-form
v-show="!isEditing"
:is-editing="false"
/>
<badge-form v-show="!isEditing" :is-editing="false" />
<badge-list v-show="!isEditing" />
</div>
</template>
This diff is collapsed.
This diff is collapsed.
......@@ -21,5 +21,4 @@ export default class FileTemplateTypeSelector extends FileTemplateSelector {
text: item => item.name,
});
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment