Merge remote-tracking branch 'origin/master' into flakes

This commit is contained in:
Eelco Dolstra 2019-10-10 12:54:37 +02:00
commit e99bb91217
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
43 changed files with 151 additions and 316 deletions

View file

@ -433,7 +433,7 @@ builtins.fetchurl {
<varlistentry xml:id="conf-keep-env-derivations"><term><literal>keep-env-derivations</literal></term> <varlistentry xml:id="conf-keep-env-derivations"><term><literal>keep-env-derivations</literal></term>
<listitem><para>If <literal>false</literal> (default), derivations <listitem><para>If <literal>false</literal> (default), derivations
are not stored in Nix user environments. That is, the derivation are not stored in Nix user environments. That is, the derivations of
any build-time-only dependencies may be garbage-collected.</para> any build-time-only dependencies may be garbage-collected.</para>
<para>If <literal>true</literal>, when you add a Nix derivation to <para>If <literal>true</literal>, when you add a Nix derivation to

View file

@ -659,7 +659,7 @@ upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
<literal>gcc-3.3.1</literal> are split into two parts: the package <literal>gcc-3.3.1</literal> are split into two parts: the package
name (<literal>gcc</literal>), and the version name (<literal>gcc</literal>), and the version
(<literal>3.3.1</literal>). The version part starts after the first (<literal>3.3.1</literal>). The version part starts after the first
dash not following by a letter. <varname>x</varname> is considered an dash not followed by a letter. <varname>x</varname> is considered an
upgrade of <varname>y</varname> if their package names match, and the upgrade of <varname>y</varname> if their package names match, and the
version of <varname>y</varname> is higher that that of version of <varname>y</varname> is higher that that of
<varname>x</varname>.</para> <varname>x</varname>.</para>

View file

@ -53,7 +53,7 @@ avoided.</para>
<para>If <replaceable>hash</replaceable> is specified, then a download <para>If <replaceable>hash</replaceable> is specified, then a download
is not performed if the Nix store already contains a file with the is not performed if the Nix store already contains a file with the
same hash and base name. Otherwise, the file is downloaded, and an same hash and base name. Otherwise, the file is downloaded, and an
error if signaled if the actual hash of the file does not match the error is signaled if the actual hash of the file does not match the
specified hash.</para> specified hash.</para>
<para>This command prints the hash on standard output. Additionally, <para>This command prints the hash on standard output. Additionally,

View file

@ -289,7 +289,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
<listitem><para>Return element <replaceable>n</replaceable> from <listitem><para>Return element <replaceable>n</replaceable> from
the list <replaceable>xs</replaceable>. Elements are counted the list <replaceable>xs</replaceable>. Elements are counted
starting from 0. A fatal error occurs in the index is out of starting from 0. A fatal error occurs if the index is out of
bounds.</para></listitem> bounds.</para></listitem>
</varlistentry> </varlistentry>
@ -1466,7 +1466,7 @@ in foo</programlisting>
<listitem><para>A set containing <literal>{ __toString = self: ...; }</literal>.</para></listitem> <listitem><para>A set containing <literal>{ __toString = self: ...; }</literal>.</para></listitem>
<listitem><para>An integer.</para></listitem> <listitem><para>An integer.</para></listitem>
<listitem><para>A list, in which case the string representations of its elements are joined with spaces.</para></listitem> <listitem><para>A list, in which case the string representations of its elements are joined with spaces.</para></listitem>
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>.</para></listitem> <listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>).</para></listitem>
<listitem><para><literal>null</literal>, which yields the empty string.</para></listitem> <listitem><para><literal>null</literal>, which yields the empty string.</para></listitem>
</itemizedlist> </itemizedlist>
</listitem> </listitem>

View file

@ -43,7 +43,7 @@ use <command>nix-build</command>s <option
linkend='opt-out-link'>-o</option> switch to give the symlink another linkend='opt-out-link'>-o</option> switch to give the symlink another
name.</para> name.</para>
<para>Nix has a transactional semantics. Once a build finishes <para>Nix has transactional semantics. Once a build finishes
successfully, Nix makes a note of this in its database: it registers successfully, Nix makes a note of this in its database: it registers
that the path denoted by <envar>out</envar> is now that the path denoted by <envar>out</envar> is now
<quote>valid</quote>. If you try to build the derivation again, Nix <quote>valid</quote>. If you try to build the derivation again, Nix

View file

@ -17,7 +17,7 @@
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>
<string>-c</string> <string>-c</string>
<string>/bin/wait4path @bindir@/nix-daemon &amp;&amp; @bindir@/nix-daemon</string> <string>/bin/wait4path /nix/var/nix/profiles/default/bin/nix-daemon &amp;&amp; /nix/var/nix/profiles/default/bin/nix-daemon</string>
</array> </array>
<key>StandardErrorPath</key> <key>StandardErrorPath</key>
<string>/var/log/nix-daemon.log</string> <string>/var/log/nix-daemon.log</string>

View file

@ -106,7 +106,7 @@ chmod 1775 $RPM_BUILD_ROOT/nix/store
for d in profiles gcroots; for d in profiles gcroots;
do do
mkdir -p $RPM_BUILD_ROOT/nix/var/nix/$d/per-user mkdir -p $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
chmod 1777 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user chmod 755 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
done done
# fix permission of nix profile # fix permission of nix profile

View file

@ -39,7 +39,7 @@ EOF
poly_configure_nix_daemon_service() { poly_configure_nix_daemon_service() {
_sudo "to set up the nix-daemon as a LaunchDaemon" \ _sudo "to set up the nix-daemon as a LaunchDaemon" \
ln -sfn "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST" cp -f "/nix/var/nix/profiles/default$PLIST_DEST" "$PLIST_DEST"
_sudo "to load the LaunchDaemon plist for nix-daemon" \ _sudo "to load the LaunchDaemon plist for nix-daemon" \
launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist

View file

@ -278,73 +278,9 @@ EOF
fi fi
if type nix-env 2> /dev/null >&2; then if type nix-env 2> /dev/null >&2; then
failure <<EOF warning <<EOF
Nix already appears to be installed, and this tool assumes it is Nix already appears to be installed. This installer may run into issues.
_not_ yet installed. If an error occurs, try manually uninstalling, then rerunning this script.
$(uninstall_directions)
EOF
fi
if [ "${NIX_REMOTE:-}" != "" ]; then
failure <<EOF
For some reason, \$NIX_REMOTE is set. It really should not be set
before this installer runs, and it hints that Nix is currently
installed. Please delete the old Nix installation and start again.
Note: You might need to close your shell window and open a new shell
to clear the variable.
EOF
fi
if echo "${SSL_CERT_FILE:-}" | grep -qE "(nix/var/nix|nix-profile)"; then
failure <<EOF
It looks like \$SSL_CERT_FILE is set to a path that used to be part of
the old Nix installation. Please unset that variable and try again:
$ unset SSL_CERT_FILE
EOF
fi
for file in ~/.bash_profile ~/.bash_login ~/.profile ~/.zshenv ~/.zprofile ~/.zshrc ~/.zlogin; do
if [ -f "$file" ]; then
if grep -l "^[^#].*.nix-profile" "$file"; then
failure <<EOF
I found a reference to a ".nix-profile" in $file.
This has a high chance of breaking a new nix installation. It was most
likely put there by a previous Nix installer.
Please remove this reference and try running this again. You should
also look for similar references in:
- ~/.bash_profile
- ~/.bash_login
- ~/.profile
or other shell init files that you may have.
$(uninstall_directions)
EOF
fi
fi
done
if [ -d /nix/store ] || [ -d /nix/var ]; then
failure <<EOF
There are some relics of a previous installation of Nix at /nix, and
this scripts assumes Nix is _not_ yet installed. Please delete the old
Nix installation and start again.
$(uninstall_directions)
EOF
fi
if [ -d /etc/nix ]; then
failure <<EOF
There are some relics of a previous installation of Nix at /etc/nix, and
this scripts assumes Nix is _not_ yet installed. Please delete the old
Nix installation and start again.
$(uninstall_directions) $(uninstall_directions)
EOF EOF
@ -364,38 +300,10 @@ in case.
2. Take care to make sure that $profile_target$PROFILE_BACKUP_SUFFIX doesn't look like 2. Take care to make sure that $profile_target$PROFILE_BACKUP_SUFFIX doesn't look like
it has anything nix-related in it. If it does, something is probably it has anything nix-related in it. If it does, something is probably
quite wrong. Please open an issue or get in touch immediately. quite wrong. Please open an issue or get in touch immediately.
3. Take care to make sure that $profile_target doesn't look like it has
anything nix-related in it. If it does, and $profile_target _did not_,
run:
$ /usr/bin/sudo /bin/mv $profile_target$PROFILE_BACKUP_SUFFIX $profile_target
and try again.
EOF
fi
if [ -e "$profile_target" ] && grep -qi "nix" "$profile_target"; then
failure <<EOF
It looks like $profile_target already has some Nix configuration in
there. There should be no reason to run this again. If you're having
trouble, please open an issue.
EOF EOF
fi fi
done done
danger_paths=("$ROOT_HOME/.nix-defexpr" "$ROOT_HOME/.nix-channels" "$ROOT_HOME/.nix-profile")
for danger_path in "${danger_paths[@]}"; do
if _sudo "making sure that $danger_path doesn't exist" \
test -e "$danger_path"; then
failure <<EOF
I found a file at $danger_path, which is a relic of a previous
installation. You must first delete this file before continuing.
$(uninstall_directions)
EOF
fi
done
} }
setup_report() { setup_report() {
@ -529,24 +437,17 @@ create_build_users() {
} }
create_directories() { create_directories() {
# FIXME: remove all of this because it duplicates LocalStore::LocalStore().
_sudo "to make the basic directory structure of Nix (part 1)" \ _sudo "to make the basic directory structure of Nix (part 1)" \
mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool} mkdir -pv -m 0755 /nix /nix/var /nix/var/log /nix/var/log/nix /nix/var/log/nix/drvs /nix/var/nix{,/db,/gcroots,/profiles,/temproots,/userpool} /nix/var/nix/{gcroots,profiles}/per-user
_sudo "to make the basic directory structure of Nix (part 2)" \ _sudo "to make the basic directory structure of Nix (part 2)" \
mkdir -pv -m 1777 /nix/var/nix/{gcroots,profiles}/per-user
_sudo "to make the basic directory structure of Nix (part 3)" \
mkdir -pv -m 1775 /nix/store mkdir -pv -m 1775 /nix/store
_sudo "to make the basic directory structure of Nix (part 4)" \ _sudo "to make the basic directory structure of Nix (part 3)" \
chgrp "$NIX_BUILD_GROUP_NAME" /nix/store chgrp "$NIX_BUILD_GROUP_NAME" /nix/store
_sudo "to set up the root user's profile (part 1)" \
mkdir -pv -m 0755 /nix/var/nix/profiles/per-user/root
_sudo "to set up the root user's profile (part 2)" \
mkdir -pv -m 0700 "$ROOT_HOME/.nix-defexpr"
_sudo "to place the default nix daemon configuration (part 1)" \ _sudo "to place the default nix daemon configuration (part 1)" \
mkdir -pv -m 0555 /etc/nix mkdir -pv -m 0555 /etc/nix
} }
@ -772,9 +673,7 @@ main() {
welcome_to_nix welcome_to_nix
chat_about_sudo chat_about_sudo
if [ "${ALLOW_PREEXISTING_INSTALLATION:-}" = "" ]; then
validate_starting_assumptions validate_starting_assumptions
fi
setup_report setup_report

View file

@ -5,45 +5,6 @@ __ETC_PROFILE_NIX_SOURCED=1
export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER" export NIX_USER_PROFILE_DIR="@localstatedir@/nix/profiles/per-user/$USER"
export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile" export NIX_PROFILES="@localstatedir@/nix/profiles/default $HOME/.nix-profile"
# Set up the per-user profile.
mkdir -m 0755 -p $NIX_USER_PROFILE_DIR
if ! test -O "$NIX_USER_PROFILE_DIR"; then
echo "WARNING: bad ownership on $NIX_USER_PROFILE_DIR" >&2
fi
if test -w $HOME; then
if ! test -L $HOME/.nix-profile; then
if test "$USER" != root; then
ln -s $NIX_USER_PROFILE_DIR/profile $HOME/.nix-profile
else
# Root installs in the system-wide profile by default.
ln -s @localstatedir@/nix/profiles/default $HOME/.nix-profile
fi
fi
# Subscribe the root user to the NixOS channel by default.
if [ "$USER" = root -a ! -e $HOME/.nix-channels ]; then
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels
fi
# Create the per-user garbage collector roots directory.
NIX_USER_GCROOTS_DIR=@localstatedir@/nix/gcroots/per-user/$USER
mkdir -m 0755 -p $NIX_USER_GCROOTS_DIR
if ! test -O "$NIX_USER_GCROOTS_DIR"; then
echo "WARNING: bad ownership on $NIX_USER_GCROOTS_DIR" >&2
fi
# Set up a default Nix expression from which to install stuff.
if [ ! -e $HOME/.nix-defexpr -o -L $HOME/.nix-defexpr ]; then
rm -f $HOME/.nix-defexpr
mkdir -p $HOME/.nix-defexpr
if [ "$USER" != root ]; then
ln -s @localstatedir@/nix/profiles/per-user/root/channels $HOME/.nix-defexpr/channels_root
fi
fi
fi
# Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work. # Set $NIX_SSL_CERT_FILE so that Nixpkgs applications like curl work.
if [ ! -z "${NIX_SSL_CERT_FILE:-}" ]; then if [ ! -z "${NIX_SSL_CERT_FILE:-}" ]; then
: # Allow users to override the NIX_SSL_CERT_FILE : # Allow users to override the NIX_SSL_CERT_FILE

View file

@ -1,6 +1,4 @@
if [ -n "$HOME" ] && [ -n "$USER" ]; then if [ -n "$HOME" ] && [ -n "$USER" ]; then
__savedpath="$PATH"
export PATH=@coreutils@
# Set up the per-user profile. # Set up the per-user profile.
# This part should be kept in sync with nixpkgs:nixos/modules/programs/shell.nix # This part should be kept in sync with nixpkgs:nixos/modules/programs/shell.nix
@ -9,48 +7,6 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER NIX_USER_PROFILE_DIR=@localstatedir@/nix/profiles/per-user/$USER
mkdir -m 0755 -p "$NIX_USER_PROFILE_DIR"
if [ "$(stat --printf '%u' "$NIX_USER_PROFILE_DIR")" != "$(id -u)" ]; then
echo "Nix: WARNING: bad ownership on "$NIX_USER_PROFILE_DIR", should be $(id -u)" >&2
fi
if [ -w "$HOME" ]; then
if ! [ -L "$NIX_LINK" ]; then
echo "Nix: creating $NIX_LINK" >&2
if [ "$USER" != root ]; then
if ! ln -s "$NIX_USER_PROFILE_DIR"/profile "$NIX_LINK"; then
echo "Nix: WARNING: could not create $NIX_LINK -> $NIX_USER_PROFILE_DIR/profile" >&2
fi
else
# Root installs in the system-wide profile by default.
ln -s @localstatedir@/nix/profiles/default "$NIX_LINK"
fi
fi
# Subscribe the user to the unstable Nixpkgs channel by default.
if [ ! -e "$HOME/.nix-channels" ]; then
echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > "$HOME/.nix-channels"
fi
# Create the per-user garbage collector roots directory.
__user_gcroots=@localstatedir@/nix/gcroots/per-user/"$USER"
mkdir -m 0755 -p "$__user_gcroots"
if [ "$(stat --printf '%u' "$__user_gcroots")" != "$(id -u)" ]; then
echo "Nix: WARNING: bad ownership on $__user_gcroots, should be $(id -u)" >&2
fi
unset __user_gcroots
# Set up a default Nix expression from which to install stuff.
__nix_defexpr="$HOME"/.nix-defexpr
[ -L "$__nix_defexpr" ] && rm -f "$__nix_defexpr"
mkdir -m 0755 -p "$__nix_defexpr"
if [ "$USER" != root ] && [ ! -L "$__nix_defexpr"/channels_root ]; then
ln -s @localstatedir@/nix/profiles/per-user/root/channels "$__nix_defexpr"/channels_root
fi
unset __nix_defexpr
fi
# Append ~/.nix-defexpr/channels to $NIX_PATH so that <nixpkgs> # Append ~/.nix-defexpr/channels to $NIX_PATH so that <nixpkgs>
# paths work when the user has fetched the Nixpkgs channel. # paths work when the user has fetched the Nixpkgs channel.
export NIX_PATH=${NIX_PATH:+$NIX_PATH:}$HOME/.nix-defexpr/channels export NIX_PATH=${NIX_PATH:+$NIX_PATH:}$HOME/.nix-defexpr/channels
@ -78,6 +34,6 @@ if [ -n "$HOME" ] && [ -n "$USER" ]; then
export MANPATH="$NIX_LINK/share/man:$MANPATH" export MANPATH="$NIX_LINK/share/man:$MANPATH"
fi fi
export PATH="$NIX_LINK/bin:$__savedpath" export PATH="$NIX_LINK/bin:$PATH"
unset __savedpath NIX_LINK NIX_USER_PROFILE_DIR unset NIX_LINK NIX_USER_PROFILE_DIR
fi fi

View file

@ -47,11 +47,10 @@ static void printValue(std::ostream & str, std::set<const Value *> & active, con
{ {
checkInterrupt(); checkInterrupt();
if (active.find(&v) != active.end()) { if (!active.insert(&v).second) {
str << "<CYCLE>"; str << "<CYCLE>";
return; return;
} }
active.insert(&v);
switch (v.type) { switch (v.type) {
case tInt: case tInt:
@ -1486,8 +1485,7 @@ void EvalState::forceValueDeep(Value & v)
std::function<void(Value & v)> recurse; std::function<void(Value & v)> recurse;
recurse = [&](Value & v) { recurse = [&](Value & v) {
if (seen.find(&v) != seen.end()) return; if (!seen.insert(&v).second) return;
seen.insert(&v);
forceValue(v); forceValue(v);
@ -1905,8 +1903,7 @@ size_t valueSize(Value & v)
std::set<const void *> seen; std::set<const void *> seen;
auto doString = [&](const char * s) -> size_t { auto doString = [&](const char * s) -> size_t {
if (seen.find(s) != seen.end()) return 0; if (!seen.insert(s).second) return 0;
seen.insert(s);
return strlen(s) + 1; return strlen(s) + 1;
}; };
@ -1914,8 +1911,7 @@ size_t valueSize(Value & v)
std::function<size_t(Env & v)> doEnv; std::function<size_t(Env & v)> doEnv;
doValue = [&](Value & v) -> size_t { doValue = [&](Value & v) -> size_t {
if (seen.find(&v) != seen.end()) return 0; if (!seen.insert(&v).second) return 0;
seen.insert(&v);
size_t sz = sizeof(Value); size_t sz = sizeof(Value);
@ -1930,8 +1926,7 @@ size_t valueSize(Value & v)
sz += doString(v.path); sz += doString(v.path);
break; break;
case tAttrs: case tAttrs:
if (seen.find(v.attrs) == seen.end()) { if (seen.insert(v.attrs).second) {
seen.insert(v.attrs);
sz += sizeof(Bindings) + sizeof(Attr) * v.attrs->capacity(); sz += sizeof(Bindings) + sizeof(Attr) * v.attrs->capacity();
for (auto & i : *v.attrs) for (auto & i : *v.attrs)
sz += doValue(*i.value); sz += doValue(*i.value);
@ -1940,8 +1935,7 @@ size_t valueSize(Value & v)
case tList1: case tList1:
case tList2: case tList2:
case tListN: case tListN:
if (seen.find(v.listElems()) == seen.end()) { if (seen.insert(v.listElems()).second) {
seen.insert(v.listElems());
sz += v.listSize() * sizeof(Value *); sz += v.listSize() * sizeof(Value *);
for (size_t n = 0; n < v.listSize(); ++n) for (size_t n = 0; n < v.listSize(); ++n)
sz += doValue(*v.listElems()[n]); sz += doValue(*v.listElems()[n]);
@ -1962,8 +1956,7 @@ size_t valueSize(Value & v)
sz += doValue(*v.primOpApp.right); sz += doValue(*v.primOpApp.right);
break; break;
case tExternal: case tExternal:
if (seen.find(v.external) != seen.end()) break; if (!seen.insert(v.external).second) break;
seen.insert(v.external);
sz += v.external->valueSize(seen); sz += v.external->valueSize(seen);
break; break;
default: default:
@ -1974,8 +1967,7 @@ size_t valueSize(Value & v)
}; };
doEnv = [&](Env & env) -> size_t { doEnv = [&](Env & env) -> size_t {
if (seen.find(&env) != seen.end()) return 0; if (!seen.insert(&env).second) return 0;
seen.insert(&env);
size_t sz = sizeof(Env) + sizeof(Value *) * env.size; size_t sz = sizeof(Env) + sizeof(Value *) * env.size;

View file

@ -277,8 +277,7 @@ static bool getDerivation(EvalState & state, Value & v,
/* Remove spurious duplicates (e.g., a set like `rec { x = /* Remove spurious duplicates (e.g., a set like `rec { x =
derivation {...}; y = x;}'. */ derivation {...}; y = x;}'. */
if (done.find(v.attrs) != done.end()) return false; if (!done.insert(v.attrs).second) return false;
done.insert(v.attrs);
DrvInfo drv(state, attrPath, v.attrs); DrvInfo drv(state, attrPath, v.attrs);

View file

@ -1,5 +1,5 @@
%glr-parser %glr-parser
%pure-parser %define api.pure
%locations %locations
%define parse.error verbose %define parse.error verbose
%defines %defines
@ -138,11 +138,10 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath,
static void addFormal(const Pos & pos, Formals * formals, const Formal & formal) static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
{ {
if (formals->argNames.find(formal.name) != formals->argNames.end()) if (!formals->argNames.insert(formal.name).second)
throw ParseError(format("duplicate formal function argument '%1%' at %2%") throw ParseError(format("duplicate formal function argument '%1%' at %2%")
% formal.name % pos); % formal.name % pos);
formals->formals.push_front(formal); formals->formals.push_front(formal);
formals->argNames.insert(formal.name);
} }

View file

@ -396,8 +396,7 @@ static void prim_genericClosure(EvalState & state, const Pos & pos, Value * * ar
throw EvalError(format("attribute 'key' required, at %1%") % pos); throw EvalError(format("attribute 'key' required, at %1%") % pos);
state.forceValue(*key->value); state.forceValue(*key->value);
if (doneKeys.find(key->value) != doneKeys.end()) continue; if (!doneKeys.insert(key->value).second) continue;
doneKeys.insert(key->value);
res.push_back(e); res.push_back(e);
/* Call the `operator' function with `e' as argument. */ /* Call the `operator' function with `e' as argument. */
@ -1273,13 +1272,12 @@ static void prim_listToAttrs(EvalState & state, const Pos & pos, Value * * args,
string name = state.forceStringNoCtx(*j->value, pos); string name = state.forceStringNoCtx(*j->value, pos);
Symbol sym = state.symbols.create(name); Symbol sym = state.symbols.create(name);
if (seen.find(sym) == seen.end()) { if (seen.insert(sym).second) {
Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue)); Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue));
if (j2 == v2.attrs->end()) if (j2 == v2.attrs->end())
throw TypeError(format("'value' attribute missing in a call to 'listToAttrs', at %1%") % pos); throw TypeError(format("'value' attribute missing in a call to 'listToAttrs', at %1%") % pos);
v.attrs->push_back(Attr(sym, j2->value, j2->pos)); v.attrs->push_back(Attr(sym, j2->value, j2->pos));
seen.insert(sym);
} }
} }

View file

@ -105,10 +105,9 @@ static void printValueAsXML(EvalState & state, bool strict, bool location,
XMLOpenElement _(doc, "derivation", xmlAttrs); XMLOpenElement _(doc, "derivation", xmlAttrs);
if (drvPath != "" && drvsSeen.find(drvPath) == drvsSeen.end()) { if (drvPath != "" && drvsSeen.insert(drvPath).second)
drvsSeen.insert(drvPath);
showAttrs(state, strict, location, *v.attrs, doc, context, drvsSeen); showAttrs(state, strict, location, *v.attrs, doc, context, drvsSeen);
} else else
doc.writeEmptyElement("repeated"); doc.writeEmptyElement("repeated");
} }

View file

@ -568,10 +568,9 @@ UserLock::UserLock()
{ {
auto lockedPaths(lockedPaths_.lock()); auto lockedPaths(lockedPaths_.lock());
if (lockedPaths->count(fnUserLock)) if (!lockedPaths->insert(fnUserLock).second)
/* We already have a lock on this one. */ /* We already have a lock on this one. */
continue; continue;
lockedPaths->insert(fnUserLock);
} }
try { try {
@ -620,8 +619,8 @@ UserLock::UserLock()
UserLock::~UserLock() UserLock::~UserLock()
{ {
auto lockedPaths(lockedPaths_.lock()); auto lockedPaths(lockedPaths_.lock());
assert(lockedPaths->count(fnUserLock)); auto erased = lockedPaths->erase(fnUserLock);
lockedPaths->erase(fnUserLock); assert(erased);
} }
@ -1125,10 +1124,8 @@ void DerivationGoal::addWantedOutputs(const StringSet & outputs)
needRestart = true; needRestart = true;
} else } else
for (auto & i : outputs) for (auto & i : outputs)
if (wantedOutputs.find(i) == wantedOutputs.end()) { if (wantedOutputs.insert(i).second)
wantedOutputs.insert(i);
needRestart = true; needRestart = true;
}
} }

View file

@ -123,8 +123,7 @@ static Path out;
static void addPkg(const Path & pkgDir, int priority) static void addPkg(const Path & pkgDir, int priority)
{ {
if (done.count(pkgDir)) return; if (!done.insert(pkgDir).second) return;
done.insert(pkgDir);
createLinks(pkgDir, out, priority); createLinks(pkgDir, out, priority);
try { try {

View file

@ -70,15 +70,17 @@ LocalStore::LocalStore(const Params & params)
createSymlink(profilesDir, gcRootsDir + "/profiles"); createSymlink(profilesDir, gcRootsDir + "/profiles");
} }
for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) {
createDirs(perUserDir);
if (chmod(perUserDir.c_str(), 0755) == -1)
throw SysError("could not set permissions on '%s' to 755", perUserDir);
}
createUser(getUserName(), getuid());
/* Optionally, create directories and set permissions for a /* Optionally, create directories and set permissions for a
multi-user install. */ multi-user install. */
if (getuid() == 0 && settings.buildUsersGroup != "") { if (getuid() == 0 && settings.buildUsersGroup != "") {
Path perUserDir = profilesDir + "/per-user";
createDirs(perUserDir);
if (chmod(perUserDir.c_str(), 01777) == -1)
throw SysError(format("could not set permissions on '%1%' to 1777") % perUserDir);
mode_t perm = 01775; mode_t perm = 01775;
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
@ -1285,8 +1287,7 @@ void LocalStore::verifyPath(const Path & path, const PathSet & store,
{ {
checkInterrupt(); checkInterrupt();
if (done.find(path) != done.end()) return; if (!done.insert(path).second) return;
done.insert(path);
if (!isStorePath(path)) { if (!isStorePath(path)) {
printError(format("path '%1%' is not in the Nix store") % path); printError(format("path '%1%' is not in the Nix store") % path);
@ -1426,4 +1427,19 @@ void LocalStore::signPathInfo(ValidPathInfo & info)
} }
void LocalStore::createUser(const std::string & userName, uid_t userId)
{
for (auto & dir : {
fmt("%s/profiles/per-user/%s", stateDir, userName),
fmt("%s/gcroots/per-user/%s", stateDir, userName)
}) {
createDirs(dir);
if (chmod(dir.c_str(), 0755) == -1)
throw SysError("changing permissions of directory '%s'", dir);
if (chown(dir.c_str(), userId, getgid()) == -1)
throw SysError("changing owner of directory '%s'", dir);
}
}
} }

View file

@ -293,6 +293,8 @@ private:
Path getRealStoreDir() override { return realStoreDir; } Path getRealStoreDir() override { return realStoreDir; }
void createUser(const std::string & userName, uid_t userId) override;
friend class DerivationGoal; friend class DerivationGoal;
friend class SubstitutionGoal; friend class SubstitutionGoal;
}; };

View file

@ -39,9 +39,12 @@ libstore_CXXFLAGS = \
-DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \ -DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \
-DNIX_BIN_DIR=\"$(bindir)\" \ -DNIX_BIN_DIR=\"$(bindir)\" \
-DNIX_MAN_DIR=\"$(mandir)\" \ -DNIX_MAN_DIR=\"$(mandir)\" \
-DSANDBOX_SHELL="\"$(sandbox_shell)\"" \
-DLSOF=\"$(lsof)\" -DLSOF=\"$(lsof)\"
ifneq ($(sandbox_shell),)
libstore_CXXFLAGS += -DSANDBOX_SHELL="\"$(sandbox_shell)\""
endif
$(d)/local-store.cc: $(d)/schema.sql.gen.hh $(d)/local-store.cc: $(d)/schema.sql.gen.hh
$(d)/build.cc: $(d)/build.cc:

View file

@ -29,8 +29,7 @@ void Store::computeFSClosure(const PathSet & startPaths,
{ {
auto state(state_.lock()); auto state(state_.lock());
if (state->exc) return; if (state->exc) return;
if (state->paths.count(path)) return; if (!state->paths.insert(path).second) return;
state->paths.insert(path);
state->pending++; state->pending++;
} }
@ -175,8 +174,7 @@ void Store::queryMissing(const PathSet & targets,
{ {
auto state(state_.lock()); auto state(state_.lock());
if (state->done.count(path)) return; if (!state->done.insert(path).second) return;
state->done.insert(path);
} }
DrvPathWithOutputs i2 = parseDrvPathWithOutputs(path); DrvPathWithOutputs i2 = parseDrvPathWithOutputs(path);
@ -252,8 +250,7 @@ Paths Store::topoSortPaths(const PathSet & paths)
if (parents.find(path) != parents.end()) if (parents.find(path) != parents.end())
throw BuildError(format("cycle detected in the references of '%1%' from '%2%'") % path % *parent); throw BuildError(format("cycle detected in the references of '%1%' from '%2%'") % path % *parent);
if (visited.find(path) != visited.end()) return; if (!visited.insert(path).second) return;
visited.insert(path);
parents.insert(path); parents.insert(path);
PathSet references; PathSet references;

View file

@ -36,11 +36,10 @@ static void search(const unsigned char * s, size_t len,
} }
if (!match) continue; if (!match) continue;
string ref((const char *) s + i, refLength); string ref((const char *) s + i, refLength);
if (hashes.find(ref) != hashes.end()) { if (hashes.erase(ref)) {
debug(format("found reference to '%1%' at offset '%2%'") debug(format("found reference to '%1%' at offset '%2%'")
% ref % i); % ref % i);
seen.insert(ref); seen.insert(ref);
hashes.erase(ref);
} }
++i; ++i;
} }

View file

@ -949,8 +949,7 @@ std::list<ref<Store>> getDefaultSubstituters()
StringSet done; StringSet done;
auto addStore = [&](const std::string & uri) { auto addStore = [&](const std::string & uri) {
if (done.count(uri)) return; if (!done.insert(uri).second) return;
done.insert(uri);
try { try {
stores.push_back(openStore(uri)); stores.push_back(openStore(uri));
} catch (Error & e) { } catch (Error & e) {

View file

@ -629,6 +629,9 @@ public:
return storePath; return storePath;
} }
virtual void createUser(const std::string & userName, uid_t userId)
{ }
protected: protected:
Stats stats; Stats stats;

View file

@ -171,4 +171,9 @@ JSONObject JSONPlaceholder::object()
return JSONObject(state); return JSONObject(state);
} }
JSONPlaceholder::~JSONPlaceholder()
{
assert(!first || std::uncaught_exception());
}
} }

View file

@ -168,10 +168,7 @@ public:
{ {
} }
~JSONPlaceholder() ~JSONPlaceholder();
{
assert(!first || std::uncaught_exception());
}
template<typename T> template<typename T>
void write(const T & v) void write(const T & v)

View file

@ -486,6 +486,16 @@ std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
} }
std::string getUserName()
{
auto pw = getpwuid(geteuid());
std::string name = pw ? pw->pw_name : getEnv("USER", "");
if (name.empty())
throw Error("cannot figure out user name");
return name;
}
static Lazy<Path> getHome2([]() { static Lazy<Path> getHome2([]() {
Path homeDir = getEnv("HOME"); Path homeDir = getEnv("HOME");
if (homeDir.empty()) { if (homeDir.empty()) {

View file

@ -122,6 +122,12 @@ void deletePath(const Path & path);
void deletePath(const Path & path, unsigned long long & bytesFreed); void deletePath(const Path & path, unsigned long long & bytesFreed);
/* Create a temporary directory. */
Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
bool includePid = true, bool useGlobalCounter = true, mode_t mode = 0755);
std::string getUserName();
/* Return $HOME or the user's home directory from /etc/passwd. */ /* Return $HOME or the user's home directory from /etc/passwd. */
Path getHome(); Path getHome();

View file

@ -412,7 +412,7 @@ static void _main(int argc, char * * argv)
auto rcfile = (Path) tmpDir + "/rc"; auto rcfile = (Path) tmpDir + "/rc";
writeFile(rcfile, fmt( writeFile(rcfile, fmt(
(keepTmp ? "" : "rm -rf '%1%'; "s) + (keepTmp ? "" : "rm -rf '%1%'; "s) +
"[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc; " (pure ? "" : "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc;") +
"%2%" "%2%"
"dontAddDisableDepTrack=1; " "dontAddDisableDepTrack=1; "
"[ -e $stdenv/setup ] && source $stdenv/setup; " "[ -e $stdenv/setup ] && source $stdenv/setup; "

View file

@ -159,13 +159,7 @@ static int _main(int argc, char ** argv)
nixDefExpr = home + "/.nix-defexpr"; nixDefExpr = home + "/.nix-defexpr";
// Figure out the name of the channels profile. // Figure out the name of the channels profile.
; profile = fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName());
auto pw = getpwuid(geteuid());
std::string name = pw ? pw->pw_name : getEnv("USER", "");
if (name.empty())
throw Error("cannot figure out user name");
profile = settings.nixStateDir + "/profiles/per-user/" + name + "/channels";
createDirs(dirOf(profile));
enum { enum {
cNone, cNone,

View file

@ -742,7 +742,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
} }
static void processConnection(bool trusted) static void processConnection(bool trusted,
const std::string & userName, uid_t userId)
{ {
MonitorFdHup monitor(from.fd); MonitorFdHup monitor(from.fd);
@ -793,6 +794,8 @@ static void processConnection(bool trusted)
params["path-info-cache-size"] = "0"; params["path-info-cache-size"] = "0";
auto store = openStore(settings.storeUri, params); auto store = openStore(settings.storeUri, params);
store->createUser(userName, userId);
tunnelLogger->stopWork(); tunnelLogger->stopWork();
to.flush(); to.flush();
@ -1053,7 +1056,7 @@ static void daemonLoop(char * * argv)
/* Handle the connection. */ /* Handle the connection. */
from.fd = remote.get(); from.fd = remote.get();
to.fd = remote.get(); to.fd = remote.get();
processConnection(trusted); processConnection(trusted, user, peer.uid);
exit(0); exit(0);
}, options); }, options);
@ -1133,7 +1136,7 @@ static int _main(int argc, char * * argv)
} }
} }
} else { } else {
processConnection(true); processConnection(true, "root", 0);
} }
} else { } else {
daemonLoop(argv); daemonLoop(argv);

View file

@ -124,11 +124,10 @@ static void getAllExprs(EvalState & state,
string attrName = i; string attrName = i;
if (hasSuffix(attrName, ".nix")) if (hasSuffix(attrName, ".nix"))
attrName = string(attrName, 0, attrName.size() - 4); attrName = string(attrName, 0, attrName.size() - 4);
if (attrs.find(attrName) != attrs.end()) { if (!attrs.insert(attrName).second) {
printError(format("warning: name collision in input Nix expressions, skipping '%1%'") % path2); printError(format("warning: name collision in input Nix expressions, skipping '%1%'") % path2);
continue; continue;
} }
attrs.insert(attrName);
/* Load the expression on demand. */ /* Load the expression on demand. */
Value & vFun = state.getBuiltin("import"); Value & vFun = state.getBuiltin("import");
Value & vArg(*state.allocValue()); Value & vArg(*state.allocValue());
@ -193,12 +192,6 @@ static void loadDerivations(EvalState & state, Path nixExprPath,
} }
static Path getDefNixExprPath()
{
return getHome() + "/.nix-defexpr";
}
static long getPriority(EvalState & state, DrvInfo & drv) static long getPriority(EvalState & state, DrvInfo & drv)
{ {
return drv.queryMetaInt("priority", 0); return drv.queryMetaInt("priority", 0);
@ -307,11 +300,9 @@ static DrvInfos filterBySelector(EvalState & state, const DrvInfos & allElems,
/* Insert only those elements in the final list that we /* Insert only those elements in the final list that we
haven't inserted before. */ haven't inserted before. */
for (auto & j : matches) for (auto & j : matches)
if (done.find(j.second) == done.end()) { if (done.insert(j.second).second)
done.insert(j.second);
elems.push_back(j.first); elems.push_back(j.first);
} }
}
checkSelectorUse(selectors); checkSelectorUse(selectors);
@ -1330,9 +1321,22 @@ static int _main(int argc, char * * argv)
Globals globals; Globals globals;
globals.instSource.type = srcUnknown; globals.instSource.type = srcUnknown;
globals.instSource.nixExprPath = getDefNixExprPath(); globals.instSource.nixExprPath = getHome() + "/.nix-defexpr";
globals.instSource.systemFilter = "*"; globals.instSource.systemFilter = "*";
if (!pathExists(globals.instSource.nixExprPath)) {
try {
createDirs(globals.instSource.nixExprPath);
replaceSymlink(
fmt("%s/profiles/per-user/%s/channels", settings.nixStateDir, getUserName()),
globals.instSource.nixExprPath + "/channels");
if (getuid() != 0)
replaceSymlink(
fmt("%s/profiles/per-user/root/channels", settings.nixStateDir),
globals.instSource.nixExprPath + "/channels_root");
} catch (Error &) { }
}
globals.dryRun = false; globals.dryRun = false;
globals.preserveInstalled = false; globals.preserveInstalled = false;
globals.removeAll = false; globals.removeAll = false;
@ -1425,9 +1429,18 @@ static int _main(int argc, char * * argv)
if (globals.profile == "") { if (globals.profile == "") {
Path profileLink = getHome() + "/.nix-profile"; Path profileLink = getHome() + "/.nix-profile";
globals.profile = pathExists(profileLink) try {
? absPath(readLink(profileLink), dirOf(profileLink)) if (!pathExists(profileLink)) {
: canonPath(settings.nixStateDir + "/profiles/default"); replaceSymlink(
getuid() == 0
? settings.nixStateDir + "/profiles/default"
: fmt("%s/profiles/per-user/%s/profile", settings.nixStateDir, getUserName()),
profileLink);
}
globals.profile = absPath(readLink(profileLink), dirOf(profileLink));
} catch (Error &) {
globals.profile = profileLink;
}
} }
op(globals, opFlags, opArgs); op(globals, opFlags, opArgs);

View file

@ -71,9 +71,7 @@ void printClosure(const Path & nePath, const StoreExpr & fs)
Path path = *(workList.begin()); Path path = *(workList.begin());
workList.erase(path); workList.erase(path);
if (doneSet.find(path) == doneSet.end()) { if (doneSet.insert(path).second) {
doneSet.insert(path);
ClosureElems::const_iterator elem = fs.closure.elems.find(path); ClosureElems::const_iterator elem = fs.closure.elems.find(path);
if (elem == fs.closure.elems.end()) if (elem == fs.closure.elems.end())
throw Error(format("bad closure, missing path '%1%'") % path); throw Error(format("bad closure, missing path '%1%'") % path);
@ -104,8 +102,7 @@ void printDotGraph(ref<Store> store, const PathSet & roots)
Path path = *(workList.begin()); Path path = *(workList.begin());
workList.erase(path); workList.erase(path);
if (doneSet.find(path) != doneSet.end()) continue; if (!doneSet.insert(path).second) continue;
doneSet.insert(path);
cout << makeNode(path, symbolicName(path), "#ff0000"); cout << makeNode(path, symbolicName(path), "#ff0000");

View file

@ -242,11 +242,10 @@ const string treeNull = " ";
static void printTree(const Path & path, static void printTree(const Path & path,
const string & firstPad, const string & tailPad, PathSet & done) const string & firstPad, const string & tailPad, PathSet & done)
{ {
if (done.find(path) != done.end()) { if (!done.insert(path).second) {
cout << format("%1%%2% [...]\n") % firstPad % path; cout << format("%1%%2% [...]\n") % firstPad % path;
return; return;
} }
done.insert(path);
cout << format("%1%%2%\n") % firstPad % path; cout << format("%1%%2%\n") % firstPad % path;

View file

@ -120,7 +120,7 @@ public:
void log(State & state, Verbosity lvl, const std::string & s) void log(State & state, Verbosity lvl, const std::string & s)
{ {
if (state.active) { if (state.active) {
writeToStderr("\r\e[K" + s + ANSI_NORMAL "\n"); writeToStderr("\r\e[K" + filterANSIEscapes(s, !isTTY) + ANSI_NORMAL "\n");
draw(state); draw(state);
} else { } else {
auto s2 = s + ANSI_NORMAL "\n"; auto s2 = s + ANSI_NORMAL "\n";

View file

@ -75,10 +75,6 @@ struct CmdSearch : SourceExprCommand, MixJSON
Example{ Example{
"To search for git and frontend or gui:", "To search for git and frontend or gui:",
"nix search git 'frontend|gui'" "nix search git 'frontend|gui'"
},
Example{
"To display the description of the found packages:",
"nix search git --verbose"
} }
}; };
} }
@ -262,6 +258,7 @@ struct CmdSearch : SourceExprCommand, MixJSON
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145 */
if (!jsonCacheFile) if (!jsonCacheFile)
throw Error("error writing to %s", tmpFile); throw Error("error writing to %s", tmpFile);
throw;
} }
if (writeCache && rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1) if (writeCache && rename(tmpFile.c_str(), jsonCacheFileName.c_str()) == -1)

View file

@ -113,8 +113,7 @@ struct CmdVerify : StorePathsCommand
auto doSigs = [&](StringSet sigs) { auto doSigs = [&](StringSet sigs) {
for (auto sig : sigs) { for (auto sig : sigs) {
if (sigsSeen.count(sig)) continue; if (!sigsSeen.insert(sig).second) continue;
sigsSeen.insert(sig);
if (validSigs < ValidPathInfo::maxSigs && info->checkSignature(publicKeys, sig)) if (validSigs < ValidPathInfo::maxSigs && info->checkSignature(publicKeys, sig))
validSigs++; validSigs++;
} }

View file

@ -117,9 +117,7 @@ Path resolveSymlink(const Path & path)
std::set<string> resolveTree(const Path & path, PathSet & deps) std::set<string> resolveTree(const Path & path, PathSet & deps)
{ {
std::set<string> results; std::set<string> results;
if (deps.count(path)) if (!deps.insert(path).second) return {};
return {};
deps.insert(path);
for (auto & lib : runResolver(path)) { for (auto & lib : runResolver(path)) {
results.insert(lib); results.insert(lib);
for (auto & p : resolveTree(lib, deps)) { for (auto & p : resolveTree(lib, deps)) {

View file

@ -36,7 +36,7 @@ grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
# Do an install. # Do an install.
nix-env -i dependencies nix-env -i dependencies
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ] [ -e $TEST_HOME/.nix-profile/foobar ]
clearProfiles clearProfiles
rm -f $TEST_HOME/.nix-channels rm -f $TEST_HOME/.nix-channels
@ -55,5 +55,5 @@ grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
# Do an install. # Do an install.
nix-env -i dependencies nix-env -i dependencies
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ] [ -e $TEST_HOME/.nix-profile/foobar ]

View file

@ -7,8 +7,3 @@ rm -rf $TEST_HOME $TEST_ROOT/profile-var
mkdir -p $TEST_HOME mkdir -p $TEST_HOME
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set" USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set"
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency
[ -L $TEST_HOME/.nix-profile ]
[ -e $TEST_HOME/.nix-channels ]
[ -e $TEST_ROOT/profile-var/nix/gcroots/per-user/$user ]
[ -e $TEST_ROOT/profile-var/nix/profiles/per-user/$user ]

View file

@ -13,3 +13,7 @@ cmp $TEST_ROOT/d1 $TEST_ROOT/d2
nix-store --gc --max-freed 1K nix-store --gc --max-freed 1K
killDaemon killDaemon
user=$(whoami)
[ -e $NIX_STATE_DIR/gcroots/per-user/$user ]
[ -e $NIX_STATE_DIR/profiles/per-user/$user ]

View file

@ -20,7 +20,7 @@ drvPath10=$(nix-env -f ./user-envs.nix -qa --drv-path --no-name '*' | grep foo-1
# Query descriptions. # Query descriptions.
nix-env -f ./user-envs.nix -qa '*' --description | grep -q silly nix-env -f ./user-envs.nix -qa '*' --description | grep -q silly
rm -f $HOME/.nix-defexpr rm -rf $HOME/.nix-defexpr
ln -s $(pwd)/user-envs.nix $HOME/.nix-defexpr ln -s $(pwd)/user-envs.nix $HOME/.nix-defexpr
nix-env -qa '*' --description | grep -q silly nix-env -qa '*' --description | grep -q silly