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

Wr/twinning #452

Merged
merged 10 commits into from
Dec 13, 2022
6 changes: 3 additions & 3 deletions bin/run
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/usr/bin/env node

/* tslint:disable:no-var-requires only-arrow-functions */
/* eslint-disable global-require, prefer-arrow-callback */

// Since the CLI is a single process, we can have a larger amount of max listeners since
// the process gets shut down. Don't set it to 0 (no limit) since we should still be aware
// of rouge event listeners
Expand All @@ -14,6 +11,9 @@ process.setMaxListeners = () => {};
// Check node version before requiring additional packages
require('../dist/versions').checkNodeVersion();

// Pre-process/prune flags before creating or running the actual CLI
require('../dist/flags').preprocessCliFlags(process);

const cli = require('../dist/cli');
const pjson = require('../package.json');

Expand Down
43 changes: 43 additions & 0 deletions src/flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

// -------------------------------------------------------------------------------
// No requires or imports since this is loaded early in the cli lifecycle and we
// want to minimize the number of packages that load before enabling require
// instrumentation.
// -------------------------------------------------------------------------------

export interface ProcessLike {
argv: string[];
env: { [key: string]: string | undefined };
}

export function preprocessCliFlags(process: ProcessLike): void {
process.argv.map((arg) => {
if (arg === '--dev-debug') {
let debug = '*';
const filterIndex = process.argv.indexOf('--debug-filter');
if (filterIndex > 0) {
debug = process.argv[filterIndex + 1];

process.argv.splice(filterIndex, 2);
}
// convert --dev-debug into a set of environment variables
process.env.DEBUG = debug;
process.env.SF_DEBUG = '1';
process.env.SF_ENV = 'development';
process.env.SFDX_DEBUG = '1';
process.env.SFDX_ENV = 'development';

// need to calculate indexOf --dev-debug here because it might've changed based on --debug-filter
process.argv.splice(process.argv.indexOf('--dev-debug'), 1);
}
});
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
module.exports.preprocessCliFlags = preprocessCliFlags;
11 changes: 7 additions & 4 deletions src/versions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable */
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
Expand All @@ -8,21 +7,24 @@

import * as semver from 'semver';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const pjson = require('../package.json');
const pjson = require('../package.json') as { engines: { node: string } };

type Tag = string | semver.SemVer | null | undefined;

/**
* Determines whether or not a tag string is a semantic version.
*
* @param {*} tag The possible version string
* @returns {boolean} True, if the string is recognized as a semantic version
*/
export function isVersion(tag) {
export function isVersion(tag: Tag): boolean {
if (!tag) {
return false;
}
return !!semver.valid(tag) || false;
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
module.exports.isVersion = isVersion;

/**
Expand All @@ -32,7 +34,7 @@ export function checkNodeVersion(
preferThrow = false,
currentVersion = process.versions.node,
requiredVersion = pjson.engines.node.slice(2)
) {
): void {
if (semver.compare(currentVersion, requiredVersion) < 0) {
const message = `Unsupported Node.js version ${currentVersion}, version ${requiredVersion} or later is required.`;
if (!preferThrow) {
Expand All @@ -45,4 +47,5 @@ export function checkNodeVersion(
}
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
module.exports.checkNodeVersion = checkNodeVersion;
4 changes: 1 addition & 3 deletions test/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
// the below, there's lots of un-awaited promises for testing
/* eslint-disable no-unused-expressions*/
/* eslint-disable @typescript-eslint/require-await*/

import { Config, Interfaces } from '@oclif/core';
import { LoadOptions } from '@oclif/core/lib/interfaces/config';
import { stubInterface } from '@salesforce/ts-sinon';
Expand Down Expand Up @@ -66,7 +65,6 @@ describe('cli', () => {
});

it('should initialize a Doctor instance when the doctor command is run', async () => {
debugger;
sandbox.stub(Config.prototype, 'load').callsFake(() => Promise.resolve());
let loadOptions: LoadOptions;
const exec = async (argv?: string[], opts?: LoadOptions): Promise<void> => {
Expand Down
3 changes: 1 addition & 2 deletions test/env.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
// the below, there's lots of un-awaited promises for testing
/* eslint-disable no-unused-expressions*/
/* eslint-disable @typescript-eslint/require-await*/

import { expect } from 'chai';
import { EnvironmentVariable } from '@salesforce/core';
import { Env } from '../src/util/env';
Expand Down
94 changes: 94 additions & 0 deletions test/flags.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2018, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { expect } from 'chai';
import { preprocessCliFlags, ProcessLike } from '../src/flags';

describe('CLI flags', () => {
it('should pass through args it does not recognize', () => {
const process: ProcessLike = {
argv: ['force:some:command', '--dev-debug', '--foo', '-f', 'bar'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).to.deep.equal(['force:some:command', '--foo', '-f', 'bar']);
});

it('should recognize --dev-debug', () => {
const process: ProcessLike = {
argv: ['--dev-debug'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).not.to.include('--dev-debug');
expect(process.env.DEBUG).to.equal('*');
expect(process.env.SF_DEBUG).to.equal('1');
expect(process.env.SF_ENV).to.equal('development');
expect(process.env.SFDX_DEBUG).to.equal('1');
expect(process.env.SFDX_ENV).to.equal('development');
});

it('should recognize --dev-debug in any order', () => {
const process: ProcessLike = {
argv: ['-a', 'alias', 'var=arg', '--dev-debug'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).not.to.include('--dev-debug');
expect(process.env.DEBUG).to.equal('*');
expect(process.env.SF_DEBUG).to.equal('1');
expect(process.env.SF_ENV).to.equal('development');
expect(process.env.SFDX_DEBUG).to.equal('1');
expect(process.env.SFDX_ENV).to.equal('development');
expect(process.argv.length).to.equal(3);
});

it('should recognize --dev-debug with a DEBUG filter', () => {
const process: ProcessLike = {
argv: ['--dev-debug', '--debug-filter', 'sf:config'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).to.deep.equal([]);
expect(process.argv).not.to.include('sf:Config');
expect(process.env.DEBUG).to.equal('sf:config');
expect(process.env.SF_DEBUG).to.equal('1');
expect(process.env.SF_ENV).to.equal('development');
expect(process.env.SFDX_DEBUG).to.equal('1');
expect(process.env.SFDX_ENV).to.equal('development');
});

it('should recognize --dev-debug with a DEBUG filter in any order', () => {
const process: ProcessLike = {
argv: ['--setdefault', '--debug-filter', 'sf:Config', '--dev-debug'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).to.deep.equal(['--setdefault']);
expect(process.argv).not.to.include('sf:Config');
expect(process.argv).to.include('--setdefault');
expect(process.env.DEBUG).to.equal('sf:Config');
expect(process.env.SF_DEBUG).to.equal('1');
expect(process.env.SF_ENV).to.equal('development');
expect(process.env.SFDX_DEBUG).to.equal('1');
expect(process.env.SFDX_ENV).to.equal('development');
});

it('should only set DEBUG if --dev-debug is present', () => {
const process: ProcessLike = {
argv: ['--setdefault', '--debug-filter', 'sf:Config'],
env: {},
};
preprocessCliFlags(process);
expect(process.argv).to.deep.equal(['--setdefault', '--debug-filter', 'sf:Config']);
expect(process.env.DEBUG).to.undefined;
expect(process.env.SF_DEBUG).to.be.undefined;
expect(process.env.SF_ENV).to.undefined;
expect(process.env.SFDX_DEBUG).to.undefined;
expect(process.env.SFDX_ENV).to.undefined;
});
});