···1179117911801180### `wrapProgram` \<executable\> \<makeWrapperArgs\> {#fun-wrapProgram}
1181118111821182-Convenience function for `makeWrapper` that replaces `<\executable\>` with a wrapper that executes the original program. It takes all the same arguments as `makeWrapper`, except for `--inherit-argv0` (used by the `makeBinaryWrapper` implementation) and `--argv0` (used by both `makeWrapper` and `makeBinaryWrapper` wrapper implementations).
11821182+Convenience function for `makeWrapper` that replaces `<executable>` with a wrapper that executes the original program. It takes all the same arguments as `makeWrapper`, except for `--inherit-argv0` (used by the `makeBinaryWrapper` implementation) and `--argv0` (used by both `makeWrapper` and `makeBinaryWrapper` wrapper implementations).
1183118311841184If you will apply it multiple times, it will overwrite the wrapper file and you will end up with double wrapping, which should be avoided.
11851185
+5
nixos/doc/manual/release-notes/rl-2311.section.md
···5353- [Honk](https://humungus.tedunangst.com/r/honk), a complete ActivityPub server with minimal setup and support costs.
5454 Available as [services.honk](#opt-services.honk.enable).
55555656+- [NNCP](http://www.nncpgo.org/). Added nncp-daemon and nncp-caller services. Configuration is set with [programs.nncp.settings](#opt-programs.nncp.settings) and the daemons are enabled at [services.nncp](#opt-services.nncp.caller.enable).
5757+5658## Backward Incompatibilities {#sec-release-23.11-incompatibilities}
57595860- The `boot.loader.raspberryPi` options have been marked deprecated, with intent for removal for NixOS 24.11. They had a limited use-case, and do not work like people expect. They required either very old installs ([before mid-2019](https://github.com/NixOS/nixpkgs/pull/62462)) or customized builds out of scope of the standard and generic AArch64 support. That option set never supported the Raspberry Pi 4 family of devices.
···115117- PHP now defaults to PHP 8.2, updated from 8.1.
116118117119- The ISC DHCP package and corresponding module have been removed, because they are end of life upstream. See https://www.isc.org/blogs/isc-dhcp-eol/ for details and switch to a different DHCP implementation like kea or dnsmasq.
120120+121121+- `prometheus-unbound-exporter` has been replaced by the Let's Encrypt maintained version, since the previous version was archived. This requires some changes to the module configuration, most notable `controlInterface` needs migration
122122+ towards `unbound.host` and requires either the `tcp://` or `unix://` URI scheme.
118123119124- `odoo` now defaults to 16, updated from 15.
120125
···8585#[cfg(test)]
8686mod tests {
8787 use crate::check_nixpkgs;
8888+ use crate::structure;
8889 use anyhow::Context;
8990 use std::env;
9091 use std::fs;
9191- use std::path::PathBuf;
9292+ use std::path::Path;
9393+ use tempfile::{tempdir, tempdir_in};
92949395 #[test]
9494- fn test_cases() -> anyhow::Result<()> {
9595- let extra_nix_path = PathBuf::from("tests/mock-nixpkgs.nix");
9696-9797- // We don't want coloring to mess up the tests
9898- env::set_var("NO_COLOR", "1");
9999-100100- for entry in PathBuf::from("tests").read_dir()? {
9696+ fn tests_dir() -> anyhow::Result<()> {
9797+ for entry in Path::new("tests").read_dir()? {
10198 let entry = entry?;
10299 let path = entry.path();
103100 let name = entry.file_name().to_string_lossy().into_owned();
104101105105- if !entry.path().is_dir() {
102102+ if !path.is_dir() {
106103 continue;
107104 }
108105109109- // This test explicitly makes sure we don't add files that would cause problems on
110110- // Darwin, so we cannot test it on Darwin itself
111111- #[cfg(not(target_os = "linux"))]
112112- if name == "case-sensitive-duplicate-package" {
113113- continue;
114114- }
115115-116116- let mut writer = vec![];
117117- check_nixpkgs(&path, vec![&extra_nix_path], &mut writer)
118118- .context(format!("Failed test case {name}"))?;
119119-120120- let actual_errors = String::from_utf8_lossy(&writer);
121106 let expected_errors =
122107 fs::read_to_string(path.join("expected")).unwrap_or(String::new());
123108124124- if actual_errors != expected_errors {
125125- panic!(
126126- "Failed test case {name}, expected these errors:\n\n{}\n\nbut got these:\n\n{}",
127127- expected_errors, actual_errors
128128- );
129129- }
109109+ test_nixpkgs(&name, &path, &expected_errors)?;
130110 }
131111 Ok(())
112112+ }
113113+114114+ // We cannot check case-conflicting files into Nixpkgs (the channel would fail to
115115+ // build), so we generate the case-conflicting file instead.
116116+ #[test]
117117+ fn test_case_sensitive() -> anyhow::Result<()> {
118118+ let temp_nixpkgs = tempdir()?;
119119+ let path = temp_nixpkgs.path();
120120+121121+ if is_case_insensitive_fs(&path)? {
122122+ eprintln!("We're on a case-insensitive filesystem, skipping case-sensitivity test");
123123+ return Ok(());
124124+ }
125125+126126+ let base = path.join(structure::BASE_SUBPATH);
127127+128128+ fs::create_dir_all(base.join("fo/foo"))?;
129129+ fs::write(base.join("fo/foo/package.nix"), "{ someDrv }: someDrv")?;
130130+131131+ fs::create_dir_all(base.join("fo/foO"))?;
132132+ fs::write(base.join("fo/foO/package.nix"), "{ someDrv }: someDrv")?;
133133+134134+ test_nixpkgs(
135135+ "case_sensitive",
136136+ &path,
137137+ "pkgs/by-name/fo: Duplicate case-sensitive package directories \"foO\" and \"foo\".\n",
138138+ )?;
139139+140140+ Ok(())
141141+ }
142142+143143+ fn test_nixpkgs(name: &str, path: &Path, expected_errors: &str) -> anyhow::Result<()> {
144144+ let extra_nix_path = Path::new("tests/mock-nixpkgs.nix");
145145+146146+ // We don't want coloring to mess up the tests
147147+ env::set_var("NO_COLOR", "1");
148148+149149+ let mut writer = vec![];
150150+ check_nixpkgs(&path, vec![&extra_nix_path], &mut writer)
151151+ .context(format!("Failed test case {name}"))?;
152152+153153+ let actual_errors = String::from_utf8_lossy(&writer);
154154+155155+ if actual_errors != expected_errors {
156156+ panic!(
157157+ "Failed test case {name}, expected these errors:\n\n{}\n\nbut got these:\n\n{}",
158158+ expected_errors, actual_errors
159159+ );
160160+ }
161161+ Ok(())
162162+ }
163163+164164+ /// Check whether a path is in a case-insensitive filesystem
165165+ fn is_case_insensitive_fs(path: &Path) -> anyhow::Result<bool> {
166166+ let dir = tempdir_in(path)?;
167167+ let base = dir.path();
168168+ fs::write(base.join("aaa"), "")?;
169169+ Ok(base.join("AAA").exists())
132170 }
133171}