summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/framework/typography.scss1
-rw-r--r--app/models/container_repository.rb3
-rw-r--r--app/views/admin/services/index.html.haml2
-rw-r--r--changelogs/unreleased/empty-task-list-alignment.yml4
-rw-r--r--changelogs/unreleased/fix-trace-seeking.yml4
-rw-r--r--lib/banzai/filter/issuable_state_filter.rb4
-rw-r--r--lib/container_registry/path.rb4
-rw-r--r--lib/gitlab/ci/trace/stream.rb7
-rw-r--r--spec/fixtures/trace/ansi-sequence-and-unicode5
-rw-r--r--spec/lib/banzai/filter/issuable_state_filter_spec.rb43
-rw-r--r--spec/lib/container_registry/path_spec.rb22
-rw-r--r--spec/lib/gitlab/ci/trace/stream_spec.rb28
-rw-r--r--spec/models/container_repository_spec.rb14
-rw-r--r--spec/support/fixture_helpers.rb7
-rw-r--r--vendor/assets/javascripts/notebooklab.js59
15 files changed, 160 insertions, 47 deletions
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index c241816788b..664539e93e1 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -158,6 +158,7 @@
li.task-list-item {
list-style-type: none;
position: relative;
+ min-height: 22px;
padding-left: 28px;
margin-left: 0 !important;
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index 82f4182d59a..d0c94d3b694 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -20,7 +20,8 @@ class ContainerRepository < ActiveRecord::Base
end
def path
- @path ||= [project.full_path, name].select(&:present?).join('/')
+ @path ||= [project.full_path, name]
+ .select(&:present?).join('/').downcase
end
def location
diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml
index 6a5986f496a..50132572096 100644
--- a/app/views/admin/services/index.html.haml
+++ b/app/views/admin/services/index.html.haml
@@ -13,7 +13,7 @@
- @services.sort_by(&:title).each do |service|
%tr
%td
- = icon("copy", class: 'clgray')
+ = boolean_to_icon service.activated?
%td
= link_to edit_admin_application_settings_service_path(service.id) do
%strong= service.title
diff --git a/changelogs/unreleased/empty-task-list-alignment.yml b/changelogs/unreleased/empty-task-list-alignment.yml
new file mode 100644
index 00000000000..ca04e1cab5a
--- /dev/null
+++ b/changelogs/unreleased/empty-task-list-alignment.yml
@@ -0,0 +1,4 @@
+---
+title: Fixed alignment of empty task list items
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-trace-seeking.yml b/changelogs/unreleased/fix-trace-seeking.yml
new file mode 100644
index 00000000000..b753df4bb43
--- /dev/null
+++ b/changelogs/unreleased/fix-trace-seeking.yml
@@ -0,0 +1,4 @@
+---
+title: Fix invalid encoding when showing some traces
+merge_request: 10681
+author:
diff --git a/lib/banzai/filter/issuable_state_filter.rb b/lib/banzai/filter/issuable_state_filter.rb
index 6b78aa795b4..0b2b8bd7f4d 100644
--- a/lib/banzai/filter/issuable_state_filter.rb
+++ b/lib/banzai/filter/issuable_state_filter.rb
@@ -13,8 +13,8 @@ module Banzai
issuables = extractor.extract([doc])
issuables.each do |node, issuable|
- if VISIBLE_STATES.include?(issuable.state)
- node.children.last.content += " [#{issuable.state}]"
+ if VISIBLE_STATES.include?(issuable.state) && node.children.present?
+ node.add_child(Nokogiri::XML::Text.new(" [#{issuable.state}]", doc))
end
end
diff --git a/lib/container_registry/path.rb b/lib/container_registry/path.rb
index a4b5f2aba6c..4a585996aa5 100644
--- a/lib/container_registry/path.rb
+++ b/lib/container_registry/path.rb
@@ -15,7 +15,7 @@ module ContainerRegistry
LEVELS_SUPPORTED = 3
def initialize(path)
- @path = path
+ @path = path.to_s.downcase
end
def valid?
@@ -25,7 +25,7 @@ module ContainerRegistry
end
def components
- @components ||= @path.to_s.split('/')
+ @components ||= @path.split('/')
end
def nodes
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index 41dcf846fed..3b335cdfd01 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -25,11 +25,10 @@ module Gitlab
end
def limit(last_bytes = LIMIT_SIZE)
- stream_size = size
- if stream_size < last_bytes
- last_bytes = stream_size
+ if last_bytes < size
+ stream.seek(-last_bytes, IO::SEEK_END)
+ stream.readline
end
- stream.seek(-last_bytes, IO::SEEK_END)
end
def append(data, offset)
diff --git a/spec/fixtures/trace/ansi-sequence-and-unicode b/spec/fixtures/trace/ansi-sequence-and-unicode
new file mode 100644
index 00000000000..5d2466f0d0f
--- /dev/null
+++ b/spec/fixtures/trace/ansi-sequence-and-unicode
@@ -0,0 +1,5 @@
+.
+..
+😺
+ヾ(´༎ຶД༎ຶ`)ノ
+許功蓋
diff --git a/spec/lib/banzai/filter/issuable_state_filter_spec.rb b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
index 603b79a323c..5cb98163746 100644
--- a/spec/lib/banzai/filter/issuable_state_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_state_filter_spec.rb
@@ -6,8 +6,8 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
let(:user) { create(:user) }
- def create_link(data)
- link_to('text', '', class: 'gfm has-tooltip', data: data)
+ def create_link(text, data)
+ link_to(text, '', class: 'gfm has-tooltip', data: data)
end
it 'ignores non-GFM links' do
@@ -19,16 +19,37 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'ignores non-issuable links' do
project = create(:empty_project, :public)
- link = create_link(project: project, reference_type: 'issue')
+ link = create_link('text', project: project, reference_type: 'issue')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
end
+ it 'ignores issuable links with empty content' do
+ issue = create(:issue, :closed)
+ link = create_link('', issue: issue.id, reference_type: 'issue')
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.text).to eq('')
+ end
+
+ it 'adds text with standard formatting' do
+ issue = create(:issue, :closed)
+ link = create_link(
+ 'something <strong>else</strong>'.html_safe,
+ issue: issue.id,
+ reference_type: 'issue'
+ )
+ doc = filter(link, current_user: user)
+
+ expect(doc.css('a').last.inner_html).
+ to eq('something <strong>else</strong> [closed]')
+ end
+
context 'for issue references' do
it 'ignores open issue references' do
issue = create(:issue)
- link = create_link(issue: issue.id, reference_type: 'issue')
+ link = create_link('text', issue: issue.id, reference_type: 'issue')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
@@ -36,7 +57,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'ignores reopened issue references' do
reopened_issue = create(:issue, :reopened)
- link = create_link(issue: reopened_issue.id, reference_type: 'issue')
+ link = create_link('text', issue: reopened_issue.id, reference_type: 'issue')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
@@ -44,7 +65,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'appends [closed] to closed issue references' do
closed_issue = create(:issue, :closed)
- link = create_link(issue: closed_issue.id, reference_type: 'issue')
+ link = create_link('text', issue: closed_issue.id, reference_type: 'issue')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text [closed]')
@@ -54,7 +75,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
context 'for merge request references' do
it 'ignores open merge request references' do
mr = create(:merge_request)
- link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ link = create_link('text', merge_request: mr.id, reference_type: 'merge_request')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
@@ -62,7 +83,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'ignores reopened merge request references' do
mr = create(:merge_request, :reopened)
- link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ link = create_link('text', merge_request: mr.id, reference_type: 'merge_request')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
@@ -70,7 +91,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'ignores locked merge request references' do
mr = create(:merge_request, :locked)
- link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ link = create_link('text', merge_request: mr.id, reference_type: 'merge_request')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text')
@@ -78,7 +99,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'appends [closed] to closed merge request references' do
mr = create(:merge_request, :closed)
- link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ link = create_link('text', merge_request: mr.id, reference_type: 'merge_request')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text [closed]')
@@ -86,7 +107,7 @@ describe Banzai::Filter::IssuableStateFilter, lib: true do
it 'appends [merged] to merged merge request references' do
mr = create(:merge_request, :merged)
- link = create_link(merge_request: mr.id, reference_type: 'merge_request')
+ link = create_link('text', merge_request: mr.id, reference_type: 'merge_request')
doc = filter(link, current_user: user)
expect(doc.css('a').last.text).to eq('text [merged]')
diff --git a/spec/lib/container_registry/path_spec.rb b/spec/lib/container_registry/path_spec.rb
index b9c4572c269..f3b3a9a715f 100644
--- a/spec/lib/container_registry/path_spec.rb
+++ b/spec/lib/container_registry/path_spec.rb
@@ -33,10 +33,20 @@ describe ContainerRegistry::Path do
end
describe '#to_s' do
- let(:path) { 'some/image' }
+ context 'when path does not have uppercase characters' do
+ let(:path) { 'some/image' }
- it 'return a string with a repository path' do
- expect(subject.to_s).to eq path
+ it 'return a string with a repository path' do
+ expect(subject.to_s).to eq 'some/image'
+ end
+ end
+
+ context 'when path has uppercase characters' do
+ let(:path) { 'SoMe/ImAgE' }
+
+ it 'return a string with a repository path' do
+ expect(subject.to_s).to eq 'some/image'
+ end
end
end
@@ -70,6 +80,12 @@ describe ContainerRegistry::Path do
it { is_expected.to be_valid }
end
+
+ context 'when path contains uppercase letters' do
+ let(:path) { 'Some/Registry' }
+
+ it { is_expected.to be_valid }
+ end
end
describe '#has_repository?' do
diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb
index 2e57ccef182..9e3bd6d662f 100644
--- a/spec/lib/gitlab/ci/trace/stream_spec.rb
+++ b/spec/lib/gitlab/ci/trace/stream_spec.rb
@@ -17,12 +17,12 @@ describe Gitlab::Ci::Trace::Stream do
describe '#limit' do
let(:stream) do
described_class.new do
- StringIO.new("12345678")
+ StringIO.new((1..8).to_a.join("\n"))
end
end
- it 'if size is larger we start from beggining' do
- stream.limit(10)
+ it 'if size is larger we start from beginning' do
+ stream.limit(20)
expect(stream.tell).to eq(0)
end
@@ -30,7 +30,27 @@ describe Gitlab::Ci::Trace::Stream do
it 'if size is smaller we start from the end' do
stream.limit(2)
- expect(stream.tell).to eq(6)
+ expect(stream.raw).to eq("8")
+ end
+
+ context 'when the trace contains ANSI sequence and Unicode' do
+ let(:stream) do
+ described_class.new do
+ File.open(expand_fixture_path('trace/ansi-sequence-and-unicode'))
+ end
+ end
+
+ it 'forwards to the next linefeed, case 1' do
+ stream.limit(7)
+
+ expect(stream.raw).to eq('')
+ end
+
+ it 'forwards to the next linefeed, case 2' do
+ stream.limit(29)
+
+ expect(stream.raw).to eq("\e[01;32m許功蓋\e[0m\n")
+ end
end
end
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 6d6c9f2adfc..eff41d85972 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -34,8 +34,18 @@ describe ContainerRepository do
end
describe '#path' do
- it 'returns a full path to the repository' do
- expect(repository.path).to eq('group/test/my_image')
+ context 'when project path does not contain uppercase letters' do
+ it 'returns a full path to the repository' do
+ expect(repository.path).to eq('group/test/my_image')
+ end
+ end
+
+ context 'when path contains uppercase letters' do
+ let(:project) { create(:project, path: 'MY_PROJECT', group: group) }
+
+ it 'returns a full path without capital letters' do
+ expect(repository.path).to eq('group/my_project/my_image')
+ end
end
end
diff --git a/spec/support/fixture_helpers.rb b/spec/support/fixture_helpers.rb
index a05c9d18002..5515c355cea 100644
--- a/spec/support/fixture_helpers.rb
+++ b/spec/support/fixture_helpers.rb
@@ -1,8 +1,11 @@
module FixtureHelpers
def fixture_file(filename)
return '' if filename.blank?
- file_path = File.expand_path(Rails.root.join('spec/fixtures/', filename))
- File.read(file_path)
+ File.read(expand_fixture_path(filename))
+ end
+
+ def expand_fixture_path(filename)
+ File.expand_path(Rails.root.join('spec/fixtures/', filename))
end
end
diff --git a/vendor/assets/javascripts/notebooklab.js b/vendor/assets/javascripts/notebooklab.js
index 601a645b655..b8cfdc53b48 100644
--- a/vendor/assets/javascripts/notebooklab.js
+++ b/vendor/assets/javascripts/notebooklab.js
@@ -699,6 +699,48 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
//
//
+var renderer = new _marked2.default.Renderer();
+
+/*
+ Regex to match KaTex blocks.
+
+ Supports the following:
+
+ \begin{equation}<math>\end{equation}
+ $$<math>$$
+ inline $<math>$
+
+ The matched text then goes through the KaTex renderer & then outputs the HTML
+*/
+var katexRegexString = '(\n ^\\\\begin{[a-zA-Z]+}\\s\n |\n ^\\$\\$\n |\n \\s\\$(?!\\$)\n)\n (.+?)\n(\n \\s\\\\end{[a-zA-Z]+}$\n |\n \\$\\$$\n |\n \\$\n)\n'.replace(/\s/g, '').trim();
+
+renderer.paragraph = function (t) {
+ var text = t;
+ var inline = false;
+
+ if (typeof katex !== 'undefined') {
+ var katexString = text.replace(/\\/g, '\\');
+ var matches = new RegExp(katexRegexString, 'gi').exec(katexString);
+
+ if (matches && matches.length > 0) {
+ if (matches[1].trim() === '$' && matches[3].trim() === '$') {
+ inline = true;
+
+ text = katexString.replace(matches[0], '') + ' ' + katex.renderToString(matches[2]);
+ } else {
+ text = katex.renderToString(matches[2]);
+ }
+ }
+ }
+
+ return '<p class="' + (inline ? 'inline-katex' : '') + '">' + text + '</p>';
+};
+
+_marked2.default.setOptions({
+ sanitize: true,
+ renderer: renderer
+});
+
exports.default = {
components: {
prompt: _prompt2.default
@@ -711,20 +753,7 @@ exports.default = {
},
computed: {
markdown: function markdown() {
- var regex = new RegExp('^\\$\\$(.*)\\$\\$$', 'g');
-
- var source = this.cell.source.map(function (line) {
- var matches = regex.exec(line.trim());
-
- // Only render use the Katex library if it is actually loaded
- if (matches && matches.length > 0 && typeof katex !== 'undefined') {
- return katex.renderToString(matches[1]);
- }
-
- return line;
- });
-
- return (0, _marked2.default)(source.join(''));
+ return (0, _marked2.default)(this.cell.source.join(''));
}
}
};
@@ -3047,7 +3076,7 @@ exports = module.exports = __webpack_require__(1)(undefined);
// module
-exports.push([module.i, ".markdown .katex{display:block;text-align:center}", ""]);
+exports.push([module.i, ".markdown .katex{display:block;text-align:center}.markdown .inline-katex .katex{display:inline;text-align:initial}", ""]);
// exports