Skip to content

Commit

Permalink
Merge pull request #10 from MikeGarde/list
Browse files Browse the repository at this point in the history
Better List handling
  • Loading branch information
MikeGarde authored Jul 6, 2024
2 parents 8780c84 + 57866b1 commit 4475023
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ tasks:
- task is-branch-safe
cmds:
- npm publish --access public
release-*-pub:
release:publish:*:
desc: Create a new release and publish it to npm, release-[patch|minor|major]-pub
vars:
STEP: '{{index .MATCH 0}}'
Expand Down
14 changes: 7 additions & 7 deletions src/envObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ export class EnvValue {
lineEnd: number;

constructor(value: string, lineStart: number = -1, lineEnd: number = -1) {
this.value = value;
this.value = value;
this.lineStart = lineStart;
this.lineEnd = lineEnd;
this.lineEnd = lineEnd;
}
}

Expand Down Expand Up @@ -40,9 +40,9 @@ class EnvObject {
} else {
// TODO: let's not allow this
target[key as string] = {
value: value,
value: value,
lineStart: -1, // You might want to set these values appropriately
lineEnd: -1
lineEnd: -1
};
}
return true;
Expand All @@ -54,8 +54,8 @@ class EnvObject {
let obj: { [key: string]: string } = {};

for (const key in this) {
const keyName = key as string;
const value = this[keyName].value;
const keyName: string = key as string;
const value = this[keyName].value;

if (typeof value === 'string') {
obj[keyName] = value;
Expand All @@ -64,7 +64,7 @@ class EnvObject {
return obj;
}

toJsonString(pretty:boolean = false): string {
toJsonString(pretty: boolean = false): string {
if (pretty) {
return JSON.stringify(this.toObj(), null, 2);
} else {
Expand Down
36 changes: 21 additions & 15 deletions src/envParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,32 @@ function getEndLine(envLines: string[], startLine: number, quoteType: string): n
}

function extractLines(envLines: string[], startLine: number, endLine: number, quoted: boolean): EnvValue {
let allLines = envLines.slice(startLine, endLine + 1);
allLines[0] = allLines[0].split('=')[1];
let allLines: string[] = envLines.slice(startLine, endLine + 1);
allLines[0] = allLines[0].split('=')[1];
let blob: string = allLines.join('\n').trim();

let blob = allLines.join('\n').trim();
if (quoted) {
blob = blob.slice(1, -1);
}

if (blob.startsWith('[') && blob.endsWith(']')) {
let arr: string[] = [];
try {
arr = JSON.parse(blob);
} catch (e) {
throw new EnvParseError(startLine + 1, `Invalid list: ${blob}`);
}
arr = arr.map((item: string) => `"${item}"`);
blob = '[' + arr.join(', ') + ']';
}

return {
value: blob,
lineStart: startLine,
lineEnd: endLine
};
}

/**
* Parse the .env file into an object
*
* @param filePath
*/
function parseEnvFile(filePath: string): EnvObject {
const envContent: string = fs.readFileSync(filePath, 'utf8');
const envLines: string[] = envContent.split('\n');
Expand Down Expand Up @@ -62,16 +69,15 @@ function parseEnvFile(filePath: string): EnvObject {
log.debug(`${lineCurrent + 1} | key: ${key}, single quoted, ${value.endsWith("'") ? 'single line' : 'multiline'}`);
lineCurrent = getEndLine(envLines, lineStart, "");
envObject[key] = extractLines(envLines, lineStart, lineCurrent, true);
} else if (value.startsWith('[')) {
log.debug(`${lineCurrent + 1} | key: ${key}, list, ${value.endsWith(']') ? 'single line' : 'multiline'}`);
lineCurrent = getEndLine(envLines, lineStart, ']');
envObject[key] = extractLines(envLines, lineStart, lineCurrent, false);
} else {
log.debug(`${lineCurrent + 1} | key: ${key}, un-quoted, single line`)

// If a list we'll allow it
const hasQuotes: boolean = value.includes('"') || value.includes("'");
const evenDoubleQuotes: boolean = value.split('"').length % 2 === 0;
const evenSingleQuotes: boolean = value.split("'").length % 2 === 0;
const isList: boolean = value.startsWith('[') && value.endsWith(']');

if (hasQuotes && (!evenDoubleQuotes || !evenSingleQuotes) && !isList) {
const hasQuotes: boolean = value.includes('"') || value.includes("'");
if (hasQuotes) {
throw new EnvParseError(lineCurrent + 1, `Invalid value: ${envLines[lineCurrent]}`);
}
envObject[key] = extractLines(envLines, lineStart, lineCurrent, false);
Expand Down
7 changes: 6 additions & 1 deletion tests/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ multi-line"
SINGLE_MULTI='Single
multi-line'
// invalid comment
TERRAFORM_LIST=["one", "two", "three"]
LIST_SINGLE_LINE=["one", "two", "three"]
LIST_MULTI_LINE=[
"one",
"two",
"three"
]
CORRECT_MULTI="correct\nmulti-line"
EMPTY=

Expand Down
18 changes: 18 additions & 0 deletions tests/app.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ describe('app.ts', () => {
const appPath = path.resolve(__dirname, '../build/app.js');
const envPath = path.resolve(__dirname, '.env.test');

const badListPath = path.resolve(__dirname, 'envFiles/badList.env');

test('missing .env file', async () => {
try {
const nonExistent = execSync(`node ${appPath} void --file non-existent.env`);
Expand Down Expand Up @@ -51,4 +53,20 @@ describe('app.ts', () => {
expect(errorMsg).toBe('');
}
});

test('valid single line list', () => {
const result = execSync(`node ${appPath} LIST_SINGLE_LINE --file ${envPath}`);
expect(result.toString().trim()).toBe('["one", "two", "three"]');
});

test('valid multi-line list', () => {
const result = execSync(`node ${appPath} LIST_MULTI_LINE --file ${envPath}`);
expect(result.toString().trim()).toBe('["one", "two", "three"]');
});

test('invalid list throws error', () => {
expect(() => {
execSync(`node ${appPath} BAD_LIST --file ${badListPath}`);
}).toThrow('EnvParseError');
});
});
4 changes: 4 additions & 0 deletions tests/envFiles/badList.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
BAD_LIST=["starts right",
"new line
in the middle",
"makes it invalid"]
2 changes: 1 addition & 1 deletion tests/envParser.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ describe('envParse', () => {

// TODO: Race conditions by the setAndDelete tests may cause this number to vary upward
// TODO: expect(envCount).toBe(7);
expect(envCount).toBeGreaterThanOrEqual(8);
expect(envCount).toBeGreaterThanOrEqual(9);
});
});

0 comments on commit 4475023

Please sign in to comment.