diff --git a/tvix/website/default.nix b/tvix/website/default.nix deleted file mode 100644 index a2fc247e4..000000000 --- a/tvix/website/default.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ depot, lib, pkgs, ... }: - -let - description = "Rust implementation of the purely-functional Nix package manager"; - - # https://developers.google.com/search/docs/advanced/structured-data/ - # https://schema.org/SoftwareApplication - structuredData = { - "@context" = "https://schema.org"; - "@type" = "SoftwareApplication"; - name = "Tvix"; - url = "https://tvix.dev"; - abstract = description; - applicationCategory = "DeveloperApplication"; - contributor = "https://tvl.fyi"; - image = "https://tvix.dev/logo.webp"; - }; - - # All Tvix-related blog posts from the main TVL website - tvixPosts = builtins.filter - (post: !(post.draft or false) && (lib.hasInfix "Tvix" post.title)) - depot.web.tvl.blog.posts; - - postListEntries = map (p: "* [${p.title}](https://tvl.fyi/blog/${p.key})") tvixPosts; - - landing = depot.web.tvl.template { - title = "Tvix - A new implementation of Nix"; - content = '' - ${builtins.readFile ./landing-en.md} - ${builtins.concatStringsSep "\n" postListEntries} - ''; - - extraHead = '' - - - ''; - }; - -in -pkgs.runCommand "tvix-website" { } '' - mkdir $out - cp ${landing} $out/index.html - cp ${depot.tvix.logo}/logo.webp $out/ -'' diff --git a/web/atom-feed/default.nix b/web/atom-feed/default.nix deleted file mode 100644 index 27c90a7b9..000000000 --- a/web/atom-feed/default.nix +++ /dev/null @@ -1,153 +0,0 @@ -# This file defines functions for generating an Atom feed. - -{ depot, lib, pkgs, ... }: - -with depot.nix.yants; - -let - inherit (builtins) foldl' map readFile replaceStrings sort; - inherit (lib) concatStrings concatStringsSep max removeSuffix; - inherit (pkgs) runCommand; - - # 'link' describes a related link to a feed, or feed element. - # - # https://validator.w3.org/feed/docs/atom.html#link - link = struct "link" { - rel = string; - href = string; - }; - - # 'entry' describes a feed entry, for example a single post on a - # blog. Some optional fields have been omitted. - # - # https://validator.w3.org/feed/docs/atom.html#requiredEntryElements - entry = struct "entry" { - # Identifies the entry using a universally unique and permanent URI. - id = string; - - # Contains a human readable title for the entry. This value should - # not be blank. - title = string; - - # Content of the entry. - content = option string; - - # Indicates the last time the entry was modified in a significant - # way (in seconds since epoch). - updated = int; - - # Names authors of the entry. Recommended element. - authors = option (list string); - - # Related web pages, such as the web location of a blog post. - links = option (list link); - - # Conveys a short summary, abstract, or excerpt of the entry. - summary = option string; - - # Contains the time of the initial creation or first availability - # of the entry. - published = option int; - - # Conveys information about rights, e.g. copyrights, held in and - # over the entry. - rights = option string; - }; - - # 'feed' describes the metadata of the Atom feed itself. - # - # Some optional fields have been omitted. - # - # https://validator.w3.org/feed/docs/atom.html#requiredFeedElements - feed = struct "feed" { - # Identifies the feed using a universally unique and permanent URI. - id = string; - - # Contains a human readable title for the feed. - title = string; - - # Indicates the last time the feed was modified in a significant - # way (in seconds since epoch). Will be calculated based on most - # recently updated entry if unset. - updated = option int; - - # Entries contained within the feed. - entries = list entry; - - # Names authors of the feed. Recommended element. - authors = option (list string); - - # Related web locations. Recommended element. - links = option (list link); - - # Conveys information about rights, e.g. copyrights, held in and - # over the feed. - rights = option string; - - # Contains a human-readable description or subtitle for the feed. - subtitle = option string; - }; - - # Feed generation functions: - - renderEpoch = epoch: removeSuffix "\n" (readFile (runCommand "date-${toString epoch}" { } '' - date --date='@${toString epoch}' --utc --iso-8601='seconds' > $out - '')); - - escape = replaceStrings [ "<" ">" "&" "'" ] [ "<" ">" "&" "'" ]; - - elem = name: content: ''<${name}>${escape content}''; - - renderLink = defun [ link string ] (l: '' - - ''); - - # Technically the author element can also contain 'uri' and 'email' - # fields, but they are not used for the purpose of this feed and are - # omitted. - renderAuthor = author: ''${escape author}''; - - renderEntry = defun [ entry string ] (e: '' - - ${elem "title" e.title} - ${elem "id" e.id} - ${elem "updated" (renderEpoch e.updated)} - ${if e ? published - then elem "published" (renderEpoch e.published) - else "" - } - ${if e ? content - then ''${escape e.content}'' - else "" - } - ${if e ? summary then elem "summary" e.summary else ""} - ${concatStrings (map renderAuthor (e.authors or []))} - ${if e ? subtitle then elem "subtitle" e.subtitle else ""} - ${if e ? rights then elem "rights" e.rights else ""} - ${concatStrings (map renderLink (e.links or []))} - - ''); - - mostRecentlyUpdated = defun [ (list entry) int ] (entries: - foldl' max 0 (map (e: e.updated) entries) - ); - - sortEntries = sort (a: b: a.published > b.published); - - renderFeed = defun [ feed string ] (f: '' - - - ${elem "id" f.id} - ${elem "title" f.title} - ${elem "updated" (renderEpoch (f.updated or (mostRecentlyUpdated f.entries)))} - ${concatStringsSep "\n" (map renderAuthor (f.authors or []))} - ${if f ? subtitle then elem "subtitle" f.subtitle else ""} - ${if f ? rights then elem "rights" f.rights else ""} - ${concatStrings (map renderLink (f.links or []))} - ${concatStrings (map renderEntry (sortEntries f.entries))} - - ''); -in -{ - inherit entry feed renderFeed renderEpoch; -} diff --git a/web/blog/default.nix b/web/blog/default.nix deleted file mode 100644 index 696a9529c..000000000 --- a/web/blog/default.nix +++ /dev/null @@ -1,70 +0,0 @@ -# This creates the static files that make up my blog from the Markdown -# files in this repository. -# -# All blog posts are rendered from Markdown by cheddar. -{ depot, lib, pkgs, ... }@args: - -with depot.nix.yants; - -let - inherit (builtins) readFile; - inherit (depot.nix) renderMarkdown; - inherit (depot.web) atom-feed; - inherit (lib) singleton; - - # Type definition for a single blog post. - post = struct "blog-post" { - key = string; - title = string; - date = int; - - # Optional time at which this post was last updated. - updated = option int; - - # Path to the Markdown file containing the post content. - content = path; - - # Whether dangerous HTML tags should be filtered in this post. Can - # be disabled to, for example, embed videos in a post. - tagfilter = option bool; - - # Optional name of the author to display. - author = option string; - - # Should this post be included in the index? (defaults to true) - listed = option bool; - - # Is this a draft? (adds a banner indicating that the link should - # not be shared) - draft = option bool; - - # Previously each post title had a numeric ID. For these numeric - # IDs, redirects are generated so that old URLs stay compatible. - oldKey = option string; - }; - - # Rendering fragments for the HTML version of the blog. - fragments = import ./fragments.nix args; - - # Functions for generating feeds for these blogs using //web/atom-feed. - toFeedEntry = { baseUrl, ... }: defun [ post atom-feed.entry ] (post: rec { - id = "${baseUrl}/${post.key}"; - title = post.title; - content = readFile (renderMarkdown post.content); - published = post.date; - updated = post.updated or post.date; - - links = singleton { - rel = "alternate"; - href = id; - }; - }); -in -{ - inherit post toFeedEntry; - inherit (fragments) renderPost; - - # Helper function to determine whether a post should be included in - # listings (on homepages, feeds, ...) - includePost = post: !(fragments.isDraft post) && !(fragments.isUnlisted post); -} diff --git a/web/blog/fragments.nix b/web/blog/fragments.nix deleted file mode 100644 index 20fb879d9..000000000 --- a/web/blog/fragments.nix +++ /dev/null @@ -1,95 +0,0 @@ -# This file defines various fragments of the blog, such as the header -# and footer, as functions that receive arguments to be templated into -# them. -# -# An entire post is rendered by `renderPost`, which assembles the -# fragments together in a runCommand execution. -{ depot, lib, pkgs, ... }: - -let - inherit (builtins) filter map hasAttr replaceStrings; - inherit (pkgs) runCommand writeText; - inherit (depot.nix) renderMarkdown; - - # Generate a post list for all listed, non-draft posts. - isDraft = post: (hasAttr "draft" post) && post.draft; - isUnlisted = post: (hasAttr "listed" post) && !post.listed; - - escape = replaceStrings [ "<" ">" "&" "'" ] [ "<" ">" "&" "'" ]; - - header = name: title: staticUrl: '' - - - - - - - - - ${escape name}: ${escape title} - - -
-

${escape name}

-
-
- ''; - - fullFooter = content: '' -
- - - ''; - - draftWarning = writeText "draft.html" '' -

- Note: This post is a draft! Please do not share - the link to it without asking first. -

-
- ''; - - unlistedWarning = writeText "unlisted.html" '' -

- Note: This post is unlisted! Please do not share - the link to it without asking first. -

-
- ''; - - renderPost = { name, footer, staticUrl ? "https://static.tvl.fyi/${depot.web.static.drvHash}", ... }: post: runCommand "${post.key}.html" { } '' - cat ${writeText "header.html" (header name post.title staticUrl)} > $out - - # Write the post title & date - echo '

${escape post.title}

' >> $out - echo '' >> $out - - ${ - # Add a warning to draft/unlisted posts to make it clear that - # people should not share the post. - - if (isDraft post) then "cat ${draftWarning} >> $out" - else if (isUnlisted post) then "cat ${unlistedWarning} >> $out" - else "# Your ads could be here?" - } - - # Write the actual post through cheddar's about-filter mechanism - cat ${renderMarkdown { path = post.content; tagfilter = post.tagfilter or true; }} >> $out - echo '
' >> $out - - cat ${writeText "footer.html" (fullFooter footer)} >> $out - ''; -in -{ - inherit isDraft isUnlisted renderPost; -} diff --git a/web/static/default.nix b/web/static/default.nix deleted file mode 100644 index 9eaeb0ec1..000000000 --- a/web/static/default.nix +++ /dev/null @@ -1,29 +0,0 @@ -# Expose all static assets as a folder. The derivation contains a -# `drvHash` attribute which can be used for cache-busting. -{ depot, lib, pkgs, ... }: - -let - storeDirLength = with builtins; (stringLength storeDir) + 1; - logo = depot.web.tvl.logo; -in -lib.fix (self: pkgs.runCommand "tvl-static" -{ - passthru = { - # Preserving the string context here makes little sense: While we are - # referencing this derivation, we are not doing so via the nix store, - # so it makes little sense for Nix to police the references. - drvHash = builtins.unsafeDiscardStringContext ( - lib.substring storeDirLength 32 self.drvPath - ); - }; -} '' - mkdir $out - cp -r ${./.}/* $out - cp ${logo.pastelRainbow} $out/logo-animated.svg - cp ${logo.bluePng} $out/logo-blue.png - cp ${logo.greenPng} $out/logo-green.png - cp ${logo.orangePng} $out/logo-orange.png - cp ${logo.purplePng} $out/logo-purple.png - cp ${logo.redPng} $out/logo-red.png - cp ${logo.yellowPng} $out/logo-yellow.png -'') diff --git a/web/static/favicon.webp b/web/static/favicon.webp deleted file mode 100644 index 741cdbc64..000000000 Binary files a/web/static/favicon.webp and /dev/null differ diff --git a/web/static/files/adisbladis_tazjin_tvix.webp b/web/static/files/adisbladis_tazjin_tvix.webp deleted file mode 100644 index 38e004543..000000000 Binary files a/web/static/files/adisbladis_tazjin_tvix.webp and /dev/null differ diff --git a/web/static/files/flokli_tazjin_tvix.webp b/web/static/files/flokli_tazjin_tvix.webp deleted file mode 100644 index 4c0b94903..000000000 Binary files a/web/static/files/flokli_tazjin_tvix.webp and /dev/null differ diff --git a/web/static/jetbrains-mono-bold-italic.woff2 b/web/static/jetbrains-mono-bold-italic.woff2 deleted file mode 100644 index 34b5c69ae..000000000 Binary files a/web/static/jetbrains-mono-bold-italic.woff2 and /dev/null differ diff --git a/web/static/jetbrains-mono-bold.woff2 b/web/static/jetbrains-mono-bold.woff2 deleted file mode 100644 index 84a008af7..000000000 Binary files a/web/static/jetbrains-mono-bold.woff2 and /dev/null differ diff --git a/web/static/jetbrains-mono-italic.woff2 b/web/static/jetbrains-mono-italic.woff2 deleted file mode 100644 index 85fd46878..000000000 Binary files a/web/static/jetbrains-mono-italic.woff2 and /dev/null differ diff --git a/web/static/jetbrains-mono.woff2 b/web/static/jetbrains-mono.woff2 deleted file mode 100644 index d5b94cb9e..000000000 Binary files a/web/static/jetbrains-mono.woff2 and /dev/null differ diff --git a/web/static/terminal.min.css b/web/static/terminal.min.css deleted file mode 100644 index 828978582..000000000 --- a/web/static/terminal.min.css +++ /dev/null @@ -1 +0,0 @@ -/* SPDX-License-Identifier: MIT; https://terminalcss.xyz/ */ :root{--global-font-size:15px;--global-line-height:1.4em;--global-space:10px;--font-stack:Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;--mono-font-stack:Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;--background-color:#fff;--page-width:60em;--font-color:#151515;--invert-font-color:#fff;--primary-color:#1a95e0;--secondary-color:#727578;--error-color:#d20962;--progress-bar-background:#727578;--progress-bar-fill:#151515;--code-bg-color:#e8eff2;--input-style:solid;--display-h1-decoration:none}*{box-sizing:border-box;text-rendering:geometricPrecision}::-moz-selection{background:var(--primary-color);color:var(--invert-font-color)}::selection{background:var(--primary-color);color:var(--invert-font-color)}body{font-size:var(--global-font-size);color:var(--font-color);line-height:var(--global-line-height);margin:0;font-family:var(--font-stack);word-wrap:break-word;background-color:var(--background-color)}.logo,h1,h2,h3,h4,h5,h6{line-height:var(--global-line-height)}a{cursor:pointer;color:var(--primary-color);text-decoration:none}a:hover{background-color:var(--primary-color);color:var(--invert-font-color)}em{font-size:var(--global-font-size);font-style:italic;font-family:var(--font-stack);color:var(--font-color)}blockquote,code,em,strong{line-height:var(--global-line-height)}.logo,blockquote,code,footer,h1,h2,h3,h4,h5,h6,header,li,ol,p,section,ul{float:none;margin:0;padding:0}.logo,blockquote,h1,ol,p,ul{margin-top:calc(var(--global-space) * 2);margin-bottom:calc(var(--global-space) * 2)}.logo,h1{position:relative;display:inline-block;display:table-cell;padding:calc(var(--global-space) * 2) 0 calc(var(--global-space) * 2);margin:0;overflow:hidden;font-weight:600}h1::after{content:"====================================================================================================";position:absolute;bottom:5px;left:0;display:var(--display-h1-decoration)}.logo+*,h1+*{margin-top:0}h2,h3,h4,h5,h6{position:relative;margin-bottom:var(--global-line-height);font-weight:600}blockquote{position:relative;padding-left:calc(var(--global-space) * 2);padding-left:2ch;overflow:hidden}blockquote::after{content:">\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>";white-space:pre;position:absolute;top:0;left:0;line-height:var(--global-line-height);color:#9ca2ab}code{font-weight:inherit;background-color:var(--code-bg-color);font-family:var(--mono-font-stack)}code::after,code::before{content:"`";display:inline}pre code::after,pre code::before{content:""}pre{display:block;word-break:break-all;word-wrap:break-word;color:var(--secondary-color);background-color:var(--background-color);border:1px solid var(--secondary-color);padding:var(--global-space);white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap}pre code{overflow-x:scroll;padding:0;margin:0;display:inline-block;min-width:100%;font-family:var(--mono-font-stack)}.terminal .logo,.terminal blockquote,.terminal code,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal strong{font-size:var(--global-font-size);font-style:normal;font-family:var(--font-stack);color:var(--font-color)}.terminal-prompt{position:relative;white-space:nowrap}.terminal-prompt::before{content:"> "}.terminal-prompt::after{content:"";-webkit-animation:cursor .8s infinite;animation:cursor .8s infinite;background:var(--primary-color);border-radius:0;display:inline-block;height:1em;margin-left:.2em;width:3px;bottom:-2px;position:relative}@-webkit-keyframes cursor{0%{opacity:0}50%{opacity:1}to{opacity:0}}@keyframes cursor{0%{opacity:0}50%{opacity:1}to{opacity:0}}li,li>ul>li{position:relative;display:block;padding-left:calc(var(--global-space) * 2)}nav>ul>li{padding-left:0}li::after{position:absolute;top:0;left:0}ul>li::after{content:"-"}nav ul>li::after{content:""}ol li::before{content:counters(item, ".") ". ";counter-increment:item}ol ol li::before{content:counters(item, ".") " ";counter-increment:item}.terminal-menu li::after,.terminal-menu li::before{display:none}ol{counter-reset:item}ol li:nth-child(n+10)::after{left:-7px}ol ol{margin-top:0;margin-bottom:0}.terminal-menu{width:100%}.terminal-nav{display:flex;flex-direction:column;align-items:flex-start}ul ul{margin-top:0;margin-bottom:0}.terminal-menu ul{list-style-type:none;padding:0!important;display:flex;flex-direction:column;width:100%;flex-grow:1;font-size:var(--global-font-size);margin-top:0}.terminal-menu li{display:flex;margin:0 0 .5em 0;padding:0}ol.terminal-toc li{border-bottom:1px dotted var(--secondary-color);padding:0;margin-bottom:15px}.terminal-menu li:last-child{margin-bottom:0}ol.terminal-toc li a{margin:4px 4px 4px 0;background:var(--background-color);position:relative;top:6px;text-align:left;padding-right:4px}.terminal-menu li a:not(.btn){text-decoration:none;display:block;width:100%;border:none;color:var(--secondary-color)}.terminal-menu li a.active{color:var(--font-color)}.terminal-menu li a:hover{background:0 0;color:inherit}ol.terminal-toc li::before{content:counters(item, ".") ". ";counter-increment:item;position:absolute;right:0;background:var(--background-color);padding:4px 0 4px 4px;bottom:-8px}ol.terminal-toc li a:hover{background:var(--primary-color);color:var(--invert-font-color)}hr{position:relative;overflow:hidden;margin:calc(var(--global-space) * 4) 0;border:0;border-bottom:1px dashed var(--secondary-color)}p{margin:0 0 var(--global-line-height);color:var(--global-font-color)}.container{max-width:var(--page-width)}.container,.container-fluid{margin:0 auto;padding:0 calc(var(--global-space) * 2)}img{width:100%}.progress-bar{height:8px;background-color:var(--progress-bar-background);margin:12px 0}.progress-bar.progress-bar-show-percent{margin-top:38px}.progress-bar-filled{background-color:var(--progress-bar-fill);height:100%;transition:width .3s ease;position:relative;width:0}.progress-bar-filled::before{content:"";border:6px solid transparent;border-top-color:var(--progress-bar-fill);position:absolute;top:-12px;right:-6px}.progress-bar-filled::after{color:var(--progress-bar-fill);content:attr(data-filled);display:block;font-size:12px;white-space:nowrap;position:absolute;border:6px solid transparent;top:-38px;right:0;transform:translateX(50%)}.progress-bar-no-arrow>.progress-bar-filled::after,.progress-bar-no-arrow>.progress-bar-filled::before{content:"";display:none;visibility:hidden;opacity:0}table{width:100%;border-collapse:collapse;margin:var(--global-line-height) 0;color:var(--font-color);font-size:var(--global-font-size)}table td,table th{vertical-align:top;border:1px solid var(--font-color);line-height:var(--global-line-height);padding:calc(var(--global-space)/ 2);font-size:1em}table thead th{font-size:1em}table tfoot tr th{font-weight:500}table caption{font-size:1em;margin:0 0 1em 0}table tbody td:first-child{font-weight:700;color:var(--secondary-color)}.form{width:100%}fieldset{border:1px solid var(--font-color);padding:1em}label{font-size:1em;color:var(--font-color)}input[type=email],input[type=number],input[type=password],input[type=search],input[type=text]{border:1px var(--input-style) var(--font-color);width:100%;padding:.7em .5em;font-size:1em;font-family:var(--font-stack);-webkit-appearance:none;border-radius:0}input[type=email]:active,input[type=email]:focus,input[type=number]:active,input[type=number]:focus,input[type=password]:active,input[type=password]:focus,input[type=search]:active,input[type=search]:focus,input[type=text]:active,input[type=text]:focus{outline:0;-webkit-appearance:none;border:1px solid var(--font-color)}input[type=email]:not(:placeholder-shown):invalid,input[type=number]:not(:placeholder-shown):invalid,input[type=password]:not(:placeholder-shown):invalid,input[type=search]:not(:placeholder-shown):invalid,input[type=text]:not(:placeholder-shown):invalid{border-color:var(--error-color)}input,textarea{color:var(--font-color);background-color:var(--background-color)}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:var(--secondary-color)!important;opacity:1}input::-moz-placeholder,textarea::-moz-placeholder{color:var(--secondary-color)!important;opacity:1}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--secondary-color)!important;opacity:1}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--secondary-color)!important;opacity:1}input::placeholder,textarea::placeholder{color:var(--secondary-color)!important;opacity:1}textarea{height:auto;width:100%;resize:none;border:1px var(--input-style) var(--font-color);padding:.5em;font-size:1em;font-family:var(--font-stack);-webkit-appearance:none;border-radius:0}textarea:focus{outline:0;-webkit-appearance:none;border:1px solid var(--font-color)}textarea:not(:placeholder-shown):invalid{border-color:var(--error-color)}input:-webkit-autofill,input:-webkit-autofill:focus textarea:-webkit-autofill,input:-webkit-autofill:hover,select:-webkit-autofill,select:-webkit-autofill:focus,select:-webkit-autofill:hover,textarea:-webkit-autofill:hover textarea:-webkit-autofill:focus{border:1px solid var(--font-color);-webkit-text-fill-color:var(--font-color);box-shadow:0 0 0 1000px var(--invert-font-color) inset;-webkit-box-shadow:0 0 0 1000px var(--invert-font-color) inset;transition:background-color 5000s ease-in-out 0s}.form-group{margin-bottom:var(--global-line-height);overflow:auto}.btn{border-style:solid;border-width:1px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;outline:0;padding:.65em 2em;font-size:1em;font-family:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;z-index:1}.btn:active{box-shadow:none}.btn.btn-ghost{border-color:var(--font-color);color:var(--font-color);background-color:transparent}.btn.btn-ghost:focus,.btn.btn-ghost:hover{border-color:var(--tertiary-color);color:var(--tertiary-color);z-index:2}.btn.btn-ghost:hover{background-color:transparent}.btn-block{width:100%;display:flex}.btn-default{background-color:var(--font-color);border-color:var(--invert-font-color);color:var(--invert-font-color)}.btn-default:focus:not(.btn-ghost),.btn-default:hover{background-color:var(--secondary-color);color:var(--invert-font-color)}.btn-default.btn-ghost:focus,.btn-default.btn-ghost:hover{border-color:var(--secondary-color);color:var(--secondary-color);z-index:2}.btn-error{color:var(--invert-font-color);background-color:var(--error-color);border:1px solid var(--error-color)}.btn-error:focus:not(.btn-ghost),.btn-error:hover{background-color:var(--error-color);border-color:var(--error-color)}.btn-error.btn-ghost{border-color:var(--error-color);color:var(--error-color)}.btn-error.btn-ghost:focus,.btn-error.btn-ghost:hover{border-color:var(--error-color);color:var(--error-color);z-index:2}.btn-primary{color:var(--invert-font-color);background-color:var(--primary-color);border:1px solid var(--primary-color)}.btn-primary:focus:not(.btn-ghost),.btn-primary:hover{background-color:var(--primary-color);border-color:var(--primary-color)}.btn-primary.btn-ghost{border-color:var(--primary-color);color:var(--primary-color)}.btn-primary.btn-ghost:focus,.btn-primary.btn-ghost:hover{border-color:var(--primary-color);color:var(--primary-color);z-index:2}.btn-small{padding:.5em 1.3em!important;font-size:.9em!important}.btn-group{overflow:auto}.btn-group .btn{float:left}.btn-group .btn-ghost:not(:first-child){margin-left:-1px}.terminal-card{border:1px solid var(--secondary-color)}.terminal-card>header{color:var(--invert-font-color);text-align:center;background-color:var(--secondary-color);padding:.5em 0}.terminal-card>div:first-of-type{padding:var(--global-space)}.terminal-timeline{position:relative;padding-left:70px}.terminal-timeline::before{content:' ';background:var(--secondary-color);display:inline-block;position:absolute;left:35px;width:2px;height:100%;z-index:400}.terminal-timeline .terminal-card{margin-bottom:25px}.terminal-timeline .terminal-card::before{content:' ';background:var(--invert-font-color);border:2px solid var(--secondary-color);display:inline-block;position:absolute;margin-top:25px;left:26px;width:15px;height:15px;z-index:400}.terminal-alert{color:var(--font-color);padding:1em;border:1px solid var(--font-color);margin-bottom:var(--global-space)}.terminal-alert-error{color:var(--error-color);border-color:var(--error-color)}.terminal-alert-primary{color:var(--primary-color);border-color:var(--primary-color)}@media screen and (max-width:960px){label{display:block;width:100%}pre::-webkit-scrollbar{height:3px}}@media screen and (max-width:480px){form{width:100%}}@media only screen and (min-width:30em){.terminal-nav{flex-direction:row;align-items:center}.terminal-menu ul{flex-direction:row;justify-items:flex-end;align-items:center;justify-content:flex-end;margin-top:calc(var(--global-space) * 2)}.terminal-menu li{margin:0;margin-right:2em}.terminal-menu li:last-child{margin-right:0}}.terminal-media:not(:last-child){margin-bottom:1.25rem}.terminal-media-left{padding-right:var(--global-space)}.terminal-media-left,.terminal-media-right{display:table-cell;vertical-align:top}.terminal-media-right{padding-left:var(--global-space)}.terminal-media-body{display:table-cell;vertical-align:top}.terminal-media-heading{font-size:1em;font-weight:700}.terminal-media-content{margin-top:.3rem}.terminal-placeholder{background-color:var(--secondary-color);text-align:center;color:var(--font-color);font-size:1rem;border:1px solid var(--secondary-color)}figure>img{padding:0}.terminal-avatarholder{width:calc(var(--global-space) * 5);height:calc(var(--global-space) * 5)}.terminal-avatarholder img{padding:0}figure{margin:0}figure>figcaption{color:var(--secondary-color);text-align:center}.hljs{display:block;overflow-x:auto;padding:.5em;background:var(--block-background-color);color:var(--font-color)}.hljs-comment,.hljs-quote{color:var(--secondary-color)}.hljs-variable{color:var(--font-color)}.hljs-built_in,.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:var(--primary-color)}.hljs-addition,.hljs-attribute,.hljs-literal,.hljs-section,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type{color:var(--secondary-color)}.hljs-string{color:var(--secondary-color)}.hljs-deletion,.hljs-meta,.hljs-selector-attr,.hljs-selector-pseudo{color:var(--primary-color)}.hljs-doctag{color:var(--secondary-color)}.hljs-attr{color:var(--primary-color)}.hljs-bullet,.hljs-link,.hljs-symbol{color:var(--primary-color)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} diff --git a/web/static/tvl.css b/web/static/tvl.css deleted file mode 100644 index b28736bce..000000000 --- a/web/static/tvl.css +++ /dev/null @@ -1,136 +0,0 @@ -/* Jetbrains Mono font from https://www.jetbrains.com/lp/mono/ - licensed under Apache 2.0. Thanks, Jetbrains! */ -@font-face { - font-family: jetbrains-mono; - src: url(jetbrains-mono.woff2); -} - -@font-face { - font-family: jetbrains-mono; - font-weight: bold; - src: url(jetbrains-mono-bold.woff2); -} - -@font-face { - font-family: jetbrains-mono; - font-style: italic; - src: url(jetbrains-mono-italic.woff2); -} - -@font-face { - font-family: jetbrains-mono; - font-weight: bold; - font-style: italic; - src: url(jetbrains-mono-bold-italic.woff2); -} - -/* Generic-purpose styling */ - -body { - max-width: 800px; - margin: 40px auto; - line-height: 1.6; - font-size: 18px; - padding: 0 10px; - font-family: jetbrains-mono, monospace; -} - -h1, h2, h3 { - line-height: 1.2 -} - -/* Blog Posts */ - -article { - line-height: 1.5em; -} - -/* spacing between the paragraphs in blog posts */ -article p { - margin: 1.4em auto; -} - -/* Blog styling */ - -.light { - color: #383838; -} - -.blog-title { - color: inherit; - text-decoration: none; -} - -.footer { - text-align: right; -} - -.date { - text-align: right; - font-style: italic; - float: right; -} - -.inline { - display: inline; -} - -.lod { - text-align: center; -} - -.uncoloured-link { - color: inherit; -} - -pre { - width: 100%; - overflow: auto; -} - -code { - background: aliceblue; -} - -img { - max-width: 100%; -} - -.cheddar-callout { - display: block; - padding: 10px; -} - -.cheddar-question { - color: #3367d6; - background-color: #e8f0fe; -} - -.cheddar-todo { - color: #616161; - background-color: #eeeeee; -} - -.cheddar-tip { - color: #00796b; - background-color: #e0f2f1; -} - -.cheddar-warning { - color: #a52714; - background-color: #fbe9e7; -} - -kbd { - background-color: #eee; - border-radius: 3px; - border: 1px solid #b4b4b4; - box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255, 255, 255, .7) inset; - color: #333; - display: inline-block; - font-size: .85em; - font-weight: 700; - line-height: 1; - padding: 2px 4px; - white-space: nowrap; -} diff --git a/web/tvl/OWNERS b/web/tvl/OWNERS deleted file mode 100644 index ba1c06534..000000000 --- a/web/tvl/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -set noparent - -tazjin diff --git a/web/tvl/blog/2024-02-tvix-update.md b/web/tvl/blog/2024-02-tvix-update.md deleted file mode 100644 index 648c4b803..000000000 --- a/web/tvl/blog/2024-02-tvix-update.md +++ /dev/null @@ -1,333 +0,0 @@ -We've now been working on our rewrite of Nix, [Tvix][], for a little more than -two years. - -Our last written update was in September 2023, and although we did publish a -couple of things in the meantime (flokli's talk on Tvix at [NixCon -2023][nixcon2023], our interview at the [Nix Developer -Dialogues][nix-dev-dialogues-tvix], or tazjin's [talk on -tvix-eval][tvix-eval-ru] (in Russian)), we never found the time to write -something down. - -In the meantime a lot of stuff has happened though, so it's time to change that -:-) - -Note: This blog post is intended for a technical audience that is already -intimately familiar with Nix, and knows what things like derivations or store -paths are. If you're new to Nix, this will not make a lot of sense to you! - -## Evaluation regression testing - -Most of the evaluator work has been driven by evaluating `nixpkgs`, and ensuring -that we produce the same derivations, and that their build results end up in the -same store paths. - -Builds are not hooked up all the way to the evaluator yet, but for Nix code -without IFD (such as `nixpkgs`!) we can verify this property without building. -An evaluated Nix derivation's `outPath` (and `drvPath`) can be compared with -what C++ Nix produces for the same code, to determine whether we evaluated the -package (and all of its dependencies!) correctly [^1]. - -We added integration tests in CI that ensure that the paths we calculate match -C++ Nix, and are successfully evaluating fairly complicated expressions in them. -For example, we test against the Firefox derivation, which exercises some of the -more hairy bits in `nixpkgs` (like WASM cross-compilation infrastructure). Yay! - -Although we're avoiding fine-grained optimization until we're sure Tvix -evaluates all of `nixpkgs` correctly, we still want to have an idea about -evaluation performance and how our work affects it over time. - -For this we extended our benchmark suite and integrated it with -[Windtunnel][windtunnel], which now regularly runs benchmarks and provides a -view into how the timings change from commit to commit. - -In the future, we plan to run this as a part of code review, before changes are -applied to our canonical branch, to provide this as an additional signal to -authors and reviewers without having to run the benchmarks manually. - -## ATerms, output path calculation, and `builtins.derivation` - -We've implemented all of these features, which comprise the components needed to -construct derivations in the Nix language, and to allow us to perform the path -comparisons we mentioned before. - -As an interesting side note, in C++ Nix `builtins.derivation` is not actually a -builtin! It is a piece of [bundled Nix code][nixcpp-builtins-derivation], that -massages some parameters and then calls the *actual* builtin: -`derivationStrict`. We've decided to keep this setup, and implemented support in -Tvix to have builtins defined in `.nix` source code. - -These builtins return attribute sets with the previously mentioned `outPath` and -`drvPath` fields. Implementing them correctly meant that we needed to implement -output path calculation *exactly* the same way as Nix does (bit-by-bit). - -Very little of how this output path calculation works is documented anywhere in -C++ Nix. It uses a subset of [ATerm][aterm] internally, produces "fingerprints" -containing hashes of these ATerms, which are then hashed again. The intermediate -hashes are not printed out anywhere (except if you [patch -Nix][nixcpp-patch-hashes] to do so). - -We already did parts of this correctly while starting this work on -[go-nix][go-nix-outpath] some while ago, but found some more edge cases and -ultimately came up with a nicer interface for Tvix. - -All the Derivation internal data model, ATerm serialization and output path -calculation have been sliced out into a more general-purpose -[nix-compat][nix-compat-derivation] crate, alongside with more documentation -unit tests and a Derivation ATerm parser, so hopefully this will now be more -accessible for everyone now. - -Note our builtin does *not* yet persist the Derivation anywhere "on -disk" (though we have a debug CL that does write it to a temporary directory, -in case we want to track down differences). - -## `tvix-[ca]store` -Tvix now has a store implementation! - -### The Nix model -Inside Nix, store path contents are normally hashed and communicated in NAR -format, which is very coarse and often wasteful - a single bit of change in one -file in a large store path causes a new NAR file to be uploaded to the binary -cache, which then needs to be downloaded. - -Additionally, identifying everything by the SHA256 digest of its NAR -representation makes Nix store paths very incompatible with other -content-addressed systems, as it's a very Nix-specific format. - -### The more granular Tvix model -After experimenting with some concepts and ideas in Golang, mostly around how to -improve binary cache performance[^3], both on-disk as well as over the network, -we settled on a more granular, content-addressed and general-purpose format. - -Internally, it behaves very similar to how git handles tree objects, except -blobs are identified by their raw BLAKE3 digests rather than some custom -encoding, and similarly, tree/directory objects use the BLAKE3 digest of its -canonical protobuf serialization as identifiers. - -This provides some immediate benefits: - - We only need to keep the same data once, even if it's used across different - store paths. - - Transfers can be more granular and only need to fetch the data that's - needed. Due to everything being content-addressed, it can be fetched from - anything supporting BLAKE3 digests, immediately making it compatible with - other P2P systems (IPFS blake3 blobs, …), or general-purpose - content-addressed caches ([bazel-remote]). - -There's a lot more details about the data model, certain decisions etc. in -[the docs][castore-docs]. - -### Compatibility -We however still want to stay compatible with Nix, as in calculating -"NAR-addressed" store paths the same, support substituting from regular Nix -binary caches, as well as storing all the other additional metadata about store -paths. - -We accomplished this by splitting the two different concerns into two separate -`tvix-store` and `tvix-castore` crates, with the former one holding all -Nix-specific metadata and functionality, and the latter being a general-purpose -content-addressed blob and filesystem tree storage system, which is usable in a -lot of contexts outside of Tvix too. For example, if you want to use -tvix-castore to write your own git alternative, or provide granular and -authenticated access into large scientific datasets, you could! - -### Backends -In addition to a gRPC API and client bindings, there's support for local -filesystem-based backends, as well as for sled, an embedded K/V database. - -We're also currently working on a backend supporting most common object -storages, as well as on more granular seeking and content-defined chunking for -blobs. - -### FUSE/virtiofs -A tvix-store can be mounted via FUSE, or exposed through virtiofs[^4]. -While doing the obvious thing - allowing mounting and browsing the contents -of the store, this will allow lazy substitution of builds on remote builders, be -in containerized or virtualized workloads. - -We have an [example][tvix-boot-readme] in the repository seeding gnu hello into -a throwaway store, then booting a MicroVM and executing it. - -### nar-bridge, bridging binary caches -`nar-bridge` and the `NixHTTPPathInfoService` bridge `tvix-[ca]store` with -existing Nix binary caches and Nix. - -The former exposes a `tvix-[ca]store` over the common Nix HTTP Binary Cache -interface (both read and write). - -The latter allows Tvix to substitute from regular Nix HTTP Binary caches, -unpacking NARs and ingesting them on-the-fly into the castore model. -The necessary parsers for NARInfo, signatures etc are also available in the -[nix-compat crate][nix-compat-narinfo]. - -## EvalIO / builtins interacting with the store more closely -tvix-eval itself is designed to be quite pure when it comes to IO - it doesn't -do any IO directly on its own, but for the very little IO functionality it -does as part of "basic interaction with paths" (like importing other -`.nix` files), it goes through an `EvalIO` interface, which is provided to the -Evaluator struct on instantiation. - -This allows us to be a bit more flexible with how IO looks like in practice, -which becomes interesting for specific store implementations that might not -expose a POSIX filesystem directly, or targets where we don't have a filesystem -at all (like WASM). - -Using the `EvalIO` trait also lets `tvix-eval` avoid becoming too strongly -coupled to a specific store implementation, hashing scheme etc[^2]. As we can -extend the set of builtins available to the evaluator with "foreign builtins", -these can live in other crates. - -Following this pattern, we started implementing some of the "basic" builtins -that deal with path access in `tvix-eval`, like: - - - `builtins.pathExists` - - `builtins.readFile` - -We also recently started working on more complicated builtins like -`builtins.filterSource` and `builtins.path`, which are also used in `nixpkgs`. - -Both import a path into the store, and allow passing a Nix expression that's -used as a filter function for each path. `builtins.path` can also ensuring the -imported contents match a certain hash. - -This required the builtin to interact with the store and evaluator in a very -tight fashion, as the filter function (written in Nix) needs to be repeatedly -executed for each path, and its return value is able to cause the store to skip -over certain paths (which it previously couldn't). - -Getting the abstractions right there required some back-and-forth, but the -remaining changes should land quite soon. - -## Catchables / tryEval - -Nix has a limited exception system for dealing with user-generated errors: -`builtins.tryEval` can be used to detect if an expression fails (if -`builtins.throw` or `assert` are used to generate it). This feature requires -extra support in any Nix implementation, as errors may not necessarily cause the -Nix program to abort. - -The C++ Nix implementation reuses the C++ language-provided Exception system for -`builtins.tryEval` which Tvix can't (even if Rust had an equivalent system): - -In C++ Nix the runtime representation of the program in execution corresponds -to the Nix expression tree of the relevant source files. This means that an -exception raised in C++ code will automatically bubble up correctly since the -C++ and Nix call stacks are equivalent to each other. - -Tvix compiles the Nix expressions to a byte code program which may be mutated by -extra optimization rules (for example, we hope to eliminate as many thunks as -possible in the future). This means that such a correspondence between the state -of the runtime and the original Nix code is not guaranteed. - -Previously, `builtins.tryEval` (which is implemented in Rust and can access VM -internals) just allowed the VM to recover from certain kinds of errors. This -proved to be insufficient as it [blew up as soon as a `builtins.tryEval`-ed -thunk is forced again][tryeval-infrec] – extra bookkeeping was needed. As a -solution, we now store recoverable errors as a separate runtime value type. - -As you can imagine, storing evaluation failures as "normal" values quickly leads -to all sorts of bugs because most VM/builtins code is written with only ordinary -values like attribute sets, strings etc. in mind. - -While ironing those out, we made sure to supplement those fixes with as many -test cases for `builtins.tryEval` as possible. This will hopefully prevent any -regressions if or rather when we touch this system again. We already have some -ideas for replacing the `Catchable` value type with a cleaner representation, -but first we want to pin down all the unspoken behaviour. - -## String contexts - -For a long time, we had the [working theory][refscan-string-contexts] that we -could get away with not implementing string contexts, and instead do reference -scanning on a set of "known paths" (and not implement -`builtins.unsafeDiscardStringContext`). - -Unfortunately, we discovered that while this is *conceptually* true, due to a -[bug in Nix][string-contexts-nix-bug] that's worked around in the -`stdenv.mkDerivation` implementation, we can't currently do this and calculate -the same hashes. - -Because hash compatibility is important for us at this point, we bit the bullet -and added support for string contexts into our `NixString` implementation, -implemented the context-related builtins, and added more unit tests that verify -string context behaviour of various builtins. - -## Strings as byte strings - -C++ Nix uses C-style zero-terminated strings internally - however, until -recently, Tvix has used standard Rust strings for string values. Since those are -required to be valid UTF-8, we haven't been able to properly represent all the -string values that Nix supports. - -We recently converted our internal representation to byte strings, which allows -us to treat a `Vec` as a "string-like" value. - -## JSON/TOML/XML - -We added support for the `toJSON`, `toXML`, `fromJSON` and `fromTOML` builtins. - -`toXML` is particularly exciting, as it's the only format that allows expressing -(partially applied) functions. It's also used in some of Nix' own test suite, so -we can now include these in our unit test suite (and pass, yay!). - -## Builder protocol, drv->builder - -We've been working on the builder protocol, and Tvix's internal build -representation. - -Nix uses derivations (encoded in ATerm) as nodes in its build graph, but it -refers to other store paths used in that build by these store paths *only*. As -mentioned before, store paths only address the inputs - and not the content. - -This poses a big problem in Nix as soon as builds are scheduled on remote -builders: There is no guarantee that files at the same store path on the remote -builder actually have the same contents as on the machine orchestrating the -build. If a package is not binary reproducible, this can lead to so-called -[frankenbuilds][frankenbuild]. - -This also introduces a dependency on the state that's present on the remote -builder machine: Whatever is in its store and matches the paths will be used, -even if it was maliciously placed there. - -To eliminate this hermiticity problem and increase the integrity of builds, -we've decided to use content-addressing in the builder protocol. - -We're currently hacking on this at [Thaigersprint](https://thaigersprint.org/) -and might have some more news to share soon! - --------------- - -That's it for now, try out Tvix and hit us up on IRC or on our mailing list if -you run into any snags, or have any questions. - -เจอกันนะ :) - -[^1]: We know that we calculated all dependencies correctly because of how their - hashes are included in the hashes of their dependents, and so on. More on - path calculation and input-addressed paths in the next section! -[^2]: That's the same reason why `builtins.derivation[Strict]` also lives in - `tvix-glue`, not in `tvix-eval`. -[^3]: See [nix-casync](https://discourse.nixos.org/t/nix-casync-a-more-efficient-way-to-store-and-substitute-nix-store-paths/16539) - for one example - investing content-defined chunking (while still keeping - the NAR format) -[^4]: Strictly speaking, not limited to tvix-store - literally anything - providing a listing into tvix-castore nodes. - -[Tvix]: https://tvix.dev -[aterm]: http://program-transformation.org/Tools/ATermFormat.html -[bazel-remote]: https://github.com/buchgr/bazel-remote/pull/715 -[castore-docs]: https://code.tvl.fyi/tree/tvix/docs/src/castore -[frankenbuild]: https://blog.layus.be/posts/2021-06-25-frankenbuilds.html -[go-nix-outpath]: https://github.com/nix-community/go-nix/blob/93cb24a868562714f1691840e94d54ef57bc0a5a/pkg/derivation/hashes.go#L52 -[nix-compat-derivation]: https://docs.tvix.dev/rust/nix_compat/derivation/struct.Derivation.html -[nix-compat-narinfo]: https://docs.tvix.dev/rust/nix_compat/narinfo/index.html -[nix-dev-dialogues-tvix]: https://www.youtube.com/watch?v=ZYG3T4l8RU8 -[nixcon2023]: https://www.youtube.com/watch?v=j67prAPYScY -[tvix-eval-ru]: https://tazj.in/blog/tvix-eval-talk-2023 -[nixcpp-builtins-derivation]: https://github.com/NixOS/nix/blob/49cf090cb2f51d6935756a6cf94d568cab063f81/src/libexpr/primops/derivation.nix#L4 -[nixcpp-patch-hashes]: https://github.com/adisbladis/nix/tree/hash-tracing -[refscan-string-contexts]: https://inbox.tvl.su/depot/20230316120039.j4fkp3puzrtbjcpi@tp/T/#t -[store-docs]: https://code.tvl.fyi/about/tvix/docs/src/store/api.md -[string-contexts-nix-bug]: https://github.com/NixOS/nix/issues/4629 -[tryeval-infrec]: https://b.tvl.fyi/issues/281 -[tvix-boot-readme]: https://code.tvl.fyi/about/tvix/boot/README.md -[why-string-contexts-now]: https://cl.tvl.fyi/c/depot/+/10446/7/tvix/eval/docs/build-references.md -[windtunnel]: https://staging.windtunnel.ci/tvl/tvix diff --git a/web/tvl/blog/2024-08-tvix-update.md b/web/tvl/blog/2024-08-tvix-update.md deleted file mode 100644 index 5fc15c02d..000000000 --- a/web/tvl/blog/2024-08-tvix-update.md +++ /dev/null @@ -1,266 +0,0 @@ -It's already been around half a year since -[the last Tvix update][2024-02-tvix-update], so time for another one! - -Note: This blog post is intended for a technical audience that is already -intimately familiar with Nix, and knows what things like derivations or store -paths are. If you're new to Nix, this will not make a lot of sense to you! - -## Builds -A long-term goal is obviously to be able to use the expressions in nixpkgs to -build things with Tvix. We made progress on many places towards that goal: - -### Drive builds on IO -As already explained in our [first blog post][blog-rewriting-nix], in Tvix, we -want to make IFD a first-class citizen without significant perf cost. - -Nix tries hard to split Evaluation and Building into two phases, visible in -the `nix-instantiate` command which produces `.drv` files in `/nix/store` and -the `nix-build` command which can be invoked on such `.drv` files without -evaluation. -Scheduling (like in Hydra) usually happens by walking the graph of `.drv` files -produced in the first phase. - -As soon as there's some IFD along the path, everything until then gets built in -the Evaluator (which is why IFD is prohibited in nixpkgs). - -Tvix does not have two separate "phases" in a build, only a graph of unfinished -Derivations/Builds and their associated store paths. This graph does not need -to be written to disk, and can grow during runtime, as new Derivations with new -output paths are discovered. - -Build scheduling happens continuously with that graph, for everything that's -really needed, when it's needed. - -We do this by only "forcing" the realization of a specific store path if the -user ultimately wants that specific result to be available on their system, and -transitively, if something else wants it. This includes IFD in a very elegant -way. - -We want to play with this approach as we continue on bringing our build -infrastructure up. - -### Fetchers -There's a few Nix builtins that allow describing a fetch (be it download of a -file from the internet, clone of a git repo). These needed to be implemented -for completeness. We implemented pretty much all downloads of Tarballs, NARs and -plain files, except git repositories, which are left for later. - -Instead of doing these fetches immediately, we added a generic `Fetch` type -that allows describing such fetches *before actually doing them*, similar to -being able to describe builds, and use the same "Drive builds on IO" machinery -to delay these fetches to the point where it's needed. We also show progress -bars when doing fetches. - -Very early, during bootstrapping, nixpkgs relies on some `builtin:fetchurl` -"fake" Derivation, which has some special handling logic in Nix. We implemented -these quirks, by converting it to instances of our `Fetch` type and dealing with -it there in a consistent fashion. - -### More fixes, Refscan -With the above work done, and after fixing some small bugs [^3], we were already -able to build some first few store paths with Tvix and our `runc`-based builder -🎉! - -We didn't get too far though, as we still need to implement reference scanning, -so that's next on our TODO list for here. Stay tuned for further updates there! - -## Eval correctness & Performance -As already written in the previous update, we've been evaluating parts of -`nixpkgs` and ensuring we produce the same derivations. We managed to find and -fix some correctness issues there. - -Even though we don't want to focus too much on performance improvements -until all features of Nix are properly understood and representable with our -architecture, there's been some work on removing some obvious and low-risk -performance bottlenecks. Expect a detailed blog post around that soon after -this one! - -## Tracing / O11Y Support -Tvix got support for Tracing, and is able to emit spans in -[OpenTelemetry][opentelemetry]-compatible format. - -This means, if the necessary tooling is set up to collect such spans [^1], it's -possible to see what's happening inside the different components of Tvix across -process (and machine) boundaries. - -Tvix now also propagates trace IDs via gRPC and HTTP requests [^2], and -continues them if receiving such ones. - -As an example, this allows us to get "callgraphs" on how a tvix-store operation -is processed through a multi-node deployment, and find bottlenecks and places to -optimize performance for. - -Currently, this is compiled in by default, trying to send traces to an endpoint -at `localhost` (as per the official [SDK defaults][otlp-sdk]). It can -be disabled by building without the `otlp` feature, or running with the -`--otlp=false` CLI flag. - -This piggy-backs on the excellent [tracing][tracing-rs] crate, which we already -use for structured logging, so while at it, we improved some log messages and -fields to make it easier to filter for certain types of events. - -We also added support for sending out [Tracy][tracy] traces, though these are -disabled by default. - -Additionally, some CLI entrypoints can now report progress to the user! -For example, when we're fetching something during evaluation -(via `builtins.fetchurl`), or uploading store path contents, we can report on -this. See [here][asciinema-import] for an example. - -We're still considering these outputs as early prototypes, and will refine them as -we go. - -## tvix-castore ingestion generalization -We spent some time refactoring and generalizing tvix-castore importer code. - -It's now generalized on a stream of "ingestion entries" produced in a certain -order, and there's various producers of this stream (reading through the local -filesystem, reading through a NAR, reading through a tarball, soon: traversing -contents of a git repo, …). - -This prevented a lot of code duplication for these various formats, and allows -pulling out helper code for concurrent blob uploading. - -## More tvix-[ca]store backends -We added some more store backends to Tvix: - - - There's a [redb][redb] `PathInfoService` and `DirectoryService`, which - also replaced the previous `sled` default backend. - - There's a [bigtable][bigtable] `PathInfoService` and `DirectoryService` - backend. - - The "simplefs" `BlobService` has been removed, as it can be expressed using - the "objectstore" backend with a `file://` URI. - - There's been some work on feature-flagging certain backends. - -## Documentation reconcilation -Various bits and pieces of documentation have previously been scattered -throughout the Tvix codebase, which wasn't very accessible and quite confusing. - -These have been consolidated into a mdbook (at `//tvix/docs`). - -We plan to properly host these as a website, hopefully providing a better introduction -and overview of Tvix, while adding more content over time. - -## `nar-bridge` RIIR -While the golang implementation of `nar-bridge` did serve us well for a while, -it being the only remaining non-Rust part was a bit annoying. - -Adding some features there meant they would not be accessible in the rest of -Tvix - and the other way round. -Also, we could not open data stores directly from there, but always had to start -a separate `tvix-store daemon`. - -The initial plans for the Rust rewrite were already made quite a while ago, -but we finally managed to finish implementing the remaining bits. `nar-bridge` -is now fully written in Rust, providing the same CLI experience features and -store backends as the rest of Tvix. - -## `crate2nix` and overall rust Nix improvements -We landed some fixes in [crate2nix][crate2nix], the tool we're using to for -per-crate incremental builds of Tvix. - -It now supports the corner cases needed to build WASM - so now -[Tvixbolt][tvixbolt] is built with it, too. - -We also fixed some bugs in how test directories are prepared, which unlocked -running some more tests for filesystem related builtins such as `readDir` in our test suite. - -Additionally, there has been some general improvements around ensuring various -combinations of Tvix feature flags build (now continuously checked by CI), and -reducing the amount of unnecessary rebuilds, by filtering non-sourcecode files -before building. - -These should all improve DX while working on Tvix. - -## Store Composition -Another big missing feature that landed was Store Composition. We briefly spoke -about the Tvix Store Model in the last update, but we didn't go into too much -detail on how that'd work in case there's multiple potential sources for a store -path or some more granular contents (which is pretty much always the case -normally, think about using things from your local store OR then falling back to -a remote place). - -Nix has the default model of using `/nix/store` with a sqlite database for -metadata as a local store, and one or multiple "subsituters" using the Nix HTTP -Binary Cache protocol. - -In Tvix, things need to be a bit more flexible: - - You might be in a setting where you don't have a local `/nix/store` at all. - - You might want to have a view of different substituters/binary caches for - different users. - - You might want to explicitly specify caches in between some of these layers, - and control their config. - -The idea in Tvix is that you'll be able to combine "hierarchies of stores" through -runtime configuration to express all this. - -It's currently behind a `xp-store-composition` feature flag, which adds the -optional `--experimental-store-composition` CLI arg, pointing to a TOML file -specifying the composition configuration. If set, this has priority over the old -CLI args for the three (single) stores. - -We're still not 100% sure how to best expose this functionality, in terms of the -appropriate level of granularity, in a user-friendly format. - -There's also some more combinators and refactors missing, but please let us -know your thoughts! - -## Contributors -There's been a lot of progress, which would not have been possible without our -contributors! Be it a small drive-by contributions, or large efforts, thank -you all! - - - Adam Joseph - - Alice Carroll - - Aspen Smith - - Ben Webb - - binarycat - - Brian Olsen - - Connor Brewster - - Daniel Mendler - - edef - - Edwin Mackenzie-Owen - - espes - - Farid Zakaria - - Florian Klink - - Ilan Joselevich - - Luke Granger-Brown - - Markus Rudy - - Matthew Tromp - - Moritz Sanft - - Padraic-O-Mhuiris - - Peter Kolloch - - Picnoir - - Profpatsch - - Ryan Lahfa - - Simon Hauser - - sinavir - - sterni - - Steven Allen - - tcmal - - toastal - - Vincent Ambo - - Yureka - ---- - -That's it again, try out Tvix and hit us up on IRC or on our mailing list if you -run into any snags, or have any questions. - - -[^1]: Essentially, deploying a collecting agent on your machines, accepting - these traces. -[^2]: Using the `traceparent` header field from https://www.w3.org/TR/trace-context/#trace-context-http-headers-format -[^3]: like `builtins.toFile` not adding files yet, or `inputSources` being missed initially, duh!) - -[2024-02-tvix-update]: https://tvl.fyi/blog/tvix-update-february-24 -[opentelemetry]: https://opentelemetry.io/ -[otlp-sdk]: https://opentelemetry.io/docs/languages/sdk-configuration/otlp-exporter/ -[tracing-rs]: https://tracing.rs/ -[tracy]: https://github.com/wolfpld/tracy -[asciinema-import]: https://asciinema.org/a/Fs4gKTFFpPGYVSna0xjTPGaNp -[blog-rewriting-nix]: https://tvl.fyi/blog/rewriting-nix -[crate2nix]: https://github.com/nix-community/crate2nix -[redb]: https://github.com/cberner/redb -[bigtable]: https://cloud.google.com/bigtable -[tvixbolt]: https://bolt.tvix.dev/ diff --git a/web/tvl/blog/default.nix b/web/tvl/blog/default.nix deleted file mode 100644 index 966be083b..000000000 --- a/web/tvl/blog/default.nix +++ /dev/null @@ -1,42 +0,0 @@ -{ depot, ... }: - -{ - config = { - name = "TVL's blog"; - footer = depot.web.tvl.footer { }; - baseUrl = "https://tvl.fyi/blog"; - }; - - posts = builtins.sort (a: b: a.date > b.date) [ - { - key = "rewriting-nix"; - title = "Tvix: We are rewriting Nix"; - date = 1638381387; - content = ./rewriting-nix.md; - author = "tazjin"; - } - - { - key = "tvix-status-september-22"; - title = "Tvix Status - September '22"; - date = 1662995534; - content = ./tvix-status-202209.md; - author = "tazjin"; - } - - { - key = "tvix-update-february-24"; - title = "Tvix Status - February '24"; - date = 1707472132; - content = ./2024-02-tvix-update.md; - author = "flokli"; - } - { - key = "tvix-update-august-24"; - title = "Tvix Status - August '24"; - date = 1723219370; - content = ./2024-08-tvix-update.md; - author = "flokli"; - } - ]; -} diff --git a/web/tvl/blog/rewriting-nix.md b/web/tvl/blog/rewriting-nix.md deleted file mode 100644 index a45cc571a..000000000 --- a/web/tvl/blog/rewriting-nix.md +++ /dev/null @@ -1,90 +0,0 @@ -Evaluating the Nix programming language, used by the Nix package -manager, is currently very slow. This becomes apparent in all projects -written in Nix that are not just simple package definitions, for -example: - -* the NixOS module system -* TVL projects like - [`//nix/yants`](https://at.tvl.fyi/?q=%2F%2Fnix%2Fyants) and - [`//web/bubblegum`](https://at.tvl.fyi/?q=%2F%2Fweb%2Fbubblegum). -* the code that [generates build - instructions](https://at.tvl.fyi/?q=%2F%2Fops%2Fpipelines) for TVL's - [CI setup](https://tvl.fyi/builds) - -Whichever project you pick, they all suffer from issues with the -language implementation. At TVL, it takes us close to a minute to -create the CI instructions for our monorepo at the moment - despite it -being a plain Nix evaluation. Running our Nix-native build systems for -[Go](https://code.tvl.fyi/about/nix/buildGo) and [Common -Lisp](https://code.tvl.fyi/about/nix/buildLisp) takes much more time -than we would like. - -Some time last year a few of us got together and started investigating -ways to modernise the current architecture of Nix and figure out how -to improve the speed of some of the components. We created over [250 -commits](https://cl.tvl.fyi/q/topic:tvix) in our fork of the Nix 2.3 -codebase at the time, tried [performance -experiments](https://cl.tvl.fyi/c/depot/+/1123/) aimed at improving -the current evaluator and fought [gnarly -bugs](https://cl.tvl.fyi/c/depot/+/1504). - -After a while we realised that we were treading water: Some of our -ideas are too architecturally divergent from Nix to be done on top of -the existing codebase, and the memory model of Nix causes significant -headaches when trying to do any kind of larger change. - -We needed an alternative approach and started brainstorming on a bent -whiteboard in a small flat in Hurghada, Egypt. - -![flokli & tazjin brainstorming](https://static.tvl.fyi/latest/files/flokli_tazjin_tvix.webp) - -Half a year later we are now ready to announce our new project: -**Tvix**, a re-imagined Nix with full nixpkgs compatibility. Tvix is -generously funded [by NLNet](https://nlnet.nl/project/Tvix/) (thanks!) -and we are ready to start implementing it. - -The [Tvix -architecture](https://code.tvl.fyi/about/tvix/docs/components.md) is -designed to be modular: It should be possible to write an evaluator -that plugs in the Guile language (for compatibility with GNU Guix), to -use arbitrary builders, and to replace the store implementation. - -Tvix has these high-level goals: - -* Creating an alternative implementation of Nix that is **fully - compatible with nixpkgs**. - - The package collection is an enormous effort with hundreds of - thousands of commits, encoding expert knowledge about lots of - different software and ways of building and managing it. It is a - very valuable piece of software and we must be able to reuse it. - -* More efficient Nix language evaluation, leading to greatly increased - performance. - -* No more strict separation of evaluation and build phases: Generating - Nix data structures from build artefacts ("IFD") should be supported - first-class and not incur significant performance cost. - -* Well-defined interaction protocols for how the three different - components (evaluator, builder, store) interact. - -* A builder implementation using OCI instead of custom sandboxing - code. - -![adisbladis & tazjin brainstorming](https://static.tvl.fyi/latest/files/adisbladis_tazjin_tvix.webp) - -Tvix is not intended to *replace* Nix, instead we want to improve the -ecosystem by offering an alternative, fast and reliable implementation -for Nix features that are in use today. - -As things ramp up we will be posting more information on this blog, -for now you can keep an eye on -[`//tvix`](https://code.tvl.fyi/tree/tvix) in the TVL monorepo -and subscribe to [our feed](https://tvl.fyi/feed.atom). - -Stay tuned! - -PS: TVL is international, but a lot of -the development will take place in our office in Moscow. Say hi if -you're around and interested! diff --git a/web/tvl/blog/tvix-status-202209.md b/web/tvl/blog/tvix-status-202209.md deleted file mode 100644 index 627c2d290..000000000 --- a/web/tvl/blog/tvix-status-202209.md +++ /dev/null @@ -1,165 +0,0 @@ -We've now been working on our rewrite of Nix, [Tvix][], for over a -year. - -As you can imagine, this past year has been turbulent, to say the -least, given the regions where many of us live. As a result we haven't -had as much time to work on fun things (like open-source software -projects!) as we'd like. - -We've all been fortunate enough to continue making progress, but we -just haven't had the bandwidth to communicate with you and keep you up -to speed on what's going on. That's what this blog post is for. - -## Nix language evaluator - -The most significant progress in the past six months has been on our -Nix language evaluator. To answer the most important question: yes, -you can play with it right now – in [Tvixbolt][]! - -We got the evaluator into its current state by first listing all the -problems we were likely to encounter, then solving them independently, -and finally assembling all those small-scale solutions into a coherent -whole. As a result, we briefly had an impractically large private -source tree, which we have since [integrated][] into our monorepo. - -This process was much slower than we would have liked, due to code -review bandwidth... which is to say, we're all volunteers. People have -lives, bottlenecks happen. - -Most of this code was either written or reviewed by [grfn][], -[sterni][] and [tazjin][] (that's me!). - -### How much of eval is working? - -*Most of it*! You can enter most (but not *all*, sorry! Not yet, -anyway.) Nix language expressions in [Tvixbolt][] and observe how they -are evaluated. - -There's a lot of interesting stuff going on under the hood, such as: - -* The Tvix compiler can emit warnings and errors without failing - early, and retains as much source information as possible. This will - enable you to use Tvix as the basis for developer tooling, such as - language servers. - -* The Tvix compiler performs in-depth scope analysis, so it can both - generate efficient bytecode for accessing identifiers, and alert you - about problems in your code before runtime. - -* The runtime supports tail-call optimisation in many (but – again – - not yet all) cases, so you can evaluate recursive expressions in - constant stack space. - -* The runtime can give you different backing representations for the - same Nix type. For example, an attribute set is represented - differently depending on whether you've constructed an empty one, a - `name/value` pair, or a larger set. This lets us optimise frequent, - well-known use-cases without impacting the general case much. - -We've run some initial benchmarks against C++ Nix (using the features -that are ready), and in most cases Tvix evaluation is an order of -magnitude faster. To be fair, though, these benchmarks are in no way -indicative of real-life performance for things like `nixpkgs`. More -information is coming... eventually. - -### How does it all work? - -Tvix's evaluator uses a custom abstract machine with a Nix-specific -instruction set, and a compiler that traverses a parsed Nix AST to -emit this bytecode and perform a set of optimisations and other -analysis. The most important benefit of this is that we can plan and -lay out the execution of a program in a way that is better suited to -an efficient runtime than directly traversing the AST. - -TIP: You can see the generated bytecode in [Tvixbolt][]! - -This is all written in about 4000 lines of Rust (naturally), some of -which – especially around scope-handling – are deceptively simple. - -As part of our CI suite, we run the evaluator against some tests we -wrote ourselves, as well as against the upstream Nix test suite (which -we don't *quite* pass yet. We're working on it!). - -### What's next for tvix-eval? - -Despite all our progress, there are still some unfinished feature -areas, and some of them are pretty important: - -1. The majority of Nix's builtins – including fundamental ones like - `import` and `derivation` – aren't implemented yet. - -2. Neither are recursive attribute sets (`rec`). This isn't because of - a problem with the recursion itself, but because of the handling of - nested keys (such as `a.b`). We have a lackluster solution already, - but are designing a more efficient one. - -In both cases, we've mostly figured out what to do; now it's just a -matter of finding the time to do it. Our progress is steady, and can -be tracked [in the source][src] (viewer without Javascript -[here][src-noscript]). - -Apart from that, the next steps are: - -* Comprehensive benchmarking. We're standing up an infrastructure for - continuous benchmarking to measure the impact of changes. It'll also - let us identify and optimise hotspots - -* Implementing known optimisations. There are some areas of the code - that have the potential for significant speed gains, but we're - holding off implementing those until the evaluator is feature - complete and passes the Nix test suite. - -* Finishing our language specification. Based on what we've learned, - we're writing a specification of the Nix language that captures its - various behaviours in all their tricky subtlety and subtle trickery. - -Once we can evaluate `nixpkgs`, we're likely to shift our focus -towards the other areas of Tvix. - -## The Other Areas of Tvix - -Speaking of these other areas (most importantly, the builder and store -implementation), we've made some nice progress there also. - -While we've yet to start assembling the actual pieces, [flokli][] and -[adisbladis][] have been hard at work on [go-nix][], which aims to -implement many of the low-level primitives required for the Nix store -and builder (hashing and encoding schemes, archive formats, reference -scanning ...). - -We're looking forward to telling you more in the next Tvix status -update! - -## Outro ... - -We'd be delighted to onboard new contributors to Tvix! Please take a -look at the main [TVL page](https://tvl.fyi) to find out how to get in -touch with us if you'd like to join! - -Thanks also, of course, to [NLNet](https://nlnet.nl/) for sponsoring -some of this work! - -And finally, we would like to thank and pay our respects to jD91mZM2 – -the original author of -[rnix-parser](https://github.com/nix-community/rnix-parser) – who has -sadly passed away. Please, tell people how important they are to you. - -We use `rnix-parser` in our compiler, and its well-designed internals -(also thanks to its new maintainers!) have saved us a lot of time. - -That's it for this update. Go play with [Tvixbolt][], have fun -figuring out weird ways to break it – and if you do, let us know. - -We'll see you around! - -[Tvix]: https://tvl.fyi/blog/rewriting-nix -[Tvixbolt]: https://bolt.tvix.dev -[integrated]: https://cl.tvl.fyi/q/status:merged+%2522tvix/eval%2522+mergedbefore:2022-09-09 -[src]: https://code.tvl.fyi/tree/tvix/eval -[src-noscript]: https://code.tvl.fyi/tree/tvix/eval -[tazjin]: https://tazj.in -[grfn]: https://gws.fyi/ -[sterni]: https://github.com/sternenseemann -[go-nix]: https://github.com/nix-community/go-nix -[flokli]: https://flokli.de/ -[adisbladis]: https://github.com/adisbladis diff --git a/web/tvl/default.nix b/web/tvl/default.nix deleted file mode 100644 index 8bbc7d566..000000000 --- a/web/tvl/default.nix +++ /dev/null @@ -1,141 +0,0 @@ -{ depot, lib, pkgs, ... }: - -with depot.nix.yants; - -let - inherit (builtins) filter; - inherit (pkgs) graphviz runCommand writeText; - inherit (depot.web) atom-feed blog tvl; - - listPosts = defun [ (list blog.post) string ] (posts: - lib.concatStringsSep "\n" (map (p: "* [${p.title}](blog/${p.key})") posts) - ); - - postRenderingCommands = defun [ (list blog.post) string ] (posts: - lib.concatStringsSep "\n" - (map (p: "cp ${blog.renderPost tvl.blog.config p} $out/blog/${p.key}.html") posts) - ); - - tvlGraph = runCommand "tvl.svg" - { - nativeBuildInputs = with pkgs; [ fontconfig freetype cairo jetbrains-mono ]; - } '' - ${graphviz}/bin/neato -Tsvg ${./tvl.dot} > $out - ''; - - publishedPosts = filter blog.includePost tvl.blog.posts; - - feed = { - id = "https://tvl.fyi/"; - title = "TVL blog"; - subtitle = "Thoughts and news from The Virus Lounge"; - authors = [ "tazjin" ]; # TODO(tazjin): Extract from post info - - links = lib.singleton { - rel = "self"; - href = "https://tvl.fyi/feed.atom"; - }; - - entries = map (blog.toFeedEntry tvl.blog.config) publishedPosts; - }; - - atomFeed = writeText "feed.atom" (atom-feed.renderFeed feed); - - homepage = tvl.template { - title = "The Virus Lounge"; - content = '' - The Virus Lounge - ================ - - ---------------- - - - - Welcome to **The Virus Lounge**. We're a group of people who got - together in 2020, when we felt that there was not enough - spontaneous socialising on the internet. - - Because of our shared interests in topics like **build systems** - and **monorepos** we started working on code together, in our - monorepo called the *depot*. - - Feel free to explore the tech we have built so far, all our - systems are linked in the footer. - - ---------------- - - ## Blog - - Here are the most recent TVL blog posts. - - ${listPosts publishedPosts} - - You can also follow our [atom feed](https://tvl.fyi/feed.atom). - - ---------------- - - ## Getting in touch - - We mostly hang out on IRC. You can find us in [`#tvl`][tvl-irc] - on [hackint][], which is also reachable [via XMPP][hackint-xmpp] - at [`#tvl@irc.hackint.org`][tvl-xmpp] (sic!) and [via - Matrix][hackint-matrix] at [`#tvl:hackint.org`][tvl-matrix]. - - Hackint also provide a [web chat][tvl-webchat]. - - [tvl-irc]: ircs://irc.hackint.org:6697/#tvl - [hackint]: https://hackint.org/ - [hackint-xmpp]: https://hackint.org/transport/xmpp - [tvl-xmpp]: xmpp:#tvl@irc.hackint.org?join - [hackint-matrix]: https://hackint.org/transport/matrix - [tvl-matrix]: https://matrix.to/#/#tvl:hackint.org - [tvl-webchat]: https://webirc.hackint.org/#ircs://irc.hackint.org/#tvl - - Discussions of our software, patches, and anything else really - can also be sent to us via email to **depot@tvl.su**. You can - see the mails submitted to that list in our [public inbox][]. - - [public inbox]: https://inbox.tvl.su - - ---------------- - - ## Where did all these people come from? - - It's pretty straightforward. Feel free to click on people, too. - -
- - ${builtins.readFile tvlGraph} -
- ''; - extraHead = '' - - ''; - }; -in -runCommand "website" { } '' - mkdir -p $out/blog - cp ${homepage} $out/index.html - ${postRenderingCommands tvl.blog.posts} - cp ${atomFeed} $out/feed.atom -'' diff --git a/web/tvl/footer/default.nix b/web/tvl/footer/default.nix deleted file mode 100644 index dc2c963f9..000000000 --- a/web/tvl/footer/default.nix +++ /dev/null @@ -1,21 +0,0 @@ -# Footer fragment for TVL homepages, used by //web/tvl/template for -# our static pages and also via //web/blog for blog posts. -{ lib, ... }: - -args: '' - -

ಠ_ಠ

-'' diff --git a/web/tvl/logo/default.nix b/web/tvl/logo/default.nix deleted file mode 100644 index 808413549..000000000 --- a/web/tvl/logo/default.nix +++ /dev/null @@ -1,97 +0,0 @@ -# Creates an output containing the logo in SVG format (animated and -# static, one for each background colour) and without animations in -# PNG. -{ depot, lib, pkgs, ... }: - -let - palette = { - purple = "#CC99C9"; - blue = "#9EC1CF"; - green = "#9EE09E"; - yellow = "#FDFD97"; - orange = "#FEB144"; - red = "#FF6663"; - }; - - staticCss = colour: '' - #armchair-background { - fill: ${colour}; - } - ''; - - # Create an animated CSS that equally spreads out the colours over - # the animation duration (1min). - animatedCss = colours: - let - # Calculate at which percentage offset each colour should appear. - stepSize = 100 / ((builtins.length colours) - 1); - frames = lib.imap0 (idx: colour: { inherit colour; at = idx * stepSize; }) colours; - frameCss = frame: "${toString frame.at}% { fill: ${frame.colour}; }"; - in - '' - #armchair-background { - animation: 30s infinite alternate armchairPalette; - } - - @keyframes armchairPalette { - ${lib.concatStringsSep "\n" (map frameCss frames)} - } - ''; - - # Dark version of the logo, suitable for light backgrounds. - darkCss = armchairCss: '' - .structure { - fill: #383838; - } - #letters { - fill: #fefefe; - } - ${armchairCss} - ''; - - # Light version, suitable for dark backgrounds. - lightCss = armchairCss: '' - .structure { - fill: #e4e4ef; - } - #letters { - fill: #181818; - } - ${armchairCss} - ''; - - logoShapes = builtins.readFile ./logo-shapes.svg; - logoSvg = style: '' - - - ${logoShapes} - - ''; - -in -depot.nix.readTree.drvTargets (lib.fix (self: { - # Expose the logo construction functions. - inherit palette darkCss lightCss animatedCss staticCss; - - # Create a TVL logo SVG with the specified style. - logoSvg = style: pkgs.writeText "logo.svg" (logoSvg style); - - # Create a PNG of the TVL logo with the specified style and DPI. - logoPng = style: dpi: pkgs.runCommand "logo.png" { } '' - ${pkgs.inkscape}/bin/inkscape \ - --export-area-drawing \ - --export-background-opacity 0 \ - --export-dpi ${toString dpi} \ - ${self.logoSvg style} -o $out - ''; - - # Animated dark SVG logo with all colours. - pastelRainbow = self.logoSvg (darkCss (animatedCss (lib.attrValues palette))); -} - - # Add individual outputs for static dark logos of each colour. - // (lib.mapAttrs' - (k: v: lib.nameValuePair "${k}Png" - (self.logoPng (darkCss (staticCss v)) 96)) - palette))) diff --git a/web/tvl/logo/logo-shapes.svg b/web/tvl/logo/logo-shapes.svg deleted file mode 100644 index d35971e0a..000000000 --- a/web/tvl/logo/logo-shapes.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/web/tvl/template/default.nix b/web/tvl/template/default.nix deleted file mode 100644 index 50ddc31e7..000000000 --- a/web/tvl/template/default.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ depot, pkgs, lib, ... }: - -{ - # content of the tag - title - # main part of the page, usually wrapped with <main> -, content - # optional extra html to inject into <head> -, extraHead ? null - # optional extra html to inject into <footer> -, extraFooter ? null - # URL at which static assets are located -, staticUrl ? "https://static.tvl.fyi/${depot.web.static.drvHash}" -}@args: - -let - inherit (pkgs) runCommand lib; - inherit (depot.tools) cheddar; -in - -runCommand "${lib.strings.sanitizeDerivationName title}-index.html" -{ - headerPart = '' - <!DOCTYPE html> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <meta name="description" content="The Virus Lounge"> - <link rel="stylesheet" type="text/css" href="${staticUrl}/tvl.css" media="all"> - <link rel="icon" type="image/webp" href="${staticUrl}/favicon.webp"> - <link rel="alternate" type="application/atom+xml" title="Atom Feed" href="https://tvl.fyi/feed.atom"> - <title>${title} - '' + lib.optionalString (args ? extraHead) extraHead + '' - - - ''; - - inherit content; - - footerPart = '' -
- - - ''; - - passAsFile = [ "headerPart" "content" "footerPart" ]; -} '' - ${cheddar}/bin/cheddar --about-filter content.md < $contentPath > rendered.html - cat $headerPartPath rendered.html $footerPartPath > $out -'' diff --git a/web/tvl/tvl.dot b/web/tvl/tvl.dot deleted file mode 100644 index 71a134163..000000000 --- a/web/tvl/tvl.dot +++ /dev/null @@ -1,173 +0,0 @@ -digraph tvl { - node [fontname = "JetBrains Mono"]; - overlap = false; - splines = polyline; - - TVL [style="bold" href="http://tvl.fyi"]; - tazjin -> TVL [style="bold"]; - - // people - subgraph { - Irenes [href="https://www.pluralpride.com/"]; - K900 [href="https://0upti.me/"]; - Profpatsch [href="http://profpatsch.de/"]; - adisbladis [href="http://nixos.expert/"]; - amjoseph; - andi [label="andi-" href="https://andreas.rammhold.de/"]; - aurora [href="https://nonegenderleftfox.aventine.se/"]; - benjojo [href="https://benjojo.co.uk/"]; - cynthia [href="https://cynthia.re/"]; - edef [href="https://edef.eu/files/edef.hs"]; - ericvolp [href="https://ericv.me"]; - espes; - eta [href="https://theta.eu.org/"]; - etu [href="https://elis.nu/"]; - ezemtsov [href="https://github.com/ezemtsov"]; - firefly [href="http://firefly.nu/"]; - flokli [href="https://flokli.de/"]; - fzakaria [href="https://fzakaria.com/"]; - ghuntley [href="https://ghuntley.com/"]; - aspen [href="http://gws.fyi"]; - implr [href="https://twitter.com/implring"]; - isomer [href="https://www.lorier.net/"]; - j4m3s [href="https://github.com/j4m3s-s"]; - jusrin [href="https://jusrin.dev/"]; - kn; - lassulus; - leah2 [href="https://leahneukirchen.org/"]; - lukegb [href="https://lukegb.com/"]; - marcusr [href="http://marcus.nordaaker.com/"]; - ncl; - nikky [href="http://nikky.moe/"]; - nyanotech [href="https://twitter.com/nyanotech"]; - seven [href="https://open.spotify.com/user/so7"]; - sterni [href="https://sterni.lv/"]; - tazjin [href="https://tazj.in/"]; - wpcarro [href="https://wpcarro.dev/"]; - raitobezarius [href="https://ryan.lahfa.xyz/"]; - vova [href="https://github.com/vkryachko"]; - yuuko; - } - - // companies (blue) - subgraph { - node [color="#4285f4" fontcolor="#4285f4"]; - spotify [href="https://www.spotify.com/"]; - google [href="https://www.google.com/"]; - } - - // communities? (red) - subgraph { - node [color="#db4437" fontcolor="#db4437"]; - eve [href="https://www.eveonline.com/"]; - nix [href="https://nixos.org/nix/"]; - tvix [href="https://code.tvl.fyi/tree/tvix"]; - ircv3 [href="https://ircv3.net/"]; - muccc [label="µccc" href="https://muc.ccc.de/"]; - afra [label="AfRA" href="https://afra-berlin.de/"]; - } - - // special - subgraph { - baby [color="pink" fontcolor="pink" href="https://cynthia.re/s/baby"]; - unspecific [color="grey" fontcolor="grey"]; - } - - // primary edges (how did they end up in TVL?) - subgraph { - // Direct edges - nix -> TVL; - tvix -> TVL; - - spotify -> tazjin; - google -> tazjin; - eve -> tazjin; - unspecific -> tazjin; - edef -> tazjin; - ezemtsov -> tazjin; - - // via nix - adisbladis -> nix; - jusrin -> nix; - ghuntley -> nix; - flokli -> nix; - andi -> nix; - Profpatsch -> nix; - lassulus -> nix; - etu -> nix; - vova -> nix; - - // via tvix - j4m3s -> tvix; - amjoseph -> tvix; - K900 -> tvix; - - // via edef - benjojo -> edef; - espes -> edef; - firefly -> edef; - leah2 -> aurora; - ncl -> edef; - - // via spotify - seven -> spotify; - - // via google - Irenes -> google; - isomer -> google; - lukegb -> google; - wpcarro -> google; - fzakaria -> google; - - // random primary - aspen -> wpcarro; - aurora -> eve; - cynthia -> benjojo; - eta -> unspecific; - ericvolp -> lukegb; - marcusr -> unspecific; - implr -> lukegb; - afra -> unspecific; - nikky -> afra; - kn -> flokli; - sterni -> Profpatsch; - yuuko -> ncl; - raitobezarius -> flokli; - } - - // secondary edges (how are they connected otherwise?) - subgraph { - edge [weight=0 style="dotted" color="grey" arrowhead="none"]; - - // ircv3 - eta -> ircv3; - firefly -> ircv3; - raitobezarius -> ircv3; - - // µccc - leah2 -> muccc; - - // random - leah2 -> edef; - lukegb -> isomer; - eta -> firefly; - cynthia -> firefly; - cynthia -> lukegb; - implr -> google; - nyanotech -> google; - lukegb -> benjojo; - espes -> benjojo; - espes -> aurora; - aspen -> nix; - edef -> nix; - ezemtsov -> nix; - raitobezarius -> nix; - } - - // baby - subgraph { - edge [weight=0 style="dotted" color="pink" arrowhead="none"]; - cynthia -> baby; - eta -> baby; - } -}