Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for painless language autocomplete within monaco #80577

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
19fb59f
painless autocomplete with stubbed data
alisonelizabeth Oct 8, 2020
6981934
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Oct 13, 2020
ab6ef61
add descriptions for autcomplete
alisonelizabeth Oct 13, 2020
1de9f52
extract autocomplete logic + add support for constructor autocomplete
alisonelizabeth Oct 14, 2020
f0e31b8
move painless monaco code to kbn/monaco package
alisonelizabeth Oct 16, 2020
7965d31
move painless lang support out of painless_lab
alisonelizabeth Oct 16, 2020
f02b836
add support to specify context for autocomplete
alisonelizabeth Oct 16, 2020
7a4f372
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Oct 19, 2020
cc4964c
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Oct 22, 2020
b5db29e
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Oct 26, 2020
00efc3c
app support for switching contexts
alisonelizabeth Oct 27, 2020
ed23ea1
added script to generate autocomplete definitions
alisonelizabeth Oct 27, 2020
1658496
add support for fields autocomplete
alisonelizabeth Oct 29, 2020
b558097
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Oct 29, 2020
dbf4063
fix TS
alisonelizabeth Oct 29, 2020
5ffe030
cleanup script
alisonelizabeth Oct 30, 2020
254e47f
add back support for constructor autocomplete
alisonelizabeth Nov 2, 2020
5c310c5
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Nov 2, 2020
b6904d0
code cleanup
alisonelizabeth Nov 2, 2020
6f85233
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Nov 3, 2020
d1c90a4
update tests
alisonelizabeth Nov 3, 2020
8f674e5
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Nov 5, 2020
b2f5a06
add readme
alisonelizabeth Nov 5, 2020
1f50f23
cleanup + tests
alisonelizabeth Nov 5, 2020
0457b15
remove duplicate methods from autocomplete suggestions
alisonelizabeth Nov 6, 2020
b6a7d64
add support for multiple return value types
alisonelizabeth Nov 10, 2020
0aae95f
integrate autocomplete with other plugins
alisonelizabeth Nov 11, 2020
9b15fdf
Revert "integrate autocomplete with other plugins"
alisonelizabeth Nov 12, 2020
f358d8b
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Nov 12, 2020
356e45f
delete submodule
alisonelizabeth Nov 12, 2020
9094383
Merge branch 'master' of github.com:elastic/kibana into painless-mona…
alisonelizabeth Nov 17, 2020
31e32d3
address review feedback
alisonelizabeth Nov 17, 2020
46a1538
remove $ in class names
alisonelizabeth Nov 17, 2020
77cbfd5
do not create shortname for non-imported classes
alisonelizabeth Nov 17, 2020
0ce4fa6
cleanup
alisonelizabeth Nov 18, 2020
761109a
update script comment
alisonelizabeth Nov 18, 2020
427e2b9
Merge branch 'master' into painless-monaco-autocomplete
kibanamachine Nov 18, 2020
a2939bf
Merge branch 'master' into painless-monaco-autocomplete
kibanamachine Nov 20, 2020
472f7bf
Merge branch 'master' into painless-monaco-autocomplete
kibanamachine Nov 26, 2020
e2f50e7
Merge branch 'master' into painless-monaco-autocomplete
kibanamachine Nov 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"src/plugins/management"
],
"maps_legacy": "src/plugins/maps_legacy",
"monaco": "packages/kbn-monaco/src",
"indexPatternManagement": "src/plugins/index_pattern_management",
"advancedSettings": "src/plugins/advanced_settings",
"kibana_legacy": "src/plugins/kibana_legacy",
Expand Down
52 changes: 52 additions & 0 deletions packages/kbn-monaco/scripts/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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.
*/

module.exports = {
licenseHeader: `/*
* 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.
*/
`,
supportedContexts: [
'boolean_script_field_script_field',
'date_script_field',
'double_script_field_script_field',
'filter',
'ip_script_field_script_field',
'long_script_field_script_field',
'painless_test',
'processor_conditional',
'score',
'string_script_field_script_field',
],
};
102 changes: 102 additions & 0 deletions packages/kbn-monaco/scripts/generate_autocomplete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* 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.
*/

const { join } = require('path');
const { readdirSync, readFileSync, writeFileSync } = require('fs');
const minimist = require('minimist');
const semver = require('semver');
const ora = require('ora');
const del = require('del');

const {
cloneAndCheckout,
createAutocompleteDefinitions,
createAutocompleteExports,
} = require('./utils');
const { supportedContexts } = require('./constants');

start(
minimist(process.argv.slice(2), {
string: ['tag', 'branch'],
})
);

function start(opts) {
const log = ora('Loading Elasticsearch repository').start();

if (opts.branch == null && semver.valid(opts.tag) === null) {
log.fail(`Missing or invalid tag: ${opts.tag}`);
return;
}

const autocompleteOutputFolder = join(
__dirname,
'..',
'src',
'painless',
'autocomplete_definitions'
);

log.text = 'Cleaning autocomplete definitions folder';
del.sync([`${autocompleteOutputFolder}/**`]);

cloneAndCheckout(
{ log, tag: opts.tag, branch: opts.branch },
(err, { esPainlessContextFolder }) => {
if (err) {
log.fail(err.message);
return;
}

const painlessContextFolderContents = readdirSync(esPainlessContextFolder);

// Generate autocomplete definitions
painlessContextFolderContents
.filter((file) => {
// Expected filename format: whitelist-<contextName>.json
const contextName = file.split('.')[0].split('whitelist-').pop();
return supportedContexts.includes(contextName);
})
.forEach((file) => {
try {
const { name, classes: painlessClasses } = JSON.parse(
readFileSync(join(esPainlessContextFolder, file), 'utf8')
);
const filePath = join(autocompleteOutputFolder, `${name}.json`);
const code = JSON.stringify(
{ suggestions: createAutocompleteDefinitions(painlessClasses) },
null,
2
);
writeFileSync(filePath, code, { encoding: 'utf8' });
} catch (err) {
log.fail(err.message);
}
});

// Create index.ts file for autocomplete definitions
const indexFilePath = join(autocompleteOutputFolder, 'index.ts');
const indexCode = createAutocompleteExports();

writeFileSync(indexFilePath, indexCode, { encoding: 'utf8' });

log.succeed('Painless autocomplete definitions generated successfully');
}
);
}
149 changes: 149 additions & 0 deletions packages/kbn-monaco/scripts/utils/clone_es.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* 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.
*/

const { accessSync, mkdirSync } = require('fs');
const { join } = require('path');
const simpleGit = require('simple-git');

// Note: The generated whitelists have not yet been merged to master
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alisonelizabeth Per #71398 we should refer to allowlists instead of whitelists and blocklists instead of blacklists.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! Will fix in #85055.

// so this script may fail until code in this branch has been merged:
// https://github.com/stu-elastic/elasticsearch/tree/scripting/whitelists
const esRepo = 'https://github.com/elastic/elasticsearch.git';

const esFolder = join(__dirname, '..', '..', 'elasticsearch');
const esPainlessContextFolder = join(
esFolder,
'modules',
'lang-painless',
'src',
'main',
'generated'
);

/**
* Checks if the given path exists
* @param {string} path
* @returns {boolean} true if exists, false if not
*/
const pathExist = (path) => {
try {
accessSync(path);
return true;
} catch (err) {
return false;
}
};

/**
* Creates the given folder
* @param {string} name
* @returns {boolean} true on success, false on failure
*/
const createFolder = (name) => {
try {
mkdirSync(name);
return true;
} catch (err) {
return false;
}
};

/**
* Sets the Elasticsearch repository to the given branch or tag.
* If the repository is not present in `esFolder` it will
* clone the repository and the checkout the branch or tag.
* If the repository is already present but it cannot checkout to
* the given tag, it will perform a pull and then try again.
*
* This code was largely borrowed from the ES JS client:
* https://github.com/elastic/elasticsearch-js/blob/master/scripts/utils/clone-es.js
*
* @param {object} options
* @param {function} callback
*/
const cloneAndCheckout = (opts, callback) => {
const { log, tag, branch } = opts;

let fresh = false;
let retry = 0;

if (!pathExist(esFolder)) {
if (!createFolder(esFolder)) {
log.fail('Failed to create ES folder');
return;
}
fresh = true;
}

const git = simpleGit(esFolder);

const pull = (cb) => {
log.text = 'Pulling Elasticsearch repository';

git.pull((err) => {
if (err) {
callback(err, { esPainlessContextFolder });
return;
}
cb();
});
};

const clone = (cb) => {
log.text = 'Cloning Elasticsearch repository';

git.clone(esRepo, esFolder, (err) => {
if (err) {
callback(err, { esPainlessContextFolder });
return;
}
cb();
});
};

const checkout = (alsoPull = false) => {
if (branch) {
log.text = `Checking out branch '${branch}'`;
} else {
log.text = `Checking out tag '${tag}'`;
}

git.checkout(branch || tag, (err) => {
if (err) {
if (retry++ > 0) {
callback(new Error(`Cannot checkout '${branch || tag}'`), { esPainlessContextFolder });
return;
}
return pull(checkout);
}
if (alsoPull) {
return pull(checkout);
}
callback(null, { esPainlessContextFolder });
});
};

if (fresh) {
clone(checkout);
} else {
checkout(Boolean(opts.branch));
}
};

module.exports = cloneAndCheckout;
Loading