11import { platform } from "os" ;
22import { basename , dirname , join , normalize , resolve } from "path" ;
33import { lstat , readdir } from "fs/promises" ;
4- import { extLogger } from "./logging/vscode" ;
5-
6- async function log ( message : string ) : Promise < void > {
7- await extLogger . log ( message ) ;
8- }
4+ import type { BaseLogger } from "./logging" ;
95
106/**
117 * Expand a single short path component
@@ -16,45 +12,46 @@ async function log(message: string): Promise<void> {
1612async function expandShortPathComponent (
1713 dir : string ,
1814 shortBase : string ,
15+ logger : BaseLogger ,
1916) : Promise < string > {
20- await log ( `Expanding short path component: ${ shortBase } ` ) ;
17+ void logger . log ( `Expanding short path component: ${ shortBase } ` ) ;
2118
2219 const fullPath = join ( dir , shortBase ) ;
2320
2421 // Use `lstat` instead of `stat` to avoid following symlinks.
2522 const stats = await lstat ( fullPath , { bigint : true } ) ;
2623 if ( stats . dev === BigInt ( 0 ) || stats . ino === BigInt ( 0 ) ) {
2724 // No inode info, so we won't be able to find this in the directory listing.
28- await log ( `No inode info available. Skipping.` ) ;
25+ void logger . log ( `No inode info available. Skipping.` ) ;
2926 return shortBase ;
3027 }
31- await log ( `dev/inode: ${ stats . dev } /${ stats . ino } ` ) ;
28+ void logger . log ( `dev/inode: ${ stats . dev } /${ stats . ino } ` ) ;
3229
3330 try {
3431 // Enumerate the children of the parent directory, and try to find one with the same dev/inode.
3532 const children = await readdir ( dir ) ;
3633 for ( const child of children ) {
37- await log ( `considering child: ${ child } ` ) ;
34+ void logger . log ( `considering child: ${ child } ` ) ;
3835 try {
3936 const childStats = await lstat ( join ( dir , child ) , { bigint : true } ) ;
40- await log ( `child dev/inode: ${ childStats . dev } /${ childStats . ino } ` ) ;
37+ void logger . log ( `child dev/inode: ${ childStats . dev } /${ childStats . ino } ` ) ;
4138 if ( childStats . dev === stats . dev && childStats . ino === stats . ino ) {
4239 // Found a match.
43- await log ( `Found a match: ${ child } ` ) ;
40+ void logger . log ( `Found a match: ${ child } ` ) ;
4441 return child ;
4542 }
4643 } catch ( e ) {
4744 // Can't read stats for the child, so skip it.
48- await log ( `Error reading stats for child: ${ e } ` ) ;
45+ void logger . log ( `Error reading stats for child: ${ e } ` ) ;
4946 }
5047 }
5148 } catch ( e ) {
5249 // Can't read the directory, so we won't be able to find this in the directory listing.
53- await log ( `Error reading directory: ${ e } ` ) ;
50+ void logger . log ( `Error reading directory: ${ e } ` ) ;
5451 return shortBase ;
5552 }
5653
57- await log ( `No match found. Returning original.` ) ;
54+ void logger . log ( `No match found. Returning original.` ) ;
5855 return shortBase ;
5956}
6057
@@ -63,49 +60,58 @@ async function expandShortPathComponent(
6360 * @param shortPath The path to expand.
6461 * @returns The expanded path.
6562 */
66- async function expandShortPathRecursive ( shortPath : string ) : Promise < string > {
63+ async function expandShortPathRecursive (
64+ shortPath : string ,
65+ logger : BaseLogger ,
66+ ) : Promise < string > {
6767 const shortBase = basename ( shortPath ) ;
6868 if ( shortBase . length === 0 ) {
6969 // We've reached the root.
7070 return shortPath ;
7171 }
7272
73- const dir = await expandShortPathRecursive ( dirname ( shortPath ) ) ;
74- await log ( `dir: ${ dir } ` ) ;
75- await log ( `base: ${ shortBase } ` ) ;
73+ const dir = await expandShortPathRecursive ( dirname ( shortPath ) , logger ) ;
74+ void logger . log ( `dir: ${ dir } ` ) ;
75+ void logger . log ( `base: ${ shortBase } ` ) ;
7676 if ( shortBase . indexOf ( "~" ) < 0 ) {
7777 // This component doesn't have a short name, so just append it to the (long) parent.
78- await log ( `Component is not a short name` ) ;
78+ void logger . log ( `Component is not a short name` ) ;
7979 return join ( dir , shortBase ) ;
8080 }
8181
8282 // This component looks like it has a short name, so try to expand it.
83- const longBase = await expandShortPathComponent ( dir , shortBase ) ;
83+ const longBase = await expandShortPathComponent ( dir , shortBase , logger ) ;
8484 return join ( dir , longBase ) ;
8585}
8686
8787/**
8888 * Expands a path that potentially contains 8.3 short names (e.g. "C:\PROGRA~1" instead of "C:\Program Files").
89+ *
90+ * See https://en.wikipedia.org/wiki/8.3_filename if you're not familiar with Windows 8.3 short names.
91+ *
8992 * @param shortPath The path to expand.
9093 * @returns A normalized, absolute path, with any short components expanded.
9194 */
92- export async function expandShortPaths ( shortPath : string ) : Promise < string > {
95+ export async function expandShortPaths (
96+ shortPath : string ,
97+ logger : BaseLogger ,
98+ ) : Promise < string > {
9399 const absoluteShortPath = normalize ( resolve ( shortPath ) ) ;
94100 if ( platform ( ) !== "win32" ) {
95101 // POSIX doesn't have short paths.
96102 return absoluteShortPath ;
97103 }
98104
99- await log ( `Expanding short paths in: ${ absoluteShortPath } ` ) ;
105+ void logger . log ( `Expanding short paths in: ${ absoluteShortPath } ` ) ;
100106 // A quick check to see if there might be any short components.
101107 // There might be a case where a short component doesn't contain a `~`, but if there is, I haven't
102108 // found it.
103109 // This may find long components that happen to have a '~', but that's OK.
104110 if ( absoluteShortPath . indexOf ( "~" ) < 0 ) {
105111 // No short components to expand.
106- await log ( `Skipping due to no short components` ) ;
112+ void logger . log ( `Skipping due to no short components` ) ;
107113 return absoluteShortPath ;
108114 }
109115
110- return await expandShortPathRecursive ( absoluteShortPath ) ;
116+ return await expandShortPathRecursive ( absoluteShortPath , logger ) ;
111117}
0 commit comments