7rikazhexde’s tech log

技術的な興味関心や備忘録をまとめてます。

Macでnodenvをインストールする

概要

npmのパッケージ管理ツールとしてnを使用していましたが、
brew doctorを実行したところ以下のwarningが出ました。

% brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry or file an issue; just ignore this. Thanks!

Warning: You have unlinked kegs in your Cellar.
Leaving kegs unlinked can lead to build-trouble and cause formulae that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
  node

nとbrewコマンドでインストールしたnodeの設定に問題があり、
nodeコマンドの実体についてリンクを設定し直せばwarningは解消できそうでしたが、
Pythonをpyenvで管理していることもあり、Node.jsも同様に仮想環境で管理したいと考えました。
そこでNode.js用の管理ツールであるnodenvをインストールすることにしました。

nとnode(npm)を削除する

以下の記事を参考にさせていただきました。
手順は同じですが、./zshrcを変えていたので関連する箇所は個別に修正しました。
nパッケージを完全にアンインストールする

削除後にbrewコマンドではnode,npmがインストールしていないことを確認する

% brew node
Error: Unknown command: node
% brew npm
Error: Unknown command: npm

nodenvをインストール

nodenvのインストールは以下の記事を参考にさせていただきました。
nodenvでNode.jsのバージョンを切り替える

Homebrewでnodenvをインストールする

# https://github.com/nodenv/nodenv#homebrew-on-macos
# Homebrew on macOS
% brew install nodenv
Running `brew update --auto-update`...
==> Downloading https://ghcr.io/v2/homebrew/core/node-build/manifests/4.9.87
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/node-build/blobs/sha256:4187ec6
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/nodenv/manifests/1.4.0
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/nodenv/blobs/sha256:a20f7a9c8ce
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sh
######################################################################## 100.0%
==> Installing dependencies for nodenv: node-build
==> Installing nodenv dependency: node-build
==> Pouring node-build--4.9.87.all.bottle.tar.gz
🍺  /usr/local/Cellar/node-build/4.9.87: 775 files, 928.6KB
==> Installing nodenv
==> Pouring nodenv--1.4.0.monterey.bottle.tar.gz
🍺  /usr/local/Cellar/nodenv/1.4.0: 34 files, 106.4KB
==> Running `brew cleanup nodenv`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

zshrcに以下を追加

% vi ~/.zshrc
eval "$(nodenv init -)"

nodenv-doctor スクリプトを使用して、nodenv が適切に設定されていることを確認する

# https://github.com/nodenv/nodenv#homebrew-on-macos
# 4. Verify that nodenv is properly set up using this nodenv-doctor script:
% curl -fsSL https://github.com/nodenv/nodenv-installer/raw/master/bin/nodenv-doctor | bash
Checking for `nodenv' in PATH: /usr/local/bin/nodenv
# nodenvコマンド(エイリアス)のインストール先
Checking for nodenv shims in PATH: OK
Checking `nodenv install' support: /usr/local/bin/nodenv-install (node-build 4.9.87)
# nodenv-installコマンド(エイリアス)のインストール先
Counting installed Node versions: none
  There aren't any Node versions installed under `$HOME/.nodenv/versions'.
  You can install Node versions like so: nodenv install 2.2.4
Auditing installed plugins: OK

<補足> brewコマンドで更新する場合:nodenv,node-buildそれぞれ指定する

# https://github.com/nodenv/nodenv#homebrew-on-macos
# Upgrading with Homebrew
% brew upgrade nodenv node-build
Warning: nodenv 1.4.0 already installed
Warning: node-build 4.9.87 already installed

<補足> nodenvコマンド(実体)の確認

% cd /usr/local/bin/      
% ls -lt nodenv
lrwxr-xr-x  1 [computer_name]  admin  33  8  4 21:04 nodenv -> ../Cellar/nodenv/1.4.0/bin/nodenv

% cd ../Cellar/nodenv/1.4.0/bin/

% pwd
/usr/local/Cellar/nodenv/1.4.0/bin

% ls
nodenv

<補足> nodenv-installコマンド(実体)の確認

% ls -lt nodenv-install
lrwxr-xr-x  1 [computer_name]  admin  46  8  4 21:04 nodenv-install -> ../Cellar/node-build/4.9.87/bin/nodenv-install

% cd ../Cellar/node-build/4.9.87/bin/

% pwd
/usr/local/Cellar/node-build/4.9.87/bin

% ls
node-build      nodenv-install      nodenv-uninstall
# nodenv-install以外も追加されている

nodenv-package-rehashプラグインをインストール
nodenv-package-rehashプラグインはグローバルパッケージをインストールまたはアンインストールするたびに、nodenv rehash を自動的に実行されるようになります。

# install via git (recommended)
% git clone https://github.com/nodenv/nodenv-package-rehash.git "$(nodenv root)"/plugins/nodenv-package-rehash
Cloning into '$HOME/.nodenv/plugins/nodenv-package-rehash'...
remote: Enumerating objects: 820, done.
remote: Total 820 (delta 0), reused 0 (delta 0), pack-reused 820
Receiving objects: 100% (820/820), 111.61 KiB | 4.65 MiB/s, done.
Resolving deltas: 100% (374/374), done.

zshrcを以下に変更

% vi ~/.zshrc
- eval "$(nodenv init -)"
+ eval "$(nodenv init - --no-rehash)"

nodenv init - --no-rehashによる設定について

https://github.com/nodenv/nodenv-package-rehash
Configuration (optional)
With this plugin, rehashing will happen on-demand (when global npm modules are installed/uninstalled). You can take advantage of this and remove nodenv's automatic hashing upon shell initialization. In your shell startup file (.bash_profile, .bashrc, or .zshrc), add the --no-rehash flag to the nodenv init - invocation: eval "$(nodenv init - --no-rehash)" This will speed up your shell initialization since nodenv will no longer need to rehash on every startup.

シェルの起動ファイル (.bash_profile, .bashrc, .zshrc) で、
nodenv init - invocation に --no-rehashフラグを追加することにより、オンデマンドでリハッシュが行われます。
(グローバルなnpmモジュールがインストール/アンインストールされたとき)
これを利用して、シェル初期化時のnodenvの自動ハッシュ化を解除することができます。
nodenvが起動のたびにリハッシュする必要がなくなるので、シェルの初期化が高速化されます。

nodenvコマンドの使い方

指定バージョンのインストール方法

% nodenv install -l

0.1.14
# 省略
18.4.0
18.5.0
18.6.0
18.7.0
chakracore-dev
chakracore-nightly
chakracore-8.1.2
# 省略
iojs-3.3.1
nightly
node-dev
rc
v8-canary

% nodenv install 17.9.1
Downloading node-v17.9.1-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v17.9.1/node-v17.9.1-darwin-x64.tar.gz

WARNING: node-v17.9.1-darwin-x64 is past its end of life and is now unsupported.
It no longer receives bug fixes or security updates.

Installing node-v17.9.1-darwin-x64...
Installed node-v17.9.1-darwin-x64 to $HOME/.nodenv/versions/17.9.1

Installed postinstall/postuninstall package hooks for 17.9.1

% nodenv install 18.6.0
Downloading node-v18.6.0-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v18.6.0/node-v18.6.0-darwin-x64.tar.gz
Installing node-v18.6.0-darwin-x64...
Installed node-v18.6.0-darwin-x64 to $HOME/.nodenv/versions/18.6.0

Installed postinstall/postuninstall package hooks for 18.6.0

% nodenv install 18.7.0 
Downloading node-v18.7.0-darwin-x64.tar.gz...
-> https://nodejs.org/dist/v18.7.0/node-v18.7.0-darwin-x64.tar.gz
Installing node-v18.7.0-darwin-x64...
Installed node-v18.7.0-darwin-x64 to $HOME/.nodenv/versions/18.7.0

Installed postinstall/postuninstall package hooks for 18.7.0

#インストールされているNode.jsのバージョン一覧
% nodenv versions      
  17.9.1
  18.6.0
  18.7.0

# インストールされているNode.jsをアンインストール方法
% nodenv uninstall 17.9.1
nodenv: remove $HOME/.nodenv/versions/17.9.1? [yN] y
% nodenv versions        
  18.6.0
  18.7.0

バージョン変更

% node -v                
nodenv: node: command not found

The `node' command exists in these Node versions:
  18.6.0
  18.7.0

# グローバル(システム全体)で利用するNode.jsのバージョンを設定する
% nodenv global 18.7.0
% node -v             
v18.7.0

% nodenv versions               
  18.6.0
* 18.7.0 (set by $HOME/.nodenv/version)

# ローカル(カレントディレクトリ配下)で利用するNode.jsのバージョンを設定する
node % mkdir nodenvtest
node % cd nodenvtest 
nodenvtest % nodenv local 18.6.0
nodenvtest % node -v            
v18.6.0

% cat .node-version
# nodenv localコマンドで.node-versionが作成されバージョン情報が書き込まれる 
18.6.0

<補足> バージョンの切り替えについて
pyenvはrbenvからフォークされたプロジェクトのため、
https://github.com/nodenv/nodenv/wiki/Why-nodenv%3F
バージョン管理構造はrbenvと同じでshimsコマンドを使用している。
概念と仕組みについては下記の記事がわかりやすく記載されているため参考にさせていただきました。
https://mogulla3.tech/articles/2021-07-10-understanding-rbenv-1/

コマンドの実行ファイル(パス)

% which node
$HOME/.nodenv/shims/node
% which npm 
$HOME/.nodenv/shims/npm

% cd $HOME/.nodenv/shims/
% ls
corepack    node        npm     npx

shims % ls -lt
total 32
-rwxr-xr-x  1 [computer_name]  staff  421  8  4 21:18 npx
-rwxr-xr-x  1 [computer_name]  staff  421  8  4 21:18 npm
-rwxr-xr-x  1 [computer_name]  staff  421  8  4 21:18 node
-rwxr-xr-x  1 [computer_name]  staff  421  8  4 21:18 corepack

バージョン毎のnodeファイル

% ls ~/.nodenv/
plugins     shims       version     versions

% ls ~/.nodenv/versions/   
18.6.0  18.7.0

% ls ~/.nodenv/versions/18.6.0/
CHANGELOG.md    README.md   include     share
LICENSE     bin     lib

シェル固有の Node バージョンを設定する方法 このバージョンはアプリケーション固有のバージョンとグローバルバージョンをオーバーライドする。

% nodenv shell 18.7.0   
% nodenv versions    
  18.6.0
* 18.7.0 (set by NODENV_VERSION environment variable)
% echo $NODENV_VERSION
18.7.0
% env | grep NODENV_VERSION
NODENV_VERSION=18.7.0
# 環境変数としてnodeのバージョンが設定されている

# ただしこのバージョンはshell instanceごとにアクティブなnodeバージョンのためshellを再起動すると削除される。
% env | grep NODENV_VERSION
% nodenv versions          
  18.6.0
* 18.7.0 (set by $HOME/.nodenv/version)

# シェル固有の Node バージョンを未設定にする
% nodenv shell --unset
% nodenv versions          
  18.6.0
* 18.7.0 (set by $HOME/.nodenv/version)
% env | grep NODENV_VERSION

まとめ

参考記事を元にnodenvのインストールしました。特に悩む点はなくインストールできました。
n以外にもnodeのパッケージツールはいくつかありますが、それぞれ設定が必要な場合もあるため少し抵抗がありました。
また、MacではHomebrewで他のスクリプトを管理しているため、nodenv+brewでシンプルになり、フォルダごとにバージョンを区別できるのでより管理がしやすくなるかなと思います。

IPhoneのショートカットアプリで土日、祝日、平日を考慮してアラームを指定時間で設定するオートメーションについて

経緯

IPhoneの時計アプリではアラームを設定することができますが、設定を自動化したくなりショートカットアプリで作成することにしました。
IPhoneでは「ヘルスケア」の睡眠スケジュール機能として曜日ごとにアラームを設定できる機能がありますが、アラーム設定は平日と休日で異なる場合があります。例えば祝日の場合は平日のアラームが設定することがあると思います。しかし、現状のヘルスケアの睡眠スケジュール機能では祝日の判定ができないため、希望通りの設定ができません。 また、睡眠スケジュールアラームには曲を選択することはできたいため、曲を指定したい場合は時計アプリを使用する必要があります。 そこで本記事ではカレンダーの情報から平日と祝日の情報を取得してアラームを設定するショートカットアプリを作成したので紹介します。

作成したもの

指定時間(デフォルトでは0時)に土、日、祝日用と平日用に2種類のアラームを設定するショートカットアプリです。

動作確認環境

iOS 13.x以降

使用手順

  1. 下記リンクよりアラーム設定のショートカットをショートカットアプリに追加する。
    ※リンクから追加画面に遷移しない場合はメモにURLを貼り付けてからアクセスしてください。 www.icloud.com
  2. 時計アプリで土、日、祝日用と平日用のアラームを作成する。
  3. アラーム設定のショートカットに2.で作成した時間を土、日、祝日用と平日用のアラームについて、アラームの切り替えアクションでオン、オフをそれぞれ設定する。
  4. 新規オートメーション画面で個人用オートメーションを作成して時刻を00:00、繰り返しを毎日に設定し、アクションを追加ボタンから1.で追加したアラーム設定のショートカットを設定する。

注意事項

土、日、祝日は同じ時間のアラームを設定するようにしています。(個人的に土、日、祝日で分ける必要はなかったためです。)
それぞれ設定する場合は後述するアラーム設定用の変数と判定処理を追加すれば対応可能です。
実行可能な端末はIPhoneIPadです。Macでもショートカットアプリはサポートしていますが。時計アプリとオートメーションが未サポート(MacOS バージョン12.5現在)のため実行できません。

ショートカットの処理について

以下アクティビティ図に従い処理します。
※アラーム設定のショートカットにもコメントを追加していますので合わせて確認ください。 アラーム設定初期化処理平日と土、日、祝日用のアラームをオフにする。アラームオフ処理アラーム設定用変数を0で初期化する。 土日用:flagSetAlarmSatAndSub 祝日用:flagSetAlarmHolidayアラーム設定用変数の初期化処理土日判定処理カレンダーアクションから現在の日付指定でフォーマットした日付情報を取得する。 日付フォーマット:カスタム 文字列フォーマット:EEE ロケール:デフォルト日付情報取得処理trueフォーマット済みの日付が次を含む 土ならばflagSetAlarmSatAndSub=1trueフォーマット済みの日付が次を含む 日ならば)falseflagSetAlarmSatAndSub=1土日ではない(flagSetAlarmSatAndSub==0)N/A祝日判定処理カレンダーアクションから全てのカレンダーイベントを検索(以下の条件に合うもの)次の全てが真(TRUE) 開始時日が今日であるおよび カレンダーが次と等しい日本の祝日カレンダーイベント検索処理日本の祝日と等しいtruefalseflagSetAlarmHoliday=1祝日ではない(flagSetAlarmHoliday==0)N/Aアラーム設定処理祝日用アラームをオンにするショートカットを停止して終了する。trueflagSetAlarmHoliday==1土日用アラームをオンにするショートカットを停止して終了する。trueflagSetAlarmSatAndSub==1平日用アラームをオンにするショートカットを停止して終了する。trueflagSetAlarmHoliday==flagSetAlarmSatAndSubショートカットを停止して終了する。※基本的にこの分岐に来ることはないが念の為ショートカットを停止する。

まとめ

IPhoneの時計アプリのアラームを自動で設定するショートカットアプリを作成しました。
カレンダーから土日、祝日、平日の情報を取得、判定することでアラームを設定しました。 気になった方は是非使ってみてください。
本来は寝る時間も起きる時間も固定化して規則正しい睡眠を取ることが理想ですが、寝る時間はバラついているので寝るまでの時間も意識して習慣化したいなと思っています。

ご挨拶

はじめまして。7rikaz(ナリカズ)と言います。
技術系の興味、関心や備忘録をまとめていこうと思いブログを始めることにしました。

以下簡単な自己紹介です。
横浜の会社でソフトウェアエンジニアをしています。
会社ではC言語で開発をしています。 他の言語としてはJavaC#PythonRubyJavaScriptの経験がありますが、趣味で書く程度で開発経験はほぼありません。
その他、趣味は自転車と写真です。

また、コードを書くモチベーションは生活のストレスを解消することで、
技術的なトピックスとしてはデータ分析、自動化、クリプトが興味、関心の対象になっています。

コードはQiitaGitHubでも公開していますが、はてなブログの方でも投稿していこうと考えています。

よろしくお願いします。