Skip to content

Instantly share code, notes, and snippets.

@creachadair
creachadair / rsync-pitfall.md
Created April 25, 2026 17:48
A Curious Permission Preservation Pitfall in rsync

A Curious Permission Preservation Pitfall in rsync

When using rsync to back up or archive data, you typically want to preserve file metadata such as owner and group ID, permissions, and modification times, in addition to the file content. You might run with --archive (-a) or using the --times (-t), --perms (-P), --owner (-o) and --group (-g) flags, for example.

In particular, preserving permissions naturally means that if a file is read-only in the source (e.g., mode 0444 or -r--r--r--), then its mirror in the destination will also be read-only. This is working as intended, and does not ordinarily cause any problems because (by default) when rsync updates file contents, it does so by creating a (writable) temp file with the new content, then replacing the target file (and updating the file metadata) once it is complete.

The --inplace flag overrides the default behaviour, causing rsync to update existing target files directly rather than via a temporary. This can be useful when dea

@creachadair
creachadair / app-installation.md
Created June 3, 2025 16:28
Finding the installation ID of a GitHub app installation

Find the Installation ID of a GitHub App Installation

  • Go to the org settings.
  • Select GitHub Apps.
  • Find the app and select its "Configure".
  • In the title choose "App settings".
  • Open the tab "Install App".
  • On the installation of interest, select the settings (gear icon).

The installation ID is the trailing number in the resulting URL:

@creachadair
creachadair / compact-func.md
Last active September 20, 2025 04:52
A Go syntax for compact function literals

A Go Syntax for Compact Function Literals

Note

This does not exist, I am sketching out a design idea.

The go keyword accepts a call expression, evaluates all the terms of the expression up to the point of the call itself, then issues the call inside a newly-created goroutine.

By analogy, the call keyword accepts a call expression and generates a function literal that evalutes that expression.

Examples

@creachadair
creachadair / port-mnemonics.md
Created December 3, 2024 22:32
Port numbering mnemonics

Mnemonics for port numbers

Although this convention is quite old, I only learned of it fairly recently. One way to pick a "memorable" port number is to use a telephone-style encoding of the digits to their corresponding letters on a (QWERTY) keyboard. So, just as one might spell 364-9255 as "DOG-WALK", you can do the same trick with the keyboard letters.

In tabular format, that is:

1  2  3  4  5  6  7  8  9  0
Q  W  E  R  T  Y  U  I  O  P
A S D F G H J K L ?
@creachadair
creachadair / reddit-api.md
Created October 22, 2024 22:43
Calling the Reddit API

Calling the Reddit API

Most requests go to https://www.reddit.com[/path], where paths are either /api/... or /r/subreddit/... or similar, depending on the method. API docs give the details.

Many APIs permit unauthenticated access, but Reddit imposes rate limits and—perhaps more annoyingly—blocks various IP ranges (notably a bunch of AWS). Their support does not respond to tickets unless you embarrass them publicly. I lack both the ability and the desire to do that, so I needed another way.

So anyway, the recommended way to talk to the API is using OAuth, which is annoying if all you wanted to do was grab a few stats about your subreddits. Fortunately, they have a lighter-weight auth flow you can use, described in https://github.com/reddit-archive/reddit/wiki/OAuth2#application-only-oauth

In summary:

@creachadair
creachadair / update-aws-cli.sh
Last active March 13, 2026 15:34
Update installed version of the AWS CLI on a Linux system
#!/usr/bin/env bash
#
# Update the installed version of the AWS CLI on Linux.
#
set -euo pipefail
: ${TMPDIR:=/tmp}
tmp="$(mktemp -d $TMPDIR/awscli.XXXXXXXXXX)"
trap "rm -fr -- '$tmp'" EXIT
@creachadair
creachadair / remove-taint.sh
Created September 13, 2024 17:09
Remove quarantine taint from files on macOS
#!/usr/bin/env bash
#
# Usage: remove-taint.sh <filename>
#
# Remove the annoying mark-of-the-web taint xattrs from a file.
# For some reason macOS ignores a removexattr for these attributes,
# but the taint does not survive a pipe copy and rename.
#
set -euo pipefail
@creachadair
creachadair / self-signed-tls.md
Last active November 24, 2024 23:54
Self-signed TLS certificates

Creating Self-Signed TLS Certificates

(see also: https://github.com/creachadair/tlsutil)

A "CA" certificate is basically just a self-signed certificate that someone has blessed. There are a few pedantic details you have to get right in the cert settings if you want a browser to accept it (particularly an older browser), but CLI tools seem to be less picky.

@creachadair
creachadair / go-mod-proxy.md
Last active August 23, 2024 04:56
Notes on building a Go module caching proxy
@creachadair
creachadair / go-experiment.md
Last active November 24, 2024 23:47
Installing a Go toolchain with a GOEXPERIMENT set

Installing a Go Toolchain with GOEXPERIMENT

(see also: https://github.com/creachadair/misctools/blob/main/scripts/install-go.sh)

Go allows the definition of named, [experimental features][xpkg], which are established by setting GOEXPERIMENT in the environment. While some of these features are [available at runtime][xrun], some must be enabled when building the toolchain itself. An example of the latter is the [cacheprog experiment][xcp] (as of August 2024).

To enable such an experiment:

  1. Download a source distribution of Go.
  2. Unpack the distribution and cd go/src.