Add Your Email Address to Your RSS Feed
Inspired by the Add Your Email Address to Your RSS Feed article, I added the email element to the Atom feed of the blog (the RSS feed already had the email address). Enjoy đ
(via)
Inspired by the Add Your Email Address to Your RSS Feed article, I added the email element to the Atom feed of the blog (the RSS feed already had the email address). Enjoy đ
(via)
In the Agentic Coding article, Simon WIllson talks about the Agentic Coding: The Future of Software Development with Agents YouTube talk from Armin Ronacher.
I picked up a bunch of useful tips from this video:
- Armin runs Claude Code with the
--dangerously-skip-permissions
option, and says this unlocks a huge amount of productivity. I haven't been brave enough to do this yet but I'm going to start using that option while running in a Docker container to ensure nothing too bad can happen.- When your agentic coding tool can run commands in a terminal you can mostly avoid MCP - instead of adding a new MCP tool, write a script or add a Makefile command and tell the agent to use that instead. The only MCP Armin uses is the Playwright one.
- Combined logs are a really good idea: have everything log to the same place and give the agent an easy tool to read the most recent N log lines.
- While running Claude Code, use Gemini CLI to run sub-agents, to perform additional tasks without using up Claude Code's own context
- Designing additional tools that provide very clear errors, so the agents can recover when something goes wrong.
- Thanks to Playwright, Armin has Claude Code perform all sorts of automated operations via a signed in browser instance as well. "Claude can debug your CI... it can sign into a browser, click around, debug..." - he also has it use the
gh
GitHub CLI tool to interact with things like GitHub Actions workflows.
I would add to this list a link to the Agentic Coding Recommendations blog post of Armin.
It supports both single variables and more complex expressions. Hereâs a few examples:
>>> x = 42 >>> f"{x=}" 'x=42' >>> f"{1+2=}" '1+2=3' >>> f"{(1+2)*3=}" '(1+2)*3=9'This is described in Whatâs New In Python 3.8;
(via)
Started the festival season at ZOA City with yet again a concert of Lost Frequencies. đ„ł
I've long had a list of "magic numbers" which show up in a bunch of places, and even made a post about it back in November of 2020. You ever wonder about certain permutations, like 497 days, or 19.6 years, or 5184 hours, and what they actually mean?
I've been doing that stuff by hand in a calculator and finally decided to just do it in Javascript and put it online for anyone to try.
So, here's my latest waste of CPU cycles:
(via)
Here's a tip that works on YouTube and almost any other web page that shows you a video. You can increase the playback rate beyond the usually-exposed 2x by running this in your browser DevTools console:
document.querySelector('video').playbackRate = 2.5
(via)
Cleaned up a bit the links in the sidebar.
I find myself clicking less and less on them.
Mostly reading blogs via NetNewsWire these days.
Removed:
Someday I should find the motivation to export an OPML file from the reader and make it available.
The full OPML list would be way too big for the sidebar, so a dedicated place would need to be found. đ
benjojo does some clever data analysis for Picking uncontested private IP subnets with usage data.
He not only gathers the usage data of the various subnets, but also provides a nice tool to get a /24 subnet from the list that has no known users.
And to top it off the article also provides the underlying data.
A Zip file with the /24 subnets with number of known users (local copy).
And the distilled list of subnets that have no known users (local copy).
As part of my migration to Bunny CDN for andreas-jaggi.ch, I also moved the DNS zone over.
There are not many records in the zone, but one which turned out to be a bit more tricky was the CAA one.
I wanted to use the following Terraform snippet to create it:
resource "bunnynet_dns_record" "andreas_jaggi_ch_CAA" { zone = bunnynet_dns_zone.andreas_jaggi_ch.id name = "" type = "CAA" value = "0 issue \"letsencrypt.org;validationmethods=http-01\"" }
But this always failed with a cryptic error message during terraform apply
:
â Error: Unable to create DNS record â â with bunnynet_dns_record.andreas_jaggi_ch_CAA, â on dns.tf line 22, in resource "bunnynet_dns_record" "andreas_jaggi_ch_CAA": â 22: resource "bunnynet_dns_record" "andreas_jaggi_ch_CAA" { â â A tag can be a maximum of 50 ASCII characters.
After some head-scratching I figured out that the Terraform provider has dedicated fields for the flags
and tag
parts of the CAA DNS record.
And it insists on them being used this way:
resource "bunnynet_dns_record" "andreas_jaggi_ch_CAA" { zone = bunnynet_dns_zone.andreas_jaggi_ch.id name = "" type = "CAA" tag = "issue" flags = 0 value = "letsencrypt.org;validationmethods=http-01" }
With this in place, it worked fine.
And it prepared me also for the MX record where a similar approach is required.
For andreas-jaggi.ch I wanted to try out Bunny CDN.
Everything went very smooth and I nicely used Terraform to configure Edge Rules blocking all unwanted access.
As andreas-jaggi.ch does not have much content this resulted in a list of allowed files similar to this:
resource "bunnynet_pullzone_edgerule" "andreas_jaggi_4" { pullzone = bunnynet_pullzone.andreas_jaggi.id description = "block not(known good) http://www.andreas-jaggi.ch" enabled = true match_type = "MatchNone" actions = [{ type = "BlockRequest", parameter1 = null, parameter2 = null, parameter3 = null }] triggers = [ { match_type = "MatchAny", patterns = [ "http://www.andreas-jaggi.ch/", "http://www.andreas-jaggi.ch/favicon.ico", "http://www.andreas-jaggi.ch/robots.txt", "http://www.andreas-jaggi.ch/security.txt", ], type = "Url", parameter1 = null, parameter2 = null }, ] }
After this I did setup the www subdomain as CNAME and added it as additional hostname to the CDN Pullzone.
But the process to get a Let's Encrypt certificate for the www subdomain always failed with an error.
This is where I messed up.
Turns out my Edge Rules blocking all unwanted access also blocked the Let's Encrypt validation requests. đ€Š
Once I realized this (which took a shamefully long amount of time), I added an entry to the Edge Rules for the .well-known/acme-challenge/
subpath:
resource "bunnynet_pullzone_edgerule" "andreas_jaggi_4" { pullzone = bunnynet_pullzone.andreas_jaggi.id description = "block not(known good) https://www.andreas-jaggi.ch" enabled = true match_type = "MatchNone" actions = [{ type = "BlockRequest", parameter1 = null, parameter2 = null, parameter3 = null }] triggers = [ { match_type = "MatchAny", patterns = [ "http://www.andreas-jaggi.ch/", "http://www.andreas-jaggi.ch/favicon.ico", "http://www.andreas-jaggi.ch/robots.txt", "http://www.andreas-jaggi.ch/security.txt", "http://www.andreas-jaggi.ch/.well-known/acme-challenge/*", ], type = "Url", parameter1 = null, parameter2 = null }, ] }
With this in place, the process worked immediately and the www subdomain now also serves encrypted traffic. đ
In the You can style alt text like any other text article, Andy Bell showcases how the alt test of images can be styled with CSS.
And then goes on to provide a smooth gracefully degrading experience by leveraging JavaScript to style image loading errors differently than successfully loaded images.
I like that CSS gives us plenty of opportunities to add finer details when we want them. One of those finer details is making the experience of an image not loading a little better.
The alt
text is surfaced on the page when an image fails to load.
Itâs yet another reason to write good alt text and really hone your skills in creating a user-focused experience by being descriptive.
Whatâs happening here is Iâm hooking a function up to the<img>
âs built-inonerror
event. When that event fires, Iâm setting adata-img-loading-error
attribute.
(via)
Here comes a handy utility:
timeout
. As the name suggests, this command adds a timeout to other commands. You specify the time limit you want to wait for a command and if that time passes,timeout
sends a signal to terminate it and exits with non-zero. By default,timeout
sendsSIGTERM
, but you can change it with the--signal
flag, e.g.timeout --signal=SIGKILL 1s foo
.For example,
timeout 1s sleep 5
will send theSIGTERM
signal tosleep
after 1 second.
(via)
After a bit more than 13 years I now removed Disqus from the blog.
Over these years, it only contributed 36 comments.
Most of them around a single post that made it onto the frontpage of Hacker News and Reddit.
I'll extract these comments from the export file of Disqus.
Then backfill them as static entries to the corresponding posts so they are preserved.
In the future I might add another way to comment/contribute directly on the blog.
For now, please use the communication channels listed on the About page.
(via)
This year, I missed the CSS Naked Day.
I very much like the idea of ensuring my blog is also readable without CSS.
Thus to make sure I'll not miss it next year, I've added the following snippet into my nginx config:
set $csp_style "'unsafe-inline' blog.x-way.org https://*.disquscdn.com https://gist.x-way.org/assets/"; if ( $time_iso8601 ~* ^20[0-9][0-9]-0?4-0?9T.*$ ) { set $csp_style "'none'"; } include /etc/nginx/conf_includes/x-way.org_security_headers;
It's using a very basic mechanism to ensure no CSS is shown on April 9 next year (or any other year)
First it checks if the date is April 9, and if yes it sets the variable for the style-src
Content-Security-Policy header to 'none'
.
Which forbids the browser to load any CSS when rendering my blog.
Now let's see how it looks next April 9th âșïž
Being only an occasional coffee drinker, I lack any coffee making machinery at home. Not even some instant-coffee.
Thus this text is going to be less extensive than the inspiration post from Mike.
I have my coffee usually outside. Sometimes a cup in the office at work (when not working from home).
And quite often in one of the nice cafes in Zurich.
This afternoon I had a very yummy Flat White made from «UBA purple» beans at MAME đ
In the Passkeys for Normal People article, Troy Hunt explains in simple terms how Passkeys work.
The article covers also what type of attack they prevent against (using Troy Hunt's recent falling for phishing experience) and how to setup Passkeys for common services.
At the end it briefly touches on using hardware U2F keys as well đ
Added some subtle links to the next and previous posts.
Turns out this is a built-in feature of Jekyll, which I never thought about using so far :-)
Here's the snippet which I just added to my custom post layout template:
<footer class="navfooter"> <nav> {%- if page.next.url %} <a rel="next" href="{{ site.url }}{{ page.next.url }}" title="{{ page.next.title | strip_html | escape_once }}">←</a> {% endif -%} {%- if page.previous.url %} <a rel="prev" href="{{ site.url }}{{ page.previous.url }}" title="{{ page.previous.title | strip_html | escape_once }}">→</a> {% endif -%} </nav> </footer>
(Only thing left now, is to tame the ugly Disqus comments section so these links become more visible…)
The Yeah, I Made It Lilac post inspired me to try to do something similar here.
I was wondering how complicated a post-specific style-sheet would be.
Turns out it can be quite simple.
First I changed my current style-sheet to use custom properties to define the colors in the :root pseudo-class.
This allows to make simple modifications without having to re-define a style-sheet from scratch.
Basically it is enough to re-define some of the custom properties with new colors, and everything else inherits them.
I already had some templating logic in place allowing to inject custom stylesheet fragments (eg. for the About and Statistics pages).
And a positive surprise, the logic behaves as desired when used for blog posts as well.
The custom stylesheet is injected when the page of the post is loaded, but is not injected when the post is shown as part of a collection (home page, archives, categories etc.).
Thus limiting the change to exactly the page of the post, and not messing with the style-sheet of other pages.
So in the end the lilac.css file which is injected for this post is quite simple:
:root { --border-color-3: #6952a7; --border-color-2: #a076c6; --border-color: #ddabe2; --pre-bg-color: #f7f7f9; }
Youâre in a rush and you need to grab a bottle of wine for a special occasion. Youâve got $40 and no preference for red or white, but you like wines with animal labels. Which wine are you buying?
We used ChatGPT Vision to identify animals on close to 1,500 wine labels to see if we could predict the price and quality of a bottle based on the animal on the label.
The Pour-Igin of Species by The Pudding.
TL;DR: New Zealand wines provide good quality for reasonable price. Cats are high quality.
(via)
In the Hiding elements that require JavaScript without JavaScript article, dade explains techniques to hide elements when JavaScript is not enabled.
The result is a generic class that can be applied to hide elements, and works with a clever use of <noscript>
:
<noscript> <style> .d-js-required { display: none; } </style> </noscript>
(via)
In his latest article Russ Cox explains the concept of using Differential Coverage for Debugging.
It's a clever approach using the difference of the coverage output between two test runs, to directly highlight the lines of code that contributed to a bug.
# collect coverage of a passing test run (skip the failing test) go test -coverprofile=c1.prof -skip='TestAddSub$' # collect coverage of a failing test run (run the failing test only) go test -coverprofile=c2.prof -run='TestAddSub$' # calculate the coverage difference between the runs (so only the code of the failing test gets highlighted) (head -1 c1.prof; diff c[12].prof | sed -n 's/^> //p') >c3.prof # display the code in a web browser (green/covered code did contribute to the failing test) go tool cover -html=c3.prof
The Web Key Directory (WKD) is a standard for discovery of OpenPGP keys by email address, via the domain of its email provider.
The following command can be used to test/import a key via WKD.
gpg --locate-keys --auto-key-locate clear,nodefault,wkd address@example.org
(via)
Added a -f
flag to the pgp-expiry-monitor tool.
It takes the fingerprint of a PGP key and looks it up on keys.openpgp.org to get the keyfile to verify.
% pgp-expiry-monitor -f 401F1D483C69BF624364CC01E9A68DCFA3A54203 -v Key A3A54203 (401f1d483c69bf624364cc01e9a68dcfa3a54203) expires on 2030-04-13 Key 29A48884 (1e8838bdcf9adf702496866f6baf170e29a48884) expires on 2025-10-15 Key B645E283 (47122b88b77ece545effb494498ea9eab645e283) expires on 2025-11-17 Key 93DDE912 (2f21f0dd9af127d61363423d4099876b93dde912) expires on 2027-04-24 Key 0240ACAF (a1f4c70962f89c2e628e8f05d29a32fd0240acaf) expires on 2026-04-09 Key 0B691623 (0d0bc31f58b8d18cb97c31eeebd187b60b691623) expires on 2027-04-13 Key 3AB76067 (43a83177a4ec64a62bae1ac77d779e883ab76067) expires on 2026-04-09 Key 7AE809A1 (9a6d5dbde2703d7c54806f1b5acb66c47ae809a1) expires on 2027-04-13
Hallucinated package names fuel 'slopsquatting'.
All that's required is to create a malicious software package under a hallucinated package name and then upload the bad package to a package registry or index like PyPI or npm for distribution. Thereafter, when an AI code assistant re-hallucinates the co-opted name, the process of installing dependencies and executing the code will run the malware.
(via)
To ensure I don't forget to rotate/extend one of the subkeys of my PGP key, I created a little monitoring tool.
I wanted something that reminds me well before my published PGP key shows sign of expiry.
And I wanted it built in a way so it can be used in a simple cronjob to continuously nag me until the expiring key has been replaced. đ
So pgp-expiry-monitor was born.
It takes two parameters, the URL of a PGP key and the number of days in advance it should start warning.
If all is fine and the PGP key does not contain any expiring keys, it returns without any output.
Thus ideal for a cronjob.
Discovered a very helpful debugging utility: GPG/PGP Decoder
The hosted version helps to quickly find out which subkey was used to sign a message.
I used it to check that this signature contains the fingerprint and ID of my new subkey đ
One of my yearly digital routines is to update my GPG key.
Part of this involves adding new ECC subkeys (ECDH and EdDSA).
These are the commands I used this time (so I don't have to look them up again next year).
% gpg --edit-key 401F1D483C69BF624364CC01E9A68DCFA3A54203
gpg> addkey Select number 10 ECC signing Select number 1 Curve 25519 Select a validity of 2y
gpg> addkey Select number 12 ECC encryption Select number 1 Curve 25519 Select a validity of 2y
gpg> save
After this the new subkeys are available and the updated public key can be exported and published.
TIL: With iOS 18 a new feature was added to lock or hide apps.
Apps can be locked so that they require the passcode or FaceID to be opened.
And they also can be hidden so that they no longer appear on the homescreen.
Lock or hide an app on iPhone - Apple Support
(via)
zkbro discovered the nice Blanket web version of the Blanket Gnome/Linux app. Provides you with a selection of ambient sounds. Ranging from Nature over Travel, Interiors to Pink/White Noise.
50 ways to rest – Nicola Jane Hobbs
For anyone else who is in a season of their life where naps and hot baths and yoga classes are inaccessible, we can still rest. We might not be able to get the rest we truly need, but we can find little pockets of respite among the demands and responsibilities of our lives.
(via)
Hubble explores the universe 24 hours a day, 7 days a week. That means it has observed some fascinating cosmic wonder every day of the year, including on your birthday.
What did Hubble look at on your birthday? Enter the month and date below to find out! What Did Hubble See on Your Birthday? - NASA Science
My birthday picture is of the Whirlpool Galaxy:
(via)
no hello - please don't say just hello in chat
(via)
Saw this Blog Questions Challenge about Travel Adventures and it piqued my interest.
What's the silliest souvenir you've ever brought back from a trip?
More stupid than silly. On my way to Australia, I bought some very nice honey in Mauritius.
It promptly got confiscated by the Australian Border Force as their biosecurity does not allow the import of honey.
If you could teleport anywhere right now, for a day trip, where would you go?
Off the top of my head this would be Île des Pins in New Caledonia.
I spent two very nice days there in 2018 while doing an extended New Caledonia weekend trip during my last rotation in Sydney.
What's the weirdest food you've ever tried while traveling?
Probably crocodile. This was in 2013 while traveling in Australia.
There was a australian game meat BBQ organized for us tourists, and various meats could be tasted.
Didn't particularly like the crocodile, it tasted a lot like chicken.
The hosts explained that crocodile usually tastes like the thing it eats, and these ones were fed with chicken, cue them tasting like chicken.
What's the most memorable "wrong turn" you've taken on an adventure?
While traveling by train to Amsterdam, somewhere outside Frankfurt there was a problem with the tracks.
The ICE I was on, returned halfway to Frankfurt and then used a very long but scenic route along the Rhine river to reach Koeln.
Overall the journey to Amsterdam took 4 hours longer than planned, but we got to see some very pitoresque villages along the river.
(via)
How to write exceptional documentation
(via)
I recently tried out Claude Code for both some personal project as well as some work project.
Was very impressed how far the AI coding assistants have come already.
Looks like a powerful tool when used by an experienced software engineer.
I've been using Claude Code for a couple of days, and it has been absolutely ruthless in chewing through legacy bugs in my gnarly old code base. It's like a wood chipper fueled by dollars. It can power through shockingly impressive tasks, using nothing but chat. [...]
Claude Code's form factor is clunky as hell, it has no multimodal support, and it's hard to juggle with other tools. But it doesn't matter. It might look antiquated but it makes Cursor, Windsurf, Augment and the rest of the lot (yeah, ours too, and Copilot, let's be honest) FEEL antiquated.
â Steve Yegge, who works on Cody at Sourcegraph
(via)
If your content is only on social media, I'm not going to see it by Cory Dransfeldt.
If you only post on social media, I won't see it. If you don't have an RSS feed, I won't follow it, I won't subscribe to it. I don't want want your app because I don't want a homescreen full of apps for publications and platforms.
I don't have a fear of missing out. I am missing out. I've come to terms with that. Algorithms can be a convenient means of surfacing relevant content. They can be. But those algorithms are tailored by platform operators whose aims are (very) often not aligned with yours. They tailor content discovery purely to keep you hooked. Eyeballs to ads, money to shareholders.
Or as commented on by Mike Sass:
Same same. Just get an RSS feed, and stop relying on the hegemonic platform silos.
(via)
Tmux - the essentials is a concise article by David Winter giving a gentle introduction to the tmux terminal multiplexer.
tmux
create a new tmux sessiontmux ls
list any existing tmux sessionstmux a
reattach to the last open tmux sessionctrl
+b
the default tmux command prefixprefix
+d
detach from current tmux sessionprefix
+c
create a new windowprefix
+0
-9
to switch to the numbered windowprefix
+,
rename the existing windowprefix
+%
split the current pane into two vertical panes, left and rightprefix
+"
split the current pane into two horizontal panes, top and bottomprefix
+q
view numbered panes for current windowprefix
+q
,0
-9
switch to pane immediately after displaying pane numbersprefix
+z
to zoom and unzoom
(via)
Jan-Piet Mens wrote up a short note explaining how to sign Git commits using an SSH key. It also includes a short guide how to setup your GitHub account to recognize the SSH signing key.
$ git config --global user.signingkey ~/.ssh/key_file.pub $ git config --global gpg.format ssh $ git config --global commit.gpgsign true $ git config --global tag.gpgsign true
In SPACE Framework: 5 Metrics That Actually Work, Csaba Okrona explains the five dimensions of the SPACE framework for developer productivity. For each dimension he presents examples of real-life indicators.
Satisfaction and Well-being: The Foundation
- Work-life balance metrics (after-hours commits, weekend work patterns)
- Team survey responses about job satisfaction
- Voluntary overtime trends
- Project ownership satisfaction
- Learning and growth opportunities
Performance: Outcomes Over Output
- Feature adoption rates
- Customer impact metrics
- System reliability improvements
- Technical debt reduction impact
- Time-to-value for new features
Activity: The Daily Reality
- Time distribution across different types of work
- Code review participation patterns
- Documentation contributions
- Technical design involvement
- Mentorship and knowledge sharing activities
Communication and Collaboration: The Force Multiplier
- Code review response times
- Cross-team collaboration frequency
- Knowledge sharing effectiveness
- Documentation quality and usage
- Meeting efficiency ratings
Efficiency and Flow: The Productivity Engine
- Time blocked on dependencies
- Context switching frequency
- Deployment pipeline efficiency
- Build time trends
- Interruption patterns
How Core Git Developers Configure Git
What `git config` settings should be defaults by now? Here are some settings that even the core developers change.
TLDR
# clearly makes git better [column] ui = auto [branch] sort = -committerdate [tag] sort = version:refname [init] defaultBranch = main [diff] algorithm = histogram colorMoved = plain mnemonicPrefix = true renames = true [push] default = simple autoSetupRemote = true followTags = true [fetch] prune = true pruneTags = true all = true # why the hell not? [help] autocorrect = prompt [commit] verbose = true [rerere] enabled = true autoupdate = true [core] excludesfile = ~/.gitignore [rebase] autoSquash = true autoStash = true updateRefs = true # a matter of taste (uncomment if you dare) [core] # fsmonitor = true # untrackedCache = true [merge] # (just 'diff3' if git version < 2.3) # conflictstyle = zdiff3 [pull] # rebase = true
(via)
There's a corner of the Internet where people have been reclaiming their digital independence by hosting their own websites and promoting the idea of owning your own contentâit's called the IndieWeb.
This movement promotes the idea that individuals should control their own digital presence through personal websites. But every time this topic comes up in online discussions, someone inevitably claims that the IndieWeb hasn't taken off!
The IndieWeb doesn't need to go mainstream to be meaningful. It's a celebration of a more personal, decentralised, and creative world wide web. And for those of us who still care about these values, it is already meaningful.
Nice article by Mike Sass explaining how he added shark fins to the <hr> on his site: Shark Fin <hr>
(via)
MapCanvas creates beautiful map portraits.
You can enter any city and have it generate minimal custom maps.
And if inclined also order them as printouts and framed posters.
(via)
Name your own gulf by MapQuest.
(via)
Finding Flow: Escaping Digital Distractions Through Deep Work and Slow Living – a personal guide to reclaiming focus in the age of endless temptation.
— Simon SpĂ€ti
The Stolen Focus: Why You Canât Pay Attention book by Johann Hari which inspired this article goes on the /reading list đ
âI urge you to please notice when you are happy, and exclaim or murmur or think at some point, âIf this isnât nice, I donât know what is.ââ
— Kurt Vonnegut
(via)
Itâs a simple two-step process:
- First, notice. Notice that things are good. Notice the feeling of pleasure. Notice todayâs perfect temperature. Notice the art project your child is sharing with you.
- Then, say thank you. To the person youâre with, for the life you live, to the reality youâve been blessed with, to the God you feel must be there.
And if none of those feel like the right objects of gratitude, thatâs okay too. Simply murmur to yourself, âIf this isnât nice, I donât know what is.â
(via)
Ruben Schade published a post with answers to the terminal survey that Julia Evans recently conducted.
Inspired by this, below are my answers to these questions.
Since 2002.
zsh (on my laptop/workstation), bash (on servers).
No and yes (was using zsh before macOS made it the default).
macOS, Linux.
Terminal.app, GNOME Terminal.
Yes, vim.
Yes, my current scheme evolved from the 2003 Gentoo default scheme.
Run reset
.
PATH
, environment variables, alias, the prompt, custom functions, history, syntax-highlighting.
No. Tried it sporadically, but not really my thing, rather using a terminal multiplexer.
Basic local operations mostly in the GUI. Anything advanced, automated, remote or mass-operations in the terminal.
PATH
, EDITOR
, and some others:
% grep export zshrc/zshrc|sed -e 's/=.*//' export GIT_AUTHOR_NAME export GIT_COMMITTER_NAME export TZ export PERL5LIB export GOPATH export LOCKPRG export SAM_CLI_TELEMETRY export JAVA_HOME export RSYNC_RSH export CVS_RSH export EDITOR export USE_EDITOR export CVSEDITOR export BROWSER export LESS export HOMEBREW_NO_ANALYTICS export WWW_BROWSER
Yes.
/
to search, then mostly spacebar to scroll and the occasional j
/k
.
sort
, uniq
, tr
, sed
, find
with xargs
to parallelise, and awk
.
screen
(still trying to migrate to tmux
, eventually).
Scripts assuming GNU specific parameters/tools on macOS.
Whenever somebody sends you a pull request, give them commit access to your project.
In the Conventional Commits article, Mike Perham explains how git commit templating can be used to support commit message consistency.
The key part is the template
statement in the ~/.gitconfig
:
[commit] template = ~/.gitmessage
This references the ~/.gitmessage
file which is used as template for every new commit message.
For Conventional Commits, the following can be useful:
# type(subsystem): short description ### Types # feat: A new feature # fix: A bug fix # docs: Documentation only changes # build: Changes that affect the build system or external dependencies # ci: Changes to our CI configuration files and scripts # perf: A code change that improves performance # refactor: A code change that neither fixes a bug nor adds a feature # style: Changes that do not affect the meaning of the code # test: Adding missing tests or correcting existing tests
In Re-ordering Git commits, Cassidy Williams explains nicely how interactive Git rebasing can be used to re-order Git commits.
TL;DR:
git rebase -i HEAD~4
In The beauty of goofy diagrams Einenlum explains how a diagram drawn in a more casual style, can support conveying information easier to the audience.
The thing is, Iâm more and more convinced that the style of a presentation matters. Even before looking at the content itself, the style puts you in a particular mood.
[...] To me, although they convey the same content, the first one creates a sense of seriousness and gravity. It feels like only clever people can understand it. Iâm already a bit tense and I feel like I need to focus. I almost take a deep breath and say to myself âokay, you can do itâ. I feel dumb but I feel that with enough curiosity and hard work I can understand the content.
The second one, on the other hand, makes me feel more relaxed and probably more curious. The topic seems easier to grasp and Iâm quite confident I can understand it. It doesnât mean it brings more clarity: the first diagram is actually probably clearer but the content has more chance of reaching my brain with the second one because Iâm more open to it.
(via)
I upgraded the blog to the newest Jekyll 4.4.0 which was released yesterday.
Unfortunately this first resulted in the following segfault while running jekyll build
đ
/usr/gem/gems/sass-embedded-1.83.4/ext/sass/embedded_sass_pb.rb:11: [BUG] Segmentation fault at 0x0000000000004410 ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux-musl]
Turns out that this is a known problem of the google-protobuf gem (which is used by jekyll-sass-converter which is part of the default Jekyll).
Luckily there is a workaround.
Adding the following to my Gemfile
fixed it đ
gem 'google-protobuf', force_ruby_platform: true if RUBY_PLATFORM.include?('linux-musl')
Robert Birming maintains a very nice Blog Inspiration page.
It contains a collection of articles and resources providing inspiration for blogging.
Ranging from inspiring stories why people blog, over blog directories to accessibility and design resources.
(via)
One more for the list of blog directories: blogroll.club — A Blog Directory
A space dedicated to curating a diverse and comprehensive collection of blogs, and personal sites across the web. The goal is to foster a community where content is available for anyone and everyone.
Everything about this site is hand-crafted by two human beings: JCProbably and Lou Plummer.
Russel Baylis shares this helpful article about their learnings regarding improving the working environment to reduce eye strain.
I work from home everyday, I am susceptible to eye strain, eye pain, and dizziness. Having a working environment thatâs as easy on my eyes as possible is of critical importance. I'd like to share what I've learned over the years in hopes that it can be helpful to you if you work from home, and like many, have experienced WFH eye strain.
- An even, diffused lighting environment is best for the eyes
- When it comes to light brightness, too much is just as problematic as too little
- Use natural light wherever possible
- Quality of artificial light matters
- The best lighting for camera, is not necessarily the best lighting for ergonomics
- Even the perfect lighting environment will fatigue you â take breaks, and take care of yourself
(via)
When connecting to an older SSH device the following 'unable to negotiate' errors occurred. They indicate that my client-side config does not allow the (old/obsolete) methods offered by the device.
Unable to negotiate with 10.222.23.2 port 22: no matching key exchange method found. Their offer: diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1,diffie-hellman-group14-sha1
This can be fixed by enabling one of the old key exchange methods:
ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 10.222.23.2
Unable to negotiate with 10.222.23.2 port 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss
This can be fixed by additionally enabling one of the old host key types:
ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -oHostKeyAlgorithms=+ssh-rsa 10.222.23.2
terra tauri quotes from the Platform Engineering book:
If you only promote people who solve big technical problems, youâre going to have a hard time retaining the people who do the work to smooth out the usability edges, actively listen to the customer teams, and adjust their work priorities to fix the stuff that is causing the most pain. So, look closely at what you are celebrating, compensating, and promoting, and make sure you are including work that makes the product better, whatever that looks like, even if it isnât the hardest technical bits. You may even want to reevaluate your engineering ladder to make sure the expectations at each level reflect all of the skills you now demand. Remember, this is a cultural change, and cultural changes that donât involve changes to what is valued (as seen by what you recognize and reward) are destined to fail.
Looks like this might be a candidate for my /reading list.
(via)
Flexoki — a great looking color scheme inspired by paper and ink colors.
Flexoki is an inky color scheme for prose and code. Flexoki is designed for reading and writing on digital screens. It is inspired by analog inks and warm shades of paper.
Flexoki is minimalistic and high-contrast. The colors are calibrated for legibility and perceptual balance across devices and when switching between light and dark modes.
(via)
Manu Moreale: Blogging: youâre doing it right
Thatâs all you need to know. If youâre doing it, youâre doing it right. If you have decided to reclaim ownership of your place on the web, youâre doing it right. It doesnât matter how you did it. [...] What matters is that youâre doing it. Your effort is commendable. You deserve to be thanked so, thank you.
(via)
My new favorite type of CAPTCHA: DOOM CAPTCHA
(via)
During casual surfing I found this article from Brain Baker explaining their revised backup strategy.
The most interesting part was the brief mention of PhotoSync used to sync photos to their Linux system.
This came just at the right moment, as I was exploring options how to get photos from an iPhone to a Linux machine as seemlessly as possible.
Previous attempts with ifuse/libimobiledevice didn't work reliably, and uploading the photos to iCloud and somehow scraping/downloading them again doesn't look very future-proof either.
Thus very happy about PhotoSync which runs on the iPhone and talks a plethora of protocols on the other side (in my case I opted for SFTP).
It is a freemium app with paid in-app purchase for the pro/premium features (raw photo sync and autosync in the background).
Based on the good reviews and initial functionality testing of the free version I decided to fo for the one-time purchase to unlock the premium features.
I did setup a chrooted SFTP user to receive the photos on the Linux machine.
Then configured this SFTP access in the app which worked seamless.
So far the manual sync of existing photos and videos worked reliably over WiFi.
And I'm looking forward for the geofence-triggered autosync to run đ€đ»
In this article, MacKenzie builds up a config, script and systemd file to respectfully fetch an RSS feed with curl.
It uses the following as base config for curl:
fail compressed max-time = 30 no-progress-meter alt-svc = alt-svc-cache.txt etag-compare = tech.CitizenLab.rss.etag etag-save = tech.CitizenLab.rss.etag output = tech.CitizenLab.rss.xml time-cond = "Tue, 05 Nov 2024 15:00:35 GMT" write-out = "%output{tech.CitizenLab.rss.lm}%header{last-modified}" url = "https://citizenlab.ca/feed/" next
Then adds conditional checks for the etag-compare
and time-cond
directives, so they are only added if the corresponding file contains a non-empty value.
The last part is then to use a systemd Timer file with OnUnitInactiveSec=1hour
, so that the command will be run one hour after the previous run finished.