Skip to content

Commit

Permalink
Add splitVersion primop.
Browse files Browse the repository at this point in the history
Fixes NixOS#1868.
  • Loading branch information
shlevy committed Feb 14, 2018
1 parent 3fe9767 commit b095c06
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 1 deletion.
11 changes: 11 additions & 0 deletions doc/manual/expressions/builtins.xml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
</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>
<replaceable>lists</replaceable></term>

Expand Down
2 changes: 1 addition & 1 deletion src/libexpr/names.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
/* Skip any dots and dashes (component separators). */
Expand Down
2 changes: 2 additions & 0 deletions src/libexpr/names.hh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ private:

typedef list<DrvName> DrvNames;

string nextComponent(string::const_iterator & p,
const string::const_iterator end);
int compareVersions(const string & v1, const string & v2);
DrvNames drvNamesFromArgs(const Strings & opArgs);

Expand Down
21 changes: 21 additions & 0 deletions src/libexpr/primops.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
*************************************************************/
Expand Down Expand Up @@ -2196,6 +2216,7 @@ void EvalState::createBaseEnv()
// Versions
addPrimOp("__parseDrvName", 1, prim_parseDrvName);
addPrimOp("__compareVersions", 2, prim_compareVersions);
addPrimOp("__splitVersion", 1, prim_splitVersion);

// Derivations
addPrimOp("derivationStrict", 1, prim_derivationStrict);
Expand Down
1 change: 1 addition & 0 deletions tests/lang/eval-okay-splitversion.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ "1" "2" "3" ]
1 change: 1 addition & 0 deletions tests/lang/eval-okay-splitversion.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
builtins.splitVersion "1.2.3"

0 comments on commit b095c06

Please sign in to comment.