Commit c03f4141 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-03-26

# Conflicts:
#	config/webpack.config.js

[ci skip]
parents b38f4bbf 391732a2
......@@ -1809,9 +1809,11 @@ export default class Notes {
}
}
$closeBtn.text($closeBtn.data('originalText'));
/* eslint-disable promise/catch-or-return */
// Make request to submit comment on server
axios
return axios
.post(`${formAction}?html=true`, formData)
.then(res => {
const note = res.data;
......@@ -1928,8 +1930,6 @@ export default class Notes {
this.reenableTargetFormSubmitButton(e);
this.addNoteError($form);
});
return $closeBtn.text($closeBtn.data('originalText'));
}
/**
......
<script>
import { sprintf, s__ } from '~/locale';
import statusCodes from '../../lib/utils/http_status';
import { bytesToMiB } from '../../lib/utils/number_utils';
import { backOff } from '../../lib/utils/common_utils';
......@@ -45,17 +46,28 @@ export default {
shouldShowMetricsUnavailable() {
return !this.loadingMetrics && !this.hasMetrics && !this.loadFailed;
},
memoryChangeType() {
memoryChangeMessage() {
const messageProps = {
memoryFrom: this.memoryFrom,
memoryTo: this.memoryTo,
metricsLinkStart: `<a href="${this.metricsMonitoringUrl}">`,
metricsLinkEnd: '</a>',
emphasisStart: '<b>',
emphasisEnd: '</b>',
};
const memoryTo = Number(this.memoryTo);
const memoryFrom = Number(this.memoryFrom);
let memoryUsageMsg = '';
if (memoryTo > memoryFrom) {
return 'increased';
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} increased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB'), messageProps, false);
} else if (memoryTo < memoryFrom) {
return 'decreased';
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB'), messageProps, false);
} else {
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB'), messageProps, false);
}
return 'unchanged';
return memoryUsageMsg;
},
},
mounted() {
......@@ -130,24 +142,22 @@ export default {
<i
class="fa fa-spinner fa-spin usage-info-load-spinner"
aria-hidden="true">
</i>Loading deployment statistics
</i>{{ s__('mrWidget|Loading deployment statistics') }}
</p>
<p
v-if="shouldShowMemoryGraph"
class="usage-info js-usage-info">
<a
:href="metricsMonitoringUrl"
>Memory</a> usage <b>{{ memoryChangeType }}</b> from {{ memoryFrom }}MB to {{ memoryTo }}MB
{{ memoryChangeMessage }}
</p>
<p
v-if="shouldShowLoadFailure"
class="usage-info js-usage-info usage-info-failed">
Failed to load deployment statistics
{{ s__('mrWidget|Failed to load deployment statistics') }}
</p>
<p
v-if="shouldShowMetricsUnavailable"
class="usage-info js-usage-info usage-info-unavailable">
Deployment statistics are not available currently
{{ s__('mrWidget|Deployment statistics are not available currently') }}
</p>
<memory-graph
v-if="shouldShowMemoryGraph"
......
#!/usr/bin/env ruby
begin
# Remove this block when upgraded to rails 5.0.
unless %w[1 true].include?(ENV["RAILS5"])
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
rescue LoadError => e
raise unless e.message.include?('spring')
end
end
APP_PATH = File.expand_path('../../config/application', __FILE__)
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'
#!/usr/bin/env ruby
begin
# Remove this block when upgraded to rails 5.0.
unless %w[1 true].include?(ENV["RAILS5"])
begin
load File.expand_path('../spring', __FILE__)
rescue LoadError => e
rescue LoadError => e
raise unless e.message.include?('spring')
end
end
require_relative '../config/boot'
require 'rake'
Rake.application.run
#!/usr/bin/env ruby
require 'pathname'
def rails5?
%w[1 true].include?(ENV["RAILS5"])
end
require "pathname"
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
APP_ROOT = Pathname.new File.expand_path("../../", __FILE__)
if rails5?
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
end
Dir.chdir APP_ROOT do
# This script is a starting point to setup your application.
# Add necessary setup steps to this file:
puts "== Installing dependencies =="
if rails5?
system! "gem install bundler --conservative"
system("bundle check") || system!("bundle install")
else
system "gem install bundler --conservative"
system "bundle check || bundle install"
end
# puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml")
# system "cp config/database.yml.sample config/database.yml"
# cp "config/database.yml.sample", "config/database.yml"
# end
puts "\n== Preparing database =="
if rails5?
system! "bin/rails db:setup"
else
system "bin/rake db:reset"
end
puts "\n== Removing old logs and tempfiles =="
if rails5?
system! "bin/rails log:clear tmp:clear"
else
system "rm -f log/*"
system "rm -rf tmp/cache"
end
puts "\n== Restarting application server =="
if rails5?
system! "bin/rails restart"
else
system "touch tmp/restart.txt"
end
end
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a way to update your development environment automatically.
# Add necessary update steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end
---
title: Added i18n support for the prometheus memory widget
merge_request: 17753
author:
type: other
---
title: Fix 500 error when trying to resolve non-ASCII conflicts in the editor
merge_request: 17962
author:
type: fixed
require 'rubygems'
def rails5?
%w[1 true].include?(ENV["RAILS5"])
end
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'rubygems' unless rails5?
gemfile = rails5? ? "Gemfile.rails5" : "Gemfile"
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../#{gemfile}", __dir__)
# Set up gems listed in the Gemfile.
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
# Load the rails application
require File.expand_path('../application', __FILE__)
# Remove this condition when upgraded to rails 5.0.
if %w[1 true].include?(ENV["RAILS5"])
require_relative 'application'
else
require File.expand_path('../application', __FILE__)
end
# Initialize the rails application
Rails.application.initialize!
......@@ -9,7 +9,11 @@ Rails.application.configure do
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
if Gitlab.rails5?
config.public_file_server.enabled = false
else
config.serve_static_files = false
end
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
......
......@@ -18,7 +18,13 @@ Rails.application.configure do
# Configure static asset server for tests with Cache-Control for performance
config.assets.compile = false if ENV['CI']
if Gitlab.rails5?
config.public_file_server.enabled = true
else
config.serve_static_files = true
end
config.static_cache_control = "public, max-age=3600"
# Show full error reports and disable caching
......
# Remove this `if` condition when upgraded to rails 5.0.
# The body must be kept.
if Gitlab.rails5?
# Be sure to restart your server when you modify this file.
# ActiveSupport::Reloader.to_prepare do
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
# end
end
# Remove this `if` condition when upgraded to rails 5.0.
# The body must be kept.
if Gitlab.rails5?
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 5.0 upgrade.
#
# Once upgraded flip defaults one by one to migrate to the new default.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
Rails.application.config.action_controller.raise_on_unfiltered_parameters = true
# Enable per-form CSRF tokens. Previous versions had false.
Rails.application.config.action_controller.per_form_csrf_tokens = false
# Enable origin-checking CSRF mitigation. Previous versions had false.
Rails.application.config.action_controller.forgery_protection_origin_check = false
# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
# Previous versions had false.
ActiveSupport.to_time_preserves_timezone = false
# Require `belongs_to` associations by default. Previous versions had false.
Rails.application.config.active_record.belongs_to_required_by_default = false
# Do not halt callback chains when a callback returns false. Previous versions had true.
ActiveSupport.halt_callback_chains_on_return_false = true
end
%w(
.ruby-version
.rbenv-vars
tmp/restart.txt
tmp/caching-dev.txt
).each { |path| Spring.watch(path) }
......@@ -37,6 +37,7 @@ function generateEntries() {
}
pageEntries.forEach(path => generateAutoEntries(path));
<<<<<<< HEAD
// EE-specific auto entries
const eePageEntries = glob.sync('pages/**/index.js', {
......@@ -44,6 +45,8 @@ function generateEntries() {
});
eePageEntries.forEach(path => generateAutoEntries(path, 'ee'));
watchAutoEntries.concat(path.join(ROOT_PATH, 'ee/app/assets/javascripts/pages/'));
=======
>>>>>>> upstream/master
autoEntriesCount = Object.keys(autoEntries).length;
......@@ -253,12 +256,15 @@ const config = {
vendor: path.join(ROOT_PATH, 'vendor/assets/javascripts'),
vue$: 'vue/dist/vue.esm.js',
spec: path.join(ROOT_PATH, 'spec/javascripts'),
<<<<<<< HEAD
// EE-only
ee: path.join(ROOT_PATH, 'ee/app/assets/javascripts'),
ee_empty_states: path.join(ROOT_PATH, 'ee/app/views/shared/empty_states'),
ee_icons: path.join(ROOT_PATH, 'ee/app/views/shared/icons'),
ee_images: path.join(ROOT_PATH, 'ee/app/assets/images'),
=======
>>>>>>> upstream/master
},
},
......
......@@ -40,7 +40,10 @@ module Gitlab
# when there are no conflict files.
files.each(&:lines)
files.any?
rescue Gitlab::Git::CommandError, Gitlab::Git::Conflict::Parser::UnresolvableError, Gitlab::Git::Conflict::Resolver::ConflictSideMissing
rescue Gitlab::Git::CommandError,
Gitlab::Git::Conflict::Parser::UnresolvableError,
Gitlab::Git::Conflict::Resolver::ConflictSideMissing,
Gitlab::Git::Conflict::File::UnsupportedEncoding
false
end
cache_method :can_be_resolved_in_ui?
......
......@@ -2,17 +2,19 @@ module Gitlab
module Git
module Conflict
class File
UnsupportedEncoding = Class.new(StandardError)
attr_reader :their_path, :our_path, :our_mode, :repository, :commit_oid
attr_accessor :content
attr_accessor :raw_content
def initialize(repository, commit_oid, conflict, content)
def initialize(repository, commit_oid, conflict, raw_content)
@repository = repository
@commit_oid = commit_oid
@their_path = conflict[:theirs][:path]
@our_path = conflict[:ours][:path]
@our_mode = conflict[:ours][:mode]
@content = content
@raw_content = raw_content
end
def lines
......@@ -29,6 +31,14 @@ module Gitlab
end
end
def content
@content ||= @raw_content.dup.force_encoding('UTF-8')
raise UnsupportedEncoding unless @content.valid_encoding?
@content
end
def type
lines unless @type
......
......@@ -4,7 +4,6 @@ module Gitlab
class Parser
UnresolvableError = Class.new(StandardError)
UnmergeableFile = Class.new(UnresolvableError)
UnsupportedEncoding = Class.new(UnresolvableError)
# Recoverable errors - the conflict can be resolved in an editor, but not with
# sections.
......@@ -75,10 +74,6 @@ module Gitlab
def validate_text!(text)
raise UnmergeableFile if text.blank? # Typically a binary file
raise UnmergeableFile if text.length > 200.kilobytes
text.force_encoding('UTF-8')
raise UnsupportedEncoding unless text.valid_encoding?
end
def validate_delimiter!(condition)
......
......@@ -17,7 +17,7 @@ module Gitlab
current_file = file_from_gitaly_header(gitaly_file.header)
else
current_file.content << gitaly_file.content
current_file.raw_content << gitaly_file.content
end
end
end
......
This diff is collapsed.
......@@ -23,9 +23,7 @@ const metricsMockData = {
memory_values: [
{
metric: {},
values: [
[1493716685, '4.30859375'],
],
values: [[1493716685, '4.30859375']],
},
],
},
......@@ -53,7 +51,8 @@ const createComponent = () => {
const messages = {
loadingMetrics: 'Loading deployment statistics',
hasMetrics: 'Memory usage unchanged from 0MB to 0MB',
hasMetrics:
'<a href="/root/acets-review-apps/environments/15/metrics"> Memory </a> usage is <b> unchanged </b> at 0MB',
loadFailed: 'Failed to load deployment statistics',
metricsUnavailable: 'Deployment statistics are not available currently',
};
......@@ -92,26 +91,26 @@ describe('MemoryUsage', () => {
});
describe('computed', () => {
describe('memoryChangeType', () => {
it('should return "increased" if memoryFrom value is less than memoryTo value', () => {
describe('memoryChangeMessage', () => {
it('should contain "increased" if memoryFrom value is less than memoryTo value', () => {
vm.memoryFrom = 4.28;
vm.memoryTo = 9.13;
expect(vm.memoryChangeType).toEqual('increased');
expect(vm.memoryChangeMessage.indexOf('increased')).not.toEqual('-1');
});
it('should return "decreased" if memoryFrom value is less than memoryTo value', () => {
it('should contain "decreased" if memoryFrom value is less than memoryTo value', () => {
vm.memoryFrom = 9.13;
vm.memoryTo = 4.28;
expect(vm.memoryChangeType).toEqual('decreased');
expect(vm.memoryChangeMessage.indexOf('decreased')).not.toEqual('-1');
});
it('should return "unchanged" if memoryFrom value equal to memoryTo value', () => {
it('should contain "unchanged" if memoryFrom value equal to memoryTo value', () => {
vm.memoryFrom = 1;
vm.memoryTo = 1;
expect(vm.memoryChangeType).toEqual('unchanged');
expect(vm.memoryChangeMessage.indexOf('unchanged')).not.toEqual('-1');
});
});
});
......@@ -130,7 +129,13 @@ describe('MemoryUsage', () => {
describe('computeGraphData', () => {
it('should populate sparkline graph', () => {
vm.computeGraphData(metrics, deployment_time);
const { hasMetrics, memoryMetrics, deploymentTime, memoryFrom, memoryTo } = vm;
const {
hasMetrics,
memoryMetrics,
deploymentTime,
memoryFrom,
memoryTo,
} = vm;
expect(hasMetrics).toBeTruthy();
expect(memoryMetrics.length > 0).toBeTruthy();
......@@ -141,20 +146,26 @@ describe('MemoryUsage', () => {
});
describe('loadMetrics', () => {
const returnServicePromise = () => new Promise((resolve) => {
const returnServicePromise = () =>
new Promise(resolve => {
resolve({
data: metricsMockData,
});
});
it('should load metrics data using MRWidgetService', (done) => {
spyOn(MRWidgetService, 'fetchMetrics').and.returnValue(returnServicePromise(true));
it('should load metrics data using MRWidgetService', done => {
spyOn(MRWidgetService, 'fetchMetrics').and.returnValue(
returnServicePromise(true),
);
spyOn(vm, 'computeGraphData');
vm.loadMetrics();
setTimeout(() => {
expect(MRWidgetService.fetchMetrics).toHaveBeenCalledWith(url);
expect(vm.computeGraphData).toHaveBeenCalledWith(metrics, deployment_time);
expect(vm.computeGraphData).toHaveBeenCalledWith(
metrics,
deployment_time,
);
done();
}, 333);
});
......@@ -167,51 +178,67 @@ describe('MemoryUsage', () => {
expect(el.querySelector('.js-usage-info')).toBeDefined();
});
it('should show loading metrics message while metrics are being loaded', (done) => {
it('should show loading metrics message while metrics are being loaded', done => {
vm.loadingMetrics = true;
vm.hasMetrics = false;
vm.loadFailed = false;
Vue.nextTick(() => {
expect(el.querySelector('.js-usage-info.usage-info-loading')).toBeDefined();
expect(el.querySelector('.js-usage-info .usage-info-load-spinner')).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadingMetrics);
expect(
el.querySelector('.js-usage-info.usage-info-loading'),
).toBeDefined();
expect(
el.querySelector('.js-usage-info .usage-info-load-spinner'),
).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(
messages.loadingMetrics,
);
done();
});
});
it('should show deployment memory usage when metrics are loaded', (done) => {
it('should show deployment memory usage when metrics are loaded', done => {
vm.loadingMetrics = false;
vm.hasMetrics = true;
vm.loadFailed = false;
Vue.nextTick(() => {
expect(el.querySelector('.memory-graph-container')).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(messages.hasMetrics);
expect(el.querySelector('.js-usage-info').innerText).toContain(
messages.hasMetrics,
);
done();
});
});
it('should show failure message when metrics loading failed', (done) => {
it('should show failure message when metrics loading failed', done => {
vm.loadingMetrics = false;
vm.hasMetrics = false;
vm.loadFailed = true;
Vue.nextTick(() => {
expect(el.querySelector('.js-usage-info.usage-info-failed')).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadFailed);
expect(
el.querySelector('.js-usage-info.usage-info-failed'),
).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(
messages.loadFailed,
);
done();
});
});
it('should show metrics unavailable message when metrics loading failed', (done) => {
it('should show metrics unavailable message when metrics loading failed', done => {
vm.loadingMetrics = false;
vm.hasMetrics = false;
vm.loadFailed = false;
Vue.nextTick(() => {
expect(el.querySelector('.js-usage-info.usage-info-unavailable')).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(messages.metricsUnavailable);
expect(
el.querySelector('.js-usage-info.usage-info-unavailable'),
).toBeDefined();
expect(el.querySelector('.js-usage-info').innerText).toContain(
messages.metricsUnavailable,
);
done();
});
});
......
# coding: utf-8
require 'spec_helper'
describe Gitlab::Git::Conflict::File do
let(:conflict) { { theirs: { path: 'foo', mode: 33188 }, ours: { path: 'foo', mode: 33188 } } }
let(:invalid_content) { described_class.new(nil, nil, conflict, "a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
let(:valid_content) { described_class.new(nil, nil, conflict, "Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) }
describe '#lines' do
context 'when the content contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do
expect { invalid_content.lines }
.to raise_error(described_class::UnsupportedEncoding)
end
end
context 'when the content can be converted to UTF-8' do
it 'sets lines to the lines' do
expect(valid_content.lines).to eq([{
full_line: 'España',
type: nil,
line_obj_index: 0,
line_old: 1,
line_new: 1
}])
end
it 'sets the type to text' do
expect(valid_content.type).to eq('text')
end
end
end
describe '#content' do
context 'when the content contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do
expect { invalid_content.content }
.to raise_error(described_class::UnsupportedEncoding)
end
end
context 'when the content can be converted to UTF-8' do
it 'returns a valid UTF-8 string' do
expect(valid_content.content).to eq('España')
expect(valid_content.content).to be_valid_encoding
expect(valid_content.content.encoding).to eq(Encoding::UTF_8)
end
end
end
end
......@@ -212,13 +212,6 @@ CONFLICT
.not_to raise_error
end
end
context 'when the file contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do
expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
.to raise_error(Gitlab::Git::Conflict::Parser::UnsupportedEncoding)
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment