* 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:
Eelco Dolstra 2003-12-21 23:58:56 +00:00
parent a81b621202
commit f3c9783846
2 changed files with 110 additions and 38 deletions

View file

@ -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

View file

@ -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") {