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

chore(NA): introduce new yarn kbn reset command to support bazel workflow #89597

Merged
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b89c402
chore(NA): introduce new yarn kbn destroy command to support bazel wo…
mistic Jan 28, 2021
229e602
Merge remote-tracking branch 'upstream/master' into add-kbn-destroy-c…
mistic Jan 28, 2021
4149c35
chore(NA): update wording for new kbn pm changes
mistic Jan 28, 2021
5bc9861
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Jan 28, 2021
2a6aebf
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Jan 28, 2021
60ad545
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Jan 28, 2021
77ed40a
Merge remote-tracking branch 'upstream/master' into add-kbn-destroy-c…
mistic Jan 28, 2021
bf74bf8
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Jan 29, 2021
c62a943
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Jan 31, 2021
0ebe848
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Feb 2, 2021
c830f51
chore(NA): update .bazelrc.common
mistic Feb 2, 2021
dafb69f
chore(NA): update .bazelrc
mistic Feb 2, 2021
198ab76
chore(NA): update packages/kbn-pm/src/commands/clean.ts
mistic Feb 2, 2021
8b4b975
chore(NA): update packages/kbn-pm/src/commands/destroy.ts
mistic Feb 2, 2021
6174436
chore(NA): update packages/kbn-pm/src/commands/clean.ts
mistic Feb 2, 2021
19f1413
chore(NA): update packages/kbn-pm/src/commands/destroy.ts
mistic Feb 2, 2021
f5ef355
chore(NA): rename destroy command into reset
mistic Feb 2, 2021
12b83f7
Merge remote-tracking branch 'upstream/master' into add-kbn-destroy-c…
mistic Feb 2, 2021
94def68
chore(NA): update packages/kbn-pm/src/commands/clean.ts
mistic Feb 2, 2021
37ba587
chore(NA): restore old behaviour on kbn clean
mistic Feb 2, 2021
5c52143
chore(NA): update reset command to delete bazel caches on disk
mistic Feb 2, 2021
5a46fa8
chore(NA): update packages/kbn-pm/src/commands/clean.ts
mistic Feb 2, 2021
976eb34
chore(NA): update prefix to match bazel defined one for cache settings
mistic Feb 2, 2021
4740d1b
Merge branch 'add-kbn-destroy-cmd-for-bazel-integration' of github.co…
mistic Feb 2, 2021
aee3b7f
chore(NA): update kbn pm dist file
mistic Feb 2, 2021
a8abd93
chore(NA): merge and solve conflicts with master
mistic Feb 3, 2021
9f844e9
chore(NA): update kbn pm dist
mistic Feb 3, 2021
ac98e19
chore(NA): update gitignore
mistic Feb 3, 2021
1354eeb
Merge remote-tracking branch 'upstream/master' into add-kbn-destroy-c…
mistic Feb 3, 2021
f8a9ef5
chore(NA): add new ignore files after changed bazel aggregated folder
mistic Feb 3, 2021
3176915
Merge remote-tracking branch 'upstream/master' into add-kbn-destroy-c…
mistic Feb 3, 2021
4f35ee9
Merge branch 'master' into add-kbn-destroy-cmd-for-bazel-integration
kibanamachine Feb 3, 2021
7e0afa2
chore(NA): merging and solve conflicts with master
mistic Feb 3, 2021
e27c9bb
Merge branch 'add-kbn-destroy-cmd-for-bazel-integration' of github.co…
mistic Feb 3, 2021
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
2 changes: 1 addition & 1 deletion .bazelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Inspired on from https://raw.githubusercontent.com/bazelbuild/rules_nodejs/master/.bazelrc
# Inspired by https://raw.githubusercontent.com/bazelbuild/rules_nodejs/master/.bazelrc
# Import shared settings first so we can override below
import %workspace%/.bazelrc.common

Expand Down
23 changes: 13 additions & 10 deletions .bazelrc.common
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@
#
# The full list of Bazel options: https://docs.bazel.build/versions/master/command-line-reference.html

# Cache action outputs on disk so they persist across output_base and bazel shutdown (eg. changing branches)
build --disk_cache=bazel-cache/disk-cache
# Local Cache Settings
## Avoid cache results from being corrupt when changing source during build
common --experimental_guard_against_concurrent_changes

# Bazel repo cache settings
build --repository_cache=bazel-cache/repository-cache
## Cache action outputs on disk so they persist across output_base and bazel shutdown (eg. changing branches)
build --disk_cache=~/.bazel-cache/disk-cache

## Bazel repo cache settings
build --repository_cache=~/.bazel-cache/repository-cache

# Bazel will create symlinks from the workspace directory to output artifacts.
# Build results will be placed in a directory called "bazel-dist/bin"
# Build results will be placed in a directory called "bazel/bin"
# This will still create a bazel-out symlink in
# the project directory, which must be excluded from the
# editor's search path.
build --symlink_prefix=bazel-dist/
build --symlink_prefix=bazel/
# To disable the symlinks altogether (including bazel-out) we can use
# build --symlink_prefix=/
# however this makes it harder to find outputs.
Expand All @@ -37,9 +41,7 @@ common --color=yes
build --show_task_finish
build --noshow_progress
build --noshow_loading_progress

## enforced default values
build --show_result=1
build --show_result=0

# Specifies desired output mode for running tests.
# Valid values are
Expand Down Expand Up @@ -78,7 +80,8 @@ test:debug --test_output=streamed --test_strategy=exclusive --test_timeout=9999
# The node process will break before user code starts and wait for the debugger to connect.
run:debug --define=VERBOSE_LOGS=1 -- --node_options=--inspect-brk
# The following option will change the build output of certain rules such as terser and may not be desirable in all cases
build:debug --compilation_mode=dbg
# It will also output both the repo cache and action cache to a folder inside the repo
build:debug --compilation_mode=dbg --show_result=1 --disk_cache=bazel-cache/disk-cache --repository_cache=bazel-cache/repository-cache
mistic marked this conversation as resolved.
Show resolved Hide resolved

# Turn off legacy external runfiles
# This prevents accidentally depending on this feature, which Bazel will remove.
Expand Down
3 changes: 3 additions & 0 deletions packages/kbn-dev-utils/stdio/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"main": "../target/stdio"
}
19,846 changes: 10,092 additions & 9,754 deletions packages/kbn-pm/dist/index.js

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion packages/kbn-pm/src/commands/clean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,27 @@
* Public License, v 1.
*/

import dedent from 'dedent';
import del from 'del';
import ora from 'ora';
import { join, relative } from 'path';

import { runBazel } from '../utils/bazel';
import { isDirectory } from '../utils/fs';
import { log } from '../utils/log';
import { ICommand } from './';

export const CleanCommand: ICommand = {
description: 'Remove the node_modules and target directories from all projects.',
description: 'Deletes output directories, node_modules and resets internal caches.',
name: 'clean',

async run(projects) {
log.warning(dedent`
This command is only necessary for the rare circumstance where you need to recover a consistent
state when problems arise. If you need to run this command often, please let us know by
filling out this form: https://ela.st/yarn-kbn-clean.
mistic marked this conversation as resolved.
Show resolved Hide resolved
`);

const toDelete = [];
for (const project of projects.values()) {
if (await isDirectory(project.nodeModulesLocation)) {
Expand All @@ -44,6 +52,10 @@ export const CleanCommand: ICommand = {
}
}

// Runs Bazel soft clean
await runBazel(['clean']);
log.success('Soft cleaned bazel');

if (toDelete.length === 0) {
log.success('Nothing to delete');
} else {
Expand Down
2 changes: 2 additions & 0 deletions packages/kbn-pm/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ export interface ICommand {

import { BootstrapCommand } from './bootstrap';
import { CleanCommand } from './clean';
import { ResetCommand } from './reset';
import { RunCommand } from './run';
import { WatchCommand } from './watch';
import { Kibana } from '../utils/kibana';

export const commands: { [key: string]: ICommand } = {
bootstrap: BootstrapCommand,
clean: CleanCommand,
reset: ResetCommand,
run: RunCommand,
watch: WatchCommand,
};
94 changes: 94 additions & 0 deletions packages/kbn-pm/src/commands/reset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* and the Server Side Public License, v 1; you may not use this file except in
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/

import dedent from 'dedent';
import del from 'del';
import ora from 'ora';
import { join, relative } from 'path';

import { getBazelDiskCacheFolder, getBazelRepositoryCacheFolder, runBazel } from '../utils/bazel';
import { isDirectory } from '../utils/fs';
import { log } from '../utils/log';
import { ICommand } from './';

export const ResetCommand: ICommand = {
description:
'Deletes node_modules and output directories, resets internal and disk caches, and stops Bazel server',
name: 'reset',

async run(projects) {
log.warning(dedent`
In most cases, 'yarn kbn clean' is all that should be needed to recover a consistent state when
problems arise. If you need to use this command, please let us know, as it should not be necessary.
`);

const toDelete = [];
for (const project of projects.values()) {
if (await isDirectory(project.nodeModulesLocation)) {
toDelete.push({
cwd: project.path,
pattern: relative(project.path, project.nodeModulesLocation),
});
}

if (await isDirectory(project.targetLocation)) {
toDelete.push({
cwd: project.path,
pattern: relative(project.path, project.targetLocation),
});
}

const { extraPatterns } = project.getCleanConfig();
if (extraPatterns) {
toDelete.push({
cwd: project.path,
pattern: extraPatterns,
});
}
}

// Runs Bazel hard clean
await runBazel(['clean', '--expunge']);
log.success('Hard cleaned bazel');

// Deletes Bazel Cache Folders
await del([await getBazelDiskCacheFolder(), await getBazelRepositoryCacheFolder()], {
tylersmalley marked this conversation as resolved.
Show resolved Hide resolved
force: true,
});
log.success('Removed disk caches');

if (toDelete.length === 0) {
return;
}

/**
* In order to avoid patterns like `/build` in packages from accidentally
* impacting files outside the package we use `process.chdir()` to change
* the cwd to the package and execute `del()` without the `force` option
* so it will check that each file being deleted is within the package.
*
* `del()` does support a `cwd` option, but it's only for resolving the
* patterns and does not impact the cwd check.
*/
const originalCwd = process.cwd();
try {
for (const { pattern, cwd } of toDelete) {
process.chdir(cwd);
const promise = del(pattern);

if (log.wouldLogLevel('info')) {
ora.promise(promise, relative(originalCwd, join(cwd, String(pattern))));
}

await promise;
}
} finally {
process.chdir(originalCwd);
}
},
};
25 changes: 25 additions & 0 deletions packages/kbn-pm/src/utils/bazel/get_cache_folders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* and the Server Side Public License, v 1; you may not use this file except in
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/

import { dirname, resolve } from 'path';
import { spawn } from '../child_process';

async function rawRunBazelInfoRepoCache() {
const { stdout: bazelRepositoryCachePath } = await spawn('bazel', ['info', 'repository_cache'], {
stdio: 'pipe',
});
return bazelRepositoryCachePath;
}

export async function getBazelDiskCacheFolder() {
return resolve(dirname(await rawRunBazelInfoRepoCache()), 'disk-cache');
mistic marked this conversation as resolved.
Show resolved Hide resolved
}

export async function getBazelRepositoryCacheFolder() {
return await rawRunBazelInfoRepoCache();
}
2 changes: 2 additions & 0 deletions packages/kbn-pm/src/utils/bazel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
* Public License, v 1.
*/

export * from './get_cache_folders';
export * from './install_tools';
export * from './run';
43 changes: 43 additions & 0 deletions packages/kbn-pm/src/utils/bazel/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* and the Server Side Public License, v 1; you may not use this file except in
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/

import chalk from 'chalk';
import execa from 'execa';
import * as Rx from 'rxjs';
import { tap } from 'rxjs/operators';
import { observeLines } from '@kbn/dev-utils/stdio';
import { spawn } from '../child_process';
import { log } from '../log';

export async function runBazel(bazelArgs: string[], runOpts: execa.Options = {}) {
// Force logs to pipe in order to control the output of them
const bazelOpts: execa.Options = {
...runOpts,
stdio: 'pipe',
};

const bazelProc = spawn('bazel', bazelArgs, bazelOpts);

const bazelLogs$ = new Rx.Subject<string>();

// Bazel outputs machine readable output into stdout and human readable output goes to stderr.
// Therefore we need to get both. In order to get errors we need to parse the actual text line
const bazelLogSubscription = Rx.merge(
observeLines(bazelProc.stdout!).pipe(
tap((line) => log.info(`${chalk.cyan('[bazel]')} ${line}`))
),
observeLines(bazelProc.stderr!).pipe(
tap((line) => log.info(`${chalk.cyan('[bazel]')} ${line}`))
)
).subscribe(bazelLogs$);

// Wait for process and logs to finish, unsubscribing in the end
await bazelProc;
await bazelLogs$.toPromise();
await bazelLogSubscription.unsubscribe();
}