Skip to content

feat: add preparse hook for --flags-dir #1536

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

Merged
merged 16 commits into from
Mar 22, 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
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"homepage": "https://github.com/salesforcecli/cli",
"bugs": "https://github.com/forcedotcom/cli/issues",
"engines": {
"node": ">=16.0.0"
"node": ">=18.0.0"
},
"packageManager": "yarn@1.22.19",
"files": [
Expand Down Expand Up @@ -92,7 +92,8 @@
"command_incomplete": "./dist/hooks/incomplete",
"plugins:preinstall": "./dist/hooks/pluginsPreinstall.js",
"update": "./dist/hooks/display-release-notes.js",
"prerun": "./dist/hooks/prerun"
"prerun": "./dist/hooks/prerun",
"preparse": "/dist/hooks/preparse"
},
"update": {
"s3": {
Expand Down Expand Up @@ -137,7 +138,7 @@
},
"dependencies": {
"@inquirer/select": "^1.3.1",
"@oclif/core": "3.25.3",
"@oclif/core": "3.26.0",
"@oclif/plugin-autocomplete": "3.0.13",
"@oclif/plugin-commands": "3.2.0",
"@oclif/plugin-help": "6.0.18",
Expand Down Expand Up @@ -166,7 +167,7 @@
"@salesforce/plugin-templates": "56.0.24",
"@salesforce/plugin-trust": "3.3.17",
"@salesforce/plugin-user": "3.3.4",
"@salesforce/sf-plugins-core": "7.1.16",
"@salesforce/sf-plugins-core": "8.0.0",
"chalk": "^5.3.0",
"debug": "^4.3.4",
"strip-ansi": "^7.1.0"
Expand Down Expand Up @@ -254,6 +255,7 @@
"@salesforce/dev-scripts": "^8.1.0",
"@salesforce/plugin-release-management": "^4.7.7",
"@salesforce/ts-sinon": "^1.4.19",
"@salesforce/ts-types": "^2.0.9",
"@types/debug": "^4.1.12",
"aws-sdk": "^2.1580.0",
"oclif": "^4.5.7",
Expand Down
101 changes: 101 additions & 0 deletions src/hooks/preparse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2024, 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 type { Hook } from '@oclif/core';

const hook: Hook<'preparse'> = async function ({ argv, options, context }) {
// Skip this hook if command does not have a --flags-dir flag or if it is not present in argv
if (!argv.includes('--flags-dir') || !options.flags?.['flags-dir']) return argv;
const flagsDir = argv[argv.indexOf('--flags-dir') + 1];
if (!flagsDir) {
context.debug('No flags dir provided');
return argv;
}
if (flagsDir.startsWith('-')) {
context.debug(`No flags dir provided, got ${flagsDir}`);
return argv;
}

const { default: fs } = await import('node:fs/promises');
const { default: path } = await import('node:path');

context.debug('Initial argv', argv.join(' '));
const flagsToIgnore = new Set(
Object.entries(options.flags ?? {})
.filter(
([, flagOptions]) =>
// don't ignore if flag can take multiple values
(flagOptions.type === 'option' && flagOptions.multiple !== true) || flagOptions.type === 'boolean'
)
.filter(
([flagName, flagOptions]) =>
// ignore if short char flag is present
argv.includes(`-${flagOptions.char}`) ||
// ignore if long flag is present
argv.includes(`--${flagName}`) ||
// ignore if --no- flag is present
(flagOptions.type === 'boolean' && flagOptions.allowNo && argv.includes(`--no-${flagName}`))
)
.flatMap(([flagName, flagOptions]) => {
// Also ignore the --no- flag if boolean flag allows it
if (flagOptions.type === 'boolean' && flagOptions.allowNo) {
return [flagName, `no-${flagName}`];
}

return [flagName];
})
);
context.debug('Flags to ignore', flagsToIgnore);

async function safeReadDir(filePath: string): Promise<string[]> {
try {
return await fs.readdir(filePath);
} catch (err) {
context.debug('No flags dir found');
context.debug(err);
return [];
}
}

async function safeReadFile(filePath: string): Promise<string | undefined> {
try {
return await fs.readFile(filePath, 'utf8');
} catch (err) {
context.debug(filePath, err);
}
}

const filesInDir = await safeReadDir(flagsDir);
context.debug('Files in dir', filesInDir);
const flagsToInsert = await Promise.all(
filesInDir
// ignore files that were provided as flags
.filter((f) => !flagsToIgnore.has(f))
.map(async (file) => {
const { name, ext } = path.parse(file);
const contents = await safeReadFile(path.join(flagsDir, file));
if (contents === undefined) {
return [name, undefined] satisfies [string, undefined];
}
const values = ext === '.json' ? [JSON.stringify(JSON.parse(contents))] : contents?.trim().split('\n');
return [name, values] satisfies [string, string[]];
})
);

const newArgv = [...argv];
context.debug('Flags to insert', flagsToInsert);
for (const [flag, values] of flagsToInsert) {
for (const value of values ?? []) {
newArgv.push(flag.length === 1 ? `-${flag}` : `--${flag}`);
if (value) newArgv.push(value);
}
}

context.debug(`Returning argv: ${newArgv.join(' ')}`);
return newArgv;
};

export default hook;
3 changes: 1 addition & 2 deletions src/util/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { EnvVars } from '@salesforce/core/lib/config/envVars.js';
import { Optional } from '@salesforce/ts-types';

export class Env extends EnvVars {
public static SF_AUTOUPDATE_DISABLE = 'SF_AUTOUPDATE_DISABLE';
Expand Down Expand Up @@ -46,7 +45,7 @@ export class Env extends EnvVars {
return this.getBoolean(Env.SF_INSTALLER);
}

public getNpmRegistryOverride(): Optional<string> {
public getNpmRegistryOverride(): string | undefined {
return this.getString(Env.SF_NPM_REGISTRY);
}

Expand Down
Loading