···11---
22name: Missing or incorrect documentation
33-about:
33+about: Help us improve the Nixpkgs and NixOS reference manuals
44title: ''
55labels: '9.needs: documentation'
66assignees: ''
+53
lib/tests/misc.nix
···12061206 expr = strings.levenshteinAtMost 3 "hello" "Holla";
12071207 expected = true;
12081208 };
12091209+12101210+ testTypeDescriptionInt = {
12111211+ expr = (with types; int).description;
12121212+ expected = "signed integer";
12131213+ };
12141214+ testTypeDescriptionListOfInt = {
12151215+ expr = (with types; listOf int).description;
12161216+ expected = "list of signed integer";
12171217+ };
12181218+ testTypeDescriptionListOfListOfInt = {
12191219+ expr = (with types; listOf (listOf int)).description;
12201220+ expected = "list of list of signed integer";
12211221+ };
12221222+ testTypeDescriptionListOfEitherStrOrBool = {
12231223+ expr = (with types; listOf (either str bool)).description;
12241224+ expected = "list of (string or boolean)";
12251225+ };
12261226+ testTypeDescriptionEitherListOfStrOrBool = {
12271227+ expr = (with types; either (listOf bool) str).description;
12281228+ expected = "(list of boolean) or string";
12291229+ };
12301230+ testTypeDescriptionEitherStrOrListOfBool = {
12311231+ expr = (with types; either str (listOf bool)).description;
12321232+ expected = "string or list of boolean";
12331233+ };
12341234+ testTypeDescriptionOneOfListOfStrOrBool = {
12351235+ expr = (with types; oneOf [ (listOf bool) str ]).description;
12361236+ expected = "(list of boolean) or string";
12371237+ };
12381238+ testTypeDescriptionOneOfListOfStrOrBoolOrNumber = {
12391239+ expr = (with types; oneOf [ (listOf bool) str number ]).description;
12401240+ expected = "(list of boolean) or string or signed integer or floating point number";
12411241+ };
12421242+ testTypeDescriptionEitherListOfBoolOrEitherStringOrNumber = {
12431243+ expr = (with types; either (listOf bool) (either str number)).description;
12441244+ expected = "(list of boolean) or string or signed integer or floating point number";
12451245+ };
12461246+ testTypeDescriptionEitherEitherListOfBoolOrStringOrNumber = {
12471247+ expr = (with types; either (either (listOf bool) str) number).description;
12481248+ expected = "(list of boolean) or string or signed integer or floating point number";
12491249+ };
12501250+ testTypeDescriptionEitherNullOrBoolOrString = {
12511251+ expr = (with types; either (nullOr bool) str).description;
12521252+ expected = "null or boolean or string";
12531253+ };
12541254+ testTypeDescriptionEitherListOfEitherBoolOrStrOrInt = {
12551255+ expr = (with types; either (listOf (either bool str)) int).description;
12561256+ expected = "(list of (boolean or string)) or signed integer";
12571257+ };
12581258+ testTypeDescriptionEitherIntOrListOrEitherBoolOrStr = {
12591259+ expr = (with types; either int (listOf (either bool str))).description;
12601260+ expected = "signed integer or list of (boolean or string)";
12611261+ };
12091262}
+69-13
lib/types.nix
···113113 name
114114 , # Description of the type, defined recursively by embedding the wrapped type if any.
115115 description ? null
116116+ # A hint for whether or not this description needs parentheses. Possible values:
117117+ # - "noun": a simple noun phrase such as "positive integer"
118118+ # - "conjunction": a phrase with a potentially ambiguous "or" connective.
119119+ # - "composite": a phrase with an "of" connective
120120+ # See the `optionDescriptionPhrase` function.
121121+ , descriptionClass ? null
116122 , # Function applied to each definition that should return true if
117123 # its type-correct, false otherwise.
118124 check ? (x: true)
···158164 nestedTypes ? {}
159165 }:
160166 { _type = "option-type";
161161- inherit name check merge emptyValue getSubOptions getSubModules substSubModules typeMerge functor deprecationMessage nestedTypes;
167167+ inherit
168168+ name check merge emptyValue getSubOptions getSubModules substSubModules
169169+ typeMerge functor deprecationMessage nestedTypes descriptionClass;
162170 description = if description == null then name else description;
163171 };
164172173173+ # optionDescriptionPhrase :: (str -> bool) -> optionType -> str
174174+ #
175175+ # Helper function for producing unambiguous but readable natural language
176176+ # descriptions of types.
177177+ #
178178+ # Parameters
179179+ #
180180+ # optionDescriptionPhase unparenthesize optionType
181181+ #
182182+ # `unparenthesize`: A function from descriptionClass string to boolean.
183183+ # It must return true when the class of phrase will fit unambiguously into
184184+ # the description of the caller.
185185+ #
186186+ # `optionType`: The option type to parenthesize or not.
187187+ # The option whose description we're returning.
188188+ #
189189+ # Return value
190190+ #
191191+ # The description of the `optionType`, with parentheses if there may be an
192192+ # ambiguity.
193193+ optionDescriptionPhrase = unparenthesize: t:
194194+ if unparenthesize (t.descriptionClass or null)
195195+ then t.description
196196+ else "(${t.description})";
165197166198 # When adding new types don't forget to document them in
167199 # nixos/doc/manual/development/option-types.xml!
···170202 raw = mkOptionType rec {
171203 name = "raw";
172204 description = "raw value";
205205+ descriptionClass = "noun";
173206 check = value: true;
174207 merge = mergeOneOption;
175208 };
···177210 anything = mkOptionType {
178211 name = "anything";
179212 description = "anything";
213213+ descriptionClass = "noun";
180214 check = value: true;
181215 merge = loc: defs:
182216 let
···216250 };
217251218252 unspecified = mkOptionType {
219219- name = "unspecified";
253253+ name = "unspecified value";
254254+ descriptionClass = "noun";
220255 };
221256222257 bool = mkOptionType {
223258 name = "bool";
224259 description = "boolean";
260260+ descriptionClass = "noun";
225261 check = isBool;
226262 merge = mergeEqualOption;
227263 };
···229265 int = mkOptionType {
230266 name = "int";
231267 description = "signed integer";
268268+ descriptionClass = "noun";
232269 check = isInt;
233270 merge = mergeEqualOption;
234271 };
···294331 float = mkOptionType {
295332 name = "float";
296333 description = "floating point number";
334334+ descriptionClass = "noun";
297335 check = isFloat;
298336 merge = mergeEqualOption;
299337 };
···325363 str = mkOptionType {
326364 name = "str";
327365 description = "string";
366366+ descriptionClass = "noun";
328367 check = isString;
329368 merge = mergeEqualOption;
330369 };
···332371 nonEmptyStr = mkOptionType {
333372 name = "nonEmptyStr";
334373 description = "non-empty string";
374374+ descriptionClass = "noun";
335375 check = x: str.check x && builtins.match "[ \t\n]*" x == null;
336376 inherit (str) merge;
337377 };
···344384 mkOptionType {
345385 name = "singleLineStr";
346386 description = "(optionally newline-terminated) single-line string";
387387+ descriptionClass = "noun";
347388 inherit check;
348389 merge = loc: defs:
349390 lib.removeSuffix "\n" (merge loc defs);
···352393 strMatching = pattern: mkOptionType {
353394 name = "strMatching ${escapeNixString pattern}";
354395 description = "string matching the pattern ${pattern}";
396396+ descriptionClass = "noun";
355397 check = x: str.check x && builtins.match pattern x != null;
356398 inherit (str) merge;
357399 };
···364406 then "Concatenated string" # for types.string.
365407 else "strings concatenated with ${builtins.toJSON sep}"
366408 ;
409409+ descriptionClass = "noun";
367410 check = isString;
368411 merge = loc: defs: concatStringsSep sep (getValues defs);
369412 functor = (defaultFunctor name) // {
···387430388431 passwdEntry = entryType: addCheck entryType (str: !(hasInfix ":" str || hasInfix "\n" str)) // {
389432 name = "passwdEntry ${entryType.name}";
390390- description = "${entryType.description}, not containing newlines or colons";
433433+ description = "${optionDescriptionPhrase (class: class == "noun") entryType}, not containing newlines or colons";
391434 };
392435393436 attrs = mkOptionType {
···407450 # ("/nix/store/hash-foo"). These get a context added to them using builtins.storePath.
408451 package = mkOptionType {
409452 name = "package";
453453+ descriptionClass = "noun";
410454 check = x: isDerivation x || isStorePath x;
411455 merge = loc: defs:
412456 let res = mergeOneOption loc defs;
···427471428472 listOf = elemType: mkOptionType rec {
429473 name = "listOf";
430430- description = "list of ${elemType.description}";
474474+ description = "list of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
475475+ descriptionClass = "composite";
431476 check = isList;
432477 merge = loc: defs:
433478 map (x: x.value) (filter (x: x ? value) (concatLists (imap1 (n: def:
···450495 nonEmptyListOf = elemType:
451496 let list = addCheck (types.listOf elemType) (l: l != []);
452497 in list // {
453453- description = "non-empty " + list.description;
498498+ description = "non-empty ${optionDescriptionPhrase (class: class == "noun") list}";
454499 emptyValue = { }; # no .value attr, meaning unset
455500 };
456501457502 attrsOf = elemType: mkOptionType rec {
458503 name = "attrsOf";
459459- description = "attribute set of ${elemType.description}";
504504+ description = "attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
505505+ descriptionClass = "composite";
460506 check = isAttrs;
461507 merge = loc: defs:
462508 mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
···479525 # error that it's not defined. Use only if conditional definitions don't make sense.
480526 lazyAttrsOf = elemType: mkOptionType rec {
481527 name = "lazyAttrsOf";
482482- description = "lazy attribute set of ${elemType.description}";
528528+ description = "lazy attribute set of ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
529529+ descriptionClass = "composite";
483530 check = isAttrs;
484531 merge = loc: defs:
485532 zipAttrsWith (name: defs:
···509556 # Value of given type but with no merging (i.e. `uniq list`s are not concatenated).
510557 uniq = elemType: mkOptionType rec {
511558 name = "uniq";
512512- inherit (elemType) description check;
559559+ inherit (elemType) description descriptionClass check;
513560 merge = mergeOneOption;
514561 emptyValue = elemType.emptyValue;
515562 getSubOptions = elemType.getSubOptions;
···521568522569 unique = { message }: type: mkOptionType rec {
523570 name = "unique";
524524- inherit (type) description check;
571571+ inherit (type) description descriptionClass check;
525572 merge = mergeUniqueOption { inherit message; };
526573 emptyValue = type.emptyValue;
527574 getSubOptions = type.getSubOptions;
···534581 # Null or value of ...
535582 nullOr = elemType: mkOptionType rec {
536583 name = "nullOr";
537537- description = "null or ${elemType.description}";
584584+ description = "null or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") elemType}";
585585+ descriptionClass = "conjunction";
538586 check = x: x == null || elemType.check x;
539587 merge = loc: defs:
540588 let nrNulls = count (def: def.value == null) defs; in
···552600553601 functionTo = elemType: mkOptionType {
554602 name = "functionTo";
555555- description = "function that evaluates to a(n) ${elemType.description}";
603603+ description = "function that evaluates to a(n) ${optionDescriptionPhrase (class: class == "noun" || class == "composite") elemType}";
604604+ descriptionClass = "composite";
556605 check = isFunction;
557606 merge = loc: defs:
558607 fnArgs: (mergeDefinitions (loc ++ [ "[function body]" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue;
···578627 deferredModuleWith = attrs@{ staticModules ? [] }: mkOptionType {
579628 name = "deferredModule";
580629 description = "module";
630630+ descriptionClass = "noun";
581631 check = x: isAttrs x || isFunction x || path.check x;
582632 merge = loc: defs: {
583633 imports = staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs;
···603653 optionType = mkOptionType {
604654 name = "optionType";
605655 description = "optionType";
656656+ descriptionClass = "noun";
606657 check = value: value._type or null == "option-type";
607658 merge = loc: defs:
608659 if length defs == 1
···749800 "value ${show (builtins.head values)} (singular enum)"
750801 else
751802 "one of ${concatMapStringsSep ", " show values}";
803803+ descriptionClass =
804804+ if builtins.length values < 2
805805+ then "noun"
806806+ else "conjunction";
752807 check = flip elem values;
753808 merge = mergeEqualOption;
754809 functor = (defaultFunctor name) // { payload = values; binOp = a: b: unique (a ++ b); };
···757812 # Either value of type `t1` or `t2`.
758813 either = t1: t2: mkOptionType rec {
759814 name = "either";
760760- description = "${t1.description} or ${t2.description}";
815815+ description = "${optionDescriptionPhrase (class: class == "noun" || class == "conjunction") t1} or ${optionDescriptionPhrase (class: class == "noun" || class == "conjunction" || class == "composite") t2}";
816816+ descriptionClass = "conjunction";
761817 check = x: t1.check x || t2.check x;
762818 merge = loc: defs:
763819 let
···795851 coercedType.description})";
796852 mkOptionType rec {
797853 name = "coercedTo";
798798- description = "${finalType.description} or ${coercedType.description} convertible to it";
854854+ description = "${optionDescriptionPhrase (class: class == "noun") finalType} or ${optionDescriptionPhrase (class: class == "noun") coercedType} convertible to it";
799855 check = x: (coercedType.check x && finalType.check (coerceFunc x)) || finalType.check x;
800856 merge = loc: defs:
801857 let
···486486 </listitem>
487487 <listitem>
488488 <para>
489489+ lemmy module option
490490+ <literal>services.lemmy.settings.database.createLocally</literal>
491491+ moved to
492492+ <literal>services.lemmy.database.createLocally</literal>.
493493+ </para>
494494+ </listitem>
495495+ <listitem>
496496+ <para>
489497 virtlyst package and <literal>services.virtlyst</literal>
490498 module removed, due to lack of maintainers.
491499 </para>
+3
nixos/doc/manual/release-notes/rl-2211.section.md
···166166167167- dd-agent package removed along with the `services.dd-agent` module, due to the project being deprecated in favor of `datadog-agent`, which is available via the `services.datadog-agent` module.
168168169169+- lemmy module option `services.lemmy.settings.database.createLocally`
170170+ moved to `services.lemmy.database.createLocally`.
171171+169172- virtlyst package and `services.virtlyst` module removed, due to lack of maintainers.
170173171174- The `services.graphite.api` and `services.graphite.beacon` NixOS options, and
···7788stdenv.mkDerivation rec {
99 pname = "wolfssl";
1010- version = "5.4.0";
1010+ version = "5.5.0";
11111212 src = fetchFromGitHub {
1313 owner = "wolfSSL";
1414 repo = "wolfssl";
1515 rev = "v${version}-stable";
1616- sha256 = "sha256-5a83Mi+S+mASdZ6O2+0I+qulsF6yNUe80a3qZvWmXHw=";
1616+ sha256 = "sha256-PqxwWPK5eBcS5d6e0CL4uZHybDye1K8pxniKU99YSAE=";
1717 };
18181919 postPatch = ''
2020 patchShebangs ./scripts
2121 # ocsp tests require network access
2222 sed -i -e '/ocsp\.test/d' -e '/ocsp-stapling\.test/d' scripts/include.am
2323+ # ensure test detects musl-based systems too
2424+ substituteInPlace scripts/ocsp-stapling2.test \
2525+ --replace '"linux-gnu"' '"linux-"'
2326 '';
24272528 # Almost same as Debian but for now using --enable-all --enable-reproducible-build instead of --enable-distro to ensure options.h gets installed
+1
pkgs/development/node-packages/main-programs.nix
···99 coffee-script = "coffee";
1010 typescript = "tsc";
1111 vue-cli = "vue";
1212+ "@withgraphite/graphite-cli" = "gt";
12131314 # Packages that provide a single executable whose name differs from the package's `name`.
1415 "@angular/cli" = "ng";
···10101111buildGoModule rec {
1212 pname = "buf";
1313- version = "1.7.0";
1313+ version = "1.8.0";
14141515 src = fetchFromGitHub {
1616 owner = "bufbuild";
1717 repo = pname;
1818 rev = "v${version}";
1919- sha256 = "sha256-ALqyl5GLOxwsojR0/hfjO4yD3AEkyQK+faa3smMW94c=";
1919+ sha256 = "sha256-yU1xPOnSQXrYdF24EsXb/x+IfoQFjIbW1KEt//7Fl5Q=";
2020 };
21212222- vendorSha256 = "sha256-K+CAC2OrmjzpRF0DLSYp21BgvkxtJCF2FdpzYx/CqGI=";
2222+ vendorSha256 = "sha256-zEcKfMib/4/GfQC7M3f8R3v/hGh9F/KtjFs+pXDzbFk=";
23232424 patches = [
2525 # Skip a test that requires networking to be available to work.
2626 ./skip_test_requiring_network.patch
2727 # Skip TestWorkspaceGit which requires .git and commits.
2828 ./skip_test_requiring_dotgit.patch
2929- # Skips the invalid_upstream test as it is flakey. Based on upstream commit
3030- # 27930caf2eb35c2592a77f59ed5afe4d9e2fb7ea.
3131- # This patch may be removed on the next buf update.
3232- ./skip_test_invalid_upstream_flakey.patch
3329 ];
34303531 nativeBuildInputs = [ installShellFiles ];
···11-diff --git a/private/bufpkg/bufstudioagent/bufstudioagent_test.go b/private/bufpkg/bufstudioagent/bufstudioagent_test.go
22-index 6e010937..9cacc082 100644
33---- a/private/bufpkg/bufstudioagent/bufstudioagent_test.go
44-+++ b/private/bufpkg/bufstudioagent/bufstudioagent_test.go
55-@@ -186,6 +186,19 @@ func testPlainPostHandlerErrors(t *testing.T, upstreamServer *httptest.Server) {
66- })
77-88- t.Run("invalid_upstream", func(t *testing.T) {
99-+ // TODO: unskip this test. This is flaky because of two reasons:
1010-+ //
1111-+ // 1. When a connection is closed, the underlying HTTP client does not
1212-+ // always knows it, since the http handler implementation in go has no way
1313-+ // of changing the connection timeout. See:
1414-+ // https://github.com/golang/go/issues/16100
1515-+ //
1616-+ // 2. The expected status code is `StatusBadGateway` since the issue
1717-+ // happened client-side (a response never came back from the server). This
1818-+ // is not deterministic in the business logic because we're based on the
1919-+ // connect error code that's returned. See
2020-+ // https://linear.app/bufbuild/issue/BSR-383/flaky-test-in-bufstudioagent-testgo
2121-+ t.SkipNow()
2222- listener, err := net.Listen("tcp", "127.0.0.1:")
2323- require.NoError(t, err)
2424- go func() {
···211211 src = ../bazel_rc.patch;
212212 bazelSystemBazelRCPath = bazelRC;
213213 })
214214+215215+ # disable suspend detection during a build inside Nix as this is
216216+ # not available inside the darwin sandbox
217217+ ../bazel_darwin_sandbox.patch
214218 ] ++ lib.optional enableNixHacks ../nix-hacks.patch;
215219216220
···246246 src = ../bazel_rc.patch;
247247 bazelSystemBazelRCPath = bazelRC;
248248 })
249249+250250+ # disable suspend detection during a build inside Nix as this is
251251+ # not available inside the darwin sandbox
252252+ ../bazel_darwin_sandbox.patch
249253 ] ++ lib.optional enableNixHacks ../nix-hacks.patch;
250254251255
···99# updater
1010, python27, python3, writeScript
1111# Apple dependencies
1212-, cctools, libcxx, CoreFoundation, CoreServices, Foundation
1212+, cctools, libcxx, sigtool, CoreFoundation, CoreServices, Foundation
1313# Allow to independently override the jdks used to build and run respectively
1414, buildJdk, runJdk
1515, runtimeShell
···208208 src = ../bazel_rc.patch;
209209 bazelSystemBazelRCPath = bazelRC;
210210 })
211211+212212+ # disable suspend detection during a build inside Nix as this is
213213+ # not available inside the darwin sandbox
214214+ ./bazel_darwin_sandbox.patch
211215 ] ++ lib.optional enableNixHacks ../nix-hacks.patch;
212216213217···378382 # clang installed from Xcode has a compatibility wrapper that forwards
379383 # invocations of gcc to clang, but vanilla clang doesn't
380384 sed -i -e 's;_find_generic(repository_ctx, "gcc", "CC", overriden_tools);_find_generic(repository_ctx, "clang", "CC", overriden_tools);g' tools/cpp/unix_cc_configure.bzl
381381-385385+ sed -i -e 's;env -i codesign --identifier $@ --force --sign;env -i CODESIGN_ALLOCATE=${cctools}/bin/${cctools.targetPrefix}codesign_allocate ${sigtool}/bin/codesign --identifier $@ --force -s;g' tools/osx/BUILD
382386 sed -i -e 's;"/usr/bin/libtool";_find_generic(repository_ctx, "libtool", "LIBTOOL", overriden_tools);g' tools/cpp/unix_cc_configure.bzl
383387 wrappers=( tools/cpp/osx_cc_wrapper.sh tools/cpp/osx_cc_wrapper.sh.tpl )
384388 for wrapper in "''${wrappers[@]}"; do
···11+diff --git a/builder.go b/builder.go
22+index ed6c5ef..36e8055 100644
33+--- a/builder.go
44++++ b/builder.go
55+@@ -200,7 +200,7 @@ func NewReplace(old, new string) Replace {
66+ // It is the caller's responsibility to remove the folder when finished.
77+ func newTempFolder() (string, error) {
88+ var parentDir string
99+- if runtime.GOOS == "darwin" {
1010++ if false && runtime.GOOS == "darwin" {
1111+ // After upgrading to macOS High Sierra, Caddy builds mysteriously
1212+ // started missing the embedded version information that -ldflags
1313+ // was supposed to produce. But it only happened on macOS after