-
Notifications
You must be signed in to change notification settings - Fork 450
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
Using consistence function for environment set and get to fix the gap between windows and unix. #1763
Using consistence function for environment set and get to fix the gap between windows and unix. #1763
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ import {CMakeOutputConsumer} from '@cmt/diagnostics/cmake'; | |
import {RawDiagnosticParser} from '@cmt/diagnostics/util'; | ||
import {ProgressMessage} from '@cmt/drivers/cms-client'; | ||
import * as expand from '@cmt/expand'; | ||
import {CMakeGenerator, effectiveKitEnvironment, Kit, kitChangeNeedsClean, KitDetect, getKitDetect, getKitEnvironmentVariablesObject} from '@cmt/kit'; | ||
import {CMakeGenerator, effectiveKitEnvironment, Kit, kitChangeNeedsClean, KitDetect, getKitDetect} from '@cmt/kit'; | ||
import * as logging from '@cmt/logging'; | ||
import paths from '@cmt/paths'; | ||
import {fs} from '@cmt/pr'; | ||
|
@@ -169,69 +169,56 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
|
||
/** | ||
* The environment variables required by the current kit | ||
* The ${dollar} are not expanded and missing environment variable subs are not expanded for this variables | ||
*/ | ||
private _kitEnvironmentVariables = new Map<string, string>(); | ||
|
||
/** | ||
* Compute the environment variables that apply with substitutions by expansionOptions | ||
*/ | ||
async computeExpandedEnvironment(in_env: proc.EnvironmentVariables, expanded_env: proc.EnvironmentVariables): Promise<proc.EnvironmentVariables> { | ||
const env = {} as {[key: string]: string}; | ||
const opts = this.expansionOptions; | ||
|
||
await Promise.resolve( | ||
util.objectPairs(in_env) | ||
.forEach(async ([key, value]) => env[key] = await expand.expandString(value, {...opts, envOverride: expanded_env})) | ||
); | ||
return env; | ||
} | ||
private _kitEnvironmentVariables: proc.EnvironmentVariables = {}; | ||
|
||
/** | ||
* Get the environment variables that should be set at CMake-configure time. | ||
*/ | ||
async getConfigureEnvironment(): Promise<proc.EnvironmentVariables> { | ||
const envs_to_merge: (proc.EnvironmentVariables | undefined)[] = []; | ||
if (this.useCMakePresets) { | ||
return this._configurePreset?.environment as proc.EnvironmentVariables; | ||
envs_to_merge.push(this._configurePreset?.environment as proc.EnvironmentVariables); | ||
} else { | ||
let envs = getKitEnvironmentVariablesObject(this._kitEnvironmentVariables); | ||
/* NOTE: By mergeEnvironment one by one to enable expanding self containd variable such as PATH properly */ | ||
/* If configureEnvironment and environment both configured different PATH, doing this will preserve them all */ | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.environment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.configureEnvironment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this._variantEnv, envs)); | ||
return envs; | ||
envs_to_merge.push(this._kitEnvironmentVariables); | ||
} | ||
envs_to_merge.push(this.config.environment); | ||
envs_to_merge.push(this.config.configureEnvironment); | ||
envs_to_merge.push(this._variantEnv); | ||
return expand.mergeEnvironmentWithExpand(false, envs_to_merge, this.expansionOptions); | ||
} | ||
|
||
/** | ||
* Get the environment variables that should be set at CMake-build time. | ||
*/ | ||
async getCMakeBuildCommandEnvironment(in_env: proc.EnvironmentVariables): Promise<proc.EnvironmentVariables> { | ||
let envs: proc.EnvironmentVariables; | ||
const envs_to_merge: (proc.EnvironmentVariables | undefined)[] = [in_env]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for your contribution. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /**
* mergeEnvironmentWithExpand will merge new env variable and
* expand it one by one, so that the environment like this
* will expand properly:
* config.environment
* { PATH:`${env.PATH};C:\\MinGW\\bin` }
* config.configureEnvironment
* { PATH:`${env.PATH};C:\\OtherPath\\bin` }
*
* @param intermediateExpand If this is the intermediate expanding
* procedure or the final expanding procedure, if it's the
* intermediate expanding procedure, the variable that not found
* won't not expaned, if it's the final expanding procedure, the variable
* that not found would expand to ''.
* @param envs The list of environment variables to expand
* @param opts Environment expand options
*
* NOTE: By mergeEnvironment one by one to enable expanding self
* containd variable such as PATH properly. If configureEnvironment
* and environment both configured different PATH, doing this will
* preserve them all
*/
export async function mergeEnvironmentWithExpand(
intermediateExpand: boolean,
envs: (EnvironmentVariables | undefined)[],
opts?: ExpansionOptions) I've document it in mergeEnvironmentWithExpand, don't know if the function name is proper, looking for better name There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate if you could add some comments/samples to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't touch and use of splitEnvironmentVars, other functions are documented |
||
if (this.useCMakePresets) { | ||
envs = util.mergeEnvironment(in_env, this._buildPreset?.environment as proc.EnvironmentVariables); | ||
envs_to_merge.push(this._buildPreset?.environment as proc.EnvironmentVariables); | ||
} else { | ||
envs = util.mergeEnvironment(in_env, getKitEnvironmentVariablesObject(this._kitEnvironmentVariables)); | ||
envs_to_merge.push(this._kitEnvironmentVariables); | ||
} | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.environment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.buildEnvironment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this._variantEnv, envs)); | ||
return envs; | ||
envs_to_merge.push(this.config.environment); | ||
envs_to_merge.push(this.config.buildEnvironment); | ||
envs_to_merge.push(this._variantEnv); | ||
return expand.mergeEnvironmentWithExpand(false, envs_to_merge, this.expansionOptions); | ||
} | ||
|
||
/** | ||
* Get the environment variables that should be set at CTest and running program time. | ||
*/ | ||
async getCTestCommandEnvironment(): Promise<proc.EnvironmentVariables> { | ||
const envs_to_merge: (proc.EnvironmentVariables | undefined)[] = []; | ||
if (this.useCMakePresets) { | ||
return (this._testPreset?.environment ? this._testPreset?.environment : {}) as proc.EnvironmentVariables; | ||
envs_to_merge.push(this._testPreset?.environment as proc.EnvironmentVariables); | ||
} else { | ||
let envs = getKitEnvironmentVariablesObject(this._kitEnvironmentVariables); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.environment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this.config.testEnvironment, envs)); | ||
envs = util.mergeEnvironment(envs, await this.computeExpandedEnvironment(this._variantEnv, envs)); | ||
return envs; | ||
envs_to_merge.push(this._kitEnvironmentVariables); | ||
} | ||
envs_to_merge.push(this.config.environment); | ||
envs_to_merge.push(this.config.testEnvironment); | ||
envs_to_merge.push(this._variantEnv); | ||
return expand.mergeEnvironmentWithExpand(false, envs_to_merge, this.expansionOptions); | ||
} | ||
|
||
get onProgress(): vscode.Event<ProgressMessage> { | ||
|
@@ -318,15 +305,29 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
return {vars, variantVars}; | ||
} | ||
|
||
getEffectiveSubprocessEnvironment(opts?: proc.ExecutionOptions): proc.EnvironmentVariables { | ||
const cur_env = process.env as proc.EnvironmentVariables; | ||
const kit_env = (this.config.ignoreKitEnv) ? {} : getKitEnvironmentVariablesObject(this._kitEnvironmentVariables); | ||
return util.mergeEnvironment(cur_env, kit_env, (opts && opts.environment) ? opts.environment : {}); | ||
async getEffectiveSubprocessEnvironment(opts?: proc.ExecutionOptions): Promise<proc.EnvironmentVariables> { | ||
let envs_to_merge: (proc.EnvironmentVariables | undefined)[] = []; | ||
if (this.config.ignoreKitEnv) { | ||
envs_to_merge = [ | ||
process.env as proc.EnvironmentVariables, | ||
this.config.environment, | ||
this._variantEnv, | ||
opts?.environment | ||
]; | ||
} else { | ||
envs_to_merge = [ | ||
this._kitEnvironmentVariables, | ||
this.config.environment, | ||
this._variantEnv, | ||
opts?.environment | ||
]; | ||
} | ||
return expand.mergeEnvironmentWithExpand(false, envs_to_merge, this.expansionOptions); | ||
} | ||
|
||
executeCommand(command: string, args?: string[], consumer?: proc.OutputConsumer, options?: proc.ExecutionOptions): | ||
proc.Subprocess { | ||
const environment = this.getEffectiveSubprocessEnvironment(options); | ||
async executeCommand(command: string, args?: string[], consumer?: proc.OutputConsumer, options?: proc.ExecutionOptions): | ||
Promise<proc.Subprocess> { | ||
const environment = await this.getEffectiveSubprocessEnvironment(options); | ||
const exec_options = {...options, environment}; | ||
return proc.execute(command, args, consumer, exec_options); | ||
} | ||
|
@@ -347,13 +348,13 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
* Launch the given compilation command in an embedded terminal. | ||
* @param cmd The compilation command from a compilation database to run | ||
*/ | ||
runCompileCommand(cmd: ArgsCompileCommand): vscode.Terminal { | ||
async runCompileCommand(cmd: ArgsCompileCommand): Promise<vscode.Terminal> { | ||
let env: proc.EnvironmentVariables; | ||
if (this.useCMakePresets) { | ||
// buildpreset.environment at least has process.env after expansion | ||
env = this._buildPreset!.environment as proc.EnvironmentVariables; | ||
} else { | ||
env = this.getEffectiveSubprocessEnvironment(); | ||
env = await this.getCMakeBuildCommandEnvironment({}); | ||
} | ||
const key = `${cmd.directory}${JSON.stringify(env)}`; | ||
let existing = this._compileTerms.get(key); | ||
|
@@ -742,7 +743,7 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
} | ||
|
||
public async testHaveCommand(program: string, args: string[] = ['--version']): Promise<boolean> { | ||
const child = this.executeCommand(program, args, undefined, {silent: true}); | ||
const child = await this.executeCommand(program, args, undefined, {silent: true}); | ||
try { | ||
const result = await child.result; | ||
log.debug(localize('command.version.test.return.code', 'Command version test return code {0}', nullableValueToString(result.retc))); | ||
|
@@ -838,7 +839,7 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
if (arg) { | ||
args.push(arg); | ||
} | ||
const child = this.executeCommand(program, args, undefined, {silent: true, cwd}); | ||
const child = await this.executeCommand(program, args, undefined, {silent: true, cwd}); | ||
try { | ||
const result = await child.result; | ||
console.log(localize('command.version.test.return.code', 'Command version test return code {0}', nullableValueToString(result.retc))); | ||
|
@@ -1568,7 +1569,7 @@ export abstract class CMakeDriver implements vscode.Disposable { | |
} | ||
const exeOpt: proc.ExecutionOptions | ||
= {environment: buildcmd.build_env, outputEncoding: outputEnc, useTask: this.config.buildTask}; | ||
const child = this.executeCommand(buildcmd.command, buildcmd.args, consumer, exeOpt); | ||
const child = await this.executeCommand(buildcmd.command, buildcmd.args, consumer, exeOpt); | ||
this._currentBuildProcess = child; | ||
await child.result; | ||
this._currentBuildProcess = null; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UPDATE: We just updated the coding guidelines. You don't have to follow the new guideline for this PR. We will start applying it for the upcoming PRs :)
....
the plan is not to use
_
anymore, I know you didn't name this property, but as you are touching it, that would be good to rename it at the end.That would be great to apply the new naming guidelines for the rest of the PR as well: https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I touched too much variable with leading _, I think it's better to apply the naming guidelines with a single short, maybe by the lint rules, otherwise it's would get the code hard to review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, it's easier if we start applying new guidelines in future PRs.