Skip to content

Commit

Permalink
Merge branch 'master' of github.com:elastic/kibana into add-anomalies…
Browse files Browse the repository at this point in the history
…-to-timeline

* 'master' of github.com:elastic/kibana: (22 commits)
  update apm index pattern (elastic#78732)
  78024: move transform out of dataset (elastic#78216)
  [QA][Code Coverage] Upload the coverage static site before ingestion (elastic#78695)
  [Discover] Make _source field not clickable (elastic#78698)
  [Fleet] Rename Ingest Manager => Fleet, Fleet => Agents in the UI (elastic#78685)
  [APM] Review feedback from distribution + transaction metrics (elastic#78752)
  [Ingest pipelines] Add ability to stop pipeline simulation  (elastic#78183)
  [CSM] Fix core vital legend background (elastic#78273)
  [Usage Collection] [schema] Support spreads + `canvas` definition (elastic#78481)
  fix lodash imports (elastic#78456)
  [Maps] Add layer type preview icons (elastic#78650)
  [APM] Use transaction metrics for distribution charts (elastic#78484)
  [Uptime] Ml anomaly alert edit (elastic#76909)
  [ML] Limit exposing shared static code through ml/public/index.ts. (elastic#77745)
  making expression debug info serializable (elastic#78727)
  fix lodahs imports in app-arch code (elastic#78582)
  Make Field a React.lazy export (elastic#78483)
  [Security Solution] Improves detections tests (elastic#77295)
  [TSVB] Different field format on different series is ignored (elastic#78138)
  RFC: Improve saved object migrations (elastic#66056)
  ...
  • Loading branch information
phillipb committed Sep 29, 2020
2 parents b7a9f8c + 9ea4984 commit f7e5f99
Show file tree
Hide file tree
Showing 226 changed files with 4,039 additions and 2,057 deletions.
2 changes: 1 addition & 1 deletion .ci/Jenkinsfile_coverage
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def handleIngestion(timestamp) {
kibanaCoverage.collectVcsInfo("### Collect VCS Info")
kibanaCoverage.generateReports("### Merge coverage reports")
kibanaCoverage.uploadCombinedReports()
kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, previousSha, teamAssignmentsPath(), '### Generate Team Assignments && Ingest')
kibanaCoverage.uploadCoverageStaticSite(timestamp)
kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, previousSha, teamAssignmentsPath(), '### Generate Team Assignments && Ingest')
}

def handlePreviousSha() {
Expand Down
4 changes: 1 addition & 3 deletions packages/kbn-std/src/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
// Prefer importing entire lodash library, e.g. import { get } from "lodash"
// eslint-disable-next-line no-restricted-imports
import isPlainObject from 'lodash/isPlainObject';
import { isPlainObject } from 'lodash';
/**
* Deeply merges two objects, omitting undefined values, and not deeply merging Arrays.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { SyntaxKind } from 'typescript';
import { ParsedUsageCollection } from '../ts_parser';

export const parsedSchemaDefinedWithSpreadsCollector: ParsedUsageCollection = [
'src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts',
{
collectorName: 'schema_defined_with_spreads',
schema: {
value: {
flat: {
type: 'keyword',
},
my_str: {
type: 'text',
},
my_objects: {
total: {
type: 'number',
},
type: {
type: 'boolean',
},
},
},
},
fetch: {
typeName: 'Usage',
typeDescriptor: {
flat: {
kind: SyntaxKind.StringKeyword,
type: 'StringKeyword',
},
my_str: {
kind: SyntaxKind.StringKeyword,
type: 'StringKeyword',
},
my_objects: {
total: {
kind: SyntaxKind.NumberKeyword,
type: 'NumberKeyword',
},
type: {
kind: SyntaxKind.BooleanKeyword,
type: 'BooleanKeyword',
},
},
},
},
},
];

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('extractCollectors', () => {
const programPaths = await getProgramPaths(configs[0]);

const results = [...extractCollectors(programPaths, tsConfig)];
expect(results).toHaveLength(7);
expect(results).toHaveLength(8);
expect(results).toMatchSnapshot();
});
});
7 changes: 7 additions & 0 deletions packages/kbn-telemetry-tools/src/tools/ts_parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { parsedNestedCollector } from './__fixture__/parsed_nested_collector';
import { parsedExternallyDefinedCollector } from './__fixture__/parsed_externally_defined_collector';
import { parsedImportedUsageInterface } from './__fixture__/parsed_imported_usage_interface';
import { parsedImportedSchemaCollector } from './__fixture__/parsed_imported_schema';
import { parsedSchemaDefinedWithSpreadsCollector } from './__fixture__/parsed_schema_defined_with_spreads_collector';

export function loadFixtureProgram(fixtureName: string) {
const fixturePath = path.resolve(
Expand Down Expand Up @@ -62,6 +63,12 @@ describe('parseUsageCollection', () => {
expect(result).toEqual([parsedWorkingCollector]);
});

it('parses collector with schema defined as union of spreads', () => {
const { program, sourceFile } = loadFixtureProgram('schema_defined_with_spreads_collector');
const result = [...parseUsageCollection(sourceFile, program)];
expect(result).toEqual([parsedSchemaDefinedWithSpreadsCollector]);
});

it('parses nested collectors', () => {
const { program, sourceFile } = loadFixtureProgram('nested_collector');
const result = [...parseUsageCollection(sourceFile, program)];
Expand Down
101 changes: 61 additions & 40 deletions packages/kbn-telemetry-tools/src/tools/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,42 +100,55 @@ export function getIdentifierDeclaration(node: ts.Node) {
return getIdentifierDeclarationFromSource(node, source);
}

export function getVariableValue(node: ts.Node): string | Record<string, any> {
export function getVariableValue(node: ts.Node, program: ts.Program): string | Record<string, any> {
if (ts.isStringLiteral(node) || ts.isNumericLiteral(node)) {
return node.text;
}

if (ts.isObjectLiteralExpression(node)) {
return serializeObject(node);
return serializeObject(node, program);
}

if (ts.isIdentifier(node)) {
const declaration = getIdentifierDeclaration(node);
if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
return getVariableValue(declaration.initializer);
return getVariableValue(declaration.initializer, program);
} else {
// Go fetch it in another file
return getIdentifierValue(node, node, program, { chaseImport: true });
}
// TODO: If this is another imported value from another file, we'll need to go fetch it like in getPropertyValue
}

throw Error(`Unsuppored Node: cannot get value of node (${node.getText()}) of kind ${node.kind}`);
if (ts.isSpreadAssignment(node)) {
return getVariableValue(node.expression, program);
}

throw Error(
`Unsupported Node: cannot get value of node (${node.getText()}) of kind ${node.kind}`
);
}

export function serializeObject(node: ts.Node) {
export function serializeObject(node: ts.Node, program: ts.Program) {
if (!ts.isObjectLiteralExpression(node)) {
throw new Error(`Expecting Object literal Expression got ${node.getText()}`);
}

const value: Record<string, any> = {};
let value: Record<string, any> = {};
for (const property of node.properties) {
const propertyName = property.name?.getText();
const val = ts.isPropertyAssignment(property)
? getVariableValue(property.initializer, program)
: getVariableValue(property, program);

if (typeof propertyName === 'undefined') {
throw new Error(`Unable to get property name ${property.getText()}`);
}
const cleanPropertyName = propertyName.replace(/["']/g, '');
if (ts.isPropertyAssignment(property)) {
value[cleanPropertyName] = getVariableValue(property.initializer);
if (typeof val === 'object') {
value = { ...value, ...val };
} else {
throw new Error(`Unable to get property name ${property.getText()}`);
}
} else {
value[cleanPropertyName] = getVariableValue(property);
const cleanPropertyName = propertyName.replace(/["']/g, '');
value[cleanPropertyName] = val;
}
}

Expand All @@ -155,45 +168,53 @@ export function getResolvedModuleSourceFile(
return resolvedModuleSourceFile;
}

export function getPropertyValue(
export function getIdentifierValue(
node: ts.Node,
initializer: ts.Identifier,
program: ts.Program,
config: Optional<{ chaseImport: boolean }> = {}
) {
const { chaseImport = false } = config;
const identifierName = initializer.getText();
const declaration = getIdentifierDeclaration(initializer);
if (ts.isImportSpecifier(declaration)) {
if (!chaseImport) {
throw new Error(
`Value of node ${identifierName} is imported from another file. Chasing imports is not allowed.`
);
}

if (ts.isPropertyAssignment(node)) {
const { initializer } = node;
const importedModuleName = getModuleSpecifier(declaration);

if (ts.isIdentifier(initializer)) {
const identifierName = initializer.getText();
const declaration = getIdentifierDeclaration(initializer);
if (ts.isImportSpecifier(declaration)) {
if (!chaseImport) {
throw new Error(
`Value of node ${identifierName} is imported from another file. Chasing imports is not allowed.`
);
}
const source = node.getSourceFile();
const declarationSource = getResolvedModuleSourceFile(source, program, importedModuleName);
const declarationNode = getIdentifierDeclarationFromSource(initializer, declarationSource);
if (!ts.isVariableDeclaration(declarationNode)) {
throw new Error(`Expected ${identifierName} to be variable declaration.`);
}
if (!declarationNode.initializer) {
throw new Error(`Expected ${identifierName} to be initialized.`);
}
const serializedObject = serializeObject(declarationNode.initializer, program);
return serializedObject;
}

const importedModuleName = getModuleSpecifier(declaration);
return getVariableValue(declaration, program);
}

const source = node.getSourceFile();
const declarationSource = getResolvedModuleSourceFile(source, program, importedModuleName);
const declarationNode = getIdentifierDeclarationFromSource(initializer, declarationSource);
if (!ts.isVariableDeclaration(declarationNode)) {
throw new Error(`Expected ${identifierName} to be variable declaration.`);
}
if (!declarationNode.initializer) {
throw new Error(`Expected ${identifierName} to be initialized.`);
}
const serializedObject = serializeObject(declarationNode.initializer);
return serializedObject;
}
export function getPropertyValue(
node: ts.Node,
program: ts.Program,
config: Optional<{ chaseImport: boolean }> = {}
) {
if (ts.isPropertyAssignment(node)) {
const { initializer } = node;

return getVariableValue(declaration);
if (ts.isIdentifier(initializer)) {
return getIdentifierValue(node, initializer, program, config);
}

return getVariableValue(initializer);
return getVariableValue(initializer, program);
}
}

Expand Down
Loading

0 comments on commit f7e5f99

Please sign in to comment.