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

[scripts, teraslice-cli, ts-transforms] Update execa from 5.1.0 to 9.4.0 #3767

Merged
merged 6 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 packages/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@kubernetes/client-node": "^0.21.0",
"@terascope/utils": "^1.1.0",
"codecov": "^3.8.3",
"execa": "^5.1.0",
"execa": "9.4.0",
"fs-extra": "^11.2.0",
"globby": "^11.0.4",
"got": "^11.8.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/scripts/src/helpers/k8s-env/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import execa from 'execa';
import { execaCommandSync } from 'execa';
import {
dockerTag, isKindInstalled, isKubectlInstalled,
k8sStartService, k8sStopService, getNodeVersionFromImage
Expand Down Expand Up @@ -85,7 +85,7 @@ export async function launchK8sEnv(options: K8sEnvOptions) {
}
signale.info(`Running yarn setup with node ${process.version}...`);
try {
execa.commandSync('yarn setup');
execaCommandSync('yarn setup');
} catch (err) {
signale.fatal(err);
await kind.destroyCluster();
Expand Down
4 changes: 2 additions & 2 deletions packages/scripts/src/helpers/k8s-env/k8s.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as k8sClient from '@kubernetes/client-node';
import fs from 'node:fs';
import ms from 'ms';
import path from 'node:path';
import execa from 'execa';
import { execaCommand } from 'execa';
import { cloneDeep, debugLogger, pDelay } from '@terascope/utils';
import { Terafoundation as TF, Teraslice as TS } from '@terascope/types';
import { getE2eK8sDir } from '../../helpers/packages.js';
Expand Down Expand Up @@ -188,7 +188,7 @@ export class K8s {
let terasliceRunning = false;
try {
// TODO: switch to a teraslice client
const kubectlResponse = await execa.command(`curl http://${config.HOST_IP}:${this.tsPort}`);
const kubectlResponse = await execaCommand(`curl http://${config.HOST_IP}:${this.tsPort}`);
response = JSON.parse(kubectlResponse.stdout);
if (response.clustering_type === 'kubernetes' || response.clustering_type === 'kubernetesV2') {
terasliceRunning = true;
Expand Down
16 changes: 8 additions & 8 deletions packages/scripts/src/helpers/kind.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import execa from 'execa';
import { execaCommand } from 'execa';
import yaml from 'js-yaml';
import { Logger, debugLogger, isCI } from '@terascope/utils';
import type { V1Volume, V1VolumeMount } from '@kubernetes/client-node';
Expand Down Expand Up @@ -60,21 +60,21 @@ export class Kind {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tempYaml'));
fs.writeFileSync(path.join(tempDir, 'kindConfig.yaml'), updatedYaml);
const updatedYamlConfigPath = `${path.join(tempDir, 'kindConfig.yaml')}`;
const subprocess = await execa.command(`kind create cluster --config ${updatedYamlConfigPath}`);
const subprocess = await execaCommand(`kind create cluster --config ${updatedYamlConfigPath}`);
this.logger.debug(subprocess.stderr);
if (tempDir) {
fs.rmSync(tempDir, { recursive: true, force: true });
}
}

async destroyCluster(): Promise<void> {
const subprocess = await execa.command(`kind delete cluster --name ${this.clusterName}`);
const subprocess = await execaCommand(`kind delete cluster --name ${this.clusterName}`);
this.logger.debug(subprocess.stderr);
}

// TODO: check that image is loaded before we continue
async loadTerasliceImage(terasliceImage: string): Promise<void> {
const subprocess = await execa.command(`kind load docker-image ${terasliceImage} --name ${this.clusterName}`);
const subprocess = await execaCommand(`kind load docker-image ${terasliceImage} --name ${this.clusterName}`);
this.logger.debug(subprocess.stderr);
}

Expand All @@ -92,12 +92,12 @@ export class Kind {
if (!fs.existsSync(filePath)) {
throw new Error(`No file found at ${filePath}. Have you restored the cache?`);
}
subprocess = await execa.command(`gunzip -d ${filePath}`);
subprocess = await execaCommand(`gunzip -d ${filePath}`);
signale.info(`${subprocess.command}: successful`);
subprocess = await execa.command(`kind load --name ${this.clusterName} image-archive ${tarPath}`);
subprocess = await execaCommand(`kind load --name ${this.clusterName} image-archive ${tarPath}`);
fs.rmSync(tarPath);
} else {
subprocess = await execa.command(`kind load --name ${this.clusterName} docker-image ${serviceImage}:${version}`);
subprocess = await execaCommand(`kind load --name ${this.clusterName} docker-image ${serviceImage}:${version}`);
}
signale.info(`${subprocess.command}: successful`);
} catch (err) {
Expand All @@ -108,7 +108,7 @@ export class Kind {

async getKindVersion(): Promise<string> {
try {
const subprocess = await execa.command('kind version');
const subprocess = await execaCommand('kind version');
const version = subprocess.stdout.split(' ')[1].slice(1);
return version;
} catch (err) {
Expand Down
42 changes: 23 additions & 19 deletions packages/scripts/src/helpers/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs';
import os from 'node:os';
import ms from 'ms';
import path from 'node:path';
import execa from 'execa';
import { execa, execaCommand, type Options } from 'execa';
import fse from 'fs-extra';
import yaml from 'js-yaml';
import {
Expand Down Expand Up @@ -32,7 +32,7 @@ type ExecOpts = {

function _exec(opts: ExecOpts) {
let subprocess;
const options: execa.Options = {
const options: Options = {
cwd: opts.cwd || getRootDir(),
env: opts.env,
preferLocal: true,
Expand Down Expand Up @@ -68,6 +68,10 @@ export async function exec(opts: ExecOpts, log = true): Promise<string> {
_opts.env = env;
const subprocess = _exec(_opts);
const { stdout } = await subprocess;

if (typeof stdout !== 'string') {
throw new Error('exec() requires ExecOpts that result in a stdout string. See the execa docs for details.');
}
Comment on lines +72 to +74
Copy link
Contributor Author

@busma13 busma13 Sep 26, 2024

Choose a reason for hiding this comment

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

Depending on the ExecOpts passed into exec stdout could be any of 'string | string[] | Uint8Array | unknown[]'. We don't use any options that change the stdout return type and always expect a string, so I think this should be fine. Though the error message could be better

const result = stdout.trim();
logger.debug(`exec result: ${opts.cmd} ${(opts.args || []).join(' ')}`, log && result);
return result;
Expand Down Expand Up @@ -231,11 +235,11 @@ export async function getContainerInfo(name: string): Promise<any> {
}

export async function dockerNetworkExists(name: string): Promise<boolean> {
const subprocess = await execa.command(
const subprocess = await execaCommand(
`docker network ls --format='{{json .Name}}' | grep '"${name}"'`,
{ reject: false }
);
return subprocess.exitCode > 0;
return subprocess.exitCode ? subprocess.exitCode > 0 : false;
godber marked this conversation as resolved.
Show resolved Hide resolved
}

export async function remoteDockerImageExists(image: string): Promise<boolean> {
Expand Down Expand Up @@ -330,7 +334,7 @@ export async function dockerRun(
try {
const result = await subprocess;

if (result.exitCode > 0) {
if (result.exitCode && result.exitCode > 0) {
stderr = result.all;
error = new Error(`${result.command} failed`);
}
Expand Down Expand Up @@ -429,7 +433,7 @@ export async function dockerBuild(
}

export async function dockerPush(image: string): Promise<void> {
const subprocess = await execa.command(
const subprocess = await execaCommand(
`docker push ${image}`,
{ reject: false }
);
Expand All @@ -440,7 +444,7 @@ export async function dockerPush(image: string): Promise<void> {
}

async function dockerImageRm(image: string): Promise<void> {
const subprocess = await execa.command(
const subprocess = await execaCommand(
`docker image rm ${image}`,
{ reject: false }
);
Expand All @@ -466,7 +470,7 @@ export async function loadThenDeleteImageFromCache(imageName: string): Promise<b
return false;
}

const result = await execa.command(`gunzip -c ${filePath} | docker load`, { shell: true });
const result = await execaCommand(`gunzip -c ${filePath} | docker load`, { shell: true });
signale.info('Result: ', result);

if (result.exitCode !== 0) {
Expand Down Expand Up @@ -513,7 +517,7 @@ export async function saveAndZip(imageName: string, imageSavePath: string) {
const fileName = imageName.replace(/[/:]/g, '_');
const filePath = path.join(imageSavePath, `${fileName}.tar`);
const command = `docker save ${imageName} | gzip > ${filePath}.gz`;
await execa.command(command, { shell: true });
await execaCommand(command, { shell: true });
await dockerImageRm(imageName);
}

Expand Down Expand Up @@ -622,7 +626,7 @@ export async function yarnPublish(

export async function isKindInstalled(): Promise<boolean> {
try {
const subprocess = await execa.command('command -v kind');
const subprocess = await execaCommand('command -v kind');
return !!subprocess.stdout;
} catch (err) {
return false;
Expand All @@ -631,7 +635,7 @@ export async function isKindInstalled(): Promise<boolean> {

export async function isKubectlInstalled(): Promise<boolean> {
try {
const subprocess = await execa.command('command -v kubectl');
const subprocess = await execaCommand('command -v kubectl');
return !!subprocess.stdout;
} catch (err) {
return false;
Expand All @@ -647,7 +651,7 @@ export async function k8sStopService(serviceName: string): Promise<void> {
try {
// Any new service's yaml file must be named '<serviceName>Deployment.yaml'
const yamlFile = `${serviceName}Deployment.yaml`;
const subprocess = await execa.command(`kubectl delete -n services-dev1 -f ${path.join(e2eK8sDir, yamlFile)}`);
const subprocess = await execaCommand(`kubectl delete -n services-dev1 -f ${path.join(e2eK8sDir, yamlFile)}`);
logger.debug(subprocess.stdout);
} catch (err) {
// Do nothing. This should fail because no services should be up yet.
Expand Down Expand Up @@ -686,7 +690,7 @@ export async function k8sStartService(
const updatedYaml = jsDoc.map((doc) => yaml.dump(doc)).join('---\n');
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tempYaml'));
fs.writeFileSync(path.join(tempDir, `${serviceName}Deployment.yaml`), updatedYaml);
const subprocess = await execa.command(`kubectl create -n services-dev1 -f ${path.join(tempDir, `${serviceName}Deployment.yaml`)}`);
const subprocess = await execaCommand(`kubectl create -n services-dev1 -f ${path.join(tempDir, `${serviceName}Deployment.yaml`)}`);
logger.debug(subprocess.stdout);
fs.rmSync(tempDir, { recursive: true, force: true });
} catch (err) {
Expand All @@ -708,7 +712,7 @@ function waitForKafkaRunning(timeoutMs = 120000): Promise<void> {

let kafkaRunning = false;
try {
const kubectlResponse = await execa.command('kubectl -n services-dev1 get pods -l app.kubernetes.io/name=cpkafka -o=jsonpath="{.items[?(@.status.containerStatuses)].status.containerStatuses[0].ready}"');
const kubectlResponse = await execaCommand('kubectl -n services-dev1 get pods -l app.kubernetes.io/name=cpkafka -o=jsonpath="{.items[?(@.status.containerStatuses)].status.containerStatuses[0].ready}"');
const kafkaReady = kubectlResponse.stdout;
if (kafkaReady === '"true"') {
kafkaRunning = true;
Expand All @@ -729,27 +733,27 @@ function waitForKafkaRunning(timeoutMs = 120000): Promise<void> {
}

export async function setAlias(tsPort: string) {
let subprocess = await execa.command('earl aliases remove k8s-e2e 2> /dev/null || true', { shell: true });
let subprocess = await execaCommand('earl aliases remove k8s-e2e 2> /dev/null || true', { shell: true });
logger.debug(subprocess.stdout);
subprocess = await execa.command(`earl aliases add k8s-e2e http://${config.HOST_IP}:${tsPort}`);
subprocess = await execaCommand(`earl aliases add k8s-e2e http://${config.HOST_IP}:${tsPort}`);
logger.debug(subprocess.stdout);
}

export async function showState(tsPort: string) {
const subprocess = await execa.command('kubectl get deployments,po,svc --all-namespaces --show-labels -o wide');
const subprocess = await execaCommand('kubectl get deployments,po,svc --all-namespaces --show-labels -o wide');
logger.debug(subprocess.stdout);
logger.debug(await showESIndices());
logger.debug(await showAssets(tsPort));
}

async function showESIndices() {
const subprocess = await execa.command(`curl ${config.HOST_IP}:${config.ELASTICSEARCH_PORT}/_cat/indices?v`);
const subprocess = await execaCommand(`curl ${config.HOST_IP}:${config.ELASTICSEARCH_PORT}/_cat/indices?v`);
return subprocess.stdout;
}

async function showAssets(tsPort: string) {
try {
const subprocess = await execa.command(`curl ${config.HOST_IP}:${tsPort}/v1/assets`);
const subprocess = await execaCommand(`curl ${config.HOST_IP}:${tsPort}/v1/assets`);
return subprocess.stdout;
} catch (err) {
return err;
Expand Down
2 changes: 1 addition & 1 deletion packages/scripts/src/helpers/test-runner/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import semver from 'semver';
import fs from 'fs-extra';
import path from 'node:path';
import { Kafka } from 'kafkajs';
import execa from 'execa';
import { execa } from 'execa';
import {
pWhile, TSError, debugLogger,
toHumanTime, getErrorStatusCode
Expand Down
2 changes: 1 addition & 1 deletion packages/teraslice-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"ejs": "^3.1.10",
"esbuild": "^0.21.5",
"events": "^3.3.0",
"execa": "^5.1.0",
"execa": "9.4.0",
"fs-extra": "^11.2.0",
"glob": "^8.0.3",
"glob-promise": "5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/teraslice-cli/src/helpers/asset-src.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import execa from 'execa';
import { execa } from 'execa';
import prettyBytes from 'pretty-bytes';
import glob from 'glob-promise';
import fs from 'fs-extra';
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-transforms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"@types/valid-url": "^1.0.7",
"@types/validator": "^13.11.10",
"@types/yargs": "^17.0.33",
"execa": "^5.1.0"
"execa": "9.4.0"
},
"engines": {
"node": ">=18.18.0",
Expand Down
9 changes: 6 additions & 3 deletions packages/ts-transforms/test/command-spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import execa from 'execa';
import { execaCommand, type Options } from 'execa';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { pWhile } from '@terascope/utils';
Expand All @@ -8,9 +8,12 @@ const dirname = path.dirname(fileURLToPath(import.meta.url));
const cwd = path.join(dirname, '../');
const cliPath = path.join(cwd, './bin/ts-transform.js');

async function runCli(command: string, options: execa.Options = {}) {
const testProcess = await execa.command(command, options);
async function runCli(command: string, options: Options = {}) {
const testProcess = await execaCommand(command, options);
const { stdout, stderr } = await testProcess;
if (typeof stdout !== 'string') {
throw new Error('runCli() requires Options that result in a stdout string. See the execa docs for details.');
}
await pWhile(async () => testProcess.exitCode !== null);
return { stdout, stderr };
}
Expand Down
Loading
Loading