Add eslint import resolution (#12025)

* add and configure eslint import plugins

eslint-plugin-import and eslint-import-resolver-kibana

* fix duplicate imports

* fix named exports

mostly fix the way exports works so the linter could resolve them, but fix a few incorrect imports as well

* fix import/no-named-as-default-member issues

* fix export name

don't use named export name when consuming the default export

* fix eslint namespace issue

* remove unused install_or_update_repo file

* fix metrics vis exporting

* fix multi import

* ignore resolution issues in console

custom resolver seems unable to deal with amd modules correctly

* ignore import issues in ui framework setup

resolver is unable to deal with raw imports at the moment

* add duplicates exception to select tests

* add projectRoot override to core kibana plugin

also bump @elastic/eslint-import-resolver-kibana, so the correct package.json file is used to resolve the root path

* set kibanaPath

required for the CI

* fix one last module.exports in new code
This commit is contained in:
Joe Fleming 2017-06-09 11:19:31 -07:00 committed by GitHub
parent 30dcd59068
commit 27b869ab04
46 changed files with 90 additions and 162 deletions

View file

@ -1,12 +1,8 @@
---
extends: '@elastic/kibana'
rules:
import/no-unresolved: off
import/named: off
import/namespace: off
import/default: off
import/export: off
import/no-named-as-default: off
import/no-named-as-default-member: off
import/no-duplicates: off
settings:
import/resolver:
'@elastic/eslint-import-resolver-kibana':
rootPackageName: 'kibana'
kibanaPath: .

View file

@ -203,6 +203,7 @@
},
"devDependencies": {
"@elastic/eslint-config-kibana": "0.6.1",
"@elastic/eslint-import-resolver-kibana": "0.8.0",
"@elastic/eslint-plugin-kibana-custom": "1.0.3",
"angular-mocks": "1.4.7",
"babel-eslint": "7.2.3",

View file

@ -1,6 +1,6 @@
import _ from 'lodash';
module.exports = function (command, spaces) {
export default function help(command, spaces) {
if (!_.size(command.commands)) {
return command.outputHelp();
}
@ -24,7 +24,7 @@ ${indent(commandsSummary(command), 2)}
${cmdHelp(defCmd)}
`
).trim().replace(/^/gm, spaces || '');
};
}
function indent(str, n) {
return String(str || '').trim().replace(/^/gm, _.repeat(' ', n));

View file

@ -1,7 +1,6 @@
import { fromRoot } from '../../utils';
import { fromRoot, pkg } from '../../utils';
import install from './install';
import Logger from '../lib/logger';
import { pkg } from '../../utils';
import { getConfig } from '../../server/path';
import { parse, parseMilliseconds } from './settings';
import logWarnings from '../lib/log_warnings';

View file

@ -1,3 +1,4 @@
/* eslint import/no-unresolved: 0 */
(function (window) {
"use strict";

View file

@ -1,3 +1,4 @@
/* eslint import/no-unresolved: 0 */
let ace = require('ace');
ace.define("ace/theme/sense-dark", ['require', 'exports', 'module'],

View file

@ -1,4 +1,9 @@
{
"name": "kibana",
"version": "kibana"
"version": "kibana",
"config": {
"@elastic/eslint-import-resolver-kibana": {
"projectRoot": false
}
}
}

View file

@ -6,8 +6,7 @@ import { PanelUtils } from './panel/panel_utils';
import moment from 'moment';
import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory';
import { createPanelState } from 'plugins/kibana/dashboard/panel/panel_state';
import { getPersistedStateId } from 'plugins/kibana/dashboard/panel/panel_state';
import { createPanelState, getPersistedStateId } from 'plugins/kibana/dashboard/panel/panel_state';
function getStateDefaults(dashboard, hideWriteControls) {
return {

View file

@ -3,7 +3,7 @@ import _ from 'lodash';
import AggSelect from './agg_select';
import FieldSelect from './field_select';
import AggRow from './agg_row';
import collectionActions from '../lib/collection_actions';
import * as collectionActions from '../lib/collection_actions';
import AddDeleteButtons from '../add_delete_buttons';
import Select from 'react-select';
import uuid from 'uuid';

View file

@ -1,7 +1,7 @@
import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import AddDeleteButtons from '../add_delete_buttons';
import collectionActions from '../lib/collection_actions';
import * as collectionActions from '../lib/collection_actions';
import MetricSelect from './metric_select';
class CalculationVars extends Component {

View file

@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import collectionActions from './lib/collection_actions';
import * as collectionActions from './lib/collection_actions';
import AddDeleteButtons from './add_delete_buttons';
import ColorPicker from './color_picker';
import FieldSelect from './aggs/field_select';

View file

@ -1,7 +1,6 @@
import React, { Component, PropTypes } from 'react';
import Tooltip from './tooltip';
import CustomColorPicker from './custom_color_picker';
const Picker = CustomColorPicker;
import Picker from './custom_color_picker';
class ColorPicker extends Component {

View file

@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import AddDeleteButtons from './add_delete_buttons';
import Select from 'react-select';
import collectionActions from './lib/collection_actions';
import * as collectionActions from './lib/collection_actions';
import ColorPicker from './color_picker';
class ColorRules extends Component {

View file

@ -1,5 +1,8 @@
import uuid from 'uuid';
import _ from 'lodash';
const newFn = () => ({ id: uuid.v1() });
export function handleChange(props, doc) {
const { model, name } = props;
const collection = model[name] || [];
@ -23,7 +26,6 @@ export function handleDelete(props, doc) {
}
}
const newFn = () => ({ id: uuid.v1() });
export function handleAdd(props, fn = newFn) {
if (!_.isFunction(fn)) fn = newFn;
const { model, name } = props;

View file

@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react';
import _ from 'lodash';
import collectionActions from '../lib/collection_actions';
import * as collectionActions from '../lib/collection_actions';
import AddDeleteButtons from '../add_delete_buttons';
import ColorPicker from '../color_picker';
import uuid from 'uuid';

View file

@ -1,7 +1,8 @@
import React, { PropTypes } from 'react';
import tickFormatter from '../../lib/tick_formatter';
import _ from 'lodash';
import { Gauge, getLastValue } from 'plugins/metrics/visualizations';
import Gauge from 'plugins/metrics/visualizations/components/gauge';
import getLastValue from 'plugins/metrics/visualizations/lib/get_last_value';
import color from 'color';
function getColors(props) {

View file

@ -1,10 +1,10 @@
import React, { PropTypes } from 'react';
import tickFormatter from '../../lib/tick_formatter';
import _ from 'lodash';
import { Metric, getLastValue } from 'plugins/metrics/visualizations';
import Metric from 'plugins/metrics/visualizations/components/metric';
import getLastValue from 'plugins/metrics/visualizations/lib/get_last_value';
import color from 'color';
function getColors(props) {
const { model, visData } = props;
const series = _.get(visData, `${model.id}.series`, []);

View file

@ -1,7 +1,7 @@
import React, { PropTypes } from 'react';
import tickFormatter from '../../lib/tick_formatter';
import _ from 'lodash';
import { Timeseries } from 'plugins/metrics/visualizations';
import Timeseries from 'plugins/metrics/visualizations/components/timeseries';
import color from 'color';
import replaceVars from '../../lib/replace_vars';
import { getAxisLabelString } from '../../lib/get_axis_label_string';

View file

@ -1,6 +1,8 @@
import tickFormatter from '../../lib/tick_formatter';
import _ from 'lodash';
import { TopN, getLastValue } from 'plugins/metrics/visualizations';
import TopN from 'plugins/metrics/visualizations/components/top_n';
import getLastValue from 'plugins/metrics/visualizations/lib/get_last_value';
import color from 'color';
import replaceVars from '../../lib/replace_vars';

View file

@ -1,20 +0,0 @@
import getLastValue from './lib/get_last_value';
import flot from './lib/flot';
import events from './lib/events';
import Timeseries from './components/timeseries';
import Metric from './components/metric';
import Gauge from './components/gauge';
import TopN from './components/top_n';
export default {
// visualizations
TopN,
Timeseries,
Metric,
Gauge,
// utilities
getLastValue,
flot,
events,
};

View file

@ -1,14 +1,13 @@
import _ from 'lodash';
import offsetTime from './offset_time';
function getParams(req, indexPattern, timeField, offsetBy) {
export function getParams(req, indexPattern, timeField, offsetBy) {
const { from, to } = offsetTime(req, offsetBy);
const indexConstraints = {};
indexConstraints[timeField] = {
max_value: { gte: from.valueOf(), format: 'epoch_millis' },
min_value: { lte: to.valueOf(), format: 'epoch_millis' }
const indexConstraints = {
[timeField]: {
max_value: { gte: from.valueOf(), format: 'epoch_millis' },
min_value: { lte: to.valueOf(), format: 'epoch_millis' }
},
};
return {
@ -20,10 +19,9 @@ function getParams(req, indexPattern, timeField, offsetBy) {
index_constraints: indexConstraints
}
};
}
function handleResponse(indexPattern) {
export function handleResponse(indexPattern) {
return resp => {
const indices = _.map(resp.indices, (_info, index) => index);
if (indices.length === 0) {
@ -34,15 +32,10 @@ function handleResponse(indexPattern) {
};
}
function calculateIndices(req, indexPattern = '*', timeField = '@timestamp', offsetBy) {
export function calculateIndices(req, indexPattern = '*', timeField = '@timestamp', offsetBy) {
const { server } = req;
const { callWithRequest } = server.plugins.elasticsearch.getCluster('data');
const params = getParams(req, indexPattern, timeField, offsetBy);
return callWithRequest(req, 'fieldStats', params)
.then(handleResponse(indexPattern));
}
calculateIndices.handleResponse = handleResponse;
calculateIndices.getParams = getParams;
export default calculateIndices;

View file

@ -1,4 +1,4 @@
import calculateIndices from './calculate_indices';
import { calculateIndices } from './calculate_indices';
import buildAnnotationRequest from './build_annotation_request';
import handleAnnotationResponse from './handle_annotation_response';

View file

@ -1,4 +1,4 @@
import calculateIndices from './calculate_indices';
import { calculateIndices } from './calculate_indices';
import buildRequestBody from './build_request_body';
import getIntervalAndTimefield from './get_interval_and_timefield';

View file

@ -1,6 +1,6 @@
import _ from 'lodash';
import Chainable from '../../lib/classes/chainable';
import * as regress from './lib/regress';
import { linear, log } from './lib/regress';
const validRegressions = {
linear: 'linear',
@ -44,7 +44,7 @@ export default new Chainable('trend', {
const subset = series.data.slice(start, end);
const result = regress[args.byName.mode || 'linear'](subset);
const result = (args.byName.mode === 'log') ? log(subset) : linear(subset);
_.each(series.data, function (point) {
point[1] = null;

View file

@ -2,8 +2,7 @@ import Joi from 'joi';
import _ from 'lodash';
import override from './override';
import createDefaultSchema from './schema';
import { pkg, unset } from '../../utils';
import { deepCloneWithBuffers as clone } from '../../utils';
import { pkg, unset, deepCloneWithBuffers as clone } from '../../utils';
const schema = Symbol('Joi Schema');
const schemaExts = Symbol('Schema Extensions');

View file

@ -1,3 +1,4 @@
/* eslint import/no-duplicates: 0 */
import sinon from 'sinon';
import expect from 'expect.js';

View file

@ -1,3 +1,4 @@
/* eslint import/no-duplicates: 0 */
import sinon from 'sinon';
import expect from 'expect.js';
import { noop } from 'lodash';

View file

@ -1,3 +1,4 @@
/* eslint import/no-duplicates: 0 */
import sinon from 'sinon';
import expect from 'expect.js';
import { identity, shuffle, sortBy } from 'lodash';

View file

@ -1,3 +1,4 @@
/* eslint import/no-duplicates: 0 */
import { cloneDeep } from 'lodash';
import expect from 'expect.js';
import sinon from 'sinon';

View file

@ -15,8 +15,7 @@ import pluginsScanMixin from './plugins/scan';
import pluginsCheckEnabledMixin from './plugins/check_enabled';
import pluginsCheckVersionMixin from './plugins/check_version';
import configCompleteMixin from './config/complete';
import uiMixin from '../ui';
import { uiSettingsMixin } from '../ui';
import uiMixin, { uiSettingsMixin } from '../ui';
import optimizeMixin from '../optimize';
import pluginsInitializeMixin from './plugins/initialize';
import { indexPatternsMixin } from './index_patterns';

View file

@ -1,15 +1,15 @@
import expect from 'expect.js';
import path from '../';
import { getConfig, getData } from '../';
import { accessSync, R_OK } from 'fs';
describe('Default path finder', function () {
it('should find a kibana.yml', () => {
const configPath = path.getConfig();
const configPath = getConfig();
expect(() => accessSync(configPath, R_OK)).to.not.throwError();
});
it('should find a data directory', () => {
const dataPath = path.getData();
const dataPath = getData();
expect(() => accessSync(dataPath, R_OK)).to.not.throwError();
});
});

View file

@ -26,7 +26,5 @@ function findFile(paths) {
return availablePath || paths[0];
}
export default {
getConfig: () => findFile(CONFIG_PATHS),
getData: () => findFile(DATA_PATHS)
};
export const getConfig = () => findFile(CONFIG_PATHS);
export const getData = () => findFile(DATA_PATHS);

View file

@ -1,8 +1,7 @@
import _ from 'lodash';
import { fromNode } from 'bluebird';
import { fromNode, each } from 'bluebird';
import { readdir, stat } from 'fs';
import { resolve } from 'path';
import { each } from 'bluebird';
import PluginCollection from './plugin_collection';
export default async (kbnServer, server, config) => {

View file

@ -1,7 +1,6 @@
import { defaults, _ } from 'lodash';
import { props } from 'bluebird';
import { props, reduce as reduceAsync } from 'bluebird';
import Boom from 'boom';
import { reduce as reduceAsync } from 'bluebird';
import { resolve } from 'path';
import UiExports from './ui_exports';

View file

@ -1,6 +1,5 @@
import { remove } from 'lodash';
import { remove, isString } from 'lodash';
import { parse, format } from 'url';
import { isString } from 'lodash';
export function initChromeNavApi(chrome, internals) {
chrome.getNavLinks = function () {

View file

@ -3,8 +3,7 @@ import ngMock from 'ng_mock';
import expect from 'expect.js';
import { DomLocationProvider } from 'ui/dom_location';
import { constant } from 'lodash';
import { cloneDeep } from 'lodash';
import { constant, cloneDeep } from 'lodash';
import $ from 'jquery';
import 'ui/chrome';
import '../app_switcher';

View file

@ -1,8 +1,5 @@
import _ from 'lodash';
import { isNumber } from 'lodash';
import { Notifier } from 'ui/notify/notifier';
import { SearchRequestProvider } from './search';
import { SegmentedHandleProvider } from './segmented_handle';
@ -91,7 +88,7 @@ export function SegmentedRequestProvider(es, Private, Promise, timefilter, confi
const indices = this._active = this._queue.splice(0, indexCount);
params.index = _.pluck(indices, 'index');
if (isNumber(this._desiredSize)) {
if (_.isNumber(this._desiredSize)) {
params.body.size = this._pickSizeForIndices(indices);
}
@ -236,7 +233,7 @@ export function SegmentedRequestProvider(es, Private, Promise, timefilter, confi
});
}
if (isNumber(desiredSize)) {
if (_.isNumber(desiredSize)) {
this._mergedResp.hits.hits = mergedHits.slice(0, desiredSize);
}
}
@ -290,7 +287,7 @@ export function SegmentedRequestProvider(es, Private, Promise, timefilter, confi
const desiredSize = this._desiredSize;
const size = _.size(hits);
if (!isNumber(desiredSize) || size < desiredSize) {
if (!_.isNumber(desiredSize) || size < desiredSize) {
this._hitWindow = {
size: size,
min: -Infinity,
@ -316,7 +313,7 @@ export function SegmentedRequestProvider(es, Private, Promise, timefilter, confi
const hitWindow = this._hitWindow;
const desiredSize = this._desiredSize;
if (!isNumber(desiredSize)) return null;
if (!_.isNumber(desiredSize)) return null;
// we don't have any hits yet, get us more info!
if (!hitWindow) return desiredSize;
// the order of documents isn't important, just get us more

View file

@ -1,5 +1,4 @@
import { pluck } from 'lodash';
import _ from 'lodash';
import { pluck, first, size, includes } from 'lodash';
import sinon from 'sinon';
import expect from 'expect.js';
import ngMock from 'ng_mock';
@ -43,7 +42,7 @@ describe('IndexPatternsCalculateIndicesProvider', () => {
indices = pluck(value, 'index');
});
$rootScope.$apply();
config = _.first(es.fieldStats.lastCall.args);
config = first(es.fieldStats.lastCall.args);
constraints = config.body.index_constraints;
}
@ -58,11 +57,11 @@ describe('IndexPatternsCalculateIndicesProvider', () => {
});
it('includes time field', () => {
run();
expect(_.includes(config.body.fields, '@something')).to.be(true);
expect(includes(config.body.fields, '@something')).to.be(true);
});
it('no constraints by default', () => {
run();
expect(_.size(constraints['@something'])).to.equal(0);
expect(size(constraints['@something'])).to.equal(0);
});
describe('when given start', () => {
@ -111,8 +110,8 @@ describe('IndexPatternsCalculateIndicesProvider', () => {
describe('response filtering', () => {
it('filters out any indices that have empty fields', () => {
run();
expect(_.includes(indices, 'mock-*')).to.be(true);
expect(_.includes(indices, 'ignore-*')).to.be(false);
expect(includes(indices, 'mock-*')).to.be(true);
expect(includes(indices, 'ignore-*')).to.be(false);
});
});

View file

@ -7,7 +7,8 @@ const notify = new Notifier({
location: 'Index Patterns'
});
module.exports = function (opts) {
// eslint-disable-next-line kibana-custom/no-default-export
export default function (opts) {
opts = opts || {};
const whenMissingRedirectTo = opts.whenMissingRedirectTo || null;
let defaultRequiredToasts = null;
@ -53,6 +54,4 @@ module.exports = function (opts) {
else defaultRequiredToasts.push(notify.error(err));
}
);
};
}

View file

@ -3,7 +3,8 @@ import _ from 'lodash';
import { wrapRouteWithPrep } from './wrap_route_with_prep';
import { RouteSetupManager } from './route_setup_manager';
function RouteManager() {
// eslint-disable-next-line kibana-custom/no-default-export
export default function RouteManager() {
const self = this;
const setup = new RouteSetupManager();
const when = [];
@ -68,5 +69,3 @@ function RouteManager() {
self.RouteManager = RouteManager;
}
module.exports = RouteManager;

View file

@ -1,7 +1,6 @@
import sinon from 'sinon';
import expect from 'expect.js';
import ngMock from 'ng_mock';
import 'ui/state_management/app_state';
import { AppStateProvider } from 'ui/state_management/app_state';
describe('State Management', function () {

View file

@ -1,5 +1,4 @@
import { duration as d } from 'moment';
import moment from 'moment';
import moment, { duration as d } from 'moment';
export function TimeBucketsCalcAutoIntervalProvider() {
// these are the rounding rules used by roundInterval()

View file

@ -1,15 +1,13 @@
import _ from 'lodash';
module.exports = {
keysToSnakeCaseShallow: function (object) {
return _.mapKeys(object, (value, key) => {
return _.snakeCase(key);
});
},
export function keysToSnakeCaseShallow(object) {
return _.mapKeys(object, (value, key) => {
return _.snakeCase(key);
});
}
keysToCamelCaseShallow: function (object) {
return _.mapKeys(object, (value, key) => {
return _.camelCase(key);
});
}
};
export function keysToCamelCaseShallow(object) {
return _.mapKeys(object, (value, key) => {
return _.camelCase(key);
});
}

View file

@ -1,39 +0,0 @@
import Promise from 'bluebird';
import spawn from './spawn';
import grunt from 'grunt';
module.exports = function (repo, dir) {
// store the previous and new hash from the repo
// to know if there was an update from fetch
let prevHash;
let newHash;
return Promise.resolve()
.then(function () {
if (!grunt.file.isDir(dir + '/.git')) {
if (grunt.file.isDir(dir)) {
throw new Error(dir + ' needs to be removed so that we can replace it with a git-repo');
}
return spawn('git', ['clone', repo, dir])();
} else {
return spawn.silent('git', ['log', '-1', '--pretty=%H'], dir)()
.then(function (out) {
prevHash = out.trim();
})
.then(spawn('git', ['fetch', 'origin', 'master'], dir))
.then(spawn('git', ['reset', '--hard', 'origin/master'], dir))
.then(spawn.silent('git', ['log', '-1', '--pretty=%H'], dir));
}
})
.then(function (out) {
if (prevHash) newHash = out.trim();
if (!prevHash || newHash !== prevHash) {
return spawn('npm', ['update'], dir)()
.then(spawn('bower', ['install'], dir))
.then(function () {
return true;
});
}
});
};

View file

@ -1,3 +1,4 @@
/* eslint import/named: 0 */
import {
GuideExample,
} from '../../components';

View file

@ -1,3 +1,4 @@
/* eslint import/no-duplicates: 0, import/default: 0 */
import React from 'react';
import { renderToHtml } from '../../services';