1
0
mirror of https://github.com/jbranchaud/til synced 2026-01-07 09:08:01 +00:00

Compare commits

...

27 Commits

Author SHA1 Message Date
Irbaz Ahmed
3137ed2b1d Merge 0044cb1381 into c8445c45a9 2025-03-06 12:02:18 -05:00
jbranchaud
c8445c45a9 Add Read Existing Dot Env File Into Env Vars as a Mise TIL 2025-03-05 13:19:08 -06:00
jbranchaud
497b0ff3b7 Add Files With Local Changes Cannot Be Removed as a Git TIL 2025-03-04 18:05:58 -06:00
jbranchaud
64df6d16d7 Add Find All Tool Version Files Containing Postgres as a Unix TIL 2025-03-04 17:41:03 -06:00
jbranchaud
7dac057246 Add List The Files Being Loaded By Mise as a Mise TIL 2025-03-04 09:24:27 -06:00
jbranchaud
8961c67026 Add Create Todo Items In Logseq as a Workflow TIL 2025-03-03 17:06:58 -06:00
jbranchaud
4ff24a7336 Add Restart Puma Server By Touching Restart File as a Rails TIL 2025-03-01 09:48:48 -06:00
jbranchaud
2916fbc3b5 Add Create And Jump Into A Directory as a Zsh TIL 2025-02-28 10:39:23 -06:00
jbranchaud
e3fc10edd8 Fix alphabetical ordering of Rails TILs 2025-02-26 16:53:08 -06:00
jbranchaud
4fe0817b2d Add Buy Me A Coffee Link to README 2025-02-26 16:52:32 -06:00
jbranchaud
fc74264040 Add Adjust The Production Log Level as a Rails TIL 2025-02-26 16:52:13 -06:00
jbranchaud
2b38e1caf8 Add SSH Into An ECS Container as an AWS TIL 2025-02-25 12:12:52 -06:00
jbranchaud
db6d18f086 Add Enforce Locals Passed To A Partial as a Rails TIL 2025-02-24 19:15:52 -06:00
jbranchaud
84548b7a7f Add List The PID And Name Of Current Shell Process as a Unix TIL 2025-02-23 10:12:52 -06:00
jbranchaud
f9b966a0f1 Add Use Specific AWS Profile With CLI as an AWS TIL 2025-02-23 09:57:30 -06:00
jbranchaud
871d555e95 Add Filter Blur Requires Expensive Calculation as a CSS TIL 2025-02-21 15:29:14 -06:00
jbranchaud
cea3bc05b5 Add Fix Previous Command With fc as a Unix TIL 2025-02-20 17:42:32 -06:00
jbranchaud
ee31f5b70d Add Find And Follow Server Logs as an AWS TIL 2025-02-19 09:00:35 -06:00
jbranchaud
5b6a88b327 Remove the amplify TOC item, no longer exists 2025-02-19 09:00:11 -06:00
jbranchaud
49ebb8dd78 Add A Better Way To Reload ZSH Configuration as a ZSH TIL 2025-02-18 17:06:35 -06:00
jbranchaud
6ff8f19d08 Add OpenStruct Has Bad Performance Characteristics as a Ruby TIL 2025-02-17 15:32:15 -06:00
jbranchaud
14e6635383 Add Fix Shim Path After asdf Upgrade as a Unix TIL 2025-02-17 10:31:58 -06:00
jbranchaud
0a0a509827 Link to groff in latest TIL 2025-02-17 09:52:06 -06:00
jbranchaud
bb331577ca Collapse Amplify category into the AWS category 2025-02-17 09:46:02 -06:00
jbranchaud
0e0dcbf2b4 Add AWS CLI Requires Groff Executable as an AWS TIL 2025-02-17 09:44:27 -06:00
jbranchaud
fe9b62a631 Add Prevent Containers From Running On Startup as a Docker TIL 2025-02-13 11:44:38 -06:00
IA21
0044cb1381 Added another shortcut (Alt+D) that can be done with one hand. 2020-04-19 20:16:13 +05:00
23 changed files with 755 additions and 9 deletions

View File

@@ -10,20 +10,23 @@ pairing with smart people at Hashrocket.
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
_1589 TILs and counting..._
_1609 TILs and counting..._
See some of the other learning resources I work on:
- [Ruby Operator Lookup](https://www.visualmode.dev/ruby-operators)
- [Vim Un-Alphabet](https://www.youtube.com/playlist?list=PL46-cKSxMYYCMpzXo6p0Cof8hJInYgohU)
If you've learned something here, support my efforts writing daily TILs by
[buying me a coffee](https://buymeacoffee.com/jbranchaud) 💜
---
### Categories
* [Ack](#ack)
* [Amplify](#amplify)
* [Ansible](#ansible)
* [Astro](#astro)
* [AWS](#aws)
* [Brew](#brew)
* [Chrome](#chrome)
* [Clojure](#clojure)
@@ -51,6 +54,7 @@ See some of the other learning resources I work on:
* [Linux](#linux)
* [LLM](#llm)
* [Mac](#mac)
* [Mise](#mise)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
* [Neovim](#neovim)
@@ -97,10 +101,6 @@ See some of the other learning resources I work on:
- [Case-Insensitive Search](ack/case-insensitive-search.md)
- [List Available File Types](ack/list-available-file-types.md)
### Amplify
- [Sign Up User With Email And Password](amplify/sign-up-user-with-email-and-password.md)
### Ansible
- [Loop Over A List Of Dictionaries](ansible/loop-over-a-list-of-dictionaries.md)
@@ -110,6 +110,14 @@ See some of the other learning resources I work on:
- [Generate Types For A Content Collection](astro/generate-types-for-a-content-collection.md)
- [Markdown Files Are Of Type MarkdownInstance](astro/markdown-files-are-of-type-markdown-instance.md)
### AWS
- [AWS CLI Requires Groff Executable](aws/aws-cli-requires-groff-executable.md)
- [Find And Follow Server Logs](aws/find-and-follow-server-logs.md)
- [Sign Up User With Email And Password](aws/sign-up-user-with-email-and-password.md)
- [SSH Into An ECS Container](aws/ssh-into-an-ecs-container.md)
- [Use Specific AWS Profile With CLI](aws/use-specific-aws-profile-with-cli.md)
### Brew
- [Configure Brew Environment Variables](brew/configure-brew-environment-variables.md)
@@ -176,6 +184,7 @@ See some of the other learning resources I work on:
- [Define HSL Colors With Alpha Values](css/define-hsl-colors-with-alpha-values.md)
- [Display Responsive iframe Maintaining Aspect Ratio](css/display-responsive-iframe-maintaining-aspect-ratio.md)
- [Dry Up SCSS With Mixins](css/dry-up-scss-with-mixins.md)
- [Filter Blur Requires Expensive Calculation](css/filter-blur-requires-expensive-calculation.md)
- [Give Elements The Same Width With Flexbox](css/give-elements-the-same-width-with-flexbox.md)
- [Let Pointer Events Pass Through An Element](css/let-pointer-events-pass-through-an-element.md)
- [Lighten And Darken With CSS Brightness Filter](css/lighten-and-darken-with-css-brightness-filter.md)
@@ -216,6 +225,7 @@ See some of the other learning resources I work on:
- [Configure Different Host And Container Ports](docker/configure-different-host-and-container-ports.md)
- [List Running Docker Containers](docker/list-running-docker-containers.md)
- [Prevent Containers From Running On Startup](docker/prevent-containers-from-running-on-startup.md)
- [Run A Basic PostgreSQL Server In Docker](docker/run-a-basic-postgresql-server-in-docker.md)
### Drizzle
@@ -317,6 +327,7 @@ See some of the other learning resources I work on:
- [Exclude A File From A Diff Output](git/exclude-a-file-from-a-diff-output.md)
- [Excluding Files Locally](git/excluding-files-locally.md)
- [Extend Git With Custom Commands](git/extend-git-with-custom-commands.md)
- [Files With Local Changes Cannot Be Removed](git/files-with-local-changes-cannot-be-removed.md)
- [Find And Remove Files That Match A Name](git/find-and-remove-files-that-match-a-name.md)
- [Find The Date That A File Was Added To The Repo](git/find-the-date-that-a-file-was-added-to-the-repo.md)
- [Find The Initial Commit](git/find-the-initial-commit.md)
@@ -677,6 +688,11 @@ See some of the other learning resources I work on:
- [View All Windows Of The Current App](mac/view-all-windows-of-the-current-app.md)
- [Write System Clipboard To A File](mac/write-system-clipboard-to-a-file.md)
### Mise
- [List The Files Being Loaded By Mise](mise/list-the-files-being-loaded-by-mise.md)
- [Read Existing Dot Env File Into Env Vars](mise/read-existing-dot-env-file-into-env-vars.md)
### MongoDB
- [Determine The Database Version](mongodb/determine-the-database-version.md)
@@ -947,6 +963,8 @@ See some of the other learning resources I work on:
### Rails
- [Access Secrets In A Rails 5.2 App](rails/access-secrets-in-a-rails-5-2-app.md)
- [ActiveRecord Query For This Or That](rails/active-record-query-for-this-or-that.md)
- [Add A Check Constraint To A Table](rails/add-a-check-constraint-to-a-table.md)
- [Add A Database Index If It Does Not Already Exist](rails/add-a-database-index-if-it-does-not-already-exist.md)
- [Add A Foreign Key Reference To A Table](rails/add-a-foreign-key-reference-to-a-table.md)
@@ -955,8 +973,7 @@ See some of the other learning resources I work on:
- [Add ActiveRecord Error Not Tied To Any Attribute](rails/add-activerecord-error-not-tied-to-any-attribute.md)
- [Add React With Webpacker To A New Rails App](rails/add-react-with-webpacker-to-a-new-rails-app.md)
- [Add timestamptz Columns With The Migration DSL](rails/add-timestamptz-columns-with-the-migration-dsl.md)
- [Access Secrets In A Rails 5.2 App](rails/access-secrets-in-a-rails-5-2-app.md)
- [ActiveRecord Query For This Or That](rails/active-record-query-for-this-or-that.md)
- [Adjust The Production Log Level](rails/adjust-the-production-log-level.md)
- [Advance The Date](rails/advance-the-date.md)
- [Allow Associations To Be Optional](rails/allow-associations-to-be-optional.md)
- [Allow List Params Anywhere With Strong Params](rails/allow-list-params-anywhere-with-strong-params.md)
@@ -999,6 +1016,7 @@ See some of the other learning resources I work on:
- [Different Ways To Add A Foreign Key Reference](rails/different-ways-to-add-a-foreign-key-reference.md)
- [Disambiguate Where In A Joined Relation](rails/disambiguate-where-in-a-joined-relation.md)
- [Empty find_by Returns First Record](rails/empty-find-by-returns-first-record.md)
- [Enforce Locals Passed To A Partial](rails/enforce-locals-passed-to-a-partial.md)
- [Ensure A Rake Task Cannot Write Data](rails/ensure-a-rake-task-cannot-write-data.md)
- [Ensure Migrations Use The Latest Schema](rails/ensure-migrations-use-the-latest-schema.md)
- [Ensure Record Saved With after_commit Callback](rails/ensure-record-saved-with-after-commit-callback.md)
@@ -1063,6 +1081,7 @@ See some of the other learning resources I work on:
- [Rescue From](rails/rescue-from.md)
- [Rescue From With A Separate Method](rails/rescue-from-with-a-separate-method.md)
- [Respond With JSON Regardless of Content Type](rails/respond-with-json-regardless-of-content-type.md)
- [Restart Puma Server By Touching Restart File](rails/restart-puma-server-by-touching-restart-file.md)
- [Retrieve An Object If It Exists](rails/retrieve-an-object-if-it-exists.md)
- [Rollback A Couple Migrations](rails/rollback-a-couple-migrations.md)
- [Rollback A Specific Migration Out Of Order](rails/rollback-a-specific-migration-out-of-order.md)
@@ -1316,6 +1335,7 @@ See some of the other learning resources I work on:
- [Named Regex Captures Are Assigned To Variables](ruby/named-regex-captures-are-assigned-to-variables.md)
- [Navigate Back In The Browser With Capybara](ruby/navigate-back-in-the-browser-with-capybara.md)
- [Next And Previous Floats](ruby/next-and-previous-floats.md)
- [OpenStruct Has Bad Performance Characteristics](ruby/open-struct-has-bad-performance-characteristics.md)
- [Or Operator Precedence](ruby/or-operator-precedence.md)
- [Output Bytecode For A Ruby Program](ruby/output-bytecode-for-a-ruby-program.md)
- [Override The Initial Sequence Value](ruby/override-the-initial-sequence-value.md)
@@ -1521,6 +1541,7 @@ See some of the other learning resources I work on:
- [File Type Info With File](unix/file-type-info-with-file.md)
- [Find All Files Matching A Name With fd](unix/find-all-files-matching-a-name-with-fd.md)
- [Find All Files With A Specific Extension With fd](unix/find-all-files-with-a-specific-extension-with-fd.md)
- [Find All Tool Version Files Containing Postgres](unix/find-all-tool-version-files-containing-postgres.md)
- [Find Any Dotfiles That Modify Path Env Var](unix/find-any-dotfiles-that-modify-path-env-var.md)
- [Find A File Installed By Brew](unix/find-a-file-installed-by-brew.md)
- [Find Duplicate Lines In A File](unix/find-duplicate-lines-in-a-file.md)
@@ -1528,6 +1549,8 @@ See some of the other learning resources I work on:
- [Find Newer Files](unix/find-newer-files.md)
- [Find Occurrences Of Multiple Values With Ripgrep](unix/find-occurrences-of-multiple-values-with-ripgrep.md)
- [Find Top-Level Directories Matching A Pattern](unix/find-top-level-directories-matching-a-pattern.md)
- [Fix Previous Command With fc](unix/fix-previous-command-with-fc.md)
- [Fix Shim Path After asdf Upgrade](unix/fix-shim-path-after-asdf-upgrade.md)
- [Fix Unlinked Node Binaries With asdf](unix/fix-unlinked-node-binaries-with-asdf.md)
- [Forward Multiple Ports Over SSH](unix/forward-multiple-ports-over-ssh.md)
- [Generate A SAML Key And Certificate Pair](unix/generate-a-saml-key-and-certificate-pair.md)
@@ -1567,6 +1590,7 @@ See some of the other learning resources I work on:
- [List Parent pid With ps](unix/list-parent-pid-with-ps.md)
- [List Stats For A File](unix/list-stats-for-a-file.md)
- [List The Available JDKs](unix/list-the-available-jdks.md)
- [List The PID And Name Of Current Shell Process](unix/list-the-pid-and-name-of-current-shell-process.md)
- [List The Stack Of Remembered Directories](unix/list-the-stack-of-remembered-directories.md)
- [List TXT DNS Records For A Domain](unix/list-txt-dns-records-for-a-domain.md)
- [Load Env Vars In Bash Script](unix/load-env-vars-in-bash-script.md)
@@ -1831,6 +1855,7 @@ See some of the other learning resources I work on:
- [Convert An ePub Document To PDF On Mac](workflow/convert-an-epub-document-to-pdf-on-mac.md)
- [Create A Local Sanity Dataset Backup](workflow/create-a-local-sanity-dataset-backup.md)
- [Create A Public URL For A Local Server](workflow/create-a-public-url-for-a-local-server.md)
- [Create Todo Items In Logseq](workflow/create-todo-items-in-logseq.md)
- [Enable Dev Tools For Safari](workflow/enable-dev-tools-for-safari.md)
- [Forward Stripe Events To Local Server](workflow/forward-stripe-events-to-local-server.md)
- [Get URL For GitHub User Profile Photo](workflow/get-url-for-github-user-profile-photo.md)
@@ -1879,7 +1904,9 @@ See some of the other learning resources I work on:
### Zsh
- [A Better Way To Reload ZSH Configuration](zsh/a-better-way-to-reload-zsh-configuration.md)
- [Add To The Path Via Path Array](zsh/add-to-the-path-via-path-array.md)
- [Create And Jump Into A Directory](zsh/create-and-jump-into-a-directory.md)
- [Link A Scalar To An Array](zsh/link-a-scalar-to-an-array.md)
- [Use A Space To Exclude Command From History](zsh/use-a-space-to-exclude-command-from-history.md)

View File

@@ -0,0 +1,30 @@
# AWS CLI Requires Groff Executable
I have the AWS CLI installed on this machine, but when I went to run certain
commands like `aws logs tail my_log_group` or even `aws logs tail help`, I'd
get the following error:
```
$ aws logs tail help
Could not find executable named 'groff'
```
This may only be an issue on MacOS Ventura for older versions of the CLI, per
[this PR](https://github.com/aws/aws-cli/pull/7413):
> The CLI's help commands are currently broken on macOS Ventura because Ventura has replaced groff with mandoc. This PR fixes the issue by falling back on mandoc if groff doesn't exist in the path.
There are two ways of dealing with this. One would be to install the missing
dependency, [`groff`](https://www.gnu.org/software/groff/):
```bash
$ brew install groff
```
The other is to update the AWS CLI to one that falls back to `mandoc`.
Depending on how you originally installed the AWS CLI, you can either [follow
their official install/upgrade
instructions](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html),
`pip install --upgrade awscli`, or upgrade view homebrew (`brew upgrade
awscli`).

View File

@@ -0,0 +1,46 @@
# Find And Follow Server Logs
Let's say you are authenticated with the AWS CLI and have the appropriate
CloudWatch permissions. You have a few services running in production with
associated logs. One of those is a Rails server.
We want to run `aws logs tail`, but first we check how that command works.
```bash
$ aws logs tail help
```
We see a bunch of options, but the only required one is `group_name` ("The name
of the CloudWatch Logs group."). We may also notice the `--follow` flag which
we'll want to use as well to keep incoming logs flowing.
We need to determine the log group name for the Rails server. We can do that
from the CLI as well (no need to dig into the web UI).
```bash
$ aws logs describe-log-groups
{
"logGroups": [
{
"logGroupName": "/aws/codebuild/fc-rails-app-abcefg-123456",
"creationTime": 1739476650823,
"metricFilterCount": 0,
"arn": "arn:aws:logs:us-east-2:123456789:log-group:/aws/codebuild/fc-rails-app-abcefg-123456:*",
"storedBytes": 65617,
"logGroupClass": "STANDARD",
"logGroupArn": "arn:aws:logs:us-east-2:123456789:log-group:/aws/codebuild/fc-rails-app-abcefg-123456"
},
...
]
}
```
Because the group name is descriptive enough, we can find the log group we are
interested in: `/aws/codebuild/fc-rails-app-abcefg-123456`.
Now we know what we want to `tail`.
```bash
$ aws logs tail /aws/codebuild/fc-rails-app-abcefg-123456 --follow
```

View File

@@ -0,0 +1,50 @@
# SSH Into An ECS Container
In [Connect To Production Rails Console on AWS /
Flightcontrol](https://www.visualmode.dev/connect-to-production-rails-console-aws-flightcontrol),
I went into full detail about how to access `rails console` for a production
Rails app running in an ECS container.
A big part of that process was establishing an SSH connection to the ECS container.
To do that, I need to know my region, container ID, and task ID. I can get the
first two by listing my clusters and finding the cluster/container that houses
the Rails app.
```bash
$ aws ecs list-clusters
{
"clusterArns": [
"arn:aws:ecs:us-east-2:123:cluster/rails-app-abc123"
]
}
```
The region then is `us-east-2` and the container ID is `rails-app-abc123`.
I can use that to find the task ID:
```bash
$ aws ecs list-tasks --region us-east-2 --cluster rails-app-abc123
{
"taskArns": [
"arn:aws:ecs:us-east-2:123:task/rails-app-abc123/8526b3191d103bb1ff90c65a655ad004"
]
}
```
The task ID is the final portion of the URL:
`8526b3191d103bb1ff90c65a655ad004`.
Putting this all together I can SSH into the ECS container with a bash profile
like so:
```bash
$ aws ecs execute-command \
--region us-east-2 \
--cluster rails-app-abc123 \
--container rails-app-abc123 \
--task 8526b3191d103bb1ff90c65a655ad004 \
--interactive \
--command "/bin/bash"
```

View File

@@ -0,0 +1,37 @@
# Use Specific AWS Profile With CLI
I have multiple AWS profiles authenticated with the AWS CLI. For some projects
I need to use the `default` one and for others I need to use the other.
First, I can list the available profiles like so:
```bash
$ aws configure list-profiles
default
dev-my-app
```
For one-off commands I can specify the profile for any AWS CLI command using
the `--profile` flag.
```bash
$ aws ecs list-clusters --profile josh-visualmode
```
However, I don't want to have to specify that flag every time when I'm working
on a specific project. Instead I can specify the profile with an environment
variable. The [`direnv`](https://direnv.net/) tool is a great way to do this on
a per-project / per-directory basis.
I can create or update the `.envrc` file (assuming I have `direnv` installed)
adding the following line (and re-allowing the changed file):
```
# .envrc
export AWS_PROFILE=dev-my-app
```
Now, any AWS command I issue from that directory or its subdirectories will use
that profile by default.
[source](https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html#cli-configure-files-using-profiles)

View File

@@ -0,0 +1,29 @@
# Filter Blur Requires Expensive Calculation
I had [a
page](https://www.visualmode.dev/connect-to-production-rails-console-aws-flightcontrol)
on my blog that was experiencing some odd rendering behavior. The issue was
manifesting a couple ways.
- Resizing and scrolling were janky and causing entire page layers to re-render
causing the page to flash in and out.
- Sometimes entire layer chunks would fail to paint leaving a white block
missing from the page.
The issue was occurring with and without JavaScript turned on for a
statically-built page. I suspected that some aspect of the CSS was at fault.
I was going back and forth with Dillon Hafer about what the issue could be and
he wondered, "could it be the backdrop-blur class from tailwind?". I tried
removing that class and the responsiveness of the page immediately improved.
The [`filter:
blur`](https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/blur)
and [`backdrop-filter:
blur`](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter) both
use an expensive [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur)
calculation. One of these on a modern machine and browser probably won't have a
noticable impact. However, a bunch of them, as in the case of my page with a
recurring component, can have quite the performance hit.
[source](https://github.com/tailwindlabs/tailwindcss/issues/15256)

View File

@@ -0,0 +1,53 @@
# Prevent Containers From Running On Startup
I have a bunch of docker containers managed by Docker Desktop. Some are related
to projects I'm actively working on. Whereas many others are inactive projects.
When I restart my machine, regardless of which containers I had running or
turned off, several of them are booted into a running state on startup. This is
becaue their restart policy is set to `always`. That's fine for the project I'm
actively working on, but the others I would like to be _off_ by default.
I need to update each of their restart policies from `always` to `no`.
First, I need to figure out their container IDs:
```bash
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eb7b40aeba2d postgres:latest "docker-entrypoint.s…" 3 months ago Up 11 minutes 0.0.0.0:9875->5432/tcp still-postgres-1
eb9ab2213f2b postgres:latest "docker-entrypoint.s…" 3 months ago Exited (0) 11 minutes ago next-drizzle-migration-repro-app-postgres-1
ba792e185734 postgres:latest "docker-entrypoint.s…" 4 months ago Up 11 minutes 0.0.0.0:9876->5432/tcp better_reads-postgres-1
3139f9beae76 postgres:latest "docker-entrypoint.s…" 9 months ago Exited (128) 7 months ago basic-next-prisma-postgres-1
```
Referencing the `CONTAINER ID` and `NAMES` columns, I'm able to then inspect
each container and see the current `RestartPolicy`:
```bash
$ docker inspect eb9ab2213f2b | grep -A3 RestartPolicy
"RestartPolicy": {
"Name": "always",
"MaximumRetryCount": 0
},
```
I can then update the `RestartPolicy` to be `no`:
```bash
$ docker update --restart no eb9ab2213f2b
```
Inpsecting that container again, I can see the updated policy:
```bash
$ docker inspect eb9ab2213f2b | grep -A3 RestartPolicy
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
```
Rinse and repeat for each of the offending containers.
[source](https://stackoverflow.com/questions/45423334/stopping-docker-containers-from-being-there-on-startup)

View File

@@ -0,0 +1,26 @@
# Files With Local Changes Cannot Be Removed
This is a nice quality-of-life feature in `git` that should help you avoid
accidentally discarding changes that won't be retrievable.
```bash
git rm .tool-versions
error: the following file has local modifications:
.tool-versions
(use --cached to keep the file, or -f to force removal)
```
My `.tool-versions` file has some local changes. I don't realize that and I go
to issue a `git rm` command on that file. Instead of quietly wiping out my
changes, `git` lets me know I'm doing something destructive (these local
changes won't be in the diff or the reflog).
I can force the removal if I know what I'm doing with the `-f` flag. Or I can
take the two step approach of calling `git restore` on that file and then `git
rm`.
The `--cached` flag is also interesting because it doesn't actually delete the
file from my file system, but it does stage the file deletion with `git`. That
means the file now shows up as one of my untracked files.
See `man git-rm` for more details.

View File

@@ -3,7 +3,7 @@
There are a lot of things you can do in the browser without having to reach
for the mouse. Bringing the URL bar into focus is one of those things.
Hit `Cmd+L` in any modern browser (I've tried Chrome, Firefox, and Safari)
Hit `Cmd+L` or `Alt+D` in any modern browser (I've tried Chrome, Firefox, and Safari)
and the URL bar will be brought into focus. From there, you can quickly
change the URL of the current tab and your fingers never left the keyboard.

View File

@@ -0,0 +1,29 @@
# List The Files Being Loaded By Mise
While running `mise` for the first time, after adding a `mise.toml` file to a
project, I noticed something strange. Instead of invoking the command I had
specified (`mise run dev`), several parellel tool downloads were kicked off. In
addition to Ruby, it was installing an older version of Postgres, and lua. What
gives?
By running `mise cfg`, I can list all the files being loaded by `mise` and get
to the bottom of this.
```bash
mise cfg
Path Tools
~/.tool-versions node, ruby, postgres, lua
~/code/still/.ruby-version ruby
~/code/still/Gemfile (none)
~/code/still/.tool-versions ruby
~/code/still/mise.toml (none)
```
I was only thinking about the files local to my project and I forgot that I
have a system-wide `.tool-versions` file. As we can see from the output, that
file specifies `postgres` and `lua` as well. Mise wanted to ensure that it had
downloaded the specified versions of each of those tools before running my
task.
[source](https://mise.jdx.dev/configuration.html)

View File

@@ -0,0 +1,28 @@
# Read Existing Dot Env File Into Env Vars
Just about any web app that I've worked on has had a `.env` file as a way of
configuring aspects of the app specific to that environment. These typically
are read into the environment with a language-specific
[dotenv](https://github.com/bkeepers/dotenv) tool.
Mise supports this convention. In addition to specifying individual non-secret
env vars, you can also instruct `mise` to read-in a `.env` file like so:
```toml
[env]
PORT=3344
_.file = ".env"
```
The `_.file` line tells `mise` that there is a file `.env` with key-value pairs
that it should read in. It can even handle `.env.json` and `.env.toml` file
formats.
To ensure that `mise` is picking up the values from the `.env` file, you can
run the following command and make sure they show up in the output:
```bash
$ mise env
```
[source](https://mise.jdx.dev/environments/secrets.html)

View File

@@ -0,0 +1,33 @@
# Adjust The Production Log Level
A Rails app by default takes on the `debug` log level. This is great for
development because it spits out a lot of information as you build and debug.
That's going to typically be a bit too noisy for a production environment
though. That is why Rails ships with the `config/environments/production.rb`
file configured to the `info` log level.
```ruby
# config/environments/production.rb
Rails.application.configure do
# ...
# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
# ...
end
```
Sometimes, like when we're trying to track down some buggy behavior, we may
want to switch Rails from one log level to another. That's why it is configured
by the `RAILS_LOG_LEVEL` env var and otherwise falls back to `info`.
To, for example, switch production over to the `debug` log level, we'd first
change the `RAILS_LOG_LEVEL` env var to `debug`. Then we'd need to make sure
our Rails app is restarted so that the config change is picked up. Heroku's
`heroku config:set` will do that automatically. Depending on your setup, you
may need to manually restart your web server (e.g. Puma).

View File

@@ -0,0 +1,42 @@
# Enforce Locals Passed To A Partial
I have a big form partial (`_form.html.erb`) that is rendered by several
different _new_ and _edit_ views. It's hard to tell at a glance, but the
partial requires that `blogmark` and `cancel_path` are included as locals when
it is rendered.
As of [Rails 7.1](https://github.com/rails/rails/pull/45602), we now have a
built-in way to enforce locals passed to a partial. We can add a magic comment
at the top of the partial that specifies the locals:
```ruby
<%# locals: (blogmark:, cancel_path:) -%>
<%= form_with(model: blogmark, local: true, class: "w-full max-w-3xl mb-8") do |form| %>
<% ... %>
<% end %>
```
This particular ERB magic comment declares that
[`blogmark`](https://still.visualmode.dev/blogmarks) and `cancel_path` are
required locals.
So, what happens if I have a `new.html.erb` view that looks like this:
```ruby
<h1>New Blogmark</h1>
<%= render 'blogmarks/form', blogmark: @blogmark %>
```
When I try to view the page, an error is raised:
```
Showing /Some/path/app/views/blogmarks/_form.html.erb where line # raised:
missing local: :cancel_path for app/views/blogmarks/_form.html.erb
```
Updating the `render` statement to include a `cancel_path` local fixes the
issue.
[source](https://gorails.com/episodes/template-locals-in-rails-7-1)

View File

@@ -0,0 +1,28 @@
# Restart Puma Server By Touching Restart File
Puma includes a plugin that allows us to restart the web server by touching the
`tmp/restart.txt` file.
In one terminal pane I have my Rails server running. In another terminal pane
from the Rails directory, where there exists a `tmp` folder, I run the
following command.
```bash
$ touch tmp/restart.txt
```
Then in the pane running the Rails server, I see the following after a second:
```
* Restarting...
=> Booting Puma
=> Rails 8.0.1 application starting in development
...
```
What is happening is that `touch` updates the modified time of that file, which
already exists in the `temp` directory. When the plugin notices (it checks
every 2 seconds) that the modified time is now fresher than the original
modified time when the plugin started, then it calls `launcher.restart`.
[source](https://github.com/puma/puma/blob/ca201ef69757f8830b636251b0af7a51270eb68a/lib/puma/plugin/tmp_restart.rb)

View File

@@ -0,0 +1,32 @@
# OpenStruct Has Bad Performance Characteristics
The Ruby docs for `OpenStruct` have a [_Caveats_
section](https://ruby-doc.org/3.4.1/stdlibs/ostruct/OpenStruct.html#class-OpenStruct-label-Caveats)
that warns about the poor performance characteristics of `OpenStruct` relative
to `Struct` and `Hash`.
> This should be a consideration if there is a concern about the performance of
> the objects that are created, as there is much more overhead in the setting
> of these properties compared to using a Hash or a Struct. Creating an open
> struct from a small Hash and accessing a few of the entries can be 200 times
> slower than accessing the hash directly.
This doesn't mean don't use `OpenStruct`, but do be aware of if you are using
it in a hot path or if you are allocating and processing tons of them.
If you turn on _Performance Warnings_ in Ruby, you'll see a warning message
when allocating an `OpenStruct`.
```ruby
> require 'ostruct'
=> true
> os1 = OpenStruct.new
=> #<OpenStruct>
> Warning[:performance] = true
=> true
> os2 = OpenStruct.new
(irb):6: warning: OpenStruct use is discouraged for performance reasons
=> #<OpenStruct>
```
[source](https://www.reddit.com/r/ruby/comments/1d54mwl/comment/l6jgn59/)

View File

@@ -0,0 +1,38 @@
# Find All Tool Version Files Containing Postgres
I've been using [`asdf`](https://asdf-vm.com/) for many years now which means I
have projects and directories all over my machine with `.tool-versions` files.
Many of them specify Ruby and Node versions. Some of them also include
PostgreSQL versions. I used to use `asdf` to manage Postgres versions, but no
longer do that for new or active projects.
I want to find all the places that a `.tool-versions` file declares `postgres`
as a tool. That way I can begin to clean up the left behind artifacts of
asdf-managed Postgres.
By combining [`fd`](https://github.com/sharkdp/fd) (a better `find`) and
[`rg`](https://github.com/BurntSushi/ripgrep) (a better `grep`), I'm able to
quickly track down the list of places.
```bash
$ fd --hidden .tool-versions ~/ | xargs rg postgres
/Users/jbranchaud/.local/state/nvim/undo/%Users%jbranchaud%.tool-versions: binary file matches (found "\0" byte around offset 9)
/Users/jbranchaud/code/fake-data/.tool-versions
2:postgres 13.1
/Users/jbranchaud/code/thirty_days/thirty_days_server/.tool-versions
1:postgres 13.1
/Users/jbranchaud/code/visualmode/.tool-versions
1:postgres 11.11
```
That first instance is a binary file as part of `nvim`'s undo history which I
can ignore. The other three are good results.
I tell the `fd` command to not exclude hidden files as it looks for all
occurrences of `.tool-versions` recursively from my home (`~/`) directory. I
then pipe that list of files to `xargs` which makes those filenames arguments
to the `rg postgres` command.

View File

@@ -0,0 +1,26 @@
# Fix Previous Command With fc
The `fc` command is a Bash and ZSH built-in command that allows you to interact
with the history of commands issued in the shell. The most straightforward use
case I know of for using this command is to fix or edit some aspect of the
previous run command.
When `fc` is executed with no arguments or flags, it will grab the latest entry
to the command history and load it into your default editor. For me, that is
Vim.
I can make edits in that Vim session like I'd do in any other Vim session. When
I write and quit (`:wq`) the file, the updated command will be executed. This
is useful if, say, I've made a typo in the previous command and would prefer
the ergonomics of my default editor to fix it. Or let's say I have a really
long command with many flags and long file path arguments. It would be much
easier and quicker to edit those paths from my editor than from the terminal
prompt.
If I've opened my editor (Vim) with `fc` and I decide I don't want to execute
the command after all, I can _compiler quit_ Vim (exit with an error code)
using `:cq`. The command will not be executed in this case.
See `man zshbuiltins` for more details about this command and all of its flags.
[source](https://www.computerhope.com/unix/uhistory.htm)

View File

@@ -0,0 +1,34 @@
# Fix Shim Path After asdf Upgrade
While doing [`brew install groff`](aws/aws-cli-requires-groff-executable.md),
Homebrew decided to upgrade every last thing it knows about on my machine,
including `asdf`.
`asdf` has undergone some big recent changes, including [a rewrite in
Go](https://stratus3d.com/blog/2025/02/03/asdf-has-been-rewritten-in-go/).
I noticed that `asdf` wasn't picking up my specified tool versions. I tried an
`asdf reshim`, but that didn't do the trick. Someone else wrote that [asdf
seems broken after homebrew
upgrade](https://braytonium.com/2023/01/09/asdf-seems-broken-after-homebrew-upgrade/)
which gave some hints and pointed me to some interesting GitHub issues.
Additionally, I noticed when opening a fresh terminal session the following error from `zsh`:
```bash
/Users/jbranchaud/.zshrc:.:225: no such file or directory: /usr/local/opt/asdf/libexec/asdf.sh
```
That directory and file is gone. So, how does `asdf` now want you to configure
its path with `zsh`? Revisiting their updated docs, I can see that the instead
of sourcing that shell script, we should now export shims to the path:
```bash
# . /usr/local/opt/asdf/libexec/asdf.sh
export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
```
Updating my `.zshrc` to the above and then reloading did the trick. My tool
versions are registering now.
[source](https://asdf-vm.com/guide/getting-started.html#_2-configure-asdf)

View File

@@ -0,0 +1,27 @@
# List PID And Name Of Current Shell Process
In Julia Evans' [How to add a directory to your
PATH](https://jvns.ca/blog/2025/02/13/how-to-add-a-directory-to-your-path/),
she shows off an odd-looking command for determining what shell (e.g. bash or
zsh) you are currently running.
```bash
$ ps -p $$ -o pid=,comm=
38105 -zsh
```
I already know I'm running `zsh`, but I thought this command was interesting
enough to dig into and break down.
- The `ps` command lists processes that "have controlling terminals"
- The `$$` is a special shell variable representing the PID of the current process (try `echo $$`)
- The `-p` flag allows you to specify a PID for `ps` to grab, in this case, the `$$` PID
- The `-o` flag allows us to specify the output format, such as the PID and command name
- The `=` after `pid` and `comm` tell `ps` to exclude headers from the output
Additionally, I noticed that it output `-zsh` (not just `zsh`). That leading
hyphen seems to indicate that [this `zsh` process is a _login
shell_](https://unix.stackexchange.com/a/46856/5916). That means it was the
process used to initiate an interactive shell session and something like the
`.zprofile` would have been sourced as part of that.

View File

@@ -0,0 +1,32 @@
# Create Todo Items In Logseq
Having used GitHub flavored markdown and tools like Roam Research and Obsidian,
I'm used to being able to add interactive todo items to a document with square
brackets, like so:
```
- [ ] Do this
- [ ] Do that
```
This exact syntax doesn't work in Logseq, but I've figured out two ways of
adding todo items.
First, you can access the todo syntax with a forward slash command. Type `/`
and then start typing `TODO`. It will show up as a top result. Hit enter and
you'll have a fresh todo item that you can add a description to.
Second, as the above hints at, we can get right to the todo syntax by typing
one of `TODO`, `NOW`, or `LATER` in all caps followed by a description. For
example:
```
TODO Send out invoices
NOW Reply to those emails
LATER Schedule that meeting
```
These will render as checkable boxes marked as either `TODO`, `NOW`, or
`LATER`, until they are checked off.
You can also search for blocks that match one of these three categories.

View File

@@ -0,0 +1,35 @@
# A Better Way To Reload ZSH Configuration
I have an alias in my `~/.zshrc` that I set up to make it easy to "reload" my
ZSH configuration. This is handy if I'm iterating on some changes to my
`~/.zshrc` file and need verify them as I go.
```bash
alias reload='source ~/.zshrc'
```
With this alias, I can call `reload` from the terminal and the latest version
of my configuration (according to the `~/.zshrc` file) will be loaded for that
shell instance.
This has some downsides. It doesn't account for the other kinds of files that
contribute to your shell configuration (e.g. `~/.zprofile`) and it can lead to
duplicate values in your `PATH` and init scripts being run an additional time.
A better way is to use:
```bash
$ omz reload
```
This is [a wrapper call around `exec
zsh`](https://github.com/ohmyzsh/ohmyzsh/blob/master/lib/cli.zsh#L669-L677),
which restarts the `zsh` process. It also clears the completion cache.
I've since updated my `~/.zshrc` alias for `reload`:
```bash
alias reload='omz reload'
```
[source](https://batsov.com/articles/2022/09/15/reload-zsh-configuration/)

View File

@@ -0,0 +1,64 @@
# Create And Jump Into A Directory
[Oh My Zsh](https://github.com/ohmyzsh/ohmyzsh) defines a function `take` that
we can use to both create and `cd` into a directory. If the directory already
exists, it will simply `cd` into that directory.
```bash
~/code
take take-demo
~/code/take-demo
mkdir already-exists
~/code/take-demo
take already-exists
~/code/take-demo/already-exists
cd ..
~/code/take-demo
take one/two/three
~/code/take-demo/one/two/three
```
First `take` creates and `cd`s into `take-demo`. Then `take` only `cd`s into
`already-exists`. Then we see that `take` can create multiple levels of nested
directories.
With the help of `which` we can see how `take` is defined:
```bash
$ which take
take () {
if [[ $1 =~ ^(https?|ftp).*\.tar\.(gz|bz2|xz)$ ]]
then
takeurl "$1"
elif [[ $1 =~ ^([A-Za-z0-9]\+@|https?|git|ssh|ftps?|rsync).*\.git/?$ ]]
then
takegit "$1"
else
takedir "$@"
fi
}
```
We're not dealing with compressed files or git URLs, so we fall through to the
`else` block with invokes `takedir`.
```bash
$ which takedir
takedir () {
mkdir -p $@ && cd ${@:$#}
}
```
The `mkdir -p $@` is what allows it make new, nested directories and then we
`cd` to it. The `${@:$#}` is a way of [grabbing the last argument to the
function](https://stackoverflow.com/a/37601842/535590). This suggests that you
can pass multiple things to `take`, it will create all of them, and then `cd`
you into the last one.
[source](https://github.com/ohmyzsh/ohmyzsh/blob/master/lib/functions.zsh#L75-L85)