Goland でファイル名が main じゃないとブレークポイントが貼れない? #Goland #golang

問題

docker-compose を使って Goland でリモートデバッグを試していた。

エントリポイント (main関数) のあるファイルだけブレークポイントを貼れない。

Cannot find debugger path for /path/to/server.go みたいなメッセージが出て、ブレークポイントが無効にされてしまう。

他のファイルにはブレークポイント貼れるし、実際に実行すると止まる。

f:id:su-kun1899:20220222235452p:plain

解決策

main関数のあるファイルの名前が server.go だったので、 main.go に名前を変えたところ問題は解消した。

原因

分からない。。

エントリポイントのファイル名は main.go じゃないとダメなんだろうか?

Goland の問題なのか、 delve の問題なのか、自分が何か間違っているのか。。

clasp の push で package.json が求められる #gas

GAS の実装や管理には clasp が便利なんですが、いざ clasp push で反映しようとしたらエラーが出て怒られた。

ENOENT: no such file or directory, open 'package.json'

複数の App Script をまとめて管理するために、下記のようなディレクトリ構造にしていたのが原因っぽい。

※ルートには package.json があるが、スクリプト本体のディレクトリにはない状態

.
├── HogeScript
│   ├── clasp.json
│   ├── appscript.json
│   └── hoge.ts
├── FugaScript
│   ├── clasp.json
│   ├── appscript.json
│   └── fuga.ts
└── package.json

clasp のリポジトリ同じ問題と思われる Issue があって、「空の package.json 作ると解消」とのことなので、試してみると解消した。

https://github.com/google/clasp/issues/875

空の package.json

{}
.
├── HogeScript
│   ├── clasp.json
│   ├── appscript.json
│   ├── hoge.ts
│   └── package.json    ←ここにも作ってあげる
├── FugaScript
│   ├── clasp.json
│   ├── appscript.json
│   ├── fuga.ts
│   └── package.json    ←ここにも作ってあげる
└── package.json
$ cd HogeScript
$ clasp push

Go の Web アプリケーションを Heroku にデプロイしたメモ #golang #heroku

概要

基本的な流れは公式に従ってやってみれば問題ないのだろうけど、自分で作ったものをデプロイしようとしたらちょこちょこ詰まったので備忘録。

https://devcenter.heroku.com/articles/getting-started-with-go https://github.com/heroku/go-getting-started

サブディレクトリのみ対象のときは subtree で push

これは自分がディレクトリ構造をコネてたのが原因なのだが、 git リポジトリとアプリケーションのディレクトリ構造があってないと、うまくデプロイできない。

デプロイ対象がサブディレクトリにあるようなケースでは subtree を使って push する。

git subtree push --prefix my-app/ heroku main

subtree では force push できない

いわゆる force-push ができない状況になると、 heroku に push できなくなる。

subtree には force オプションがないので、 subtree split でどうにかする。

git push heroku `git subtree split --prefix myapp mainr`:main --force

stackoverflow.com

main 以外のブランチをデプロイするとき

my-branch:main のようにしてあげないと skip される。

Postgres への接続

接続情報を Config Vars に設定

Postgres add-on だと DATABASE_URL という変数に格納されるが、接続文字列をそのまま使わなかったので、バラして別名の変数に入れ直した。

DATABASE_URL は下記の形式なので、それぞれ設定し直した。

postgres://{user}:{password}@{hostname}:{port}/{database-name}

ちなみに heroku config で Config Vars は取得できる。

Heroku CLI のインストール

Mac だと homebrew で入る。

<200b>brew tap heroku/brew && brew install heroku

heroku autocomplete しておくと補完をしてくれるようになる。

おまけ

homebrew で入れたやつの completion シュッとやる方法がドキュメントにあった。

docs.brew.sh

heroku run

heroku run bash やると直接コマンド叩ける。

調査のとき便利。

ssh-add コマンドの -K オプションが deprecated になってた

無邪気に ssh-add -K したら、 WARNING が出てることに気づいた。

WARNING: The -K and -A flags are deprecated and have been replaced
         by the --apple-use-keychain and --apple-load-keychain
         flags, respectively.  To suppress this warning, set the
         environment variable APPLE_SSH_ADD_BEHAVIOR as described in
         the ssh-add(1) manual page.

メッセージの通りだけれど、 -K は deprecated になったようだ。

代わりに --apple-use-keychain を使えば OK 。

「先延ばしと挫折をなくす計画術 無敵の法則」を読んだ

Twitter のタイムラインで言及されてて少し気になり、 Kindle でセールだったのもあり読んでみた。

著者のドヤと煽りが満載な雰囲気はあまり好みではないのだが、この類の本を何冊か読んで、自己啓発本というのはそういうものなんだなと理解してきた。

徹底的にスケジュール管理していくアプローチは、同意できるところや参考になる点もあるものの、かなり極端ではあるので、価値観は正直共感できないところも多かった。

それでも「ここまでは流石にやらないけど、これくらいはやってみるかなぁ」という気持ちになったので、読んでよかったかな。

CakePHP で Table の Validator を差し替える #cakephp

以前 Validation をカスタムしやすくする方法を書いた。

su-kun1899.hatenablog.com

Validation は bootstrap.php で差し替えればいいんだけれど、じゃあ自前で呼ばない Table の Validator を差し替えるにはどうしたらいいのか。

Table での Validation

Table クラスでの既定のバリデーションは、 validationDefault() で行われる。

インターフェースとしては Validator を引数で受け取る形になっており、ここを差し替えたい。

<?php
public function validationDefault(Validator $validator)
{
    $validator
        ->requirePresence('title', 'create')
        ->notEmpty('title');

    ...

    return $validator;
}

initialize で書き換えればよい

Table クラスの initialize で、 _validatorClass を差し替えてあげればよさそう。

<?php
public function initialize(array $config): void
{
    $this->_validatorClass = MyValidator::class;;
}

ドキュメントにもちゃんと書いてあった。

https://book.cakephp.org/4/en/orm/validation.html#default-validator-class

横断的に差し替えたいとなったら、基底クラス用意するのがいいのかなー。

PHP7 で CakePHP4 の FrozenDate を使うと、月差分が正しく判定されない場合がある #php #cakephp

概要

PHP8.1 未満の環境における CakePHP の FrozenDate は、 UTC でない Timezone を使った場合に、日付差分が正しく取れないケースがある。

FrozenTime を使うようにするか、 PHP8.1 以降にバージョンを上げると解決する。

※タイトルでは PHP7 としているけど、 8.0 でもだめなはず。

PHP8.1未満で比較する場合

環境は PHP7.4 , CakePHP は 4.2.8 で試す。

たとえば 2021年1月1日から3月1日までの差分を求めるとする。

期待値は当然 2 だ。

$ php -v
PHP 7.4.24 (cli) (built: Sep 23 2021 22:49:50) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.24, Copyright (c), by Zend Technologies
    with Xdebug v2.9.8, Copyright (c) 2002-2020, by Derick Rethans
$ bin/cake version
4.2.8

FrozenTime を使った場合

以前からあった diffInMonths は TimeZone の問題を抱えていたが、diffInMonthsIgnoreTimezone が提供されるようになったことで、期待通りの結果が得られるようになった。

github.com

<?php
use Cake\I18n\FrozenTime;

// UTC 以外にする
date_default_timezone_set('Asia/Tokyo');

$from = FrozenTime::create(2021, 1, 1);
$to = FrozenTime::create(2021, 3, 1);

// UTC 以外だと 1 が返ってきてしまうのでだめ
$result1 = $from->diffInMonths($to);

// 期待通り!
$result2 = $from->diffInMonthsIgnoreTimezone($to);

FrozenDate を使った場合

ところが FrozenDate を使うと、どうにも 1 が返ってきてしまう。

<?php
use Cake\I18n\FrozenDate;

// UTC 以外にする
date_default_timezone_set('Asia/Tokyo');

$from = FrozenDate::create(2021, 1, 1);
$to = FrozenDate::create(2021, 3, 1);

// IgnoreTimezone しても 1 が返ってきてしまう!
$result = $from->diffInMonthsIgnoreTimezone($to);

原因

前述の Issue にコメントされているのだが、どうやらそもそも DateTime::diff に問題があったようで、バグ報告されている。

このバグは既に対応済で、 PHP8.1 のリリースに含まれている。

PHP8.1で比較する場合

環境は PHP8.1 , CakePHP は 4.3.2 で試す。

$ php -v  
PHP 8.1.0 (cli) (built: Nov 30 2021 06:10:58) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.0, Copyright (c) Zend Technologies
$ bin/cake version
4.3.2

この環境で試すと、期待通りの結果が得られる。

(コードは同じもの)

<?php
use Cake\I18n\FrozenDate;

// UTC 以外にする
date_default_timezone_set('Asia/Tokyo');

$from = FrozenDate::create(2021, 1, 1);
$to = FrozenDate::create(2021, 3, 1);

// 無事 2 が返ってくるようになった
$result = $from->diffInMonthsIgnoreTimezone($to);

宣伝

今回の検証にあたって、以前作った Cake 用の Docker Image に PHP8.1 版を追加しておいたので、よかったら使ってみてください。

参考

dateInMonths の罠については↓らへんの記事が参考になった。