mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-19 11:23:29 +00:00
Merge staging-next into staging
This commit is contained in:
commit
873ee0b8e8
@ -1256,7 +1256,7 @@ let
|
||||
(opt.highestPrio or defaultOverridePriority)
|
||||
(f opt.value);
|
||||
|
||||
doRename = { from, to, visible, warn, use, withPriority ? true }:
|
||||
doRename = { from, to, visible, warn, use, withPriority ? true, condition ? true }:
|
||||
{ config, options, ... }:
|
||||
let
|
||||
fromOpt = getAttrFromPath from options;
|
||||
@ -1272,7 +1272,7 @@ let
|
||||
} // optionalAttrs (toType != null) {
|
||||
type = toType;
|
||||
});
|
||||
config = mkMerge [
|
||||
config = mkIf condition (mkMerge [
|
||||
(optionalAttrs (options ? warnings) {
|
||||
warnings = optional (warn && fromOpt.isDefined)
|
||||
"The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
|
||||
@ -1280,7 +1280,7 @@ let
|
||||
(if withPriority
|
||||
then mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt
|
||||
else mkAliasAndWrapDefinitions (setAttrByPath to) fromOpt)
|
||||
];
|
||||
]);
|
||||
};
|
||||
|
||||
/* Use this function to import a JSON file as NixOS configuration.
|
||||
|
@ -465,6 +465,9 @@ checkConfigOutput '^1234$' config.c.d.e ./doRename-basic.nix
|
||||
checkConfigOutput '^"The option `a\.b. defined in `.*/doRename-warnings\.nix. has been renamed to `c\.d\.e.\."$' \
|
||||
config.result \
|
||||
./doRename-warnings.nix
|
||||
checkConfigOutput "^true$" config.result ./doRename-condition.nix ./doRename-condition-enable.nix
|
||||
checkConfigOutput "^true$" config.result ./doRename-condition.nix ./doRename-condition-no-enable.nix
|
||||
checkConfigOutput "^true$" config.result ./doRename-condition.nix ./doRename-condition-migrated.nix
|
||||
|
||||
# Anonymous modules get deduplicated by key
|
||||
checkConfigOutput '^"pear"$' config.once.raw ./merge-module-with-key.nix
|
||||
|
10
lib/tests/modules/doRename-condition-enable.nix
Normal file
10
lib/tests/modules/doRename-condition-enable.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config = {
|
||||
services.foo.enable = true;
|
||||
services.foo.bar = "baz";
|
||||
result =
|
||||
assert config.services.foos == { "" = { bar = "baz"; }; };
|
||||
true;
|
||||
};
|
||||
}
|
10
lib/tests/modules/doRename-condition-migrated.nix
Normal file
10
lib/tests/modules/doRename-condition-migrated.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
config = {
|
||||
services.foos."".bar = "baz";
|
||||
result =
|
||||
assert config.services.foos == { "" = { bar = "baz"; }; };
|
||||
assert config.services.foo.bar == "baz";
|
||||
true;
|
||||
};
|
||||
}
|
9
lib/tests/modules/doRename-condition-no-enable.nix
Normal file
9
lib/tests/modules/doRename-condition-no-enable.nix
Normal file
@ -0,0 +1,9 @@
|
||||
{ config, lib, options, ... }:
|
||||
{
|
||||
config = {
|
||||
result =
|
||||
assert config.services.foos == { };
|
||||
assert ! options.services.foo.bar.isDefined;
|
||||
true;
|
||||
};
|
||||
}
|
42
lib/tests/modules/doRename-condition.nix
Normal file
42
lib/tests/modules/doRename-condition.nix
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Simulate a migration from a single-instance `services.foo` to a multi instance
|
||||
`services.foos.<name>` module, where `name = ""` serves as the legacy /
|
||||
compatibility instance.
|
||||
|
||||
- No instances must exist, unless one is defined in the multi-instance module,
|
||||
or if the legacy enable option is set to true.
|
||||
- The legacy instance options must be renamed to the new instance, if it exists.
|
||||
|
||||
The relevant scenarios are tested in separate files:
|
||||
- ./doRename-condition-enable.nix
|
||||
- ./doRename-condition-no-enable.nix
|
||||
*/
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib) mkOption mkEnableOption types doRename;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.foo.enable = mkEnableOption "foo";
|
||||
services.foos = mkOption {
|
||||
type = types.attrsOf (types.submodule {
|
||||
options = {
|
||||
bar = mkOption { type = types.str; };
|
||||
};
|
||||
});
|
||||
default = { };
|
||||
};
|
||||
result = mkOption {};
|
||||
};
|
||||
imports = [
|
||||
(doRename {
|
||||
from = [ "services" "foo" "bar" ];
|
||||
to = [ "services" "foos" "" "bar" ];
|
||||
visible = true;
|
||||
warn = false;
|
||||
use = x: x;
|
||||
withPriority = true;
|
||||
condition = config.services.foo.enable;
|
||||
})
|
||||
];
|
||||
}
|
@ -100,9 +100,11 @@ moonscript,https://github.com/leafo/moonscript.git,dev-1,,,,arobyn
|
||||
nlua,,,,,,teto
|
||||
nui.nvim,,,,,,mrcjkb
|
||||
nvim-cmp,https://github.com/hrsh7th/nvim-cmp,,,,,
|
||||
nvim-nio,,,,,,mrcjkb
|
||||
penlight,https://github.com/lunarmodules/Penlight.git,,,,,alerque
|
||||
plenary.nvim,https://github.com/nvim-lua/plenary.nvim.git,,,,5.1,
|
||||
rapidjson,https://github.com/xpol/lua-rapidjson.git,,,,,
|
||||
rocks.nvim,,,,,5.1,teto mrcjkb
|
||||
rest.nvim,,,,,5.1,teto
|
||||
rustaceanvim,,,,,,mrcjkb
|
||||
say,https://github.com/Olivine-Labs/say.git,,,,,
|
||||
|
|
@ -14,6 +14,15 @@ let
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
imports = [
|
||||
(mkRemovedOptionModule [ "services" "rabbitmq" "cookie" ] ''
|
||||
This option wrote the Erlang cookie to the store, while it should be kept secret.
|
||||
Please remove it from your NixOS configuration and deploy a cookie securely instead.
|
||||
The renamed `unsafeCookie` must ONLY be used in isolated non-production environments such as NixOS VM tests.
|
||||
'')
|
||||
];
|
||||
|
||||
###### interface
|
||||
options = {
|
||||
services.rabbitmq = {
|
||||
@ -62,13 +71,18 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
cookie = mkOption {
|
||||
unsafeCookie = mkOption {
|
||||
default = "";
|
||||
type = types.str;
|
||||
description = lib.mdDoc ''
|
||||
Erlang cookie is a string of arbitrary length which must
|
||||
be the same for several nodes to be allowed to communicate.
|
||||
Leave empty to generate automatically.
|
||||
|
||||
Setting the cookie via this option exposes the cookie to the store, which
|
||||
is not recommended for security reasons.
|
||||
Only use this option in an isolated non-production environment such as
|
||||
NixOS VM tests.
|
||||
'';
|
||||
};
|
||||
|
||||
@ -209,9 +223,8 @@ in
|
||||
};
|
||||
|
||||
preStart = ''
|
||||
${optionalString (cfg.cookie != "") ''
|
||||
echo -n ${cfg.cookie} > ${cfg.dataDir}/.erlang.cookie
|
||||
chmod 600 ${cfg.dataDir}/.erlang.cookie
|
||||
${optionalString (cfg.unsafeCookie != "") ''
|
||||
install -m 600 <(echo -n ${cfg.unsafeCookie}) ${cfg.dataDir}/.erlang.cookie
|
||||
''}
|
||||
'';
|
||||
};
|
||||
|
@ -17,15 +17,6 @@ version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
@ -163,6 +154,12 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||
|
||||
[[package]]
|
||||
name = "block"
|
||||
version = "0.1.6"
|
||||
@ -355,6 +352,7 @@ dependencies = [
|
||||
"printer",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"subprocess",
|
||||
"tokio",
|
||||
@ -568,6 +566,12 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dunce"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
@ -604,6 +608,16 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "extracted_fzy"
|
||||
version = "0.1.0"
|
||||
@ -783,7 +797,7 @@ version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b989d6a7ca95a362cf2cfc5ad688b3a467be1f87e480b8dad07fee8c79b0044"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"libgit2-sys",
|
||||
"log",
|
||||
@ -796,7 +810,7 @@ version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d"
|
||||
dependencies = [
|
||||
"aho-corasick 1.1.2",
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
@ -805,40 +819,38 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "grep-matcher"
|
||||
version = "0.1.6"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3902ca28f26945fe35cad349d776f163981d777fee382ccd6ef451126f51b319"
|
||||
checksum = "47a3141a10a43acfedc7c98a60a834d7ba00dfe7bec9071cbfc19b55b292ac02"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grep-regex"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "997598b41d53a37a2e3fc5300d5c11d825368c054420a9c65125b8fe1078463f"
|
||||
checksum = "f748bb135ca835da5cbc67ca0e6955f968db9c5df74ca4f56b18e1ddbc68230d"
|
||||
dependencies = [
|
||||
"aho-corasick 0.7.20",
|
||||
"bstr",
|
||||
"grep-matcher",
|
||||
"log",
|
||||
"regex",
|
||||
"regex-syntax 0.6.29",
|
||||
"thread_local",
|
||||
"regex-automata 0.4.3",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "grep-searcher"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5601c4b9f480f0c9ebb40b1f6cbf447b8a50c5369223937a6c5214368c58779f"
|
||||
checksum = "ba536ae4f69bec62d8839584dd3153d3028ef31bb229f04e09fb5a9e5a193c54"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"bytecount",
|
||||
"encoding_rs",
|
||||
"encoding_rs_io",
|
||||
"grep-matcher",
|
||||
"log",
|
||||
"memchr",
|
||||
"memmap2",
|
||||
]
|
||||
|
||||
@ -1203,6 +1215,12 @@ version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
@ -1219,6 +1237,19 @@ version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.94.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66bfd44a06ae10647fe3f8214762e9369fd4248df1350924b4ef9e770a85ea1"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
@ -1230,7 +1261,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "maple"
|
||||
version = "0.1.49"
|
||||
version = "0.1.50"
|
||||
dependencies = [
|
||||
"built",
|
||||
"chrono",
|
||||
@ -1263,6 +1294,7 @@ dependencies = [
|
||||
"ignore",
|
||||
"itertools",
|
||||
"maple_derive",
|
||||
"maple_lsp",
|
||||
"matcher",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
@ -1276,6 +1308,7 @@ dependencies = [
|
||||
"rpc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strsim",
|
||||
"sublime_syntax",
|
||||
"subprocess",
|
||||
"thiserror",
|
||||
@ -1301,6 +1334,23 @@ dependencies = [
|
||||
"types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maple_lsp"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"lsp-types",
|
||||
"parking_lot",
|
||||
"paths",
|
||||
"rpc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matcher"
|
||||
version = "0.1.0"
|
||||
@ -1331,9 +1381,9 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.10"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327"
|
||||
checksum = "deaba38d7abf1d4cca21cc89e932e542ba2b9258664d2a9ef0e61512039c9375"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -1394,7 +1444,7 @@ version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset 0.7.1",
|
||||
@ -1485,7 +1535,7 @@ version = "6.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"onig_sys",
|
||||
@ -1535,6 +1585,7 @@ name = "paths"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"dunce",
|
||||
"itertools",
|
||||
"serde",
|
||||
]
|
||||
@ -1663,7 +1714,7 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1672,7 +1723,7 @@ version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1692,7 +1743,7 @@ version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick 1.1.2",
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.3",
|
||||
"regex-syntax 0.8.2",
|
||||
@ -1713,7 +1764,7 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick 1.1.2",
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
@ -1813,6 +1864,19 @@ version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.8"
|
||||
@ -1921,6 +1985,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.4"
|
||||
@ -2053,7 +2128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e02b4b303bf8d08bfeb0445cba5068a3d306b6baece1d5582171a9bf49188f91"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"flate2",
|
||||
"fnv",
|
||||
"once_cell",
|
||||
@ -2073,7 +2148,7 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
@ -2471,6 +2546,9 @@ name = "tree_sitter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"toml 0.5.11",
|
||||
"tree-sitter",
|
||||
"tree-sitter-bash",
|
||||
"tree-sitter-c",
|
||||
@ -2553,6 +2631,7 @@ dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2707,6 +2786,19 @@ version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bf3ea8596f3a0dd5980b46430f2058dfe2c36a27ccfbb1845d6fbfcd9ba6e14"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -2774,6 +2866,15 @@ dependencies = [
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
@ -2804,6 +2905,21 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -2816,6 +2932,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
@ -2828,6 +2950,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
@ -2840,6 +2968,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
@ -2852,6 +2986,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
@ -2864,6 +3004,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
@ -2876,6 +3022,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
@ -2888,6 +3040,12 @@ version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.18"
|
||||
|
@ -11,13 +11,13 @@
|
||||
}:
|
||||
|
||||
let
|
||||
version = "0.49";
|
||||
version = "0.50";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "liuchengxu";
|
||||
repo = "vim-clap";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-xir0v3SzfkxNXKR6N7Rso0QFtVQIRfu0TIPGWSEwsHM=";
|
||||
hash = "sha256-EYAylATdtwDzM92tN4OlzbQ1XqErRwT9mCNpzj63oxk=";
|
||||
};
|
||||
|
||||
meta = with lib; {
|
||||
|
@ -61,8 +61,8 @@ rec {
|
||||
};
|
||||
|
||||
kops_1_28 = mkKops rec {
|
||||
version = "1.28.3";
|
||||
sha256 = "sha256-pkHTVAssNDjMHpdRxqPCNwG2of8TKIzZN0uqk+hPZSA=";
|
||||
version = "1.28.4";
|
||||
sha256 = "sha256-nknsrLdV7tQKLOir5RM3LRhTS+dyiAc1GjbByJzjwCo=";
|
||||
rev = "v${version}";
|
||||
};
|
||||
}
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "appflowy";
|
||||
version = "0.4.3";
|
||||
version = "0.4.6";
|
||||
|
||||
src = fetchzip {
|
||||
url = "https://github.com/AppFlowy-IO/appflowy/releases/download/${version}/AppFlowy-${version}-linux-x86_64.tar.gz";
|
||||
hash = "sha256-JrcqVPlFr8zD9ZSBxk9WqN7KCLKq+yCjMfA4QbIfDZE=";
|
||||
hash = "sha256-496uXlJ/3ID8fnW/LKwk0Waca4gSQBuKIFMJ4EJGcsA=";
|
||||
stripRoot = false;
|
||||
};
|
||||
|
||||
|
@ -40,5 +40,7 @@ python3Packages.buildPythonApplication rec {
|
||||
license = lib.licenses.gpl2Plus;
|
||||
platforms = lib.platforms.linux;
|
||||
maintainers = [ lib.maintainers.mathnerd314 ];
|
||||
# ModuleNotFoundError: No module named 'rabbitvcs'
|
||||
broken = true; # Added 2024-01-28
|
||||
};
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
buildDotnetGlobalTool {
|
||||
pname = "csharpier";
|
||||
version = "0.27.0";
|
||||
version = "0.27.2";
|
||||
executables = "dotnet-csharpier";
|
||||
|
||||
nugetSha256 = "sha256-aI8sZoUXAA/bOn7ITMkBFXHeTVRm9O/qX+bWfOKwRDs=";
|
||||
nugetSha256 = "sha256-P4v4h09FuisIry9B/6batrG0CpLqnrkxnlk1yEd1JbY=";
|
||||
|
||||
meta = with lib; {
|
||||
description = "An opinionated code formatter for C#";
|
||||
|
@ -5,19 +5,22 @@
|
||||
|
||||
python3.pkgs.buildPythonApplication rec {
|
||||
pname = "gcp-scanner";
|
||||
version = "1.3.0";
|
||||
version = "1.4.0";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "google";
|
||||
repo = "gcp_scanner";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-mMvAoqwptCA73JiUl8HIhFBO198NnUmvCbf8Rk9dWxA=";
|
||||
hash = "sha256-6bIrSaTqpXQjB64YWAI64DlgQBD2XD+zMvKymMtwpDk=";
|
||||
};
|
||||
|
||||
pythonRelaxDeps = true;
|
||||
|
||||
nativeBuildInputs = with python3.pkgs; [
|
||||
setuptools
|
||||
setuptools-git-versioning
|
||||
pythonRelaxDepsHook
|
||||
];
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
|
@ -6,16 +6,16 @@
|
||||
|
||||
let
|
||||
pname = "lefthook";
|
||||
version = "1.5.7";
|
||||
version = "1.6.1";
|
||||
in
|
||||
buildGoModule rec {
|
||||
buildGoModule {
|
||||
inherit pname version;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "evilmartians";
|
||||
repo = "lefthook";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-0z4hTx9ClGh20Ncf23SbwuPBdGoFz80FQUx7s77l7y8=";
|
||||
hash = "sha256-015tIgu9L62uZm4ae1JzU/GAK6fwX8BI9HGYhc+4jQQ=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-/VLS7+nPERjIU7V2CzqXH69Z3/y+GKZbAFn+KcRKRuA=";
|
||||
|
48
pkgs/by-name/nm/nmap-parse/package.nix
Normal file
48
pkgs/by-name/nm/nmap-parse/package.nix
Normal file
@ -0,0 +1,48 @@
|
||||
{ lib
|
||||
, fetchFromGitHub
|
||||
, python3
|
||||
}:
|
||||
|
||||
python3.pkgs.buildPythonApplication rec {
|
||||
pname = "nmap-parse";
|
||||
version = "0-unstable-2022-09-26";
|
||||
format = "other";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "jonny1102";
|
||||
repo = "nmap-parse";
|
||||
# https://github.com/jonny1102/nmap-parse/issues/12
|
||||
rev = "ae270ac9ce05bfbe822dbbb29411adf562d40abf";
|
||||
hash = "sha256-iaE4a5blbDPaKPRnR46+AfegXOEW88i+z/VIVGCepeM=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = with python3.pkgs; [
|
||||
beautifulsoup4
|
||||
cmd2
|
||||
colorama
|
||||
ipy
|
||||
tabulate
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -Dm 755 "nmap-parse.py" "$out/bin/nmap-parse"
|
||||
|
||||
install -vd $out/${python3.sitePackages}/
|
||||
cp -R modules $out/${python3.sitePackages}
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
# Project has no tests
|
||||
doCheck = false;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Command line nmap XML parser";
|
||||
homepage = "https://github.com/jonny1102/nmap-parse";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ fab ];
|
||||
mainProgram = "nmap-parse";
|
||||
};
|
||||
}
|
32
pkgs/by-name/np/np/package.nix
Normal file
32
pkgs/by-name/np/np/package.nix
Normal file
@ -0,0 +1,32 @@
|
||||
{ lib
|
||||
, buildGoModule
|
||||
, fetchFromGitHub
|
||||
}:
|
||||
|
||||
buildGoModule rec {
|
||||
pname = "np";
|
||||
version = "0.11.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "leesoh";
|
||||
repo = "np";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-4krjQi/zEC4a+CjacgbnQIMKKFVr6H2FSwRVB6pkHf0=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-rSg4YFLZdtyC/tm/EULyt7r0O9PXI72W8y6/ltDSbj4=";
|
||||
|
||||
ldflags = [
|
||||
"-s"
|
||||
"-w"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "A tool to parse, deduplicate, and query multiple port scans";
|
||||
homepage = "https://github.com/leesoh/np";
|
||||
changelog = "https://github.com/leesoh/np/releases/tag/v${version}";
|
||||
license = licenses.agpl3Only;
|
||||
maintainers = with maintainers; [ fab ];
|
||||
mainProgram = "np";
|
||||
};
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
python3Packages.buildPythonApplication rec {
|
||||
pname = "pyprland";
|
||||
version = "1.7.1";
|
||||
version = "1.8.7";
|
||||
format = "pyproject";
|
||||
|
||||
disabled = python3Packages.pythonOlder "3.10";
|
||||
@ -11,7 +11,7 @@ python3Packages.buildPythonApplication rec {
|
||||
owner = "hyprland-community";
|
||||
repo = "pyprland";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-VS1qWJxTJDRlmb4pfzSqU0geOcPAVYDYy2d/f5KcOpQ=";
|
||||
hash = "sha256-6ne1wohpknxXpaLg29COM84pXUBKXBVH0jaLfypLtUo=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = with python3Packages; [ poetry-core ];
|
||||
@ -21,11 +21,29 @@ python3Packages.buildPythonApplication rec {
|
||||
chmod -x $out/${python3Packages.python.sitePackages}/pyprland/command.py
|
||||
'';
|
||||
|
||||
# NOTE: this is required for the imports check below to work properly
|
||||
HYPRLAND_INSTANCE_SIGNATURE = "dummy";
|
||||
|
||||
pythonImportsCheck = [
|
||||
"pyprland"
|
||||
"pyprland.command"
|
||||
"pyprland.common"
|
||||
"pyprland.ipc"
|
||||
"pyprland.plugins"
|
||||
"pyprland.plugins.experimental"
|
||||
"pyprland.plugins.expose"
|
||||
"pyprland.plugins.interface"
|
||||
"pyprland.plugins.layout_center"
|
||||
"pyprland.plugins.lost_windows"
|
||||
"pyprland.plugins.magnify"
|
||||
"pyprland.plugins.monitors"
|
||||
"pyprland.plugins.monitors_v0"
|
||||
"pyprland.plugins.pyprland"
|
||||
"pyprland.plugins.scratchpads"
|
||||
"pyprland.plugins.shift_monitors"
|
||||
"pyprland.plugins.toggle_dpms"
|
||||
"pyprland.plugins.toggle_special"
|
||||
"pyprland.plugins.workspaces_follow_focus"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
|
@ -3,47 +3,45 @@
|
||||
, rustPlatform
|
||||
, fetchFromGitHub
|
||||
, installShellFiles
|
||||
, Foundation
|
||||
, darwin
|
||||
}:
|
||||
|
||||
rustPlatform.buildRustPackage rec {
|
||||
pname = "rage";
|
||||
version = "0.9.2";
|
||||
version = "0.10.0";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "str4d";
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
hash = "sha256-hFuuwmwe0ti4Y8mSJyNqUIhZjFC6qtv6W5cwtNjPUFQ=";
|
||||
hash = "sha256-7PfNDFDuvQ9T3BeA15FuY1jAprGLsyglWXcNrZvtPAE=";
|
||||
};
|
||||
|
||||
cargoHash = "sha256-1gtLWU6uiWzUfYy9y3pb2vcnUC3H+Mf9rglmqNd989M=";
|
||||
cargoHash = "sha256-5aLT0JfeFj0fZP/1sHXulCQtoquHYriapMdPtN+fxko=";
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
];
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
Foundation
|
||||
darwin.apple_sdk.frameworks.Foundation
|
||||
];
|
||||
|
||||
# cargo test has an x86-only dependency
|
||||
doCheck = stdenv.hostPlatform.isx86;
|
||||
|
||||
postBuild = ''
|
||||
cargo run --example generate-docs
|
||||
cargo run --example generate-completions
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
installManPage target/manpages/*
|
||||
installShellCompletion target/completions/*.{bash,fish,zsh}
|
||||
installManPage target/*/release/manpages/man1/*
|
||||
installShellCompletion \
|
||||
--bash target/*/release/completions/*.bash \
|
||||
--fish target/*/release/completions/*.fish \
|
||||
--zsh target/*/release/completions/_*
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
description = "A simple, secure and modern encryption tool with small explicit keys, no config options, and UNIX-style composability";
|
||||
homepage = "https://github.com/str4d/rage";
|
||||
changelog = "https://github.com/str4d/rage/raw/v${version}/rage/CHANGELOG.md";
|
||||
changelog = "https://github.com/str4d/rage/blob/v${version}/rage/CHANGELOG.md";
|
||||
license = with licenses; [ asl20 mit ]; # either at your option
|
||||
maintainers = with maintainers; [ marsam ryantm ];
|
||||
mainProgram = "rage";
|
@ -54,6 +54,14 @@ stdenv.mkDerivation rec {
|
||||
hash = "sha256-LNoPg1KCoP8RWxU/AzHR52f4Dww24I9BGQJedMhFxyQ=";
|
||||
relative = "libcxx";
|
||||
})
|
||||
] ++ lib.optionals (stdenv.isDarwin && lib.versionOlder stdenv.hostPlatform.darwinMinVersion "10.13") [
|
||||
# https://github.com/llvm/llvm-project/issues/64226
|
||||
(fetchpatch {
|
||||
name = "0042-mbstate_t-not-defined.patch";
|
||||
url = "https://github.com/macports/macports-ports/raw/acd8acb171f1658596ed1cf25da48d5b932e2d19/lang/llvm-17/files/0042-mbstate_t-not-defined.patch";
|
||||
relative = "libcxx";
|
||||
hash = "sha256-fVbX99W1gQrSaMFeBkzsJmNWNy0xVSw+oFvDe4AYXL0=";
|
||||
})
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
|
@ -110,8 +110,5 @@ stdenv.mkDerivation rec {
|
||||
# the UIUC License (a BSD-like license)":
|
||||
license = with lib.licenses; [ mit ncsa ];
|
||||
maintainers = llvm_meta.maintainers ++ [ lib.maintainers.vlstill ];
|
||||
# Broken until https://github.com/llvm/llvm-project/issues/64226 is resolved
|
||||
# We should check if the version is not 10.13 but that is currently broken.
|
||||
broken = stdenv.isDarwin && stdenv.isx86_64;
|
||||
};
|
||||
}
|
||||
|
@ -13,13 +13,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "frei0r-plugins";
|
||||
version = "2.3.1";
|
||||
version = "2.3.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "dyne";
|
||||
repo = "frei0r";
|
||||
rev = "v${version}";
|
||||
hash = "sha256-5itlZfnloQXV/aCiNgOOZzEeO1d+NLY4qSk8uMVAOmA=";
|
||||
hash = "sha256-shPCCKcmacSB/mqwLU6BPR1p+/9Myg759MMehj9yijI=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ cmake pkg-config ];
|
||||
|
@ -8,13 +8,13 @@
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
version = "3.8.0";
|
||||
version = "3.9.0";
|
||||
pname = "libre";
|
||||
src = fetchFromGitHub {
|
||||
owner = "baresip";
|
||||
repo = "re";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-zKoK5GsgNnmQrEZ5HAse2e1Gy7fPO42DEvVAL5ZTNhc=";
|
||||
sha256 = "sha256-oFaCeVaUrAN83DT8m4gvXSaKzxq5AJw2RHwOelm8HAU=";
|
||||
};
|
||||
|
||||
buildInputs = [
|
||||
|
@ -12,11 +12,11 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "tdb";
|
||||
version = "1.4.9";
|
||||
version = "1.4.10";
|
||||
|
||||
src = fetchurl {
|
||||
url = "mirror://samba/tdb/${pname}-${version}.tar.gz";
|
||||
hash = "sha256-CsImBz46LbhkjaevdEy5X1B2alL+6wAdVYsrMht0p2U=";
|
||||
hash = "sha256-AjOOM8FsIcnilXHO9SPnaytwhjYlT28wxs8ZXUjGLa8=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -460,14 +460,14 @@ buildLuarocksPackage {
|
||||
fidget-nvim = callPackage({ buildLuarocksPackage, fetchurl, fetchzip, lua, luaOlder }:
|
||||
buildLuarocksPackage {
|
||||
pname = "fidget.nvim";
|
||||
version = "1.0.0-1";
|
||||
version = "1.1.0-1";
|
||||
knownRockspec = (fetchurl {
|
||||
url = "mirror://luarocks/fidget.nvim-1.0.0-1.rockspec";
|
||||
sha256 = "09hhm95gvdxd6n9mz2y012gmvs05mpfr4w0qgwcr8zb4kz11nqlw";
|
||||
url = "mirror://luarocks/fidget.nvim-1.1.0-1.rockspec";
|
||||
sha256 = "0pgjbsqp6bs9kwi0qphihwhl47j1lzdgg3xfa6msikrcf8d7j0hf";
|
||||
}).outPath;
|
||||
src = fetchzip {
|
||||
url = "https://github.com/j-hui/fidget.nvim/archive/fa1445fe7230845ea66b2c8bec3398fe5d900307.zip";
|
||||
sha256 = "0krvmyww42dx4q0gxv0qdyv14zxbbl5g4g8pa5dl5qdlznw9vagq";
|
||||
url = "https://github.com/j-hui/fidget.nvim/archive/300018af4abd00610a345e382ca1f4b7ba420f77.zip";
|
||||
sha256 = "0bwjcqkb735wqnzc8rngvpq1b2rxgc7m0arjypvnvzsxw6wd1f61";
|
||||
};
|
||||
|
||||
disabled = (luaOlder "5.1");
|
||||
@ -2860,6 +2860,29 @@ buildLuarocksPackage {
|
||||
};
|
||||
}) {};
|
||||
|
||||
nvim-nio = callPackage({ buildLuarocksPackage, fetchurl, fetchzip, lua, luaOlder }:
|
||||
buildLuarocksPackage {
|
||||
pname = "nvim-nio";
|
||||
version = "1.2.0-1";
|
||||
knownRockspec = (fetchurl {
|
||||
url = "mirror://luarocks/nvim-nio-1.2.0-1.rockspec";
|
||||
sha256 = "0a62iv1lyx8ldrdbip6az0ixm8dmpcai3k8j5jsf49cr4zjpcjzk";
|
||||
}).outPath;
|
||||
src = fetchzip {
|
||||
url = "https://github.com/nvim-neotest/nvim-nio/archive/11864149f47e0c7a38c4dadbcea8fc17c968556e.zip";
|
||||
sha256 = "141py3csgbijpqhscgmsbnkg4lbx7ma7nwpj0akfc7v37c143dq3";
|
||||
};
|
||||
|
||||
disabled = (luaOlder "5.1");
|
||||
propagatedBuildInputs = [ lua ];
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/nvim-neotest/nvim-nio";
|
||||
description = "A library for asynchronous IO in Neovim";
|
||||
license.fullName = "MIT";
|
||||
};
|
||||
}) {};
|
||||
|
||||
penlight = callPackage({ buildLuarocksPackage, fetchgit, lua, luaOlder, luafilesystem }:
|
||||
buildLuarocksPackage {
|
||||
pname = "penlight";
|
||||
@ -2948,6 +2971,29 @@ buildLuarocksPackage {
|
||||
};
|
||||
}) {};
|
||||
|
||||
rocks-nvim = callPackage({ buildLuarocksPackage, fetchurl, fetchzip, fidget-nvim, fzy, lua, luaOlder, nvim-nio, toml, toml-edit }:
|
||||
buildLuarocksPackage {
|
||||
pname = "rocks.nvim";
|
||||
version = "2.7.3-1";
|
||||
knownRockspec = (fetchurl {
|
||||
url = "mirror://luarocks/rocks.nvim-2.7.3-1.rockspec";
|
||||
sha256 = "1nv6ym32d9vk69c6mg2i4bzn1lq0p1c039g5scf7482rx029zvnh";
|
||||
}).outPath;
|
||||
src = fetchzip {
|
||||
url = "https://github.com/nvim-neorocks/rocks.nvim/archive/v2.7.3.zip";
|
||||
sha256 = "02s7bqskfpk2xbipryvv7ybxl3gjllmn8wa8by1sqmmb4p56836j";
|
||||
};
|
||||
|
||||
disabled = (luaOlder "5.1");
|
||||
propagatedBuildInputs = [ fidget-nvim fzy lua nvim-nio toml toml-edit ];
|
||||
|
||||
meta = {
|
||||
homepage = "https://github.com/nvim-neorocks/rocks.nvim";
|
||||
description = "Neovim plugin management inspired by Cargo.";
|
||||
license.fullName = "GPL-3.0";
|
||||
};
|
||||
}) {};
|
||||
|
||||
rest-nvim = callPackage({ buildLuarocksPackage, fetchurl, fetchzip, lua, luaOlder }:
|
||||
buildLuarocksPackage {
|
||||
pname = "rest.nvim";
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "asf-search";
|
||||
version = "6.7.3";
|
||||
version = "7.0.4";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
@ -27,7 +27,7 @@ buildPythonPackage rec {
|
||||
owner = "asfadmin";
|
||||
repo = "Discovery-asf_search";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-wtsPnppsW44OdvdkkuyPoqADzpecUytXEc6G4q7HEw0=";
|
||||
hash = "sha256-eq8VKML50TfOnHZFXr+Ht7FUMm+NHJOksKvv3uMcq3g=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
|
@ -12,14 +12,14 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "awscrt";
|
||||
version = "0.19.19";
|
||||
version = "0.20.3";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
hash = "sha256-HBURU13uFGpsJqOC7T6tViWaEFs7fX2CNVOuVn0Djf4=";
|
||||
hash = "sha256-xB5HHDSUKHYGosbCa4/pesx0uJQarp2aEhpHDBmDh1g=";
|
||||
};
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
|
@ -10,16 +10,16 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "django-maintenance-mode";
|
||||
version = "0.19.0";
|
||||
version = "0.21.1";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
disabled = pythonOlder "3.8";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "fabiocaccamo";
|
||||
repo = "django-maintenance-mode";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-NAm3xMcHePTYxysihYj48bk7r9ykEtPcxPjSEju/zMM=";
|
||||
hash = "sha256-rZo0yru+y5TkdULBQDMGAVb494PSLtbnNX/7cuphKNk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -15,7 +15,7 @@
|
||||
, httpx
|
||||
}:
|
||||
let
|
||||
version = "1.20.9";
|
||||
version = "1.22.3";
|
||||
in
|
||||
buildPythonPackage rec {
|
||||
pname = "litellm";
|
||||
@ -26,7 +26,7 @@ buildPythonPackage rec {
|
||||
owner = "BerriAI";
|
||||
repo = "litellm";
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-Sb5vfaKFUjBWfR/SPHLJLPD/EpoEwW56xKqgbUgM0K4=";
|
||||
hash = "sha256-80XEbc0DW4CWGIAjbV2bossAKqvmqZqfZoFZi8H4NNc=";
|
||||
};
|
||||
|
||||
postPatch = ''
|
||||
|
@ -45,6 +45,5 @@ buildPythonPackage rec {
|
||||
changelog = "https://github.com/mitmproxy/mitmproxy_rs/blob/${src.rev}/CHANGELOG.md";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ fab ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
{ lib
|
||||
, buildPythonPackage
|
||||
, fetchFromGitHub
|
||||
, stdenv
|
||||
, darwin
|
||||
, pytestCheckHook
|
||||
, pythonOlder
|
||||
, rustPlatform
|
||||
, setuptools-rust
|
||||
}:
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "mitmproxy-wireguard";
|
||||
version = "0.1.23";
|
||||
format = "pyproject";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "decathorpe";
|
||||
repo = "mitmproxy_wireguard";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-z9ucTBLLRXc1lcHA0r1wUleoP8X7yIlHrtdZdLD9qJk=";
|
||||
};
|
||||
|
||||
buildInputs = lib.optionals stdenv.isDarwin [
|
||||
darwin.libiconv
|
||||
darwin.apple_sdk.frameworks.Security
|
||||
];
|
||||
|
||||
nativeBuildInputs = [
|
||||
setuptools-rust
|
||||
] ++ (with rustPlatform; [
|
||||
cargoSetupHook
|
||||
maturinBuildHook
|
||||
]);
|
||||
|
||||
cargoDeps = rustPlatform.fetchCargoTarball {
|
||||
inherit src;
|
||||
name = "${pname}-${version}";
|
||||
hash = "sha256-qgyAaUpyuWVYMxUA4Gg8inlUMlSLo++16+nVvmDMhTQ=";
|
||||
};
|
||||
|
||||
# Module has no tests, only a test client
|
||||
doCheck = false;
|
||||
|
||||
pythonImportsCheck = [
|
||||
"mitmproxy_wireguard"
|
||||
];
|
||||
|
||||
meta = with lib; {
|
||||
description = "WireGuard frontend for mitmproxy";
|
||||
homepage = "https://github.com/decathorpe/mitmproxy_wireguard";
|
||||
changelog = "https://github.com/decathorpe/mitmproxy_wireguard/releases/tag/${version}";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [ fab ];
|
||||
};
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "panel";
|
||||
version = "1.3.4";
|
||||
version = "1.3.8";
|
||||
|
||||
format = "wheel";
|
||||
|
||||
@ -25,7 +25,7 @@ buildPythonPackage rec {
|
||||
# tries to fetch even more artifacts
|
||||
src = fetchPypi {
|
||||
inherit pname version format;
|
||||
hash = "sha256-FK/ekqXCtTHyzLeFs0tHEeH0VXk0yFcns1lOLa5z0KU=";
|
||||
hash = "sha256-Sb85MZhqDd8/e0vaPGXGoxHVJ3UkrNtOC/9py6a/V3U=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "param";
|
||||
version = "2.0.1";
|
||||
version = "2.0.2";
|
||||
pyproject = true;
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
@ -25,7 +25,7 @@ buildPythonPackage rec {
|
||||
owner = "holoviz";
|
||||
repo = pname;
|
||||
rev = "refs/tags/v${version}";
|
||||
hash = "sha256-IJchqSXZ87WZUKGDY3ObfdYCRfXM++N//kM7kb1wFow=";
|
||||
hash = "sha256-kVuab6+l4KOtSvj6aI9zsQJ91tfCDJkHrSTcRL9SViY=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "pathos";
|
||||
version = "0.3.1";
|
||||
version = "0.3.2";
|
||||
format = "setuptools";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
@ -18,8 +18,8 @@ buildPythonPackage rec {
|
||||
src = fetchFromGitHub {
|
||||
owner = "uqfoundation";
|
||||
repo = pname;
|
||||
rev = "refs/tags/pathos-${version}";
|
||||
hash = "sha256-uQv1t3TRbvoQv86wNOdc5k0cgKt9kvnw5/DGbbbE46w=";
|
||||
rev = "refs/tags/${version}";
|
||||
hash = "sha256-b4HCiAvBGkFMxWh2PHC2kZ9G4PsQqVhKeIxLBKj09jU=";
|
||||
};
|
||||
|
||||
propagatedBuildInputs = [
|
||||
@ -39,7 +39,7 @@ buildPythonPackage rec {
|
||||
meta = with lib; {
|
||||
description = "Parallel graph management and execution in heterogeneous computing";
|
||||
homepage = "https://pathos.readthedocs.io/";
|
||||
changelog = "https://github.com/uqfoundation/pathos/releases/tag/pathos-${version}";
|
||||
changelog = "https://github.com/uqfoundation/pathos/releases/tag/${version}";
|
||||
license = licenses.bsd3;
|
||||
maintainers = with maintainers; [ ];
|
||||
};
|
||||
|
@ -27,14 +27,14 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "snowflake-connector-python";
|
||||
version = "3.6.0";
|
||||
version = "3.7.0";
|
||||
format = "pyproject";
|
||||
|
||||
disabled = pythonOlder "3.7";
|
||||
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
hash = "sha256-FWZ6kYeA152nVeamC79pGAUYVJUej1bM31aSKD6ahHk=";
|
||||
hash = "sha256-sr+uxkBZMHsIyq2tQCFNSI/vtKI/zXVTrHX16nWKkWk=";
|
||||
};
|
||||
|
||||
# snowflake-connector-python requires arrow 10.0.1, which we don't have in
|
||||
|
@ -9,13 +9,13 @@
|
||||
|
||||
buildDotnetModule rec {
|
||||
pname = "jackett";
|
||||
version = "0.21.1658";
|
||||
version = "0.21.1672";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = pname;
|
||||
repo = pname;
|
||||
rev = "v${version}";
|
||||
hash = "sha512-nhtCvuOoRiQxsuE4UCa2PdYNp0OzYRHPEwTIFGuRKIgrEGuGUECGGBHKDNCnOmMiGyxm495r+sKtHqTfhQSUng==";
|
||||
hash = "sha512-afXP02lZwCjL0XqLzapVM/N2qlE7rxdbfPrTaulN8N227jOPRgq3g96rnXr42crMv1IhThUbEFxN0E1vcMDm5w==";
|
||||
};
|
||||
|
||||
projectFile = "src/Jackett.Server/Jackett.Server.csproj";
|
||||
|
8
pkgs/test/nixpkgs-check-by-name/Cargo.lock
generated
8
pkgs/test/nixpkgs-check-by-name/Cargo.lock
generated
@ -213,6 +213,12 @@ version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
@ -289,10 +295,12 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"colored",
|
||||
"indoc",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"rnix",
|
||||
"rowan",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"temp-env",
|
||||
|
@ -14,6 +14,8 @@ anyhow = "1.0"
|
||||
lazy_static = "1.4.0"
|
||||
colored = "2.0.4"
|
||||
itertools = "0.11.0"
|
||||
rowan = "0.15.11"
|
||||
|
||||
[dev-dependencies]
|
||||
temp-env = "0.3.5"
|
||||
indoc = "2.0.4"
|
||||
|
@ -76,6 +76,7 @@ let
|
||||
CallPackage = {
|
||||
call_package_variant = value._callPackageVariant;
|
||||
is_derivation = pkgs.lib.isDerivation value;
|
||||
location = builtins.unsafeGetAttrPos name pkgs;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
use crate::nixpkgs_problem::NixpkgsProblem;
|
||||
use crate::ratchet;
|
||||
use crate::structure;
|
||||
use crate::utils;
|
||||
use crate::validation::ResultIteratorExt as _;
|
||||
use crate::validation::{self, Validation::Success};
|
||||
use crate::NixFileStore;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Context;
|
||||
@ -48,6 +51,15 @@ struct CallPackageInfo {
|
||||
call_package_variant: CallPackageVariant,
|
||||
/// Whether the attribute is a derivation (`lib.isDerivation`)
|
||||
is_derivation: bool,
|
||||
location: Option<Location>,
|
||||
}
|
||||
|
||||
/// The structure returned by `builtins.unsafeGetAttrPos`
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
struct Location {
|
||||
pub file: PathBuf,
|
||||
pub line: usize,
|
||||
pub column: usize,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -70,6 +82,7 @@ enum CallPackageVariant {
|
||||
/// See the `eval.nix` file for how this is achieved on the Nix side
|
||||
pub fn check_values(
|
||||
nixpkgs_path: &Path,
|
||||
nix_file_store: &mut NixFileStore,
|
||||
package_names: Vec<String>,
|
||||
keep_nix_path: bool,
|
||||
) -> validation::Result<ratchet::Nixpkgs> {
|
||||
@ -142,150 +155,223 @@ pub fn check_values(
|
||||
)
|
||||
})?;
|
||||
|
||||
let check_result = validation::sequence(attributes.into_iter().map(
|
||||
|(attribute_name, attribute_value)| {
|
||||
let relative_package_file = structure::relative_file_for_package(&attribute_name);
|
||||
|
||||
use ratchet::RatchetState::*;
|
||||
use Attribute::*;
|
||||
use AttributeInfo::*;
|
||||
use ByNameAttribute::*;
|
||||
use CallPackageVariant::*;
|
||||
use NonByNameAttribute::*;
|
||||
|
||||
let check_result = match attribute_value {
|
||||
// The attribute succeeds evaluation and is NOT defined in pkgs/by-name
|
||||
NonByName(EvalSuccess(attribute_info)) => {
|
||||
let uses_by_name = match attribute_info {
|
||||
// In these cases the package doesn't qualify for being in pkgs/by-name,
|
||||
// so the UsesByName ratchet is already as tight as it can be
|
||||
NonAttributeSet => Success(NonApplicable),
|
||||
NonCallPackage => Success(NonApplicable),
|
||||
// This is the case when the `pkgs/by-name`-internal _internalCallByNamePackageFile
|
||||
// is used for a package outside `pkgs/by-name`
|
||||
CallPackage(CallPackageInfo {
|
||||
call_package_variant: Auto,
|
||||
..
|
||||
}) => {
|
||||
// With the current detection mechanism, this also triggers for aliases
|
||||
// to pkgs/by-name packages, and there's no good method of
|
||||
// distinguishing alias vs non-alias.
|
||||
// Using `config.allowAliases = false` at least currently doesn't work
|
||||
// because there's nothing preventing people from defining aliases that
|
||||
// are present even with that disabled.
|
||||
// In the future we could kind of abuse this behavior to have better
|
||||
// enforcement of conditional aliases, but for now we just need to not
|
||||
// give an error.
|
||||
Success(NonApplicable)
|
||||
}
|
||||
// Only derivations can be in pkgs/by-name,
|
||||
// so this attribute doesn't qualify
|
||||
CallPackage(CallPackageInfo {
|
||||
is_derivation: false,
|
||||
..
|
||||
}) => Success(NonApplicable),
|
||||
|
||||
// The case of an attribute that qualifies:
|
||||
// - Uses callPackage
|
||||
// - Is a derivation
|
||||
CallPackage(CallPackageInfo {
|
||||
is_derivation: true,
|
||||
call_package_variant: Manual { path, empty_arg },
|
||||
}) => Success(Loose(ratchet::CouldUseByName {
|
||||
call_package_path: path,
|
||||
empty_arg,
|
||||
})),
|
||||
};
|
||||
uses_by_name.map(|x| ratchet::Package {
|
||||
manual_definition: Tight,
|
||||
uses_by_name: x,
|
||||
})
|
||||
}
|
||||
NonByName(EvalFailure) => {
|
||||
// We don't know anything about this attribute really
|
||||
Success(ratchet::Package {
|
||||
// We'll assume that we can't remove any manual definitions, which has the
|
||||
// minimal drawback that if there was a manual definition that could've
|
||||
// been removed, fixing the package requires removing the definition, no
|
||||
// big deal, that's a minor edit.
|
||||
manual_definition: Tight,
|
||||
|
||||
// Regarding whether this attribute could `pkgs/by-name`, we don't really
|
||||
// know, so return NonApplicable, which has the effect that if a
|
||||
// package evaluation gets broken temporarily, the fix can remove it from
|
||||
// pkgs/by-name again. For now this isn't our problem, but in the future we
|
||||
// might have another check to enforce that evaluation must not be broken.
|
||||
// The alternative of assuming that it's using `pkgs/by-name` already
|
||||
// has the problem that if a package evaluation gets broken temporarily,
|
||||
// fixing it requires a move to pkgs/by-name, which could happen more
|
||||
// often and isn't really justified.
|
||||
uses_by_name: NonApplicable,
|
||||
})
|
||||
}
|
||||
ByName(Missing) => NixpkgsProblem::UndefinedAttr {
|
||||
relative_package_file: relative_package_file.clone(),
|
||||
package_name: attribute_name.clone(),
|
||||
}
|
||||
.into(),
|
||||
ByName(Existing(NonAttributeSet)) => NixpkgsProblem::NonDerivation {
|
||||
relative_package_file: relative_package_file.clone(),
|
||||
package_name: attribute_name.clone(),
|
||||
}
|
||||
.into(),
|
||||
ByName(Existing(NonCallPackage)) => NixpkgsProblem::WrongCallPackage {
|
||||
relative_package_file: relative_package_file.clone(),
|
||||
package_name: attribute_name.clone(),
|
||||
}
|
||||
.into(),
|
||||
ByName(Existing(CallPackage(CallPackageInfo {
|
||||
is_derivation,
|
||||
call_package_variant,
|
||||
}))) => {
|
||||
let check_result = if !is_derivation {
|
||||
NixpkgsProblem::NonDerivation {
|
||||
relative_package_file: relative_package_file.clone(),
|
||||
package_name: attribute_name.clone(),
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Success(())
|
||||
};
|
||||
|
||||
check_result.and(match &call_package_variant {
|
||||
Auto => Success(ratchet::Package {
|
||||
manual_definition: Tight,
|
||||
uses_by_name: Tight,
|
||||
}),
|
||||
Manual { path, empty_arg } => {
|
||||
let correct_file = if let Some(call_package_path) = path {
|
||||
relative_package_file == *call_package_path
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if correct_file {
|
||||
Success(ratchet::Package {
|
||||
// Empty arguments for non-auto-called packages are not allowed anymore.
|
||||
manual_definition: if *empty_arg { Loose(()) } else { Tight },
|
||||
uses_by_name: Tight,
|
||||
})
|
||||
} else {
|
||||
NixpkgsProblem::WrongCallPackage {
|
||||
relative_package_file: relative_package_file.clone(),
|
||||
package_name: attribute_name.clone(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
check_result.map(|value| (attribute_name.clone(), value))
|
||||
},
|
||||
));
|
||||
let check_result = validation::sequence(
|
||||
attributes
|
||||
.into_iter()
|
||||
.map(|(attribute_name, attribute_value)| {
|
||||
let check_result = match attribute_value {
|
||||
Attribute::NonByName(non_by_name_attribute) => handle_non_by_name_attribute(
|
||||
nixpkgs_path,
|
||||
nix_file_store,
|
||||
non_by_name_attribute,
|
||||
)?,
|
||||
Attribute::ByName(by_name_attribute) => {
|
||||
by_name(&attribute_name, by_name_attribute)
|
||||
}
|
||||
};
|
||||
Ok::<_, anyhow::Error>(check_result.map(|value| (attribute_name.clone(), value)))
|
||||
})
|
||||
.collect_vec()?,
|
||||
);
|
||||
|
||||
Ok(check_result.map(|elems| ratchet::Nixpkgs {
|
||||
package_names: elems.iter().map(|(name, _)| name.to_owned()).collect(),
|
||||
package_map: elems.into_iter().collect(),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Handles the evaluation result for an attribute in `pkgs/by-name`,
|
||||
/// turning it into a validation result.
|
||||
fn by_name(
|
||||
attribute_name: &str,
|
||||
by_name_attribute: ByNameAttribute,
|
||||
) -> validation::Validation<ratchet::Package> {
|
||||
use ratchet::RatchetState::*;
|
||||
use AttributeInfo::*;
|
||||
use ByNameAttribute::*;
|
||||
use CallPackageVariant::*;
|
||||
|
||||
let relative_package_file = structure::relative_file_for_package(attribute_name);
|
||||
|
||||
match by_name_attribute {
|
||||
Missing => NixpkgsProblem::UndefinedAttr {
|
||||
relative_package_file: relative_package_file.to_owned(),
|
||||
package_name: attribute_name.to_owned(),
|
||||
}
|
||||
.into(),
|
||||
Existing(NonAttributeSet) => NixpkgsProblem::NonDerivation {
|
||||
relative_package_file: relative_package_file.to_owned(),
|
||||
package_name: attribute_name.to_owned(),
|
||||
}
|
||||
.into(),
|
||||
Existing(NonCallPackage) => NixpkgsProblem::WrongCallPackage {
|
||||
relative_package_file: relative_package_file.to_owned(),
|
||||
package_name: attribute_name.to_owned(),
|
||||
}
|
||||
.into(),
|
||||
Existing(CallPackage(CallPackageInfo {
|
||||
is_derivation,
|
||||
call_package_variant,
|
||||
..
|
||||
})) => {
|
||||
let check_result = if !is_derivation {
|
||||
NixpkgsProblem::NonDerivation {
|
||||
relative_package_file: relative_package_file.to_owned(),
|
||||
package_name: attribute_name.to_owned(),
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Success(())
|
||||
};
|
||||
|
||||
check_result.and(match &call_package_variant {
|
||||
Auto => Success(ratchet::Package {
|
||||
manual_definition: Tight,
|
||||
uses_by_name: Tight,
|
||||
}),
|
||||
// TODO: Use the call_package_argument_info_at instead/additionally and
|
||||
// simplify the eval.nix code
|
||||
Manual { path, empty_arg } => {
|
||||
let correct_file = if let Some(call_package_path) = path {
|
||||
relative_package_file == *call_package_path
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if correct_file {
|
||||
Success(ratchet::Package {
|
||||
// Empty arguments for non-auto-called packages are not allowed anymore.
|
||||
manual_definition: if *empty_arg { Loose(()) } else { Tight },
|
||||
uses_by_name: Tight,
|
||||
})
|
||||
} else {
|
||||
NixpkgsProblem::WrongCallPackage {
|
||||
relative_package_file: relative_package_file.to_owned(),
|
||||
package_name: attribute_name.to_owned(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles the evaluation result for an attribute _not_ in `pkgs/by-name`,
|
||||
/// turning it into a validation result.
|
||||
fn handle_non_by_name_attribute(
|
||||
nixpkgs_path: &Path,
|
||||
nix_file_store: &mut NixFileStore,
|
||||
non_by_name_attribute: NonByNameAttribute,
|
||||
) -> validation::Result<ratchet::Package> {
|
||||
use ratchet::RatchetState::*;
|
||||
use AttributeInfo::*;
|
||||
use CallPackageVariant::*;
|
||||
use NonByNameAttribute::*;
|
||||
|
||||
Ok(match non_by_name_attribute {
|
||||
// The attribute succeeds evaluation and is NOT defined in pkgs/by-name
|
||||
EvalSuccess(attribute_info) => {
|
||||
let uses_by_name = match attribute_info {
|
||||
// In these cases the package doesn't qualify for being in pkgs/by-name,
|
||||
// so the UsesByName ratchet is already as tight as it can be
|
||||
NonAttributeSet => Success(NonApplicable),
|
||||
NonCallPackage => Success(NonApplicable),
|
||||
// This is the case when the `pkgs/by-name`-internal _internalCallByNamePackageFile
|
||||
// is used for a package outside `pkgs/by-name`
|
||||
CallPackage(CallPackageInfo {
|
||||
call_package_variant: Auto,
|
||||
..
|
||||
}) => {
|
||||
// With the current detection mechanism, this also triggers for aliases
|
||||
// to pkgs/by-name packages, and there's no good method of
|
||||
// distinguishing alias vs non-alias.
|
||||
// Using `config.allowAliases = false` at least currently doesn't work
|
||||
// because there's nothing preventing people from defining aliases that
|
||||
// are present even with that disabled.
|
||||
// In the future we could kind of abuse this behavior to have better
|
||||
// enforcement of conditional aliases, but for now we just need to not
|
||||
// give an error.
|
||||
Success(NonApplicable)
|
||||
}
|
||||
// Only derivations can be in pkgs/by-name,
|
||||
// so this attribute doesn't qualify
|
||||
CallPackage(CallPackageInfo {
|
||||
is_derivation: false,
|
||||
..
|
||||
}) => Success(NonApplicable),
|
||||
// A location of None indicates something weird, we can't really know where
|
||||
// this attribute is defined, probably an alias
|
||||
CallPackage(CallPackageInfo { location: None, .. }) => Success(Tight),
|
||||
// The case of an attribute that qualifies:
|
||||
// - Uses callPackage
|
||||
// - Is a derivation
|
||||
CallPackage(CallPackageInfo {
|
||||
is_derivation: true,
|
||||
call_package_variant: Manual { .. },
|
||||
location: Some(location),
|
||||
}) =>
|
||||
// We'll use the attribute's location to parse the file that defines it
|
||||
{
|
||||
match nix_file_store
|
||||
.get(&location.file)?
|
||||
.call_package_argument_info_at(
|
||||
location.line,
|
||||
location.column,
|
||||
nixpkgs_path,
|
||||
)? {
|
||||
// If the definition is not of the form `<attr> = callPackage <arg1> <arg2>;`,
|
||||
// it's generally not possible to migrate to `pkgs/by-name`
|
||||
None => Success(NonApplicable),
|
||||
Some(call_package_argument_info) => {
|
||||
if let Some(ref rel_path) = call_package_argument_info.relative_path {
|
||||
if rel_path.starts_with(utils::BASE_SUBPATH) {
|
||||
// Package variants of by-name packages are explicitly allowed according to RFC 140
|
||||
// https://github.com/NixOS/rfcs/blob/master/rfcs/0140-simple-package-paths.md#package-variants:
|
||||
//
|
||||
// foo-variant = callPackage ../by-name/fo/foo/package.nix {
|
||||
// someFlag = true;
|
||||
// }
|
||||
//
|
||||
// While such definitions could be moved to `pkgs/by-name` by using
|
||||
// `.override { someFlag = true; }` instead, this changes the semantics in
|
||||
// relation with overlays.
|
||||
Success(NonApplicable)
|
||||
} else {
|
||||
Success(Loose(call_package_argument_info))
|
||||
}
|
||||
} else {
|
||||
Success(Loose(call_package_argument_info))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
uses_by_name.map(|x| ratchet::Package {
|
||||
manual_definition: Tight,
|
||||
uses_by_name: x,
|
||||
})
|
||||
}
|
||||
EvalFailure => {
|
||||
// We don't know anything about this attribute really
|
||||
Success(ratchet::Package {
|
||||
// We'll assume that we can't remove any manual definitions, which has the
|
||||
// minimal drawback that if there was a manual definition that could've
|
||||
// been removed, fixing the package requires removing the definition, no
|
||||
// big deal, that's a minor edit.
|
||||
manual_definition: Tight,
|
||||
|
||||
// Regarding whether this attribute could `pkgs/by-name`, we don't really
|
||||
// know, so return NonApplicable, which has the effect that if a
|
||||
// package evaluation gets broken temporarily, the fix can remove it from
|
||||
// pkgs/by-name again. For now this isn't our problem, but in the future we
|
||||
// might have another check to enforce that evaluation must not be broken.
|
||||
// The alternative of assuming that it's using `pkgs/by-name` already
|
||||
// has the problem that if a package evaluation gets broken temporarily,
|
||||
// fixing it requires a move to pkgs/by-name, which could happen more
|
||||
// often and isn't really justified.
|
||||
uses_by_name: NonApplicable,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::nix_file::NixFileStore;
|
||||
mod eval;
|
||||
mod nix_file;
|
||||
mod nixpkgs_problem;
|
||||
mod ratchet;
|
||||
mod references;
|
||||
@ -116,6 +118,8 @@ pub fn check_nixpkgs<W: io::Write>(
|
||||
keep_nix_path: bool,
|
||||
error_writer: &mut W,
|
||||
) -> validation::Result<ratchet::Nixpkgs> {
|
||||
let mut nix_file_store = NixFileStore::default();
|
||||
|
||||
Ok({
|
||||
let nixpkgs_path = nixpkgs_path.canonicalize().with_context(|| {
|
||||
format!(
|
||||
@ -132,9 +136,9 @@ pub fn check_nixpkgs<W: io::Write>(
|
||||
)?;
|
||||
Success(ratchet::Nixpkgs::default())
|
||||
} else {
|
||||
check_structure(&nixpkgs_path)?.result_map(|package_names|
|
||||
check_structure(&nixpkgs_path, &mut nix_file_store)?.result_map(|package_names|
|
||||
// Only if we could successfully parse the structure, we do the evaluation checks
|
||||
eval::check_values(&nixpkgs_path, package_names, keep_nix_path))?
|
||||
eval::check_values(&nixpkgs_path, &mut nix_file_store, package_names, keep_nix_path))?
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -169,7 +173,7 @@ mod tests {
|
||||
|
||||
// tempfile::tempdir needs to be wrapped in temp_env lock
|
||||
// because it accesses TMPDIR environment variable.
|
||||
fn tempdir() -> anyhow::Result<TempDir> {
|
||||
pub fn tempdir() -> anyhow::Result<TempDir> {
|
||||
let empty_list: [(&str, Option<&str>); 0] = [];
|
||||
Ok(temp_env::with_vars(empty_list, tempfile::tempdir)?)
|
||||
}
|
||||
|
510
pkgs/test/nixpkgs-check-by-name/src/nix_file.rs
Normal file
510
pkgs/test/nixpkgs-check-by-name/src/nix_file.rs
Normal file
@ -0,0 +1,510 @@
|
||||
//! This is a utility module for interacting with the syntax of Nix files
|
||||
|
||||
use crate::utils::LineIndex;
|
||||
use anyhow::Context;
|
||||
use rnix::ast;
|
||||
use rnix::ast::Expr;
|
||||
use rnix::ast::HasEntry;
|
||||
use rnix::SyntaxKind;
|
||||
use rowan::ast::AstNode;
|
||||
use rowan::TextSize;
|
||||
use rowan::TokenAtOffset;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A structure to store parse results of Nix files in memory,
|
||||
/// making sure that the same file never has to be parsed twice
|
||||
#[derive(Default)]
|
||||
pub struct NixFileStore {
|
||||
entries: HashMap<PathBuf, NixFile>,
|
||||
}
|
||||
|
||||
impl NixFileStore {
|
||||
/// Get the store entry for a Nix file if it exists, otherwise parse the file, insert it into
|
||||
/// the store, and return the value
|
||||
///
|
||||
/// Note that this function only gives an anyhow::Result::Err for I/O errors.
|
||||
/// A parse error is anyhow::Result::Ok(Result::Err(error))
|
||||
pub fn get(&mut self, path: &Path) -> anyhow::Result<&NixFile> {
|
||||
match self.entries.entry(path.to_owned()) {
|
||||
Entry::Occupied(entry) => Ok(entry.into_mut()),
|
||||
Entry::Vacant(entry) => Ok(entry.insert(NixFile::new(path)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A structure for storing a successfully parsed Nix file
|
||||
pub struct NixFile {
|
||||
/// The parent directory of the Nix file, for more convenient error handling
|
||||
pub parent_dir: PathBuf,
|
||||
/// The path to the file itself, for errors
|
||||
pub path: PathBuf,
|
||||
pub syntax_root: rnix::Root,
|
||||
pub line_index: LineIndex,
|
||||
}
|
||||
|
||||
impl NixFile {
|
||||
/// Creates a new NixFile, failing for I/O or parse errors
|
||||
fn new(path: impl AsRef<Path>) -> anyhow::Result<NixFile> {
|
||||
let Some(parent_dir) = path.as_ref().parent() else {
|
||||
anyhow::bail!("Could not get parent of path {}", path.as_ref().display())
|
||||
};
|
||||
|
||||
let contents = read_to_string(&path)
|
||||
.with_context(|| format!("Could not read file {}", path.as_ref().display()))?;
|
||||
let line_index = LineIndex::new(&contents);
|
||||
|
||||
// NOTE: There's now another Nixpkgs CI check to make sure all changed Nix files parse
|
||||
// correctly, though that uses mainline Nix instead of rnix, so it doesn't give the same
|
||||
// errors. In the future we should unify these two checks, ideally moving the other CI
|
||||
// check into this tool as well and checking for both mainline Nix and rnix.
|
||||
rnix::Root::parse(&contents)
|
||||
// rnix's ::ok returns Result<_, _> , so no error is thrown away like it would be with
|
||||
// std::result's ::ok
|
||||
.ok()
|
||||
.map(|syntax_root| NixFile {
|
||||
parent_dir: parent_dir.to_path_buf(),
|
||||
path: path.as_ref().to_owned(),
|
||||
syntax_root,
|
||||
line_index,
|
||||
})
|
||||
.with_context(|| format!("Could not parse file {} with rnix", path.as_ref().display()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about callPackage arguments
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct CallPackageArgumentInfo {
|
||||
/// The relative path of the first argument, or `None` if it's not a path.
|
||||
pub relative_path: Option<PathBuf>,
|
||||
/// Whether the second argument is an empty attribute set
|
||||
pub empty_arg: bool,
|
||||
}
|
||||
|
||||
impl NixFile {
|
||||
/// Returns information about callPackage arguments for an attribute at a specific line/column
|
||||
/// index.
|
||||
/// If the location is not of the form `<attr> = callPackage <arg1> <arg2>;`, `None` is
|
||||
/// returned.
|
||||
/// This function only returns `Err` for problems that can't be caused by the Nix contents,
|
||||
/// but rather problems in this programs code itself.
|
||||
///
|
||||
/// This is meant to be used with the location returned from `builtins.unsafeGetAttrPos`, e.g.:
|
||||
/// - Create file `default.nix` with contents
|
||||
/// ```nix
|
||||
/// self: {
|
||||
/// foo = self.callPackage ./default.nix { };
|
||||
/// }
|
||||
/// ```
|
||||
/// - Evaluate
|
||||
/// ```nix
|
||||
/// builtins.unsafeGetAttrPos "foo" (import ./default.nix { })
|
||||
/// ```
|
||||
/// results in `{ file = ./default.nix; line = 2; column = 3; }`
|
||||
/// - Get the NixFile for `.file` from a `NixFileStore`
|
||||
/// - Call this function with `.line`, `.column` and `relative_to` as the (absolute) current directory
|
||||
///
|
||||
/// You'll get back
|
||||
/// ```rust
|
||||
/// Some(CallPackageArgumentInfo { path = Some("default.nix"), empty_arg: true })
|
||||
/// ```
|
||||
///
|
||||
/// Note that this also returns the same for `pythonPackages.callPackage`. It doesn't make an
|
||||
/// attempt at distinguishing this.
|
||||
pub fn call_package_argument_info_at(
|
||||
&self,
|
||||
line: usize,
|
||||
column: usize,
|
||||
relative_to: &Path,
|
||||
) -> anyhow::Result<Option<CallPackageArgumentInfo>> {
|
||||
let Some(attrpath_value) = self.attrpath_value_at(line, column)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
self.attrpath_value_call_package_argument_info(attrpath_value, relative_to)
|
||||
}
|
||||
|
||||
// Internal function mainly to make it independently testable
|
||||
fn attrpath_value_at(
|
||||
&self,
|
||||
line: usize,
|
||||
column: usize,
|
||||
) -> anyhow::Result<Option<ast::AttrpathValue>> {
|
||||
let index = self.line_index.fromlinecolumn(line, column);
|
||||
|
||||
let token_at_offset = self
|
||||
.syntax_root
|
||||
.syntax()
|
||||
.token_at_offset(TextSize::from(index as u32));
|
||||
|
||||
// The token_at_offset function takes indices to mean a location _between_ characters,
|
||||
// which in this case is some spacing followed by the attribute name:
|
||||
//
|
||||
// foo = 10;
|
||||
// /\
|
||||
// This is the token offset, we get both the (newline + indentation) on the left side,
|
||||
// and the attribute name on the right side.
|
||||
let TokenAtOffset::Between(_space, token) = token_at_offset else {
|
||||
anyhow::bail!("Line {line} column {column} in {} is not the start of a token, but rather {token_at_offset:?}", self.path.display())
|
||||
};
|
||||
|
||||
// token looks like "foo"
|
||||
let Some(node) = token.parent() else {
|
||||
anyhow::bail!(
|
||||
"Token on line {line} column {column} in {} does not have a parent node: {token:?}",
|
||||
self.path.display()
|
||||
)
|
||||
};
|
||||
|
||||
// node looks like "foo"
|
||||
let Some(attrpath_node) = node.parent() else {
|
||||
anyhow::bail!(
|
||||
"Node in {} does not have a parent node: {node:?}",
|
||||
self.path.display()
|
||||
)
|
||||
};
|
||||
|
||||
if attrpath_node.kind() != SyntaxKind::NODE_ATTRPATH {
|
||||
// This can happen for e.g. `inherit foo`, so definitely not a syntactic `callPackage`
|
||||
return Ok(None);
|
||||
}
|
||||
// attrpath_node looks like "foo.bar"
|
||||
let Some(attrpath_value_node) = attrpath_node.parent() else {
|
||||
anyhow::bail!(
|
||||
"Attribute path node in {} does not have a parent node: {attrpath_node:?}",
|
||||
self.path.display()
|
||||
)
|
||||
};
|
||||
|
||||
if !ast::AttrpathValue::can_cast(attrpath_value_node.kind()) {
|
||||
anyhow::bail!(
|
||||
"Node in {} is not an attribute path value node: {attrpath_value_node:?}",
|
||||
self.path.display()
|
||||
)
|
||||
}
|
||||
// attrpath_value_node looks like "foo.bar = 10;"
|
||||
|
||||
// unwrap is fine because we confirmed that we can cast with the above check.
|
||||
// We could avoid this `unwrap` for a `clone`, since `cast` consumes the argument,
|
||||
// but we still need it for the error message when the cast fails.
|
||||
Ok(Some(ast::AttrpathValue::cast(attrpath_value_node).unwrap()))
|
||||
}
|
||||
|
||||
// Internal function mainly to make attrpath_value_at independently testable
|
||||
fn attrpath_value_call_package_argument_info(
|
||||
&self,
|
||||
attrpath_value: ast::AttrpathValue,
|
||||
relative_to: &Path,
|
||||
) -> anyhow::Result<Option<CallPackageArgumentInfo>> {
|
||||
let Some(attrpath) = attrpath_value.attrpath() else {
|
||||
anyhow::bail!("attrpath value node doesn't have an attrpath: {attrpath_value:?}")
|
||||
};
|
||||
|
||||
// At this point we know it's something like `foo...bar = ...`
|
||||
|
||||
if attrpath.attrs().count() > 1 {
|
||||
// If the attribute path has multiple entries, the left-most entry is an attribute and
|
||||
// can't be a `callPackage`.
|
||||
//
|
||||
// FIXME: `builtins.unsafeGetAttrPos` will return the same position for all attribute
|
||||
// paths and we can't really know which one it is. We could have a case like
|
||||
// `foo.bar = callPackage ... { }` and trying to determine if `bar` is a `callPackage`,
|
||||
// where this is not correct.
|
||||
// However, this case typically doesn't occur anyways,
|
||||
// because top-level packages wouldn't be nested under an attribute set.
|
||||
return Ok(None);
|
||||
}
|
||||
let Some(value) = attrpath_value.value() else {
|
||||
anyhow::bail!("attrpath value node doesn't have a value: {attrpath_value:?}")
|
||||
};
|
||||
|
||||
// At this point we know it's something like `foo = ...`
|
||||
|
||||
let Expr::Apply(apply1) = value else {
|
||||
// Not even a function call, instead something like `foo = null`
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(function1) = apply1.lambda() else {
|
||||
anyhow::bail!("apply node doesn't have a lambda: {apply1:?}")
|
||||
};
|
||||
let Some(arg1) = apply1.argument() else {
|
||||
anyhow::bail!("apply node doesn't have an argument: {apply1:?}")
|
||||
};
|
||||
|
||||
// At this point we know it's something like `foo = <fun> <arg>`.
|
||||
// For a callPackage, `<fun>` would be `callPackage ./file` and `<arg>` would be `{ }`
|
||||
|
||||
let empty_arg = if let Expr::AttrSet(attrset) = arg1 {
|
||||
// We can only statically determine whether the argument is empty if it's an attribute
|
||||
// set _expression_, even though other kind of expressions could evaluate to an attribute
|
||||
// set _value_. But this is what we want anyways
|
||||
attrset.entries().next().is_none()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Because callPackage takes two curried arguments, the first function needs to be a
|
||||
// function call itself
|
||||
let Expr::Apply(apply2) = function1 else {
|
||||
// Not a callPackage, instead something like `foo = import ./foo`
|
||||
return Ok(None);
|
||||
};
|
||||
let Some(function2) = apply2.lambda() else {
|
||||
anyhow::bail!("apply node doesn't have a lambda: {apply2:?}")
|
||||
};
|
||||
let Some(arg2) = apply2.argument() else {
|
||||
anyhow::bail!("apply node doesn't have an argument: {apply2:?}")
|
||||
};
|
||||
|
||||
// At this point we know it's something like `foo = <fun2> <arg2> <arg1>`.
|
||||
// For a callPackage, `<fun2>` would be `callPackage`, `<arg2>` would be `./file`
|
||||
|
||||
// Check that <arg2> is a path expression
|
||||
let path = if let Expr::Path(actual_path) = arg2 {
|
||||
// Try to statically resolve the path and turn it into a nixpkgs-relative path
|
||||
if let ResolvedPath::Within(p) = self.static_resolve_path(actual_path, relative_to) {
|
||||
Some(p)
|
||||
} else {
|
||||
// We can't statically know an existing path inside Nixpkgs used as <arg2>
|
||||
None
|
||||
}
|
||||
} else {
|
||||
// <arg2> is not a path, but rather e.g. an inline expression
|
||||
None
|
||||
};
|
||||
|
||||
// Check that <fun2> is an identifier, or an attribute path with an identifier at the end
|
||||
let ident = match function2 {
|
||||
Expr::Ident(ident) => {
|
||||
// This means it's something like `foo = callPackage <arg2> <arg1>`
|
||||
ident
|
||||
}
|
||||
Expr::Select(select) => {
|
||||
// This means it's something like `foo = self.callPackage <arg2> <arg1>`.
|
||||
// We also end up here for e.g. `pythonPackages.callPackage`, but the
|
||||
// callPackage-mocking method will take care of not triggering for this case.
|
||||
|
||||
if select.default_expr().is_some() {
|
||||
// Very odd case, but this would be `foo = self.callPackage or true ./test.nix {}
|
||||
// (yes this is valid Nix code)
|
||||
return Ok(None);
|
||||
}
|
||||
let Some(attrpath) = select.attrpath() else {
|
||||
anyhow::bail!("select node doesn't have an attrpath: {select:?}")
|
||||
};
|
||||
let Some(last) = attrpath.attrs().last() else {
|
||||
// This case shouldn't be possible, it would be `foo = self. ./test.nix {}`,
|
||||
// which shouldn't parse
|
||||
anyhow::bail!("select node has an empty attrpath: {select:?}")
|
||||
};
|
||||
if let ast::Attr::Ident(ident) = last {
|
||||
ident
|
||||
} else {
|
||||
// Here it's something like `foo = self."callPackage" /test.nix {}`
|
||||
// which we're not gonna bother with
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
// Any other expression we're not gonna treat as callPackage
|
||||
_ => return Ok(None),
|
||||
};
|
||||
|
||||
let Some(token) = ident.ident_token() else {
|
||||
anyhow::bail!("ident node doesn't have a token: {ident:?}")
|
||||
};
|
||||
|
||||
if token.text() == "callPackage" {
|
||||
Ok(Some(CallPackageArgumentInfo {
|
||||
relative_path: path,
|
||||
empty_arg,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of trying to statically resolve a Nix path expression
|
||||
pub enum ResolvedPath {
|
||||
/// Something like `./foo/${bar}/baz`, can't be known statically
|
||||
Interpolated,
|
||||
/// Something like `<nixpkgs>`, can't be known statically
|
||||
SearchPath,
|
||||
/// Path couldn't be resolved due to an IO error,
|
||||
/// e.g. if the path doesn't exist or you don't have the right permissions
|
||||
Unresolvable(std::io::Error),
|
||||
/// The path is outside the given absolute path
|
||||
Outside,
|
||||
/// The path is within the given absolute path.
|
||||
/// The `PathBuf` is the relative path under the given absolute path.
|
||||
Within(PathBuf),
|
||||
}
|
||||
|
||||
impl NixFile {
|
||||
/// Statically resolves a Nix path expression and checks that it's within an absolute path
|
||||
///
|
||||
/// E.g. for the path expression `./bar.nix` in `./foo.nix` and an absolute path of the
|
||||
/// current directory, the function returns `ResolvedPath::Within(./bar.nix)`
|
||||
pub fn static_resolve_path(&self, node: ast::Path, relative_to: &Path) -> ResolvedPath {
|
||||
if node.parts().count() != 1 {
|
||||
// If there's more than 1 interpolated part, it's of the form `./foo/${bar}/baz`.
|
||||
return ResolvedPath::Interpolated;
|
||||
}
|
||||
|
||||
let text = node.to_string();
|
||||
|
||||
if text.starts_with('<') {
|
||||
// A search path like `<nixpkgs>`. There doesn't appear to be better way to detect
|
||||
// these in rnix
|
||||
return ResolvedPath::SearchPath;
|
||||
}
|
||||
|
||||
// Join the file's parent directory and the path expression, then resolve it
|
||||
// FIXME: Expressions like `../../../../foo/bar/baz/qux` or absolute paths
|
||||
// may resolve close to the original file, but may have left the relative_to.
|
||||
// That should be checked more strictly
|
||||
match self.parent_dir.join(Path::new(&text)).canonicalize() {
|
||||
Err(resolution_error) => ResolvedPath::Unresolvable(resolution_error),
|
||||
Ok(resolved) => {
|
||||
// Check if it's within relative_to
|
||||
match resolved.strip_prefix(relative_to) {
|
||||
Err(_prefix_error) => ResolvedPath::Outside,
|
||||
Ok(suffix) => ResolvedPath::Within(suffix.to_path_buf()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::tests;
|
||||
use indoc::indoc;
|
||||
|
||||
#[test]
|
||||
fn detects_attributes() -> anyhow::Result<()> {
|
||||
let temp_dir = tests::tempdir()?;
|
||||
let file = temp_dir.path().join("file.nix");
|
||||
let contents = indoc! {r#"
|
||||
toInherit: {
|
||||
foo = 1;
|
||||
"bar" = 2;
|
||||
${"baz"} = 3;
|
||||
"${"qux"}" = 4;
|
||||
|
||||
# A
|
||||
quux
|
||||
# B
|
||||
=
|
||||
# C
|
||||
5
|
||||
# D
|
||||
;
|
||||
# E
|
||||
|
||||
/**/quuux/**/=/**/5/**/;/*E*/
|
||||
|
||||
inherit toInherit;
|
||||
}
|
||||
"#};
|
||||
|
||||
std::fs::write(&file, contents)?;
|
||||
|
||||
let nix_file = NixFile::new(&file)?;
|
||||
|
||||
// These are builtins.unsafeGetAttrPos locations for the attributes
|
||||
let cases = [
|
||||
(2, 3, Some("foo = 1;")),
|
||||
(3, 3, Some(r#""bar" = 2;"#)),
|
||||
(4, 3, Some(r#"${"baz"} = 3;"#)),
|
||||
(5, 3, Some(r#""${"qux"}" = 4;"#)),
|
||||
(8, 3, Some("quux\n # B\n =\n # C\n 5\n # D\n ;")),
|
||||
(17, 7, Some("quuux/**/=/**/5/**/;")),
|
||||
(19, 10, None),
|
||||
];
|
||||
|
||||
for (line, column, expected_result) in cases {
|
||||
let actual_result = nix_file
|
||||
.attrpath_value_at(line, column)?
|
||||
.map(|node| node.to_string());
|
||||
assert_eq!(actual_result.as_deref(), expected_result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detects_call_package() -> anyhow::Result<()> {
|
||||
let temp_dir = tests::tempdir()?;
|
||||
let file = temp_dir.path().join("file.nix");
|
||||
let contents = indoc! {r#"
|
||||
self: with self; {
|
||||
a.sub = null;
|
||||
b = null;
|
||||
c = import ./file.nix;
|
||||
d = import ./file.nix { };
|
||||
e = pythonPackages.callPackage ./file.nix { };
|
||||
f = callPackage ./file.nix { };
|
||||
g = callPackage ({ }: { }) { };
|
||||
h = callPackage ./file.nix { x = 0; };
|
||||
i = callPackage ({ }: { }) (let in { });
|
||||
}
|
||||
"#};
|
||||
|
||||
std::fs::write(&file, contents)?;
|
||||
|
||||
let nix_file = NixFile::new(&file)?;
|
||||
|
||||
let cases = [
|
||||
(2, None),
|
||||
(3, None),
|
||||
(4, None),
|
||||
(5, None),
|
||||
(
|
||||
6,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
empty_arg: true,
|
||||
}),
|
||||
),
|
||||
(
|
||||
7,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
empty_arg: true,
|
||||
}),
|
||||
),
|
||||
(
|
||||
8,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: None,
|
||||
empty_arg: true,
|
||||
}),
|
||||
),
|
||||
(
|
||||
9,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: Some(PathBuf::from("file.nix")),
|
||||
empty_arg: false,
|
||||
}),
|
||||
),
|
||||
(
|
||||
10,
|
||||
Some(CallPackageArgumentInfo {
|
||||
relative_path: None,
|
||||
empty_arg: false,
|
||||
}),
|
||||
),
|
||||
];
|
||||
|
||||
for (line, expected_result) in cases {
|
||||
let actual_result = nix_file.call_package_argument_info_at(line, 3, temp_dir.path())?;
|
||||
assert_eq!(actual_result, expected_result);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
use crate::structure;
|
||||
use crate::utils::PACKAGE_NIX_FILENAME;
|
||||
use rnix::parser::ParseError;
|
||||
use std::ffi::OsString;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
@ -58,11 +57,6 @@ pub enum NixpkgsProblem {
|
||||
subpath: PathBuf,
|
||||
io_error: io::Error,
|
||||
},
|
||||
CouldNotParseNix {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
error: ParseError,
|
||||
},
|
||||
PathInterpolation {
|
||||
relative_package_dir: PathBuf,
|
||||
subpath: PathBuf,
|
||||
@ -184,14 +178,6 @@ impl fmt::Display for NixpkgsProblem {
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
),
|
||||
NixpkgsProblem::CouldNotParseNix { relative_package_dir, subpath, error } =>
|
||||
write!(
|
||||
f,
|
||||
"{}: File {} could not be parsed by rnix: {}",
|
||||
relative_package_dir.display(),
|
||||
subpath.display(),
|
||||
error,
|
||||
),
|
||||
NixpkgsProblem::PathInterpolation { relative_package_dir, subpath, line, text } =>
|
||||
write!(
|
||||
f,
|
||||
|
@ -2,11 +2,11 @@
|
||||
//!
|
||||
//! Each type has a `compare` method that validates the ratchet checks for that item.
|
||||
|
||||
use crate::nix_file::CallPackageArgumentInfo;
|
||||
use crate::nixpkgs_problem::NixpkgsProblem;
|
||||
use crate::structure;
|
||||
use crate::validation::{self, Validation, Validation::Success};
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// The ratchet value for the entirety of Nixpkgs.
|
||||
#[derive(Default)]
|
||||
@ -148,16 +148,8 @@ impl ToNixpkgsProblem for ManualDefinition {
|
||||
/// It also checks that once a package uses pkgs/by-name, it can't switch back to all-packages.nix
|
||||
pub enum UsesByName {}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CouldUseByName {
|
||||
/// The first callPackage argument, used for better errors
|
||||
pub call_package_path: Option<PathBuf>,
|
||||
/// Whether the second callPackage argument is empty, used for better errors
|
||||
pub empty_arg: bool,
|
||||
}
|
||||
|
||||
impl ToNixpkgsProblem for UsesByName {
|
||||
type ToContext = CouldUseByName;
|
||||
type ToContext = CallPackageArgumentInfo;
|
||||
|
||||
fn to_nixpkgs_problem(
|
||||
name: &str,
|
||||
@ -167,13 +159,13 @@ impl ToNixpkgsProblem for UsesByName {
|
||||
if let Some(()) = optional_from {
|
||||
NixpkgsProblem::MovedOutOfByName {
|
||||
package_name: name.to_owned(),
|
||||
call_package_path: to.call_package_path.clone(),
|
||||
call_package_path: to.relative_path.clone(),
|
||||
empty_arg: to.empty_arg,
|
||||
}
|
||||
} else {
|
||||
NixpkgsProblem::NewPackageNotUsingByName {
|
||||
package_name: name.to_owned(),
|
||||
call_package_path: to.call_package_path.clone(),
|
||||
call_package_path: to.relative_path.clone(),
|
||||
empty_arg: to.empty_arg,
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,32 @@
|
||||
use crate::nixpkgs_problem::NixpkgsProblem;
|
||||
use crate::utils;
|
||||
use crate::utils::LineIndex;
|
||||
use crate::validation::{self, ResultIteratorExt, Validation::Success};
|
||||
use crate::NixFileStore;
|
||||
|
||||
use anyhow::Context;
|
||||
use rnix::{Root, SyntaxKind::NODE_PATH};
|
||||
use rowan::ast::AstNode;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::read_to_string;
|
||||
use std::path::Path;
|
||||
|
||||
/// Check that every package directory in pkgs/by-name doesn't link to outside that directory.
|
||||
/// Both symlinks and Nix path expressions are checked.
|
||||
pub fn check_references(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
absolute_package_dir: &Path,
|
||||
) -> validation::Result<()> {
|
||||
// The empty argument here is the subpath under the package directory to check
|
||||
// An empty one means the package directory itself
|
||||
check_path(relative_package_dir, absolute_package_dir, Path::new("")).with_context(|| {
|
||||
// The first subpath to check is the package directory itself, which we can represent as an
|
||||
// empty path, since the absolute package directory gets prepended to this.
|
||||
// We don't use `./.` to keep the error messages cleaner
|
||||
// (there's no canonicalisation going on underneath)
|
||||
let subpath = Path::new("");
|
||||
check_path(
|
||||
nix_file_store,
|
||||
relative_package_dir,
|
||||
absolute_package_dir,
|
||||
subpath,
|
||||
)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"While checking the references in package directory {}",
|
||||
relative_package_dir.display()
|
||||
@ -26,7 +35,12 @@ pub fn check_references(
|
||||
}
|
||||
|
||||
/// Checks for a specific path to not have references outside
|
||||
///
|
||||
/// The subpath is the relative path within the package directory we're currently checking.
|
||||
/// A relative path so that the error messages don't get absolute paths (which are messy in CI).
|
||||
/// The absolute package directory gets prepended before doing anything with it though.
|
||||
fn check_path(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
absolute_package_dir: &Path,
|
||||
subpath: &Path,
|
||||
@ -62,21 +76,27 @@ fn check_path(
|
||||
utils::read_dir_sorted(&path)?
|
||||
.into_iter()
|
||||
.map(|entry| {
|
||||
let entry_subpath = subpath.join(entry.file_name());
|
||||
check_path(relative_package_dir, absolute_package_dir, &entry_subpath)
|
||||
.with_context(|| {
|
||||
format!("Error while recursing into {}", subpath.display())
|
||||
})
|
||||
check_path(
|
||||
nix_file_store,
|
||||
relative_package_dir,
|
||||
absolute_package_dir,
|
||||
&subpath.join(entry.file_name()),
|
||||
)
|
||||
})
|
||||
.collect_vec()?,
|
||||
.collect_vec()
|
||||
.with_context(|| format!("Error while recursing into {}", subpath.display()))?,
|
||||
)
|
||||
} else if path.is_file() {
|
||||
// Only check Nix files
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == OsStr::new("nix") {
|
||||
check_nix_file(relative_package_dir, absolute_package_dir, subpath).with_context(
|
||||
|| format!("Error while checking Nix file {}", subpath.display()),
|
||||
)?
|
||||
check_nix_file(
|
||||
nix_file_store,
|
||||
relative_package_dir,
|
||||
absolute_package_dir,
|
||||
subpath,
|
||||
)
|
||||
.with_context(|| format!("Error while checking Nix file {}", subpath.display()))?
|
||||
} else {
|
||||
Success(())
|
||||
}
|
||||
@ -92,91 +112,63 @@ fn check_path(
|
||||
/// Check whether a nix file contains path expression references pointing outside the package
|
||||
/// directory
|
||||
fn check_nix_file(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
relative_package_dir: &Path,
|
||||
absolute_package_dir: &Path,
|
||||
subpath: &Path,
|
||||
) -> validation::Result<()> {
|
||||
let path = absolute_package_dir.join(subpath);
|
||||
let parent_dir = path
|
||||
.parent()
|
||||
.with_context(|| format!("Could not get parent of path {}", subpath.display()))?;
|
||||
|
||||
let contents = read_to_string(&path)
|
||||
.with_context(|| format!("Could not read file {}", subpath.display()))?;
|
||||
let nix_file = nix_file_store.get(&path)?;
|
||||
|
||||
let root = Root::parse(&contents);
|
||||
if let Some(error) = root.errors().first() {
|
||||
// NOTE: There's now another Nixpkgs CI check to make sure all changed Nix files parse
|
||||
// correctly, though that uses mainline Nix instead of rnix, so it doesn't give the same
|
||||
// errors. In the future we should unify these two checks, ideally moving the other CI
|
||||
// check into this tool as well and checking for both mainline Nix and rnix.
|
||||
return Ok(NixpkgsProblem::CouldNotParseNix {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
error: error.clone(),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
let line_index = LineIndex::new(&contents);
|
||||
|
||||
Ok(validation::sequence_(root.syntax().descendants().map(
|
||||
|node| {
|
||||
Ok(validation::sequence_(
|
||||
nix_file.syntax_root.syntax().descendants().map(|node| {
|
||||
let text = node.text().to_string();
|
||||
let line = line_index.line(node.text_range().start().into());
|
||||
let line = nix_file.line_index.line(node.text_range().start().into());
|
||||
|
||||
if node.kind() != NODE_PATH {
|
||||
// We're only interested in Path expressions
|
||||
Success(())
|
||||
} else if node.children().count() != 0 {
|
||||
// Filters out ./foo/${bar}/baz
|
||||
// TODO: We can just check ./foo
|
||||
NixpkgsProblem::PathInterpolation {
|
||||
// We're only interested in Path expressions
|
||||
let Some(path) = rnix::ast::Path::cast(node) else {
|
||||
return Success(());
|
||||
};
|
||||
|
||||
use crate::nix_file::ResolvedPath;
|
||||
|
||||
match nix_file.static_resolve_path(path, absolute_package_dir) {
|
||||
ResolvedPath::Interpolated => NixpkgsProblem::PathInterpolation {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into()
|
||||
} else if text.starts_with('<') {
|
||||
// Filters out search paths like <nixpkgs>
|
||||
NixpkgsProblem::SearchPath {
|
||||
.into(),
|
||||
ResolvedPath::SearchPath => NixpkgsProblem::SearchPath {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
// Resolves the reference of the Nix path
|
||||
// turning `../baz` inside `/foo/bar/default.nix` to `/foo/baz`
|
||||
match parent_dir.join(Path::new(&text)).canonicalize() {
|
||||
Ok(target) => {
|
||||
// Then checking if it's still in the package directory
|
||||
// No need to handle the case of it being inside the directory, since we scan through the
|
||||
// entire directory recursively anyways
|
||||
if let Err(_prefix_error) = target.strip_prefix(absolute_package_dir) {
|
||||
NixpkgsProblem::OutsidePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into()
|
||||
} else {
|
||||
Success(())
|
||||
}
|
||||
}
|
||||
Err(e) => NixpkgsProblem::UnresolvablePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
io_error: e,
|
||||
}
|
||||
.into(),
|
||||
.into(),
|
||||
ResolvedPath::Outside => NixpkgsProblem::OutsidePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
}
|
||||
.into(),
|
||||
ResolvedPath::Unresolvable(e) => NixpkgsProblem::UnresolvablePathReference {
|
||||
relative_package_dir: relative_package_dir.to_path_buf(),
|
||||
subpath: subpath.to_path_buf(),
|
||||
line,
|
||||
text,
|
||||
io_error: e,
|
||||
}
|
||||
.into(),
|
||||
ResolvedPath::Within(..) => {
|
||||
// No need to handle the case of it being inside the directory, since we scan through the
|
||||
// entire directory recursively anyways
|
||||
Success(())
|
||||
}
|
||||
}
|
||||
},
|
||||
)))
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::references;
|
||||
use crate::utils;
|
||||
use crate::utils::{BASE_SUBPATH, PACKAGE_NIX_FILENAME};
|
||||
use crate::validation::{self, ResultIteratorExt, Validation::Success};
|
||||
use crate::NixFileStore;
|
||||
use itertools::concat;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
@ -34,7 +35,10 @@ pub fn relative_file_for_package(package_name: &str) -> PathBuf {
|
||||
|
||||
/// Check the structure of Nixpkgs, returning the attribute names that are defined in
|
||||
/// `pkgs/by-name`
|
||||
pub fn check_structure(path: &Path) -> validation::Result<Vec<String>> {
|
||||
pub fn check_structure(
|
||||
path: &Path,
|
||||
nix_file_store: &mut NixFileStore,
|
||||
) -> validation::Result<Vec<String>> {
|
||||
let base_dir = path.join(BASE_SUBPATH);
|
||||
|
||||
let shard_results = utils::read_dir_sorted(&base_dir)?
|
||||
@ -88,7 +92,13 @@ pub fn check_structure(path: &Path) -> validation::Result<Vec<String>> {
|
||||
let package_results = entries
|
||||
.into_iter()
|
||||
.map(|package_entry| {
|
||||
check_package(path, &shard_name, shard_name_valid, package_entry)
|
||||
check_package(
|
||||
nix_file_store,
|
||||
path,
|
||||
&shard_name,
|
||||
shard_name_valid,
|
||||
package_entry,
|
||||
)
|
||||
})
|
||||
.collect_vec()?;
|
||||
|
||||
@ -102,6 +112,7 @@ pub fn check_structure(path: &Path) -> validation::Result<Vec<String>> {
|
||||
}
|
||||
|
||||
fn check_package(
|
||||
nix_file_store: &mut NixFileStore,
|
||||
path: &Path,
|
||||
shard_name: &str,
|
||||
shard_name_valid: bool,
|
||||
@ -161,6 +172,7 @@ fn check_package(
|
||||
});
|
||||
|
||||
let result = result.and(references::check_references(
|
||||
nix_file_store,
|
||||
&relative_package_dir,
|
||||
&path.join(&relative_package_dir),
|
||||
)?);
|
||||
|
@ -35,12 +35,13 @@ impl LineIndex {
|
||||
// the vec
|
||||
for split in s.split_inclusive('\n') {
|
||||
index += split.len();
|
||||
newlines.push(index);
|
||||
newlines.push(index - 1);
|
||||
}
|
||||
LineIndex { newlines }
|
||||
}
|
||||
|
||||
/// Returns the line number for a string index
|
||||
/// Returns the line number for a string index.
|
||||
/// If the index points to a newline, returns the line number before the newline
|
||||
pub fn line(&self, index: usize) -> usize {
|
||||
match self.newlines.binary_search(&index) {
|
||||
// +1 because lines are 1-indexed
|
||||
@ -48,4 +49,47 @@ impl LineIndex {
|
||||
Err(x) => x + 1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the string index for a line and column.
|
||||
pub fn fromlinecolumn(&self, line: usize, column: usize) -> usize {
|
||||
// If it's the 1th line, the column is the index
|
||||
if line == 1 {
|
||||
// But columns are 1-indexed
|
||||
column - 1
|
||||
} else {
|
||||
// For the nth line, we add the index of the (n-1)st newline to the column,
|
||||
// and remove one more from the index since arrays are 0-indexed.
|
||||
// Then add the 1-indexed column to get not the newline index itself,
|
||||
// but rather the index of the position on the next line
|
||||
self.newlines[line - 2] + column
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn line_index() {
|
||||
let line_index = LineIndex::new("a\nbc\n\ndef\n");
|
||||
|
||||
let pairs = [
|
||||
(0, 1, 1),
|
||||
(1, 1, 2),
|
||||
(2, 2, 1),
|
||||
(3, 2, 2),
|
||||
(4, 2, 3),
|
||||
(5, 3, 1),
|
||||
(6, 4, 1),
|
||||
(7, 4, 2),
|
||||
(8, 4, 3),
|
||||
(9, 4, 4),
|
||||
];
|
||||
|
||||
for (index, line, column) in pairs {
|
||||
assert_eq!(line_index.line(index), line);
|
||||
assert_eq!(line_index.fromlinecolumn(line, column), index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
self: super: {
|
||||
set = self.callPackages ({ callPackage }: {
|
||||
foo = callPackage ({ someDrv }: someDrv) { };
|
||||
}) { };
|
||||
|
||||
inherit (self.set) foo;
|
||||
}
|
@ -0,0 +1 @@
|
||||
import <test-nixpkgs> { root = ./.; }
|
@ -0,0 +1,5 @@
|
||||
self: super: {
|
||||
foo-variant-unvarianted = self.callPackage ./package.nix { };
|
||||
|
||||
foo-variant-new = self.callPackage ./pkgs/by-name/fo/foo/package.nix { };
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
self: super: {
|
||||
foo-variant-unvarianted = self.callPackage ./pkgs/by-name/fo/foo/package.nix { };
|
||||
}
|
@ -0,0 +1 @@
|
||||
import <test-nixpkgs> { root = ./.; }
|
@ -0,0 +1 @@
|
||||
{ someDrv }: someDrv
|
@ -0,0 +1 @@
|
||||
import <test-nixpkgs> { root = ./.; }
|
@ -0,0 +1 @@
|
||||
{ someDrv }: someDrv
|
@ -0,0 +1 @@
|
||||
{ someDrv }: someDrv
|
@ -55,7 +55,7 @@ with py.pkgs; buildPythonApplication rec {
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace 'cryptography>=3.3.2,<40.0.2' 'cryptography>=3.3.2' \
|
||||
--replace 'flit_core>=3.7.1,<3.8.1' 'flit_core>=3.7.1' \
|
||||
--replace 'awscrt==0.19.18' 'awscrt>=0.19' \
|
||||
--replace 'awscrt>=0.19.18,<=0.19.19' 'awscrt>=0.19.18' \
|
||||
--replace 'docutils>=0.10,<0.20' 'docutils>=0.10' \
|
||||
--replace 'prompt-toolkit>=3.0.24,<3.0.39' 'prompt-toolkit>=3.0.24'
|
||||
|
||||
|
@ -32,13 +32,13 @@ let
|
||||
]);
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "gwe";
|
||||
version = "0.15.6";
|
||||
version = "0.15.7";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "leinardi";
|
||||
repo = pname;
|
||||
rev = version;
|
||||
sha256 = "sha256-xlAz67sThXZ5o2kABb+aQI/7N7jmRpWU/5m24u8TkII=";
|
||||
sha256 = "sha256-0/VQD3WuSMShsPjydOxVEufBZqVOCTFO3UbJpsy+oLE=";
|
||||
};
|
||||
|
||||
prePatch = ''
|
||||
|
@ -11,10 +11,10 @@ stdenv.mkDerivation rec {
|
||||
|
||||
buildInputs = [ liblockfile ];
|
||||
|
||||
env.NIX_CFLAGS_COMPILE = toString [
|
||||
env.NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isGNU (toString [
|
||||
# Needed with GCC 12
|
||||
"-Wno-error=format-overflow"
|
||||
];
|
||||
]);
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
@ -25,7 +25,6 @@ stdenv.mkDerivation rec {
|
||||
'';
|
||||
|
||||
meta = {
|
||||
broken = stdenv.isDarwin;
|
||||
description = "Programs for locking and unlocking files and mailboxes";
|
||||
homepage = "http://packages.debian.org/sid/lockfile-progs";
|
||||
license = lib.licenses.gpl2Only;
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
pname = "xdg-ninja";
|
||||
version = "0.2.0.1";
|
||||
version = "0.2.0.2";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "b3nj5m1n";
|
||||
repo = "xdg-ninja";
|
||||
rev = "v${version}";
|
||||
sha256 = "sha256-ZyqxMlyCB8gEsZTVrxgLdW/mQ/4xeTHTK+lDKIzYs6I=";
|
||||
sha256 = "sha256-ASJIFQ/BpZMQGRtw8kPhtMCbXC1eb/X8TWQz+CAnaSM=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
@ -5,13 +5,13 @@
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "ocserv";
|
||||
version = "1.2.3";
|
||||
version = "1.2.4";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
owner = "openconnect";
|
||||
repo = "ocserv";
|
||||
rev = version;
|
||||
sha256 = "sha256-PHAhkHEbt5CsVc5gr/gh+xR7wfRb752bpz301g5ra9s=";
|
||||
sha256 = "sha256-IYiYC9oAw35YjpptUEnhuZQqoDevku25r7qi6SG8xtk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ autoreconfHook gperf pkg-config ronn ];
|
||||
|
@ -7751,10 +7751,6 @@ with pkgs;
|
||||
inherit (pkgs.darwin.apple_sdk.libs) utmp;
|
||||
};
|
||||
|
||||
rage = callPackage ../tools/security/rage {
|
||||
inherit (darwin.apple_sdk.frameworks) Foundation;
|
||||
};
|
||||
|
||||
rar2fs = callPackage ../tools/filesystems/rar2fs { };
|
||||
|
||||
rocmPackages = rocmPackages_5;
|
||||
|
@ -275,6 +275,7 @@ mapAliases ({
|
||||
mir_eval = mir-eval; # added 2024-01-07
|
||||
mistune_0_8 = throw "mistune_0_8 was removed because it was outdated and insecure"; # added 2022-08-12
|
||||
mistune_2_0 = mistune; # added 2022-08-12
|
||||
mitmproxy-wireguard = throw "mitmproxy-wireguard has been removed because it was replaced by upstream with mitmproxy-rs"; # added 2023-11-06
|
||||
mkdocs-minify = mkdocs-minify-plugin; # added 2023-11-28
|
||||
mox = throw "mox was removed because it is unmaintained"; # added 2023-02-21
|
||||
mrkd = throw "mrkd has been promoted to a top-level attribute"; # added 2023-08-01
|
||||
|
@ -7121,8 +7121,6 @@ self: super: with self; {
|
||||
|
||||
mitmproxy-rs = callPackage ../development/python-modules/mitmproxy-rs { };
|
||||
|
||||
mitmproxy-wireguard = callPackage ../development/python-modules/mitmproxy-wireguard { };
|
||||
|
||||
mitogen = callPackage ../development/python-modules/mitogen { };
|
||||
|
||||
mixins = callPackage ../development/python-modules/mixins { };
|
||||
|
Loading…
Reference in New Issue
Block a user