【Elixir】テストを書いてみる
Elixir でのテストを触りだけやる
バージョン 🔗
$ elixir -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Elixir 1.14.2 (compiled with Erlang/OTP 25)
$ mix -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Mix 1.14.2 (compiled with Erlang/OTP 25)
プロジェクト作成 🔗
mix new でプロジェクトを作成する
$ mix new hello
以下のファイル群が生成された
$ cd hello
$ tree .
.
├── README.md
├── lib
│ └── hello.ex
├── mix.exs
└── test
├── hello_test.exs
└── test_helper.exs
2 directories, 5 files
hello.ex には、:world を返す hello 関数が定義されている
$ iex -S mix
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Interactive Elixir (1.14.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Hello.hello
:world
mix test でテストを実行する
Elixir で Hello, World!
Elixir も触っておきたいなと思ったので、取り急ぎの Hello, World! をやってみた
インストール 🔗
Mac は HomeBrew でインストールすることができる
$ brew install elixir
$ elixir --version
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Elixir 1.14.2 (compiled with Erlang/OTP 25)
他のインストール方法は https://elixir-lang.org/install.html を参照
インタラクティブモード 🔗
いわゆる REPL
$ iex
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Interactive Elixir (1.14.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 1 + 2
3
Ctrl + C
を2回で終了できる
スクリプトモードで Hello, World! 🔗
拡張子 exs
でファイルを作って、elixir ファイル名
で実行
defmodule Hello do
def greet do
IO.puts "Hello, World!"
end
end
$ elixir hello.exs
Hello, World!
コンパイルして Hello, World! 🔗
拡張子 ex
でファイルを作って、elixirc ファイル名
でコンパイル
Heroku の PostgreSQL のデータをバックアップしてローカルのデータベースにリストアする
pg_dump と pg_restore を使ったやり方なので、Heroku 関係なしにできる
Heroku のPostgreSQL からバックアップ 🔗
$ PGPASSWORD=${パスワード} pg_dump --format=custom --no-acl --no-owner -h ${ホスト名} -U ${ユーザー名} ${データベース名} > app_production.custom
フォーマットはカスタム形式にしている
データベース情報の確認 🔗
Heroku で使っている PostgreSQL の情報は以下のコマンドで確認することができる
$ heroku pg:credentials:url
ローカルにリストア 🔗
$ pg_restore --clean --no-acl --no-owner -h ${ホスト名} -U ${ユーザー名} -d ${データベース名} app_production.custom
Heroku のデータベースとローカルのデータベースの違いが原因で警告が表示されるが、無視しても問題ないらしい
実際にリストアできていることが確認できた
参考 🔗
Next.js 13 に NextUI を導入する
Next.js 13 の app ディレクトリモード?に NextUI を導入した時のメモ
NextUI はまだ Next.js 13 に完全対応はしておらず、とりあえず動くところまで持っていけただけなので参考程度に
前提条件 🔗
以下コマンドで Next.js のアプリを作成したばかりところに導入する
$ yarn create next-app app_name --typescript --experimental-app
手順 🔗
インストール 🔗
$ yarn add @nextui-org/react
セットアップ 🔗
app/providers.tsx を作成
"use client"
import { useServerInsertedHTML } from "next/navigation"
import { NextUIProvider, CssBaseline } from "@nextui-org/react"
export function Providers({ children }: { children: React.ReactNode }) {
useServerInsertedHTML(() => {
return <>{CssBaseline.flush()}</>
})
return <NextUIProvider>{children}</NextUIProvider>
}
app/layout.tsx を以下のように修正
import "./globals.css"
+import { Providers } from "./providers"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</head>
- <body>{children}</body>
+ <body>
+ <Providers>{children}</Providers>
+ </body>
</html>
)
}
動作確認 🔗
ボタンを仮設置して、NextUI が有効になっているかを確認する
【GitHub Actions】Raspberry Pi でセルフホストランナーを起動する
GitHub Actions の セルフホストランナーを Raspberry Pi で起動してみた
基本は公式ドキュメントと設定画面に表示される手順でサクッとできる
ランナーはリポジトリ単位かオーガニゼーション単位で起動できる
ユーザー単位ではできないっぽい
今回はリポジトリに対してランナーを起動
悪意のあるコードが実行される可能性があるのでリポジトリはプライベートで作成することが推奨されている
環境 🔗
- Raspberry Pi 4 Model B
- Raspberry Pi OS 10.11
手順 🔗
リポジトリの「Settings」->「Actions」->「Runners」->「New self-hosted runner」からランナーを追加できる
Runner image は Linux、Architecture は ARM を選択
環境に合った手順が表示されるのでそれをただ実行するだけ
ダウンロード 🔗
$ mkdir actions-runner && cd actions-runner
$ curl -o actions-runner-linux-arm-2.299.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.299.1/actions-runner-linux-arm-2.299.1.tar.gz
$ tar xzf ./actions-runner-linux-arm-2.299.1.tar.gz
設定 🔗
./config.sh --url https://github.com/ユーザー名/リポジトリ名 --token トークン
対話形式でいろいろ聞かれるが、基本そのままエンターキーで良い
起動 🔗
$ ./run.sh
√ Connected to GitHub
Current runner version: '2.299.1'
2022-11-16 11:25:51Z: Listening for Jobs
ランナーが追加され、Status が 「Idle」になっていることが確認できた
【GitHub Actions】「Node.js 12 actions are deprecated.」の対応
とある Ruby のプロジェクトの GitHub Actions のページを開いたら、以下の警告が出ていた
Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout, actions/checkout
GitHub Actions で Node.js 12 のサポートが終了するから Node.js 16 に切り替えろとのこと
Ruby のプロジェクトだけど、actions/checkout で Node.js を使っているため対応する必要がある
対応方法 🔗
actions/checkout@v2 から actions/checkout@v3 に変更するだけで良い
name: Ruby ${{ matrix.ruby }}
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
Dependabot で GitHub Actions のアクションを自動更新する 🔗
手動で対応するのは面倒なので、ライブラリなどと同じようにアクションも Dependabot で更新するようにした
【Vagrant】CPU の数を変更する
仮想マシンに割り当てる CPU の数を増やしたかった
メモリを増やす方法と同じやり方でできた
config.vm.provider "virtualbox" do |vb|
# Display the VirtualBox GUI when booting the machine
# vb.gui = true
# Customize the amount of memory on the VM:
vb.memory = "15360"
+ vb.cpus = "3"
end
$ grep processor /proc/cpuinfo | wc -l
3
CPU のコア数が3になっていることが確認できる
参考 🔗
Vagrant で VirtualBox 仮想マシンの CPU 数とメモリサイズを変更 - なんとなくな Developer のメモ 物理 CPU、CPU コア、および論理 CPU の数を確認する - Red Hat Customer Portal
git diff コマンドで省略せず全行表示する
git diff はデフォルトで変更された行の前後3行分だけ表示されるようになっている
$ git diff main.tf
diff --git a/main.tf b/main.tf
index e82334f..361f6ac 100644
--- a/main.tf
+++ b/main.tf
@@ -1,3 +1,7 @@
+variable access_key {}
+variable secret_key {}
+variable endpoints_s3 {}
+
terraform {
required_providers {
aws = {
@@ -8,13 +12,13 @@ terraform {
}
provider "aws" {
- access_key = "access key"
- secret_key = "secret key"
+ access_key = var.access_key
+ secret_key = var.secret_key
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
endpoints {
- s3 = "https://<account id>.r2.cloudflarestorage.com"
+ s3 = var.endpoints_s3
}
region = "auto"
}
省略しないで全て表示させたい時は、-U<任意の数字> オプションを使うと良い
変更された行の前後<任意の数字>分表示されるようになる
【Faraday】HTTP/2 でリクエストする
HTTP/2 でしか何故か受け付けない API があったので調べた
手順 🔗
Typhoeus の Faraday 用のミドルウェア(アダプター)、faraday-typhoeus を使う
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'faraday'
gem 'faraday-typhoeus'
end
conn = Faraday.new(url: 'https://example.com') do |conn|
conn.adapter :typhoeus, http_version: :httpv2_0
end
puts conn.get('/').body
動作確認 🔗
これで実際に HTTP/2 でリクエストできているのかを確認する
確認方法には nc コマンドを使った
$ ( echo "HTTP/1.1 200 OK"; echo; echo "Hello World" ) | nc -l 5555
HTTP/1.1 🔗
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'faraday'
end
conn = Faraday.new(url: 'http://localhost:5555')
puts conn.get('/').body
$ ruby faraday-http2.rb
Hello World
$ ( echo "HTTP/1.1 200 OK"; echo; echo "Hello World" ) | nc -l 5555
GET / HTTP/1.1
User-Agent: Faraday v2.6.0
Accept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept: */*
Host: localhost:5555
シンプルに Faraday を使うと HTTP/1.1 になっている
switchbot gem v0.7.0 をリリースした
SwitchBot API 用の Gem、switchbot v0.7.0
をリリースした
このリリースで、SwitchBot API v1.1 を使うようになった
https://rubygems.org/gems/switchbot
変更点 🔗
認証方法の変更 🔗
SwitchBot API v1.1 では認証方法が変わり、トークンに加えてシークレットも必要になった
シークレットはトークンと同じく SwitchBot のアプリから取得できる
client = Switchbot::Client.new('YOUR_TOKEN', 'YOUR_SECRET')
SwitchBot ロックに対応 🔗
認証方式が変わってセキュリティが強化されたので、API 経由でロックの解錠・施錠ができるようになった
client = Switchbot::Client.new('YOUR_TOKEN', 'YOUR_SECRET')
client.lock('C271111EC0AB').unlock
#=>
#{:status_code=>100,
# :body=>
# {:items=>
# [{:device_id=>"C271111EC0AB",
# :code=>100,
# :status=>
# {:door_state=>"closed",
# :is_slave=>false,
# :door_state_source=>"master",
# :is_slave_online=>false,
# :battery=>95,
# :pause_auto_lock=>false,
# :lock_state=>"unlocked",
# :last_action_source=>"autoLock",
# :is_calibrate=>true,
# :power=>"on",
# :is_group=>false,
# :door_opened_overtime_warning=>false,
# :unlocked_overtime_warning=>false},
# :message=>"success!"}]},
# :message=>"success"}
client.lock('C271111EC0AB').lock
#=>
#{:status_code=>100,
# :body=>
# {:items=>
# [{:device_id=>"C271111EC0AB",
# :code=>100,
# :status=>
# {:door_state=>"closed",
# :is_slave=>false,
# :door_state_source=>"master",
# :is_slave_online=>false,
# :battery=>95,
# :pause_auto_lock=>false,
# :lock_state=>"locked",
# :last_action_source=>"command",
# :is_calibrate=>true,
# :power=>"on",
# :is_group=>false,
# :door_opened_overtime_warning=>false,
# :unlocked_overtime_warning=>false},
# :message=>"success!"}]},
# :message=>"success"}
AWS CLI で S3 からワイルドカードで指定してファイルをダウンロードしたい
S3 に yyyy-mm-dd.csv という名前の形式で CSV ファイルが保存されている
$ aws s3 ls s3://path/to/
2017-01-20 18:03:55 47968 2014-10-16.csv
2017-01-20 18:02:47 71855 2014-10-17.csv
2017-01-20 18:02:45 73806 2014-10-18.csv
...
2022-10-24 03:21:43 7162892 2022-10-21.csv
2022-10-24 03:21:40 6656291 2022-10-22.csv
2022-10-24 03:21:39 5379009 2022-10-23.csv
不具合の調査で4月分の CSV ファイルをダウンロードしたかった
$ aws s3 ls s3://path/to/2022-04
2022-04-04 03:19:20 8364026 2022-04-01.csv
2022-04-05 03:20:20 8394353 2022-04-02.csv
2022-04-06 03:18:53 8243473 2022-04-03.csv
...
2022-05-01 03:18:09 8029591 2022-04-28.csv
2022-05-02 03:18:00 7992829 2022-04-29.csv
2022-05-03 03:18:49 7502806 2022-04-30.csv
ls コマンドで絞り込みできるなら cp コマンドでもできるだろうと思ったらできなかった
$ aws s3 cp s3://path/to/2022-04 .
fatal error: An error occurred (404) when calling the HeadObject operation: Key "path/to/2022-04" does not exist
–recursive オプションと –exclude オプション と –include オプションを使うと絞り込みができた
HomeBrew で最新版の q をインストールする
HomeBrew で q をインストールしようとしたら、brew install q では最新版が入らなかった
$ brew install q
$ q -v
q version 2.0.20
Python: 3.9.15 (main, Oct 11 2022, 22:26:39) // [Clang 13.0.0 (clang-1300.0.29.30)]
Copyright (C) 2012-2020 Harel Ben-Attia ([email protected], @harelba on twitter)
http://harelba.github.io/q/
正しいインストール方法 🔗
どうやら公式のフォーミュラから削除したっぽい
$ brew install harelba/q/q
$ q -v
q version 3.1.6
Python: 3.9.7 (default, Oct 18 2021, 00:59:13) // [Clang 13.0.0 ]
Copyright (C) 2012-2021 Harel Ben-Attia ([email protected], @harelba on twitter)
http://harelba.github.io/q/
【Ruby】Base64.encode64 は改行コードが入る
Ruby で Base64.encode64 を使った時に末尾に改行コード(\n)が入っていることに気がついた
require 'base64'
Base64.encode64('こんにちはこんにちはこんにちはこんにちは')
#=> "44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv\n44GT44KT44Gr44Gh44Gv\n"
RFC2045 の仕様に準拠していて、末尾以外にも60文字ごとに改行コードが追加されるっぽい(Base64.#encode64 (Ruby 3.1 リファレンスマニュアル) )
改行コードが入って欲しくない時は、Base64.strict_encode64 を使うと良い
require 'base64'
Base64.strict_encode64('こんにちはこんにちはこんにちはこんにちは')
#=> "44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv44GT44KT44Gr44Gh44Gv"
これは RFC4648 の仕様に準拠している(Base64.#strict_encode64 (Ruby 3.1 リファレンスマニュアル) )
参考 🔗
SwitchBot API v1.1 の認証(Ruby バージョン)
先日、SwitchBot API の v1.1 が公開された
v1.1 では認証方法が変わっている
公式ドキュメント
には Python と JavaScript での認証方法のサンプルコードが載っていたが、Ruby がなかったので書いてみた
コード 🔗
require 'securerandom'
require 'base64'
require 'openssl'
token = 'hoge-token'
secret = 'fuga-secret'
t = (Time.now.to_f * 1000).to_i
nonce = SecureRandom.alphanumeric
sign = Base64.strict_encode64(OpenSSL::HMAC.digest('sha256', secret, "#{token}#{t}#{nonce}"))
puts "Authorization: #{token}"
puts "t: #{t}"
puts "sign: #{sign}"
puts "nonce: #{nonce}"
- token: アクセストークン
- secret: アクセストークンシークレット(SwitchBot アプリ v6.14 以降で取得可能)
- t: 13桁のタイムスタンプ
- nonce: 利用するプログラムで生成した UUID キー
- sign: 特定のアルゴリズムで生成した文字列
実行 🔗
実行すると必要な情報が出力される
$ ruby app.rb
Authorization: hoge-token
t: 1665582731060
sign: Lk4PPsJLZXAN6yhRTfhE5Vargx9N0iIBJRO+YeAkyJU=
nonce: flMkSCm3PkBgOukF
リクエストヘッダーに追加して curl などでリクエストしたらOK(例はデバイスを取得する)
$ curl -X GET 'https://api.switch-bot.com/v1.1/devices' \
--header 'Authorization: hoge-token' \
--header 't: 1665582731060' \
--header 'sign: Lk4PPsJLZXAN6yhRTfhE5Vargx9N0iIBJRO+YeAkyJU=' \
--header 'nonce: flMkSCm3PkBgOukF'
本当は Ruby で API を叩くところまでやりたかったけど、なぜかうまくいかなかったので調査中
Terraform で Cloudflare R2 のバケットを作成する
Terraform の肩慣らしとして、Cloudflare R2 のバケットを作成してみた
Cloudflare R2 のドキュメントに書いてあったものを参考にした
https://developers.cloudflare.com/r2/examples/terraform/
Terraform バージョン 🔗
$ terraform -v
Terraform v1.3.2
on darwin_amd64
手順 🔗
設定ファイルを作成 🔗
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.34.0"
}
}
}
provider "aws" {
access_key = "access key"
secret_key = "secret key"
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
endpoints {
s3 = "https://<account id>.r2.cloudflarestorage.com"
}
region = "auto"
}
resource "aws_s3_bucket" "cloudflare-bucket" {
bucket = "my-tf-test-bucket"
}
access key と secret key は R2 の管理画面、「R2 API トークンの管理」から作成できる
編集の権限を付けて作成した
OSS のコントリビュート状況を確認する
自分が今までどのくらい OSS にコントリビュートしてきたか確認したかった
https://github.com/pulls で「involves:{username} -user:{username}」を検索したら確認できる
検索オプションについて 🔗
involves 🔗
関連している人(Issue or PR を作成した人、アサインされている人、コメントしている人、メンションが飛んでいる人)の絞り込み
個別に
- author: Issue or PR を作成した人
- assignee: アサインされている人
- commenter: コメントしている人
- mentions: メンションが飛んでいる人 で指定できる
user 🔗
リポジトリのオーナーの絞り込み
自分のリポジトリは不要なので、- を付けて(-user)で除外している
所属しているオーガニゼーションも除外したかったら、-org を使う
例 兼 自分用リンク 🔗
https://github.com/pulls?q=involves%3Aytkg+-user%3Aytkg
実際には、身内のリポジトリと会社のオーガニゼーションを除外して確認している
参考 🔗
【Deno】deno init コマンド
Deno 1.25.0 で、プロジェクトの初期化をしてくれるサブコマンド deno init が追加された
$ deno --version
deno 1.25.4 (release, x86_64-apple-darwin)
v8 10.7.193.3
typescript 4.7.4
コマンドを実行すると、main.ts と main_test.ts の2つのファイルが生成される
$ deno init
✅ Project initialized
Run these commands to get started
deno run main.ts
deno test
$ ls
main.ts main_test.ts
Deno の基本的な書き方とそのテストの例が書かれている
export function add(a: number, b: number): number {
return a + b;
}
// Learn more at https://deno.land/manual/examples/module_metadata#concepts
if (import.meta.main) {
console.log("Add 2 + 3 =", add(2, 3));
}
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
import { add } from "./main.ts";
Deno.test(function addTest() {
assertEquals(add(2, 3), 5);
});
$ deno run main.ts
Add 2 + 3 = 5
$ deno test
running 1 test from ./main_test.ts
addTest ... ok (7ms)
ok | 1 passed | 0 failed (41ms)
Deno はたまにしか書かず、久々に書こうとした時にどうやって書くんだっけと毎回ググったり、他リポジトリを覗きにいったりしていたのでこのコマンドの追加は嬉しい
もちろん複雑なプログラムを書く時は他のことでどうせググるだろうけど、取っ掛かりまでのハードルが大幅に下がったのは大きい
tfenv で Terraform をインストールする
Terraform を使う機会が出てきたので tfenv でインストールした
tfenv のインストール 🔗
tfenv 自体は Homebrew でインストール
$ brew install tfenv
$ tfenv -v
tfenv 3.0.0
Terraform のインストール 🔗
$ tfenv install
$ tfenv use 1.3.0
$ terraform -v
Terraform v1.3.0
on darwin_amd64
引数にバージョンを指定しないと、環境変数 TFENV_TERRAFORM_VERSION で指定されたバージョンか、.terraform-version で指定されたバージョンか、latest がインストールされるっぽい(優先順位は記述順)
他、よく使いそうなコマンド 🔗
インストール済みのバージョンを確認 🔗
$ tfenv list
* 1.3.0 (set by /usr/local/Cellar/tfenv/3.0.0/version)
インストール可能なバージョンを確認 🔗
$ tfenv list-remote
1.3.0
1.3.0-rc1
1.3.0-beta1
1.3.0-alpha20220817
1.3.0-alpha20220803
1.3.0-alpha20220706
1.3.0-alpha20220622
1.3.0-alpha20220608
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
省略したけど、全部のバージョンが表示された
長いので rbenv
とかみたいにデフォルトは安定板のみ表示して欲しいと思った
【Sinatra / Rails】ユーザーID に ULID を使うことにした
Rails でも同じなのでタイトルに追加している
Sinatra アプリでユーザーの ID に UUID を使っていたが、ULID に切り替えた
ULID は、UUID と互換性があり、ミリ秒単位で時系列ソートができる
Gem があったのでそれを使うことにした
https://github.com/rafaelsales/ulid
require 'ulid'
ULID.generate
#=> "01G9VYHMNH5YWA0B96K1Q1KBHB"
以前書いた記事(【Rails / Sinatra】ID を UUID にする ) のモデルを以下のように書き換えるだけで移行完了
require 'ulid'
class User < ActiveRecord::Base
before_create -> { self.id = ULID.generate }
end
【Discord】Webhook でメッセージを送信する
Wenhook URL は、「サーバー設定」->「連携サービス」->「ウェブフックを確認」->「新しいウェブフック」で作成できる
$ curl -X POST -H 'Content-Type: application/json' https://discord.com/api/webhooks/1234565/HOGEHOGE -d '{"content": "Hello!"}'
参考 🔗
Discord に Webhook でいろいろ投稿する - Qiita https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
Cookpad Code Puzzle for RubyKaigi 2022 をやった
Cookpad Code Puzzle for RubyKaigi 2022
func4 から急に難しくなったけど、なんとか func10 まで解けた
func10 は変に難しく考えてしまい、無駄に時間掛かってしまった
素直に同じ挙動をするメソッドを書けばいい
func11 以降の解き方 🔗
func20 まであるらしいけど、func11 から問題が出てこない
以下のように自分で定義して実行したらいいっぽい
p func11
def answer11
end
ちなみに実行例やヒントはない
参考 🔗
【Ruby】タイムゾーンを変更する
GitHub Actions で時間を扱うRuby スクリプトを動かしたい
そのためには、GitHub Actions のタイムゾーンは UTC になっているので、タイムゾーンを変更する必要がある
Ruby はシステムのタイムゾーンに依存する 🔗
puts Time.now
$ ruby app.rb
2022-09-10 20:14:08 +0900
環境変数 TZ を指定してタイムゾーンを変更する 🔗
システムのタイムゾーンを変更するか、環境変数 TZ で指定してあげれば変更できる
環境変数で指定するのが手軽そう
$ TZ=UTC ruby app.rb
2022-09-10 11:14:33 +0000
$ TZ=America/New_York ruby app.rb
2022-09-10 07:14:46 -0400
GitHub Actions で日本時間で Ruby スクリプトを実行する 🔗
GitHub Actions では、上記の実行時に TZ を指定するやり方と、env で TZ を指定するやり方ができる
実行時に TZ を指定 🔗
jobs:
ruby:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.1
- name: Run script
run: TZ=Asia/Tokyo ruby app.rb
env で TZ を指定 🔗
jobs:
ruby:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.1
- name: Run script
env:
TZ: "Asia/Tokyo"
run: ruby app.rb
参考 🔗
#Ruby と #Rails の Time や Time.zone の扱いががマジで分からないし混沌としてるのでちょっとだけ整理したい。 - Qiita
【Mac】date コマンドで UNIX 時間を通常時間に変換する
【JavaScript】Fetch API で Basic 認証
Basic 認証が掛かった API からデータを取得するコードを書くことがよくある
その度に調べているのでメモ
#!/usr/bin/env zx
const username = "takagi"
const password = "thisispassword"
const res = await fetch("http://localhost:4567/auth", {
headers: {
Authorization: "Basic " + btoa(`${username}:${password}`)
}
})
console.log(await res.text())
$ zx script.mjs --quiet
Authorized.
最近よく使っている zx で動作確認した
いつも脳死でコピペしてたけど、よく見たらそんなに難しい書き方じゃないから普通に覚えられるな
補足 🔗
動作確認で使った API は「【Sinatra】ページ単位で Basic 認証を入れる 」で作ったやつを使った
$ curl http://localhost:4567/auth
Unauthorized.
$ curl http://localhost:4567/auth -H "Authorization: Basic $(echo -n 'takagi:thisispassword' | base64)"
Authorized.
【JavaScript】Base64 でエンコード・デコード
JavaScript で文字列を Base64 でエンコード・デコードする機会があったのでメモ
標準で btoa(), atob() が用意されているのでそれを使えばサクッとできる
const text = "Hello"
const encoded = btoa(text)
console.log(encoded) //=> SGVsbG8=
const decoded = atob(encoded)
console.log(decoded) //=> Hello
日本語などのマルチバイトの場合は、さらに encodeURIComponent(), decodeURIComponent() でエンコード・デコードする必要がある
const text = "こんにちは"
const encoded = btoa(encodeURIComponent(text))
console.log(encoded) //=> JUUzJTgxJTkzJUUzJTgyJTkzJUUzJTgxJUFCJUUzJTgxJUExJUUzJTgxJUFG
const decoded = decodeURIComponent(atob(encoded))
console.log(decoded) //=> こんにちは
補足 🔗
- btoa: binary to ASCII
- atob: ASCII to binary