1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-09 18:41:03 +01:00

Merge branch 'master' (pre-reformat)

This commit is contained in:
Eelco Dolstra 2025-07-23 21:22:19 +02:00
commit 72e8f7cd35
23 changed files with 202 additions and 131 deletions

View file

@ -7,12 +7,7 @@
#include "nix/util/error.hh"
#include <boost/version.hpp>
#define USE_FLAT_SYMBOL_SET (BOOST_VERSION >= 108100)
#if USE_FLAT_SYMBOL_SET
# include <boost/unordered/unordered_flat_set.hpp>
#else
# include <boost/unordered/unordered_set.hpp>
#endif
#include <boost/unordered/unordered_flat_set.hpp>
namespace nix {
@ -214,12 +209,7 @@ private:
* Transparent lookup of string view for a pointer to a ChunkedVector entry -> return offset into the store.
* ChunkedVector references are never invalidated.
*/
#if USE_FLAT_SYMBOL_SET
boost::unordered_flat_set<SymbolStr, SymbolStr::Hash, SymbolStr::Equal> symbols{SymbolStr::chunkSize};
#else
using SymbolValueAlloc = std::pmr::polymorphic_allocator<SymbolStr>;
boost::unordered_set<SymbolStr, SymbolStr::Hash, SymbolStr::Equal, SymbolValueAlloc> symbols{SymbolStr::chunkSize, {&buffer}};
#endif
public:
@ -230,19 +220,7 @@ public:
// Most symbols are looked up more than once, so we trade off insertion performance
// for lookup performance.
// FIXME: make this thread-safe.
return [&]<typename T>(T && key) -> Symbol {
if constexpr (requires { symbols.insert<T>(key); }) {
auto [it, _] = symbols.insert<T>(key);
return Symbol(*it);
} else {
auto it = symbols.find<T>(key);
if (it != symbols.end())
return Symbol(*it);
it = symbols.emplace(key).first;
return Symbol(*it);
}
}(SymbolStr::Key{store, s, stringAlloc});
return Symbol(*symbols.insert(SymbolStr::Key{store, s, stringAlloc}).first);
}
std::vector<SymbolStr> resolve(const std::vector<Symbol> & symbols) const
@ -287,5 +265,3 @@ struct std::hash<nix::Symbol>
return std::hash<decltype(s.id)>{}(s.id);
}
};
#undef USE_FLAT_SYMBOL_SET

View file

@ -545,15 +545,20 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
append(gitArgs, {"--depth", "1"});
append(gitArgs, {std::string("--"), url, refspec});
runProgram(RunOptions {
auto [status, output] = runProgram(RunOptions {
.program = "git",
.lookupPath = true,
// FIXME: git stderr messes up our progress indicator, so
// we're using --quiet for now. Should process its stderr.
.args = gitArgs,
.input = {},
.mergeStderrToStdout = true,
.isInteractive = true
});
if (status > 0) {
throw Error("Failed to fetch git repository %s : %s", url, output);
}
}
void verifyCommit(

View file

@ -444,7 +444,11 @@ struct GitInputScheme : InputScheme
// repo, treat as a remote URI to force a clone.
static bool forceHttp = getEnv("_NIX_FORCE_HTTP") == "1"; // for testing
auto url = parseURL(getStrAttr(input.attrs, "url"));
bool isBareRepository = url.scheme == "file" && !pathExists(url.path + "/.git");
// Why are we checking for bare repository?
// well if it's a bare repository we want to force a git fetch rather than copying the folder
bool isBareRepository = url.scheme == "file" && pathExists(url.path) &&
!pathExists(url.path + "/.git");
//
// FIXME: here we turn a possibly relative path into an absolute path.
// This allows relative git flake inputs to be resolved against the
@ -462,6 +466,12 @@ struct GitInputScheme : InputScheme
"See https://github.com/NixOS/nix/issues/12281 for details.",
url);
}
// If we don't check here for the path existence, then we can give libgit2 any directory
// and it will initialize them as git directories.
if (!pathExists(url.path)) {
throw Error("The path '%s' does not exist.", url.path);
}
repoInfo.location = std::filesystem::absolute(url.path);
} else {
if (url.scheme == "file")
@ -599,7 +609,7 @@ struct GitInputScheme : InputScheme
? cacheDir / ref
: cacheDir / "refs/heads" / ref;
bool doFetch;
bool doFetch = false;
time_t now = time(0);
/* If a rev was specified, we need to fetch if it's not in the

View file

@ -111,6 +111,25 @@ static DownloadTarballResult downloadTarball_(
const Headers & headers,
const std::string & displayPrefix)
{
// Some friendly error messages for common mistakes.
// Namely lets catch when the url is a local file path, but
// it is not in fact a tarball.
if (url.rfind("file://", 0) == 0) {
// Remove "file://" prefix to get the local file path
std::string localPath = url.substr(7);
if (!std::filesystem::exists(localPath)) {
throw Error("tarball '%s' does not exist.", localPath);
}
if (std::filesystem::is_directory(localPath)) {
if (std::filesystem::exists(localPath + "/.git")) {
throw Error(
"tarball '%s' is a git repository, not a tarball. Please use `git+file` as the scheme.", localPath);
}
throw Error("tarball '%s' is a directory, not a file.", localPath);
}
}
Cache::Key cacheKey{"tarball", {{"url", url}}};
auto cached = settings.getCache()->lookupExpired(cacheKey);

View file

@ -60,6 +60,7 @@ test(
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
'NIX_CONFIG': 'extra-experimental-features = flakes',
'HOME': meson.current_build_dir() / 'test-home',
},
protocol : 'gtest',
)

View file

@ -3,6 +3,7 @@
buildPackages,
stdenv,
mkMesonExecutable,
writableTmpDirAsHomeHook,
nix-flake,
nix-flake-c,
@ -55,19 +56,14 @@ mkMesonExecutable (finalAttrs: {
runCommand "${finalAttrs.pname}-run"
{
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
buildInputs = [ writableTmpDirAsHomeHook ];
}
(
lib.optionalString stdenv.hostPlatform.isWindows ''
export HOME="$PWD/home-dir"
mkdir -p "$HOME"
''
+ ''
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
export NIX_CONFIG="extra-experimental-features = flakes"
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
touch $out
''
);
(''
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
export NIX_CONFIG="extra-experimental-features = flakes"
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
touch $out
'');
};
};

View file

@ -100,6 +100,8 @@ test(
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
'HOME': meson.current_build_dir() / 'test-home',
'NIX_REMOTE': meson.current_build_dir() / 'test-home' / 'store',
},
protocol : 'gtest',
)

View file

@ -28,10 +28,6 @@ TEST_F(nix_api_store_test, nix_store_get_uri)
TEST_F(nix_api_util_context, nix_store_get_storedir_default)
{
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
// skipping test in sandbox because nix_store_open tries to create /nix/var/nix/profiles
GTEST_SKIP();
}
nix_libstore_init(ctx);
Store * store = nix_store_open(ctx, nullptr, nullptr);
assert_ctx_ok();
@ -141,10 +137,6 @@ TEST_F(nix_api_store_test, nix_store_real_path)
TEST_F(nix_api_util_context, nix_store_real_path_relocated)
{
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
// Can't open default store from within sandbox
GTEST_SKIP();
}
auto tmp = nix::createTempDir();
std::string storeRoot = tmp + "/store";
std::string stateDir = tmp + "/state";
@ -184,13 +176,7 @@ TEST_F(nix_api_util_context, nix_store_real_path_relocated)
TEST_F(nix_api_util_context, nix_store_real_path_binary_cache)
{
if (nix::getEnv("HOME").value_or("") == "/homeless-shelter") {
// TODO: override NIX_CACHE_HOME?
// skipping test in sandbox because narinfo cache can't be written
GTEST_SKIP();
}
Store * store = nix_store_open(ctx, "https://cache.nixos.org", nullptr);
Store * store = nix_store_open(ctx, nix::fmt("file://%s/binary-cache", nix::createTempDir()).c_str(), nullptr);
assert_ctx_ok();
ASSERT_NE(store, nullptr);

View file

@ -3,6 +3,7 @@
buildPackages,
stdenv,
mkMesonExecutable,
writableTmpDirAsHomeHook,
nix-store,
nix-store-c,
@ -72,18 +73,14 @@ mkMesonExecutable (finalAttrs: {
runCommand "${finalAttrs.pname}-run"
{
meta.broken = !stdenv.hostPlatform.emulatorAvailable buildPackages;
buildInputs = [ writableTmpDirAsHomeHook ];
}
(
lib.optionalString stdenv.hostPlatform.isWindows ''
export HOME="$PWD/home-dir"
mkdir -p "$HOME"
''
+ ''
export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"}
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
touch $out
''
);
(''
export _NIX_TEST_UNIT_DATA=${data + "/src/libstore-tests/data"}
export NIX_REMOTE=$HOME/store
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
touch $out
'');
};
};

View file

@ -39,7 +39,6 @@ struct LocalBinaryCacheStore :
, BinaryCacheStore{*config}
, config{config}
{
init();
}
void init() override;
@ -126,10 +125,12 @@ StringSet LocalBinaryCacheStoreConfig::uriSchemes()
}
ref<Store> LocalBinaryCacheStoreConfig::openStore() const {
return make_ref<LocalBinaryCacheStore>(ref{
auto store = make_ref<LocalBinaryCacheStore>(ref{
// FIXME we shouldn't actually need a mutable config
std::const_pointer_cast<LocalBinaryCacheStore::Config>(shared_from_this())
});
store->init();
return store;
}
static RegisterStoreImplementation<LocalBinaryCacheStore::Config> regLocalBinaryCacheStore;

View file

@ -289,8 +289,6 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStore
, s3Helper(config->profile, config->region, config->scheme, config->endpoint)
{
diskCache = getNarInfoDiskCache();
init();
}
std::string getUri() override
@ -597,10 +595,12 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStore
ref<Store> S3BinaryCacheStoreImpl::Config::openStore() const
{
return make_ref<S3BinaryCacheStoreImpl>(ref{
auto store = make_ref<S3BinaryCacheStoreImpl>(ref{
// FIXME we shouldn't actually need a mutable config
std::const_pointer_cast<S3BinaryCacheStore::Config>(shared_from_this())
});
store->init();
return store;
}
static RegisterStoreImplementation<S3BinaryCacheStoreImpl::Config> regS3BinaryCacheStore;

View file

@ -250,7 +250,7 @@ void handleSQLiteBusy(const SQLiteBusy & e, time_t & nextWarning)
if (now > nextWarning) {
nextWarning = now + 10;
logWarning({
.msg = HintFmt(e.what())
.msg = e.info().msg
});
}

View file

@ -59,6 +59,7 @@ boost = dependency(
'boost',
modules : ['context', 'coroutine', 'iostreams'],
include_type: 'system',
version: '>=1.82.0'
)
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we
# put in `deps_other`.

View file

@ -194,10 +194,6 @@ size_t StringSource::read(char * data, size_t len)
}
#if BOOST_VERSION >= 106300 && BOOST_VERSION < 106600
#error Coroutines are broken in this version of Boost!
#endif
std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
{
struct SourceToSink : FinishSink

View file

@ -190,8 +190,10 @@ void ignoreExceptionInDestructor(Verbosity lvl)
try {
try {
throw;
} catch (Error & e) {
printMsg(lvl, ANSI_RED "error (ignored):" ANSI_NORMAL " %s", e.info().msg);
} catch (std::exception & e) {
printMsg(lvl, "error (ignored): %1%", e.what());
printMsg(lvl, ANSI_RED "error (ignored):" ANSI_NORMAL " %s", e.what());
}
} catch (...) { }
}
@ -202,8 +204,10 @@ void ignoreExceptionExceptInterrupt(Verbosity lvl)
throw;
} catch (const Interrupted & e) {
throw;
} catch (Error & e) {
printMsg(lvl, ANSI_RED "error (ignored):" ANSI_NORMAL " %s", e.info().msg);
} catch (std::exception & e) {
printMsg(lvl, "error (ignored): %1%", e.what());
printMsg(lvl, ANSI_RED "error (ignored):" ANSI_NORMAL " %s", e.what());
}
}

View file

@ -1,7 +1,8 @@
#include "nix/util/windows-async-pipe.hh"
#include "nix/util/windows-error.hh"
#ifdef _WIN32
# include "nix/util/windows-async-pipe.hh"
# include "nix/util/windows-error.hh"
namespace nix::windows {

View file

@ -1,6 +1,5 @@
#include "nix/util/windows-error.hh"
#ifdef _WIN32
#include "nix/util/windows-error.hh"
#include <error.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

View file

@ -212,6 +212,14 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs, virtual RootArgs
lowdown. */
static void showHelp(std::vector<std::string> subcommand, NixArgs & toplevel)
{
// Check for aliases if subcommand has exactly one element
if (subcommand.size() == 1) {
auto alias = toplevel.aliases.find(subcommand[0]);
if (alias != toplevel.aliases.end()) {
subcommand = alias->second.replacement;
}
}
auto mdName = subcommand.empty() ? "nix" : fmt("nix3-%s", concatStringsSep("-", subcommand));
evalSettings.restrictEval = false;