Add splitVersion primop.

Fixes #1868.
This commit is contained in:
Shea Levy 2018-02-13 18:28:27 -05:00
parent 3fe9767dd3
commit b095c06139
No known key found for this signature in database
GPG key ID: 5C0BD6957D86FE27
6 changed files with 37 additions and 1 deletions

View file

@ -126,6 +126,17 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
</varlistentry> </varlistentry>
<varlistentry><term><function>builtins.splitVersion</function>
<replaceable>s</replaceable></term>
<listitem><para>Split a string representing a version into its
components, by the same version splitting logic underlying the
version comparison in <link linkend="ssec-version-comparisons">
<command>nix-env -u</command></link>.</para></listitem>
</varlistentry>
<varlistentry><term><function>builtins.concatLists</function> <varlistentry><term><function>builtins.concatLists</function>
<replaceable>lists</replaceable></term> <replaceable>lists</replaceable></term>

View file

@ -41,7 +41,7 @@ bool DrvName::matches(DrvName & n)
} }
static string nextComponent(string::const_iterator & p, string nextComponent(string::const_iterator & p,
const string::const_iterator end) const string::const_iterator end)
{ {
/* Skip any dots and dashes (component separators). */ /* Skip any dots and dashes (component separators). */

View file

@ -24,6 +24,8 @@ private:
typedef list<DrvName> DrvNames; typedef list<DrvName> DrvNames;
string nextComponent(string::const_iterator & p,
const string::const_iterator end);
int compareVersions(const string & v1, const string & v2); int compareVersions(const string & v1, const string & v2);
DrvNames drvNamesFromArgs(const Strings & opArgs); DrvNames drvNamesFromArgs(const Strings & opArgs);

View file

@ -1961,6 +1961,26 @@ static void prim_compareVersions(EvalState & state, const Pos & pos, Value * * a
} }
static void prim_splitVersion(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
string version = state.forceStringNoCtx(*args[0], pos);
auto iter = version.cbegin();
Strings components;
while (iter != version.cend()) {
auto component = nextComponent(iter, version.cend());
if (component.empty())
break;
components.emplace_back(std::move(component));
}
state.mkList(v, components.size());
unsigned int n = 0;
for (auto & component : components) {
auto listElem = v.listElems()[n++] = state.allocValue();
mkString(*listElem, std::move(component));
}
}
/************************************************************* /*************************************************************
* Networking * Networking
*************************************************************/ *************************************************************/
@ -2196,6 +2216,7 @@ void EvalState::createBaseEnv()
// Versions // Versions
addPrimOp("__parseDrvName", 1, prim_parseDrvName); addPrimOp("__parseDrvName", 1, prim_parseDrvName);
addPrimOp("__compareVersions", 2, prim_compareVersions); addPrimOp("__compareVersions", 2, prim_compareVersions);
addPrimOp("__splitVersion", 1, prim_splitVersion);
// Derivations // Derivations
addPrimOp("derivationStrict", 1, prim_derivationStrict); addPrimOp("derivationStrict", 1, prim_derivationStrict);

View file

@ -0,0 +1 @@
[ "1" "2" "3" ]

View file

@ -0,0 +1 @@
builtins.splitVersion "1.2.3"