From 00d4f77ed2dc7a711bd324e466ae93cf8077b41d Mon Sep 17 00:00:00 2001 From: Johannes Kirschbauer Date: Wed, 3 Jan 2024 15:51:27 +0100 Subject: [PATCH] improve: interactive contribution guide --- website/src/app/f/[...path]/page.tsx | 2 +- .../src/app/tutorials/documentation/page.mdx | 28 ++-- website/src/app/tutorials/typing/page.mdx | 133 ++++++++++++++++++ website/src/components/PositionLink.tsx | 38 +++-- website/src/styles/globals.css | 35 ++++- 5 files changed, 203 insertions(+), 33 deletions(-) create mode 100644 website/src/app/tutorials/typing/page.mdx diff --git a/website/src/app/f/[...path]/page.tsx b/website/src/app/f/[...path]/page.tsx index 98506ae..d12236e 100644 --- a/website/src/app/f/[...path]/page.tsx +++ b/website/src/app/f/[...path]/page.tsx @@ -242,7 +242,7 @@ export default async function Page(props: { params: { path: string[] } }) { )} - {meta && } + {meta && }
{(!!meta?.aliases?.length || !!signature) && ( <> diff --git a/website/src/app/tutorials/documentation/page.mdx b/website/src/app/tutorials/documentation/page.mdx index f41cd33..63f77fe 100644 --- a/website/src/app/tutorials/documentation/page.mdx +++ b/website/src/app/tutorials/documentation/page.mdx @@ -10,18 +10,6 @@ associated code. These comments serve as a source of reference documentation for noogle, offering valuable information about the purpose, functionality, and usage of the code elements they document. -## Checklist for writers - -- [ ] Describe what the function does. -- [ ] Provide examples for different scenarios when this function might be useful. -> ` # Example(s) ` -- [ ] Provide a (single) type signature -> `# Type ` - - [ ] What types does the function expect? - - [ ] Try to follow the [typednix](https://typednix.dev) convention for best compatibility with noogle -- [ ] Describe the purpose of all arguments.-> `# Arguments` - - [ ] Positional Arguments - - [ ] All known Attributes -- [ ] Maybe describe edge cases or what else should be taken into account -- [ ] References to other functions ## Placement @@ -40,5 +28,19 @@ In any case you can place the documentation directly before the lamba. (only whi x: x; ``` -> TIP: Open up the file in your editor and go to the exact `line` `column` marker that noogle gave you. +> **Advice** +> +> Open up the file in your editor and go to the exact `line` `column` marker that noogle gave you. +## Checklist for writing good documentation + +- [ ] Describe what the function does. +- [ ] Provide examples for different scenarios when this function might be useful. -> ` # Example(s) ` +- [ ] Provide a (single) type signature -> `# Type ` + - [ ] What types does the function expect? + - [ ] Try to use this [typing convention](/tutorials/typing) for best compatibility with noogle +- [ ] Describe the purpose of all arguments.-> `# Arguments` + - [ ] Positional Arguments + - [ ] All known Attributes +- [ ] Maybe describe edge cases or what else should be taken into account +- [ ] References to other functions diff --git a/website/src/app/tutorials/typing/page.mdx b/website/src/app/tutorials/typing/page.mdx new file mode 100644 index 0000000..5bceb57 --- /dev/null +++ b/website/src/app/tutorials/typing/page.mdx @@ -0,0 +1,133 @@ +# Typing + +As the nix language has no static types we use +Type informations in doc-comments to communicate type expectations, behaviors and abstract interfaces. + +In this short tutorial your will learn how to properly type a nix function, such that it can be discovered by noogle and most imporantantly understood by other developers. + +## Primitives + +|Type | Description | +|---|---| +| Bool | A value of type boolean can be either `true` or `false` | +| Int | The classical integer type | +| Float | A float with 64 bits | +| String | A string of any unicode characters | +| Path | Path referencing a location or a file. With no assumptions on the existence of that | +| Null | The value null | +| Never | The bottom type. e.g. the function `builtins.abort` which returns `Never` | + +## Complex + +`T`, `U`, ...; are placeholders for any types, those MUST be specifically declared on usage + +| Annotation | Type | Description | +| --- | --- | --- | +| `[ T ]` | List | List of elements with type `T` each | +| `{ U::T }` | AttrSet | AttrSet where member `N` references value of type `T` | +| `T -> U` | Lambda | A function that takes a single argument of type `T` and returns a value of type `U` | + +## Common Aliases + +Sometimes common aliases for more complex types can be used. + +They are composed from other types as follows + +| Type | Composition | Description | +|---|---|---| +| `Derivation` | see [builtins.derivation](f/builtins/derivation) | is just a special AttrSet. see [builtins.derivation](f/builtins/derivation) | +| `Any` | `?` | There is no `Any` type. Avoid using it. Use type variables (e.g. `a -> b`) instead if you want to allow variable type signatures. | +| `Number` | `Int {or} Float` | The `Number` is either of type `Int` or of type `Float` | +| `StorePath` | `Path` | The `StorePath` is just a meaningful alias of the type `Path` | + +## Examples + +These examples should give you a short feeling of correctly using type signatures. + +```haskell +bitOr :: Int -> Int -> Int +``` + +```haskell +map :: (a -> b) -> [a] -> [b] +``` + +```haskell +map :: (a -> b) -> [a] -> [b] +``` + +```haskell +mapAttrs :: (String -> a -> b) -> { ${name} :: a } -> { ${name} :: b } +``` + +> **Advice** +> +> In some cases it is very hard and complex to describe all behaviors. Keep it simple. + +--- + +Entering the last and likewise important chapter, 'Operators' + +## Operators + +__All Operators SHOULD be used with surrounding whitespace.__ + +### `::` declares the type + +e.g. `name :: String` + +### `()` Parenthesis + +Parenthesis to clarify order of type evaluation + +e.g. `( a -> b ) | Bool` + +Precedence: (Highest) + +### `;` Separator for subsequent entries (like in AttrSet) + +e.g. `{ foo :: Number; bar :: String }` + +> Currently this is very inconsistent in nixpkgs. +> +> Lets improve here + +### `|` syntactic or + +syntactic `Or` can be used for composition or enums + +Precedence: 2 + +#### Special Cases + +```hs +Any | a +``` + +Is always `Any`; Because any other type `a` must already be a subtype of any, due to the definition of `Any`. + +```hs +b | Never +``` + +Is always `b`; Due to the definition of `Never`; `b` must be a supertype of `Never`. + +### `...` - arbitrary input values + +can only be used within an AttrSet to allow any more `name-value pairs`. + +`...` = `${rest} :: a` within an AttrSet context + +Precedence: None + +### `->` arrow operator + +Allows for lambda types + +Precedence: 1 + +### `?` optional arguments in an AttrSet + +--e.g. `{ opt ? :: Int }` + +Precedence: None diff --git a/website/src/components/PositionLink.tsx b/website/src/components/PositionLink.tsx index 1e7d957..7a8742e 100644 --- a/website/src/components/PositionLink.tsx +++ b/website/src/components/PositionLink.tsx @@ -1,4 +1,4 @@ -import { DocMeta, FilePosition } from "@/models/data"; +import { ContentSource, DocMeta, FilePosition } from "@/models/data"; import { Box, Button, @@ -23,7 +23,13 @@ const getSourcePosition = (baseUrl: string, position: FilePosition): string => { return res; }; -export const PositionLink = ({ meta }: { meta: DocMeta }) => { +export const PositionLink = ({ + meta, + content, +}: { + meta: DocMeta; + content?: ContentSource; +}) => { const { attr_position, lambda_position, count_applied, content_meta } = meta; const contentPosition = content_meta?.position; @@ -96,15 +102,15 @@ export const PositionLink = ({ meta }: { meta: DocMeta }) => { `(${content_meta?.path?.join(".")})`} - {!contentPosition && ( + {!content?.content && ( <> {"Contribute"} - Sometimes documentation is missing or tooling support from noogle - is missing. + Enhance the ecosystem with your expertise! Contribute to fill the + gaps in documentation. Your input can make a difference. @@ -117,16 +123,18 @@ export const PositionLink = ({ meta }: { meta: DocMeta }) => { - - {/* */} - {/* */} - - {/* */} - {/* */} - + {!contentPosition && ( + + {/* */} + + + + {/* */} + + )} diff --git a/website/src/styles/globals.css b/website/src/styles/globals.css index 2edc36c..f05e425 100644 --- a/website/src/styles/globals.css +++ b/website/src/styles/globals.css @@ -6,10 +6,37 @@ body { scroll-behavior: smooth; } -/* a { - color: inherit; - text-decoration: none; -} */ +table{ + width: 100%; + border-collapse:collapse; + border:1px solid #d8e2ff; +} + +table td{ + padding: 8px; + border:1px solid #d8e2ff; +} +table th{ + padding: 8px; + border:1px solid #d8e2ff; +} +@media (prefers-color-scheme: dark) { + a { + color:#adc6ff; + } + table{ + border-color:#0f448e; + } + + table td{ + border-color:#0f448e; + } + table th{ + border-color:#0f448e; + } +} + + * { box-sizing: border-box;