Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nix for openSUSE:Factory checked in 
at 2025-09-26 22:24:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nix (Old)
 and      /work/SRC/openSUSE:Factory/.nix.new.11973 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nix"

Fri Sep 26 22:24:39 2025 rev:8 rq:1307210 version:2.31.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/nix/nix.changes  2025-09-05 21:44:16.579080774 
+0200
+++ /work/SRC/openSUSE:Factory/.nix.new.11973/nix.changes       2025-09-26 
22:25:59.177713278 +0200
@@ -1,0 +2,10 @@
+Thu Sep 18 13:04:51 UTC 2025 - Marcus Rueckert <[email protected]>
+
+- Update to 2.31.2:
+  - Temporary build directories created during derivation builds no
+    longer include the derivation name in their path to avoid build
+    failures when the derivation name is too long. This change
+    ensures pred ictable prefix lengths for build directories under
+    `/nix/var/nix/builds`
+
+-------------------------------------------------------------------

Old:
----
  nix-2.31.1.tar.gz

New:
----
  nix-2.31.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nix.spec ++++++
--- /var/tmp/diff_new_pack.8pRRUg/_old  2025-09-26 22:25:59.849741620 +0200
+++ /var/tmp/diff_new_pack.8pRRUg/_new  2025-09-26 22:25:59.853741788 +0200
@@ -35,7 +35,7 @@
 %endif
 
 Name:           nix
-Version:        2.31.1
+Version:        2.31.2
 Release:        0
 Summary:        The purely functional package manager
 License:        LGPL-2.1-only

++++++ nix-2.31.1.tar.gz -> nix-2.31.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/.version new/nix-2.31.2/.version
--- old/nix-2.31.1/.version     2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/.version     2025-09-17 22:25:38.000000000 +0200
@@ -1 +1 @@
-2.31.1
+2.31.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/doc/manual/rl-next/shorter-build-dir-names.md 
new/nix-2.31.2/doc/manual/rl-next/shorter-build-dir-names.md
--- old/nix-2.31.1/doc/manual/rl-next/shorter-build-dir-names.md        
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.31.2/doc/manual/rl-next/shorter-build-dir-names.md        
2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1,6 @@
+---
+synopsis: "Temporary build directories no longer include derivation names"
+prs: [13839]
+---
+
+Temporary build directories created during derivation builds no longer include 
the derivation name in their path to avoid build failures when the derivation 
name is too long. This change ensures predictable prefix lengths for build 
directories under `/nix/var/nix/builds`.
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libcmd/installables.cc 
new/nix-2.31.2/src/libcmd/installables.cc
--- old/nix-2.31.1/src/libcmd/installables.cc   2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libcmd/installables.cc   2025-09-17 22:25:38.000000000 
+0200
@@ -178,10 +178,16 @@
             for (auto & [inputName, input] : flake.lockFile.root->inputs) {
                 auto input2 = flake.lockFile.findInput({inputName}); // 
resolve 'follows' nodes
                 if (auto input3 = std::dynamic_pointer_cast<const 
flake::LockedNode>(input2)) {
+                    fetchers::Attrs extraAttrs;
+
+                    if (!input3->lockedRef.subdir.empty()) {
+                        extraAttrs["dir"] = input3->lockedRef.subdir;
+                    }
+
                     overrideRegistry(
                         fetchers::Input::fromAttrs(fetchSettings, {{"type", 
"indirect"}, {"id", inputName}}),
                         input3->lockedRef.input,
-                        {});
+                        extraAttrs);
                 }
             }
         }},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libexpr/meson.build 
new/nix-2.31.2/src/libexpr/meson.build
--- old/nix-2.31.1/src/libexpr/meson.build      2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libexpr/meson.build      2025-09-17 22:25:38.000000000 
+0200
@@ -40,7 +40,10 @@
 
 boost = dependency(
   'boost',
-  modules : [ 'container', 'context' ],
+  modules : [
+    'container',
+    'context',
+  ],
   include_type : 'system',
 )
 # boost is a public dependency, but not a pkg-config dependency unfortunately, 
so we
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libfetchers/include/nix/fetchers/input-cache.hh 
new/nix-2.31.2/src/libfetchers/include/nix/fetchers/input-cache.hh
--- old/nix-2.31.1/src/libfetchers/include/nix/fetchers/input-cache.hh  
2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libfetchers/include/nix/fetchers/input-cache.hh  
2025-09-17 22:25:38.000000000 +0200
@@ -11,6 +11,7 @@
         ref<SourceAccessor> accessor;
         Input resolvedInput;
         Input lockedInput;
+        Attrs extraAttrs;
     };
 
     CachedResult getAccessor(ref<Store> store, const Input & originalInput, 
UseRegistries useRegistries);
@@ -19,6 +20,7 @@
     {
         Input lockedInput;
         ref<SourceAccessor> accessor;
+        Attrs extraAttrs;
     };
 
     virtual std::optional<CachedInput> lookup(const Input & originalInput) 
const = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libfetchers/input-cache.cc 
new/nix-2.31.2/src/libfetchers/input-cache.cc
--- old/nix-2.31.1/src/libfetchers/input-cache.cc       2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libfetchers/input-cache.cc       2025-09-17 
22:25:38.000000000 +0200
@@ -22,7 +22,8 @@
                 fetched = lookup(resolvedInput);
                 if (!fetched) {
                     auto [accessor, lockedInput] = 
resolvedInput.getAccessor(store);
-                    fetched.emplace(CachedInput{.lockedInput = lockedInput, 
.accessor = accessor});
+                    fetched.emplace(
+                        CachedInput{.lockedInput = lockedInput, .accessor = 
accessor, .extraAttrs = extraAttrs});
                 }
                 upsert(resolvedInput, *fetched);
             } else {
@@ -36,7 +37,7 @@
 
     debug("got tree '%s' from '%s'", fetched->accessor, 
fetched->lockedInput.to_string());
 
-    return {fetched->accessor, resolvedInput, fetched->lockedInput};
+    return {fetched->accessor, resolvedInput, fetched->lockedInput, 
fetched->extraAttrs};
 }
 
 struct InputCacheImpl : InputCache
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libflake/flake.cc 
new/nix-2.31.2/src/libflake/flake.cc
--- old/nix-2.31.1/src/libflake/flake.cc        2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libflake/flake.cc        2025-09-17 22:25:38.000000000 
+0200
@@ -340,8 +340,9 @@
     // Fetch a lazy tree first.
     auto cachedInput = state.inputCache->getAccessor(state.store, 
originalRef.input, useRegistries);
 
-    auto resolvedRef = FlakeRef(std::move(cachedInput.resolvedInput), 
originalRef.subdir);
-    auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), 
originalRef.subdir);
+    auto subdir = fetchers::maybeGetStrAttr(cachedInput.extraAttrs, 
"dir").value_or(originalRef.subdir);
+    auto resolvedRef = FlakeRef(std::move(cachedInput.resolvedInput), subdir);
+    auto lockedRef = FlakeRef(std::move(cachedInput.lockedInput), subdir);
 
     // Parse/eval flake.nix to get at the input.self attributes.
     auto flake = readFlake(state, originalRef, resolvedRef, lockedRef, 
{cachedInput.accessor}, lockRootAttrPath);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore/include/nix/store/filetransfer.hh 
new/nix-2.31.2/src/libstore/include/nix/store/filetransfer.hh
--- old/nix-2.31.1/src/libstore/include/nix/store/filetransfer.hh       
2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore/include/nix/store/filetransfer.hh       
2025-09-17 22:25:38.000000000 +0200
@@ -30,9 +30,17 @@
         )",
         {"binary-caches-parallel-connections"}};
 
+    /* Do not set this too low. On glibc, getaddrinfo() contains fallback code
+       paths that deal with ill-behaved DNS servers. Setting this too low
+       prevents some fallbacks from occurring.
+
+       See description of options timeout, single-request, 
single-request-reopen
+       in resolv.conf(5). Also see https://github.com/NixOS/nix/pull/13985 for
+       details on the interaction between getaddrinfo(3) behavior and libcurl
+       CURLOPT_CONNECTTIMEOUT. */
     Setting<unsigned long> connectTimeout{
         this,
-        5,
+        15,
         "connect-timeout",
         R"(
           The timeout (in seconds) for establishing connections in the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore/include/nix/store/store-reference.hh 
new/nix-2.31.2/src/libstore/include/nix/store/store-reference.hh
--- old/nix-2.31.1/src/libstore/include/nix/store/store-reference.hh    
2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore/include/nix/store/store-reference.hh    
2025-09-17 22:25:38.000000000 +0200
@@ -64,7 +64,29 @@
         auto operator<=>(const Specified & rhs) const = default;
     };
 
-    typedef std::variant<Auto, Specified> Variant;
+    /**
+     * Special case for `daemon` to avoid normalization.
+     */
+    struct Daemon : Specified
+    {
+        Daemon()
+            : Specified({.scheme = "unix"})
+        {
+        }
+    };
+
+    /**
+     * Special case for `local` to avoid normalization.
+     */
+    struct Local : Specified
+    {
+        Local()
+            : Specified({.scheme = "local"})
+        {
+        }
+    };
+
+    typedef std::variant<Auto, Specified, Daemon, Local> Variant;
 
     Variant variant;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore/local-store.cc 
new/nix-2.31.2/src/libstore/local-store.cc
--- old/nix-2.31.1/src/libstore/local-store.cc  2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libstore/local-store.cc  2025-09-17 22:25:38.000000000 
+0200
@@ -456,12 +456,17 @@
 
 StoreReference LocalStoreConfig::getReference() const
 {
+    auto params = getQueryParams();
+    /* Back-compatibility kludge. Tools like nix-output-monitor expect 'local'
+       and can't parse 'local://'. */
+    if (params.empty())
+        return {.variant = StoreReference::Local{}};
     return {
         .variant =
             StoreReference::Specified{
                 .scheme = *uriSchemes().begin(),
             },
-        .params = getQueryParams(),
+        .params = std::move(params),
     };
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore/meson.build 
new/nix-2.31.2/src/libstore/meson.build
--- old/nix-2.31.1/src/libstore/meson.build     2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libstore/meson.build     2025-09-17 22:25:38.000000000 
+0200
@@ -101,7 +101,12 @@
 
 boost = dependency(
   'boost',
-  modules : [ 'container', 'regex' ],
+  modules : [
+    'container',
+    # Shouldn't list, because can header-only, and Meson currently looks for 
libs
+    #'regex',
+    'url',
+  ],
   include_type : 'system',
 )
 # boost is a public dependency, but not a pkg-config dependency unfortunately, 
so we
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore/store-api.cc 
new/nix-2.31.2/src/libstore/store-api.cc
--- old/nix-2.31.1/src/libstore/store-api.cc    2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libstore/store-api.cc    2025-09-17 22:25:38.000000000 
+0200
@@ -817,7 +817,13 @@
 
     auto isShorthand = [](const StoreReference & ref) {
         /* At this point StoreReference **must** be resolved. */
-        const auto & specified = 
std::get<StoreReference::Specified>(ref.variant);
+        const auto & specified = std::visit(
+            overloaded{
+                [](const StoreReference::Auto &) -> const 
StoreReference::Specified & { unreachable(); },
+                [](const StoreReference::Specified & specified) -> const 
StoreReference::Specified & {
+                    return specified;
+                }},
+            ref.variant);
         const auto & scheme = specified.scheme;
         return (scheme == "local" || scheme == "unix") && 
specified.authority.empty();
     };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore/store-reference.cc 
new/nix-2.31.2/src/libstore/store-reference.cc
--- old/nix-2.31.1/src/libstore/store-reference.cc      2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore/store-reference.cc      2025-09-17 
22:25:38.000000000 +0200
@@ -1,11 +1,12 @@
-#include <regex>
-
 #include "nix/util/error.hh"
+#include "nix/util/split.hh"
 #include "nix/util/url.hh"
 #include "nix/store/store-reference.hh"
 #include "nix/util/file-system.hh"
 #include "nix/util/util.hh"
 
+#include <boost/url/ipv6_address.hpp>
+
 namespace nix {
 
 static bool isNonUriPath(const std::string & spec)
@@ -25,6 +26,8 @@
     std::visit(
         overloaded{
             [&](const StoreReference::Auto &) { res = "auto"; },
+            [&](const StoreReference::Daemon &) { res = "daemon"; },
+            [&](const StoreReference::Local &) { res = "local"; },
             [&](const StoreReference::Specified & g) {
                 res = g.scheme;
                 res += "://";
@@ -41,6 +44,29 @@
     return res;
 }
 
+namespace {
+
+struct SchemeAndAuthorityWithPath
+{
+    std::string_view scheme;
+    std::string_view authority;
+};
+
+} // namespace
+
+/**
+ * Return the 'scheme' and remove the '://' or ':' separator.
+ */
+static std::optional<SchemeAndAuthorityWithPath> 
splitSchemePrefixTo(std::string_view string)
+{
+    auto scheme = splitPrefixTo(string, ':');
+    if (!scheme)
+        return std::nullopt;
+
+    splitPrefix(string, "//");
+    return SchemeAndAuthorityWithPath{.scheme = *scheme, .authority = string};
+}
+
 StoreReference StoreReference::parse(const std::string & uri, const 
StoreReference::Params & extraParams)
 {
     auto params = extraParams;
@@ -68,21 +94,17 @@
                 .params = std::move(params),
             };
         } else if (baseURI == "daemon") {
+            if (params.empty())
+                return {.variant = Daemon{}};
             return {
-                .variant =
-                    Specified{
-                        .scheme = "unix",
-                        .authority = "",
-                    },
+                .variant = Specified{.scheme = "unix", .authority = ""},
                 .params = std::move(params),
             };
         } else if (baseURI == "local") {
+            if (params.empty())
+                return {.variant = Local{}};
             return {
-                .variant =
-                    Specified{
-                        .scheme = "local",
-                        .authority = "",
-                    },
+                .variant = Specified{.scheme = "local", .authority = ""},
                 .params = std::move(params),
             };
         } else if (isNonUriPath(baseURI)) {
@@ -94,6 +116,32 @@
                     },
                 .params = std::move(params),
             };
+        } else if (auto schemeAndAuthority = splitSchemePrefixTo(baseURI)) {
+            /* Back-compatibility shim to accept unbracketed IPv6 addresses 
after the scheme.
+             * Old versions of nix allowed that. Note that this is ambiguous 
and does not allow
+             * specifying the port number. For that the address must be 
bracketed, otherwise it's
+             * greedily assumed to be the part of the host address. */
+            auto authorityString = schemeAndAuthority->authority;
+            auto userinfo = splitPrefixTo(authorityString, '@');
+            auto maybeIpv6 = boost::urls::parse_ipv6_address(authorityString);
+            if (maybeIpv6) {
+                std::string fixedAuthority;
+                if (userinfo) {
+                    fixedAuthority += *userinfo;
+                    fixedAuthority += '@';
+                }
+                fixedAuthority += '[';
+                fixedAuthority += authorityString;
+                fixedAuthority += ']';
+                return {
+                    .variant =
+                        Specified{
+                            .scheme = std::string(schemeAndAuthority->scheme),
+                            .authority = fixedAuthority,
+                        },
+                    .params = std::move(params),
+                };
+            }
         }
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore/uds-remote-store.cc 
new/nix-2.31.2/src/libstore/uds-remote-store.cc
--- old/nix-2.31.1/src/libstore/uds-remote-store.cc     2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore/uds-remote-store.cc     2025-09-17 
22:25:38.000000000 +0200
@@ -57,15 +57,16 @@
 
 StoreReference UDSRemoteStoreConfig::getReference() const
 {
+    /* We specifically return "daemon" here instead of "unix://" or 
"unix://${path}"
+     * to be more compatible with older versions of nix. Some tooling out there
+     * tries hard to parse store references and it might not be able to handle 
"unix://". */
+    if (path == settings.nixDaemonSocketFile)
+        return {.variant = StoreReference::Daemon{}};
     return {
         .variant =
             StoreReference::Specified{
                 .scheme = *uriSchemes().begin(),
-                // We return the empty string when the path looks like the
-                // default path, but we could also just return the path
-                // verbatim always, to be robust to overall config changes
-                // at the cost of some verbosity.
-                .authority = path == settings.nixDaemonSocketFile ? "" : path,
+                .authority = path,
             },
     };
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore/unix/build/derivation-builder.cc 
new/nix-2.31.2/src/libstore/unix/build/derivation-builder.cc
--- old/nix-2.31.1/src/libstore/unix/build/derivation-builder.cc        
2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore/unix/build/derivation-builder.cc        
2025-09-17 22:25:38.000000000 +0200
@@ -706,7 +706,7 @@
 
     /* Create a temporary directory where the build will take
        place. */
-    topTmpDir = createTempDir(buildDir, "nix-build-" + 
std::string(drvPath.name()), 0700);
+    topTmpDir = createTempDir(buildDir, "nix", 0700);
     setBuildTmpDir();
     assert(!tmpDir.empty());
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore-tests/data/store-reference/daemon_shorthand.txt 
new/nix-2.31.2/src/libstore-tests/data/store-reference/daemon_shorthand.txt
--- old/nix-2.31.1/src/libstore-tests/data/store-reference/daemon_shorthand.txt 
1970-01-01 01:00:00.000000000 +0100
+++ new/nix-2.31.2/src/libstore-tests/data/store-reference/daemon_shorthand.txt 
2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1 @@
+daemon
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore-tests/data/store-reference/local_shorthand_3.txt 
new/nix-2.31.2/src/libstore-tests/data/store-reference/local_shorthand_3.txt
--- 
old/nix-2.31.1/src/libstore-tests/data/store-reference/local_shorthand_3.txt    
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.31.2/src/libstore-tests/data/store-reference/local_shorthand_3.txt    
    2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1 @@
+local
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_1.txt
 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_1.txt
--- 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_1.txt
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_1.txt
   2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1 @@
+ssh://::1
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_2.txt
 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_2.txt
--- 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_2.txt
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_2.txt
   2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1 @@
+ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_3.txt
 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_3.txt
--- 
old/nix-2.31.1/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_3.txt
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.31.2/src/libstore-tests/data/store-reference/ssh_unbracketed_ipv6_3.txt
   2025-09-17 22:25:38.000000000 +0200
@@ -0,0 +1 @@
+ssh://userinfo@fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e?a=b&c=d
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore-tests/local-store.cc 
new/nix-2.31.2/src/libstore-tests/local-store.cc
--- old/nix-2.31.1/src/libstore-tests/local-store.cc    2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore-tests/local-store.cc    2025-09-17 
22:25:38.000000000 +0200
@@ -33,4 +33,10 @@
     EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"});
 }
 
+TEST(LocalStore, constructConfig_to_string)
+{
+    LocalStoreConfig config{"local", "", {}};
+    EXPECT_EQ(config.getReference().render(), "local");
+}
+
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore-tests/store-reference.cc 
new/nix-2.31.2/src/libstore-tests/store-reference.cc
--- old/nix-2.31.1/src/libstore-tests/store-reference.cc        2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore-tests/store-reference.cc        2025-09-17 
22:25:38.000000000 +0200
@@ -107,6 +107,13 @@
 
 URI_TEST_READ(local_shorthand_2, localExample_2)
 
+URI_TEST(
+    local_shorthand_3,
+    (StoreReference{
+        .variant = StoreReference::Local{},
+        .params = {},
+    }))
+
 static StoreReference unixExample{
     .variant =
         StoreReference::Specified{
@@ -134,4 +141,46 @@
         .params = {},
     }))
 
+URI_TEST(
+    daemon_shorthand,
+    (StoreReference{
+        .variant = StoreReference::Daemon{},
+        .params = {},
+    }))
+
+static StoreReference sshLoopbackIPv6{
+    .variant =
+        StoreReference::Specified{
+            .scheme = "ssh",
+            .authority = "[::1]",
+        },
+};
+
+URI_TEST_READ(ssh_unbracketed_ipv6_1, sshLoopbackIPv6)
+
+static StoreReference sshIPv6AuthorityWithUserinfo{
+    .variant =
+        StoreReference::Specified{
+            .scheme = "ssh",
+            .authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e]",
+        },
+};
+
+URI_TEST_READ(ssh_unbracketed_ipv6_2, sshIPv6AuthorityWithUserinfo)
+
+static StoreReference sshIPv6AuthorityWithUserinfoAndParams{
+    .variant =
+        StoreReference::Specified{
+            .scheme = "ssh",
+            .authority = "userinfo@[fea5:23e1:3916:fc24:cb52:2837:2ecb:ea8e]",
+        },
+    .params =
+        {
+            {"a", "b"},
+            {"c", "d"},
+        },
+};
+
+URI_TEST_READ(ssh_unbracketed_ipv6_3, sshIPv6AuthorityWithUserinfoAndParams)
+
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libstore-tests/uds-remote-store.cc 
new/nix-2.31.2/src/libstore-tests/uds-remote-store.cc
--- old/nix-2.31.1/src/libstore-tests/uds-remote-store.cc       2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libstore-tests/uds-remote-store.cc       2025-09-17 
22:25:38.000000000 +0200
@@ -16,4 +16,10 @@
     EXPECT_THROW(UDSRemoteStoreConfig("http", "/tmp/socket", {}), UsageError);
 }
 
+TEST(UDSRemoteStore, constructConfig_to_string)
+{
+    UDSRemoteStoreConfig config{"unix", "", {}};
+    EXPECT_EQ(config.getReference().render(), "daemon");
+}
+
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/src/libutil/meson.build 
new/nix-2.31.2/src/libutil/meson.build
--- old/nix-2.31.1/src/libutil/meson.build      2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/src/libutil/meson.build      2025-09-17 22:25:38.000000000 
+0200
@@ -57,7 +57,12 @@
 
 boost = dependency(
   'boost',
-  modules : [ 'context', 'coroutine', 'iostreams', 'url' ],
+  modules : [
+    'context',
+    'coroutine',
+    'iostreams',
+    'url',
+  ],
   include_type : 'system',
   version : '>=1.82.0',
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.31.1/src/libutil/unix/include/nix/util/monitor-fd.hh 
new/nix-2.31.2/src/libutil/unix/include/nix/util/monitor-fd.hh
--- old/nix-2.31.1/src/libutil/unix/include/nix/util/monitor-fd.hh      
2025-09-01 09:52:24.000000000 +0200
+++ new/nix-2.31.2/src/libutil/unix/include/nix/util/monitor-fd.hh      
2025-09-17 22:25:38.000000000 +0200
@@ -2,15 +2,18 @@
 ///@file
 
 #include <thread>
-#include <atomic>
+#include <cassert>
 
-#include <cstdlib>
 #include <poll.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
+#include <errno.h>
+
+#ifdef __APPLE__
+#  include <sys/types.h>
+#  include <sys/event.h>
+#endif
 
 #include "nix/util/signals.hh"
+#include "nix/util/file-descriptor.hh"
 
 namespace nix {
 
@@ -20,111 +23,113 @@
     std::thread thread;
     Pipe notifyPipe;
 
-public:
-    MonitorFdHup(int fd)
-    {
-        notifyPipe.create();
-        thread = std::thread([this, fd]() {
-            while (true) {
-                // There is a POSIX violation on macOS: you have to listen for
-                // at least POLLHUP to receive HUP events for a FD. POSIX says
-                // this is not so, and you should just receive them regardless.
-                // However, as of our testing on macOS 14.5, the events do not
-                // get delivered if in the all-bits-unset case, but do get
-                // delivered if `POLLHUP` is set.
-                //
-                // This bug filed as rdar://37537852
-                // (https://openradar.appspot.com/37537852).
-                //
-                // macOS's own man page
-                // 
(https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/poll.2.html)
-                // additionally says that `POLLHUP` is ignored as an input. It
-                // seems the likely order of events here was
-                //
-                // 1. macOS did not follow the POSIX spec
-                //
-                // 2. Somebody ninja-fixed this other spec violation to make
-                // sure `POLLHUP` was not forgotten about, even though they
-                // "fixed" this issue in a spec-non-compliant way. Whatever,
-                // we'll use the fix.
-                //
-                // Relevant code, current version, which shows the :
-                // 
https://github.com/apple-oss-distributions/xnu/blob/94d3b452840153a99b38a3a9659680b2a006908e/bsd/kern/sys_generic.c#L1751-L1758
-                //
-                // The `POLLHUP` detection was added in
-                // 
https://github.com/apple-oss-distributions/xnu/commit/e13b1fa57645afc8a7b2e7d868fe9845c6b08c40#diff-a5aa0b0e7f4d866ca417f60702689fc797e9cdfe33b601b05ccf43086c35d395R1468
-                // That means added in 2007 or earlier. Should be good enough
-                // for us.
-                short hangup_events =
-#ifdef __APPLE__
-                    POLLHUP
-#else
-                    0
-#endif
-                    ;
+    void runThread(int watchFd, int notifyFd);
 
-                /* Wait indefinitely until a POLLHUP occurs. */
-                constexpr size_t num_fds = 2;
-                struct pollfd fds[num_fds] = {
-                    {
-                        .fd = fd,
-                        .events = hangup_events,
-                    },
-                    {
-                        .fd = notifyPipe.readSide.get(),
-                        .events = hangup_events,
-                    },
-                };
-
-                auto count = poll(fds, num_fds, -1);
-                if (count == -1) {
-                    if (errno == EINTR || errno == EAGAIN)
-                        continue;
-                    throw SysError("failed to poll() in MonitorFdHup");
-                }
-                /* This shouldn't happen, but can on macOS due to a bug.
-                   See rdar://37550628.
-
-                   This may eventually need a delay or further
-                   coordination with the main thread if spinning proves
-                   too harmful.
-                */
-                if (count == 0)
-                    continue;
-                if (fds[0].revents & POLLHUP) {
-                    unix::triggerInterrupt();
-                    break;
-                }
-                if (fds[1].revents & POLLHUP) {
-                    break;
-                }
-                // On macOS, (jade thinks that) it is possible (although not
-                // observed on macOS 14.5) that in some limited cases on buggy
-                // kernel versions, all the non-POLLHUP events for the socket
-                // get delivered.
-                //
-                // We could sleep to avoid pointlessly spinning a thread on
-                // those, but this opens up a different problem, which is that
-                // if do sleep, it will be longer before the daemon fork for a
-                // client exits. Imagine a sequential shell script, running Nix
-                // commands, each of which talk to the daemon. If the previous
-                // command registered a temp root, exits, and then the next
-                // command issues a delete request before the temp root is
-                // cleaned up, that delete request might fail.
-                //
-                // Not sleeping doesn't actually fix the race condition --- we
-                // would need to block on the old connections' tempt roots 
being
-                // cleaned up in in the new connection --- but it does make it
-                // much less likely.
-            }
-        });
-    };
+public:
+    MonitorFdHup(int fd);
 
     ~MonitorFdHup()
     {
+        // Close the write side to signal termination via POLLHUP
         notifyPipe.writeSide.close();
         thread.join();
     }
 };
 
+#ifdef __APPLE__
+/* This custom kqueue usage exists because Apple's poll implementation is
+ * broken and loses event subscriptions if EVFILT_READ fires without matching
+ * the requested `events` in the pollfd.
+ *
+ * We use EVFILT_READ, which causes some spurious wakeups (at most one per 
write
+ * from the client, in addition to the socket lifecycle events), because the
+ * alternate API, EVFILT_SOCK, doesn't work on pipes, which this is also used
+ * to monitor in certain situations.
+ *
+ * See (EVFILT_SOCK):
+ * 
https://github.com/netty/netty/blob/64bd2f4eb62c2fb906bc443a2aabf894c8b7dce9/transport-classes-kqueue/src/main/java/io/netty/channel/kqueue/AbstractKQueueChannel.java#L434
+ *
+ * See: https://git.lix.systems/lix-project/lix/issues/729
+ * Apple bug in poll(2): FB17447257, available at 
https://openradar.appspot.com/FB17447257
+ */
+inline void MonitorFdHup::runThread(int watchFd, int notifyFd)
+{
+    int kqResult = kqueue();
+    if (kqResult < 0) {
+        throw SysError("MonitorFdHup kqueue");
+    }
+    AutoCloseFD kq{kqResult};
+
+    std::array<struct kevent, 2> kevs;
+
+    // kj uses EVFILT_WRITE for this, but it seems that it causes more spurious
+    // wakeups in our case of doing blocking IO from another thread compared to
+    // EVFILT_READ.
+    //
+    // EVFILT_WRITE and EVFILT_READ (for sockets at least, where I am familiar
+    // with the internals) both go through a common filter which catches EOFs
+    // and generates spurious wakeups for either readable/writable events.
+    EV_SET(&kevs[0], watchFd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 
0, nullptr);
+    EV_SET(&kevs[1], notifyFd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0, 
0, nullptr);
+
+    int result = kevent(kq.get(), kevs.data(), kevs.size(), nullptr, 0, 
nullptr);
+    if (result < 0) {
+        throw SysError("MonitorFdHup kevent add");
+    }
+
+    while (true) {
+        struct kevent event;
+        int numEvents = kevent(kq.get(), nullptr, 0, &event, 1, nullptr);
+        if (numEvents < 0) {
+            throw SysError("MonitorFdHup kevent watch");
+        }
+
+        if (numEvents > 0 && (event.flags & EV_EOF)) {
+            if (event.ident == uintptr_t(watchFd)) {
+                unix::triggerInterrupt();
+            }
+            // Either watched fd or notify fd closed, exit
+            return;
+        }
+    }
+}
+#else
+inline void MonitorFdHup::runThread(int watchFd, int notifyFd)
+{
+    while (true) {
+        struct pollfd fds[2];
+        fds[0].fd = watchFd;
+        fds[0].events = 0; // POSIX: POLLHUP is always reported
+        fds[1].fd = notifyFd;
+        fds[1].events = 0;
+
+        auto count = poll(fds, 2, -1);
+        if (count == -1) {
+            if (errno == EINTR || errno == EAGAIN) {
+                continue;
+            } else {
+                throw SysError("in MonitorFdHup poll()");
+            }
+        }
+
+        if (fds[0].revents & POLLHUP) {
+            unix::triggerInterrupt();
+            break;
+        }
+
+        if (fds[1].revents & POLLHUP) {
+            // Notify pipe closed, exit thread
+            break;
+        }
+    }
+}
+#endif
+
+inline MonitorFdHup::MonitorFdHup(int fd)
+{
+    notifyPipe.create();
+    int notifyFd = notifyPipe.readSide.get();
+    thread = std::thread([this, fd, notifyFd]() { this->runThread(fd, 
notifyFd); });
+};
+
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/tests/functional/check.sh 
new/nix-2.31.2/tests/functional/check.sh
--- old/nix-2.31.1/tests/functional/check.sh    2025-09-01 09:52:24.000000000 
+0200
+++ new/nix-2.31.2/tests/functional/check.sh    2025-09-17 22:25:38.000000000 
+0200
@@ -52,10 +52,10 @@
   nix-build check.nix -A failed --argstr checkBuildId "$checkBuildId" \
       --no-out-link --keep-failed --option build-dir 
"$TEST_ROOT/custom-build-dir" 2> "$TEST_ROOT/log" || status=$?
   [ "$status" = "100" ]
-  [[ 1 == "$(count "$customBuildDir/nix-build-"*)" ]]
-  local buildDir=("$customBuildDir/nix-build-"*)
+  [[ 1 == "$(count "$customBuildDir/nix-"*)" ]]
+  local buildDir=("$customBuildDir/nix-"*)
   if [[ "${#buildDir[@]}" -ne 1 ]]; then
-    echo "expected one nix-build-* directory, got: ${buildDir[*]}" >&2
+    echo "expected one nix-* directory, got: ${buildDir[*]}" >&2
     exit 1
   fi
   if [[ -e ${buildDir[*]}/build ]]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/tests/functional/flakes/flakes.sh 
new/nix-2.31.2/tests/functional/flakes/flakes.sh
--- old/nix-2.31.1/tests/functional/flakes/flakes.sh    2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/tests/functional/flakes/flakes.sh    2025-09-17 
22:25:38.000000000 +0200
@@ -470,3 +470,33 @@
 EOF
 
 [[ "$(nix flake metadata --json "$flake3Dir" | jq -r 
.locks.nodes.flake1.locked.rev)" = $prevFlake1Rev ]]
+
+baseDir=$TEST_ROOT/$RANDOM
+subdirFlakeDir1=$baseDir/foo1
+mkdir -p "$subdirFlakeDir1"
+
+writeSimpleFlake "$baseDir"
+
+cat > "$subdirFlakeDir1"/flake.nix <<EOF
+{
+  outputs = inputs: {
+    shouldBeOne = 1;
+  };
+}
+EOF
+
+nix registry add --registry "$registry" flake2 "path:$baseDir?dir=foo1"
+[[ "$(nix eval --flake-registry "$registry" flake2#shouldBeOne)" = 1 ]]
+
+subdirFlakeDir2=$baseDir/foo2
+mkdir -p "$subdirFlakeDir2"
+cat > "$subdirFlakeDir2"/flake.nix <<EOF
+{
+  inputs.foo1.url = "path:$baseDir?dir=foo1";
+
+  outputs = inputs: { };
+}
+EOF
+
+# Regression test for https://github.com/NixOS/nix/issues/13918
+[[ "$(nix eval --inputs-from "$subdirFlakeDir2" foo1#shouldBeOne)" = 1 ]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/tests/functional/store-info.sh 
new/nix-2.31.2/tests/functional/store-info.sh
--- old/nix-2.31.1/tests/functional/store-info.sh       2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/tests/functional/store-info.sh       2025-09-17 
22:25:38.000000000 +0200
@@ -13,14 +13,20 @@
             # Need to actually ask Nix in this case
             echo "$defaultStore"
             ;;
+        local | 'local://' )
+            echo 'local'
+            ;;
+        daemon | 'unix://' )
+            echo 'daemon'
+            ;;
         'local://'* )
             # To not be captured by next pattern
             echo "$url"
             ;;
-        local | 'local?'* )
+        'local?'* )
             echo "local://${url#local}"
             ;;
-        daemon | 'daemon?'* )
+        'daemon?'* )
             echo "unix://${url#daemon}"
             ;;
         * )
@@ -38,13 +44,13 @@
 # Test cases for `normalize_nix_store_url` itself
 
 # Normalize local store
-[[ "$(normalize_nix_store_url "local://")" = "local://" ]]
-[[ "$(normalize_nix_store_url "local")" = "local://" ]]
+[[ "$(normalize_nix_store_url "local://")" = "local" ]]
+[[ "$(normalize_nix_store_url "local")" = "local" ]]
 [[ "$(normalize_nix_store_url "local?foo=bar")" = "local://?foo=bar" ]]
 
 # Normalize unix domain socket remote store
-[[ "$(normalize_nix_store_url "unix://")" = "unix://" ]]
-[[ "$(normalize_nix_store_url "daemon")" = "unix://" ]]
+[[ "$(normalize_nix_store_url "unix://")" = "daemon" ]]
+[[ "$(normalize_nix_store_url "daemon")" = "daemon" ]]
 [[ "$(normalize_nix_store_url "daemon?x=y")" = "unix://?x=y" ]]
 
 # otherwise unchanged
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/tests/nixos/authorization.nix 
new/nix-2.31.2/tests/nixos/authorization.nix
--- old/nix-2.31.1/tests/nixos/authorization.nix        2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/tests/nixos/authorization.nix        2025-09-17 
22:25:38.000000000 +0200
@@ -84,7 +84,7 @@
           su --login mallory -c '
             nix-store --generate-binary-cache-key cache1.example.org sk1 pk1
             (! nix store sign --key-file sk1 ${pathFour} 2>&1)' | tee diag 1>&2
-          grep -F "cannot open connection to remote store 'unix://'" diag
+          grep -F "cannot open connection to remote store 'daemon'" diag
       """)
 
       machine.succeed("""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.31.1/tests/nixos/user-sandboxing/default.nix 
new/nix-2.31.2/tests/nixos/user-sandboxing/default.nix
--- old/nix-2.31.1/tests/nixos/user-sandboxing/default.nix      2025-09-01 
09:52:24.000000000 +0200
+++ new/nix-2.31.2/tests/nixos/user-sandboxing/default.nix      2025-09-17 
22:25:38.000000000 +0200
@@ -104,8 +104,8 @@
 
           # Wait for the build to be ready
           # This is OK because it runs as root, so we can access everything
-          machine.wait_until_succeeds("stat 
/nix/var/nix/builds/nix-build-open-build-dir.drv-*/build/syncPoint")
-          dir = machine.succeed("ls -d 
/nix/var/nix/builds/nix-build-open-build-dir.drv-*").strip()
+          machine.wait_until_succeeds("stat 
/nix/var/nix/builds/nix-*/build/syncPoint")
+          dir = machine.succeed("ls -d /nix/var/nix/builds/nix-*").strip()
 
           # But Alice shouldn't be able to access the build directory
           machine.fail(f"su alice -c 'ls {dir}/build'")
@@ -125,8 +125,8 @@
                 args = [ (builtins.storePath "${create-hello-world}") ];
             }' >&2 &
           """.strip())
-          machine.wait_until_succeeds("stat 
/nix/var/nix/builds/nix-build-innocent.drv-*/build/syncPoint")
-          dir = machine.succeed("ls -d 
/nix/var/nix/builds/nix-build-innocent.drv-*").strip()
+          machine.wait_until_succeeds("stat 
/nix/var/nix/builds/nix-*/build/syncPoint")
+          dir = machine.succeed("ls -d /nix/var/nix/builds/nix-*").strip()
 
           # The build ran as `nixbld1` (which is the only build user on the
           # machine), but a process running as `nixbld1` outside the sandbox

Reply via email to