Skip to content

Commit 37c64bc

Browse files
authored
Merge pull request #3 from glektarssza/bugfix/symlink-handling
[Bug Fix] Fixed handling of symbolic links (and broken ones specifically)
2 parents bd4f4a9 + 86cbccb commit 37c64bc

File tree

7 files changed

+72
-67
lines changed

7 files changed

+72
-67
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,6 @@ node_modules/
5050
## TypeScript ##
5151
out/
5252
*.vsix
53+
54+
# Test Symlinks #
55+
*-symlink

.vscode/launch.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
// A launch configuration that compiles the extension and then opens it inside a new window
21
{
3-
"version": "0.1.0",
2+
"version": "0.2.0",
43
"configurations": [
54
{
65
"name": "Launch Extension",
76
"type": "extensionHost",
87
"request": "launch",
9-
"runtimeExecutable": "${execPath}",
10-
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
11-
"sourceMaps": true,
12-
"outFiles": ["${workspaceRoot}/out/src"],
8+
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
9+
"outFiles": ["${workspaceFolder}/out/**/*.js"],
1310
"preLaunchTask": "npm"
1411
},
1512
{

.vscode/tasks.json

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,15 @@
1-
// Available variables which can be used inside of strings.
2-
// ${workspaceRoot}: the root folder of the team
3-
// ${file}: the current opened file
4-
// ${fileBasename}: the current opened file's basename
5-
// ${fileDirname}: the current opened file's dirname
6-
// ${fileExtname}: the current opened file's extension
7-
// ${cwd}: the current working directory of the spawned process
8-
9-
// A task runner that calls a custom npm script that compiles the extension.
101
{
112
"version": "2.0.0",
12-
13-
// we want to run npm
14-
"command": "npm",
15-
16-
// we run the custom script "compile" as defined in package.json
17-
"args": ["run", "compile", "--loglevel", "silent"],
18-
19-
// The tsc compiler is started in watching mode
20-
"isWatching": true,
21-
22-
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
23-
"problemMatcher": "$tsc-watch",
243
"tasks": [
254
{
265
"label": "npm",
276
"type": "shell",
287
"command": "npm",
29-
"args": ["run", "compile", "--loglevel", "silent"],
8+
"args": ["run", "build:watch", "--loglevel", "silent"],
309
"isBackground": true,
3110
"problemMatcher": "$tsc-watch",
3211
"group": {
33-
"_id": "build",
12+
"kind": "build",
3413
"isDefault": false
3514
}
3615
}

.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ types/
99
tsconfig.json
1010
vsc-extension-quickstart.md
1111
.nvmrc
12+
*-symlink

package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "glek-advanced-new-file",
33
"displayName": "G'lek's Advanced New File",
44
"description": "Create files anywhere in your workspace from the keyboard.",
5-
"version": "1.5.0",
5+
"version": "1.5.1",
66
"publisher": "glektarssza",
77
"engines": {
88
"vscode": "^1.22.0"
@@ -80,6 +80,11 @@
8080
"type": "boolean",
8181
"default": true,
8282
"description": "Whether to use the values from `files.exclude` when deciding which folders to ignore."
83+
},
84+
"advancedNewFile.showSymlinks": {
85+
"type": "boolean",
86+
"default": true,
87+
"description": "Whether to show symbolic links when listing direcotries."
8388
}
8489
}
8590
}

src/extension.ts

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,48 @@ function configIgnoredGlobs(root: string): string[] {
8585
return gitignoreToGlob(configIgnored.join('\n'), {string: true});
8686
}
8787

88+
function isDirectory(p: string): boolean {
89+
return fs.existsSync(p) && fs.lstatSync(p).isDirectory();
90+
}
91+
92+
function readSymlink(p: string): string | null {
93+
if (!isSymlink(p)) {
94+
return null;
95+
}
96+
return fs.readlinkSync(p);
97+
}
98+
99+
function readSymlinkAbsolute(p: string): string | null {
100+
const sp = readSymlink(p);
101+
if (!sp) {
102+
return null;
103+
}
104+
return path.resolve(path.dirname(p), sp);
105+
}
106+
107+
function isSymlink(p: string): boolean {
108+
return fs.existsSync(p) && fs.lstatSync(p).isSymbolicLink();
109+
}
110+
111+
function isValidSymlink(p: string): boolean {
112+
const sp = readSymlinkAbsolute(p);
113+
if (!sp) {
114+
return false;
115+
}
116+
return fs.existsSync(sp);
117+
}
118+
119+
function isDirectorySymlink(p: string): boolean {
120+
if (!isValidSymlink(p)) {
121+
return false;
122+
}
123+
const sp = readSymlinkAbsolute(p);
124+
if (!sp) {
125+
return false;
126+
}
127+
return fs.lstatSync(sp).isDirectory();
128+
}
129+
88130
function directoriesSync(root: string): FSLocation[] {
89131
const ignore: string[] = [];
90132
if (
@@ -96,16 +138,27 @@ function directoriesSync(root: string): FSLocation[] {
96138
}
97139
ignore.push(...configIgnoredGlobs(root));
98140

99-
const results = globSync('**', {cwd: root, ignore: ignore.map(invertGlob)})
141+
const results = globSync('**', {
142+
cwd: root,
143+
ignore: ignore.map(invertGlob),
144+
symlinks: vscode.workspace
145+
.getConfiguration('advancedNewFile')
146+
.get('showSymlinks', true)
147+
})
100148
.map((f): FSLocation => {
101149
return {
102150
relative: path.join(path.sep, f),
103151
absolute: path.join(root, f)
104152
};
105153
})
106-
.filter((f) => fs.statSync(f.absolute).isDirectory())
107-
.map((f) => f);
108-
154+
.filter(
155+
(f) =>
156+
isDirectory(f.absolute) ||
157+
(isDirectorySymlink(f.absolute) &&
158+
vscode.workspace
159+
.getConfiguration('advancedNewFile')
160+
.get('showSymlinks', true))
161+
);
109162
return results;
110163
}
111164

vsc-extension-quickstart.md

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)