From 8c2d06cba79ff8965a4de9467e05e80d7c7f449e Mon Sep 17 00:00:00 2001
From: GitLab Bot {{ $options.i18n.ownershipMessage }}[foo]: /url "title"
04_07__leaf_blocks__link_reference_definitions__002:
canonical: |
@@ -2151,6 +2152,7 @@
static: |-
wysiwyg: |-
+ [foo]: /url "the title"
04_07__leaf_blocks__link_reference_definitions__003:
canonical: |
@@ -2158,6 +2160,7 @@
static: |-
wysiwyg: |-
+ [foo*bar\]]: my_(url) "title (with parens)"
04_07__leaf_blocks__link_reference_definitions__004:
canonical: |
@@ -2165,6 +2168,7 @@
static: |-
wysiwyg: |-
+ [foo bar]: my url "title"
04_07__leaf_blocks__link_reference_definitions__005:
canonical: |
@@ -2180,6 +2184,11 @@
line2
">foo
[foo]: /url " + title + line1 + line2 + "wysiwyg: |- +
[foo]: /url04_07__leaf_blocks__link_reference_definitions__008: canonical: | @@ -2221,6 +2231,7 @@ static: |- wysiwyg: |- +
[foo]:04_07__leaf_blocks__link_reference_definitions__010: canonical: | @@ -2238,6 +2249,7 @@ static: |- wysiwyg: |- +
[foo]: /url\bar*baz "foo"bar\baz"04_07__leaf_blocks__link_reference_definitions__012: canonical: | @@ -2246,6 +2258,7 @@ wysiwyg: |- +
[foo]: url04_07__leaf_blocks__link_reference_definitions__013: canonical: | @@ -2253,12 +2266,15 @@ wysiwyg: |- +
[foo]: first+
[foo]: second04_07__leaf_blocks__link_reference_definitions__014: canonical: | static: |- wysiwyg: |- +
[foo]: /url04_07__leaf_blocks__link_reference_definitions__015: canonical: | @@ -2266,18 +2282,20 @@ static: |- wysiwyg: |- +
[αγω]: /φου04_07__leaf_blocks__link_reference_definitions__016: canonical: "" static: "" wysiwyg: |- - +
[foo]: /url04_07__leaf_blocks__link_reference_definitions__017: canonical: |
bar
static: |-bar
wysiwyg: |- +[foo]: /url
bar
04_07__leaf_blocks__link_reference_definitions__018: canonical: | @@ -2292,6 +2310,7 @@ static: |-"title" ok
wysiwyg: |- +[foo]: /url
"title" ok
04_07__leaf_blocks__link_reference_definitions__020: canonical: | @@ -2349,6 +2368,7 @@ wysiwyg: |-[foo]: /url
04_07__leaf_blocks__link_reference_definitions__024: canonical: | @@ -2359,6 +2379,7 @@ bar wysiwyg: |- +bar
[foo]: /url
=== foo
wysiwyg: |- +[foo]: /url
=== foo
04_07__leaf_blocks__link_reference_definitions__026: @@ -2381,6 +2403,9 @@ bar, baz wysiwyg: |- +[foo]: /foo-url "foo"+
[bar]: /bar-url "bar"+
[baz]: /baz-url@@ -2395,12 +2420,12 @@ wysiwyg: |- -
+
04_07__leaf_blocks__link_reference_definitions__028: canonical: "" static: "" wysiwyg: |- - +[foo]: /url
[foo]: /url04_08__leaf_blocks__paragraphs__001: canonical: |
aaa
@@ -4543,7 +4568,7 @@ wysiwyg: |- -a
b
d
a
b
[ref]: /url
d
[foo]: /bar* "ti*tle"06_02__inlines__backslash_escapes__013: canonical: |
foo
@@ -4969,6 +4995,7 @@
wysiwyg: |-
+ [foo]: /föö "föö"
06_03__inlines__entity_and_numeric_character_references__010:
canonical: |
foo
@@ -6475,6 +6502,7 @@
wysiwyg: |-
+ [bar]: /url "title"
06_07__inlines__links__044:
canonical: |
@@ -6482,6 +6510,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__045:
canonical: |
@@ -6489,6 +6518,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__046:
canonical: |
@@ -6496,6 +6526,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__047:
canonical: |
@@ -6503,6 +6534,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__048:
canonical: |
@@ -6510,6 +6542,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__049:
canonical: |
@@ -6517,6 +6550,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__050:
canonical: |
*foo*
@@ -6524,6 +6558,7 @@
*foo*
wysiwyg: |-
*foo*
+ [ref]: /uri
06_07__inlines__links__051:
canonical: |
@@ -6531,6 +6566,7 @@
wysiwyg: |-
+ [ref]: /uri
06_07__inlines__links__052:
canonical: |
[foo
@@ -6538,6 +6574,7 @@
[foo
wysiwyg: |-
[foo
+ [ref]: /uri
06_07__inlines__links__053:
canonical: |
[foo][ref]
@@ -6545,6 +6582,7 @@
[foo][ref]
wysiwyg: |-
[foo][ref]
+ [ref]: /uri
06_07__inlines__links__054:
canonical: |
[foohttp://example.com/?search=][ref]
@@ -6552,6 +6590,7 @@
[foohttp://example.com/?search=][ref]
wysiwyg: |-
[foohttp://example.com/?search=][ref]
+ [ref]: /uri
06_07__inlines__links__055:
canonical: |
@@ -6559,6 +6598,7 @@
wysiwyg: |-
+ [bar]: /url "title"
06_07__inlines__links__056:
canonical: |
Толпой is a Russian word.
@@ -6566,12 +6606,14 @@
Толпой is a Russian word.
wysiwyg: |-
Толпой is a Russian word.
+ [толпой]: /url
06_07__inlines__links__057:
canonical: |
static: |-
wysiwyg: |-
+ [foo bar]: /url
06_07__inlines__links__058:
canonical: |
@@ -6580,6 +6622,7 @@
[foo] bar
wysiwyg: |-
[foo] bar
+ [bar]: /url "title"
06_07__inlines__links__059:
canonical: |
[foo]
@@ -6590,12 +6633,15 @@
wysiwyg: |-
[foo]
bar
+ [bar]: /url "title"
06_07__inlines__links__060:
canonical: |
static: |-
wysiwyg: |-
+ [foo]: /url1
+ [foo]: /url2
06_07__inlines__links__061:
canonical: |
@@ -6604,6 +6650,7 @@
[bar][foo!]
wysiwyg: |-
[bar][foo!]
+ [foo!]: /url
06_07__inlines__links__062:
canonical: |
[foo][ref[]
@@ -6641,12 +6688,14 @@
wysiwyg: |-
+ [ref\[]: /uri
06_07__inlines__links__066:
canonical: |
static: |-
wysiwyg: |-
+ [bar\\]: /uri
06_07__inlines__links__067:
canonical: |
@@ -6681,6 +6730,7 @@
wysiwyg: |-
+ [foo]: /url "title"
06_07__inlines__links__070:
canonical: |
@@ -6688,6 +6738,7 @@
wysiwyg: |-
+ [*foo* bar]: /url "title"
06_07__inlines__links__071:
canonical: |
@@ -6695,6 +6746,7 @@
wysiwyg: |-
+ [foo]: /url "title"
06_07__inlines__links__072:
canonical: |
foo
@@ -6705,6 +6757,7 @@
wysiwyg: |-
foo
[]
+ [foo]: /url "title"
06_07__inlines__links__073:
canonical: |
@@ -6712,6 +6765,7 @@
wysiwyg: |-
+ [foo]: /url "title"
06_07__inlines__links__074:
canonical: |
@@ -6719,6 +6773,7 @@
wysiwyg: |-
+ [*foo* bar]: /url "title"
06_07__inlines__links__075:
canonical: |
[foo bar]
@@ -6726,6 +6781,7 @@
[foo bar]
wysiwyg: |-
[foo bar]
+ [*foo* bar]: /url "title"
06_07__inlines__links__076:
canonical: |
[[bar foo
@@ -6733,6 +6789,7 @@
[[bar foo
wysiwyg: |-
[[bar foo
+ [foo]: /url
06_07__inlines__links__077:
canonical: |
@@ -6740,6 +6797,7 @@
wysiwyg: |-
+ [foo]: /url "title"
06_07__inlines__links__078:
canonical: |
foo bar
@@ -6747,6 +6805,7 @@
foo bar
wysiwyg: |-
foo bar
+ [foo]: /url
06_07__inlines__links__079:
canonical: |
[foo]
@@ -6754,12 +6813,14 @@
[foo]
wysiwyg: |-
[foo]
+ [foo]: /url "title"
06_07__inlines__links__080:
canonical: |
*foo*
static: |-
*foo*
wysiwyg: |-
+ [foo*]: /url
*foo*
06_07__inlines__links__081:
canonical: |
@@ -6768,6 +6829,8 @@
wysiwyg: |-
+ [foo]: /url1
+ [bar]: /url2
06_07__inlines__links__082:
canonical: |
@@ -6775,6 +6838,7 @@
wysiwyg: |-
+ [foo]: /url1
06_07__inlines__links__083:
canonical: |
@@ -6782,6 +6846,7 @@
wysiwyg: |-
+ [foo]: /url1
06_07__inlines__links__084:
canonical: |
foo(not a link)
@@ -6789,6 +6854,7 @@
foo(not a link)
wysiwyg: |-
foo(not a link)
+ [foo]: /url1
06_07__inlines__links__085:
canonical: |
[foo]bar
@@ -6796,6 +6862,7 @@
[foo]bar
wysiwyg: |-
[foo]bar
+ [baz]: /url
06_07__inlines__links__086:
canonical: |
@@ -6803,6 +6870,8 @@
wysiwyg: |-
+ [baz]: /url1
+ [bar]: /url2
06_07__inlines__links__087:
canonical: |
[foo]bar
@@ -6810,6 +6879,8 @@
[foo]bar
wysiwyg: |-
[foo]bar
+ [baz]: /url1
+ [foo]: /url2
06_08__inlines__images__001:
canonical: |
![title foo](/url)
@@ -6824,6 +6895,7 @@
wysiwyg: |-
![train & tracks foo bar](train.jpg)
+ [foo *bar*]: train.jpg "train & tracks"
06_08__inlines__images__003:
canonical: |
![foo bar](/url2)
@@ -6845,6 +6917,7 @@
wysiwyg: |-
![train & tracks foo bar](train.jpg)
+ [foo *bar*]: train.jpg "train & tracks"
06_08__inlines__images__006:
canonical: |
![train & tracks foo bar](train.jpg)
@@ -6852,6 +6925,7 @@
wysiwyg: |-
![train & tracks foo bar](train.jpg)
+ [foobar]: train.jpg "train & tracks"
06_08__inlines__images__007:
canonical: |
![foo](train.jpg)
@@ -6887,6 +6961,7 @@
wysiwyg: |-
![foo](/url)
+ [bar]: /url
06_08__inlines__images__012:
canonical: |
![foo](/url)
@@ -6894,6 +6969,7 @@
wysiwyg: |-
![foo](/url)
+ [bar]: /url
06_08__inlines__images__013:
canonical: |
![title foo](/url)
@@ -6901,6 +6977,7 @@
wysiwyg: |-
![title foo](/url)
+ [foo]: /url "title"
06_08__inlines__images__014:
canonical: |
![title foo bar](/url)
@@ -6908,6 +6985,7 @@
wysiwyg: |-
![title foo bar](/url)
+ [*foo* bar]: /url "title"
06_08__inlines__images__015:
canonical: |
![title Foo](/url)
@@ -6915,6 +6993,7 @@
wysiwyg: |-
![title Foo](/url)
+ [foo]: /url "title"
06_08__inlines__images__016:
canonical: |
@@ -6925,6 +7004,7 @@
wysiwyg: |-
[]
+ [foo]: /url "title"
06_08__inlines__images__017:
canonical: |
![title foo](/url)
@@ -6932,6 +7012,7 @@
wysiwyg: |-
![title foo](/url)
+ [foo]: /url "title"
06_08__inlines__images__018:
canonical: |
![title foo bar](/url)
@@ -6939,6 +7020,7 @@
wysiwyg: |-
![title foo bar](/url)
+ [*foo* bar]: /url "title"
06_08__inlines__images__019:
canonical: |
![[foo]]
@@ -6956,6 +7038,7 @@
wysiwyg: |-
![title Foo](/url)
+ [foo]: /url "title"
06_08__inlines__images__021:
canonical: |
![foo]
@@ -6963,6 +7046,7 @@
![foo]
wysiwyg: |-
![foo]
+ [foo]: /url "title"
06_08__inlines__images__022:
canonical: |
!foo
@@ -6970,6 +7054,7 @@
!foo
wysiwyg: |-
!foo
+ [foo]: /url "title"
06_09__inlines__autolinks__001:
canonical: |
diff --git a/glfm_specification/example_snapshots/prosemirror_json.yml b/glfm_specification/example_snapshots/prosemirror_json.yml
index f770d341c42..7cb4757b368 100644
--- a/glfm_specification/example_snapshots/prosemirror_json.yml
+++ b/glfm_specification/example_snapshots/prosemirror_json.yml
@@ -3883,6 +3883,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -3910,6 +3924,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "the title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"the title\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -3937,6 +3965,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo*bar\\]",
+ "url": "my_(url)",
+ "title": "title (with parens)"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo*bar\\]]: my_(url) \"title (with parens)\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -3964,6 +4006,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo bar",
+ "url": "my url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo bar]: my url \"title\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -3991,6 +4047,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "\ntitle\nline1\nline2\n"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"\ntitle\nline1\nline2\n\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4051,6 +4121,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4102,6 +4186,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: "
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4153,6 +4251,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url\\bar*baz",
+ "title": "foo\"bar\\baz"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url\\bar*baz \"foo\"bar\\baz\""
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4200,6 +4312,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: url"
+ }
+ ]
}
]
}
@@ -4227,6 +4353,34 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "first",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: first"
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "second",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: second"
+ }
+ ]
}
]
}
@@ -4234,6 +4388,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4261,6 +4429,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "αγω",
+ "url": "/φου",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[αγω]: /φου"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4289,7 +4471,18 @@
"type": "doc",
"content": [
{
- "type": "paragraph"
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
}
]
}
@@ -4297,6 +4490,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4327,6 +4534,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4446,6 +4667,20 @@
}
]
},
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "blockquote",
"attrs": {
@@ -4469,6 +4704,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "heading",
"attrs": {
@@ -4508,6 +4757,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4539,6 +4802,48 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/foo-url",
+ "title": "foo"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /foo-url \"foo\""
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/bar-url",
+ "title": "bar"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /bar-url \"bar\""
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "baz",
+ "url": "/baz-url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[baz]: /baz-url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -4634,7 +4939,18 @@
},
"content": [
{
- "type": "paragraph"
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
}
]
}
@@ -4645,7 +4961,18 @@
"type": "doc",
"content": [
{
- "type": "paragraph"
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
}
]
}
@@ -9572,6 +9899,20 @@
"text": "b"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /url"
+ }
+ ]
}
]
},
@@ -10416,6 +10757,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/bar*",
+ "title": "ti*tle"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /bar* \"ti*tle\""
+ }
+ ]
}
]
}
@@ -10588,6 +10943,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/föö",
+ "title": "föö"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /föö \"föö\""
+ }
+ ]
}
]
}
@@ -15592,6 +15961,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -15619,6 +16002,20 @@
"text": "link [foo [bar]]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15646,6 +16043,20 @@
"text": "link [bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15739,6 +16150,20 @@
"text": "#"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15772,6 +16197,20 @@
]
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15823,6 +16262,20 @@
"text": "ref"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15886,6 +16339,20 @@
"text": "ref"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15917,6 +16384,20 @@
"text": "foo*"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15944,6 +16425,20 @@
"text": "foo *bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15959,6 +16454,20 @@
"text": "[foo "
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -15983,6 +16492,20 @@
"text": "][ref]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -16014,6 +16537,20 @@
"text": "http://example.com/?search=][ref]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref]: /uri"
+ }
+ ]
}
]
}
@@ -16041,6 +16578,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16072,6 +16623,20 @@
"text": " is a Russian word."
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "толпой",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[толпой]: /url"
+ }
+ ]
}
]
}
@@ -16079,6 +16644,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo bar",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo bar]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -16130,6 +16709,20 @@
"text": "bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16161,6 +16754,20 @@
"text": "bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16168,6 +16775,34 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url1"
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url2",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url2"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -16203,6 +16838,20 @@
"text": "[bar][foo!]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo!",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo!]: /url"
+ }
+ ]
}
]
}
@@ -16302,6 +16951,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "ref\\[",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[ref\\[]: /uri"
+ }
+ ]
}
]
}
@@ -16309,6 +16972,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar\\\\",
+ "url": "/uri",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar\\\\]: /uri"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -16404,6 +17081,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16450,6 +17141,20 @@
"text": " bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "*foo* bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[*foo* bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16477,6 +17182,20 @@
"text": "Foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16508,6 +17227,20 @@
"text": "\n[]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16535,6 +17268,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16581,6 +17328,20 @@
"text": " bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "*foo* bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[*foo* bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16635,6 +17396,20 @@
"text": "]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "*foo* bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[*foo* bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16666,6 +17441,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
}
]
}
@@ -16693,6 +17482,20 @@
"text": "Foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16724,6 +17527,20 @@
"text": " bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url"
+ }
+ ]
}
]
}
@@ -16739,6 +17556,20 @@
"text": "[foo]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -16746,6 +17577,20 @@
{
"type": "doc",
"content": [
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo*",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo*]: /url"
+ }
+ ]
+ },
{
"type": "paragraph",
"content": [
@@ -16797,6 +17642,34 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url1"
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url2",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url2"
+ }
+ ]
}
]
}
@@ -16824,6 +17697,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url1"
+ }
+ ]
}
]
}
@@ -16851,6 +17738,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url1"
+ }
+ ]
}
]
}
@@ -16882,6 +17783,20 @@
"text": "(not a link)"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url1"
+ }
+ ]
}
]
}
@@ -16913,6 +17828,20 @@
"text": "bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "baz",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[baz]: /url"
+ }
+ ]
}
]
}
@@ -16956,6 +17885,34 @@
"text": "baz"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "baz",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[baz]: /url1"
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url2",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url2"
+ }
+ ]
}
]
}
@@ -16987,6 +17944,34 @@
"text": "bar"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "baz",
+ "url": "/url1",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[baz]: /url1"
+ }
+ ]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url2",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url2"
+ }
+ ]
}
]
}
@@ -17029,6 +18014,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo *bar*",
+ "url": "train.jpg",
+ "title": "train & tracks"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo *bar*]: train.jpg \"train & tracks\""
+ }
+ ]
}
]
}
@@ -17092,6 +18091,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo *bar*",
+ "url": "train.jpg",
+ "title": "train & tracks"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo *bar*]: train.jpg \"train & tracks\""
+ }
+ ]
}
]
}
@@ -17113,6 +18126,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foobar",
+ "url": "train.jpg",
+ "title": "train & tracks"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foobar]: train.jpg \"train & tracks\""
+ }
+ ]
}
]
}
@@ -17222,6 +18249,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url"
+ }
+ ]
}
]
}
@@ -17243,6 +18284,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "bar",
+ "url": "/url",
+ "title": null
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[bar]: /url"
+ }
+ ]
}
]
}
@@ -17264,6 +18319,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17285,6 +18354,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "*foo* bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[*foo* bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17306,6 +18389,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17331,6 +18428,20 @@
"text": "\n[]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17352,6 +18463,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17373,6 +18498,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "*foo* bar",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[*foo* bar]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17418,6 +18557,20 @@
}
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17433,6 +18586,20 @@
"text": "![foo]"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
@@ -17464,6 +18631,20 @@
"text": "foo"
}
]
+ },
+ {
+ "type": "referenceDefinition",
+ "attrs": {
+ "identifier": "foo",
+ "url": "/url",
+ "title": "title"
+ },
+ "content": [
+ {
+ "type": "text",
+ "text": "[foo]: /url \"title\""
+ }
+ ]
}
]
}
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 0bc643b40a3..a71a1cc40e6 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -584,12 +584,12 @@ module API
end
end
- def log_artifact_size(file)
+ def log_artifact_file_size(file)
Gitlab::ApplicationContext.push(artifact: file.model)
end
def present_artifacts_file!(file, **args)
- log_artifact_size(file) if file
+ log_artifact_file_size(file) if file
present_carrierwave_file!(file, **args)
end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index 8c55652da43..5583c896803 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -41,8 +41,7 @@ module Gitlab
@unfolded = false
# Ensure items are collected in the the batch
- new_blob_lazy
- old_blob_lazy
+ add_blobs_to_batch_loader
end
def use_semantic_ipynb_diff?
@@ -382,6 +381,11 @@ module Gitlab
file_path.ends_with?('.ipynb')
end
+ def add_blobs_to_batch_loader
+ new_blob_lazy
+ old_blob_lazy
+ end
+
private
def diffable_by_attribute?
diff --git a/lib/gitlab/memory/reports_daemon.rb b/lib/gitlab/memory/reports_daemon.rb
index 779c19b3a1e..8788bee27a6 100644
--- a/lib/gitlab/memory/reports_daemon.rb
+++ b/lib/gitlab/memory/reports_daemon.rb
@@ -36,12 +36,16 @@ module Gitlab
sleep interval_with_jitter
reports.select(&:active?).each do |report|
- tms = Benchmark.measure do
- report.run
- end
+ start_monotonic_time = Gitlab::Metrics::System.monotonic_time
+ start_thread_cpu_time = Gitlab::Metrics::System.thread_cpu_time
- log_report(report_label(report), tms)
- @report_duration_counter.increment({ report: report_label(report) }, tms.real)
+ report.run
+
+ cpu_s = Gitlab::Metrics::System.thread_cpu_duration(start_thread_cpu_time)
+ duration_s = Gitlab::Metrics::System.monotonic_time - start_monotonic_time
+
+ log_report(label: report_label(report), cpu_s: cpu_s, duration_s: duration_s)
+ @report_duration_counter.increment({ report: report_label(report) }, duration_s)
sleep sleep_between_reports_s
end
@@ -58,15 +62,14 @@ module Gitlab
sleep_s + rand(sleep_max_delta_s)
end
- def log_report(report_label, tms)
+ def log_report(label:, duration_s:, cpu_s:)
Gitlab::AppLogger.info(
message: 'finished',
pid: $$,
worker_id: worker_id,
- perf_report: report_label,
- duration_s: tms.real.round(2),
- cpu_s: tms.utime.round(2),
- sys_cpu_s: tms.stime.round(2)
+ perf_report: label,
+ duration_s: duration_s.round(2),
+ cpu_s: cpu_s.round(2)
)
end
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index 40581bda81b..4647b19554d 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -114,6 +114,10 @@ module Gitlab
@categories ||= known_events.map { |event| event[:category] }.uniq
end
+ def categories_collected_from_metrics_definitions
+ CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS
+ end
+
# @param category [String] the category name
# @return [Array] list of event names for given category
def events_for_category(category)
@@ -164,7 +168,7 @@ module Gitlab
def categories_pending_migration
if ::Feature.enabled?(:use_redis_hll_instrumentation_classes)
- (categories - CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS)
+ (categories - categories_collected_from_metrics_definitions)
else
categories
end
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 88c9f44c165..d647573ec9f 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -1,25 +1,5 @@
---
# Compliance category
-- name: g_compliance_dashboard
- redis_slot: compliance
- category: compliance
- aggregation: weekly
-- name: g_compliance_audit_events
- category: compliance
- redis_slot: compliance
- aggregation: weekly
-- name: i_compliance_audit_events
- category: compliance
- redis_slot: compliance
- aggregation: weekly
-- name: i_compliance_credential_inventory
- category: compliance
- redis_slot: compliance
- aggregation: weekly
-- name: a_compliance_audit_events_api
- category: compliance
- redis_slot: compliance
- aggregation: weekly
- name: g_edit_by_web_ide
category: ide_edit
redis_slot: edit
diff --git a/lib/gitlab/utils/batch_loader.rb b/lib/gitlab/utils/batch_loader.rb
new file mode 100644
index 00000000000..67ade0633e2
--- /dev/null
+++ b/lib/gitlab/utils/batch_loader.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Utils
+ module BatchLoader
+ # Clears batched items under the specified batch key
+ # https://github.com/exAspArk/batch-loader#batch-key
+ def self.clear_key(batch_key)
+ return if ::BatchLoader::Executor.current.nil?
+
+ items_to_clear = ::BatchLoader::Executor.current.items_by_block.select do |k, v|
+ # The Hash key here is [source_location, batch_key], so we just check k[1]
+ k[1] == batch_key
+ end
+
+ items_to_clear.each do |k, v|
+ ::BatchLoader::Executor.current.items_by_block.delete(k)
+ ::BatchLoader::Executor.current.loaded_values_by_block.delete(k)
+ end
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 958d0a7489f..4dc897d3ddf 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11694,9 +11694,21 @@ msgstr ""
msgid "DastConfig|Enable DAST to automatically test for vulnerabilities in your project's running application, website, or API, in the CI/CD pipeline. Configuration changes must be applied to your .gitlab-ci.yml file to take effect. For details of all configuration options, see the %{linkStart}GitLab DAST documentation%{linkEnd}."
msgstr ""
+msgid "DastConfig|Enabled"
+msgstr ""
+
msgid "DastConfig|Generate code snippet"
msgstr ""
+msgid "DastConfig|Last scan triggered %{runTimeAgo} in pipeline "
+msgstr ""
+
+msgid "DastConfig|No previous scans found for this project"
+msgstr ""
+
+msgid "DastConfig|Not enabled"
+msgstr ""
+
msgid "DastProfiles|A passive scan monitors all HTTP messages (requests and responses) sent to the target. An active scan attacks the target to find potential vulnerabilities."
msgstr ""
@@ -28580,6 +28592,9 @@ msgstr ""
msgid "PipelineSchedules|None"
msgstr ""
+msgid "PipelineSchedules|Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?"
+msgstr ""
+
msgid "PipelineSchedules|Provide a short description for this pipeline"
msgstr ""
@@ -28592,6 +28607,9 @@ msgstr ""
msgid "PipelineSchedules|Variables"
msgstr ""
+msgid "PipelineSchedule|Take ownership to edit"
+msgstr ""
+
msgid "PipelineSource|API"
msgstr ""
diff --git a/package.json b/package.json
index 4ba8caee76e..d30b3f803c9 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,6 @@
"@tiptap/vue-2": "^2.0.0-beta.84",
"apollo-upload-client": "15.0.0",
"autosize": "^5.0.1",
- "aws-sdk": "^2.637.0",
"axios": "^0.24.0",
"babel-loader": "^8.2.5",
"babel-plugin-lodash": "^3.3.4",
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 59b2168c41a..edb07bbdce6 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -82,6 +82,22 @@ RSpec.describe Projects::CommitController do
expect(response).to be_successful
end
+ it 'only loads blobs in the current page' do
+ stub_feature_flags(async_commit_diff_files: false)
+ stub_const('Projects::CommitController::COMMIT_DIFFS_PER_PAGE', 1)
+
+ commit = project.commit('1a0b36b3cdad1d2ee32457c102a8c0b7056fa863')
+
+ expect_next_instance_of(Repository) do |repository|
+ # This commit contains 3 changed files but we expect only the blobs for the first one to be loaded
+ expect(repository).to receive(:blobs_at).with([[commit.id, '.gitignore']], anything).and_call_original
+ end
+
+ go(id: commit.id)
+
+ expect(response).to be_ok
+ end
+
shared_examples "export as" do |format|
it "does generally work" do
go(id: commit.id, format: format)
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index e6e0307d0ca..6ed6f7017e3 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -226,8 +226,8 @@ RSpec.describe Projects::CompareController do
context 'when page is valid' do
let(:from_project_id) { nil }
- let(:from_ref) { '08f22f25' }
- let(:to_ref) { '66eceea0' }
+ let(:from_ref) { '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9' }
+ let(:to_ref) { '5937ac0a7beb003549fc5fd26fc247adbce4a52e' }
let(:page) { 1 }
it 'shows the diff' do
@@ -237,6 +237,21 @@ RSpec.describe Projects::CompareController do
expect(assigns(:diffs).diff_files.first).to be_present
expect(assigns(:commits).length).to be >= 1
end
+
+ it 'only loads blobs in the current page' do
+ stub_const('Projects::CompareController::COMMIT_DIFFS_PER_PAGE', 1)
+
+ expect_next_instance_of(Repository) do |repository|
+ # This comparison contains 4 changed files but we expect only the blobs for the first one to be loaded
+ expect(repository).to receive(:blobs_at).with(
+ contain_exactly([from_ref, '.gitmodules'], [to_ref, '.gitmodules']), anything
+ ).and_call_original
+ end
+
+ show_request
+
+ expect(response).to be_successful
+ end
end
context 'when page is not valid' do
diff --git a/spec/events/projects/project_transfered_event_spec.rb b/spec/events/projects/project_transfered_event_spec.rb
new file mode 100644
index 00000000000..51c8bf4765f
--- /dev/null
+++ b/spec/events/projects/project_transfered_event_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::ProjectTransferedEvent do
+ where(:data, :valid) do
+ valid_event = {
+ project_id: 1,
+ old_namespace_id: 2,
+ old_root_namespace_id: 3,
+ new_namespace_id: 4,
+ new_root_namespace_id: 5
+ }
+
+ # All combinations of missing keys
+ with_missing_keys = 0.upto(valid_event.size - 1)
+ .flat_map { |size| valid_event.keys.combination(size).to_a }
+ .map { |keys| [valid_event.slice(*keys), false] }
+
+ [
+ [valid_event, true],
+ *with_missing_keys,
+ [{ project_id: 'foo', namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: 'foo' }, false],
+ [{ project_id: [], namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: [] }, false],
+ [{ project_id: {}, namespace_id: 2 }, false],
+ [{ project_id: 1, namespace_id: {} }, false],
+ ['foo', false],
+ [123, false],
+ [[], false]
+ ]
+ end
+
+ with_them do
+ it 'validates data' do
+ constructor = -> { described_class.new(data: data) }
+
+ if valid
+ expect { constructor.call }.not_to raise_error
+ else
+ expect { constructor.call }.to raise_error(Gitlab::EventStore::InvalidEvent)
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index 8cf6d5bd29b..0711a30e974 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -109,7 +109,12 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'changes ownership of the pipeline' do
- click_link 'Take ownership'
+ click_button 'Take ownership'
+
+ page.within('#pipeline-take-ownership-modal') do
+ click_link 'Take ownership'
+ end
+
page.within('.pipeline-schedule-table-row') do
expect(page).not_to have_content('No owner')
expect(page).to have_link('Sidney Jones')
diff --git a/spec/frontend/content_editor/remark_markdown_processing_spec.js b/spec/frontend/content_editor/remark_markdown_processing_spec.js
index 48adceaab58..ddf49a4c18e 100644
--- a/spec/frontend/content_editor/remark_markdown_processing_spec.js
+++ b/spec/frontend/content_editor/remark_markdown_processing_spec.js
@@ -15,6 +15,7 @@ import Link from '~/content_editor/extensions/link';
import ListItem from '~/content_editor/extensions/list_item';
import OrderedList from '~/content_editor/extensions/ordered_list';
import Paragraph from '~/content_editor/extensions/paragraph';
+import ReferenceDefinition from '~/content_editor/extensions/reference_definition';
import Sourcemap from '~/content_editor/extensions/sourcemap';
import Strike from '~/content_editor/extensions/strike';
import Table from '~/content_editor/extensions/table';
@@ -45,6 +46,7 @@ const tiptapEditor = createTestEditor({
Link,
ListItem,
OrderedList,
+ ReferenceDefinition,
Sourcemap,
Strike,
Table,
@@ -78,6 +80,7 @@ const {
listItem,
orderedList,
pre,
+ referenceDefinition,
strike,
table,
tableRow,
@@ -105,6 +108,7 @@ const {
listItem: { nodeType: ListItem.name },
orderedList: { nodeType: OrderedList.name },
paragraph: { nodeType: Paragraph.name },
+ referenceDefinition: { nodeType: ReferenceDefinition.name },
strike: { nodeType: Strike.name },
table: { nodeType: Table.name },
tableCell: { nodeType: TableCell.name },
@@ -1079,6 +1083,32 @@ _world_.
),
),
},
+ {
+ markdown: `
+[GitLab][gitlab-url]
+
+[gitlab-url]: https://gitlab.com "GitLab"
+
+ `,
+ expectedDoc: doc(
+ paragraph(
+ source('[GitLab][gitlab-url]'),
+ link(
+ { ...source('[GitLab][gitlab-url]'), href: 'https://gitlab.com', title: 'GitLab' },
+ 'GitLab',
+ ),
+ ),
+ referenceDefinition(
+ {
+ ...source('[gitlab-url]: https://gitlab.com "GitLab"'),
+ identifier: 'gitlab-url',
+ url: 'https://gitlab.com',
+ title: 'GitLab',
+ },
+ '[gitlab-url]: https://gitlab.com "GitLab"',
+ ),
+ ),
+ },
];
const runOnly = examples.find((example) => example.only === true);
diff --git a/spec/frontend/content_editor/render_html_and_json_for_all_examples.js b/spec/frontend/content_editor/render_html_and_json_for_all_examples.js
index 116a26cf7d5..782158810dd 100644
--- a/spec/frontend/content_editor/render_html_and_json_for_all_examples.js
+++ b/spec/frontend/content_editor/render_html_and_json_for_all_examples.js
@@ -26,6 +26,7 @@ import Italic from '~/content_editor/extensions/italic';
import Link from '~/content_editor/extensions/link';
import ListItem from '~/content_editor/extensions/list_item';
import OrderedList from '~/content_editor/extensions/ordered_list';
+import ReferenceDefinition from '~/content_editor/extensions/reference_definition';
import Strike from '~/content_editor/extensions/strike';
import Table from '~/content_editor/extensions/table';
import TableCell from '~/content_editor/extensions/table_cell';
@@ -63,6 +64,7 @@ const tiptapEditor = createTestEditor({
Link,
ListItem,
OrderedList,
+ ReferenceDefinition,
Strike,
Table,
TableCell,
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index 29f1f219971..422eb3f311b 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -24,6 +24,7 @@ import Link from '~/content_editor/extensions/link';
import ListItem from '~/content_editor/extensions/list_item';
import OrderedList from '~/content_editor/extensions/ordered_list';
import Paragraph from '~/content_editor/extensions/paragraph';
+import ReferenceDefinition from '~/content_editor/extensions/reference_definition';
import Sourcemap from '~/content_editor/extensions/sourcemap';
import Strike from '~/content_editor/extensions/strike';
import Table from '~/content_editor/extensions/table';
@@ -63,6 +64,7 @@ const tiptapEditor = createTestEditor({
Link,
ListItem,
OrderedList,
+ ReferenceDefinition,
Sourcemap,
Strike,
Table,
@@ -104,6 +106,7 @@ const {
listItem,
orderedList,
paragraph,
+ referenceDefinition,
strike,
table,
tableCell,
@@ -139,6 +142,7 @@ const {
listItem: { nodeType: ListItem.name },
orderedList: { nodeType: OrderedList.name },
paragraph: { nodeType: Paragraph.name },
+ referenceDefinition: { nodeType: ReferenceDefinition.name },
strike: { markType: Strike.name },
table: { nodeType: Table.name },
tableCell: { nodeType: TableCell.name },
@@ -1163,6 +1167,38 @@ Oranges are orange [^1]
);
});
+ it('correctly serializes reference definition', () => {
+ expect(
+ serialize(
+ referenceDefinition('[gitlab]: https://gitlab.com'),
+ referenceDefinition('[foobar]: foobar.com'),
+ ),
+ ).toBe(
+ `
+[gitlab]: https://gitlab.com
+[foobar]: foobar.com`.trimLeft(),
+ );
+ });
+
+ it('correctly adds a space between a reference definition and a block content', () => {
+ expect(
+ serialize(
+ paragraph('paragraph'),
+ referenceDefinition('[gitlab]: https://gitlab.com'),
+ referenceDefinition('[foobar]: foobar.com'),
+ heading({ level: 2 }, 'heading'),
+ ),
+ ).toBe(
+ `
+paragraph
+
+[gitlab]: https://gitlab.com
+[foobar]: foobar.com
+
+## heading`.trimLeft(),
+ );
+ });
+
const defaultEditAction = (initialContent) => {
tiptapEditor.chain().setContent(initialContent.toJSON()).insertContent(' modified').run();
};
diff --git a/spec/frontend/lib/gfm/index_spec.js b/spec/frontend/lib/gfm/index_spec.js
index b722315d63a..624744b9a92 100644
--- a/spec/frontend/lib/gfm/index_spec.js
+++ b/spec/frontend/lib/gfm/index_spec.js
@@ -96,28 +96,60 @@ describe('gfm', () => {
);
});
});
- });
- describe('when skipping the rendering of code blocks', () => {
- it('transforms code nodes into codeblock html tags', async () => {
- const result = await markdownToAST(
- `
+ describe('when skipping the rendering of code blocks', () => {
+ it('transforms code nodes into codeblock html tags', async () => {
+ const result = await markdownToAST(
+ `
\`\`\`javascript
console.log('Hola');
\`\`\`\
`,
- ['code'],
- );
+ ['code'],
+ );
- expectInRoot(
- result,
- expect.objectContaining({
- tagName: 'codeblock',
- properties: {
- language: 'javascript',
- },
- }),
- );
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ tagName: 'codeblock',
+ properties: {
+ language: 'javascript',
+ },
+ }),
+ );
+ });
+ });
+
+ describe('when skipping the rendering of reference definitions', () => {
+ it('transforms code nodes into codeblock html tags', async () => {
+ const result = await markdownToAST(
+ `
+[gitlab][gitlab]
+
+[gitlab]: https://gitlab.com "GitLab"
+ `,
+ ['definition'],
+ );
+
+ expectInRoot(
+ result,
+ expect.objectContaining({
+ type: 'element',
+ tagName: 'referencedefinition',
+ properties: {
+ identifier: 'gitlab',
+ title: 'GitLab',
+ url: 'https://gitlab.com',
+ },
+ children: [
+ {
+ type: 'text',
+ value: '[gitlab]: https://gitlab.com "GitLab"',
+ },
+ ],
+ }),
+ );
+ });
});
});
});
diff --git a/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js b/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js
new file mode 100644
index 00000000000..23bfdef13c6
--- /dev/null
+++ b/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js
@@ -0,0 +1,54 @@
+import { GlModal } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import TakeOwnershipModal from '~/pipeline_schedules/components/take_ownership_modal.vue';
+
+describe('Take ownership modal', () => {
+ let wrapper;
+ const url = `/root/job-log-tester/-/pipeline_schedules/3/take_ownership`;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(TakeOwnershipModal, {
+ propsData: {
+ ownershipUrl: url,
+ ...props,
+ },
+ });
+ };
+
+ const findModal = () => wrapper.findComponent(GlModal);
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('has a primary action set to a url and a post data-method', () => {
+ const actionPrimary = findModal().props('actionPrimary');
+
+ expect(actionPrimary.attributes).toEqual(
+ expect.objectContaining([
+ {
+ category: 'primary',
+ variant: 'confirm',
+ href: url,
+ 'data-method': 'post',
+ },
+ ]),
+ );
+ });
+
+ it('shows a take ownership message', () => {
+ expect(findModal().text()).toBe(
+ 'Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?',
+ );
+ });
+
+ it('emits the cancel event when clicking on cancel', async () => {
+ findModal().vm.$emit('cancel');
+
+ expect(findModal().emitted('cancel')).toBeTruthy();
+ });
+});
diff --git a/spec/frontend_integration/content_editor/content_editor_integration_spec.js b/spec/frontend_integration/content_editor/content_editor_integration_spec.js
index 89b8d8d6d94..4d400a383e3 100644
--- a/spec/frontend_integration/content_editor/content_editor_integration_spec.js
+++ b/spec/frontend_integration/content_editor/content_editor_integration_spec.js
@@ -61,29 +61,38 @@ describe('content_editor', () => {
});
});
- it('renders footnote ids alongside the footnote definition', async () => {
- buildWrapper();
+ describe('when preserveUnchangedMarkdown feature flag is enabled', () => {
+ beforeEach(() => {
+ gon.features = { preserveUnchangedMarkdown: true };
+ });
+ afterEach(() => {
+ gon.features = { preserveUnchangedMarkdown: false };
+ });
- renderMarkdown.mockResolvedValue(`
-
- This reference tag is a mix of letters and numbers. 2
-
-
-
- -
-
This is another footnote. ↩
-
-
-
+ it('processes and renders footnote ids alongside the footnote definition', async () => {
+ buildWrapper();
+
+ await contentEditorService.setSerializedContent(`
+This reference tag is a mix of letters and numbers [^footnote].
+
+[^footnote]: This is another footnote.
`);
+ await nextTick();
- await contentEditorService.setSerializedContent(`
- This reference tag is a mix of letters and numbers [^footnote].
+ expect(wrapper.text()).toContain('footnote: This is another footnote');
+ });
- [^footnote]: This is another footnote.
- `);
- await nextTick();
+ it('processes and displays reference definitions', async () => {
+ buildWrapper();
- expect(wrapper.text()).toContain('footnote: This is another footnote');
+ await contentEditorService.setSerializedContent(`
+[GitLab][gitlab]
+
+[gitlab]: https://gitlab.com
+ `);
+ await nextTick();
+
+ expect(wrapper.find('pre').text()).toContain('[gitlab]: https://gitlab.com');
+ });
});
});
diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb
index b5b572e9719..b27954de0d4 100644
--- a/spec/helpers/commits_helper_spec.rb
+++ b/spec/helpers/commits_helper_spec.rb
@@ -153,16 +153,24 @@ RSpec.describe CommitsHelper do
end
describe "#conditionally_paginate_diff_files" do
- let(:diffs_collection) { instance_double(Gitlab::Diff::FileCollection::Commit, diff_files: diff_files) }
- let(:diff_files) { Gitlab::Git::DiffCollection.new(files) }
- let(:page) { nil }
+ let_it_be(:project) { create(:project, :repository) }
+ let(:diffs_collection) { instance_double(Gitlab::Diff::FileCollection::Commit, diff_files: decorated_diff_files, project: project) }
+ let(:decorated_diff_files) do
+ diffs.map do |diff|
+ Gitlab::Diff::File.new(diff, repository: project.repository)
+ end
+ end
+
+ let(:diffs) { Gitlab::Git::DiffCollection.new(files) }
let(:files) do
Array.new(85).map do
{ too_large: false, diff: "" }
end
end
+ let(:page) { nil }
+
subject { helper.conditionally_paginate_diff_files(diffs_collection, paginate: paginate, page: page, per: Projects::CommitController::COMMIT_DIFFS_PER_PAGE) }
before do
@@ -203,8 +211,8 @@ RSpec.describe CommitsHelper do
context "pagination is disabled" do
let(:paginate) { false }
- it "returns a standard DiffCollection" do
- expect(subject).to be_a(Gitlab::Git::DiffCollection)
+ it "returns the unpaginated collection" do
+ expect(subject.size).to eq(85)
end
end
end
diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb
index 5f5e7f211f8..b160f322fb8 100644
--- a/spec/lib/gitlab/auth/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb
@@ -727,6 +727,7 @@ RSpec.describe Gitlab::Auth::OAuth::User do
context 'signup with linked omniauth and LDAP account' do
before do
stub_omniauth_config(auto_link_ldap_user: true)
+ stub_ldap_setting(enabled: true)
allow(ldap_user).to receive(:uid) { uid }
allow(ldap_user).to receive(:username) { uid }
allow(ldap_user).to receive(:email) { ['johndoe@example.com', 'john2@example.com'] }
diff --git a/spec/lib/gitlab/memory/reports_daemon_spec.rb b/spec/lib/gitlab/memory/reports_daemon_spec.rb
index 75334834c5b..6af317f2771 100644
--- a/spec/lib/gitlab/memory/reports_daemon_spec.rb
+++ b/spec/lib/gitlab/memory/reports_daemon_spec.rb
@@ -32,7 +32,6 @@ RSpec.describe Gitlab::Memory::ReportsDaemon do
hash_including(
:duration_s,
:cpu_s,
- :sys_cpu_s,
message: 'finished',
pid: Process.pid,
worker_id: 'worker_1',
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index 54d49b432f4..d45ee0113e8 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
stub_feature_flags(use_redis_hll_instrumentation_classes: true)
expect(described_class.unique_events_data.keys)
- .not_to include(*described_class::CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS)
+ .not_to include(*described_class.categories_collected_from_metrics_definitions)
end
end
@@ -91,18 +91,17 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
stub_feature_flags(use_redis_hll_instrumentation_classes: false)
expect(described_class.unique_events_data.keys)
- .to include(*described_class::CATEGORIES_COLLECTED_FROM_METRICS_DEFINITIONS)
+ .to include(*described_class.categories_collected_from_metrics_definitions)
end
end
end
end
describe '.categories' do
- it 'gets all unique category names' do
- expect(described_class.categories).to contain_exactly(
+ it 'gets CE unique category names' do
+ expect(described_class.categories).to include(
'deploy_token_packages',
'user_packages',
- 'compliance',
'ecosystem',
'analytics',
'ide_edit',
@@ -483,7 +482,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
describe '.weekly_redis_keys' do
using RSpec::Parameterized::TableSyntax
- let(:weekly_event) { 'g_compliance_dashboard' }
+ let(:weekly_event) { 'i_search_total' }
let(:redis_event) { described_class.send(:event_for, weekly_event) }
subject(:weekly_redis_keys) { described_class.send(:weekly_redis_keys, events: [redis_event], start_date: DateTime.parse(start_date), end_date: DateTime.parse(end_date)) }
@@ -493,13 +492,13 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'2020-12-21' | '2020-12-20' | []
'2020-12-21' | '2020-11-21' | []
'2021-01-01' | '2020-12-28' | []
- '2020-12-21' | '2020-12-28' | ['g_{compliance}_dashboard-2020-52']
- '2020-12-21' | '2021-01-01' | ['g_{compliance}_dashboard-2020-52']
- '2020-12-27' | '2021-01-01' | ['g_{compliance}_dashboard-2020-52']
- '2020-12-26' | '2021-01-04' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53']
- '2020-12-26' | '2021-01-11' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01']
- '2020-12-26' | '2021-01-17' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01']
- '2020-12-26' | '2021-01-18' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01', 'g_{compliance}_dashboard-2021-02']
+ '2020-12-21' | '2020-12-28' | ['i_{search}_total-2020-52']
+ '2020-12-21' | '2021-01-01' | ['i_{search}_total-2020-52']
+ '2020-12-27' | '2021-01-01' | ['i_{search}_total-2020-52']
+ '2020-12-26' | '2021-01-04' | ['i_{search}_total-2020-52', 'i_{search}_total-2020-53']
+ '2020-12-26' | '2021-01-11' | ['i_{search}_total-2020-52', 'i_{search}_total-2020-53', 'i_{search}_total-2021-01']
+ '2020-12-26' | '2021-01-17' | ['i_{search}_total-2020-52', 'i_{search}_total-2020-53', 'i_{search}_total-2021-01']
+ '2020-12-26' | '2021-01-18' | ['i_{search}_total-2020-52', 'i_{search}_total-2020-53', 'i_{search}_total-2021-01', 'i_{search}_total-2021-02']
end
with_them do
diff --git a/spec/lib/gitlab/utils/batch_loader_spec.rb b/spec/lib/gitlab/utils/batch_loader_spec.rb
new file mode 100644
index 00000000000..c1f6d6df07a
--- /dev/null
+++ b/spec/lib/gitlab/utils/batch_loader_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'batch-loader'
+
+RSpec.describe Gitlab::Utils::BatchLoader do
+ let(:stubbed_loader) do
+ double( # rubocop:disable RSpec/VerifiedDoubles
+ 'Loader',
+ load_lazy_method: [],
+ load_lazy_method_same_batch_key: [],
+ load_lazy_method_other_batch_key: []
+ )
+ end
+
+ let(:test_module) do
+ Module.new do
+ def self.lazy_method(id)
+ BatchLoader.for(id).batch(key: :my_batch_name) do |ids, loader|
+ stubbed_loader.load_lazy_method(ids)
+
+ ids.each { |id| loader.call(id, id) }
+ end
+ end
+
+ def self.lazy_method_same_batch_key(id)
+ BatchLoader.for(id).batch(key: :my_batch_name) do |ids, loader|
+ stubbed_loader.load_lazy_method_same_batch_key(ids)
+
+ ids.each { |id| loader.call(id, id) }
+ end
+ end
+
+ def self.lazy_method_other_batch_key(id)
+ BatchLoader.for(id).batch(key: :other_batch_name) do |ids, loader|
+ stubbed_loader.load_lazy_method_other_batch_key(ids)
+
+ ids.each { |id| loader.call(id, id) }
+ end
+ end
+ end
+ end
+
+ before do
+ BatchLoader::Executor.clear_current
+ allow(test_module).to receive(:stubbed_loader).and_return(stubbed_loader)
+ end
+
+ describe '.clear_key' do
+ it 'clears batched items which match the specified batch key' do
+ test_module.lazy_method(1)
+ test_module.lazy_method_same_batch_key(2)
+ test_module.lazy_method_other_batch_key(3)
+
+ described_class.clear_key(:my_batch_name)
+
+ test_module.lazy_method(4).to_i
+ test_module.lazy_method_same_batch_key(5).to_i
+ test_module.lazy_method_other_batch_key(6).to_i
+
+ expect(stubbed_loader).to have_received(:load_lazy_method).with([4])
+ expect(stubbed_loader).to have_received(:load_lazy_method_same_batch_key).with([5])
+ expect(stubbed_loader).to have_received(:load_lazy_method_other_batch_key).with([3, 6])
+ end
+
+ it 'clears loaded values which match the specified batch key' do
+ test_module.lazy_method(1).to_i
+ test_module.lazy_method_same_batch_key(2).to_i
+ test_module.lazy_method_other_batch_key(3).to_i
+
+ described_class.clear_key(:my_batch_name)
+
+ test_module.lazy_method(1).to_i
+ test_module.lazy_method_same_batch_key(2).to_i
+ test_module.lazy_method_other_batch_key(3).to_i
+
+ expect(stubbed_loader).to have_received(:load_lazy_method).with([1]).twice
+ expect(stubbed_loader).to have_received(:load_lazy_method_same_batch_key).with([2]).twice
+ expect(stubbed_loader).to have_received(:load_lazy_method_other_batch_key).with([3])
+ end
+ end
+end
diff --git a/spec/requests/api/ci/runner/jobs_artifacts_spec.rb b/spec/requests/api/ci/runner/jobs_artifacts_spec.rb
index 5767fa4326e..cd8c3dd2806 100644
--- a/spec/requests/api/ci/runner/jobs_artifacts_spec.rb
+++ b/spec/requests/api/ci/runner/jobs_artifacts_spec.rb
@@ -844,7 +844,13 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
'Content-Disposition' => %q(attachment; filename="ci_build_artifacts.zip"; filename*=UTF-8''ci_build_artifacts.zip) }
end
+ before do
+ allow(Gitlab::ApplicationContext).to receive(:push).and_call_original
+ end
+
it 'downloads artifacts' do
+ expect(Gitlab::ApplicationContext).to receive(:push).with(artifact: an_instance_of(Ci::JobArtifact)).once.and_call_original
+
download_artifact
expect(response).to have_gitlab_http_status(:ok)
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index ecf9f92d74f..49073931c02 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -64,6 +64,28 @@ RSpec.describe Projects::TransferService do
expect(project.namespace).to eq(group)
end
+ context 'EventStore' do
+ let(:group) do
+ create(:group, :nested).tap { |g| g.add_owner(user) }
+ end
+
+ let(:target) do
+ create(:group, :nested).tap { |g| g.add_owner(user) }
+ end
+
+ it 'publishes a ProjectTransferedEvent' do
+ expect { execute_transfer }
+ .to publish_event(Projects::ProjectTransferedEvent)
+ .with(
+ project_id: kind_of(Numeric),
+ old_namespace_id: group.id,
+ old_root_namespace_id: group.parent_id,
+ new_namespace_id: target.id,
+ new_root_namespace_id: target.parent_id
+ )
+ end
+ end
+
context 'when project has an associated project namespace' do
it 'keeps project namespace in sync with project' do
transfer_result = execute_transfer
@@ -299,6 +321,11 @@ RSpec.describe Projects::TransferService do
)
end
+ it 'does not publish a ProjectTransferedEvent' do
+ expect { attempt_project_transfer }
+ .not_to publish_event(Projects::ProjectTransferedEvent)
+ end
+
context 'when project has pending builds', :sidekiq_inline do
let!(:other_project) { create(:project) }
let!(:pending_build) { create(:ci_pending_build, project: project.reload) }
diff --git a/spec/services/protected_branches/cache_service_spec.rb b/spec/services/protected_branches/cache_service_spec.rb
new file mode 100644
index 00000000000..4c05d6dcbd9
--- /dev/null
+++ b/spec/services/protected_branches/cache_service_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+# rubocop:disable Style/RedundantFetchBlock
+#
+require 'spec_helper'
+
+RSpec.describe ProtectedBranches::CacheService, :clean_gitlab_redis_cache do
+ subject(:service) { described_class.new(project, user) }
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { project.first_owner }
+
+ let(:immediate_expiration) { 0 }
+
+ describe '#fetch' do
+ it 'caches the value' do
+ expect(service.fetch('main') { true }).to eq(true)
+ expect(service.fetch('not-found') { false }).to eq(false)
+
+ # Uses cached values
+ expect(service.fetch('main') { false }).to eq(true)
+ expect(service.fetch('not-found') { true }).to eq(false)
+ end
+
+ it 'sets expiry on the key' do
+ stub_const("#{described_class.name}::CACHE_EXPIRE_IN", immediate_expiration)
+
+ expect(service.fetch('main') { true }).to eq(true)
+ expect(service.fetch('not-found') { false }).to eq(false)
+
+ expect(service.fetch('main') { false }).to eq(false)
+ expect(service.fetch('not-found') { true }).to eq(true)
+ end
+
+ it 'does not set an expiry on the key after the hash is already created' do
+ expect(service.fetch('main') { true }).to eq(true)
+
+ stub_const("#{described_class.name}::CACHE_EXPIRE_IN", immediate_expiration)
+
+ expect(service.fetch('not-found') { false }).to eq(false)
+
+ expect(service.fetch('main') { false }).to eq(true)
+ expect(service.fetch('not-found') { true }).to eq(false)
+ end
+
+ context 'when CACHE_LIMIT is exceeded' do
+ before do
+ stub_const("#{described_class.name}::CACHE_LIMIT", 2)
+ end
+
+ it 'recreates cache' do
+ expect(service.fetch('main') { true }).to eq(true)
+ expect(service.fetch('not-found') { false }).to eq(false)
+
+ # Uses cached values
+ expect(service.fetch('main') { false }).to eq(true)
+ expect(service.fetch('not-found') { true }).to eq(false)
+
+ # Overflow
+ expect(service.fetch('new-branch') { true }).to eq(true)
+
+ # Refreshes values
+ expect(service.fetch('main') { false }).to eq(false)
+ expect(service.fetch('not-found') { true }).to eq(true)
+ end
+ end
+ end
+
+ describe '#refresh' do
+ it 'clears cached values' do
+ expect(service.fetch('main') { true }).to eq(true)
+ expect(service.fetch('not-found') { false }).to eq(false)
+
+ service.refresh
+
+ # Recreates cache
+ expect(service.fetch('main') { false }).to eq(false)
+ expect(service.fetch('not-found') { true }).to eq(true)
+ end
+ end
+end
+# rubocop:enable Style/RedundantFetchBlock
diff --git a/spec/services/protected_branches/create_service_spec.rb b/spec/services/protected_branches/create_service_spec.rb
index 3ac42d41377..5a371b68f0c 100644
--- a/spec/services/protected_branches/create_service_spec.rb
+++ b/spec/services/protected_branches/create_service_spec.rb
@@ -24,6 +24,14 @@ RSpec.describe ProtectedBranches::CreateService do
expect(project.protected_branches.last.merge_access_levels.map(&:access_level)).to eq([Gitlab::Access::MAINTAINER])
end
+ it 'refreshes the cache' do
+ expect_next_instance_of(ProtectedBranches::CacheService) do |cache_service|
+ expect(cache_service).to receive(:refresh)
+ end
+
+ service.execute
+ end
+
context 'when protecting a branch with a name that contains HTML tags' do
let(:name) { 'foobar<\b>' }
diff --git a/spec/services/protected_branches/destroy_service_spec.rb b/spec/services/protected_branches/destroy_service_spec.rb
index 4e55c72f312..492b91dbb8b 100644
--- a/spec/services/protected_branches/destroy_service_spec.rb
+++ b/spec/services/protected_branches/destroy_service_spec.rb
@@ -16,6 +16,14 @@ RSpec.describe ProtectedBranches::DestroyService do
expect(protected_branch).to be_destroyed
end
+ it 'refreshes the cache' do
+ expect_next_instance_of(ProtectedBranches::CacheService) do |cache_service|
+ expect(cache_service).to receive(:refresh)
+ end
+
+ service.execute(protected_branch)
+ end
+
context 'when a policy restricts rule deletion' do
before do
policy = instance_double(ProtectedBranchPolicy, allowed?: false)
diff --git a/spec/services/protected_branches/update_service_spec.rb b/spec/services/protected_branches/update_service_spec.rb
index 4405af35c37..ee61382bd89 100644
--- a/spec/services/protected_branches/update_service_spec.rb
+++ b/spec/services/protected_branches/update_service_spec.rb
@@ -18,6 +18,14 @@ RSpec.describe ProtectedBranches::UpdateService do
expect(result.reload.name).to eq(params[:name])
end
+ it 'refreshes the cache' do
+ expect_next_instance_of(ProtectedBranches::CacheService) do |cache_service|
+ expect(cache_service).to receive(:refresh)
+ end
+
+ result
+ end
+
context 'when updating name of a protected branch to one that contains HTML tags' do
let(:new_name) { 'foobar<\b>' }
let(:result) { service.execute(protected_branch) }
diff --git a/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb b/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb
index e650e183bc8..37c9908af1d 100644
--- a/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb
+++ b/spec/views/projects/pipeline_schedules/_pipeline_schedule.html.haml_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'projects/pipeline_schedules/_pipeline_schedule' do
it 'non-owner can take ownership of pipeline' do
render
- expect(rendered).to have_link('Take ownership')
+ expect(rendered).to have_button('Take ownership')
end
end
@@ -42,7 +42,7 @@ RSpec.describe 'projects/pipeline_schedules/_pipeline_schedule' do
it 'owner cannot take ownership of pipeline' do
render
- expect(rendered).not_to have_link('Take ownership')
+ expect(rendered).not_to have_button('Take ownership')
end
end
end
diff --git a/yarn.lock b/yarn.lock
index ca755429f19..4d7aae26d5b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2744,21 +2744,6 @@ autosize@^5.0.1:
resolved "https://registry.yarnpkg.com/autosize/-/autosize-5.0.1.tgz#ed269b0fa9b7eb47627048a1bb3299e99e003a0f"
integrity sha512-UIWUlE4TOVPNNj2jjrU39wI4hEYbneUypEqcyRmRFIx5CC2gNdg3rQr+Zh7/3h6egbBvm33TDQjNQKtj9Tk1HA==
-aws-sdk@^2.637.0:
- version "2.637.0"
- resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.637.0.tgz#810e25e53acf2250d35fc74498f9d4492e154217"
- integrity sha512-e7EYX5rNtQyEaleQylUtLSNKXOmvOwfifQ4bYkfF80mFsVI3DSydczLHXrqPzXoEJaS/GI/9HqVnlQcPs6Q3ew==
- dependencies:
- buffer "4.9.1"
- events "1.1.1"
- ieee754 "1.1.13"
- jmespath "0.15.0"
- querystring "0.2.0"
- sax "1.2.1"
- url "0.10.3"
- uuid "3.3.2"
- xml2js "0.4.19"
-
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"
@@ -3137,7 +3122,7 @@ buffer-xor@^1.0.3:
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
-buffer@4.9.1, buffer@^4.3.0:
+buffer@^4.3.0:
version "4.9.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
@@ -5444,11 +5429,6 @@ eventemitter3@^4.0.0:
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
-events@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
- integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
-
events@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
@@ -6582,7 +6562,7 @@ icss-utils@^4.1.0:
dependencies:
postcss "^7.0.14"
-ieee754@1.1.13, ieee754@^1.1.13, ieee754@^1.1.4:
+ieee754@^1.1.13, ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
@@ -7528,11 +7508,6 @@ jest@^26.5.2:
import-local "^3.0.2"
jest-cli "^26.5.2"
-jmespath@0.15.0:
- version "0.15.0"
- resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
- integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
-
jquery.caret@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/jquery.caret/-/jquery.caret-0.3.1.tgz#9c093318faf327eff322e826ca9f3241368bc7b8"
@@ -10598,11 +10573,6 @@ sass@^1.49.9:
immutable "^4.0.0"
source-map-js ">=0.6.2 <2.0.0"
-sax@1.2.1, sax@>=0.6.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
- integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=
-
saxes@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
@@ -12004,14 +11974,6 @@ url-loader@^4.1.1:
mime-types "^2.1.27"
schema-utils "^3.0.0"
-url@0.10.3:
- version "0.10.3"
- resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64"
- integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=
- dependencies:
- punycode "1.3.2"
- querystring "0.2.0"
-
url@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
@@ -12049,11 +12011,6 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-uuid@3.3.2:
- version "3.3.2"
- resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
- integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
-
uuid@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
@@ -12634,24 +12591,11 @@ xml-name-validator@^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==
-xml2js@0.4.19:
- version "0.4.19"
- resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
- integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
- dependencies:
- sax ">=0.6.0"
- xmlbuilder "~9.0.1"
-
xml@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
-xmlbuilder@~9.0.1:
- version "9.0.7"
- resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
- integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
-
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"