Fix go.mod parser for repeated replace directives

Constructs such as
```
replace google.golang.org/grpc => google.golang.org/grpc v1.33.2
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
```

Are perfectly valid and we previously discarded every one but the last of them.
This commit is contained in:
adisbladis 2022-05-29 01:36:10 +08:00
parent 3c029180a3
commit d831b947fc

View file

@ -3,7 +3,7 @@
# in normalised form. # in normalised form.
let let
inherit (builtins) elemAt mapAttrs split foldl' match filter typeOf; inherit (builtins) elemAt mapAttrs split foldl' match filter typeOf hasAttr length;
# Strip lines with comments & other junk # Strip lines with comments & other junk
stripStr = s: elemAt (split "^ *" (elemAt (split " *$" s) 0)) 2; stripStr = s: elemAt (split "^ *" (elemAt (split " *$" s) 0)) 2;
@ -16,9 +16,6 @@ let
# Strip leading tabs characters # Strip leading tabs characters
(lines: map (l: elemAt (match "(\t)?(.*)" l) 1) lines) (lines: map (l: elemAt (match "(\t)?(.*)" l) 1) lines)
# Strip comment lines
(filter (l: match "[ \t]*//.*" l != null))
# Filter empty lines # Filter empty lines
(filter (l: l != "")) (filter (l: l != ""))
]; ];
@ -40,21 +37,40 @@ let
in in
{ {
data = acc.data // ( data = (acc.data // (
if directive == "" && rest == ")" then { } if directive == "" && rest == ")" then { }
else if inDirective != null && rest == "(" then { else if inDirective != null && rest == "(" && ! hasAttr inDirective acc.data then {
${inDirective} = { }; ${inDirective} = { };
} else if inDirective != null then { }
else if rest == "(" || rest == ")" then { }
else if inDirective != null then {
${inDirective} = acc.data.${inDirective} // { ${directive} = rest; }; ${inDirective} = acc.data.${inDirective} // { ${directive} = rest; };
} else { } else if directive == "replace" then
(
let
segments = split " => " rest;
getSegment = elemAt segments;
in
assert length segments == 3; {
replace = acc.data.replace // {
${getSegment 0} = "=> ${getSegment 2}";
};
}
)
else {
${directive} = rest; ${directive} = rest;
} }
)
); );
inherit inDirective; inherit inDirective;
}) })
{ {
inDirective = null; inDirective = null;
data = { }; data = {
require = { };
replace = { };
exclude = { };
};
} }
lines lines
).data; ).data;
@ -98,14 +114,14 @@ let
data // { data // {
replace = replace =
mapAttrs mapAttrs
(n: v: (_: v:
let let
m = match "=> ([^ ]+) (.+)" v; m = match "=> ([^ ]+) (.+)" v;
m2 = match "=> (.*+)" v; m2 = match "=> (.*+)" v;
in in
if m != null then { if m != null then {
goPackagePath = elemAt m 0; goPackagePath = elemAt m 0;
version = parseVersion (elemAt m 1); version = elemAt m 1;
} else { } else {
path = elemAt m2 0; path = elemAt m2 0;
}) })
@ -113,12 +129,6 @@ let
} }
); );
parseRequire = data: (
data // {
require = mapAttrs (n: v: parseVersion v) data.require;
}
);
splitString = sep: s: filter (t: t != [ ]) (split sep s); splitString = sep: s: filter (t: t != [ ]) (split sep s);
in in
@ -128,5 +138,4 @@ foldl' (acc: f: f acc) (splitString "\n" contents) [
parseLines parseLines
normaliseDirectives normaliseDirectives
parseReplace parseReplace
parseRequire
] ]