Add pre/post configure script arguments globally and per configuration (#495)

* initial code for pre/post-configure script arguments

* fix typo in troubleshooting.md

* add makefile.configurations[].preConfigureArgs and makefile.configurations[].postConfigureArgs

* fix typo

* only add a space after {scriptFile} if there are args

* fix

* slight rename
This commit is contained in:
Garrett Campbell 2023-10-04 07:20:50 -04:00 коммит произвёл GitHub
Родитель cf5354fbcd
Коммит 05d3731cd1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 127 добавлений и 12 удалений

Просмотреть файл

@ -63,6 +63,7 @@ If the repository needs any special commands before make is successful:
- Write any commands (./configure, ./bootstrap, etc...) in a script and point to it via **makefile.preconfigureScript**
- In the script, we recommend you concatenate all commands into one line, separated by && (for better return code analysis)
- Any arguments that you'd like to pass to the preConfigureScript should be set via **makefile.preConfigureArgs**
- From the Command Pallette, run the **Makefile: Pre-Configure** command once before configuring your project.
- If you need this every time, set **makefile.alwaysPreConfigure** to `true`
@ -70,6 +71,7 @@ If the repository or build needs any special commands to clean up after a build:
- Write any commands in a script and point it via **makefile.postConfigureScript**
- In the script, we recommend you concatentate all commands into one line, seperated by && (for better return code analysis)
- Any arguments that you'd like to pass to the postConfigureScript should be set via **makefile.postConfigureArgs**
- From the Command Pallette, run the **Makefile: Post-Configure** command once after configuring your project.
- If you need this every time, set **makefile.alwaysPostConfigure** to `true`

Просмотреть файл

@ -293,6 +293,22 @@
"buildLog": {
"type": "string",
"description": "%makefile-tools.configuration.makefile.configurations.buildLog.description%"
},
"preConfigureArgs": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"description": "%makefile-tools.configuration.makefile.preConfigureArgs.description%"
},
"postConfigureArgs": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"description": "%makefile-tools.configuration.makefile.postConfigureArgs.description%"
}
}
},
@ -482,12 +498,28 @@
"default": null,
"scope": "resource"
},
"makefile.preConfigureArgs": {
"type": "array",
"description": "%makefile-tools.configuration.makefile.preConfigureArgs.description%",
"items": {
"type": "string"
},
"default": []
},
"makefile.postConfigureScript": {
"type": "string",
"description": "%makefile-tools.configuration.makefile.postConfigureScript.description%",
"default": null,
"scope": "resource"
},
"makefile.postConfigureArgs": {
"type": "array",
"description": "%makefile-tools.configuration.makefile.postConfigureArgs.description%",
"items": {
"type": "string"
},
"default": []
},
"makefile.alwaysPreConfigure": {
"type": "boolean",
"description": "%makefile-tools.configuration.makefile.alwaysPreConfigure.description%",

Просмотреть файл

@ -56,7 +56,9 @@
"makefile-tools.configuration.makefile.configureOnEdit.description": "Automatically configure Makefile project directories when any relevant makefiles and/or settings are changed",
"makefile-tools.configuration.makefile.configureAfterCommand.description": "Automatically configure Makefile project directories after relevant operations, like change build configuration or makefile target",
"makefile-tools.configuration.makefile.preConfigureScript.description": "The path to the script that needs to be run at least once before configure",
"makefile-tools.configuration.makefile.preConfigureArgs.description": "Arguments to pass to the preConfigureScript",
"makefile-tools.configuration.makefile.postConfigureScript.description": "The path to the script that needs to be run at least once after configure",
"makefile-tools.configuration.makefile.postConfigureArgs.description": "Arguments to pass to the postConfigureScript",
"makefile-tools.configuration.makefile.alwaysPreConfigure.description": "Always run the pre-configure script before configure",
"makefile-tools.configuration.makefile.alwaysPostConfigure.description": "Always run the post-configure script after configure",
"makefile-tools.configuration.makefile.ignoreDirectoryCommands.description": "Don't analyze directory changing commands like cd, push, pop.",

Просмотреть файл

@ -57,6 +57,12 @@ export interface MakefileConfiguration {
// instead of the dry-run output of the make tool
buildLog?: string;
// arguments for the pre configure script
preConfigureArgs?: string[];
// arguments for the post configure script
postConfigureArgs?: string[]
// TODO: investigate how flexible this is to integrate with other build systems than the MAKE family
// (basically anything that can produce a dry-run output is sufficient)
// Implement set-able dry-run, verbose, change-directory and always-make switches
@ -360,10 +366,18 @@ let preConfigureScript: string | undefined;
export function getPreConfigureScript(): string | undefined { return preConfigureScript; }
export function setPreConfigureScript(path: string): void { preConfigureScript = path; }
let preConfigureArgs: string[] = [];
export function getPreConfigureArgs(): string[] { return preConfigureArgs; }
export function setPreConfigureArgs(args: string[]): void { preConfigureArgs = args; }
let postConfigureScript: string | undefined;
export function getPostConfigureScript(): string | undefined { return postConfigureScript; }
export function setPostConfigureScript(path: string): void { postConfigureScript = path; }
let postConfigureArgs: string[] = [];
export function getPostConfigureArgs(): string[] { return postConfigureArgs; }
export function setPostConfigureArgs(args: string[]): void { postConfigureArgs = args; }
// Read from settings the path to a script file that needs to have been run at least once
// before a sucessful configure of this project.
export async function readPreConfigureScript(): Promise<void> {
@ -377,6 +391,13 @@ export async function readPreConfigureScript(): Promise<void> {
}
}
export async function readPreConfigureArgs(): Promise<void> {
preConfigureArgs = await util.getExpandedSetting<string[]>("preConfigureArgs") ?? [];
if (preConfigureArgs && preConfigureArgs.length > 0) {
logger.message(`Pre-configure arguments: '${preConfigureArgs.join("', '")}'`);
}
}
export async function readPostConfigureScript(): Promise<void> {
postConfigureScript = await util.getExpandedSetting<string>("postConfigureScript");
if (postConfigureScript) {
@ -388,6 +409,13 @@ export async function readPostConfigureScript(): Promise<void> {
}
}
export async function readPostConfigureArgs(): Promise<void> {
postConfigureArgs = await util.getExpandedSetting<string[]>("postConfigureArgs") ?? [];
if (postConfigureArgs && postConfigureArgs.length > 0) {
logger.message(`Post-configure arguments: '${postConfigureArgs.join("', '")}'`);
}
}
let alwaysPreConfigure: boolean | undefined;
export function getAlwaysPreConfigure(): boolean | undefined { return alwaysPreConfigure; }
export function setAlwaysPreConfigure(path: boolean): void { alwaysPreConfigure = path; }
@ -650,6 +678,14 @@ let configurationBuildLog: string | undefined;
export function getConfigurationBuildLog(): string | undefined { return configurationBuildLog; }
export function setConfigurationBuildLog(name: string): void { configurationBuildLog = name; }
let configurationPreConfigureArgs: string[] = [];
export function getConfigurationPreConfigureArgs(): string[] { return configurationPreConfigureArgs; }
export function setConfigurationPreConfigureArgs(args: string[]): void { configurationPreConfigureArgs = args; }
let configurationPostConfigureArgs: string[] = [];
export function getConfigurationPostConfigureArgs(): string[] { return configurationPostConfigureArgs; }
export function setConfigurationPostConfigureArgs(args: string[]): void { configurationPostConfigureArgs = args; }
// Analyze the settings of the current makefile configuration and the global workspace settings,
// according to various merging rules and decide what make command and build log
// apply to the current makefile configuration.
@ -657,9 +693,11 @@ async function analyzeConfigureParams(): Promise<void> {
getBuildLogForConfiguration(currentMakefileConfiguration);
await getCommandForConfiguration(currentMakefileConfiguration);
getProblemMatchersForConfiguration(currentMakefileConfiguration);
getPreConfigureArgsForConfiguration(currentMakefileConfiguration);
getPostConfigureArgsForConfiguration(currentMakefileConfiguration);
}
function getMakefileConfiguration(configuration: string | undefined): MakefileConfiguration | undefined {
export function getMakefileConfiguration(configuration: string | undefined): MakefileConfiguration | undefined {
return makefileConfigurations.find(k => {
if (k.name === configuration) {
return k;
@ -866,6 +904,28 @@ export function getBuildLogForConfiguration(configuration: string | undefined):
}
}
export function getPreConfigureArgsForConfiguration(configuration: string | undefined): void {
let makefileConfiguration: MakefileConfiguration | undefined = getMakefileConfiguration(configuration);
const localPreConfigArgs = makefileConfiguration?.preConfigureArgs;
if (localPreConfigArgs) {
configurationPreConfigureArgs = localPreConfigArgs;
} else {
configurationPreConfigureArgs = preConfigureArgs;
}
}
export function getPostConfigureArgsForConfiguration(configuration: string | undefined): void {
let makefileConfiguration: MakefileConfiguration | undefined = getMakefileConfiguration(configuration);
const localPostConfigArgs = makefileConfiguration?.postConfigureArgs;
if (localPostConfigArgs) {
configurationPostConfigureArgs = localPostConfigArgs;
} else {
configurationPostConfigureArgs = postConfigureArgs;
}
}
let makefileConfigurations: MakefileConfiguration[] = [];
export function getMakefileConfigurations(): MakefileConfiguration[] { return makefileConfigurations; }
export function setMakefileConfigurations(configurations: MakefileConfiguration[]): void { makefileConfigurations = configurations; }
@ -1065,8 +1125,10 @@ export async function initFromSettings(activation: boolean = false): Promise<voi
await readMakeDirectory();
extension.updateBuildLogPresent(await readBuildLog());
await readPreConfigureScript();
await readPreConfigureArgs();
await readAlwaysPreConfigure();
await readPostConfigureScript();
await readPostConfigureArgs();
await readAlwaysPostConfigure();
await readDryrunSwitches();
await readAdditionalCompilerNames();
@ -1257,6 +1319,13 @@ export async function initFromSettings(activation: boolean = false): Promise<voi
updatedSettingsSubkeys.push(subKey);
}
subKey = "preConfigureArgs";
let updatedPreConfigureArgs: string[] | undefined = await util.getExpandedSetting<string[]>(subKey);
if (updatedPreConfigureArgs && !util.areEqual(updatedPreConfigureArgs, preConfigureArgs)) {
await readPreConfigureArgs();
updatedSettingsSubkeys.push(subKey);
}
subKey = "postConfigureScript";
let updatedPostConfigureScript: string | undefined = await util.getExpandedSetting<string>(subKey);
if (updatedPostConfigureScript) {
@ -1267,6 +1336,13 @@ export async function initFromSettings(activation: boolean = false): Promise<voi
updatedSettingsSubkeys.push(subKey);
}
subKey = "postConfigureArgs";
let updatedPostConfigureArgs: string[] | undefined = await util.getExpandedSetting<string[]>(subKey);
if (updatedPostConfigureArgs && !util.areEqual(updatedPostConfigureArgs, postConfigureArgs)) {
await readPostConfigureArgs();
updatedSettingsSubkeys.push(subKey);
}
subKey = "alwaysPreConfigure";
let updatedAlwaysPreConfigure : boolean | undefined = await util.getExpandedSetting<boolean>(subKey);
if (updatedAlwaysPreConfigure !== alwaysPreConfigure) {

Просмотреть файл

@ -704,7 +704,7 @@ export async function preConfigure(triggeredBy: TriggeredBy): Promise<number> {
});
}
export async function postConfigure(triggeredBy: TriggeredBy, ): Promise<number> {
export async function postConfigure(triggeredBy: TriggeredBy): Promise<number> {
let scriptFile: string | undefined = configuration.getPostConfigureScript();
if (!scriptFile) {
vscode.window.showErrorMessage("Post-configure failed: no script provided.");
@ -752,14 +752,15 @@ async function applyEnvironment(content: string | undefined) : Promise<void> {
});
}
export async function runPrePostConfigureScript(progress: vscode.Progress<{}>, scriptFile: string, loggingMessages: { success: string, successWithSomeError: string, failure: string}): Promise<number> {
export async function runPrePostConfigureScript(progress: vscode.Progress<{}>, scriptFile: string, scriptArgs: string[], loggingMessages: { success: string, successWithSomeError: string, failure: string}): Promise<number> {
// Create a temporary wrapper for the user pre-configure script so that we collect
// in another temporary output file the environrment variables that were produced.
let wrapScriptFile: string = path.join(util.tmpDir(), "wrapConfigureScript");
let wrapScriptOutFile: string = wrapScriptFile + ".out";
let wrapScriptContent: string;
if (process.platform === "win32") {
wrapScriptContent = `call "${scriptFile}"\r\n`;
wrapScriptContent = `call "${scriptFile}"`;
wrapScriptContent += scriptArgs.length > 0 ? `${scriptArgs.join(" ").toString()}\r\n` : "\r\n";
wrapScriptContent += `set > "${wrapScriptOutFile}"`;
wrapScriptFile += ".bat";
} else {
@ -770,16 +771,16 @@ export async function runPrePostConfigureScript(progress: vscode.Progress<{}>, s
util.writeFile(wrapScriptFile, wrapScriptContent);
let scriptArgs: string[] = [];
let concreteScriptArgs: string[] = [];
let runCommand: string;
if (process.platform === 'win32') {
runCommand = "cmd";
scriptArgs.push("/c");
scriptArgs.push(`"${wrapScriptFile}"`);
concreteScriptArgs.push("/c");
concreteScriptArgs.push(`"${wrapScriptFile}"`);
} else {
runCommand = "/bin/bash";
scriptArgs.push("-c");
scriptArgs.push(`"source '${wrapScriptFile}'"`);
concreteScriptArgs.push("-c");
concreteScriptArgs.push(`"source '${wrapScriptFile}'"`);
}
try {
@ -795,7 +796,7 @@ export async function runPrePostConfigureScript(progress: vscode.Progress<{}>, s
};
// The preconfigure invocation should use the system locale.
const result: util.SpawnProcessResult = await util.spawnChildProcess(runCommand, scriptArgs, util.getWorkspaceRoot(), false, false, stdout, stderr);
const result: util.SpawnProcessResult = await util.spawnChildProcess(runCommand, concreteScriptArgs, util.getWorkspaceRoot(), false, false, stdout, stderr);
if (result.returnCode === ConfigureBuildReturnCodeTypes.success) {
if (someErr) {
// Depending how the preconfigure scripts (and any inner called sub-scripts) are written,
@ -826,7 +827,8 @@ export async function runPrePostConfigureScript(progress: vscode.Progress<{}>, s
export async function runPreConfigureScript(progress: vscode.Progress<{}>, scriptFile: string): Promise<number> {
logger.message(`Pre-configuring...\nScript: "${configuration.getPreConfigureScript()}"`);
return await runPrePostConfigureScript(progress, scriptFile, {
const currentConfigPreConfigureArgs = configuration.getConfigurationPreConfigureArgs();
return await runPrePostConfigureScript(progress, scriptFile, currentConfigPreConfigureArgs.length > 0 ? currentConfigPreConfigureArgs : configuration.getPreConfigureArgs(), {
success: "The pre-configure succeeded.",
successWithSomeError: "The pre-configure script returned success code " +
"but somewhere during the preconfigure process there were errors reported. " +
@ -838,7 +840,8 @@ export async function runPreConfigureScript(progress: vscode.Progress<{}>, scrip
export async function runPostConfigureScript(progress: vscode.Progress<{}>, scriptFile: string): Promise<number> {
logger.message(`Post-configuring...\nScript: "${configuration.getPostConfigureScript()}"`);
return await runPrePostConfigureScript(progress, scriptFile, {
const currentConfigPostConfigureArgs = configuration.getConfigurationPostConfigureArgs();
return await runPrePostConfigureScript(progress, scriptFile, currentConfigPostConfigureArgs.length > 0 ? currentConfigPostConfigureArgs : configuration.getPostConfigureArgs(), {
success: "The post-configure succeeded.",
successWithSomeError:
"The post-configure script returned success code " +