···2233## Using Ruby {#using-ruby}
4455-Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby. The attribute `ruby` refers to the default Ruby interpreter, which is currently MRI 2.6. It's also possible to refer to specific versions, e.g. `ruby_2_y`, `jruby`, or `mruby`.
55+Several versions of Ruby interpreters are available on Nix, as well as over 250 gems and many applications written in Ruby. The attribute `ruby` refers to the default Ruby interpreter, which is currently MRI 3.1. It's also possible to refer to specific versions, e.g. `ruby_3_y`, `jruby`, or `mruby`.
6677In the Nixpkgs tree, Ruby packages can be found throughout, depending on what they do, and are called from the main package set. Ruby gems, however are separate sets, and there's one default set for each interpreter (currently MRI only).
8899There are two main approaches for using Ruby with gems. One is to use a specifically locked `Gemfile` for an application that has very strict dependencies. The other is to depend on the common gems, which we'll explain further down, and rely on them being updated regularly.
10101111-The interpreters have common attributes, namely `gems`, and `withPackages`. So you can refer to `ruby.gems.nokogiri`, or `ruby_2_7.gems.nokogiri` to get the Nokogiri gem already compiled and ready to use.
1111+The interpreters have common attributes, namely `gems`, and `withPackages`. So you can refer to `ruby.gems.nokogiri`, or `ruby_3_2.gems.nokogiri` to get the Nokogiri gem already compiled and ready to use.
12121313Since not all gems have executables like `nokogiri`, it's usually more convenient to use the `withPackages` function like this: `ruby.withPackages (p: with p; [ nokogiri ])`. This will also make sure that the Ruby in your environment will be able to find the gem and it can be used in your Ruby code (for example via `ruby` or `irb` executables) via `require "nokogiri"` as usual.
1414···3333#### Load Ruby environment from `.nix` expression {#load-ruby-environment-from-.nix-expression}
34343535As explained [in the `nix-shell` section](https://nixos.org/manual/nix/stable/command-ref/nix-shell) of the Nix manual, `nix-shell` can also load an expression from a `.nix` file.
3636-Say we want to have Ruby 2.6, `nokogori`, and `pry`. Consider a `shell.nix` file with:
3636+Say we want to have Ruby, `nokogori`, and `pry`. Consider a `shell.nix` file with:
37373838```nix
3939with import <nixpkgs> {};
···114114115115The `bundlerEnv` is a wrapper over all the gems in your gemset. This means that all the `/lib` and `/bin` directories will be available, and the executables of all gems (even of indirect dependencies) will end up in your `$PATH`. The `wrappedRuby` provides you with all executables that come with Ruby itself, but wrapped so they can easily find the gems in your gemset.
116116117117-One common issue that you might have is that you have Ruby 2.6, but also `bundler` in your gemset. That leads to a conflict for `/bin/bundle` and `/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems in a `lowPrio` call. So in order to give the `bundler` from your gemset priority, it would be used like this:
117117+One common issue that you might have is that you have Ruby, but also `bundler` in your gemset. That leads to a conflict for `/bin/bundle` and `/bin/bundler`. You can resolve this by wrapping either your Ruby or your gems in a `lowPrio` call. So in order to give the `bundler` from your gemset priority, it would be used like this:
118118119119```nix
120120# ...
···106106 The `nimPackages` and `nim2Packages` sets have been removed.
107107 See https://nixos.org/manual/nixpkgs/unstable#nim for more information.
108108109109-- [Portunus](https://github.com/majewsky/portunus) has been updated to 2.0.
109109+- [Portunus](https://github.com/majewsky/portunus) has been updated to major version 2.
110110 This version of Portunus supports strong password hashes, but the legacy hash SHA-256 is also still supported to ensure a smooth migration of existing user accounts.
111111 After upgrading, follow the instructions on the [upstream release notes](https://github.com/majewsky/portunus/releases/tag/v2.0.0) to upgrade all user accounts to strong password hashes.
112112 Support for weak password hashes will be removed in NixOS 24.11.
+27-8
nixos/modules/services/misc/guix/default.nix
···2222 })
2323 (builtins.genList guixBuildUser numberOfUsers));
24242525- # A set of Guix user profiles to be linked at activation.
2525+ # A set of Guix user profiles to be linked at activation. All of these should
2626+ # be default profiles managed by Guix CLI and the profiles are located in
2727+ # `${cfg.stateDir}/profiles/per-user/$USER/$PROFILE`.
2628 guixUserProfiles = {
2727- # The current Guix profile that is created through `guix pull`.
2929+ # The default Guix profile managed by `guix pull`. Take note this should be
3030+ # the profile with the most precedence in `PATH` env to let users use their
3131+ # updated versions of `guix` CLI.
2832 "current-guix" = "\${XDG_CONFIG_HOME}/guix/current";
3333+3434+ # The default Guix home profile. This profile contains more than exports
3535+ # such as an activation script at `$GUIX_HOME_PROFILE/activate`.
3636+ "guix-home" = "$HOME/.guix-home/profile";
29373038 # The default Guix profile similar to $HOME/.nix-profile from Nix.
3139 "guix-profile" = "$HOME/.guix-profile";
···256264 # ephemeral setups where only certain part of the filesystem is
257265 # persistent (e.g., "Erase my darlings"-type of setup).
258266 system.userActivationScripts.guix-activate-user-profiles.text = let
267267+ guixProfile = profile: "${cfg.stateDir}/guix/profiles/per-user/\${USER}/${profile}";
268268+ linkProfile = profile: location: let
269269+ userProfile = guixProfile profile;
270270+ in ''
271271+ [ -d "${userProfile}" ] && ln -sfn "${userProfile}" "${location}"
272272+ '';
259273 linkProfileToPath = acc: profile: location: let
260260- guixProfile = "${cfg.stateDir}/guix/profiles/per-user/\${USER}/${profile}";
261261- in acc + ''
262262- [ -d "${guixProfile}" ] && [ -L "${location}" ] || ln -sf "${guixProfile}" "${location}"
263263- '';
274274+ in acc + (linkProfile profile location);
275275+276276+ # This should contain export-only Guix user profiles. The rest of it is
277277+ # handled manually in the activation script.
278278+ guixUserProfiles' = lib.attrsets.removeAttrs guixUserProfiles [ "guix-home" ];
264279265265- activationScript = lib.foldlAttrs linkProfileToPath "" guixUserProfiles;
280280+ linkExportsScript = lib.foldlAttrs linkProfileToPath "" guixUserProfiles';
266281 in ''
267282 # Don't export this please! It is only expected to be used for this
268283 # activation script and nothing else.
269284 XDG_CONFIG_HOME=''${XDG_CONFIG_HOME:-$HOME/.config}
270285271286 # Linking the usual Guix profiles into the home directory.
272272- ${activationScript}
287287+ ${linkExportsScript}
288288+289289+ # Activate all of the default Guix non-exports profiles manually.
290290+ ${linkProfile "guix-home" "$HOME/.guix-home"}
291291+ [ -L "$HOME/.guix-home" ] && "$HOME/.guix-home/activate"
273292 '';
274293275294 # GUIX_LOCPATH is basically LOCPATH but for Guix libc which in turn used by
···246246 # (we currently package 1.26 in Nixpkgs while Chromium bundles 1.21):
247247 # Source: https://bugs.chromium.org/p/angleproject/issues/detail?id=7582#c1
248248 ./patches/angle-wayland-include-protocol.patch
249249- ] ++ lib.optionals (!chromiumVersionAtLeast "120") [
250250- # We need to revert this patch to build M114+ with LLVM 16:
251251- (githubPatch {
252252- # Reland [clang] Disable autoupgrading debug info in ThinLTO builds
253253- commit = "54969766fd2029c506befc46e9ce14d67c7ed02a";
254254- hash = "sha256-Vryjg8kyn3cxWg3PmSwYRG6zrHOqYWBMSdEMGiaPg6M=";
255255- revert = true;
256256- })
257249 ] ++ lib.optionals (chromiumVersionAtLeast "120") [
258258- # We need to revert this patch to build M120+ with LLVM 16:
259259- ./patches/chromium-120-llvm-16.patch
250250+ # We need to revert this patch to build M120+ with LLVM 17:
251251+ ./patches/chromium-120-llvm-17.patch
260252 ] ++ lib.optionals (!chromiumVersionAtLeast "119.0.6024.0") [
261253 # Fix build with at-spi2-core ≥ 2.49
262254 # This version is still needed for electron.
···2626 # Sometimes we access `llvmPackages` via `pkgs`, and other times
2727 # via `pkgsFooBar`, so a string (attrname) is the only way to have
2828 # a single point of control over the LLVM version used.
2929- llvmPackages_attrName = "llvmPackages_16";
2929+ llvmPackages_attrName = "llvmPackages_17";
3030 stdenv = pkgs.${llvmPackages_attrName}.stdenv;
31313232 # Helper functions for changes that depend on specific versions:
···2727 # TODO(crbug.com/1235145): Investigate why/if this should be needed.
2828 if (is_win) {
2929 cflags += [ "/clang:-ffp-contract=off" ]
3030-@@ -800,13 +782,6 @@ config("compiler") {
3131- if (is_apple) {
3232- ldflags += [ "-Wcrl,object_path_lto" ]
3333- }
3434-- if (!is_chromeos) {
3535-- # TODO(https://crbug.com/972449): turn on for ChromeOS when that
3636-- # toolchain has this flag.
3737-- # We only use one version of LLVM within a build so there's no need to
3838-- # upgrade debug info, which can be expensive since it runs the verifier.
3939-- ldflags += [ "-Wl,-mllvm,-disable-auto-upgrade-debug-info" ]
4040-- }
4141- }
4242-4343- # TODO(https://crbug.com/1211155): investigate why this isn't effective on
···4545# If one wishes to use a different src or name for a very custom build
4646, overrideSrc ? {}
4747, pname ? "gnuradio"
4848-, version ? "3.10.8.0"
4848+, version ? "3.10.9.1"
4949}:
50505151let
5252- sourceSha256 = "sha256-4BoJciL3ffd9Dgk3HxXCOOwnGHqCEVuo+a1AtzJG4IY=";
5252+ sourceSha256 = "sha256-prCQj2gan5udOj2vnV8Vrr8B4OwpYpzAGb9w+kkJDQc=";
5353 featuresInfo = {
5454 # Needed always
5555 basic = {
···11-From 8e85d27f9ccfe152fc1b891c19f125915a907493 Mon Sep 17 00:00:00 2001
22-From: =?UTF-8?q?V=C3=ADt=20Ondruch?= <vondruch@redhat.com>
33-Date: Tue, 1 Oct 2019 12:03:33 +0200
44-Subject: [PATCH] Use `Gem::Package` like object instead of monkey patching.
55-66-1. This is similar to what RubyGems does and it is less magic [[1]].
77-2. It avoids deprecated code paths in RubyGems [[2]].
88-99-[1]: https://github.com/rubygems/rubygems/blob/92892bbc3adba86a90756c385433835f6761b8da/lib/rubygems/installer.rb#L151
1010-[2]: https://github.com/rubygems/rubygems/blob/92892bbc3adba86a90756c385433835f6761b8da/lib/rubygems/installer.rb#L187
1111-1212-(cherry picked from commit e960ef6f18a25c637c54f00c75bb6c24f8ab55d0)
1313----
1414- tool/rbinstall.rb | 47 +++++++++++++++++++++++++++--------------------
1515- 1 file changed, 27 insertions(+), 20 deletions(-)
1616-1717-diff --git a/tool/rbinstall.rb b/tool/rbinstall.rb
1818-index 060390626f..28ae8c409a 100755
1919---- a/tool/rbinstall.rb
2020-+++ b/tool/rbinstall.rb
2121-@@ -710,28 +710,34 @@ def remove_prefix(prefix, string)
2222- end
2323- end
2424-2525-- class UnpackedInstaller < Gem::Installer
2626-- module DirPackage
2727-- def extract_files(destination_dir, pattern = "*")
2828-- path = File.dirname(@gem.path)
2929-- return if path == destination_dir
3030-- File.chmod(0700, destination_dir)
3131-- mode = pattern == "bin/*" ? $script_mode : $data_mode
3232-- spec.files.each do |f|
3333-- src = File.join(path, f)
3434-- dest = File.join(without_destdir(destination_dir), f)
3535-- makedirs(dest[/.*(?=\/)/m])
3636-- install src, dest, :mode => mode
3737-- end
3838-- File.chmod($dir_mode, destination_dir)
3939-+ class DirPackage
4040-+ attr_reader :spec
4141-+
4242-+ attr_accessor :dir_mode
4343-+ attr_accessor :prog_mode
4444-+ attr_accessor :data_mode
4545-+
4646-+ def initialize(spec)
4747-+ @spec = spec
4848-+ @src_dir = File.dirname(@spec.loaded_from)
4949-+ end
5050-+
5151-+ def extract_files(destination_dir, pattern = "*")
5252-+ path = @src_dir
5353-+ return if path == destination_dir
5454-+ File.chmod(0700, destination_dir)
5555-+ mode = pattern == "bin/*" ? $script_mode : $data_mode
5656-+ spec.files.each do |f|
5757-+ src = File.join(path, f)
5858-+ dest = File.join(without_destdir(destination_dir), f)
5959-+ makedirs(dest[/.*(?=\/)/m])
6060-+ install src, dest, :mode => mode
6161- end
6262-+ File.chmod($dir_mode, destination_dir)
6363- end
6464-+ end
6565-6666-- def initialize(spec, *options)
6767-- super(spec.loaded_from, *options)
6868-- @package.extend(DirPackage).spec = spec
6969-- end
7070--
7171-+ class UnpackedInstaller < Gem::Installer
7272- def write_cache_file
7373- end
7474-7575-@@ -890,7 +896,8 @@ def install_default_gem(dir, srcdir)
7676- if File.directory?(ext = "#{gem_ext_dir}/#{spec.full_name}")
7777- spec.extensions[0] ||= "-"
7878- end
7979-- ins = RbInstall::UnpackedInstaller.new(spec, options)
8080-+ package = RbInstall::DirPackage.new spec
8181-+ ins = RbInstall::UnpackedInstaller.new(package, options)
8282- puts "#{INDENT}#{spec.name} #{spec.version}"
8383- ins.install
8484- File.chmod($data_mode, File.join(install_dir, "specifications", "#{spec.full_name}.gemspec"))
8585---
8686-2.35.1
8787-
+2-2
pkgs/development/interpreters/snobol4/default.nix
···16161717stdenv.mkDerivation rec {
1818 pname = "snobol4";
1919- version = "2.3.1";
1919+ version = "2.3.2";
20202121 src = fetchurl {
2222 urls = [
···2424 # fallback for when the current version is moved to the old folder
2525 "https://ftp.regressive.org/snobol4/old/snobol4-${version}.tar.gz"
2626 ];
2727- hash = "sha256-kSRNZ9TinSqtzlZVvUOC/6tExiSn6krWQRQn86vxdTU=";
2727+ hash = "sha256-QeMB6d0YDXARfWTzaU+d1U+e2QmjajJYfIvthatorBU=";
2828 };
29293030 outputs = [ "out" "man" "doc" ];
···1313 findFirst
1414 isDerivation
1515 length
1616- mapAttrsToList
1717- mergeDefinitions
1616+ concatMap
1817 mutuallyExclusive
1918 optional
2019 optionalAttrs
2120 optionalString
2221 optionals
2323- remove
2424- unknownModule
2522 isAttrs
2623 isString
2424+ mapAttrs
2725 ;
28262927 inherit (lib.lists)
···283281 isEnabled = findFirst (x: x == reason) null showWarnings;
284282 in if isEnabled != null then builtins.trace msg true else true;
285283286286- # Deep type-checking. Note that calling `type.check` is not enough: see `lib.mkOptionType`'s documentation.
287287- # We don't include this in lib for now because this function is flawed: it accepts things like `mkIf true 42`.
288288- typeCheck = type: value: let
289289- merged = mergeDefinitions [ ] type [
290290- { file = unknownModule; inherit value; }
291291- ];
292292- eval = builtins.tryEval (builtins.deepSeq merged.mergedValue null);
293293- in eval.success;
294294-295295- # TODO make this into a proper module and use the generic option documentation generation?
296284 metaTypes = let
297297- inherit (lib.types)
298298- anything
299299- attrsOf
300300- bool
301301- either
302302- int
303303- listOf
304304- mkOptionType
305305- str
306306- unspecified
307307- ;
308308-309309- platforms = listOf (either str (attrsOf anything)); # see lib.meta.platformMatch
285285+ types = import ./meta-types.nix { inherit lib; };
286286+ inherit (types) str union int attrs attrsOf any listOf bool;
287287+ platforms = listOf (union [ str (attrsOf any) ]); # see lib.meta.platformMatch
310288 in {
311289 # These keys are documented
312290 description = str;
313291 mainProgram = str;
314292 longDescription = str;
315293 branch = str;
316316- homepage = either (listOf str) str;
294294+ homepage = union [
295295+ (listOf str)
296296+ str
297297+ ];
317298 downloadPage = str;
318318- changelog = either (listOf str) str;
299299+ changelog = union [
300300+ (listOf str)
301301+ str
302302+ ];
319303 license = let
320320- licenseType = either (attrsOf anything) str; # TODO disallow `str` licenses, use a module
321321- in either licenseType (listOf licenseType);
322322- sourceProvenance = listOf lib.types.attrs;
323323- maintainers = listOf (attrsOf anything); # TODO use the maintainer type from lib/tests/maintainer-module.nix
304304+ # TODO disallow `str` licenses, use a module
305305+ licenseType = union [
306306+ (attrsOf any)
307307+ str
308308+ ];
309309+ in union [
310310+ (listOf licenseType)
311311+ licenseType
312312+ ];
313313+ sourceProvenance = listOf attrs;
314314+ maintainers = listOf (attrsOf any); # TODO use the maintainer type from lib/tests/maintainer-module.nix
324315 priority = int;
325316 pkgConfigModules = listOf str;
326317 inherit platforms;
···329320 unfree = bool;
330321 unsupported = bool;
331322 insecure = bool;
332332- # TODO: refactor once something like Profpatsch's types-simple will land
333333- # This is currently dead code due to https://github.com/NixOS/nix/issues/2532
334334- tests = attrsOf (mkOptionType {
323323+ tests = {
335324 name = "test";
336336- check = x: x == {} || ( # Accept {} for tests that are unsupported
325325+ verify = x: x == {} || ( # Accept {} for tests that are unsupported
337326 isDerivation x &&
338327 x ? meta.timeout
339328 );
340340- merge = lib.options.mergeOneOption;
341341- });
329329+ };
342330 timeout = int;
343331344332 # Needed for Hydra to expose channel tarballs:
···354342 executables = listOf str;
355343 outputsToInstall = listOf str;
356344 position = str;
357357- available = unspecified;
345345+ available = any;
358346 isBuildPythonPackage = platforms;
359347 schedulingPriority = int;
360348 isFcitxEngine = bool;
···363351 badPlatforms = platforms;
364352 };
365353366366- checkMetaAttr = k: v:
354354+ checkMetaAttr = let
355355+ # Map attrs directly to the verify function for performance
356356+ metaTypes' = mapAttrs (_: t: t.verify) metaTypes;
357357+ in k: v:
367358 if metaTypes?${k} then
368368- if typeCheck metaTypes.${k} v then
369369- null
359359+ if metaTypes'.${k} v then
360360+ [ ]
370361 else
371371- "key 'meta.${k}' has invalid value; expected ${metaTypes.${k}.description}, got\n ${
362362+ [ "key 'meta.${k}' has invalid value; expected ${metaTypes.${k}.name}, got\n ${
372363 lib.generators.toPretty { indent = " "; } v
373373- }"
364364+ }" ]
374365 else
375375- "key 'meta.${k}' is unrecognized; expected one of: \n [${concatMapStringsSep ", " (x: "'${x}'") (attrNames metaTypes)}]";
376376- checkMeta = meta: optionals config.checkMeta (remove null (mapAttrsToList checkMetaAttr meta));
366366+ [ "key 'meta.${k}' is unrecognized; expected one of: \n [${concatMapStringsSep ", " (x: "'${x}'") (attrNames metaTypes)}]" ];
367367+ checkMeta = meta: optionals config.checkMeta (concatMap (attr: checkMetaAttr attr meta.${attr}) (attrNames meta));
377368378369 checkOutputsToInstall = attrs: let
379370 expectedOutputs = attrs.meta.outputsToInstall or [];
+76
pkgs/stdenv/generic/meta-types.nix
···11+{ lib }:
22+# Simple internal type checks for meta.
33+# This file is not a stable interface and may be changed arbitrarily.
44+#
55+# TODO: add a method to the module system types
66+# see https://github.com/NixOS/nixpkgs/pull/273935#issuecomment-1854173100
77+let
88+ inherit (builtins) isString isInt isAttrs isList all any attrValues isFunction isBool concatStringsSep isFloat;
99+ isTypeDef = t: isAttrs t && t ? name && isString t.name && t ? verify && isFunction t.verify;
1010+1111+in
1212+lib.fix (self: {
1313+ string = {
1414+ name = "string";
1515+ verify = isString;
1616+ };
1717+ str = self.string; # Type alias
1818+1919+ any = {
2020+ name = "any";
2121+ verify = _: true;
2222+ };
2323+2424+ int = {
2525+ name = "int";
2626+ verify = isInt;
2727+ };
2828+2929+ float = {
3030+ name = "float";
3131+ verify = isFloat;
3232+ };
3333+3434+ bool = {
3535+ name = "bool";
3636+ verify = isBool;
3737+ };
3838+3939+ attrs = {
4040+ name = "attrs";
4141+ verify = isAttrs;
4242+ };
4343+4444+ list = {
4545+ name = "list";
4646+ verify = isList;
4747+ };
4848+4949+ attrsOf = t: assert isTypeDef t; let
5050+ inherit (t) verify;
5151+ in {
5252+ name = "attrsOf<${t.name}>";
5353+ verify =
5454+ # attrsOf<any> can be optimised to just isAttrs
5555+ if t == self.any then isAttrs
5656+ else attrs: isAttrs attrs && all verify (attrValues attrs);
5757+ };
5858+5959+ listOf = t: assert isTypeDef t; let
6060+ inherit (t) verify;
6161+ in {
6262+ name = "listOf<${t.name}>";
6363+ verify =
6464+ # listOf<any> can be optimised to just isList
6565+ if t == self.any then isList
6666+ else v: isList v && all verify v;
6767+ };
6868+6969+ union = types: assert all isTypeDef types; let
7070+ # Store a list of functions so we don't have to pay the cost of attrset lookups at runtime.
7171+ funcs = map (t: t.verify) types;
7272+ in {
7373+ name = "union<${concatStringsSep "," (map (t: t.name) types)}>";
7474+ verify = v: any (func: func v) funcs;
7575+ };
7676+})
···102102 lib.warn "blender-with-packages is deprecated in favor of blender.withPackages, e.g. `blender.withPackages(ps: [ ps.foobar ])`"
103103 (blender.withPackages (_: args.packages)).overrideAttrs (lib.optionalAttrs (args ? name) { pname = "blender-" + args.name; }); # Added 2023-10-30
104104 bluezFull = throw "'bluezFull' has been renamed to/replaced by 'bluez'"; # Converted to throw 2023-09-10
105105+ bookletimposer = throw "bookletimposer has been removed from nixpkgs; upstream unmaintained and broke with pypdf3"; # Added 2024-01-01
105106 boost168 = throw "boost168 has been deprecated in favor of the latest version"; # Added 2023-06-08
106107 boost169 = throw "boost169 has been deprecated in favor of the latest version"; # Added 2023-06-08
107108 boost16x = throw "boost16x has been deprecated in favor of the latest version"; # Added 2023-06-08