{"action":"created","issue":{"url":"https://api.github.com/repos/NixOS/nixpkgs/issues/7446","labels_url":"https://api.github.com/repos/NixOS/nixpkgs/issues/7446/labels{/name}","comments_url":"https://api.github.com/repos/NixOS/nixpkgs/issues/7446/comments","events_url":"https://api.github.com/repos/NixOS/nixpkgs/issues/7446/events","html_url":"https://github.com/NixOS/nixpkgs/issues/7446","id":69314684,"number":7446,"title":"Find a better pattern for using Nixpkgs config","user":{"login":"ehmry","id":537775,"avatar_url":"https://avatars.githubusercontent.com/u/537775?v=3","gravatar_id":"","url":"https://api.github.com/users/ehmry","html_url":"https://github.com/ehmry","followers_url":"https://api.github.com/users/ehmry/followers","following_url":"https://api.github.com/users/ehmry/following{/other_user}","gists_url":"https://api.github.com/users/ehmry/gists{/gist_id}","starred_url":"https://api.github.com/users/ehmry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ehmry/subscriptions","organizations_url":"https://api.github.com/users/ehmry/orgs","repos_url":"https://api.github.com/users/ehmry/repos","events_url":"https://api.github.com/users/ehmry/events{/privacy}","received_events_url":"https://api.github.com/users/ehmry/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/NixOS/nixpkgs/labels/documentation","name":"documentation","color":"fef2c0"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-04-18T14:41:28Z","updated_at":"2015-04-18T17:29:31Z","closed_at":null,"body":"I think the config argument to nixpkgs is underutilized, and where it is in use, its kind of messy, so I'd like to see some documention for consistent use and more customibility in packages.\r\n\r\nStarting with the MPD package, here is how its done and two ways I think it could be improved\r\n\r\n#### How its done now\r\n##### all-packages.nix\r\n```nix\r\n{\r\n  mpd = callPackage ../servers/mpd {\r\n    aacSupport    = config.mpd.aacSupport or true;\r\n    ffmpegSupport = config.mpd.ffmpegSupport or true;\r\n  };\r\n}\r\n```\r\n##### mpd/default.nix\r\n```nix\r\n{ stdenv, fetchurl, pkgconfig, glib, systemd, boost\r\n, alsaSupport ? true, alsaLib\r\n, flacSupport ? true, flac\r\n, vorbisSupport ? true, libvorbis\r\n, madSupport ? true, libmad\r\n, id3tagSupport ? true, libid3tag\r\n, mikmodSupport ? true, libmikmod\r\n, shoutSupport ? true, libshout\r\n, sqliteSupport ? true, sqlite\r\n, curlSupport ? true, curl\r\n, audiofileSupport ? true, audiofile\r\n, bzip2Support ? true, bzip2\r\n, ffmpegSupport ? true, ffmpeg\r\n, fluidsynthSupport ? true, fluidsynth\r\n, zipSupport ? true, zziplib\r\n, samplerateSupport ? true, libsamplerate\r\n, mmsSupport ? true, libmms\r\n, mpg123Support ? true, mpg123\r\n, aacSupport ? true, faad2\r\n, pulseaudioSupport ? true, pulseaudio\r\n, jackSupport ? true, jack2\r\n, gmeSupport ? true, game-music-emu\r\n, icuSupport ? true, icu\r\n}:\r\n```\r\n\r\n#### How defaults could be set in all-packages\r\n##### all-packages.nix\r\n```nix\r\n{\r\n    findOpts = pkgName: opts: with builtins;\r\n    let\r\n      pkgConfig =\r\n        if hasAttr pkgName config\r\n        then getAttr pkgName config\r\n        else { };\r\n    in\r\n    listToAttrs (map\r\n      (name:\r\n        { inherit name;\r\n          value =\r\n            if hasAttr name pkgConfig\r\n            then getAttr name pkgConfig\r\n            else getAttr name opts;\r\n        }\r\n      ) (attrNames opts));\r\n\r\n  mpd = callPackage ../servers/mpd (findOpts \"mpd\" {\r\n    aacSupport        = true;\r\n    alsaSupport       = true;\r\n    bzip2Support      = true;\r\n    audiofileSupport  = true;\r\n    clientSupport     = false; # Act as a proxy to another MPD instance.\r\n    curlSupport       = true;\r\n    ffmpegSupport     = true;\r\n    fluidsynthSupport = true;\r\n    flacSupport       = true;\r\n    gmeSupport        = true;\r\n    icuSupport        = true;\r\n    id3tagSupport     = true;\r\n    jackSupport       = config.jack or false;\r\n    madSupport        = true;\r\n    mikmodSupport     = true;\r\n    mmsSupport        = true;\r\n    mpg123Support     = true;\r\n    opusSupport       = true;\r\n    pulseaudioSupport = config.pulseaudio or true;\r\n    samplerateSupport = true;\r\n    shoutSupport      = true;\r\n    sqliteSupport     = true;\r\n    vorbisSupport     = true;\r\n    zipSupport        = true;\r\n  });\r\n}\r\n```\r\n##### mpd/default.nix\r\n```nix\r\n{ stdenv, fetchurl, pkgconfig, glib, systemd, boost\r\n, alsaSupport, alsaLib\r\n, flacSupport, flac\r\n, vorbisSupport, libvorbis\r\n, madSupport, libmad\r\n, id3tagSupport, libid3tag\r\n, mikmodSupport, libmikmod\r\n, shoutSupport, libshout\r\n, sqliteSupport, sqlite\r\n, curlSupport, curl\r\n, audiofileSupport, audiofile\r\n, bzip2Support, bzip2\r\n, ffmpegSupport, ffmpeg\r\n, fluidsynthSupport, fluidsynth\r\n, zipSupport, zziplib\r\n, samplerateSupport, libsamplerate\r\n, mmsSupport, libmms\r\n, mpg123Support, mpg123\r\n, aacSupport, faad2\r\n, pulseaudioSupport, pulseaudio\r\n, jackSupport, jack2\r\n, gmeSupport, game-music-emu\r\n, icuSupport, icu\r\n, clientSupport, mpd_clientlib\r\n, opusSupport, libopus\r\n}:\r\n```\r\n### If defaults were expressed in the package function\r\n##### all-packages.nix\r\n```nix\r\n{\r\n  config' = config // {\r\n    findOpts = pkgName: opts: with builtins;\r\n    let\r\n      pkgConfig =\r\n        if hasAttr pkgName config\r\n        then getAttr pkgName config\r\n        else { };\r\n    in\r\n    listToAttrs (map\r\n      (name:\r\n        { inherit name;\r\n          value =\r\n            if hasAttr name pkgConfig\r\n            then getAttr name pkgConfig\r\n            else getAttr name opts;\r\n        }\r\n      ) (attrNames opts));\r\n  };\r\n\r\n  mpd = callPackage ../servers/mpd { };\r\n}\r\n```\r\n##### mpd/default.nix\r\n```nix\r\n{ stdenv, config'\r\n, fetchurl, pkgconfig, glib, systemd, boost\r\n, alsaLib\r\n, flac\r\n, libvorbis\r\n, libmad\r\n, libid3tag\r\n, libmikmod\r\n, libshout\r\n, sqlite\r\n, curl\r\n, audiofile\r\n, bzip2\r\n, ffmpeg\r\n, fluidsynth\r\n, zziplib\r\n, libsamplerate\r\n, libmms\r\n, mpg123\r\n, faad2\r\n, pulseaudio\r\n, jack2\r\n, game-music-emu\r\n, icu\r\n}:\r\n\r\nlet\r\n  opts = config'.findOpts \"mpd\" {\r\n    aacSupport        = true;\r\n    alsaSupport       = true;\r\n    bzip2Support      = true;\r\n    audiofileSupport  = true;\r\n    clientSupport     = false; # Act as a proxy to another MPD instance.\r\n    curlSupport       = true;\r\n    ffmpegSupport     = true;\r\n    fluidsynthSupport = true;\r\n    flacSupport       = true;\r\n    gmeSupport        = true;\r\n    icuSupport        = true;\r\n    id3tagSupport     = true;\r\n    jackSupport       = config'.jack or false;\r\n    madSupport        = true;\r\n    mikmodSupport     = true;\r\n    mmsSupport        = true;\r\n    mpg123Support     = true;\r\n    opusSupport       = true;\r\n    pulseaudioSupport = config'.pulseaudio or true;\r\n    samplerateSupport = true;\r\n    shoutSupport      = true;\r\n    sqliteSupport     = true;\r\n    vorbisSupport     = true;\r\n    zipSupport        = true;\r\n  };\r\n\r\nin with opts; stdenv.mkDerivation rec {\r\n...\r\n}\r\n```\r\n\r\nAnyone have other patterns that would work better?\r\n"},"comment":{"url":"https://api.github.com/repos/NixOS/nixpkgs/issues/comments/94185300","html_url":"https://github.com/NixOS/nixpkgs/issues/7446#issuecomment-94185300","issue_url":"https://api.github.com/repos/NixOS/nixpkgs/issues/7446","id":94185300,"user":{"login":"Phreedom","id":62577,"avatar_url":"https://avatars.githubusercontent.com/u/62577?v=3","gravatar_id":"","url":"https://api.github.com/users/Phreedom","html_url":"https://github.com/Phreedom","followers_url":"https://api.github.com/users/Phreedom/followers","following_url":"https://api.github.com/users/Phreedom/following{/other_user}","gists_url":"https://api.github.com/users/Phreedom/gists{/gist_id}","starred_url":"https://api.github.com/users/Phreedom/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Phreedom/subscriptions","organizations_url":"https://api.github.com/users/Phreedom/orgs","repos_url":"https://api.github.com/users/Phreedom/repos","events_url":"https://api.github.com/users/Phreedom/events{/privacy}","received_events_url":"https://api.github.com/users/Phreedom/received_events","type":"User","site_admin":false},"created_at":"2015-04-18T17:29:31Z","updated_at":"2015-04-18T17:29:31Z","body":"You can easily set default configs like this:\n\n# all-packages.nix\n{\n   aacSupport = true;\n   mpd = callPackage ../servers/mpd {};\n}\n\nThis assumes of course that mpd has this config option:\n\n# mpd/default.nix\n, aacSupport ? true, faad2\n\nYou can then trivially do a global and per-package override of the config \nvalue. Setting global aacSupport to null also should work to let packages pick \ntheir preferred local default(need to test to make sure).\n\nProblems with this approach are:\n* It's convention-based. There's no way to tell if something is a config \noption, not even by its data type if its default is null. Thus, it's hard to \nforce people to document their options in a structured way\n\n* Binary packages. Or rather, lack of them. Lots of people from Gentoo \ninitially crave use flags. Especially since they are effectively free unlike in \nNixOS. But eventually convenience wins.\n\n* Maintenance overhead. Correctly identifying all optional dependencies, \nputting this knowledge into the derivation, adding asserts, testing at least \ncommon option combinations takes quite some effort.\n\nThe first step could be finding out what config values are actually in use eg by \ngrepping typical patterns like with* or *support and trying to get rid of \nduplicates, introduce some config naming guidelines etc etc.\n\nDocumenting this would be nice too.\n\nIf you don't get tired of it by then... the sky is the limit ;)\n"}}