Skip to content

Instantly share code, notes, and snippets.

@ento
Last active November 29, 2023 23:01
Show Gist options
  • Save ento/765b47da99cc05d4fec508632e8d1f64 to your computer and use it in GitHub Desktop.
Save ento/765b47da99cc05d4fec508632e8d1f64 to your computer and use it in GitHub Desktop.
let
parseLine = line:
let
parts = builtins.match "([^[:space:]=#]+)[[:space:]]*=[[:space:]]*(.*)" line;
in
if (!builtins.isNull parts) && (builtins.length parts) == 2 then
{ name = builtins.elemAt parts 0; value = builtins.elemAt parts 1; }
else
null;
in
{
# Test cases from https://bbc2.github.io/dotenv-parser-comparisons/
testBasic = {
expr = parseLine "foo=ab";
expected = { name = "foo"; value = "ab"; };
};
testEscapedZ = {
expr = parseLine "foo=a\zb";
expected = { name = "foo"; value = "a\zb"; };
};
testEscapedAndSingleQuotedZ = {
expr = parseLine "foo='a\zb'";
expected = { name = "foo"; value = "'a\zb'"; };
};
testEscapedAndDoubleQuotedZ = {
expr = parseLine ''foo="a\zb"'';
expected = { name = "foo"; value = ''"a\zb"''; };
};
testEscapedN = {
expr = parseLine "foo=a\nb";
expected = { name = "foo"; value = "a\nb"; };
};
testEscapedAndSingleQuotedN = {
expr = parseLine "foo='a\nb'";
expected = { name = "foo"; value = "'a\nb'"; };
};
testEscapedAndDoubleQuotedN = {
expr = parseLine ''foo="a\nb"'';
expected = { name = "foo"; value = ''"a\nb"''; };
};
testQuotedNewline = {
expr = parseLine ''foo="a
b"'';
expected = { name = "foo"; value = ''"a
b"''; };
};
testNonEscapedSpace = {
expr = parseLine "foo=a b";
expected = { name = "foo"; value = "a b"; };
};
testNonEscapedPoundSign = {
expr = parseLine "foo=a#b";
expected = { name = "foo"; value = "a#b"; };
};
testNonEscapedSpacedPoundSign = {
expr = parseLine "foo=a #b";
expected = { name = "foo"; value = "a #b"; };
};
testDoubleQuotedPoundSign = {
expr = parseLine ''foo="a#b"'';
expected = { name = "foo"; value = ''"a#b"''; };
};
testUTF8 = {
expr = parseLine "foo=é";
expected = { name = "foo"; value = "é"; };
};
testQuotedUTF8 = {
expr = parseLine ''foo="é"'';
expected = { name = "foo"; value = ''"é"''; };
};
testVariable = {
expr = parseLine "foo=$a";
expected = { name = "foo"; value = "$a"; };
};
testSingleQuotedVariable = {
expr = parseLine "foo='$a'";
expected = { name = "foo"; value = "'$a'"; };
};
testDoubleQuotedVariable = {
expr = parseLine ''foo="$a"'';
expected = { name = "foo"; value = ''"$a"''; };
};
testVariableWithBraces = {
expr = parseLine ''foo=x''${a}y'';
expected = { name = "foo"; value = ''x''${a}y''; };
};
testSingleQuotedVariableWithBraces = {
expr = parseLine ''foo='x''${a}y''''';
expected = { name = "foo"; value = '''x''${a}y'''''; };
};
testDoubleQuotedVariableWithBraces = {
expr = parseLine ''foo="x''${a}y"'';
expected = { name = "foo"; value = ''"x''${a}y"''; };
};
testVariableUndefined = {
expr = parseLine "foo=$a";
expected = { name = "foo"; value = "$a"; };
};
testVariableFollowedByDot = {
expr = parseLine "foo=x$a.y";
expected = { name = "foo"; value = "x$a.y"; };
};
testVariableFollowedByHyphen = {
expr = parseLine "foo=x$a-y";
expected = { name = "foo"; value = "x$a-y"; };
};
testVariableFollowedByUnderscore = {
expr = parseLine "foo=x$a_y";
expected = { name = "foo"; value = "x$a_y"; };
};
testVariableWithBracesUndefined = {
expr = parseLine ''foo=x''${a}y'';
expected = { name = "foo"; value = ''x''${a}y''; };
};
testVariableWithUnusedDefaultExpansion = {
expr = parseLine ''foo=x''${a:-c}'';
expected = { name = "foo"; value = ''x''${a:-c}''; };
};
testVariableWithDefaultExpansion = {
expr = parseLine ''foo=x''${a:-c}'';
expected = { name = "foo"; value = ''x''${a:-c}''; };
};
# Extra test cases
testComment = {
expr = parseLine "#foo=ab";
expected = null;
};
testCommentWithSpace = {
expr = parseLine "# foo=ab";
expected = null;
};
testLeadingSpace = {
expr = parseLine " foo=ab";
expected = null;
};
testSpaceInName = {
expr = parseLine "f oo=ab";
expected = null;
};
testTrailingSpace = {
expr = parseLine "foo=ab ";
expected = { name = "foo"; value = "ab "; };
};
testInlineCommentWithSpacesAroundPoundSign = {
expr = parseLine "foo=ab # comment";
expected = { name = "foo"; value = "ab # comment"; };
};
testInlineCommentWithNoSpacesAroundPoundSign = {
expr = parseLine "foo=ab#comment";
expected = { name = "foo"; value = "ab#comment"; };
};
testPoundSignInQuotes = {
expr = parseLine "foo='ab#comment'";
expected = { name = "foo"; value = "'ab#comment'"; };
};
testValueWithEqualSign = {
expr = parseLine "foo=ab=baz";
expected = { name = "foo"; value = "ab=baz"; };
};
testDatabaseUrl = {
expr = parseLine "DATABASE_URL=postgresql://postgres:postgres@localhost:5432/postgres?schema=public";
expected = { name = "DATABASE_URL"; value = "postgresql://postgres:postgres@localhost:5432/postgres?schema=public"; };
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment