mirror of
https://github.com/jbranchaud/til
synced 2026-01-07 09:08:01 +00:00
Compare commits
27 Commits
6d33ed92a5
...
6b97538287
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b97538287 | ||
|
|
c8445c45a9 | ||
|
|
497b0ff3b7 | ||
|
|
64df6d16d7 | ||
|
|
7dac057246 | ||
|
|
8961c67026 | ||
|
|
4ff24a7336 | ||
|
|
2916fbc3b5 | ||
|
|
e3fc10edd8 | ||
|
|
4fe0817b2d | ||
|
|
fc74264040 | ||
|
|
2b38e1caf8 | ||
|
|
db6d18f086 | ||
|
|
84548b7a7f | ||
|
|
f9b966a0f1 | ||
|
|
871d555e95 | ||
|
|
cea3bc05b5 | ||
|
|
ee31f5b70d | ||
|
|
5b6a88b327 | ||
|
|
49ebb8dd78 | ||
|
|
6ff8f19d08 | ||
|
|
14e6635383 | ||
|
|
0a0a509827 | ||
|
|
bb331577ca | ||
|
|
0e0dcbf2b4 | ||
|
|
5615da920f | ||
|
|
c60c63f554 |
46
README.md
46
README.md
@@ -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).
|
||||
|
||||
_1590 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)
|
||||
@@ -195,7 +204,7 @@ See some of the other learning resources I work on:
|
||||
- [Aliasing An Ansible Host](devops/aliasing-an-ansible-host.md)
|
||||
- [Allow Cross-Origin Requests To Include Cookies](devops/allow-cross-origin-requests-to-include-cookies.md)
|
||||
- [Allow HTTPS Through Your UFW Firewall](devops/allow-https-through-your-ufw-firewall.md)
|
||||
- [Check For Cached Site Assocation File For iOS](devops/check-for-cached-site-association-file-for-ios.md)
|
||||
- [Check For Cached Site Association File For iOS](devops/check-for-cached-site-association-file-for-ios.md)
|
||||
- [Check The Status of All Services](devops/check-the-status-of-all-services.md)
|
||||
- [Check The Syntax Of nginx Files](devops/check-the-syntax-of-nginx-files.md)
|
||||
- [Connect To An RDS PostgreSQL Database](devops/connect-to-an-rds-postgresql-database.md)
|
||||
@@ -318,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)
|
||||
@@ -678,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)
|
||||
@@ -771,7 +786,7 @@ See some of the other learning resources I work on:
|
||||
- [Check If Clusters Are Upgrade Compatible](postgres/check-if-clusters-are-upgrade-compatible.md)
|
||||
- [Check If The Local Server Is Running](postgres/check-if-the-local-server-is-running.md)
|
||||
- [Check If User Role Exists For Database](postgres/check-if-user-role-exists-for-database.md)
|
||||
- [Check Table For Any Oprhaned Records](postgres/check-table-for-any-orphaned-records.md)
|
||||
- [Check Table For Any Orphaned Records](postgres/check-table-for-any-orphaned-records.md)
|
||||
- [Checking Inequality](postgres/checking-inequality.md)
|
||||
- [Checking The Type Of A Value](postgres/checking-the-type-of-a-value.md)
|
||||
- [Clear The Screen In psql](postgres/clear-the-screen-in-psql.md)
|
||||
@@ -948,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)
|
||||
@@ -956,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)
|
||||
@@ -1000,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)
|
||||
@@ -1064,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)
|
||||
@@ -1317,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)
|
||||
@@ -1522,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)
|
||||
@@ -1529,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)
|
||||
@@ -1568,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)
|
||||
@@ -1832,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)
|
||||
@@ -1880,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)
|
||||
|
||||
|
||||
30
aws/aws-cli-requires-groff-executable.md
Normal file
30
aws/aws-cli-requires-groff-executable.md
Normal 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`).
|
||||
46
aws/find-and-follow-server-logs.md
Normal file
46
aws/find-and-follow-server-logs.md
Normal 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
|
||||
```
|
||||
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)
|
||||
26
git/files-with-local-changes-cannot-be-removed.md
Normal file
26
git/files-with-local-changes-cannot-be-removed.md
Normal 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.
|
||||
29
mise/list-the-files-being-loaded-by-mise.md
Normal file
29
mise/list-the-files-being-loaded-by-mise.md
Normal 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)
|
||||
28
mise/read-existing-dot-env-file-into-env-vars.md
Normal file
28
mise/read-existing-dot-env-file-into-env-vars.md
Normal 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)
|
||||
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)
|
||||
28
rails/restart-puma-server-by-touching-restart-file.md
Normal file
28
rails/restart-puma-server-by-touching-restart-file.md
Normal 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)
|
||||
32
ruby/open-struct-has-bad-performance-characteristics.md
Normal file
32
ruby/open-struct-has-bad-performance-characteristics.md
Normal 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/)
|
||||
38
unix/find-all-tool-version-files-containing-postgres.md
Normal file
38
unix/find-all-tool-version-files-containing-postgres.md
Normal 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.
|
||||
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)
|
||||
34
unix/fix-shim-path-after-asdf-upgrade.md
Normal file
34
unix/fix-shim-path-after-asdf-upgrade.md
Normal 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)
|
||||
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.
|
||||
32
workflow/create-todo-items-in-logseq.md
Normal file
32
workflow/create-todo-items-in-logseq.md
Normal 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.
|
||||
35
zsh/a-better-way-to-reload-zsh-configuration.md
Normal file
35
zsh/a-better-way-to-reload-zsh-configuration.md
Normal 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/)
|
||||
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