mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[pre-commit script] refactor for speed (#65202)
This commit is contained in:
parent
65447ec62f
commit
dc647a6e4c
7 changed files with 190 additions and 189 deletions
50
packages/kbn-dev-utils/src/precommit_hook/cli.ts
Normal file
50
packages/kbn-dev-utils/src/precommit_hook/cli.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 Path from 'path';
|
||||
import { chmod, writeFile } from 'fs';
|
||||
import { promisify } from 'util';
|
||||
|
||||
import { run } from '../run';
|
||||
import { REPO_ROOT } from '../repo_root';
|
||||
import { SCRIPT_SOURCE } from './script_source';
|
||||
import { getGitDir } from './get_git_dir';
|
||||
|
||||
const chmodAsync = promisify(chmod);
|
||||
const writeFileAsync = promisify(writeFile);
|
||||
|
||||
run(
|
||||
async ({ log }) => {
|
||||
try {
|
||||
const gitDir = await getGitDir();
|
||||
const installPath = Path.resolve(REPO_ROOT, gitDir, 'hooks/pre-commit');
|
||||
|
||||
log.info(`Registering Kibana pre-commit git hook...`);
|
||||
await writeFileAsync(installPath, SCRIPT_SOURCE);
|
||||
await chmodAsync(installPath, 0o755);
|
||||
log.success(`Kibana pre-commit git hook was installed successfully.`);
|
||||
} catch (e) {
|
||||
log.error(`Kibana pre-commit git hook was not installed as an error occur.`);
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
{
|
||||
description: 'Register git hooks in the local repo',
|
||||
}
|
||||
);
|
|
@ -17,4 +17,16 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export { registerPrecommitGitHook } from './register_git_hook';
|
||||
import execa from 'execa';
|
||||
|
||||
import { REPO_ROOT } from '../repo_root';
|
||||
|
||||
// Retrieves the correct location for the .git dir for
|
||||
// every git setup (including git worktree)
|
||||
export async function getGitDir() {
|
||||
return (
|
||||
await execa('git', ['rev-parse', '--git-common-dir'], {
|
||||
cwd: REPO_ROOT,
|
||||
})
|
||||
).stdout.trim();
|
||||
}
|
117
packages/kbn-dev-utils/src/precommit_hook/script_source.ts
Normal file
117
packages/kbn-dev-utils/src/precommit_hook/script_source.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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 os from 'os';
|
||||
|
||||
import normalizePath from 'normalize-path';
|
||||
|
||||
const HOME_DIR = normalizePath(os.homedir());
|
||||
|
||||
export const SCRIPT_SOURCE = `#!/usr/bin/env bash
|
||||
#
|
||||
# ** THIS IS AN AUTO-GENERATED FILE **
|
||||
# ** PLEASE DO NOT CHANGE IT MANUALLY **
|
||||
#
|
||||
# GENERATED BY \`node scripts/register_git_hook\`
|
||||
# IF YOU WANNA CHANGE SOMETHING IN THIS SCRIPT
|
||||
# PLEASE RE-RUN 'yarn kbn bootstrap' or 'node scripts/register_git_hook'
|
||||
|
||||
# pre-commit script takes zero arguments: https://git-scm.com/docs/githooks#_pre_commit
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Make it possible to terminate pre commit hook
|
||||
# using ctrl-c so nothing else would happen or be
|
||||
# sent to the output.
|
||||
#
|
||||
# The correct exit code on that situation
|
||||
# according the linux documentation project is 130
|
||||
# https://www.tldp.org/LDP/abs/html/exitcodes.html
|
||||
trap "exit 130" INT
|
||||
|
||||
has_node() {
|
||||
command -v node >/dev/null 2>&1
|
||||
}
|
||||
|
||||
has_nvm() {
|
||||
command -v nvm >/dev/null 2>&1
|
||||
}
|
||||
|
||||
try_load_node_from_nvm_paths () {
|
||||
# If nvm is not loaded, load it
|
||||
has_node || {
|
||||
NVM_SH="${HOME_DIR}/.nvm/nvm.sh"
|
||||
|
||||
if [ "${process.platform}" == "darwin" ] && [ -s "$(brew --prefix nvm)/nvm.sh" ]; then
|
||||
NVM_SH="$(brew --prefix nvm)/nvm.sh"
|
||||
fi
|
||||
|
||||
export NVM_DIR="${HOME_DIR}/.nvm"
|
||||
|
||||
[ -s "$NVM_SH" ] && \. "$NVM_SH"
|
||||
|
||||
# If nvm has been loaded correctly, use project .nvmrc
|
||||
has_nvm && nvm use
|
||||
}
|
||||
}
|
||||
|
||||
extend_user_path() {
|
||||
if [ "${process.platform}" == "win32" ]; then
|
||||
export PATH="$PATH:/c/Program Files/nodejs"
|
||||
else
|
||||
export PATH="$PATH:/usr/local/bin:/usr/local"
|
||||
try_load_node_from_nvm_paths
|
||||
fi
|
||||
}
|
||||
|
||||
# Extend path with common path locations for node
|
||||
# in order to make the hook working on git GUI apps
|
||||
extend_user_path
|
||||
|
||||
# Check if we have node js bin in path
|
||||
has_node || {
|
||||
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
|
||||
echo "If your PATH already has the node bin, maybe you are using some git GUI app."
|
||||
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
|
||||
echo "If your PATH already has the node bin, maybe you are using some git GUI app not launched from the shell."
|
||||
echo "In order to proceed, you need to config the PATH used by the application that are launching your git GUI app."
|
||||
echo "If you are running macOS, you can do that using:"
|
||||
echo "'sudo launchctl config user path /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
execute_precommit_hook() {
|
||||
node scripts/precommit_hook || return 1
|
||||
|
||||
PRECOMMIT_FILE="./.git/hooks/pre-commit.local"
|
||||
if [ -x "\${PRECOMMIT_FILE}" ]; then
|
||||
echo "Executing local precommit hook found in \${PRECOMMIT_FILE}"
|
||||
"$PRECOMMIT_FILE" || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
execute_precommit_hook || {
|
||||
echo "Pre-commit hook failed (add --no-verify to bypass)";
|
||||
echo ' For eslint failures you can try running \`node scripts/precommit_hook --fix\`';
|
||||
exit 1;
|
||||
}
|
||||
|
||||
exit 0
|
||||
`;
|
|
@ -17,5 +17,5 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
require('../src/setup_node_env');
|
||||
require('../src/dev/run_register_git_hook');
|
||||
require('../src/setup_node_env/prebuilt_dev_only_entry');
|
||||
require('@kbn/dev-utils/target/precommit_hook/cli');
|
||||
|
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* 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 chalk from 'chalk';
|
||||
import { chmod, unlink, writeFile } from 'fs';
|
||||
import dedent from 'dedent';
|
||||
import normalizePath from 'normalize-path';
|
||||
import os from 'os';
|
||||
import { resolve } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import SimpleGit from 'simple-git';
|
||||
import { REPO_ROOT } from '../constants';
|
||||
|
||||
const simpleGit = new SimpleGit(REPO_ROOT);
|
||||
|
||||
const chmodAsync = promisify(chmod);
|
||||
const gitRevParseAsync = promisify(simpleGit.revparse.bind(simpleGit));
|
||||
const unlinkAsync = promisify(unlink);
|
||||
const writeFileAsync = promisify(writeFile);
|
||||
|
||||
async function getPrecommitGitHookScriptPath(rootPath) {
|
||||
// Retrieves the correct location for the .git dir for
|
||||
// every git setup (including git worktree)
|
||||
const gitDirPath = (await gitRevParseAsync(['--git-common-dir'])).trim();
|
||||
|
||||
return resolve(rootPath, gitDirPath, 'hooks/pre-commit');
|
||||
}
|
||||
|
||||
function getKbnPrecommitGitHookScript(rootPath, nodeHome, platform) {
|
||||
return dedent(`
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# ** THIS IS AN AUTO-GENERATED FILE **
|
||||
# ** PLEASE DO NOT CHANGE IT MANUALLY **
|
||||
#
|
||||
# GENERATED BY ${__dirname}
|
||||
# IF YOU WANNA CHANGE SOMETHING INTO THIS SCRIPT
|
||||
# PLEASE RE-RUN 'yarn kbn bootstrap' or 'node scripts/register_git_hook' IN THE ROOT
|
||||
# OF THE CURRENT PROJECT ${rootPath}
|
||||
|
||||
# pre-commit script takes zero arguments: https://git-scm.com/docs/githooks#_pre_commit
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Make it possible to terminate pre commit hook
|
||||
# using ctrl-c so nothing else would happen or be
|
||||
# sent to the output.
|
||||
#
|
||||
# The correct exit code on that situation
|
||||
# according the linux documentation project is 130
|
||||
# https://www.tldp.org/LDP/abs/html/exitcodes.html
|
||||
trap "exit 130" INT
|
||||
|
||||
has_node() {
|
||||
command -v node >/dev/null 2>&1
|
||||
}
|
||||
|
||||
has_nvm() {
|
||||
command -v nvm >/dev/null 2>&1
|
||||
}
|
||||
|
||||
try_load_node_from_nvm_paths () {
|
||||
# If nvm is not loaded, load it
|
||||
has_node || {
|
||||
NVM_SH="${nodeHome}/.nvm/nvm.sh"
|
||||
|
||||
if [ "${platform}" == "darwin" ] && [ -s "$(brew --prefix nvm)/nvm.sh" ]; then
|
||||
NVM_SH="$(brew --prefix nvm)/nvm.sh"
|
||||
fi
|
||||
|
||||
export NVM_DIR=${nodeHome}/.nvm
|
||||
|
||||
[ -s "$NVM_SH" ] && \. "$NVM_SH"
|
||||
|
||||
# If nvm has been loaded correctly, use project .nvmrc
|
||||
has_nvm && nvm use
|
||||
}
|
||||
}
|
||||
|
||||
extend_user_path() {
|
||||
if [ "${platform}" == "win32" ]; then
|
||||
export PATH="$PATH:/c/Program Files/nodejs"
|
||||
else
|
||||
export PATH="$PATH:/usr/local/bin:/usr/local"
|
||||
try_load_node_from_nvm_paths
|
||||
fi
|
||||
}
|
||||
|
||||
# Extend path with common path locations for node
|
||||
# in order to make the hook working on git GUI apps
|
||||
extend_user_path
|
||||
|
||||
# Check if we have node js bin in path
|
||||
has_node || {
|
||||
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
|
||||
echo "If your PATH already has the node bin, maybe you are using some git GUI app."
|
||||
echo "Can't found node bin in the PATH. Please update the PATH to proceed."
|
||||
echo "If your PATH already has the node bin, maybe you are using some git GUI app not launched from the shell."
|
||||
echo "In order to proceed, you need to config the PATH used by the application that are launching your git GUI app."
|
||||
echo "If you are running macOS, you can do that using:"
|
||||
echo "'sudo launchctl config user path /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin'"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
execute_precommit_hook() {
|
||||
node scripts/precommit_hook || return 1
|
||||
|
||||
PRECOMMIT_FILE="./.git/hooks/pre-commit.local"
|
||||
if [ -x "\${PRECOMMIT_FILE}" ]; then
|
||||
echo "Executing local precommit hook found in \${PRECOMMIT_FILE}"
|
||||
"$PRECOMMIT_FILE" || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
execute_precommit_hook || {
|
||||
echo "Pre-commit hook failed (add --no-verify to bypass)";
|
||||
echo ' For eslint failures you can try running \`node scripts/precommit_hook --fix\`';
|
||||
exit 1;
|
||||
}
|
||||
|
||||
exit 0
|
||||
`);
|
||||
}
|
||||
|
||||
export async function registerPrecommitGitHook(log) {
|
||||
log.write(chalk.bold(`Registering Kibana pre-commit git hook...\n`));
|
||||
|
||||
try {
|
||||
await writeGitHook(
|
||||
await getPrecommitGitHookScriptPath(REPO_ROOT),
|
||||
getKbnPrecommitGitHookScript(REPO_ROOT, normalizePath(os.homedir()), process.platform)
|
||||
);
|
||||
} catch (e) {
|
||||
log.write(
|
||||
`${chalk.red('fail')} Kibana pre-commit git hook was not installed as an error occur.\n`
|
||||
);
|
||||
throw e;
|
||||
}
|
||||
|
||||
log.write(`${chalk.green('success')} Kibana pre-commit git hook was installed successfully.\n`);
|
||||
}
|
||||
|
||||
async function writeGitHook(gitHookScriptPath, kbnHookScriptSource) {
|
||||
try {
|
||||
await unlinkAsync(gitHookScriptPath);
|
||||
} catch (e) {
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
await writeFileAsync(gitHookScriptPath, kbnHookScriptSource);
|
||||
await chmodAsync(gitHookScriptPath, 0o755);
|
||||
}
|
|
@ -17,12 +17,5 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
// The following require statements MUST be executed before any others - BEGIN
|
||||
require('./exit_on_warning');
|
||||
require('./harden');
|
||||
// The following require statements MUST be executed before any others - END
|
||||
|
||||
require('symbol-observable');
|
||||
require('./root');
|
||||
require('./node_version_validator');
|
||||
require('./prebuilt_dev_only_entry');
|
||||
require('./babel_register');
|
||||
|
|
|
@ -17,13 +17,11 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { run, createFailError } from '@kbn/dev-utils';
|
||||
import { registerPrecommitGitHook } from './register_git_hook';
|
||||
// The following require statements MUST be executed before any others - BEGIN
|
||||
require('./exit_on_warning');
|
||||
require('./harden');
|
||||
// The following require statements MUST be executed before any others - END
|
||||
|
||||
run(async ({ log }) => {
|
||||
try {
|
||||
await registerPrecommitGitHook(log);
|
||||
} catch (error) {
|
||||
throw createFailError(error);
|
||||
}
|
||||
});
|
||||
require('symbol-observable');
|
||||
require('./root');
|
||||
require('./node_version_validator');
|
Loading…
Add table
Add a link
Reference in a new issue