export async function getBazelTargetsFromPackages()

in src/bazel/bazelTestUtils.ts [228:307]


export async function getBazelTargetsFromPackages(
	testconfig: TestConfig,
	packages: string[],
	currentGoWorkspace: string,
	debugConfig?: vscode.DebugConfiguration
): Promise<string[]> {
	const bazelTargets: string[] = [];

	for (const pkg of packages) {
		if (debugConfig) {
			const QueryResult = (await protobuf.load(path.join(__dirname, BUILD_PROTO))).lookupType(
				'blaze_query.QueryResult'
			);
			const debugTarget = await new Promise<string>((resolve) => {
				// processQueryResults contains all post-run processing steps, and is called at the completion of the query process.
				// This will be passed a full copy of the stdout buffer, containing the protobuf encoded results.
				const processQueryResults = (error: ExecException | null, stdout: Buffer) => {
					errBuf.done();
					testOutputChannel.appendLine('INFO: Query complete. Parsing results.');

					try {
						// eslint-disable-next-line @typescript-eslint/no-explicit-any
						const queryResults = <any>QueryResult.decode(stdout);
						for (const target of queryResults.target) {
							// Check each target in the results until we find the first one containing this test's file in its srcs.
							// eslint-disable-next-line @typescript-eslint/no-explicit-any
							const srcs = target.rule.attribute.filter((attr: any) => attr.name === 'srcs')[0];
							const isValidMatch =
								srcs?.stringListValue.filter((item: string) =>
									item.endsWith(`${pkg}:${debugConfig.fileName}`)
								).length > 0;
							if (isValidMatch) {
								testOutputChannel.appendLine(
									'INFO: Matching target found. Using :' + target.rule.name.split(':')[1]
								);
								return resolve(':' + target.rule.name.split(':')[1]);
							}
						}
					} catch (e) {
						testOutputChannel.append('ERROR: Failure while parsing query results.');
					}

					testOutputChannel.appendLine(
						'INFO: Unable to confirm matching target. Substituting :go_default_test.'
					);
					return resolve(':go_default_test');
				};

				// Run Bazel query to get all eligible test targets in the current package.
				const queryString = `'kind("^go_test rule$", tests(${pkg}:all))'`;
				const queryArgs = ['query', queryString, '--tool_tag=vscode-go-bazel', '--output=proto'];
				testOutputChannel.appendLine(['Running command:', 'bazel', ...queryArgs].join(' '));
				const queryProcess = cp.exec(
					['bazel', ...queryArgs].join(' '),
					{
						cwd: currentGoWorkspace,
						encoding: null // Ensures that the callback function is passed unencoded binary data.
					},
					processQueryResults
				);

				// Real-time output of any user-readable data emitted on stderr.
				const errBuf = new LineBuffer();
				errBuf.onLine((line) => testOutputChannel.appendLine(line));
				errBuf.onDone((last) => last && testOutputChannel.appendLine(last));
				queryProcess.stderr?.on('data', (chunk) => errBuf.append(chunk.toString()));

				statusBarItem.show();
			});

			bazelTargets.push(pkg + debugTarget);
			continue;
		}

		// Always use target :all for non-debug sessions since we will run with --build_tests_only.
		// Can consider moving into the query above (tradeoff between time to run query every time vs. potentially building extra test targets).
		bazelTargets.push(pkg + ':all');
	}
	return bazelTargets;
}