UNPKG

@amplitude/ampli

Version:

Amplitude CLI

74 lines (73 loc) 3.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const lodash_1 = require("lodash"); const base_1 = require("../base"); const toInt = (i) => parseInt(i, 10) || 0; class PythonVerifier extends base_1.Verifier { constructor(ampliInstanceNames = ['itly']) { super('py', ampliInstanceNames); this.ampliInstanceNames = ampliInstanceNames; this.getReferenceName = (eventName) => lodash_1.snakeCase(eventName); } static createInstanceNameRegex(instanceName) { const nameParts = instanceName.split('.'); const result = []; for (let i = nameParts.length - 1; i >= 0; i -= 1) { result.push(i > 0 ? `value=Attribute\\(` : `value=Name\\(`); } for (let i = 0; i < nameParts.length; i += 1) { result.push(i === 0 ? `id='${nameParts[i]}', ctx=Load\\(\\), lineno=(\\d+), col_offset=(\\d+)[^)]*\\)` : `attr='${nameParts[i]}', ctx=Load\\(\\)[^)]*\\)`); if (i < nameParts.length - 1) { result.push(', '); } } return `(?:${result.join('')})`; } static createRegex(instanceName) { return new RegExp(`Expr\\(value=Call\\(func=Attribute\\(${PythonVerifier.createInstanceNameRegex(instanceName)}, attr='([^']+)'`, 'g'); } static createTrackRegex(instanceName) { return new RegExp(`Expr\\(value=Call\\(func=Attribute\\(${PythonVerifier.createInstanceNameRegex(instanceName)}, attr='track', ctx=Load\\(\\), lineno=\\d+, col_offset=\\d+[^)]*\\), args=\\[(.*?)]`, 'g'); } static createEventClassByAttrRegex(instanceName) { return new RegExp(`, Call\\(func=Attribute\\(value=Name\\(id='${PythonVerifier.createInstanceNameRegex(instanceName)}', ctx=Load\\(\\), lineno=\\d+, col_offset=\\d+[^)]*\\), attr='([^']+)'`, 'g'); } checkDependencies() { super.checkDependencies(); this.execSyncToString(`python3 --version`); } async doVerify(eventNames, workingDirs) { return this.verifyEach((filePath, _, addReference) => { const script = `import ast; print(ast.dump(ast.parse(open("${filePath}").read()), True, True))`; const command = `python3 -c '${script}'`; const stdout = this.execSyncToString(command); this.ampliInstanceNames.forEach(instanceName => { const regex = PythonVerifier.createRegex(instanceName); const trackRegex = PythonVerifier.createTrackRegex(instanceName); const eventClassByAttrRegex = PythonVerifier.createEventClassByAttrRegex(instanceName); let trackMatch = trackRegex.exec(stdout); while (trackMatch != null) { const [match, row, column] = trackMatch; const eventClassNameMatch = PythonVerifier.eventClassByName.exec(match); const eventClassAttrMatch = eventClassByAttrRegex.exec(match); [eventClassNameMatch, eventClassAttrMatch].filter((m) => !!m).forEach(m => { const [, eventClassName] = m; const name = lodash_1.snakeCase(eventClassName); addReference({ filePath, name, row: toInt(row), column: toInt(column) }); }); trackMatch = trackRegex.exec(stdout); } let match = regex.exec(stdout); while (match != null) { const [, row, column, name] = match; addReference({ filePath, name, row: toInt(row), column: toInt(column) }); match = regex.exec(stdout); } }); }, workingDirs); } } exports.default = PythonVerifier; PythonVerifier.eventClassByName = /\bCall\(func=Name\(id='([^']+)'/;