@@ -4,11 +4,15 @@ import * as path from "path"
4
4
import * as util from "util"
5
5
import { Args } from "./cli"
6
6
import { HttpServer } from "./http"
7
+ import { paths } from "./util"
7
8
8
9
/* eslint-disable @typescript-eslint/no-var-requires */
9
10
10
11
export type Activate = ( httpServer : HttpServer , args : Args ) => void
11
12
13
+ /**
14
+ * Plugins must implement this interface.
15
+ */
12
16
export interface Plugin {
13
17
activate : Activate
14
18
}
@@ -23,6 +27,9 @@ require("module")._load = function (request: string, parent: object, isMain: boo
23
27
return originalLoad . apply ( this , [ request . replace ( / ^ c o d e - s e r v e r / , path . resolve ( __dirname , "../.." ) ) , parent , isMain ] )
24
28
}
25
29
30
+ /**
31
+ * Load a plugin and run its activation function.
32
+ */
26
33
const loadPlugin = async ( pluginPath : string , httpServer : HttpServer , args : Args ) : Promise < void > => {
27
34
try {
28
35
const plugin : Plugin = require ( pluginPath )
@@ -37,24 +44,42 @@ const loadPlugin = async (pluginPath: string, httpServer: HttpServer, args: Args
37
44
}
38
45
}
39
46
40
- const _loadPlugins = async ( httpServer : HttpServer , args : Args ) : Promise < void > => {
41
- const pluginPath = path . resolve ( __dirname , "../../plugins" )
42
- const files = await util . promisify ( fs . readdir ) ( pluginPath , {
43
- withFileTypes : true ,
44
- } )
45
- await Promise . all ( files . map ( ( file ) => loadPlugin ( path . join ( pluginPath , file . name ) , httpServer , args ) ) )
46
- }
47
-
48
- export const loadPlugins = async ( httpServer : HttpServer , args : Args ) : Promise < void > => {
47
+ /**
48
+ * Load all plugins in the specified directory.
49
+ */
50
+ const _loadPlugins = async ( pluginDir : string , httpServer : HttpServer , args : Args ) : Promise < void > => {
49
51
try {
50
- await _loadPlugins ( httpServer , args )
52
+ const files = await util . promisify ( fs . readdir ) ( pluginDir , {
53
+ withFileTypes : true ,
54
+ } )
55
+ await Promise . all ( files . map ( ( file ) => loadPlugin ( path . join ( pluginDir , file . name ) , httpServer , args ) ) )
51
56
} catch ( error ) {
52
57
if ( error . code !== "ENOENT" ) {
53
58
logger . warn ( error . message )
54
59
}
55
60
}
61
+ }
56
62
57
- if ( process . env . PLUGIN_DIR ) {
58
- await loadPlugin ( process . env . PLUGIN_DIR , httpServer , args )
59
- }
63
+ /**
64
+ * Load all plugins from the `plugins` directory and the directory specified by
65
+ * `PLUGIN_DIR`.
66
+
67
+ * Also load any individual plugins found in `PLUGIN_DIRS` (colon-separated).
68
+ * This allows you to test and develop plugins without having to move or symlink
69
+ * them into one directory.
70
+ */
71
+ export const loadPlugins = async ( httpServer : HttpServer , args : Args ) : Promise < void > => {
72
+ await Promise . all ( [
73
+ // Built-in plugins.
74
+ _loadPlugins ( path . resolve ( __dirname , "../../plugins" ) , httpServer , args ) ,
75
+ // User-added plugins.
76
+ _loadPlugins (
77
+ path . resolve ( process . env . PLUGIN_DIR || path . join ( paths . data , "code-server-extensions" ) ) ,
78
+ httpServer ,
79
+ args ,
80
+ ) ,
81
+ // For development so you don't have to use symlinks.
82
+ process . env . PLUGIN_DIRS &&
83
+ ( await Promise . all ( process . env . PLUGIN_DIRS . split ( ":" ) . map ( ( dir ) => loadPlugin ( dir , httpServer , args ) ) ) ) ,
84
+ ] )
60
85
}
0 commit comments