Skip to content

Commit c86ddcd

Browse files
authored
Merge pull request microsoft#3180 from iclanton/fix-issue-with-git-bash-tar
[rush] Fix an issue where the TAR exectuable on the Git Bash PATH does not handle Windows paths correctly.
2 parents 9a73f51 + fe5d636 commit c86ddcd

File tree

3 files changed

+38
-9
lines changed

3 files changed

+38
-9
lines changed

apps/rush-lib/src/logic/buildCache/ProjectBuildCache.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class ProjectBuildCache {
3939
* null === we haven't tried to initialize yet
4040
* undefined === unable to initialize
4141
*/
42-
private static _tarUtility: TarExecutable | null | undefined = null;
42+
private static _tarUtilityPromise: Promise<TarExecutable | undefined> | null = null;
4343

4444
private readonly _project: RushConfigurationProject;
4545
private readonly _localBuildCacheProvider: FileSystemBuildCacheProvider;
@@ -57,12 +57,12 @@ export class ProjectBuildCache {
5757
this._cacheId = cacheId;
5858
}
5959

60-
private static _tryGetTarUtility(terminal: ITerminal): TarExecutable | undefined {
61-
if (ProjectBuildCache._tarUtility === null) {
62-
ProjectBuildCache._tarUtility = TarExecutable.tryInitialize(terminal);
60+
private static _tryGetTarUtility(terminal: ITerminal): Promise<TarExecutable | undefined> {
61+
if (ProjectBuildCache._tarUtilityPromise === null) {
62+
ProjectBuildCache._tarUtilityPromise = TarExecutable.tryInitializeAsync(terminal);
6363
}
6464

65-
return ProjectBuildCache._tarUtility;
65+
return ProjectBuildCache._tarUtilityPromise;
6666
}
6767

6868
public static async tryGetProjectBuildCache(
@@ -180,7 +180,7 @@ export class ProjectBuildCache {
180180
)
181181
);
182182

183-
const tarUtility: TarExecutable | undefined = ProjectBuildCache._tryGetTarUtility(terminal);
183+
const tarUtility: TarExecutable | undefined = await ProjectBuildCache._tryGetTarUtility(terminal);
184184
let restoreSuccess: boolean = false;
185185
if (tarUtility && localCacheEntryPath) {
186186
const logFilePath: string = this._getTarLogFilePath();
@@ -263,7 +263,7 @@ export class ProjectBuildCache {
263263

264264
let localCacheEntryPath: string | undefined;
265265

266-
const tarUtility: TarExecutable | undefined = ProjectBuildCache._tryGetTarUtility(terminal);
266+
const tarUtility: TarExecutable | undefined = await ProjectBuildCache._tryGetTarUtility(terminal);
267267
if (tarUtility) {
268268
const tempLocalCacheEntryPath: string = this._localBuildCacheProvider.getCacheEntryPath(cacheId);
269269
const logFilePath: string = this._getTarLogFilePath();

apps/rush-lib/src/utilities/TarExecutable.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// See LICENSE in the project root for license information.
33

44
import * as path from 'path';
5+
import os from 'os';
56
import { Executable, FileSystem, FileWriter, ITerminal } from '@rushstack/node-core-library';
67
import { ChildProcess } from 'child_process';
78
import events from 'events';
@@ -31,10 +32,10 @@ export class TarExecutable {
3132
this._tarExecutablePath = tarExecutablePath;
3233
}
3334

34-
public static tryInitialize(terminal: ITerminal): TarExecutable | undefined {
35+
public static async tryInitializeAsync(terminal: ITerminal): Promise<TarExecutable | undefined> {
3536
terminal.writeVerboseLine('Trying to find "tar" binary');
3637
const tarExecutablePath: string | undefined =
37-
EnvironmentConfiguration.tarBinaryPath || Executable.tryResolve('tar');
38+
EnvironmentConfiguration.tarBinaryPath || (await TarExecutable._tryFindTarExecutablePathAsync());
3839
if (!tarExecutablePath) {
3940
terminal.writeVerboseLine('"tar" was not found on the PATH');
4041
return undefined;
@@ -163,4 +164,22 @@ export class TarExecutable {
163164

164165
return tarExitCode;
165166
}
167+
168+
private static async _tryFindTarExecutablePathAsync(): Promise<string | undefined> {
169+
if (os.platform() === 'win32') {
170+
// If we're running on Windows, first try to use the OOB tar executable. If
171+
// we're running in the Git Bash, the tar executable on the PATH doesn't handle
172+
// Windows file paths correctly.
173+
// eslint-disable-next-line dot-notation
174+
const windowsFolderPath: string | undefined = process.env['WINDIR'];
175+
if (windowsFolderPath) {
176+
const defaultWindowsTarExecutablePath: string = `${windowsFolderPath}\\system32\\tar.exe`;
177+
if (await FileSystem.existsAsync(defaultWindowsTarExecutablePath)) {
178+
return defaultWindowsTarExecutablePath;
179+
}
180+
}
181+
}
182+
183+
return Executable.tryResolve('tar');
184+
}
166185
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@microsoft/rush",
5+
"comment": "Fix an issue where the TAR exectuable on the Git Bash PATH does not handle Windows paths correctly.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush"
10+
}

0 commit comments

Comments
 (0)