···58585959- `_internalBase` (path):6060 Any files outside of this path cannot influence the set of files.6161- This is always a directory.6161+ This is always a directory and should be as long as possible.6262+ This is used by `lib.fileset.toSource` to check that all files are under the `root` argument62636364- `_internalBaseRoot` (path):6465 The filesystem root of `_internalBase`, same as `(lib.path.splitRoot _internalBase).root`.···144143 - (-) Leaves us with no identity element for `union` and no reasonable return value for `unions []`.145144 From a set theory perspective, which has a well-known notion of empty sets, this is unintuitive.146145146146+### No intersection for lists147147+148148+While there is `intersection a b`, there is no function `intersections [ a b c ]`.149149+150150+Arguments:151151+- (+) There is no known use case for such a function, it can be added later if a use case arises152152+- (+) There is no suitable return value for `intersections [ ]`, see also "Nullary intersections" [here](https://en.wikipedia.org/w/index.php?title=List_of_set_identities_and_relations&oldid=1177174035#Definitions)153153+ - (-) Could throw an error for that case154154+ - (-) Create a special value to represent "all the files" and return that155155+ - (+) Such a value could then not be used with `fileFilter` unless the internal representation is changed considerably156156+ - (-) Could return the empty file set157157+ - (+) This would be wrong in set theory158158+- (-) Inconsistent with `union` and `unions`159159+160160+### Intersection base path161161+162162+The base path of the result of an `intersection` is the longest base path of the arguments.163163+E.g. the base path of `intersection ./foo ./foo/bar` is `./foo/bar`.164164+Meanwhile `intersection ./foo ./bar` returns the empty file set without a base path.165165+166166+Arguments:167167+- Alternative: Use the common prefix of all base paths as the resulting base path168168+ - (-) This is unnecessarily strict, because the purpose of the base path is to track the directory under which files _could_ be in the file set. It should be as long as possible.169169+ All files contained in `intersection ./foo ./foo/bar` will be under `./foo/bar` (never just under `./foo`), and `intersection ./foo ./bar` will never contain any files (never under `./.`).170170+ This would lead to `toSource` having to unexpectedly throw errors for cases such as `toSource { root = ./foo; fileset = intersect ./foo base; }`, where `base` may be `./bar` or `./.`.171171+ - (-) There is no benefit to the user, since base path is not directly exposed in the interface172172+147173### Empty directories148174149149-File sets can only represent a _set_ of local files, directories on their own are not representable.175175+File sets can only represent a _set_ of local files.176176+Directories on their own are not representable.150177151178Arguments:152179- (+) There does not seem to be a sensible set of combinators when directories can be represented on their own.···190161191162 - `./.` represents all files in `./.` _and_ the directory itself, but not its subdirectories, meaning that at least `./.` will be preserved even if it's empty.192163193193- In that case, `intersect ./. ./foo` should only include files and no directories themselves, since `./.` includes only `./.` as a directory, and same for `./foo`, so there's no overlap in directories.164164+ In that case, `intersection ./. ./foo` should only include files and no directories themselves, since `./.` includes only `./.` as a directory, and same for `./foo`, so there's no overlap in directories.194165 But intuitively this operation should result in the same as `./foo` – everything else is just confusing.195166- (+) This matches how Git only supports files, so developers should already be used to it.196167- (-) Empty directories (even if they contain nested directories) are neither representable nor preserved when coercing from paths.
+41
lib/fileset/default.nix
···77 _toSourceFilter88 _unionMany99 _printFileset1010+ _intersection1011 ;11121213 inherit (builtins)···1918 ;20192120 inherit (lib.lists)2121+ elemAt2222 imap02323 ;2424···277275 (_coerceMany "lib.fileset.unions")278276 _unionMany279277 ];278278+279279+ /*280280+ The file set containing all files that are in both of two given file sets.281281+ See also [Intersection (set theory)](https://en.wikipedia.org/wiki/Intersection_(set_theory)).282282+283283+ The given file sets are evaluated as lazily as possible,284284+ with the first argument being evaluated first if needed.285285+286286+ Type:287287+ intersection :: FileSet -> FileSet -> FileSet288288+289289+ Example:290290+ # Limit the selected files to the ones in ./., so only ./src and ./Makefile291291+ intersection ./. (unions [ ../LICENSE ./src ./Makefile ])292292+ */293293+ intersection =294294+ # The first file set.295295+ # This argument can also be a path,296296+ # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).297297+ fileset1:298298+ # The second file set.299299+ # This argument can also be a path,300300+ # which gets [implicitly coerced to a file set](#sec-fileset-path-coercion).301301+ fileset2:302302+ let303303+ filesets = _coerceMany "lib.fileset.intersection" [304304+ {305305+ context = "first argument";306306+ value = fileset1;307307+ }308308+ {309309+ context = "second argument";310310+ value = fileset2;311311+ }312312+ ];313313+ in314314+ _intersection315315+ (elemAt filesets 0)316316+ (elemAt filesets 1);280317281318 /*282319 Incrementally evaluate and trace a file set in a pretty way.
+110-5
lib/fileset/internal.nix
···461461 else462462 nonEmpty;463463464464+ # Transforms the filesetTree of a file set to a shorter base path, e.g.465465+ # _shortenTreeBase [ "foo" ] (_create /foo/bar null)466466+ # => { bar = null; }467467+ _shortenTreeBase = targetBaseComponents: fileset:468468+ let469469+ recurse = index:470470+ # If we haven't reached the required depth yet471471+ if index < length fileset._internalBaseComponents then472472+ # Create an attribute set and recurse as the value, this can be lazily evaluated this way473473+ { ${elemAt fileset._internalBaseComponents index} = recurse (index + 1); }474474+ else475475+ # Otherwise we reached the appropriate depth, here's the original tree476476+ fileset._internalTree;477477+ in478478+ recurse (length targetBaseComponents);479479+480480+ # Transforms the filesetTree of a file set to a longer base path, e.g.481481+ # _lengthenTreeBase [ "foo" "bar" ] (_create /foo { bar.baz = "regular"; })482482+ # => { baz = "regular"; }483483+ _lengthenTreeBase = targetBaseComponents: fileset:484484+ let485485+ recurse = index: tree:486486+ # If the filesetTree is an attribute set and we haven't reached the required depth yet487487+ if isAttrs tree && index < length targetBaseComponents then488488+ # Recurse with the tree under the right component (which might not exist)489489+ recurse (index + 1) (tree.${elemAt targetBaseComponents index} or null)490490+ else491491+ # For all values here we can just return the tree itself:492492+ # tree == null -> the result is also null, everything is excluded493493+ # tree == "directory" -> the result is also "directory",494494+ # because the base path is always a directory and everything is included495495+ # isAttrs tree -> the result is `tree`496496+ # because we don't need to recurse any more since `index == length longestBaseComponents`497497+ tree;498498+ in499499+ recurse (length fileset._internalBaseComponents) fileset._internalTree;500500+464501 # Computes the union of a list of filesets.465502 # The filesets must already be coerced and validated to be in the same filesystem root466503 # Type: [ Fileset ] -> Fileset···534497 # So the tree under `/foo/bar` gets nested under `{ bar = ...; ... }`,535498 # while the tree under `/foo/baz` gets nested under `{ baz = ...; ... }`536499 # Therefore allowing combined operations over them.537537- trees = map (fileset:538538- setAttrByPath539539- (drop (length commonBaseComponents) fileset._internalBaseComponents)540540- fileset._internalTree541541- ) filesetsWithBase;500500+ trees = map (_shortenTreeBase commonBaseComponents) filesetsWithBase;542501543502 # Folds all trees together into a single one using _unionTree544503 # We do not use a fold here because it would cause a thunk build-up···566533 # The non-null elements have to be attribute sets representing partial trees567534 # We need to recurse into those568535 zipAttrsWith (name: _unionTrees) withoutNull;536536+537537+ # Computes the intersection of a list of filesets.538538+ # The filesets must already be coerced and validated to be in the same filesystem root539539+ # Type: Fileset -> Fileset -> Fileset540540+ _intersection = fileset1: fileset2:541541+ let542542+ # The common base components prefix, e.g.543543+ # (/foo/bar, /foo/bar/baz) -> /foo/bar544544+ # (/foo/bar, /foo/baz) -> /foo545545+ commonBaseComponentsLength =546546+ # TODO: Have a `lib.lists.commonPrefixLength` function such that we don't need the list allocation from commonPrefix here547547+ length (548548+ commonPrefix549549+ fileset1._internalBaseComponents550550+ fileset2._internalBaseComponents551551+ );552552+553553+ # To be able to intersect filesetTree's together, they need to have the same base path.554554+ # Base paths can be intersected by taking the longest one (if any)555555+556556+ # The fileset with the longest base, if any, e.g.557557+ # (/foo/bar, /foo/bar/baz) -> /foo/bar/baz558558+ # (/foo/bar, /foo/baz) -> null559559+ longestBaseFileset =560560+ if commonBaseComponentsLength == length fileset1._internalBaseComponents then561561+ # The common prefix is the same as the first path, so the second path is equal or longer562562+ fileset2563563+ else if commonBaseComponentsLength == length fileset2._internalBaseComponents then564564+ # The common prefix is the same as the second path, so the first path is longer565565+ fileset1566566+ else567567+ # The common prefix is neither the first nor the second path568568+ # This means there's no overlap between the two sets569569+ null;570570+571571+ # Whether the result should be the empty value without a base572572+ resultIsEmptyWithoutBase =573573+ # If either fileset is the empty fileset without a base, the intersection is too574574+ fileset1._internalIsEmptyWithoutBase575575+ || fileset2._internalIsEmptyWithoutBase576576+ # If there is no overlap between the base paths577577+ || longestBaseFileset == null;578578+579579+ # Lengthen each fileset's tree to the longest base prefix580580+ tree1 = _lengthenTreeBase longestBaseFileset._internalBaseComponents fileset1;581581+ tree2 = _lengthenTreeBase longestBaseFileset._internalBaseComponents fileset2;582582+583583+ # With two filesetTree's with the same base, we can compute their intersection584584+ resultTree = _intersectTree tree1 tree2;585585+ in586586+ if resultIsEmptyWithoutBase then587587+ _emptyWithoutBase588588+ else589589+ _create longestBaseFileset._internalBase resultTree;590590+591591+ # The intersection of two filesetTree's with the same base path592592+ # The second element is only evaluated as much as necessary.593593+ # Type: filesetTree -> filesetTree -> filesetTree594594+ _intersectTree = lhs: rhs:595595+ if isAttrs lhs && isAttrs rhs then596596+ # Both sides are attribute sets, we can recurse for the attributes existing on both sides597597+ mapAttrs598598+ (name: _intersectTree lhs.${name})599599+ (builtins.intersectAttrs lhs rhs)600600+ else if lhs == null || isString rhs then601601+ # If the lhs is null, the result should also be null602602+ # And if the rhs is the identity element603603+ # (a string, aka it includes everything), then it's also the lhs604604+ lhs605605+ else606606+ # In all other cases it's the rhs607607+ rhs;569608}
+95
lib/fileset/tests.sh
···587587# So, just using 1000 files for now.588588checkFileset 'unions (mapAttrsToList (name: _: ./. + "/${name}/a") (builtins.readDir ./.))'589589590590+591591+## lib.fileset.intersection592592+593593+594594+# Different filesystem roots in root and fileset are not supported595595+mkdir -p {foo,bar}/mock-root596596+expectFailure 'with ((import <nixpkgs/lib>).extend (import <nixpkgs/lib/fileset/mock-splitRoot.nix>)).fileset;597597+ toSource { root = ./.; fileset = intersection ./foo/mock-root ./bar/mock-root; }598598+' 'lib.fileset.intersection: Filesystem roots are not the same:599599+\s*first argument: root "'"$work"'/foo/mock-root"600600+\s*second argument: root "'"$work"'/bar/mock-root"601601+\s*Different roots are not supported.'602602+rm -rf -- *603603+604604+# Coercion errors show the correct context605605+expectFailure 'toSource { root = ./.; fileset = intersection ./a ./.; }' 'lib.fileset.intersection: first argument \('"$work"'/a\) does not exist.'606606+expectFailure 'toSource { root = ./.; fileset = intersection ./. ./b; }' 'lib.fileset.intersection: second argument \('"$work"'/b\) does not exist.'607607+608608+# The tree of later arguments should not be evaluated if a former argument already excludes all files609609+tree=(610610+ [a]=0611611+)612612+checkFileset 'intersection _emptyWithoutBase (_create ./. (abort "This should not be used!"))'613613+# We don't have any combinators that can explicitly remove files yet, so we need to rely on internal functions to test this for now614614+checkFileset 'intersection (_create ./. { a = null; }) (_create ./. { a = abort "This should not be used!"; })'615615+616616+# If either side is empty, the result is empty617617+tree=(618618+ [a]=0619619+)620620+checkFileset 'intersection _emptyWithoutBase _emptyWithoutBase'621621+checkFileset 'intersection _emptyWithoutBase (_create ./. null)'622622+checkFileset 'intersection (_create ./. null) _emptyWithoutBase'623623+checkFileset 'intersection (_create ./. null) (_create ./. null)'624624+625625+# If the intersection base paths are not overlapping, the result is empty and has no base path626626+mkdir a b c627627+touch {a,b,c}/x628628+expectEqual 'toSource { root = ./c; fileset = intersection ./a ./b; }' 'toSource { root = ./c; fileset = _emptyWithoutBase; }'629629+rm -rf -- *630630+631631+# If the intersection exists, the resulting base path is the longest of them632632+mkdir a633633+touch x a/b634634+expectEqual 'toSource { root = ./a; fileset = intersection ./a ./.; }' 'toSource { root = ./a; fileset = ./a; }'635635+expectEqual 'toSource { root = ./a; fileset = intersection ./. ./a; }' 'toSource { root = ./a; fileset = ./a; }'636636+rm -rf -- *637637+638638+# Also finds the intersection with null'd filesetTree's639639+tree=(640640+ [a]=0641641+ [b]=1642642+ [c]=0643643+)644644+checkFileset 'intersection (_create ./. { a = "regular"; b = "regular"; c = null; }) (_create ./. { a = null; b = "regular"; c = "regular"; })'645645+646646+# Actually computes the intersection between files647647+tree=(648648+ [a]=0649649+ [b]=0650650+ [c]=1651651+ [d]=1652652+ [e]=0653653+ [f]=0654654+)655655+checkFileset 'intersection (unions [ ./a ./b ./c ./d ]) (unions [ ./c ./d ./e ./f ])'656656+657657+tree=(658658+ [a/x]=0659659+ [a/y]=0660660+ [b/x]=1661661+ [b/y]=1662662+ [c/x]=0663663+ [c/y]=0664664+)665665+checkFileset 'intersection ./b ./.'666666+checkFileset 'intersection ./b (unions [ ./a/x ./a/y ./b/x ./b/y ./c/x ./c/y ])'667667+668668+# Complicated case669669+tree=(670670+ [a/x]=0671671+ [a/b/i]=1672672+ [c/d/x]=0673673+ [c/d/f]=1674674+ [c/x]=0675675+ [c/e/i]=1676676+ [c/e/j]=1677677+)678678+checkFileset 'intersection (unions [ ./a/b ./c/d ./c/e ]) (unions [ ./a ./c/d/f ./c/e ])'679679+680680+590681## Tracing591682592683# The second trace argument is returned···700609# The empty file set without a base also prints as empty701610expectTrace '_emptyWithoutBase' '(empty)'702611expectTrace 'unions [ ]' '(empty)'612612+mkdir foo bar613613+touch {foo,bar}/x614614+expectTrace 'intersection ./foo ./bar' '(empty)'615615+rm -rf -- *703616704617# If a directory is fully included, print it as such705618touch a
···11+{ lib22+, nix-update-script33+, python344+, fetchFromGitHub55+, cmake66+, ninja77+}:88+let99+ tree-sitter-bitbake = fetchFromGitHub {1010+ owner = "amaanq";1111+ repo = "tree-sitter-bitbake";1212+ rev = "v1.0.0";1313+ hash = "sha256-HfWUDYiBCmtlu5fFX287BSDHyCiD7gqIVFDTxH5APAE=";1414+ };1515+in1616+python3.pkgs.buildPythonApplication rec {1717+ pname = "bitbake-language-server";1818+ version = "0.0.6";1919+ format = "pyproject";2020+2121+ src = fetchFromGitHub {2222+ owner = "Freed-Wu";2323+ repo = pname;2424+ rev = version;2525+ hash = "sha256-UOeOvaQplDn7jM+3sUZip1f05TbczoaRQKMxVm+euDU=";2626+ };2727+2828+ nativeBuildInputs = with python3.pkgs; [2929+ cmake3030+ ninja3131+ pathspec3232+ pyproject-metadata3333+ scikit-build-core3434+ setuptools-scm3535+ ];3636+3737+ propagatedBuildInputs = with python3.pkgs; [3838+ lsprotocol3939+ platformdirs4040+ pygls4141+ tree-sitter4242+ ];4343+4444+ SETUPTOOLS_SCM_PRETEND_VERSION = version;4545+4646+ # The scikit-build-core runs CMake internally so we must let it run the configure step itself.4747+ dontUseCmakeConfigure = true;4848+ SKBUILD_CMAKE_ARGS = lib.strings.concatStringsSep ";" [4949+ "-DFETCHCONTENT_FULLY_DISCONNECTED=ON"5050+ "-DFETCHCONTENT_QUIET=OFF"5151+ "-DFETCHCONTENT_SOURCE_DIR_TREE-SITTER-BITBAKE=${tree-sitter-bitbake}"5252+ ];5353+5454+ passthru.updateScript = nix-update-script { };5555+5656+ meta = with lib; {5757+ description = "Language server for bitbake";5858+ homepage = "https://github.com/Freed-Wu/bitbake-language-server";5959+ changelog = "https://github.com/Freed-Wu/bitbake-language-server/releases/tag/v${version}";6060+ license = licenses.gpl3;6161+ maintainers = with maintainers; [ otavio ];6262+ };6363+}
+1-1
pkgs/data/fonts/last-resort/default.nix
···2323 description = "Fallback font of last resort";2424 homepage = "https://github.com/unicode-org/last-resort-font";2525 license = licenses.ofl;2626- maintainers = with maintainers; [ V ];2626+ maintainers = with maintainers; [ ];2727 };2828}
···438438 blasProvider = blas.provider;439439 # To help debug when a package is broken due to CUDA support440440 inherit brokenConditions;441441- } // lib.optionalAttrs cudaSupport {442442- # NOTE: supportedCudaCapabilities isn't computed unless cudaSupport is true, so we can't use443443- # it in the passthru set above because a downstream package might try to access it even444444- # when cudaSupport is false. Better to have it missing than null or an empty list by default.445445- cudaCapabilities = supportedCudaCapabilities;441441+ cudaCapabilities = if cudaSupport then supportedCudaCapabilities else [ ];446442 };447443448444 meta = with lib; {
···11+{ lib22+, stdenv33+, fetchCrate44+, rustPlatform55+, Security66+}:77+88+rustPlatform.buildRustPackage rec {99+ pname = "cargo-bazel";1010+ version = "0.8.0";1111+1212+ src = fetchCrate {1313+ inherit pname version;1414+ sha256 = "FS1WFlK0YNq1QCi3S3f5tMN+Bdcfx2dxhDKRLXLcios=";1515+ };1616+1717+ cargoSha256 = "+PVNB/apG5AR236Ikqt+JTz20zxc0HUi7z6BU6xq/Fw=";1818+1919+ buildInputs = lib.optional stdenv.isDarwin Security;2020+2121+ # `test_data` is explicitly excluded from the package published to crates.io, so tests cannot be run2222+ doCheck = false;2323+2424+ meta = with lib; {2525+ description = "Part of the `crate_universe` collection of tools which use Cargo to generate build targets for Bazel";2626+ homepage = "https://github.com/bazelbuild/rules_rust";2727+ license = licenses.asl20;2828+ maintainers = with maintainers; [ rickvanprim ];2929+ };3030+}