mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'master' into tooling/storybook-poc
This commit is contained in:
commit
7ad430a6be
@ -81,20 +81,9 @@ jobs:
|
|||||||
working_directory: /go/src/github.com/grafana/grafana
|
working_directory: /go/src/github.com/grafana/grafana
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: 'go get -u github.com/alecthomas/gometalinter'
|
|
||||||
- run: 'go get -u github.com/tsenart/deadcode'
|
|
||||||
- run: 'go get -u github.com/jgautheron/goconst/cmd/goconst'
|
|
||||||
- run: 'go get -u github.com/gordonklaus/ineffassign'
|
|
||||||
- run: 'go get -u honnef.co/go/tools/cmd/megacheck'
|
|
||||||
- run: 'go get -u github.com/opennota/check/cmd/structcheck'
|
|
||||||
- run: 'go get -u github.com/mdempsky/unconvert'
|
|
||||||
- run: 'go get -u github.com/opennota/check/cmd/varcheck'
|
|
||||||
- run:
|
- run:
|
||||||
name: run linters
|
name: Gometalinter tests
|
||||||
command: 'gometalinter --enable-gc --vendor --deadline 10m --disable-all --enable=deadcode --enable=goconst --enable=gofmt --enable=ineffassign --enable=megacheck --enable=structcheck --enable=unconvert --enable=varcheck ./...'
|
command: './scripts/gometalinter.sh'
|
||||||
- run:
|
|
||||||
name: run go vet
|
|
||||||
command: 'go vet ./pkg/...'
|
|
||||||
|
|
||||||
test-frontend:
|
test-frontend:
|
||||||
docker:
|
docker:
|
||||||
|
@ -165,6 +165,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf
|
|||||||
"externalUserMngInfo": setting.ExternalUserMngInfo,
|
"externalUserMngInfo": setting.ExternalUserMngInfo,
|
||||||
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
|
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
|
||||||
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
|
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
|
||||||
|
"viewersCanEdit": setting.ViewersCanEdit,
|
||||||
"buildInfo": map[string]interface{}{
|
"buildInfo": map[string]interface{}{
|
||||||
"version": setting.BuildVersion,
|
"version": setting.BuildVersion,
|
||||||
"commit": setting.BuildCommit,
|
"commit": setting.BuildCommit,
|
||||||
|
@ -140,7 +140,7 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er
|
|||||||
Children: dashboardChildNavs,
|
Children: dashboardChildNavs,
|
||||||
})
|
})
|
||||||
|
|
||||||
if setting.ExploreEnabled && (c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR) {
|
if setting.ExploreEnabled && (c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR || setting.ViewersCanEdit) {
|
||||||
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
data.NavTree = append(data.NavTree, &dtos.NavLink{
|
||||||
Text: "Explore",
|
Text: "Explore",
|
||||||
Id: "explore",
|
Id: "explore",
|
||||||
|
@ -34,6 +34,7 @@ export class Settings {
|
|||||||
disableUserSignUp: boolean;
|
disableUserSignUp: boolean;
|
||||||
loginHint: any;
|
loginHint: any;
|
||||||
loginError: any;
|
loginError: any;
|
||||||
|
viewersCanEdit: boolean;
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
@ -50,6 +51,7 @@ export class Settings {
|
|||||||
env: 'production',
|
env: 'production',
|
||||||
isEnterprise: false,
|
isEnterprise: false,
|
||||||
},
|
},
|
||||||
|
viewersCanEdit: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
_.extend(this, defaults, options);
|
_.extend(this, defaults, options);
|
||||||
|
@ -61,6 +61,10 @@ export class ContextSrv {
|
|||||||
store.set('grafana.sidemenu', this.sidemenu);
|
store.set('grafana.sidemenu', this.sidemenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasAccessToExplore() {
|
||||||
|
return (this.isEditor || config.viewersCanEdit) && config.exploreEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
getTheme(): ThemeName {
|
getTheme(): ThemeName {
|
||||||
return this.user.lightTheme ? ThemeNames.Light : ThemeNames.Dark;
|
return this.user.lightTheme ? ThemeNames.Light : ThemeNames.Dark;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import config from 'app/core/config';
|
|
||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
import appEvents from 'app/core/app_events';
|
import appEvents from 'app/core/app_events';
|
||||||
import { getExploreUrl } from 'app/core/utils/explore';
|
import { getExploreUrl } from 'app/core/utils/explore';
|
||||||
|
|
||||||
import Mousetrap from 'mousetrap';
|
import Mousetrap from 'mousetrap';
|
||||||
import 'mousetrap-global-bind';
|
import 'mousetrap-global-bind';
|
||||||
|
import { ContextSrv } from './context_srv';
|
||||||
|
|
||||||
export class KeybindingSrv {
|
export class KeybindingSrv {
|
||||||
helpModal: boolean;
|
helpModal: boolean;
|
||||||
@ -21,7 +21,7 @@ export class KeybindingSrv {
|
|||||||
private $timeout,
|
private $timeout,
|
||||||
private datasourceSrv,
|
private datasourceSrv,
|
||||||
private timeSrv,
|
private timeSrv,
|
||||||
private contextSrv
|
private contextSrv: ContextSrv
|
||||||
) {
|
) {
|
||||||
// clear out all shortcuts on route change
|
// clear out all shortcuts on route change
|
||||||
$rootScope.$on('$routeChangeSuccess', () => {
|
$rootScope.$on('$routeChangeSuccess', () => {
|
||||||
@ -196,7 +196,7 @@ export class KeybindingSrv {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// jump to explore if permissions allow
|
// jump to explore if permissions allow
|
||||||
if (this.contextSrv.isEditor && config.exploreEnabled) {
|
if (this.contextSrv.hasAccessToExplore()) {
|
||||||
this.bind('x', async () => {
|
this.bind('x', async () => {
|
||||||
if (dashboard.meta.focusPanelId) {
|
if (dashboard.meta.focusPanelId) {
|
||||||
const panel = dashboard.getPanelById(dashboard.meta.focusPanelId);
|
const panel = dashboard.getPanelById(dashboard.meta.focusPanelId);
|
||||||
|
@ -197,7 +197,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
|||||||
<div className="query-editor-rows">
|
<div className="query-editor-rows">
|
||||||
{panel.targets.map((query, index) => (
|
{panel.targets.map((query, index) => (
|
||||||
<QueryEditorRow
|
<QueryEditorRow
|
||||||
datasourceName={query.datasource || panel.datasource}
|
dataSourceValue={query.datasource || panel.datasource}
|
||||||
key={query.refId}
|
key={query.refId}
|
||||||
panel={panel}
|
panel={panel}
|
||||||
query={query}
|
query={query}
|
||||||
|
@ -18,11 +18,12 @@ interface Props {
|
|||||||
onAddQuery: (query?: DataQuery) => void;
|
onAddQuery: (query?: DataQuery) => void;
|
||||||
onRemoveQuery: (query: DataQuery) => void;
|
onRemoveQuery: (query: DataQuery) => void;
|
||||||
onMoveQuery: (query: DataQuery, direction: number) => void;
|
onMoveQuery: (query: DataQuery, direction: number) => void;
|
||||||
datasourceName: string | null;
|
dataSourceValue: string | null;
|
||||||
inMixedMode: boolean;
|
inMixedMode: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
loadedDataSourceValue: string | null | undefined;
|
||||||
datasource: DataSourceApi | null;
|
datasource: DataSourceApi | null;
|
||||||
isCollapsed: boolean;
|
isCollapsed: boolean;
|
||||||
angularScope: AngularQueryComponentScope | null;
|
angularScope: AngularQueryComponentScope | null;
|
||||||
@ -36,6 +37,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|||||||
datasource: null,
|
datasource: null,
|
||||||
isCollapsed: false,
|
isCollapsed: false,
|
||||||
angularScope: null,
|
angularScope: null,
|
||||||
|
loadedDataSourceValue: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -61,14 +63,14 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|||||||
const dataSourceSrv = getDatasourceSrv();
|
const dataSourceSrv = getDatasourceSrv();
|
||||||
const datasource = await dataSourceSrv.get(query.datasource || panel.datasource);
|
const datasource = await dataSourceSrv.get(query.datasource || panel.datasource);
|
||||||
|
|
||||||
this.setState({ datasource });
|
this.setState({ datasource, loadedDataSourceValue: this.props.dataSourceValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
const { datasource } = this.state;
|
const { loadedDataSourceValue } = this.state;
|
||||||
|
|
||||||
// check if we need to load another datasource
|
// check if we need to load another datasource
|
||||||
if (datasource && datasource.name !== this.props.datasourceName) {
|
if (loadedDataSourceValue !== this.props.dataSourceValue) {
|
||||||
if (this.angularQueryEditor) {
|
if (this.angularQueryEditor) {
|
||||||
this.angularQueryEditor.destroy();
|
this.angularQueryEditor.destroy();
|
||||||
this.angularQueryEditor = null;
|
this.angularQueryEditor = null;
|
||||||
@ -178,7 +180,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { query, datasourceName, inMixedMode } = this.props;
|
const { query, inMixedMode } = this.props;
|
||||||
const { datasource, isCollapsed } = this.state;
|
const { datasource, isCollapsed } = this.state;
|
||||||
const isDisabled = query.hide;
|
const isDisabled = query.hide;
|
||||||
|
|
||||||
@ -202,7 +204,7 @@ export class QueryEditorRow extends PureComponent<Props, State> {
|
|||||||
{isCollapsed && <i className="fa fa-caret-right" />}
|
{isCollapsed && <i className="fa fa-caret-right" />}
|
||||||
{!isCollapsed && <i className="fa fa-caret-down" />}
|
{!isCollapsed && <i className="fa fa-caret-down" />}
|
||||||
<span>{query.refId}</span>
|
<span>{query.refId}</span>
|
||||||
{inMixedMode && <em className="query-editor-row__context-info"> ({datasourceName})</em>}
|
{inMixedMode && <em className="query-editor-row__context-info"> ({datasource.name})</em>}
|
||||||
{isDisabled && <em className="query-editor-row__context-info"> Disabled</em>}
|
{isDisabled && <em className="query-editor-row__context-info"> Disabled</em>}
|
||||||
</div>
|
</div>
|
||||||
<div className="query-editor-row__collapsed-text" onClick={this.onToggleEditMode}>
|
<div className="query-editor-row__collapsed-text" onClick={this.onToggleEditMode}>
|
||||||
|
@ -62,7 +62,7 @@ const mustKeepProps: { [str: string]: boolean } = {
|
|||||||
const defaults: any = {
|
const defaults: any = {
|
||||||
gridPos: { x: 0, y: 0, h: 3, w: 6 },
|
gridPos: { x: 0, y: 0, h: 3, w: 6 },
|
||||||
datasource: null,
|
datasource: null,
|
||||||
targets: [{}],
|
targets: [{ refId: 'A' }],
|
||||||
cachedPluginOptions: {},
|
cachedPluginOptions: {},
|
||||||
transparent: false,
|
transparent: false,
|
||||||
};
|
};
|
||||||
@ -83,7 +83,7 @@ export class PanelModel {
|
|||||||
collapsed?: boolean;
|
collapsed?: boolean;
|
||||||
panels?: any;
|
panels?: any;
|
||||||
soloMode?: boolean;
|
soloMode?: boolean;
|
||||||
targets: any[];
|
targets: DataQuery[];
|
||||||
datasource: string;
|
datasource: string;
|
||||||
thresholds?: any;
|
thresholds?: any;
|
||||||
|
|
||||||
@ -118,6 +118,18 @@ export class PanelModel {
|
|||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
_.defaultsDeep(this, _.cloneDeep(defaults));
|
_.defaultsDeep(this, _.cloneDeep(defaults));
|
||||||
|
// queries must have refId
|
||||||
|
this.ensureQueryIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureQueryIds() {
|
||||||
|
if (this.targets) {
|
||||||
|
for (const query of this.targets) {
|
||||||
|
if (!query.refId) {
|
||||||
|
query.refId = this.getNextQueryLetter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptions(panelDefaults) {
|
getOptions(panelDefaults) {
|
||||||
@ -243,7 +255,7 @@ export class PanelModel {
|
|||||||
addQuery(query?: Partial<DataQuery>) {
|
addQuery(query?: Partial<DataQuery>) {
|
||||||
query = query || { refId: 'A' };
|
query = query || { refId: 'A' };
|
||||||
query.refId = this.getNextQueryLetter();
|
query.refId = this.getNextQueryLetter();
|
||||||
this.targets.push(query);
|
this.targets.push(query as DataQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
getNextQueryLetter(): string {
|
getNextQueryLetter(): string {
|
||||||
|
@ -9,6 +9,10 @@ describe('PanelModel', () => {
|
|||||||
model = new PanelModel({
|
model = new PanelModel({
|
||||||
type: 'table',
|
type: 'table',
|
||||||
showColumns: true,
|
showColumns: true,
|
||||||
|
targets: [
|
||||||
|
{refId: 'A'},
|
||||||
|
{noRefId: true}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -20,6 +24,10 @@ describe('PanelModel', () => {
|
|||||||
expect(model.showColumns).toBe(true);
|
expect(model.showColumns).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add missing refIds', () => {
|
||||||
|
expect(model.targets[1].refId).toBe('B');
|
||||||
|
});
|
||||||
|
|
||||||
it('getSaveModel should remove defaults', () => {
|
it('getSaveModel should remove defaults', () => {
|
||||||
const saveModel = model.getSaveModel();
|
const saveModel = model.getSaveModel();
|
||||||
expect(saveModel.gridPos).toBe(undefined);
|
expect(saveModel.gridPos).toBe(undefined);
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
import kbn from 'app/core/utils/kbn';
|
import kbn from 'app/core/utils/kbn';
|
||||||
import config from 'app/core/config';
|
|
||||||
|
|
||||||
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
import { PanelCtrl } from 'app/features/panel/panel_ctrl';
|
||||||
import { getExploreUrl } from 'app/core/utils/explore';
|
import { getExploreUrl } from 'app/core/utils/explore';
|
||||||
import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/utils/panel';
|
import { applyPanelTimeOverrides, getResolution } from 'app/features/dashboard/utils/panel';
|
||||||
|
import { ContextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
class MetricsPanelCtrl extends PanelCtrl {
|
class MetricsPanelCtrl extends PanelCtrl {
|
||||||
scope: any;
|
scope: any;
|
||||||
datasource: any;
|
datasource: any;
|
||||||
$q: any;
|
$q: any;
|
||||||
$timeout: any;
|
$timeout: any;
|
||||||
contextSrv: any;
|
contextSrv: ContextSrv;
|
||||||
datasourceSrv: any;
|
datasourceSrv: any;
|
||||||
timeSrv: any;
|
timeSrv: any;
|
||||||
templateSrv: any;
|
templateSrv: any;
|
||||||
@ -231,7 +231,7 @@ class MetricsPanelCtrl extends PanelCtrl {
|
|||||||
|
|
||||||
getAdditionalMenuItems() {
|
getAdditionalMenuItems() {
|
||||||
const items = [];
|
const items = [];
|
||||||
if (config.exploreEnabled && this.contextSrv.isEditor && this.datasource) {
|
if (this.contextSrv.hasAccessToExplore() && this.datasource) {
|
||||||
items.push({
|
items.push({
|
||||||
text: 'Explore',
|
text: 'Explore',
|
||||||
click: 'ctrl.explore();',
|
click: 'ctrl.explore();',
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
jest.mock('app/core/core', () => ({}));
|
jest.mock('app/core/core', () => ({}));
|
||||||
jest.mock('app/core/config', () => {
|
jest.mock('app/core/config', () => {
|
||||||
return {
|
return {
|
||||||
exploreEnabled: true,
|
|
||||||
panels: {
|
panels: {
|
||||||
test: {
|
test: {
|
||||||
id: 'test',
|
id: 'test',
|
||||||
@ -16,46 +15,45 @@ import { PanelModel } from 'app/features/dashboard/panel_model';
|
|||||||
import { MetricsPanelCtrl } from '../metrics_panel_ctrl';
|
import { MetricsPanelCtrl } from '../metrics_panel_ctrl';
|
||||||
|
|
||||||
describe('MetricsPanelCtrl', () => {
|
describe('MetricsPanelCtrl', () => {
|
||||||
let ctrl;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
ctrl = setupController();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('when getting additional menu items', () => {
|
describe('when getting additional menu items', () => {
|
||||||
let additionalItems;
|
describe('and has no datasource set but user has access to explore', () => {
|
||||||
|
|
||||||
describe('and has no datasource set', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
additionalItems = ctrl.getAdditionalMenuItems();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not return any items', () => {
|
it('should not return any items', () => {
|
||||||
expect(additionalItems.length).toBe(0);
|
const ctrl = setupController({ hasAccessToExplore: true });
|
||||||
|
|
||||||
|
expect(ctrl.getAdditionalMenuItems().length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('and has datasource set that supports explore and user has powers', () => {
|
describe('and has datasource set that supports explore and user does not have access to explore', () => {
|
||||||
beforeEach(() => {
|
it('should not return any items', () => {
|
||||||
ctrl.contextSrv = { isEditor: true };
|
const ctrl = setupController({ hasAccessToExplore: false });
|
||||||
ctrl.datasource = { meta: { explore: true } };
|
ctrl.datasource = { meta: { explore: true } };
|
||||||
additionalItems = ctrl.getAdditionalMenuItems();
|
|
||||||
|
expect(ctrl.getAdditionalMenuItems().length).toBe(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not return any items', () => {
|
describe('and has datasource set that supports explore and user has access to explore', () => {
|
||||||
expect(additionalItems.length).toBe(1);
|
it('should return one item', () => {
|
||||||
|
const ctrl = setupController({ hasAccessToExplore: true });
|
||||||
|
ctrl.datasource = { meta: { explore: true } };
|
||||||
|
|
||||||
|
expect(ctrl.getAdditionalMenuItems().length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupController() {
|
function setupController({ hasAccessToExplore } = { hasAccessToExplore: false }) {
|
||||||
const injectorStub = {
|
const injectorStub = {
|
||||||
get: type => {
|
get: type => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case '$q': {
|
case '$q': {
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
case 'contextSrv': {
|
||||||
|
return { hasAccessToExplore: () => hasAccessToExplore };
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return jest.fn();
|
return jest.fn();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import UsersListPage from 'app/features/users/UsersListPage';
|
|||||||
import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards';
|
import DataSourceDashboards from 'app/features/datasources/DataSourceDashboards';
|
||||||
import DataSourceSettingsPage from '../features/datasources/settings/DataSourceSettingsPage';
|
import DataSourceSettingsPage from '../features/datasources/settings/DataSourceSettingsPage';
|
||||||
import OrgDetailsPage from '../features/org/OrgDetailsPage';
|
import OrgDetailsPage from '../features/org/OrgDetailsPage';
|
||||||
|
import config from 'app/core/config';
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
export function setupAngularRoutes($routeProvider, $locationProvider) {
|
export function setupAngularRoutes($routeProvider, $locationProvider) {
|
||||||
@ -129,7 +130,7 @@ export function setupAngularRoutes($routeProvider, $locationProvider) {
|
|||||||
template: '<react-container />',
|
template: '<react-container />',
|
||||||
reloadOnSearch: false,
|
reloadOnSearch: false,
|
||||||
resolve: {
|
resolve: {
|
||||||
roles: () => ['Editor', 'Admin'],
|
roles: () => (config.viewersCanEdit ? [] : ['Editor', 'Admin']),
|
||||||
component: () => import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper'),
|
component: () => import(/* webpackChunkName: "explore" */ 'app/features/explore/Wrapper'),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
33
scripts/gometalinter.sh
Executable file
33
scripts/gometalinter.sh
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function exit_if_fail {
|
||||||
|
command=$@
|
||||||
|
echo "Executing '$command'"
|
||||||
|
eval $command
|
||||||
|
rc=$?
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
echo "'$command' returned $rc."
|
||||||
|
exit $rc
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
go get -u github.com/alecthomas/gometalinter
|
||||||
|
go get -u github.com/tsenart/deadcode
|
||||||
|
go get -u github.com/jgautheron/goconst/cmd/goconst
|
||||||
|
go get -u github.com/gordonklaus/ineffassign
|
||||||
|
go get -u github.com/opennota/check/cmd/structcheck
|
||||||
|
go get -u github.com/mdempsky/unconvert
|
||||||
|
go get -u github.com/opennota/check/cmd/varcheck
|
||||||
|
go get -u honnef.co/go/tools/cmd/staticcheck
|
||||||
|
|
||||||
|
exit_if_fail gometalinter --enable-gc --vendor --deadline 10m --disable-all \
|
||||||
|
--enable=deadcode \
|
||||||
|
--enable=goconst \
|
||||||
|
--enable=gofmt \
|
||||||
|
--enable=ineffassign \
|
||||||
|
--enable=structcheck \
|
||||||
|
--enable=unconvert \
|
||||||
|
--enable=varcheck \
|
||||||
|
--enable=staticcheck
|
||||||
|
|
||||||
|
exit_if_fail go vet ./pkg/...
|
Loading…
Reference in New Issue
Block a user