* Refactoring. Hope this doesn't break the semantics of `-u' ;-)
This commit is contained in:
		
							parent
							
								
									a04a5de8f7
								
							
						
					
					
						commit
						0cb016c209
					
				
					 3 changed files with 170 additions and 162 deletions
				
			
		| 
						 | 
					@ -45,7 +45,7 @@ typedef void (* Operation) (Globals & globals,
 | 
				
			||||||
    Strings opFlags, Strings opArgs);
 | 
					    Strings opFlags, Strings opArgs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct DrvInfo
 | 
					struct UserEnvElem
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    string name;
 | 
					    string name;
 | 
				
			||||||
    string system;
 | 
					    string system;
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,7 @@ struct DrvInfo
 | 
				
			||||||
    Path outPath;
 | 
					    Path outPath;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef map<Path, DrvInfo> DrvInfos;
 | 
					typedef map<Path, UserEnvElem> UserEnvElems;
 | 
				
			||||||
typedef vector<DrvInfo> DrvInfoList;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void printHelp()
 | 
					void printHelp()
 | 
				
			||||||
| 
						 | 
					@ -63,7 +62,7 @@ void printHelp()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
 | 
					static bool parseDerivation(EvalState & state, Expr e, UserEnvElem & elem)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ATermList es;
 | 
					    ATermList es;
 | 
				
			||||||
    e = evalExpr(state, e);
 | 
					    e = evalExpr(state, e);
 | 
				
			||||||
| 
						 | 
					@ -73,54 +72,54 @@ bool parseDerivation(EvalState & state, Expr e, DrvInfo & drv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a = queryAttr(e, "name");
 | 
					    a = queryAttr(e, "name");
 | 
				
			||||||
    if (!a) throw badTerm("derivation name missing", e);
 | 
					    if (!a) throw badTerm("derivation name missing", e);
 | 
				
			||||||
    drv.name = evalString(state, a);
 | 
					    elem.name = evalString(state, a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a = queryAttr(e, "system");
 | 
					    a = queryAttr(e, "system");
 | 
				
			||||||
    if (!a)
 | 
					    if (!a)
 | 
				
			||||||
        drv.system = "unknown";
 | 
					        elem.system = "unknown";
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        drv.system = evalString(state, a);
 | 
					        elem.system = evalString(state, a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a = queryAttr(e, "drvPath");
 | 
					    a = queryAttr(e, "drvPath");
 | 
				
			||||||
    if (a) drv.drvPath = evalPath(state, a);
 | 
					    if (a) elem.drvPath = evalPath(state, a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a = queryAttr(e, "outPath");
 | 
					    a = queryAttr(e, "outPath");
 | 
				
			||||||
    if (!a) throw badTerm("output path missing", e);
 | 
					    if (!a) throw badTerm("output path missing", e);
 | 
				
			||||||
    drv.outPath = evalPath(state, a);
 | 
					    elem.outPath = evalPath(state, a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
 | 
					static bool parseDerivations(EvalState & state, Expr e, UserEnvElems & elems)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ATermList es;
 | 
					    ATermList es;
 | 
				
			||||||
    DrvInfo drv;
 | 
					    UserEnvElem elem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    e = evalExpr(state, e);
 | 
					    e = evalExpr(state, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (parseDerivation(state, e, drv)) 
 | 
					    if (parseDerivation(state, e, elem)) 
 | 
				
			||||||
        drvs[drv.outPath] = drv;
 | 
					        elems[elem.outPath] = elem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if (matchAttrs(e, es)) {
 | 
					    else if (matchAttrs(e, es)) {
 | 
				
			||||||
        ATermMap drvMap;
 | 
					        ATermMap drvMap;
 | 
				
			||||||
        queryAllAttrs(e, drvMap);
 | 
					        queryAllAttrs(e, drvMap);
 | 
				
			||||||
        for (ATermIterator i(drvMap.keys()); i; ++i) {
 | 
					        for (ATermIterator i(drvMap.keys()); i; ++i) {
 | 
				
			||||||
            debug(format("evaluating attribute `%1%'") % *i);
 | 
					            debug(format("evaluating attribute `%1%'") % *i);
 | 
				
			||||||
            if (parseDerivation(state, drvMap.get(*i), drv))
 | 
					            if (parseDerivation(state, drvMap.get(*i), elem))
 | 
				
			||||||
                drvs[drv.outPath] = drv;
 | 
					                elems[elem.outPath] = elem;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                parseDerivations(state, drvMap.get(*i), drvs);
 | 
					                parseDerivations(state, drvMap.get(*i), elems);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else if (matchList(e, es)) {
 | 
					    else if (matchList(e, es)) {
 | 
				
			||||||
        for (ATermIterator i(es); i; ++i) {
 | 
					        for (ATermIterator i(es); i; ++i) {
 | 
				
			||||||
            debug(format("evaluating list element"));
 | 
					            debug(format("evaluating list element"));
 | 
				
			||||||
            if (parseDerivation(state, *i, drv))
 | 
					            if (parseDerivation(state, *i, elem))
 | 
				
			||||||
                drvs[drv.outPath] = drv;
 | 
					                elems[elem.outPath] = elem;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                parseDerivations(state, *i, drvs);
 | 
					                parseDerivations(state, *i, elems);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,30 +128,18 @@ bool parseDerivations(EvalState & state, Expr e, DrvInfos & drvs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void loadDerivations(EvalState & state, Path nixExprPath,
 | 
					static void loadDerivations(EvalState & state, Path nixExprPath,
 | 
				
			||||||
    string systemFilter, DrvInfos & drvs)
 | 
					    string systemFilter, UserEnvElems & elems)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Expr e = parseExprFromFile(state, absPath(nixExprPath));
 | 
					    Expr e = parseExprFromFile(state, absPath(nixExprPath));
 | 
				
			||||||
    if (!parseDerivations(state, e, drvs))
 | 
					    if (!parseDerivations(state, e, elems))
 | 
				
			||||||
        throw Error("set of derivations expected");
 | 
					        throw Error("set of derivations expected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Filter out all derivations not applicable to the current
 | 
					    /* Filter out all derivations not applicable to the current
 | 
				
			||||||
       system. */
 | 
					       system. */
 | 
				
			||||||
    for (DrvInfos::iterator i = drvs.begin(), j; i != drvs.end(); i = j) {
 | 
					    for (UserEnvElems::iterator i = elems.begin(), j; i != elems.end(); i = j) {
 | 
				
			||||||
        j = i; j++;
 | 
					        j = i; j++;
 | 
				
			||||||
        if (systemFilter != "*" && i->second.system != systemFilter)
 | 
					        if (systemFilter != "*" && i->second.system != systemFilter)
 | 
				
			||||||
            drvs.erase(i);
 | 
					            elems.erase(i);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void queryInstSources(EvalState & state,
 | 
					 | 
				
			||||||
    const InstallSourceInfo & instSource, DrvInfos & drvs)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    switch (instSource.type) {
 | 
					 | 
				
			||||||
        case srcUnknown:
 | 
					 | 
				
			||||||
            loadDerivations(state, instSource.nixExprPath,
 | 
					 | 
				
			||||||
                instSource.systemFilter, drvs);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -184,7 +171,7 @@ struct AddPos : TermFun
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void queryInstalled(EvalState & state, DrvInfos & drvs,
 | 
					static void queryInstalled(EvalState & state, UserEnvElems & elems,
 | 
				
			||||||
    const Path & userEnv)
 | 
					    const Path & userEnv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Path path = userEnv + "/manifest";
 | 
					    Path path = userEnv + "/manifest";
 | 
				
			||||||
| 
						 | 
					@ -198,19 +185,19 @@ void queryInstalled(EvalState & state, DrvInfos & drvs,
 | 
				
			||||||
    AddPos addPos;
 | 
					    AddPos addPos;
 | 
				
			||||||
    e = bottomupRewrite(addPos, e);
 | 
					    e = bottomupRewrite(addPos, e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!parseDerivations(state, e, drvs))
 | 
					    if (!parseDerivations(state, e, elems))
 | 
				
			||||||
        throw badTerm(format("set of derivations expected in `%1%'") % path, e);
 | 
					        throw badTerm(format("set of derivations expected in `%1%'") % path, e);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void createUserEnv(EvalState & state, const DrvInfos & drvs,
 | 
					static void createUserEnv(EvalState & state, const UserEnvElems & elems,
 | 
				
			||||||
    const Path & profile, bool keepDerivations)
 | 
					    const Path & profile, bool keepDerivations)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* Build the components in the user environment, if they don't
 | 
					    /* Build the components in the user environment, if they don't
 | 
				
			||||||
       exist already. */
 | 
					       exist already. */
 | 
				
			||||||
    PathSet drvsToBuild;
 | 
					    PathSet drvsToBuild;
 | 
				
			||||||
    for (DrvInfos::const_iterator i = drvs.begin(); 
 | 
					    for (UserEnvElems::const_iterator i = elems.begin(); 
 | 
				
			||||||
         i != drvs.end(); ++i)
 | 
					         i != elems.end(); ++i)
 | 
				
			||||||
        if (i->second.drvPath != "")
 | 
					        if (i->second.drvPath != "")
 | 
				
			||||||
            drvsToBuild.insert(i->second.drvPath);
 | 
					            drvsToBuild.insert(i->second.drvPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,8 +212,8 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
 | 
				
			||||||
    PathSet references;
 | 
					    PathSet references;
 | 
				
			||||||
    ATermList manifest = ATempty;
 | 
					    ATermList manifest = ATempty;
 | 
				
			||||||
    ATermList inputs = ATempty;
 | 
					    ATermList inputs = ATempty;
 | 
				
			||||||
    for (DrvInfos::const_iterator i = drvs.begin(); 
 | 
					    for (UserEnvElems::const_iterator i = elems.begin(); 
 | 
				
			||||||
         i != drvs.end(); ++i)
 | 
					         i != elems.end(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Path drvPath = keepDerivations ? i->second.drvPath : "";
 | 
					        Path drvPath = keepDerivations ? i->second.drvPath : "";
 | 
				
			||||||
        ATerm t = makeAttrs(ATmakeList5(
 | 
					        ATerm t = makeAttrs(ATmakeList5(
 | 
				
			||||||
| 
						 | 
					@ -268,7 +255,7 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Instantiate it. */
 | 
					    /* Instantiate it. */
 | 
				
			||||||
    debug(format("evaluating builder expression `%1%'") % topLevel);
 | 
					    debug(format("evaluating builder expression `%1%'") % topLevel);
 | 
				
			||||||
    DrvInfo topLevelDrv;
 | 
					    UserEnvElem topLevelDrv;
 | 
				
			||||||
    if (!parseDerivation(state, topLevel, topLevelDrv))
 | 
					    if (!parseDerivation(state, topLevel, topLevelDrv))
 | 
				
			||||||
        abort();
 | 
					        abort();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -278,37 +265,42 @@ void createUserEnv(EvalState & state, const DrvInfos & drvs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Switch the current user environment to the output path. */
 | 
					    /* Switch the current user environment to the output path. */
 | 
				
			||||||
    debug(format("switching to new user environment"));
 | 
					    debug(format("switching to new user environment"));
 | 
				
			||||||
    Path generation = createGeneration(profile,
 | 
					    Path generation = createGeneration(profile, topLevelDrv.outPath);
 | 
				
			||||||
        topLevelDrv.outPath, topLevelDrv.drvPath);
 | 
					 | 
				
			||||||
    switchLink(profile, generation);
 | 
					    switchLink(profile, generation);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void installDerivations(Globals & globals,
 | 
					static void queryInstSources(EvalState & state,
 | 
				
			||||||
    DrvNames & selectors, const Path & profile)
 | 
					    const InstallSourceInfo & instSource, const Strings & args,
 | 
				
			||||||
 | 
					    UserEnvElems & elems)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    debug(format("installing derivations"));
 | 
					    switch (instSource.type) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Fetch all derivations from the input file. */
 | 
					        /* Get the available user environment elements from the
 | 
				
			||||||
    DrvInfos availDrvs;
 | 
					           derivations specified in a Nix expression, including only
 | 
				
			||||||
    queryInstSources(globals.state, globals.instSource, availDrvs);
 | 
					           those with names matching any of the names in `args'. */
 | 
				
			||||||
 | 
					        case srcUnknown:
 | 
				
			||||||
 | 
					        case srcNixExprDrvs: {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DrvNames selectors = drvNamesFromArgs(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Load the derivations from the (default or specified)
 | 
				
			||||||
 | 
					               Nix expression. */
 | 
				
			||||||
 | 
					            UserEnvElems allElems;
 | 
				
			||||||
 | 
					            loadDerivations(state, instSource.nixExprPath,
 | 
				
			||||||
 | 
					                instSource.systemFilter, allElems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Filter out the ones we're not interested in. */
 | 
					            /* Filter out the ones we're not interested in. */
 | 
				
			||||||
    DrvInfos selectedDrvs;
 | 
					            for (UserEnvElems::iterator i = allElems.begin();
 | 
				
			||||||
    StringSet selectedNames;
 | 
					                 i != allElems.end(); ++i)
 | 
				
			||||||
    for (DrvInfos::iterator i = availDrvs.begin();
 | 
					 | 
				
			||||||
         i != availDrvs.end(); ++i)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                DrvName drvName(i->second.name);
 | 
					                DrvName drvName(i->second.name);
 | 
				
			||||||
                for (DrvNames::iterator j = selectors.begin();
 | 
					                for (DrvNames::iterator j = selectors.begin();
 | 
				
			||||||
                     j != selectors.end(); ++j)
 | 
					                     j != selectors.end(); ++j)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (j->matches(drvName)) {
 | 
					                    if (j->matches(drvName)) {
 | 
				
			||||||
                printMsg(lvlInfo,
 | 
					 | 
				
			||||||
                    format("installing `%1%'") % i->second.name);
 | 
					 | 
				
			||||||
                        j->hits++;
 | 
					                        j->hits++;
 | 
				
			||||||
                selectedDrvs.insert(*i);
 | 
					                        elems.insert(*i);
 | 
				
			||||||
                selectedNames.insert(drvName.name);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -320,25 +312,57 @@ static void installDerivations(Globals & globals,
 | 
				
			||||||
                    throw Error(format("selector `%1%' matches no derivations")
 | 
					                    throw Error(format("selector `%1%' matches no derivations")
 | 
				
			||||||
                        % i->fullName);
 | 
					                        % i->fullName);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* Add in the already installed derivations. */
 | 
					            break;
 | 
				
			||||||
    DrvInfos installedDrvs;
 | 
					        }
 | 
				
			||||||
    queryInstalled(globals.state, installedDrvs, profile);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (DrvInfos::iterator i = installedDrvs.begin();
 | 
					        case srcNixExprs:
 | 
				
			||||||
         i != installedDrvs.end(); ++i)
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case srcStorePaths:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case srcProfile:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void installDerivations(Globals & globals,
 | 
				
			||||||
 | 
					    const Strings & args, const Path & profile)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    debug(format("installing derivations"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Get the set of user environment elements to be installed. */
 | 
				
			||||||
 | 
					    UserEnvElems newElems;
 | 
				
			||||||
 | 
					    queryInstSources(globals.state, globals.instSource, args, newElems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    StringSet newNames;
 | 
				
			||||||
 | 
					    for (UserEnvElems::iterator i = newElems.begin(); i != newElems.end(); ++i) {
 | 
				
			||||||
 | 
					        printMsg(lvlInfo,
 | 
				
			||||||
 | 
					            format("installing `%1%'") % i->second.name);
 | 
				
			||||||
 | 
					        newNames.insert(DrvName(i->second.name).name);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Add in the already installed derivations, unless they have the
 | 
				
			||||||
 | 
					       same name as a to-be-installed element. */
 | 
				
			||||||
 | 
					    UserEnvElems installedElems;
 | 
				
			||||||
 | 
					    queryInstalled(globals.state, installedElems, profile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (UserEnvElems::iterator i = installedElems.begin();
 | 
				
			||||||
 | 
					         i != installedElems.end(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        DrvName drvName(i->second.name);
 | 
					        DrvName drvName(i->second.name);
 | 
				
			||||||
        if (!globals.preserveInstalled &&
 | 
					        if (!globals.preserveInstalled &&
 | 
				
			||||||
            selectedNames.find(drvName.name) != selectedNames.end())
 | 
					            newNames.find(drvName.name) != newNames.end())
 | 
				
			||||||
            printMsg(lvlInfo,
 | 
					            printMsg(lvlInfo,
 | 
				
			||||||
                format("uninstalling `%1%'") % i->second.name);
 | 
					                format("uninstalling `%1%'") % i->second.name);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            selectedDrvs.insert(*i);
 | 
					            newElems.insert(*i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (globals.dryRun) return;
 | 
					    if (globals.dryRun) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    createUserEnv(globals.state, selectedDrvs,
 | 
					    createUserEnv(globals.state, newElems,
 | 
				
			||||||
        profile, globals.keepDerivations);
 | 
					        profile, globals.keepDerivations);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -349,9 +373,7 @@ static void opInstall(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());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DrvNames drvNames = drvNamesFromArgs(opArgs);
 | 
					    installDerivations(globals, opArgs, globals.profile);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    installDerivations(globals, drvNames, globals.profile);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,7 +381,7 @@ typedef enum { utLt, utLeq, utAlways } UpgradeType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void upgradeDerivations(Globals & globals,
 | 
					static void upgradeDerivations(Globals & globals,
 | 
				
			||||||
    DrvNames & selectors, const Path & profile,
 | 
					    const Strings & args, const Path & profile,
 | 
				
			||||||
    UpgradeType upgradeType)
 | 
					    UpgradeType upgradeType)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    debug(format("upgrading derivations"));
 | 
					    debug(format("upgrading derivations"));
 | 
				
			||||||
| 
						 | 
					@ -370,47 +392,28 @@ static void upgradeDerivations(Globals & globals,
 | 
				
			||||||
       name and a higher version number. */
 | 
					       name and a higher version number. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Load the currently installed derivations. */
 | 
					    /* Load the currently installed derivations. */
 | 
				
			||||||
    DrvInfos installedDrvs;
 | 
					    UserEnvElems installedElems;
 | 
				
			||||||
    queryInstalled(globals.state, installedDrvs, profile);
 | 
					    queryInstalled(globals.state, installedElems, profile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Fetch all derivations from the input file. */
 | 
					    /* Fetch all derivations from the input file. */
 | 
				
			||||||
    DrvInfos availDrvs;
 | 
					    UserEnvElems availElems;
 | 
				
			||||||
    queryInstSources(globals.state, globals.instSource, availDrvs);
 | 
					    queryInstSources(globals.state, globals.instSource, args, availElems);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Go through all installed derivations. */
 | 
					    /* Go through all installed derivations. */
 | 
				
			||||||
    DrvInfos newDrvs;
 | 
					    UserEnvElems newElems;
 | 
				
			||||||
    for (DrvInfos::iterator i = installedDrvs.begin();
 | 
					    for (UserEnvElems::iterator i = installedElems.begin();
 | 
				
			||||||
         i != installedDrvs.end(); ++i)
 | 
					         i != installedElems.end(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        DrvName drvName(i->second.name);
 | 
					        DrvName drvName(i->second.name);
 | 
				
			||||||
        DrvName selector;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Do we want to upgrade this derivation? */
 | 
					        /* Find the derivation in the input Nix expression with the
 | 
				
			||||||
        bool upgrade = false;
 | 
					           same name and satisfying the version constraints specified
 | 
				
			||||||
        for (DrvNames::iterator j = selectors.begin();
 | 
					           by upgradeType.  If there are multiple matches, take the
 | 
				
			||||||
             j != selectors.end(); ++j)
 | 
					           one with highest version. */
 | 
				
			||||||
        {
 | 
					        UserEnvElems::iterator bestElem = availElems.end();
 | 
				
			||||||
            if (j->name == "*" || j->name == drvName.name) {
 | 
					 | 
				
			||||||
                j->hits++;
 | 
					 | 
				
			||||||
                selector = *j;
 | 
					 | 
				
			||||||
                upgrade = true;
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!upgrade) {
 | 
					 | 
				
			||||||
            newDrvs.insert(*i);
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
        /* If yes, find the derivation in the input Nix expression
 | 
					 | 
				
			||||||
           with the same name and satisfying the version constraints
 | 
					 | 
				
			||||||
           specified by upgradeType.  If there are multiple matches,
 | 
					 | 
				
			||||||
           take the one with highest version. */
 | 
					 | 
				
			||||||
        DrvInfos::iterator bestDrv = availDrvs.end();
 | 
					 | 
				
			||||||
        DrvName bestName;
 | 
					        DrvName bestName;
 | 
				
			||||||
        for (DrvInfos::iterator j = availDrvs.begin();
 | 
					        for (UserEnvElems::iterator j = availElems.begin();
 | 
				
			||||||
             j != availDrvs.end(); ++j)
 | 
					             j != availElems.end(); ++j)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            DrvName newName(j->second.name);
 | 
					            DrvName newName(j->second.name);
 | 
				
			||||||
            if (newName.name == drvName.name) {
 | 
					            if (newName.name == drvName.name) {
 | 
				
			||||||
| 
						 | 
					@ -419,31 +422,30 @@ static void upgradeDerivations(Globals & globals,
 | 
				
			||||||
                    upgradeType == utLeq && d <= 0 ||
 | 
					                    upgradeType == utLeq && d <= 0 ||
 | 
				
			||||||
                    upgradeType == utAlways)
 | 
					                    upgradeType == utAlways)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (selector.matches(newName) &&
 | 
					                    if ((bestElem == availElems.end() ||
 | 
				
			||||||
                        (bestDrv == availDrvs.end() ||
 | 
					 | 
				
			||||||
                         compareVersions(
 | 
					                         compareVersions(
 | 
				
			||||||
                             bestName.version, newName.version) < 0))
 | 
					                             bestName.version, newName.version) < 0))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        bestDrv = j;
 | 
					                        bestElem = j;
 | 
				
			||||||
                        bestName = newName;
 | 
					                        bestName = newName;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (bestDrv != availDrvs.end() &&
 | 
					        if (bestElem != availElems.end() &&
 | 
				
			||||||
            i->second.drvPath != bestDrv->second.drvPath)
 | 
					            i->second.outPath != bestElem->second.outPath)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            printMsg(lvlInfo,
 | 
					            printMsg(lvlInfo,
 | 
				
			||||||
                format("upgrading `%1%' to `%2%'")
 | 
					                format("upgrading `%1%' to `%2%'")
 | 
				
			||||||
                % i->second.name % bestDrv->second.name);
 | 
					                % i->second.name % bestElem->second.name);
 | 
				
			||||||
            newDrvs.insert(*bestDrv);
 | 
					            newElems.insert(*bestElem);
 | 
				
			||||||
        } else newDrvs.insert(*i);
 | 
					        } else newElems.insert(*i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (globals.dryRun) return;
 | 
					    if (globals.dryRun) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    createUserEnv(globals.state, newDrvs,
 | 
					    createUserEnv(globals.state, newElems,
 | 
				
			||||||
        profile, globals.keepDerivations);
 | 
					        profile, globals.keepDerivations);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -459,20 +461,18 @@ static void opUpgrade(Globals & globals,
 | 
				
			||||||
        else if (*i == "--always") upgradeType = utAlways;
 | 
					        else if (*i == "--always") upgradeType = utAlways;
 | 
				
			||||||
        else throw UsageError(format("unknown flag `%1%'") % *i);
 | 
					        else throw UsageError(format("unknown flag `%1%'") % *i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DrvNames drvNames = drvNamesFromArgs(opArgs);
 | 
					    upgradeDerivations(globals, opArgs, globals.profile, upgradeType);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    upgradeDerivations(globals, drvNames, globals.profile, upgradeType);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void uninstallDerivations(Globals & globals, DrvNames & selectors,
 | 
					static void uninstallDerivations(Globals & globals, DrvNames & selectors,
 | 
				
			||||||
    Path & profile)
 | 
					    Path & profile)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DrvInfos installedDrvs;
 | 
					    UserEnvElems installedElems;
 | 
				
			||||||
    queryInstalled(globals.state, installedDrvs, profile);
 | 
					    queryInstalled(globals.state, installedElems, profile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (DrvInfos::iterator i = installedDrvs.begin();
 | 
					    for (UserEnvElems::iterator i = installedElems.begin();
 | 
				
			||||||
         i != installedDrvs.end(); ++i)
 | 
					         i != installedElems.end(); ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        DrvName drvName(i->second.name);
 | 
					        DrvName drvName(i->second.name);
 | 
				
			||||||
        for (DrvNames::iterator j = selectors.begin();
 | 
					        for (DrvNames::iterator j = selectors.begin();
 | 
				
			||||||
| 
						 | 
					@ -480,13 +480,13 @@ static void uninstallDerivations(Globals & globals, DrvNames & selectors,
 | 
				
			||||||
            if (j->matches(drvName)) {
 | 
					            if (j->matches(drvName)) {
 | 
				
			||||||
                printMsg(lvlInfo,
 | 
					                printMsg(lvlInfo,
 | 
				
			||||||
                    format("uninstalling `%1%'") % i->second.name);
 | 
					                    format("uninstalling `%1%'") % i->second.name);
 | 
				
			||||||
                installedDrvs.erase(i);
 | 
					                installedElems.erase(i);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (globals.dryRun) return;
 | 
					    if (globals.dryRun) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    createUserEnv(globals.state, installedDrvs,
 | 
					    createUserEnv(globals.state, installedElems,
 | 
				
			||||||
        profile, globals.keepDerivations);
 | 
					        profile, globals.keepDerivations);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -510,7 +510,7 @@ static bool cmpChars(char a, char b)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool cmpDrvByName(const DrvInfo & a, const DrvInfo & b)
 | 
					static bool cmpElemByName(const UserEnvElem & a, const UserEnvElem & b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return lexicographical_compare(
 | 
					    return lexicographical_compare(
 | 
				
			||||||
        a.name.begin(), a.name.end(),
 | 
					        a.name.begin(), a.name.end(),
 | 
				
			||||||
| 
						 | 
					@ -575,17 +575,17 @@ static void opQuery(Globals & globals,
 | 
				
			||||||
        else throw UsageError(format("unknown flag `%1%'") % *i);
 | 
					        else throw UsageError(format("unknown flag `%1%'") % *i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Obtain derivation information from the specified source. */
 | 
					    /* Obtain derivation information from the specified source. */
 | 
				
			||||||
    DrvInfos drvs;
 | 
					    UserEnvElems elems;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (source) {
 | 
					    switch (source) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case sInstalled:
 | 
					        case sInstalled:
 | 
				
			||||||
            queryInstalled(globals.state, drvs, globals.profile);
 | 
					            queryInstalled(globals.state, elems, globals.profile);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        case sAvailable: {
 | 
					        case sAvailable: {
 | 
				
			||||||
            loadDerivations(globals.state, globals.instSource.nixExprPath,
 | 
					            loadDerivations(globals.state, globals.instSource.nixExprPath,
 | 
				
			||||||
                globals.instSource.systemFilter, drvs);
 | 
					                globals.instSource.systemFilter, elems);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -595,14 +595,14 @@ static void opQuery(Globals & globals,
 | 
				
			||||||
    if (opArgs.size() != 0) throw UsageError("no arguments expected");
 | 
					    if (opArgs.size() != 0) throw UsageError("no arguments expected");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Sort them by name. */
 | 
					    /* Sort them by name. */
 | 
				
			||||||
    DrvInfoList drvs2;
 | 
					    vector<UserEnvElem> elems2;
 | 
				
			||||||
    for (DrvInfos::iterator i = drvs.begin(); i != drvs.end(); ++i)
 | 
					    for (UserEnvElems::iterator i = elems.begin(); i != elems.end(); ++i)
 | 
				
			||||||
        drvs2.push_back(i->second);
 | 
					        elems2.push_back(i->second);
 | 
				
			||||||
    sort(drvs2.begin(), drvs2.end(), cmpDrvByName);
 | 
					    sort(elems2.begin(), elems2.end(), cmpElemByName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We only need to know the installed paths when we are querying
 | 
					    /* We only need to know the installed paths when we are querying
 | 
				
			||||||
       the status of the derivation. */
 | 
					       the status of the derivation. */
 | 
				
			||||||
    DrvInfos installed; /* installed paths */
 | 
					    UserEnvElems installed; /* installed paths */
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (printStatus)
 | 
					    if (printStatus)
 | 
				
			||||||
        queryInstalled(globals.state, installed, globals.profile);
 | 
					        queryInstalled(globals.state, installed, globals.profile);
 | 
				
			||||||
| 
						 | 
					@ -610,8 +610,9 @@ static void opQuery(Globals & globals,
 | 
				
			||||||
    /* Print the desired columns. */
 | 
					    /* Print the desired columns. */
 | 
				
			||||||
    Table table;
 | 
					    Table table;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for (DrvInfoList::iterator i = drvs2.begin(); i != drvs2.end(); ++i) {
 | 
					    for (vector<UserEnvElem>::iterator i = elems2.begin();
 | 
				
			||||||
 | 
					         i != elems2.end(); ++i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        Strings columns;
 | 
					        Strings columns;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (printStatus) {
 | 
					        if (printStatus) {
 | 
				
			||||||
| 
						 | 
					@ -794,6 +795,16 @@ static void opDefaultExpr(Globals & globals,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static string needArg(Strings::iterator & i,
 | 
				
			||||||
 | 
					    const Strings & args, const string & arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ++i;
 | 
				
			||||||
 | 
					    if (i == args.end()) throw UsageError(
 | 
				
			||||||
 | 
					        format("`%1%' requires an argument") % arg);
 | 
				
			||||||
 | 
					    return *i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run(Strings args)
 | 
					void run(Strings args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Strings opFlags, opArgs;
 | 
					    Strings opFlags, opArgs;
 | 
				
			||||||
| 
						 | 
					@ -818,6 +829,12 @@ void run(Strings args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (arg == "--install" || arg == "-i")
 | 
					        if (arg == "--install" || arg == "-i")
 | 
				
			||||||
            op = opInstall;
 | 
					            op = opInstall;
 | 
				
			||||||
 | 
					        else if (arg == "--from-expression" || arg == "-E")
 | 
				
			||||||
 | 
					            globals.instSource.type = srcNixExprs;
 | 
				
			||||||
 | 
					        else if (arg == "--from-profile") {
 | 
				
			||||||
 | 
					            globals.instSource.type = srcProfile;
 | 
				
			||||||
 | 
					            globals.instSource.profile = needArg(i, args, arg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else if (arg == "--uninstall" || arg == "-e")
 | 
					        else if (arg == "--uninstall" || arg == "-e")
 | 
				
			||||||
            op = opUninstall;
 | 
					            op = opUninstall;
 | 
				
			||||||
        else if (arg == "--upgrade" || arg == "-u")
 | 
					        else if (arg == "--upgrade" || arg == "-u")
 | 
				
			||||||
| 
						 | 
					@ -827,16 +844,10 @@ void run(Strings args)
 | 
				
			||||||
        else if (arg == "--import" || arg == "-I") /* !!! bad name */
 | 
					        else if (arg == "--import" || arg == "-I") /* !!! bad name */
 | 
				
			||||||
            op = opDefaultExpr;
 | 
					            op = opDefaultExpr;
 | 
				
			||||||
        else if (arg == "--profile" || arg == "-p") {
 | 
					        else if (arg == "--profile" || arg == "-p") {
 | 
				
			||||||
            ++i;
 | 
					            globals.profile = absPath(needArg(i, args, arg));
 | 
				
			||||||
            if (i == args.end()) throw UsageError(
 | 
					 | 
				
			||||||
                format("`%1%' requires an argument") % arg);
 | 
					 | 
				
			||||||
            globals.profile = absPath(*i);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (arg == "--file" || arg == "-f") {
 | 
					        else if (arg == "--file" || arg == "-f") {
 | 
				
			||||||
            ++i;
 | 
					            globals.instSource.nixExprPath = absPath(needArg(i, args, arg));
 | 
				
			||||||
            if (i == args.end()) throw UsageError(
 | 
					 | 
				
			||||||
                format("`%1%' requires an argument") % arg);
 | 
					 | 
				
			||||||
            globals.instSource.nixExprPath = absPath(*i);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (arg == "--switch-profile" || arg == "-S")
 | 
					        else if (arg == "--switch-profile" || arg == "-S")
 | 
				
			||||||
            op = opSwitchProfile;
 | 
					            op = opSwitchProfile;
 | 
				
			||||||
| 
						 | 
					@ -855,10 +866,7 @@ void run(Strings args)
 | 
				
			||||||
        else if (arg == "--preserve-installed" || arg == "-P")
 | 
					        else if (arg == "--preserve-installed" || arg == "-P")
 | 
				
			||||||
            globals.preserveInstalled = true;
 | 
					            globals.preserveInstalled = true;
 | 
				
			||||||
        else if (arg == "--system-filter") {
 | 
					        else if (arg == "--system-filter") {
 | 
				
			||||||
            ++i;
 | 
					            globals.instSource.systemFilter = needArg(i, args, arg);
 | 
				
			||||||
            if (i == args.end()) throw UsageError(
 | 
					 | 
				
			||||||
                format("`%1%' requires an argument") % arg);
 | 
					 | 
				
			||||||
            globals.instSource.systemFilter = *i;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (arg[0] == '-')
 | 
					        else if (arg[0] == '-')
 | 
				
			||||||
            opFlags.push_back(arg);
 | 
					            opFlags.push_back(arg);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ static void makeName(const Path & profile, unsigned int num,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Path createGeneration(Path profile, Path outPath, Path drvPath)
 | 
					Path createGeneration(Path profile, Path outPath)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* The new generation number should be higher than old the
 | 
					    /* The new generation number should be higher than old the
 | 
				
			||||||
       previous ones. */
 | 
					       previous ones. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ typedef list<Generation> Generations;
 | 
				
			||||||
   profile, sorted by generation number. */
 | 
					   profile, sorted by generation number. */
 | 
				
			||||||
Generations findGenerations(Path profile, int & curGen);
 | 
					Generations findGenerations(Path profile, int & curGen);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
Path createGeneration(Path profile, Path outPath, Path drvPath);
 | 
					Path createGeneration(Path profile, Path outPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void deleteGeneration(const Path & profile, unsigned int gen);
 | 
					void deleteGeneration(const Path & profile, unsigned int gen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue