1
0
mirror of https://github.com/jbranchaud/til synced 2026-01-16 21:48:02 +00:00

Compare commits

...

18 Commits

Author SHA1 Message Date
Karim Bouchez
ed9c31c259 Merge 15337dfd71 into 42854fdc38 2024-04-24 09:36:50 +09:00
jbranchaud
42854fdc38 Add Create A Cluster In A Specific Data Directory as a Postgres TIL 2024-04-23 18:04:45 -05:00
jbranchaud
eff2c548cd Add List All Services Managed By Brew as a Brew TIL 2024-04-23 15:41:01 -05:00
jbranchaud
1b229b39f1 Add Use The llm CLI With Claude Models as an LLM TIL 2024-04-22 20:54:58 -05:00
jbranchaud
2543651ec0 Add Use pipx To Install End User Apps as a Python TIL 2024-04-22 19:47:09 -05:00
jbranchaud
f3d7cf8a06 Add Access 1Password Credential From CLI as a Workflow TIL 2024-04-21 19:57:10 -05:00
jbranchaud
72089e11db Add Send cURL To Claude Text Completion API as an LLM TIL 2024-04-21 19:06:13 -05:00
jbranchaud
b766f20012 Add Define Multiline Strings With Heredocs as a Ruby TIL 2024-04-21 13:46:04 -05:00
jbranchaud
505220d9de Add Convert Seconds To Date Object as a JavaScript TIL 2024-04-19 14:38:40 -05:00
jbranchaud
9684c6a6db Add Get Formatted UTC Offset Value as a Rails TIL 2024-04-18 14:32:46 -05:00
jbranchaud
3b0d76e805 Add Get UTC Offset For Different Time Zones as a Ruby TIL 2024-04-18 10:49:29 -05:00
jbranchaud
b6c8192a04 Add Make Elements Non-Interactive With Inert as an HTML TIL 2024-04-12 11:54:52 -06:00
jbranchaud
c2f30615c3 Add Print DateTime Represented By Unix Timestamp as a Unix TIL 2024-04-08 09:24:09 -05:00
jbranchaud
f54eab20e7 Add Unrestrict Where ripgrep Searches as a Unix TIL 2024-04-04 13:24:51 -05:00
jbranchaud
b2ddce62fd Add Audit Your Ruby Project For Any CVEs as a Ruby TIL 2024-04-02 11:08:37 -05:00
jbranchaud
63a57c6bdd Add Turn Off Display Of Tabs For Files as a VS Code TIL 2024-03-28 20:01:32 -05:00
jbranchaud
87d116a4cd Add List Files In A Single Column as a Unix TIL 2024-03-27 17:21:54 -05:00
Karim Bouchez
15337dfd71 Update the old way to capture a GitHub Actions output
See [here](https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/) for more explanations:
> We are monitoring telemetry for the usage of these commands and plan to fully disable them on 31st May 2023. Starting 1st June 2023 workflows using save-state or set-output commands via stdout will fail with an error.
2023-02-12 10:36:45 +01:00
18 changed files with 553 additions and 4 deletions

View File

@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
_1402 TILs and counting..._
_1418 TILs and counting..._
---
@@ -41,6 +41,7 @@ _1402 TILs and counting..._
* [jq](#jq)
* [Kitty](#kitty)
* [Linux](#linux)
* [LLM](#llm)
* [Mac](#mac)
* [MongoDB](#mongodb)
* [MySQL](#mysql)
@@ -98,6 +99,7 @@ _1402 TILs and counting..._
### Brew
- [Configure Brew Environment Variables](brew/configure-brew-environment-variables.md)
- [List All Services Managed By Brew](brew/list-all-services-managed-by-brew.md)
### Chrome
@@ -397,6 +399,7 @@ _1402 TILs and counting..._
- [Adding Alt Text To An Image](html/adding-alt-text-to-an-image.md)
- [Determine Which Button Submitted The Form](html/determine-which-button-submitted-the-form.md)
- [Disable Auto-Completion For A Form Input](html/disable-auto-completion-for-a-form-input.md)
- [Make Elements Non-Interactive With Inert](html/make-elements-non-interactive-with-inert.md)
- [Prevent Search Engines From Indexing A Page](html/prevent-search-engines-from-indexing-a-page.md)
- [Render Text As Superscript](html/render-text-as-superscript.md)
- [Submit A Form With A Button Outside The Form](html/submit-a-form-with-a-button-outside-the-form.md)
@@ -436,6 +439,7 @@ _1402 TILs and counting..._
- [Computed Property Names In ES6](javascript/computed-property-names-in-es6.md)
- [Conditionally Include Pairs In An Object](javascript/conditionally-include-pairs-in-an-object.md)
- [Configure Jest To Run A Test Setup File](javascript/configure-jest-to-run-a-test-setup-file.md)
- [Convert Seconds To Date Object](javascript/convert-seconds-to-date-object.md)
- [Create A Cancelable Promise With PCancelable](javascript/create-a-cancelable-promise-with-pcancelable.md)
- [Create An Array Containing 1 To N](javascript/create-an-array-containing-1-to-n.md)
- [Create An Object With No Properties](javascript/create-an-object-with-no-properties.md)
@@ -552,6 +556,11 @@ _1402 TILs and counting..._
- [Show Used And Available System Memory](linux/show-used-and-available-system-memory.md)
- [Upgrading Ubuntu](linux/upgrading-ubuntu.md)
### LLM
- [Send cURL To Claude Text Completion API](llm/send-curl-to-claude-text-completion-api.md)
- [Use The llm CLI With Claude Models](llm/use-the-llm-cli-with-claude-models.md)
### Mac
- [Access All Screen And Video Capture Options](mac/access-all-screen-and-video-capture-options.md)
@@ -679,6 +688,7 @@ _1402 TILs and counting..._
- [Count How Many Records There Are Of Each Type](postgres/count-how-many-records-there-are-of-each-type.md)
- [Count Records By Type](postgres/count-records-by-type.md)
- [Count The Number Of Trues In An Aggregate Query](postgres/count-the-number-of-trues-in-an-aggregate-query.md)
- [Create A Cluster In A Specific Data Directory](postgres/create-a-cluster-in-a-specific-data-directory.md)
- [Create A Composite Primary Key](postgres/create-a-composite-primary-key.md)
- [Create A Table From The Structure Of Another](postgres/create-a-table-from-the-structure-of-another.md)
- [Create An Index Across Two Columns](postgres/create-an-index-across-two-columns.md)
@@ -818,6 +828,7 @@ _1402 TILs and counting..._
- [Access Instance Variables](python/access-instance-variables.md)
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
- [Test A Function With Pytest](python/test-a-function-with-pytest.md)
- [Use pipx To Install End User Apps](python/use-pipx-to-install-end-user-apps.md)
### Rails
@@ -878,6 +889,7 @@ _1402 TILs and counting..._
- [Get ActiveRecord Attribute Directly From Database](rails/get-active-record-attribute-directly-from-database.md)
- [Get An Array Of Values From The Database](rails/get-an-array-of-values-from-the-database.md)
- [Get An Empty ActiveRecord Relation](rails/get-an-empty-activerecord-relation.md)
- [Get Formatted UTC Offset Value](rails/get-formatted-utc-offset-value.md)
- [Get Help With A Rails App Update](rails/get-help-with-a-rails-app-update.md)
- [Get The Column Names For A Model](rails/get-the-column-names-for-a-model.md)
- [Get The Current Time](rails/get-the-current-time.md)
@@ -1089,6 +1101,7 @@ _1402 TILs and counting..._
- [Add Progress Reporting To Long-Running Script](ruby/add-progress-reporting-to-long-running-script.md)
- [Are They All True?](ruby/are-they-all-true.md)
- [Assert About An Object's Attributes With RSpec](ruby/assert-about-an-objects-attributes-with-rspec.md)
- [Audit Your Ruby Project For Any CVEs](ruby/audit-your-ruby-project-for-any-cves.md)
- [Assoc For Hashes](ruby/assoc-for-hashes.md)
- [Block Comments](ruby/block-comments.md)
- [Build HTTP And HTTPS URLs](ruby/build-http-and-https-urls.md)
@@ -1112,6 +1125,7 @@ _1402 TILs and counting..._
- [Defaulting To Frozen String Literals](ruby/defaulting-to-frozen-string-literals.md)
- [Define A Custom RSpec Matcher](ruby/define-a-custom-rspec-matcher.md)
- [Define A Method On A Struct](ruby/define-a-method-on-a-struct.md)
- [Define Multiline Strings With Heredocs](ruby/define-multiline-strings-with-heredocs.md)
- [Destructure The First Item From An Array](ruby/destructure-the-first-item-from-an-array.md)
- [Destructuring Arrays In Blocks](ruby/destructuring-arrays-in-blocks.md)
- [Disassemble Some Codes](ruby/disassemble-some-codes.md)
@@ -1135,6 +1149,7 @@ _1402 TILs and counting..._
- [Generate Ruby Version And Gemset Files With RVM](ruby/generate-ruby-version-and-gemset-files-with-rvm.md)
- [Get Info About Your RubyGems Environment](ruby/get-info-about-your-ruby-gems-environment.md)
- [Get The Output Of Running A System Program](ruby/get-the-output-of-running-a-system-program.md)
- [Get UTC Offset For Different Time Zones](ruby/get-utc-offset-for-different-time-zones.md)
- [Identify Outdated Gems](ruby/identify-outdated-gems.md)
- [If You Detect None](ruby/if-you-detect-none.md)
- [Iterate With An Offset Index](ruby/iterate-with-an-offset-index.md)
@@ -1377,6 +1392,7 @@ _1402 TILs and counting..._
- [Less With Style](unix/less-with-style.md)
- [List All The Enabled ZSH Options](unix/list-all-the-enabled-zsh-options.md)
- [List All Users](unix/list-all-users.md)
- [List Files In A Single Column](unix/list-files-in-a-single-column.md)
- [List Files Ordered By Modification Date](unix/list-files-ordered-by-modification-date.md)
- [List Names Of Files With Matches](unix/list-names-of-files-with-matches.md)
- [List Of Sessions To A Machine](unix/list-of-sessions-to-a-machine.md)
@@ -1395,6 +1411,7 @@ _1402 TILs and counting..._
- [Partial String Matching In Bash Scripts](unix/partial-string-matching-in-bash-scripts.md)
- [PID Of The Current Shell](unix/pid-of-the-current-shell.md)
- [Print A Range Of Lines For A File With Bat](unix/print-a-range-of-lines-for-a-file-with-bat.md)
- [Print DateTime Represented By Unix Timestamp](unix/print-datetime-represented-by-unix-timestamp.md)
- [Print Milliseconds In Human-Readable Format](unix/print-milliseconds-in-human-readable-format.md)
- [Print Out Files In Reverse](unix/print-out-files-in-reverse.md)
- [Print The Current Date In Human-Readable Format](unix/print-the-current-date-in-human-readable-format.md)
@@ -1425,6 +1442,7 @@ _1402 TILs and counting..._
- [Tell direnv To Load The Env File](unix/tell-direnv-to-load-the-env-file.md)
- [Touch Access And Modify Times Individually](unix/touch-access-and-modify-times-individually.md)
- [Undo Some Command Line Editing](unix/undo-some-command-line-editing.md)
- [Unrestrict Where ripgrep Searches](unix/unrestrict-where-ripgrep-searches.md)
- [Update Package Versions Known By asdf Plugin](unix/update-package-versions-known-by-asdf-plugin.md)
- [Use fzf To Change Directories](unix/use-fzf-to-change-directories.md)
- [Use Regex Pattern Matching With Grep](unix/use-regex-pattern-matching-with-grep.md)
@@ -1611,6 +1629,7 @@ _1402 TILs and counting..._
- [Pop Open The Quick Fix Window](vscode/pop-open-the-quick-fix-window.md)
- [Step Through Project-Wide Search Results](vscode/step-through-project-wide-search-results.md)
- [Toggle Between Terminals](vscode/toggle-between-terminals.md)
- [Turn Off Display Of Tabs For Files](vscode/turn-off-display-of-tabs-for-files.md)
### Webpack
@@ -1623,6 +1642,7 @@ _1402 TILs and counting..._
### Workflow
- [Add Subtitles To Existing Mux Video Asset](workflow/add-subtitles-to-existing-mux-video-asset.md)
- [Access 1Password Credential From CLI](workflow/access-1password-credential-from-cli.md)
- [Change Window Name In iTerm](workflow/change-window-name-in-iterm.md)
- [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)

View File

@@ -0,0 +1,28 @@
# List All Services Managed By Brew
Daemonized services, such as PostgreSQL, can be installed and managed with
Homebrew. Under the hood `brew` uses `launchctl` on Mac to manage these
services — i.e. starting, restarting, and stopping them.
Assuming you've already installed some services, you can run `brew services
list` to see what services there are and what their current status is.
```bash
$ brew services list
Name Status User File
mailhog none
mysql none
postgresql@11 started jbranchaud ~/Library/LaunchAgents/homebrew.mxcl.postgresql@11.plist
postgresql@13 none
postgresql@16 none
unbound none
```
This is the default behavior if you just run `brew services` without a subcommand.
This is helpful if you are, for instance, trying to see which PostgreSQL server
version you are currently running and which other ones are available to run. I
might then issue a `stop` to `postgresql@11` so that I can then `start` the
`postgresql@16` service.
See `brew services --help` for more details.

View File

@@ -23,11 +23,11 @@ version from my `.tool-versions` file with a step that uses `set-output`.
- name: Read Node.js version to install from `.tool-versions`
id: nodejs
run: >-
echo "::set-output name=NODE_VERSION::$(
echo "NODE_VERSION=$(
cat .tool-versions |
grep nodejs |
sed 's/nodejs \(.*\)$/\1/'
)"
)" >> $GITHUB_OUTPUT
```
`echo` runs the command in the string which sets `NODE_VERSION` as an output
@@ -45,4 +45,4 @@ This output value can be referenced in a later step.
`steps` has a reference to the `nodejs` step (note the `id` above) which then
has `outputs` like the `NODE_VERSION`.
[source](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#using-workflow-commands-to-access-toolkit-functions)
[source](https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter)

View File

@@ -0,0 +1,25 @@
# Make Elements Non-Interactive With Inert
The [`inert`
attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert)
global attribute is a boolean that can be applied to an element or section of
content in an HTML document. When it is `true`, that elements and anything
nested within it will not be interactive.
```html
<div class="fancy-animation" inert>
<!-- ... -->
</div>
```
This has a couple different implications:
1. Click events are not fired on these elements.
2. These elements will not be able to gain focus.
3. These elements and content are hidden from assistive technology.
This is useful for a variety of things. In particular, it is good for
accessibility when a portion of the document, like a fancy animation, isn't
meant to be traversed by assistive technology.

View File

@@ -0,0 +1,32 @@
# Convert Seconds To Date Object
Let's say you have an integer that represents the number of seconds since the
unix epoch. This is a reasonably common way for systems to represent a date.
For example, `1713350171` is an _Expiration Date_ I just got from an API.
But how do we know what date that actually represents and how can we get a
JavaScript `Date` object from that value?
The `new Date()` constructor can produce a date object given an integer. That
integer is not supposed to be seconds since the unix epoch though. See what we
get here:
```javascript
> new Date(1713350171)
1970-01-20T19:55:50.171Z
```
Something is off. The integer that you pass to `new Date()` needs to be the
_number of milliseconds_ since the unix epoch. We can get there by multiplying
our _seconds_ value by `1000`.
```javascript
> new Date(1713350171 * 1000)
2024-04-17T10:36:11.000Z
```
Not only can we, as humans, read that date, but we have a `Date` object that we
can use within our program.
Note: if you execute `Date.now()`, the value you get is in milliseconds.

View File

@@ -0,0 +1,40 @@
# Send cURL To Claude Text Completion API
Here is how we can make a `cURL` (`POST`) request to the Claude text completion
API. It requires already having a Claude API account with (paid) credits. At
this time, you can get $5 in free credits to try it out.
Assuming all that, we can grab an API key, store it somewhere safe and
accessible like 1Password, and then start formatting a request.
We need to specify a couple headers as well as `POST` body parameters.
```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "x-api-key: $(op item get "Anthropic Claude API Key" --field credential)" \
-H "anthropic-version: 2023-06-01" \
-d \
'{
"model": "claude-2.1",
"max_tokens_to_sample": 1024,
"prompt": "Human: Show me an example of a simple Ruby program.\n\nAssistant:"
}' \
https://api.anthropic.com/v1/complete
```
The required headers are:
- `"Content-Type: application/json"`
- `x-api-key` with our API key
- `"anthropic-version: 2023-06-01"` (the latest Anthropic API version)
Then, in the body, we specify:
- the `model` (e.g. `claude-2.1`)
- the max number of tokens you want the model to use
- a prompt that starts with `Human:` and then prompts the `Assistant:`
Note: this is a legacy API and the [Messages
API](https://docs.anthropic.com/claude/reference/messages_post) should be
preferred.
[source](https://docs.anthropic.com/claude/reference/complete_post)

View File

@@ -0,0 +1,26 @@
# Use The llm CLI With Claude Models
[Simon Willison's `llm`](https://llm.datasette.io/en/stable/index.html) can be
used with a bunch of different models (local and API). The whole thing is
plugin driven. To use a specific model, you'll need to install the plugin for
it. For instance, to use the [Claude 3 family of
models](https://www.anthropic.com/news/claude-3-family) you need to install
`llm-claude-3`.
```bash
$ llm install llm-claude-3
```
Then when prompting `llm`, specify which of the Claude models you want to use —
`claude-3-haiku`, `claude-3-sonnet`, or `claude-3-opus` — with the `-m` flag:
```bash
$ llm \
-m claude-3-haiku \
--key $CLAUDE_API_KEY \
'Show me the SQL query to create a cocktails table.'
```
Note: instead of adding my Claude API key to the key store, I've opted to
include it with the `--key` flag via an environment variable that I've set
ahead of time.

View File

@@ -0,0 +1,46 @@
# Create A Cluster In A Specific Data Directory
Let's say I want to create a PostgreSQL cluster near my app. So, I create a
`postgres/data` directory next to my app. Then I run the `initdb` command
pointing at that directory and specifying the UTF-8 locale.
Here is what that looks like:
```bash
$ /usr/local/opt/postgresql@13/bin/initdb -D postgres/data --locale=en_US.UTF-8
The files belonging to this database system will be owned by user "jbranchaud".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory postgres/data ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... America/Chicago
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
Success. You can now start the database server using:
'/usr/local/opt/postgresql@13/bin/pg_ctl' -D postgres/data -l logfile start
```
As stated at the end of the command's output, I can run the `postgres` server
with that data directory with:
```bash
$ '/usr/local/opt/postgresql@13/bin/pg_ctl' -D postgres/data -l logfile start
```

View File

@@ -0,0 +1,31 @@
# Use pipx To Install End User Apps
The [`pipx`](https://pipx.pypa.io/stable/) tool is an installer for the python
ecosystem. It differs from `pip` in that it is for installing end-user
applications and it does so in isolated environments.
You can install `pipx` with an OS-specific installer like Homebrew:
```bash
$ brew install pipx
```
Ensure `pipx`-installed apps are on your path:
```bash
$ pipx ensurepath
```
Then use `pipx` to install programs like
[`cowsay`](https://pypi.org/project/cowsay/) or
[`llm`](https://llm.datasette.io/en/stable/setup.html):
```bash
$ pipx install llm
$ which llm
/Users/jbranchaud/.local/bin/llm
$ llm --version
llm, version 0.13.1
```

View File

@@ -0,0 +1,37 @@
# Get Formatted UTC Offset Value
The UTC offset (during DST) for Chicago is `-05:00`. And for Newfoundland it is
`-02:30`.
Rails has an [`ActiveSupport::TimeZone`
module](https://api.rubyonrails.org/v7.1.3.2/classes/ActiveSupport/TimeZone.html#method-c-seconds_to_utc_offset)
that can turn the UTC offset in seconds into this formatted value.
```ruby
> chicago = TZInfo::Timezone.get('America/Chicago')
=> #<TZInfo::DataTimezone: America/Chicago>
> ActiveSupport::TimeZone.seconds_to_utc_offset(chicago.utc_offset)
=> "-05:00"
> newfoundland = TZInfo::Timezone.get('America/St_Johns')
=> #<TZInfo::DataTimezone: America/St_Johns>
> ActiveSupport::TimeZone.seconds_to_utc_offset(newfoundland.utc_offset)
=> "-02:30"
```
The underlying `tzinfo` gem is DST-aware and its database even knows which time
zone identifiers don't observe DST, so you can run this anytime of the year and
expect reliable results.
Here is another way at this:
```ruby
> chicago = TZInfo::Timezone.get('America/Chicago')
=> #<TZInfo::DataTimezone: America/Chicago>
> ActiveSupport::TimeZone[chicago.name]
=> #<ActiveSupport::TimeZone:0x00000001099d8140 @name="America/Chicago", @tzinfo=#<TZInfo::DataTimezone: America/Chicago>, @utc_offset=nil>
> ActiveSupport::TimeZone[chicago.name].formatted_offset
=> "-06:00"
> ActiveSupport::TimeZone[chicago.name].formatted_offset(false)
=> "-0600"
```

View File

@@ -0,0 +1,45 @@
# Audit Your Ruby Project For Any CVEs
The [`bundler-audit` gem](https://github.com/rubysec/bundler-audit) is a handy
tool that you can run manually or integrate into your CI workflow to warn you
about any CVEs in your dependencies.
Running this tool without any arguments will perform a check of your
`Gemfile.lock` file. It will check against the
[`ruby-advisory-db`](https://github.com/rubysec/ruby-advisory-db) for any CVEs
linked to your dependencies, down to the patch-level.
```bash
$ bundle exec bundler-audit
Name: puma
Version: 4.3.12
CVE: CVE-2024-21647
GHSA: GHSA-c2f4-cvqm-65w2
Criticality: Medium
URL: https://github.com/puma/puma/security/advisories/GHSA-c2f4-cvqm-65w2
Title: Puma HTTP Request/Response Smuggling vulnerability
Solution: upgrade to '~> 5.6.8', '>= 6.4.2'
Vulnerabilities found!
```
In this example run, a vulnerability was found in the currently installed
version of the `puma` gem.
I believe a standard `bundler-audit` command will make sure the advisory DB is
up-to-date, but to be sure, you can run the `update` command.
```bash
$ bundle exec bundler-audit update
Updating ruby-advisory-db ...
From https://github.com/rubysec/ruby-advisory-db
* branch master -> FETCH_HEAD
Already up to date.
Updated ruby-advisory-db
ruby-advisory-db:
advisories: 884 advisories
last updated: 2024-03-26 16:27:16 -0700
commit: 840f21aeeb8a06a93a3c3bf1e2a92d7167029992
```

View File

@@ -0,0 +1,47 @@
# Define Multiline Strings With Heredocs
[A _heredoc_ (_here document_) is a special ruby
syntax](https://ruby-doc.org/core-2.5.0/doc/syntax/literals_rdoc.html#label-Here+Documents)
for defining formatted multiline strings. These are useful for any situation
where you need to define a block of text where newlines and indentation are
preserved -- e.g. output an error, help message, or some formatted SQL.
The standard syntax is defined with `<<` and some uppercase identifier (e.g.
`TXT`, `DOC`, `SQL`, etc.) to open and close the multiline string.
```ruby
def lookup_team(team_id)
query = <<SQL
select users.id from users
join teams
on teams.id = users.team_id
where teams.id = #{team_id}
order by created_at desc
limit 10;
SQL
team_member_ids = db.execute(query)
end
```
With the SQL formatted this way, it is easier to read and we can print/log out
this nicely formatted version to make debugging easier.
Notice that the terminating `SQL` identifier is fully left justified. I find
that visually off relative to the indentation of everything else, so I like to
use the _indented_ heredoc syntax (`<<-`).
```ruby
def lookup_team(team_id)
query = <<-SQL
select users.id from users
join teams
on teams.id = users.team_id
where teams.id = #{team_id}
order by created_at desc
limit 10;
SQL
team_member_ids = db.execute(query)
end
```

View File

@@ -0,0 +1,42 @@
# Get UTC Offset For Different Time Zones
The [IANA Time Zone Database](https://www.iana.org/time-zones) uses identifiers
like `America/Chicago`, `Asia/Hong_Kong`, `Africa/Nairobi`, etc. as specifiers
for notable locations with time zone information.
> Most timezones correspond to a notable location and the database records all
> known clock transitions for that location; some timezones correspond instead
> to a fixed UTC offset.
—[Theory and pragmatics of the tz code and data](https://data.iana.org/time-zones/theory.html)
These identifiers can be used to look up time zone details with the [`tzinfo`
gem](https://github.com/tzinfo/tzinfo).
Here is an example of passing one to the `#get` method and then getting the UTC
offset in seconds.
```ruby
> require 'tzinfo'
> mountain = TZInfo::Timezone.get('America/Denver')
=> #<TZInfo::DataTimezone: America/Denver>
> mountain.utc_offset
=> -21600
```
We can even get the base UTC offset that doesn't account for DST:
```ruby
> moutain.base_utc_offset
=> -25200
```
Notice, this is the same as the standard offset for a time zone like Phoenix
that doesn't observe DST.
```ruby
> phoenix = TZInfo::Timezone.get('America/Phoenix')
=> #<TZInfo::DataTimezone: America/Phoenix>
> phoenix.utc_offset
=> -25200
```

View File

@@ -0,0 +1,34 @@
# List Files In A Single Column
The `ls` command lists out the files and directories in your current directory
or a specified directory.
The standard output for an `ls` command expands the fit the width of your
terminal screen.
```bash
ls *.(ts|js)
cypress.config.ts postcss.config.js remix.config.js remix.env.d.ts server.ts tailwind.config.ts vitest.config.ts
```
This might not always be the ideal way to view that output. For instance, the
above example when shared as a code block like in this post ends up with
horizontal scroll.
With the `-1` flag, we can tell `ls` to display the results in a single
vertical column.
```bash
ls -1 *.(ts|js)
cypress.config.ts
postcss.config.js
remix.config.js
remix.env.d.ts
server.ts
tailwind.config.ts
vitest.config.ts
```
See `man ls` for more details.
[source](https://askubuntu.com/questions/954924/listing-files-in-directory-in-one-column)

View File

@@ -0,0 +1,16 @@
# Print DateTime Represented By Unix Timestamp
A lot of tools and systems use a Unix timestamp to represent a point in time.
It is the number of seconds since the Unix epoch (Jan 1, 1970). However, just
looking at a timestamp like `1623867544` doesn't tell a human much. I can't
mentally translate that to the date and time that it is representing.
The `date` utility can help. Give it the `-r` flag with the timestamp value (in
seconds) and it will display the date and time in a human-readable format.
```bash
date -r '1623867544'
Wed Jun 16 13:19:04 CDT 2021
```
See `man date` for more details.

View File

@@ -0,0 +1,33 @@
# Unrestrict Where ripgrep Searches
One of the conveniences of [`rg`
(ripgrep)](https://github.com/BurntSushi/ripgrep) is that by default it doesn't
search in places you probably don't want it to search. That means it ignores
anything specified by your `.gitignore` file, it excludes hidden files and
directories (dotfiles, e.g. `.git/` or `.env`), and it excludes binary files.
These restrictions can be incrementally undone as needed using the `-u` flag.
The `-u` flag on its own will remove the ignored files restriction. This is
equivalent to the `--no-ignore` flag.
```bash
$ rg -u pattern
```
Adding an additional `u` (`-uu`) to that flag will remove both the ignored files and
hidden files restrictions. This is a shorthand equivalent to both `--no-ignore`
and `--hidden`.
```bash
$ rg -uu pattern
```
Adding one more `u` (`-uuu`) will additionally remove the binary file
restriction. Equivalent to those other two flags plus `--text`.
```bash
$ rg -uuu pattern
```
[source](https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md#automatic-filtering)

View File

@@ -0,0 +1,18 @@
# Turn Off Display Of Tabs For Files
Each time a file is opened in VS Code, it appears as one of many toward the top
of the window right above the text editor area. It shows the name of the file
and the 'dirty' status. Over time as more and more files are opened and edited,
the tabs accumulate and can only be viewed by horizontally scrolling left and
right.
There are other ways to navigate to files besides selecting tabs of already
opened files. So, if you'd like to reclaim some screen real estate and reduce
the visual clutter of the tabs, you can turn them off.
Hit `Cmd+Shift+P`, then search for and go to _Preferences: Open Settings (UI)_.
Search for _Show Tabs_ which will show up under _Workbench > Editor_.
The default is _Multiple_. You can switch it to _None_ to completely hide tabs.
You can also set it to _Single_ which will display file name and path for the
current file, but eliminate the clutter of all other tabs.

View File

@@ -0,0 +1,29 @@
# Access 1Password Credential From CLI
With the `op` CLI, I can store things like API keys and secrets in my 1Password
vault and then access them from the command line. This assumes I've already
installed the CLI (`brew install 1password-cli`) and connected it to the
1Password app via the _Developer_ settings.
The `op item get` command takes a credential name and returns all the details
for the entry with that _Title_. Here is how I can access my _Anthropic Claude
API Key_ details.
```bash
$ op item get "Anthropic Claude API Key"
```
With the `--field` flag, I can grab a specific field, such as the `credential`,
from that entry.
```bash
$ op item get "Anthropic Claude API Key" --field credential
sk-ant-api03-abc......xyz
```
A command like this can be embedded in other commands as a way of referencing
secrets without explicitly entering them into your shell history.
```bash
$ curl https://api -H "x-api-key: $(op item get "Anthropic Claude API Key" --field credential)" ...
```