mirror of
https://github.com/NixOS/nix
synced 2025-06-30 07:33:16 +02:00
Merge remote-tracking branch 'upstream/master' into no-stringly-typed-derivation-output
This commit is contained in:
commit
e5cc1ebc5d
20 changed files with 296 additions and 44 deletions
|
@ -217,10 +217,15 @@ MultiCommand::MultiCommand(const Commands & commands)
|
|||
{
|
||||
expectedArgs.push_back(ExpectedArg{"command", 1, true, [=](std::vector<std::string> ss) {
|
||||
assert(!command);
|
||||
auto i = commands.find(ss[0]);
|
||||
auto cmd = ss[0];
|
||||
if (auto alias = get(deprecatedAliases, cmd)) {
|
||||
warn("'%s' is a deprecated alias for '%s'", cmd, *alias);
|
||||
cmd = *alias;
|
||||
}
|
||||
auto i = commands.find(cmd);
|
||||
if (i == commands.end())
|
||||
throw UsageError("'%s' is not a recognised command", ss[0]);
|
||||
command = {ss[0], i->second()};
|
||||
throw UsageError("'%s' is not a recognised command", cmd);
|
||||
command = {cmd, i->second()};
|
||||
}});
|
||||
|
||||
categories[Command::catDefault] = "Available commands";
|
||||
|
|
|
@ -234,6 +234,8 @@ public:
|
|||
|
||||
std::map<Command::Category, std::string> categories;
|
||||
|
||||
std::map<std::string, std::string> deprecatedAliases;
|
||||
|
||||
// Selected command, if any.
|
||||
std::optional<std::pair<std::string, ref<Command>>> command;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <optional>
|
||||
|
|
130
src/libutil/tests/lru-cache.cc
Normal file
130
src/libutil/tests/lru-cache.cc
Normal file
|
@ -0,0 +1,130 @@
|
|||
#include "lru-cache.hh"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* size
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(LRUCache, sizeOfEmptyCacheIsZero) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
ASSERT_EQ(c.size(), 0);
|
||||
}
|
||||
|
||||
TEST(LRUCache, sizeOfSingleElementCacheIsOne) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("foo", "bar");
|
||||
ASSERT_EQ(c.size(), 1);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* upsert / get
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(LRUCache, getFromEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
auto val = c.get("x");
|
||||
ASSERT_EQ(val.has_value(), false);
|
||||
}
|
||||
|
||||
TEST(LRUCache, getExistingValue) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("foo", "bar");
|
||||
auto val = c.get("foo");
|
||||
ASSERT_EQ(val, "bar");
|
||||
}
|
||||
|
||||
TEST(LRUCache, getNonExistingValueFromNonEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("foo", "bar");
|
||||
auto val = c.get("another");
|
||||
ASSERT_EQ(val.has_value(), false);
|
||||
}
|
||||
|
||||
TEST(LRUCache, upsertOnZeroCapacityCache) {
|
||||
LRUCache<std::string, std::string> c(0);
|
||||
c.upsert("foo", "bar");
|
||||
auto val = c.get("foo");
|
||||
ASSERT_EQ(val.has_value(), false);
|
||||
}
|
||||
|
||||
TEST(LRUCache, updateExistingValue) {
|
||||
LRUCache<std::string, std::string> c(1);
|
||||
c.upsert("foo", "bar");
|
||||
|
||||
auto val = c.get("foo");
|
||||
ASSERT_EQ(val.value_or("error"), "bar");
|
||||
ASSERT_EQ(c.size(), 1);
|
||||
|
||||
c.upsert("foo", "changed");
|
||||
val = c.get("foo");
|
||||
ASSERT_EQ(val.value_or("error"), "changed");
|
||||
ASSERT_EQ(c.size(), 1);
|
||||
}
|
||||
|
||||
TEST(LRUCache, overwriteOldestWhenCapacityIsReached) {
|
||||
LRUCache<std::string, std::string> c(3);
|
||||
c.upsert("one", "eins");
|
||||
c.upsert("two", "zwei");
|
||||
c.upsert("three", "drei");
|
||||
|
||||
ASSERT_EQ(c.size(), 3);
|
||||
ASSERT_EQ(c.get("one").value_or("error"), "eins");
|
||||
|
||||
// exceed capacity
|
||||
c.upsert("another", "whatever");
|
||||
|
||||
ASSERT_EQ(c.size(), 3);
|
||||
// Retrieving "one" makes it the most recent element thus
|
||||
// two will be the oldest one and thus replaced.
|
||||
ASSERT_EQ(c.get("two").has_value(), false);
|
||||
ASSERT_EQ(c.get("another").value(), "whatever");
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* clear
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(LRUCache, clearEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.clear();
|
||||
ASSERT_EQ(c.size(), 0);
|
||||
}
|
||||
|
||||
TEST(LRUCache, clearNonEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("one", "eins");
|
||||
c.upsert("two", "zwei");
|
||||
c.upsert("three", "drei");
|
||||
ASSERT_EQ(c.size(), 3);
|
||||
c.clear();
|
||||
ASSERT_EQ(c.size(), 0);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* erase
|
||||
* --------------------------------------------------------------------------*/
|
||||
|
||||
TEST(LRUCache, eraseFromEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
ASSERT_EQ(c.erase("foo"), false);
|
||||
ASSERT_EQ(c.size(), 0);
|
||||
}
|
||||
|
||||
TEST(LRUCache, eraseMissingFromNonEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("one", "eins");
|
||||
ASSERT_EQ(c.erase("foo"), false);
|
||||
ASSERT_EQ(c.size(), 1);
|
||||
ASSERT_EQ(c.get("one").value_or("error"), "eins");
|
||||
}
|
||||
|
||||
TEST(LRUCache, eraseFromNonEmptyCache) {
|
||||
LRUCache<std::string, std::string> c(10);
|
||||
c.upsert("one", "eins");
|
||||
ASSERT_EQ(c.erase("one"), true);
|
||||
ASSERT_EQ(c.size(), 0);
|
||||
ASSERT_EQ(c.get("one").value_or("empty"), "empty");
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
namespace nix {
|
||||
|
||||
std::regex refRegex(refRegexS, std::regex::ECMAScript);
|
||||
std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript);
|
||||
std::regex revRegex(revRegexS, std::regex::ECMAScript);
|
||||
std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript);
|
||||
|
||||
|
|
|
@ -49,6 +49,12 @@ const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRege
|
|||
const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
|
||||
extern std::regex refRegex;
|
||||
|
||||
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is
|
||||
// This is because of the definition of a ref in refs.c in https://github.com/git/git
|
||||
// See tests/fetchGitRefs.sh for the full definition
|
||||
const static std::string badGitRefRegexS = "//|^[./]|/\\.|\\.\\.|[[:cntrl:][:space:]:?^~\[]|\\\\|\\*|\\.lock$|\\.lock/|@\\{|[/.]$|^@$|^$";
|
||||
extern std::regex badGitRefRegex;
|
||||
|
||||
// A Git revision (a SHA-1 commit hash).
|
||||
const static std::string revRegexS = "[0-9a-fA-F]{40}";
|
||||
extern std::regex revRegex;
|
||||
|
|
|
@ -459,8 +459,7 @@ string base64Encode(const string & s);
|
|||
string base64Decode(const string & s);
|
||||
|
||||
|
||||
/* Get a value for the specified key from an associate container, or a
|
||||
default value if the key doesn't exist. */
|
||||
/* Get a value for the specified key from an associate container. */
|
||||
template <class T>
|
||||
std::optional<typename T::mapped_type> get(const T & map, const typename T::key_type & key)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue