mirror of
https://github.com/jbranchaud/til
synced 2026-01-09 10:08:01 +00:00
Compare commits
12 Commits
68f2f76fa0
...
1e6676c7ea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e6676c7ea | ||
|
|
2916fbc3b5 | ||
|
|
e3fc10edd8 | ||
|
|
4fe0817b2d | ||
|
|
fc74264040 | ||
|
|
2b38e1caf8 | ||
|
|
db6d18f086 | ||
|
|
84548b7a7f | ||
|
|
f9b966a0f1 | ||
|
|
871d555e95 | ||
|
|
cea3bc05b5 | ||
|
|
295fe153ad |
17
README.md
17
README.md
@@ -10,12 +10,15 @@ pairing with smart people at Hashrocket.
|
||||
|
||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||
|
||||
_1595 TILs and counting..._
|
||||
_1603 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
|
||||
@@ -111,6 +114,8 @@ See some of the other learning resources I work on:
|
||||
- [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
|
||||
|
||||
@@ -178,6 +183,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)
|
||||
@@ -950,6 +956,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)
|
||||
@@ -958,8 +966,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)
|
||||
@@ -1002,6 +1009,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)
|
||||
@@ -1532,6 +1540,7 @@ 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)
|
||||
@@ -1572,6 +1581,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)
|
||||
@@ -1886,6 +1896,7 @@ See some of the other learning resources I work on:
|
||||
|
||||
- [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)
|
||||
|
||||
|
||||
50
aws/ssh-into-an-ecs-container.md
Normal file
50
aws/ssh-into-an-ecs-container.md
Normal 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"
|
||||
```
|
||||
37
aws/use-specific-aws-profile-with-cli.md
Normal file
37
aws/use-specific-aws-profile-with-cli.md
Normal 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)
|
||||
29
css/filter-blur-requires-expensive-calculation.md
Normal file
29
css/filter-blur-requires-expensive-calculation.md
Normal 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)
|
||||
@@ -5,6 +5,8 @@ an array-like object with all of the arguments to the function. Even if not
|
||||
all of the arguments are referenced in the function signature, they can
|
||||
still be accessed via the `arguments` object.
|
||||
|
||||
> For ES6+ compatibility, the `spread` operator used via [rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters) is preferred over the `arugments` object when accessing an abritrary number of function arguments.
|
||||
|
||||
```javascript
|
||||
function argTest(one) {
|
||||
console.log(one);
|
||||
|
||||
33
rails/adjust-the-production-log-level.md
Normal file
33
rails/adjust-the-production-log-level.md
Normal 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).
|
||||
42
rails/enforce-locals-passed-to-a-partial.md
Normal file
42
rails/enforce-locals-passed-to-a-partial.md
Normal 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)
|
||||
26
unix/fix-previous-command-with-fc.md
Normal file
26
unix/fix-previous-command-with-fc.md
Normal 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)
|
||||
27
unix/list-the-pid-and-name-of-current-shell-process.md
Normal file
27
unix/list-the-pid-and-name-of-current-shell-process.md
Normal 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.
|
||||
64
zsh/create-and-jump-into-a-directory.md
Normal file
64
zsh/create-and-jump-into-a-directory.md
Normal 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)
|
||||
Reference in New Issue
Block a user