* Version numbers can be omitted in install/uninstall. E.g.,
nix-env -i foo.nix subversion The version number part of a derivation name is defined as everything following the first dash not followed by a letter.
This commit is contained in:
parent
a81b621202
commit
f3c9783846
|
@ -4,8 +4,9 @@ nix-env [OPTIONS...] [ARGUMENTS...]
|
||||||
|
|
||||||
Operations:
|
Operations:
|
||||||
|
|
||||||
--install / -i FILE: add a derivation to the user environment
|
--install / -i FILE: add derivations to the user environment
|
||||||
--uninstall / -e: remove a derivation to the user environment
|
--uninstall / -e: remove derivations from the user environment
|
||||||
|
--upgrade / -u FILE: upgrade derivation in the user environment
|
||||||
--query / -q: perform a query on an environment or Nix expression
|
--query / -q: perform a query on an environment or Nix expression
|
||||||
|
|
||||||
The previous operations take a list of derivation names. The special
|
The previous operations take a list of derivation names. The special
|
||||||
|
|
|
@ -230,20 +230,71 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef map<string, Path> NameMap;
|
class DrvName
|
||||||
|
|
||||||
|
|
||||||
NameMap mapByNames(DrvInfos & drvs)
|
|
||||||
{
|
{
|
||||||
NameMap nameMap;
|
string fullName;
|
||||||
for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i)
|
string name;
|
||||||
nameMap[i->second.name] = i->first;
|
string version;
|
||||||
return nameMap;
|
unsigned int hits;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* Parse a derivation name. The `name' part of a derivation name
|
||||||
|
is everything up to but not including the first dash *not*
|
||||||
|
followed by a letter. The `version' part is the rest
|
||||||
|
(excluding the separating dash). E.g., `apache-httpd-2.0.48'
|
||||||
|
is parsed to (`apache-httpd', '2.0.48'). */
|
||||||
|
DrvName(const string & s) : hits(0)
|
||||||
|
{
|
||||||
|
name = fullName = s;
|
||||||
|
for (unsigned int i = 0; i < s.size(); ++i) {
|
||||||
|
if (s[i] == '-' && i + 1 < s.size() && !isalpha(s[i + 1])) {
|
||||||
|
name = string(s, 0, i);
|
||||||
|
version = string(s, i + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(DrvName & n)
|
||||||
|
{
|
||||||
|
if (name != "*" && name != n.name) return false;
|
||||||
|
if (version != "" && version != n.version) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hit()
|
||||||
|
{
|
||||||
|
hits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getHits()
|
||||||
|
{
|
||||||
|
return hits;
|
||||||
|
}
|
||||||
|
|
||||||
|
string getFullName()
|
||||||
|
{
|
||||||
|
return fullName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef list<DrvName> DrvNames;
|
||||||
|
|
||||||
|
|
||||||
|
static DrvNames drvNamesFromArgs(const Strings & opArgs)
|
||||||
|
{
|
||||||
|
DrvNames result;
|
||||||
|
for (Strings::const_iterator i = opArgs.begin();
|
||||||
|
i != opArgs.end(); ++i)
|
||||||
|
result.push_back(DrvName(*i));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void installDerivations(EvalState & state,
|
void installDerivations(EvalState & state,
|
||||||
Path nePath, Strings drvNames, const Path & linkPath)
|
Path nePath, DrvNames & selectors, const Path & linkPath)
|
||||||
{
|
{
|
||||||
debug(format("installing derivations from `%1%'") % nePath);
|
debug(format("installing derivations from `%1%'") % nePath);
|
||||||
|
|
||||||
|
@ -251,24 +302,29 @@ void installDerivations(EvalState & state,
|
||||||
DrvInfos availDrvs;
|
DrvInfos availDrvs;
|
||||||
loadDerivations(state, nePath, availDrvs);
|
loadDerivations(state, nePath, availDrvs);
|
||||||
|
|
||||||
NameMap nameMap = mapByNames(availDrvs);
|
|
||||||
|
|
||||||
/* Filter out the ones we're not interested in. */
|
/* Filter out the ones we're not interested in. */
|
||||||
DrvInfos selectedDrvs;
|
DrvInfos selectedDrvs;
|
||||||
if (drvNames.size() > 0 && drvNames.front() == "*") { /* !!! hack */
|
for (DrvInfos::iterator i = availDrvs.begin();
|
||||||
selectedDrvs = availDrvs;
|
i != availDrvs.end(); ++i)
|
||||||
} else {
|
{
|
||||||
for (Strings::iterator i = drvNames.begin();
|
DrvName drvName(i->second.name);
|
||||||
i != drvNames.end(); ++i)
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
|
j != selectors.end(); ++j)
|
||||||
{
|
{
|
||||||
NameMap::iterator j = nameMap.find(*i);
|
if (j->matches(drvName)) {
|
||||||
if (j == nameMap.end())
|
j->hit();
|
||||||
throw Error(format("unknown derivation `%1%'") % *i);
|
selectedDrvs.insert(*i);
|
||||||
else
|
}
|
||||||
selectedDrvs[j->second] = availDrvs[j->second];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check that all selectors have been used. */
|
||||||
|
for (DrvNames::iterator i = selectors.begin();
|
||||||
|
i != selectors.end(); ++i)
|
||||||
|
if (i->getHits() == 0)
|
||||||
|
throw Error(format("selector `%1%' matches no derivations")
|
||||||
|
% i->getFullName());
|
||||||
|
|
||||||
/* Add in the already installed derivations. */
|
/* Add in the already installed derivations. */
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, linkPath);
|
queryInstalled(state, installedDrvs, linkPath);
|
||||||
|
@ -286,29 +342,40 @@ static void opInstall(Globals & globals,
|
||||||
if (opArgs.size() < 1) throw UsageError("Nix file expected");
|
if (opArgs.size() < 1) throw UsageError("Nix file expected");
|
||||||
|
|
||||||
Path nePath = opArgs.front();
|
Path nePath = opArgs.front();
|
||||||
opArgs.pop_front();
|
DrvNames drvNames = drvNamesFromArgs(
|
||||||
|
Strings(++opArgs.begin(), opArgs.end()));
|
||||||
|
|
||||||
installDerivations(globals.state, nePath,
|
installDerivations(globals.state, nePath, drvNames, globals.linkPath);
|
||||||
Strings(opArgs.begin(), opArgs.end()), globals.linkPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uninstallDerivations(EvalState & state, Strings drvNames,
|
static void opUpgrade(Globals & globals,
|
||||||
|
Strings opFlags, Strings opArgs)
|
||||||
|
{
|
||||||
|
if (opFlags.size() > 0)
|
||||||
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
||||||
|
if (opArgs.size() < 1) throw UsageError("Nix file expected");
|
||||||
|
|
||||||
|
Path nePath = opArgs.front();
|
||||||
|
opArgs.pop_front();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uninstallDerivations(EvalState & state, DrvNames & selectors,
|
||||||
Path & linkPath)
|
Path & linkPath)
|
||||||
{
|
{
|
||||||
DrvInfos installedDrvs;
|
DrvInfos installedDrvs;
|
||||||
queryInstalled(state, installedDrvs, linkPath);
|
queryInstalled(state, installedDrvs, linkPath);
|
||||||
|
|
||||||
NameMap nameMap = mapByNames(installedDrvs);
|
for (DrvInfos::iterator i = installedDrvs.begin();
|
||||||
|
i != installedDrvs.end(); ++i)
|
||||||
for (Strings::iterator i = drvNames.begin();
|
|
||||||
i != drvNames.end(); ++i)
|
|
||||||
{
|
{
|
||||||
NameMap::iterator j = nameMap.find(*i);
|
DrvName drvName(i->second.name);
|
||||||
if (j == nameMap.end())
|
for (DrvNames::iterator j = selectors.begin();
|
||||||
throw Error(format("unknown derivation `%1%'") % *i);
|
j != selectors.end(); ++j)
|
||||||
else
|
if (j->matches(drvName))
|
||||||
installedDrvs.erase(j->second);
|
installedDrvs.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
createUserEnv(state, installedDrvs, linkPath);
|
createUserEnv(state, installedDrvs, linkPath);
|
||||||
|
@ -321,7 +388,9 @@ static void opUninstall(Globals & globals,
|
||||||
if (opFlags.size() > 0)
|
if (opFlags.size() > 0)
|
||||||
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
throw UsageError(format("unknown flags `%1%'") % opFlags.front());
|
||||||
|
|
||||||
uninstallDerivations(globals.state, opArgs, globals.linkPath);
|
DrvNames drvNames = drvNamesFromArgs(opArgs);
|
||||||
|
|
||||||
|
uninstallDerivations(globals.state, drvNames, globals.linkPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -412,6 +481,8 @@ void run(Strings args)
|
||||||
op = opInstall;
|
op = opInstall;
|
||||||
else if (arg == "--uninstall" || arg == "-e")
|
else if (arg == "--uninstall" || arg == "-e")
|
||||||
op = opUninstall;
|
op = opUninstall;
|
||||||
|
else if (arg == "--upgrade" || arg == "-u")
|
||||||
|
op = opUpgrade;
|
||||||
else if (arg == "--query" || arg == "-q")
|
else if (arg == "--query" || arg == "-q")
|
||||||
op = opQuery;
|
op = opQuery;
|
||||||
else if (arg == "--link" || arg == "-l") {
|
else if (arg == "--link" || arg == "-l") {
|
||||||
|
|
Loading…
Reference in a new issue