The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(dhall): obviate the use of Prelude

Signed-off-by: Xe Iaso <me@xeiaso.net>

Xe Iaso 0e079cea 877872b4

+107 -407
-3
dhall/Prelude.dhall
··· 1 - env:DHALL_PRELUDE 2 - ? https://raw.githubusercontent.com/dhall-lang/dhall-lang/v20.1.0/Prelude/package.dhall 3 - sha256:26b0ef498663d269e4dc6a82b0ee289ec565d683ef4c00d0ebdd25333a5a3c98
-43
dhall/authors.dhall
··· 1 - let Author = ./types/Author.dhall 2 - 3 - let Prelude = ./Prelude.dhall 4 - 5 - let default = ./authors/xe.dhall 6 - 7 - let authors = 8 - [ default 9 - , Author::{ 10 - , name = "Jessie" 11 - , handle = "Heartmender" 12 - , image = Some 13 - "https://cdn.xeiaso.net/file/christine-static/img/UPRcp1pO_400x400.jpg" 14 - , url = Some "https://vulpine.club/@heartmender" 15 - , inSystem = True 16 - } 17 - , Author::{ 18 - , name = "Ashe" 19 - , handle = "ectamorphic" 20 - , image = Some 21 - "https://cdn.xeiaso.net/file/christine-static/img/FFVV1InX0AkDX3f_cropped_smol.jpg" 22 - , inSystem = True 23 - } 24 - , Author::{ 25 - , name = "Nicole Brennan" 26 - , handle = "Twi" 27 - , url = Some "https://tech.lgbt/@twi" 28 - , inSystem = True 29 - } 30 - , Author::{ name = "Mai", handle = "Mai", inSystem = True } 31 - , Author::{ name = "Sephira", handle = "sephiraloveboo", inSystem = True } 32 - ] 33 - 34 - let authorToMapValue = \(a : Author.Type) -> { mapKey = a.handle, mapValue = a } 35 - 36 - let map = 37 - Prelude.List.map 38 - Author.Type 39 - (Prelude.Map.Entry Text Author.Type) 40 - authorToMapValue 41 - authors 42 - 43 - in { authors, map, default }
-2
dhall/characters.dhall
··· 1 1 let xesite = ./types/package.dhall 2 2 3 - let Prelude = ./Prelude.dhall 4 - 5 3 let C = xesite.Character 6 4 7 5 let they = ./pronouns/they.dhall
-27
dhall/nagMessages.dhall
··· 1 - let NagMessage = ./types/NagMessage.dhall 2 - 3 - in [ NagMessage::{ 4 - , name = "Cadey" 5 - , mood = "coffee" 6 - , message = 7 - "Hello! Thank you for visiting my website. You seem to have ads disabled. These ads help pay for running the website and are done by <a href=\"https://ethicalads.io\">Ethical Ads</a>. I do not receive detailed analytics on the ads and from what I understand neither does Ethical Ads. If you don't want to disable your ad blocker, please consider donating on <a href=\"https://www.patreon.com/cadey\">Patreon</a>. It helps fund the website's hosting bills and pay for the expensive technical editor that I use for my longer articles. Thanks and be well!" 8 - } 9 - , NagMessage::{ 10 - , name = "Cadey" 11 - , mood = "coffee" 12 - , message = 13 - "Hi! Thanks for reading the blog! Your ad blocker seems to be preventing the ads from showing up. Hosting is expensive, and I use <a href=\"https://ethicalads.io\">Ethical Ads</a> to help offset the bills. Every time one of my posts gets very popular, the hosting costs go up accordingly. If you don't want to have ads enabled, please consider becoming a patron on my <a href=\"https://www.patreon.com/cadey\">Patreon</a> instead. This helps me further my goals of making highly readable, entertaining, and inspirational articles so that readers like you can benefit from my struggles. Thanks and be well!" 14 - } 15 - , NagMessage::{ 16 - , name = "Mara" 17 - , mood = "hacker" 18 - , message = 19 - "Hey, I don't mean to be a bother but you seem to have an ad blocker configured for this domain. Independent tech writing and talks like these require a lot of investment in terms of writing and infrastructure. If you don't want to support the blog through ads, that's fine. Please consider donating on <a href=\"https://www.patreon.com/cadey\">Patreon</a> instead. That will help balance out the increased costs of hosting this website and get you some posts a week early as well as occasional patron-exclusive content. Thanks for reading! Hope you enjoy the article." 20 - } 21 - , NagMessage::{ 22 - , name = "Mara" 23 - , mood = "happy" 24 - , message = 25 - "Thanks for reading the latest issue of the xeiaso dot net cinematic universe! Running a cinmatic universe takes more resources than you'd think. If you don't feel comfortable supporting the blog with <a href=\"https://ethicalads.io\">Ethical Ads</a>, please consider donating on <a href=\"https://www.patreon.com/cadey\">Patreon</a>. Hosting is expensive, especially at the scale this website operates at. Every little bit helps." 26 - } 27 - ]
+2 -8
dhall/package.dhall
··· 4 4 5 5 let Link = xesite.Link 6 6 7 - let authors = ./authors.dhall 8 - 9 7 let desc = ./seriesDescriptions.dhall 10 8 11 9 in Config::{ 12 10 , signalboost = ./signalboost.dhall 13 - , authors = authors.map 14 - , defaultAuthor = authors.default 15 11 , clackSet = 16 12 [ "Ashlynn" 17 13 , "Terry Davis" 18 14 , "Dennis Ritchie" 19 - , "Steven Hawking" 15 + , "Stephen Hawking" 20 16 , "John Conway" 21 17 , "Ruth Bader Ginsburg" 22 18 , "Bram Moolenaar" ··· 33 29 ] 34 30 , jobHistory = ./jobHistory.dhall 35 31 , seriesDescriptions = desc.descriptions 36 - , seriesDescMap = desc.map 37 32 , notableProjects = 38 33 [ Link::{ 39 34 , url = "https://h.within.lgbt" ··· 45 40 , url = "https://anubis.techaro.lol" 46 41 , title = "Anubis" 47 42 , description = 48 - "A anti-scraper bot filter that protects git servers for GNOME, Sourcehut, and many other small communities" 43 + "A anti-scraper bot filter that protects git servers for GNOME, UNESCO, and many other small communities" 49 44 } 50 45 , Link::{ 51 46 , url = "https://when-then-zen.christine.website/" ··· 91 86 ] 92 87 , pronouns = ./pronouns.dhall 93 88 , characters = ./characters.dhall 94 - , vods = ./streamVOD.dhall 95 89 , resume = ./resume.dhall 96 90 }
+11 -22
dhall/seriesDescriptions.dhall
··· 1 1 let xesite = ./types/package.dhall 2 2 3 - let Prelude = ./Prelude.dhall 4 - 5 3 let Desc = xesite.SeriesDescription 6 4 7 5 let descriptions 8 6 : List Desc.Type 9 7 = [ Desc::{ 10 - , name = "anubis" 11 - , details = 12 - "Adventures, misadventures, and implementation details for Anubis, Techaro's anti-AI scraper tooling." 13 - } 8 + , name = "anubis" 9 + , details = 10 + "Adventures, misadventures, and implementation details for Anubis, Techaro's anti-AI scraper tooling." 11 + } 14 12 , Desc::{ 15 13 , name = "colemak" 16 14 , details = ··· 54 52 , Desc::{ 55 53 , name = "homelabV2" 56 54 , details = "My second attempt at a homelab via Fedora CoreOS and k3s." 57 - } 55 + } 58 56 , Desc::{ 59 57 , name = "howto" 60 58 , details = "Instructions on how to do various things." ··· 78 76 , details = 79 77 "Instructions on how to use Nix flakes, a new way to use Nix in a more reproducible way." 80 78 } 81 - , Desc::{ 82 - name = "no-way-to-prevent-this", 83 - details = "Articles about the futility of preventing memory safety vulnerabilities." 79 + , Desc::{ 80 + , name = "no-way-to-prevent-this" 81 + , details = 82 + "Articles about the futility of preventing memory safety vulnerabilities." 84 83 } 85 84 , Desc::{ name = "nixos", details = "Nix." } 86 85 , Desc::{ ··· 127 126 , Desc::{ 128 127 , name = "techaro" 129 128 , details = "Stories about Techaro, the imaginary technology startup." 130 - } 129 + } 131 130 , Desc::{ 132 131 , name = "templeos" 133 132 , details = ··· 158 157 } 159 158 ] 160 159 161 - let descToMapValue = 162 - \(desc : Desc.Type) -> { mapKey = desc.name, mapValue = desc.details } 163 - 164 - let map = 165 - Prelude.List.map 166 - Desc.Type 167 - (Prelude.Map.Entry Text Text) 168 - descToMapValue 169 - descriptions 170 - 171 - in { descriptions, map } 160 + in { descriptions }
+1 -25
dhall/signalboost.dhall
··· 57 57 } 58 58 , Person::{ 59 59 , name = "Karan Yadav" 60 - , tags = 61 - [ "ruby" 62 - , "python" 63 - , "linux" 64 - , "c++" 65 - , "aws" 66 - , "backend" 67 - ] 60 + , tags = [ "ruby", "python", "linux", "c++", "aws", "backend" ] 68 61 , links = 69 62 [ Link::{ url = "https://github.com/karan-ydv", title = "GitHub" } 70 63 , Link::{ url = "https://karanydv.tech", title = "website" } ··· 273 266 , Link::{ url = "https://resume.sjer.red", title = "Resume" } 274 267 , Link::{ url = "https://github.com/shepherdjerred", title = "GitHub" } 275 268 ] 276 - } 277 - , Person::{ 278 - , name = "Izzy Lancaster" 279 - , tags = 280 - [ "Software Engineer" 281 - , "Fullstack" 282 - , "C#" 283 - , ".NET" 284 - , "Rust" 285 - , "Python" 286 - , "React" 287 - , "Typescript" 288 - , "AWS" 289 - , "SQL" 290 - ] 291 - , links = 292 - [ Link::{ url = "https://github.com/ILikePizza555", title = "GitHub" } ] 293 269 } 294 270 ]
-111
dhall/streamVOD.dhall
··· 1 - let xesite = ./types/package.dhall 2 - 3 - let VOD = xesite.StreamVOD 4 - 5 - in [ VOD::{ 6 - , title = "Shouting at my editor" 7 - , slug = "cursorless" 8 - , description = 9 - '' 10 - This is a bit of an experimental stream where I attempted to dictate code with [cursorless](https://www.cursorless.org/). When I recorded this stream, I was at minute twenty of playing with this tool. This stream is going to sound really weird, because I am going to be rattling off voice commands that will sound weird at first. 11 - 12 - On this stream, I decided to implement a stable diffusion feature for my CDN XeDN. It replicates the API of the service gravatar, but backed by stable diffusion based off of the hash. There is a terrible bit of code that turns a gravatar hash into a stable diffusion prompt and seed combination. 13 - 14 - This stream covers the following topics: 15 - 16 - * Basic navigation with cursorless 17 - * Data transformations 18 - * How to execute on terrible ideas 19 - '' 20 - , date = "2023-03-04" 21 - , cdnPath = "talks/vod/2023/03-04-cursorless" 22 - , tags = [ "accessibility", "voiceControl", "go", "stableDiffusion" ] 23 - } 24 - , VOD::{ 25 - , title = "Ripping the bandaid off and using Emacs managed by Nix" 26 - , slug = "emacs-nix" 27 - , description = 28 - '' 29 - This is a shorter stream where I switched my Emacs config from [Spacemacs](https://spacemacs.org) to a custom configuration I've been prototyping for a year or so that has everything managed with [home-manager](https://nixos.wiki/wiki/Home_Manager) on NixOS. This allows my configuration to be completely managed in configuration and all packages that I depend on can be precompiled at deploy time_, allowing me to run my complicated configurations on less powerful hardware without having to wait for bytecode compilation to happen. Most of the rest of the stream was just going through the motions of actually making the change, and then trying to make some ergonomics changes so that I could use it as a replacement for tmux. 30 - 31 - This stream covers the following topics: 32 - 33 - * Nix/NixOS configuration management 34 - * Emacs Lisp programming 35 - * Writing custom interactive commands in Emacs 36 - * Proving chat wrong about the capabilities of Emacs 37 - '' 38 - , date = "2023-02-04" 39 - , cdnPath = "talks/vod/2023/02-04-emacs" 40 - , tags = [ "emacs", "nix", "lisp", "tmux" ] 41 - } 42 - , VOD::{ 43 - , title = "Fixing Xesite in reader mode and RSS readers" 44 - , slug = "reader-mode-css" 45 - , description = 46 - '' 47 - When you are using reader mode in Firefox, Safari or Google Chrome, the browser rends control of the website's design and renders its own design. This is typically done in order to prevent people's bad design decisions from making webpages unreadable and also to strip away advertisements from content. As a website publisher, I rely on the ability to control the CSS of my blog a lot. This stream covers the research/implementation process for fixing some long-standing issues with the Xesite CSS and making a fix to XeDN so that the site renders acceptably in reader mode. 48 - 49 - This stream covers the following topics: 50 - 51 - * Understanding complicated CSS rules and creating fixes for issues with them 52 - * Using content distribution networks (CDNs) to help reduce page load time for readers 53 - * Implementing image resizing capabilities into an existing CDN program (XeDN) 54 - * Design with end-users in mind 55 - '' 56 - , date = "2023-01-21" 57 - , cdnPath = "talks/vod/2023/01-21-reader-mode" 58 - , tags = [ "css", "xedn", "imageProcessing", "scalability", "bugFix" ] 59 - } 60 - , VOD::{ 61 - , title = "Implementing the Pronouns service in Rust and Axum" 62 - , slug = "pronouns-service" 63 - , description = 64 - '' 65 - In this stream I implemented the [pronouns](https://pronouns.within.lgbt) service and deployed it to the cloud with [fly.io](https://fly.io). This was mostly writing a bunch of data files with [Dhall](https://dhall-lang.org) and then writing a simple Rust program to query that 'database' and then show results based on the results of those queries. 66 - 67 - This stream covers the following topics: 68 - 69 - * Starting a new Rust project from scratch with Nix flakes, Axum, and Maud 70 - * API design for human and machine-paresable outputs 71 - * DevOps deployment to the cloud via [fly.io](https://fly.io) 72 - * Writing Terraform code for the pronouns service 73 - * Building Docker images with Nix flakes and `pkgs.dockerTools.buildLayeredImage` 74 - * Writing API documentation 75 - * Writing [the writeup](https://xeiaso.net/blog/pronouns-service) on the service 76 - '' 77 - , date = "2023-01-07" 78 - , cdnPath = "talks/vod/2023/01-07-pronouns" 79 - , tags = [ "rust", "axum", "terraform", "nix", "flyio", "docker" ] 80 - } 81 - , VOD::{ 82 - , title = "Modernizing hlang with the nguh compiler" 83 - , slug = "hlang-nguh-compiler" 84 - , description = 85 - '' 86 - This stream was the last stream of 2022 and focused on modernizing the [hlang](https://xeiaso.net/blog/series/h) compiler. In this stream I reverse-engineered how WebAssembly modules work and wrote my own compiler for a trivial esoteric programming language named h. The existing compiler relied on legacy features of WebAssembly tools that don't work anymore. 87 - 88 - This stream covers the following topics: 89 - 90 - * Reverse-engineering the WebAssembly module format based on the specification and other reverse-engineering tools 91 - * Adapting an existing compiler to output WebAssembly directly 92 - * Deploying a new service to my NixOS machines in the cloud 93 - * Building a Nix flake and custom NixOS module to build and deploy the new hlang website 94 - * Terraform DNS config 95 - * Writing [the writeup on the new compiler](https://xeiaso.net/blog/hlang-nguh) 96 - '' 97 - , date = "2022-12-31" 98 - , cdnPath = "talks/vod/2022/12-31-nguh" 99 - , tags = 100 - [ "hlang" 101 - , "go" 102 - , "wasm" 103 - , "philosophy" 104 - , "devops" 105 - , "terraform" 106 - , "aws" 107 - , "route53" 108 - , "nixos" 109 - ] 110 - } 111 - ]
-23
dhall/types/Author.dhall
··· 1 - let PronounSet = ./PronounSet.dhall 2 - 3 - in { Type = 4 - { name : Text 5 - , handle : Text 6 - , image : Optional Text 7 - , url : Optional Text 8 - , sameAs : List Text 9 - , jobTitle : Text 10 - , inSystem : Bool 11 - , pronouns : PronounSet.Type 12 - } 13 - , default = 14 - { name = "" 15 - , handle = "" 16 - , image = None Text 17 - , url = None Text 18 - , sameAs = [] : List Text 19 - , jobTitle = "" 20 - , inSystem = False 21 - , pronouns = ../pronouns/she.dhall 22 - } 23 - }
-16
dhall/types/Config.dhall
··· 1 1 let Person = ./Person.dhall 2 2 3 - let Author = ./Author.dhall 4 - 5 3 let Character = ./Character.dhall 6 4 7 5 let Job = ./Job.dhall 8 6 9 7 let Link = ./Link.dhall 10 - 11 - let NagMessage = ./NagMessage.dhall 12 8 13 9 let SeriesDescription = ./SeriesDescription.dhall 14 10 15 - let VOD = ./StreamVOD.dhall 16 - 17 11 let PronounSet = ./PronounSet.dhall 18 - 19 - let Prelude = ../Prelude.dhall 20 12 21 13 let Resume = ./Resume.dhall 22 14 ··· 28 20 29 21 in { Type = 30 22 { signalboost : List Person.Type 31 - , defaultAuthor : Author.Type 32 - , authors : Prelude.Map.Type Text Author.Type 33 23 , port : Natural 34 24 , clackSet : List Text 35 25 , webMentionEndpoint : Text 36 26 , miToken : Text 37 27 , jobHistory : List Job.Type 38 28 , seriesDescriptions : List SeriesDescription.Type 39 - , seriesDescMap : Prelude.Map.Type Text Text 40 29 , notableProjects : List Link.Type 41 30 , contactLinks : List Link.Type 42 31 , pronouns : List PronounSet.Type 43 32 , characters : List Character.Type 44 - , vods : List VOD.Type 45 33 , resume : Resume.Type 46 34 } 47 35 , default = 48 36 { signalboost = [] : List Person.Type 49 - , defaultAuthor = Author::{=} 50 - , authors = [] : List Author.Type 51 37 , port = defaultPort 52 38 , clackSet = [ "Ashlynn" ] 53 39 , webMentionEndpoint = defaultWebMentionEndpoint 54 40 , miToken = "${env:MI_TOKEN as Text ? ""}" 55 41 , jobHistory = [] : List Job.Type 56 42 , seriesDescriptions = [] : List SeriesDescription.Type 57 - , seriesDescMap = [] : Prelude.Map.Type Text Text 58 43 , notableProjects = [] : List Link.Type 59 44 , contactLinks = [] : List Link.Type 60 45 , pronouns = [] : List PronounSet.Type 61 46 , characters = [] : List Character.Type 62 - , vods = [] : List VOD.Type 63 47 , resume = Resume::{=} 64 48 } 65 49 }
-3
dhall/types/NagMessage.dhall
··· 1 - { Type = { name : Text, mood : Text, message : Text } 2 - , default = { name = "", mood = "", message = "" } 3 - }
-19
dhall/types/StreamVOD.dhall
··· 1 - let Link = ./Link.dhall 2 - 3 - in { Type = 4 - { title : Text 5 - , slug : Text 6 - , date : Text 7 - , description : Text 8 - , cdnPath : Text 9 - , tags : List Text 10 - } 11 - , default = 12 - { title = "" 13 - , slug = "" 14 - , date = "" 15 - , description = "" 16 - , cdnPath = "" 17 - , tags = [] : List Text 18 - } 19 - }
+1 -4
dhall/types/package.dhall
··· 1 - { Author = ./Author.dhall 2 - , Character = ./Character.dhall 1 + { Character = ./Character.dhall 3 2 , Company = ./Company.dhall 4 3 , Config = ./Config.dhall 5 4 , Job = ./Job.dhall 6 5 , Link = ./Link.dhall 7 6 , Location = ./Location.dhall 8 - , NagMessage = ./NagMessage.dhall 9 7 , Person = ./Person.dhall 10 8 , PronounSet = ./PronounSet.dhall 11 9 , Resume = ./Resume.dhall ··· 13 11 , SeriesDescription = ./SeriesDescription.dhall 14 12 , Stock = ./Stock.dhall 15 13 , StockKind = ./StockKind.dhall 16 - , StreamVOD = ./StreamVOD.dhall 17 14 }
+69 -84
internal/config/config.go
··· 34 34 } 35 35 36 36 type Config struct { 37 - Authors map[string]Author `json:"authors"` 38 - Characters []Character `json:"characters"` 39 - ClackSet []string `json:"clackSet"` 40 - ContactLinks []Link `json:"contactLinks"` 41 - DefaultAuthor Author `json:"defaultAuthor"` 42 - JobHistory []Job `json:"jobHistory"` 43 - MiToken string `json:"miToken"` 44 - NotableProjects []NotableProjects `json:"notableProjects"` 45 - Port int `json:"port"` 46 - Pronouns []Pronouns `json:"pronouns"` 47 - SeriesDescMap map[string]string `json:"seriesDescMap"` 48 - SeriesDescriptions []SeriesDescriptions `json:"seriesDescriptions"` 49 - Signalboost []Signalboost `json:"signalboost"` 50 - WebMentionEndpoint string `json:"webMentionEndpoint"` 51 - Resume Resume `json:"resume"` 37 + Characters []Character `json:"characters" dhall:"characters"` 38 + ClackSet []string `json:"clackSet" dhall:"clackSet"` 39 + ContactLinks []Link `json:"contactLinks" dhall:"contactLinks"` 40 + JobHistory []Job `json:"jobHistory" dhall:"jobHistory"` 41 + NotableProjects []NotableProjects `json:"notableProjects" dhall:"notableProjects"` 42 + Port int `json:"port" dhall:"port"` 43 + Pronouns []Pronouns `json:"pronouns" dhall:"pronouns"` 44 + SeriesDescriptions []SeriesDescriptions `json:"seriesDescriptions" dhall:"seriesDescriptions"` 45 + Signalboost []Signalboost `json:"signalboost" dhall:"signalboost"` 46 + WebMentionEndpoint string `json:"webMentionEndpoint" dhall:"webMentionEndpoint"` 47 + Resume Resume `json:"resume" dhall:"resume"` 52 48 } 53 49 54 50 type Pronouns struct { 55 - Accusative string `json:"accusative"` 56 - Nominative string `json:"nominative"` 57 - Possessive string `json:"possessive"` 58 - PossessiveDeterminer string `json:"possessiveDeterminer"` 59 - Reflexive string `json:"reflexive"` 60 - Singular bool `json:"singular"` 51 + Accusative string `json:"accusative" dhall:"accusative"` 52 + Nominative string `json:"nominative" dhall:"nominative"` 53 + Possessive string `json:"possessive" dhall:"possessive"` 54 + PossessiveDeterminer string `json:"possessiveDeterminer" dhall:"possessiveDeterminer"` 55 + Reflexive string `json:"reflexive" dhall:"reflexive"` 56 + Singular bool `json:"singular" dhall:"singular"` 61 57 } 62 58 63 59 type Character struct { 64 - DefaultPose string `json:"defaultPose"` 65 - Description string `json:"description"` 66 - Name string `json:"name"` 67 - Pronouns Pronouns `json:"pronouns"` 68 - StickerName string `json:"stickerName"` 69 - Stickers []string `json:"stickers"` 60 + DefaultPose string `json:"defaultPose" dhall:"defaultPose"` 61 + Description string `json:"description" dhall:"description"` 62 + Name string `json:"name" dhall:"name"` 63 + Pronouns Pronouns `json:"pronouns" dhall:"pronouns"` 64 + StickerName string `json:"stickerName" dhall:"stickerName"` 65 + Stickers []string `json:"stickers" dhall:"stickers"` 70 66 } 71 67 72 68 type Link struct { 73 - Description string `json:"description"` 74 - Title string `json:"title"` 75 - URL string `json:"url"` 76 - } 77 - 78 - type Author struct { 79 - Handle string `json:"handle"` 80 - Image string `json:"image"` 81 - InSystem bool `json:"inSystem"` 82 - JobTitle string `json:"jobTitle"` 83 - Name string `json:"name"` 84 - Pronouns Pronouns `json:"pronouns"` 85 - SameAs []string `json:"sameAs"` 86 - URL string `json:"url"` 69 + Description string `json:"description" dhall:"description"` 70 + Title string `json:"title" dhall:"title"` 71 + URL string `json:"url" dhall:"url"` 87 72 } 88 73 89 74 type Location struct { 90 - City string `json:"city"` 91 - Country string `json:"country"` 92 - Remote bool `json:"remote"` 93 - StateOrProvince string `json:"stateOrProvince"` 75 + City string `json:"city" dhall:"city"` 76 + Country string `json:"country" dhall:"country"` 77 + Remote bool `json:"remote" dhall:"remote"` 78 + StateOrProvince string `json:"stateOrProvince" dhall:"stateOrProvince"` 94 79 } 95 80 96 81 type Company struct { 97 - Defunct bool `json:"defunct"` 98 - Location Location `json:"location"` 99 - Name string `json:"name"` 100 - Tagline string `json:"tagline"` 101 - URL string `json:"url"` 82 + Defunct bool `json:"defunct" dhall:"defunct"` 83 + Location Location `json:"location" dhall:"location"` 84 + Name string `json:"name" dhall:"name"` 85 + Tagline string `json:"tagline" dhall:"tagline"` 86 + URL string `json:"url" dhall:"url"` 102 87 } 103 88 104 89 type Salary struct { 105 - Amount int `json:"amount"` 106 - Currency string `json:"currency"` 107 - Per string `json:"per"` 108 - Stock *Stock `json:"stoc,omitempty"` 90 + Amount int `json:"amount" dhall:"amount"` 91 + Currency string `json:"currency" dhall:"currency"` 92 + Per string `json:"per" dhall:"per"` 93 + Stock *Stock `json:"stoc,omitempty" dhall:"stoc,omitempty"` 109 94 } 110 95 111 96 type Stock struct { 112 - Amount int `json:"amount"` 113 - CliffYears int `json:"cliffYears"` 114 - Kind string `json:"kind"` 115 - Liquid bool `json:"liquid"` 116 - VestingYears int `json:"vestingYears"` 97 + Amount int `json:"amount" dhall:"amount"` 98 + CliffYears int `json:"cliffYears" dhall:"cliffYears"` 99 + Kind string `json:"kind" dhall:"kind"` 100 + Liquid bool `json:"liquid" dhall:"liquid"` 101 + VestingYears int `json:"vestingYears" dhall:"vestingYears"` 117 102 } 118 103 119 104 type Job struct { 120 - Company Company `json:"company,omitempty"` 121 - Contract bool `json:"contract"` 122 - HideFromResume bool `json:"hideFromResume"` 123 - Highlights []string `json:"highlights"` 124 - Locations []Location `json:"locations"` 125 - Salary Salary `json:"salary,omitempty"` 126 - StartDate string `json:"startDate"` 127 - Title string `json:"title"` 128 - DaysWorked int `json:"daysWorked,omitempty"` 129 - EndDate string `json:"endDate,omitempty"` 130 - LeaveReason string `json:"leaveReason,omitempty"` 131 - DaysBetween int `json:"daysBetween,omitempty"` 105 + Company Company `json:"company,omitempty" dhall:"company,omitempty"` 106 + Contract bool `json:"contract" dhall:"contract"` 107 + HideFromResume bool `json:"hideFromResume" dhall:"hideFromResume"` 108 + Highlights []string `json:"highlights" dhall:"highlights"` 109 + Locations []Location `json:"locations" dhall:"locations"` 110 + Salary Salary `json:"salary,omitempty" dhall:"salary,omitempty"` 111 + StartDate string `json:"startDate" dhall:"startDate"` 112 + Title string `json:"title" dhall:"title"` 113 + DaysWorked int `json:"daysWorked,omitempty" dhall:"daysWorked,omitempty"` 114 + EndDate string `json:"endDate,omitempty" dhall:"endDate,omitempty"` 115 + LeaveReason string `json:"leaveReason,omitempty" dhall:"leaveReason,omitempty"` 116 + DaysBetween int `json:"daysBetween,omitempty" dhall:"daysBetween,omitempty"` 132 117 } 133 118 134 119 type NotableProjects struct { 135 - Description string `json:"description"` 136 - Title string `json:"title"` 137 - URL string `json:"url"` 120 + Description string `json:"description" dhall:"description"` 121 + Title string `json:"title" dhall:"title"` 122 + URL string `json:"url" dhall:"url"` 138 123 } 139 124 140 125 type SeriesDescriptions struct { 141 - Details string `json:"details"` 142 - Name string `json:"name"` 126 + Details string `json:"details" dhall:"details"` 127 + Name string `json:"name" dhall:"name"` 143 128 } 144 129 145 130 type Signalboost struct { 146 - Links []Link `json:"links"` 147 - Name string `json:"name"` 148 - Tags []string `json:"tags"` 131 + Links []Link `json:"links" dhall:"links"` 132 + Name string `json:"name" dhall:"name"` 133 + Tags []string `json:"tags" dhall:"tags"` 149 134 } 150 135 151 136 type Resume struct { 152 - Buzzwords []string `json:"buzzwords"` 153 - Location Location `json:"location"` 154 - Name string `json:"name"` 155 - NotablePublications []Link `json:"notablePublications"` 156 - Tagline string `json:"tagline"` 137 + Buzzwords []string `json:"buzzwords" dhall:"buzzwords"` 138 + Location Location `json:"location" dhall:"location"` 139 + Name string `json:"name" dhall:"name"` 140 + NotablePublications []Link `json:"notablePublications" dhall:"notablePublications"` 141 + Tagline string `json:"tagline" dhall:"tagline"` 157 142 }
+9 -1
internal/config/config_test.go
··· 1 1 package config 2 2 3 3 import ( 4 + "os" 4 5 "testing" 5 6 ) 6 7 7 8 func TestLoad(t *testing.T) { 8 - if _, err := Load("../../config.dhall"); err != nil { 9 + wd, err := os.Getwd() 10 + if err != nil { 11 + t.Fatal(err) 12 + } 13 + os.Chdir("../../dhall") 14 + defer os.Chdir(wd) 15 + 16 + if _, err := Load("./package.dhall"); err != nil { 9 17 t.Error(err) 10 18 } 11 19 }
+14 -16
internal/lume/lume.go
··· 425 425 } 426 426 427 427 for fname, data := range map[string]any{ 428 - "argv.json": os.Args, 429 - "authors.json": f.conf.Authors, 430 - "characters.json": f.conf.Characters, 431 - "commit.json": map[string]any{"hash": siteCommit}, 432 - "contactLinks.json": f.conf.ContactLinks, 433 - "events.json": events, 434 - "jobHistory.json": f.conf.JobHistory, 435 - "notableProjects.json": f.conf.NotableProjects, 436 - "pronouns.json": f.conf.Pronouns, 437 - "resume.json": f.conf.Resume, 438 - "seriesDescriptions.json": f.conf.SeriesDescMap, 439 - "signalboost.json": f.conf.Signalboost, 428 + "argv.json": os.Args, 429 + "characters.json": f.conf.Characters, 430 + "commit.json": map[string]any{"hash": siteCommit}, 431 + "contactLinks.json": f.conf.ContactLinks, 432 + "events.json": events, 433 + "jobHistory.json": f.conf.JobHistory, 434 + "notableProjects.json": f.conf.NotableProjects, 435 + "pronouns.json": f.conf.Pronouns, 436 + "resume.json": f.conf.Resume, 437 + "signalboost.json": f.conf.Signalboost, 440 438 } { 441 439 slog.Debug("opening data file", "fname", filepath.Join(dataDir, fname)) 442 440 fh, err := os.Create(filepath.Join(dataDir, fname)) ··· 465 463 func (f *FS) writeSeriesPages() error { 466 464 seriesPageDir := filepath.Join(f.repoDir, f.opt.StaticSiteDir, "src", "blog", "series") 467 465 468 - for k, v := range f.conf.SeriesDescMap { 469 - fname := filepath.Join(seriesPageDir, fmt.Sprintf("%s.jsx", k)) 466 + for _, v := range f.conf.SeriesDescriptions { 467 + fname := filepath.Join(seriesPageDir, fmt.Sprintf("%s.jsx", v.Name)) 470 468 471 469 fout, err := os.Create(fname) 472 470 if err != nil { ··· 478 476 Series string 479 477 Desc string 480 478 }{ 481 - Series: k, 482 - Desc: v, 479 + Series: v.Name, 480 + Desc: v.Details, 483 481 }); err != nil { 484 482 return fmt.Errorf("can't write %s: %w", fname, err) 485 483 }