Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/common/envfile.ts
3291 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
/**
7
* Parses a standard .env/.envrc file into a map of the environment variables
8
* it defines.
9
*
10
* todo@connor4312: this can go away (if only used in Node.js targets) and be
11
* replaced with `util.parseEnv`. However, currently calling that makes the
12
* extension host crash.
13
*/
14
export function parseEnvFile(src: string) {
15
const result = new Map<string, string>();
16
17
// Normalize line breaks
18
const normalizedSrc = src.replace(/\r\n?/g, '\n');
19
const lines = normalizedSrc.split('\n');
20
21
for (let line of lines) {
22
// Skip empty lines and comments
23
line = line.trim();
24
if (!line || line.startsWith('#')) {
25
continue;
26
}
27
28
// Parse the line into key and value
29
const [key, value] = parseLine(line);
30
if (key) {
31
result.set(key, value);
32
}
33
}
34
35
return result;
36
37
function parseLine(line: string): [string, string] | [null, null] {
38
// Handle export prefix
39
if (line.startsWith('export ')) {
40
line = line.substring(7).trim();
41
}
42
43
// Find the key-value separator
44
const separatorIndex = findIndexOutsideQuotes(line, c => c === '=' || c === ':');
45
if (separatorIndex === -1) {
46
return [null, null];
47
}
48
49
const key = line.substring(0, separatorIndex).trim();
50
let value = line.substring(separatorIndex + 1).trim();
51
52
// Handle comments and remove them
53
const commentIndex = findIndexOutsideQuotes(value, c => c === '#');
54
if (commentIndex !== -1) {
55
value = value.substring(0, commentIndex).trim();
56
}
57
58
// Process quoted values
59
if (value.length >= 2) {
60
const firstChar = value[0];
61
const lastChar = value[value.length - 1];
62
63
if ((firstChar === '"' && lastChar === '"') ||
64
(firstChar === '\'' && lastChar === '\'') ||
65
(firstChar === '`' && lastChar === '`')) {
66
// Remove surrounding quotes
67
value = value.substring(1, value.length - 1);
68
69
// Handle escaped characters in double quotes
70
if (firstChar === '"') {
71
value = value.replace(/\\n/g, '\n').replace(/\\r/g, '\r');
72
}
73
}
74
}
75
76
return [key, value];
77
}
78
79
function findIndexOutsideQuotes(text: string, predicate: (char: string) => boolean): number {
80
let inQuote = false;
81
let quoteChar = '';
82
83
for (let i = 0; i < text.length; i++) {
84
const char = text[i];
85
86
if (inQuote) {
87
if (char === quoteChar && text[i - 1] !== '\\') {
88
inQuote = false;
89
}
90
} else if (char === '"' || char === '\'' || char === '`') {
91
inQuote = true;
92
quoteChar = char;
93
} else if (predicate(char)) {
94
return i;
95
}
96
}
97
98
return -1;
99
}
100
}
101
102