mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Packages (nix): use hash to cache count and process count manually (#817)
This commit is contained in:
@@ -118,28 +118,152 @@ static uint32_t countFilesRecursive(FFstrbuf* baseDir, const char* dirname, cons
|
||||
return sum;
|
||||
}
|
||||
|
||||
static bool isValidNixPkg(FFstrbuf* pkg)
|
||||
{
|
||||
if (!ffPathExists(pkg->chars, FF_PATHTYPE_DIRECTORY))
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrAfterLastC(pkg, '/');
|
||||
if (
|
||||
ffStrbufStartsWithS(pkg, "nixos-system-nixos-") ||
|
||||
ffStrbufEndsWithS(pkg, "-doc") ||
|
||||
ffStrbufEndsWithS(pkg, "-man") ||
|
||||
ffStrbufEndsWithS(pkg, "-info") ||
|
||||
ffStrbufEndsWithS(pkg, "-dev") ||
|
||||
ffStrbufEndsWithS(pkg, "-bin")
|
||||
) return false;
|
||||
|
||||
enum { START, DIGIT, DOT, MATCH } state = START;
|
||||
|
||||
for (uint32_t i = 0; i < pkg->length; i++)
|
||||
{
|
||||
char c = pkg->chars[i];
|
||||
switch (state)
|
||||
{
|
||||
case START:
|
||||
if (c >= '0' && c <= '9')
|
||||
state = DIGIT;
|
||||
break;
|
||||
case DIGIT:
|
||||
if (c >= '0' && c <= '9')
|
||||
continue;
|
||||
if (c == '.')
|
||||
state = DOT;
|
||||
else
|
||||
state = START;
|
||||
break;
|
||||
case DOT:
|
||||
if (c >= '0' && c <= '9')
|
||||
state = MATCH;
|
||||
else
|
||||
state = START;
|
||||
break;
|
||||
case MATCH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return state == MATCH;
|
||||
}
|
||||
|
||||
static bool checkNixCache(FFstrbuf* cacheDir, FFstrbuf* hash, uint32_t* count)
|
||||
{
|
||||
if (!ffPathExists(cacheDir->chars, FF_PATHTYPE_FILE))
|
||||
return false;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY cacheContent;
|
||||
ffStrbufInit(&cacheContent);
|
||||
if (!ffReadFileBuffer(cacheDir->chars, &cacheContent))
|
||||
return false;
|
||||
|
||||
// Format: <hash>\n<count>
|
||||
uint32_t split = ffStrbufFirstIndexC(&cacheContent, '\n');
|
||||
if (split == cacheContent.length)
|
||||
return false;
|
||||
|
||||
ffStrbufSetNS(hash, split, cacheContent.chars);
|
||||
*count = (uint32_t)atoi(cacheContent.chars + split + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool writeNixCache(FFstrbuf* cacheDir, FFstrbuf* hash, uint32_t count)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY cacheContent;
|
||||
ffStrbufInit(&cacheContent);
|
||||
ffStrbufAppend(&cacheContent, hash);
|
||||
ffStrbufAppendC(&cacheContent, '\n');
|
||||
ffStrbufAppendF(&cacheContent, "%u", count);
|
||||
return ffWriteFileBuffer(cacheDir->chars, &cacheContent);
|
||||
}
|
||||
|
||||
static uint32_t getNixPackagesImpl(char* path)
|
||||
{
|
||||
//Nix detection is kinda slow, so we only do it if the dir exists
|
||||
if(!ffPathExists(path, FF_PATHTYPE_DIRECTORY))
|
||||
return 0;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(128);
|
||||
FF_STRBUF_AUTO_DESTROY cacheDir;
|
||||
ffStrbufInit(&cacheDir);
|
||||
ffStrbufAppend(&cacheDir, &instance.state.platform.cacheDir);
|
||||
ffStrbufEnsureEndsWithC(&cacheDir, '/');
|
||||
ffStrbufAppendS(&cacheDir, "fastfetch/packages/nix");
|
||||
ffStrbufAppendS(&cacheDir, path);
|
||||
|
||||
//https://github.com/fastfetch-cli/fastfetch/issues/195#issuecomment-1191748222
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(255);
|
||||
ffStrbufAppendS(&command, "for x in $(nix-store --query --requisites ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, "); do if [ -d $x ]; then echo $x ; fi ; done | cut -d- -f2- | egrep '([0-9]{1,}\\.)+[0-9]{1,}' | egrep -v '\\-doc$|\\-man$|\\-info$|\\-dev$|\\-bin$|^nixos-system-nixos-' | uniq | wc -l");
|
||||
//Check the hash first to determine if we need to recompute the count
|
||||
FF_STRBUF_AUTO_DESTROY hash = ffStrbufCreateA(64);
|
||||
FF_STRBUF_AUTO_DESTROY cacheHash = ffStrbufCreateA(64);
|
||||
uint32_t count = 0;
|
||||
|
||||
ffProcessAppendStdOut(&output, (char* const[]) {
|
||||
"sh",
|
||||
"-c",
|
||||
command.chars,
|
||||
ffProcessAppendStdOut(&hash, (char* const[]) {
|
||||
"nix-store",
|
||||
"--query",
|
||||
"--hash",
|
||||
path,
|
||||
NULL
|
||||
});
|
||||
|
||||
return (uint32_t) strtol(output.chars, NULL, 10);
|
||||
if (checkNixCache(&cacheDir, &cacheHash, &count) && ffStrbufEqual(&hash, &cacheHash))
|
||||
return count;
|
||||
|
||||
//Cache is invalid, recompute the count
|
||||
count = 0;
|
||||
|
||||
//Implementation based on bash script from here:
|
||||
//https://github.com/fastfetch-cli/fastfetch/issues/195#issuecomment-1191748222
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA(1024);
|
||||
|
||||
ffProcessAppendStdOut(&output, (char* const[]) {
|
||||
"nix-store",
|
||||
"--query",
|
||||
"--requisites",
|
||||
path,
|
||||
NULL
|
||||
});
|
||||
|
||||
uint32_t lineLength = 0;
|
||||
for (uint32_t i = 0; i < output.length; i++)
|
||||
{
|
||||
if (output.chars[i] != '\n')
|
||||
{
|
||||
lineLength++;
|
||||
continue;
|
||||
}
|
||||
|
||||
output.chars[i] = '\0';
|
||||
FFstrbuf line = {
|
||||
.allocated = 0,
|
||||
.length = lineLength,
|
||||
.chars = output.chars + i - lineLength
|
||||
};
|
||||
if (isValidNixPkg(&line))
|
||||
count++;
|
||||
lineLength = 0;
|
||||
}
|
||||
|
||||
writeNixCache(&cacheDir, &hash, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static uint32_t getNixPackages(FFstrbuf* baseDir, const char* dirname)
|
||||
|
||||
Reference in New Issue
Block a user