OmniAICreator/Qiita-1.07M huggingface dataset:
【Ubuntu22.04】VPNServerを立ててみた【OpenVPN】 

###   Ubuntu22.04でVPNServerを立てた経緯
自宅から別の拠点にあるPCにVPNでリモートデスクトップをしたいと思いました。
そのため別拠点のラズパイ4（Ubutnu22.04）にVPNserverを立てて、自宅PCとVPN接続してからラズパイ4と同じ拠点にあるPCにリモートデスクトップをします。

office365を契約していないのでchatgptさんに構成図を作図してもらいました。

現状のNW構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446740/07420369-ad40-4c7b-589a-3fcc6df4b8ba.png)

VPNありNW構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1446740/79d5331e-63fb-37c9-fbdf-0835d56767df.png)

セットアップの流れは以下の通りです。
1. OpenVPNとEasyRSAをインストール
2. server.confのセットアップ
3. EasyRSAで証明書を作成
4. OVPNファイルを作成

### 　1.OpenVPNとEasyRSAをインストール

OpenVPNのインストール
```conf
$ sudo apt update
$ sudo apt install openvpn
```

EasyRSAのインストール
```conf
$ sudo apt install easy-rsa
```

EasyRSAの設定ディレクトリを作成
```conf
$ sudo cp -r /usr/share/easy-rsa/ /etc/openvpn/
$ cd /etc/openvpn/easy-rsa
```

### 　2. server.confの記載内容
/etc/openvpn/server/server.conf に以下の内容を記載します。

```conf
# OpenVPNサーバーがリッスンするポート番号を指定します。
port 1194

# プロトコルを選択します（UDPが速く、推奨されます）。
proto udp

# ルーティングのためのTUNデバイスを使用します。
dev tun

# CA証明書へのパスを指定します。
ca /usr/share/easy-rsa/pki/ca.crt

# サーバー証明書へのパスを指定します。
cert /usr/share/easy-rsa/pki/issued/server1.crt

# サーバーの秘密鍵へのパスを指定します。
key /usr/share/easy-rsa/pki/private/server1.key

# Diffie-Hellmanパラメータへのパスを指定します。
dh /usr/share/easy-rsa/pki/dh.pem

# VPNのサブネットとネットマスクを指定します。
server 10.0.0.0 255.255.255.0

# クライアントと仮想IPアドレスの関連を記録します。
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# 接続のドロップを検出するためのkeepaliveパラメータを設定します。
keepalive 10 120

# TLS認証キーへのパスを指定します。
tls-auth /usr/share/easy-rsa/pki/ta.key 0

# 暗号化暗号を指定します。
cipher AES-256-CBC

# 再起動時にキーとトンネルが持続するようにします。
persist-key
persist-tun

# ステータスログファイルへのパスを指定します。
status /var/log/openvpn/openvpn-status.log

# ログの詳細レベルを設定します。
verb 3

# サーバーが再起動したときにクライアントに通知します。
explicit-exit-notify 1
```

### 　3. EasyRSAで証明書の作成方法

変数の初期化
```conf
$ cd /etc/openvpn/easy-rsa
$ cd source vars
```

Clean up any previous keys and certificates
変数の初期化
```conf
$ ./clean-all
```

ビルドCA (Certificate Authority)
```conf
$ ./build-ca
```

サーバー証明書とキーの作成
```conf
$ ./build-key-server server
```

Diffie-Hellmanキーの生成
```conf
$ ./build-dh
```

クライアント証明書とキーの作成
```conf
$ ./build-key client01
```

(オプション) タンネル用の静的キーを生成
```conf
$ ./build-key client01
```

### 　4. OVPNファイルの作成方法

OVPNファイルは、クライアントがVPNサーバーに接続するための設定ファイルです。以下は基本的なOVPNファイルの内容です。

/etc/openvpn/client01.ovpn ファイルを作成します。
```conf
client
dev tun
proto udp
remote YOUR_SERVER_IP 1194
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-CBC
verb 3
<ca>
[ここにca.crtの内容を貼り付け]
</ca>
<cert>
[ここにclient01.crtの内容を貼り付け]
</cert>
<key>
[ここにclient01.keyの内容を貼り付け]
</key>
<tls-auth>
[ta.key の内容をここにペースト, もし使用している場合]
</tls-auth>
WebページのSorryページをALBとLambdaのみで自動切替できるようにしてみた

目的
---
- ALB配下のEC2が全停止したらSorryページを表示

上記を実装するにあたり色々調べたが一か所に集約されていなかったため
記事にまとめてみようと思う。

前提
---
- 既に運用中のWebサイトがある
- WebサイトをAWSで構築している

利用するサービス
---
- ALB
- Lambda
- CloudWatch


実装方法
---

- ALB

まずALBのリスナールールに通常のWebサイトを
ターゲットとするルールに加えて、メンテナンスページ用のルールを
追加する。

①リスナールールの作成
　→条件に「パス」=「*」
　→「固定レスポンスを返す」を選択
　→レスポンスコード：503
　→メッセージの形式：text/html
　→レスポンス本文：以下参照

```html
<html>
  <head>
    <title>Sorry Page</title>
  </head>
  <body>
    <h1>Webサイト名を入力</h1>
    <p>現在、メンテナンス中です。以下の時間帯ではサービスがご利用いただけません<br />
    (毎日18:00～08:00)</p>
  </body>
</html>
```

以上で、ALBのリスナールールが追加された。


- Lambda

Lamndaに付与するIAMロールも念のため作成しておく。
IAMポリシーから以下のポリシーを選択して適当な名前でロール作成
・CloudWatchReadOnlyAccess
・CloudWatchLogsFullAccess
・AmazonEC2FullAccess

上記のポリシーを付与したIAMロールを作成したら
Lambda関数の作成に取り掛かる。

```python
import boto3

def lambda_handler(event, context):
    client = boto3.client('elbv2')

    #リスナールールの優先順位切替。（メンテナンスページ→通常ページへ切替）
    responce = client.set_rule_priorities(
        RulePriorities=[
            {
                'RuleArn': 'メンテナンスページ用のリスナールールのArn',
                #優先度に指定する値は通常のWebサイトよりも小さい値に設定する。
                #通常のWebページ用の優先度が100の場合は90などに設定
                'Priority': 90
            },
        ]
    )
    
    # 変更後の設定を表示
    result = client.describe_rules(
        ListenerArn='ALBリスナーのArn',
    )
        
    return result
```

同様に、Sorryページからの戻しのルールも作成するが
変更箇所は「Priority」の値のみ。
メンテナンス用ページの優先度を通常のWebページよりも大きい値に変更する。

※Lambdaの他の設定はすべてデフォルトのままでOK

以上でLambdaの設定が完了。


- CloudWatch
実はここが一番ハマった・・・。(どうでもいい)

【やりたいこと】
CloudWatchのルール(＝EventBridge)を利用して
特定のイベントが発生したらLambdaを呼び出して
ALBのリスナールールの優先度を変更したい。

結論としては以下で実装可能
まずはメンテナンスページへ移行する場合のルール
```json
{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"],
  "detail": {
    "state": ["stopped", "stopping"],
    "instance-id": ["EC2のインスタンスID","EC2のインスタンスID",･･･]
  }
}
```

※stoppedとstoppingを両方しているのは、
　計画的に停止した場合と障害等でザクっと落ちた場合を考慮。


次に通常ページに戻す場合のルールは以下
```json
{
  "source": ["aws.ec2"],
  "detail-type": ["EC2 Instance State-change Notification"],
  "detail": {
    "state": ["running"],
  }
}
```
インスタンスIDを指定していないのは任意のインスタンスが起動すれば
Webサイトは運用可能という考え方。


動作確認
---
マネコンよりEC2を停止してみる。
すると、「stopping」のルールに反応して
503ページを表示することなく、指定したメンテナンスページを表示することができた。

また、起動時は、EC2のステータスが「running」になるまで
メンテナンスページを表示し続けてくれ、runningになったタイミングで
Webページを表示することができた。


まとめ
---
今回、WebページのSorryページを作りたいとのご要望で
ALBの機能で簡単に実装することができた。
https(SSL)のサイトにも対応した手順となっているため
実運用でも活用できる内容ではないでしょうか？
ご参考になれば幸いです。



コメントやいいねをいただけると励みになりますのでお願いいたします。
Karpathy氏のTransformerのYoutubeビデオのコードに日本語コメントを追加しました。

ビデオリンク:

https://www.youtube.com/watch?v=kCc8FmEb1nY

日本語コメントが追加されているJupyter Notebook: https://github.com/nyck33/karpathy-builds-gpt-additional-notes/blob/master/ja_gpt_dev.ipynb

ビデオを見ながらフォローすれば分かりやすくなっていると思います。

カナダ国籍、英語ネイティブのプログラマーです:https://nyck33.github.io/2021_portfolio/
JAVA応用②

# 本日の課題
問題: 文字列内の"い"を"ゐ"に置き換えるプログラムを作成せよ

~~~
いか
赤いか
スルメいか
~~~~

## 例

~~~~java
package s;

import java.util.ArrayList;

public class q {

		public static void main(String[] args) {
			 ArrayList<String>list =new ArrayList<String>();
			 list.add("いか");
			 list.add("赤いか");
			 list.add("スルメいか");
		
			 for(int i=0;i<list.size();i++) {
				 String sq=list.get(i);
				 System.out.println(sq.replaceAll("い","ゐ"));
			 }
			 
			}

		}
~~~~

### 結果

~~~
ゐか
赤ゐか
スルメゐか
~~~~
本日の気付き:replaceAllを使うことでリスト内の表記を変更できる。

#### 応用

~~~~java
package s;

import java.util.ArrayList;

public class q2 {
		public static void main(String[] args) {
				 ArrayList<String>list =new ArrayList<String>();
				 list.add("烏賊");
				 list.add("赤烏賊");
				 list.add("スルメ烏賊");
			
				 for(int i=0;i<list.size();i++) {
					 String ika=list.get(i);
					 System.out.println(ika.replaceAll("烏賊","イカ"));
				 }
				 
				}

			}
~~~~

##### 結果
~~~
イカ
赤イカ
スルメイカ
~~~~


本日の学び: 漢字からひらがな、かたかな、文字数関係なく変更可能。
Azure Pipelinesでyarn auditを実行

yarn auditってつかってますか
yarn auditコマンドはpackageの脆弱性のチェックを出力してくれるコマンドですが、普段の開発では脆弱性を意識することは少ないと思います。
なのでpipelinesでやる


## サンプルのymlファイル
やっていることとしては、
・nodeをインストールし
・audit結果をHTML化してくれるpackageをインストールし
・auditを実行しつつHTML化し
・publishしpipelineの結果としてHTMLで見れるようにする
です。


```yml:audit.yml
trigger: none

pool:
  vmImage: ubuntu-latest

steps:
  - task: NodeTool@0
    inputs:
      versionSource: 'spec'
      versionSpec: '18.x'
      checkLatest: true
    displayName: 'Install Node.js'

  - script: yarn global add yarn-audit-html
    displayName: 'yarn install yarn-audit-html'

  - script: yarn audit --json | yarn-audit-html
    displayName: 'audit'

  - task: PublishHtmlReport@1
    inputs:
      reportDir: './yarn-audit.html'

  - script: yarn audit --json | yarn-audit-html --fatal-exit-code
    displayName: 'audit fatal'

```

### 結果のHTML出力のイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/ba3127fc-03d0-ac9b-8697-783acbc8fbe8.png)


### スケジュール実行は設定のTriggersからお好きに設定してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/14e85d1f-5c04-c147-bf9a-623995d4bcd2.png)
UIMenuをUIControl (UIView)から呼び出す

## はじめに

[UIMenu](https://developer.apple.com/documentation/uikit/uimenu) iOS13から利用可能なコンテナビューですが、iOS14から `UIButton` や `UIBarButtonItem` に [menu](https://developer.apple.com/documentation/uikit/uibutton/3601189-menu) プロパティが追加されるなど、より簡単に利用できるようになっている印象です。

```Swift
let sampleMenu = UIMenu(title: "sample menu", children: [
    UIAction(title: "1", handler: { _ in
        // action code
    }),
    UIAction(title: "2", handler: { _ in
        // action code
    }),
    UIAction(title: "3", handler: { _ in
        // action code
    }),

    //...
])

// UIButton
let button = UIButton()
button.menu = sampleMenu

// UIBarButtonItem
let barButton = UIBarButtonItem(systemItem: .action,
                                menu: sampleMenu)
```

カスタムボタンは、より汎用的に使えるように `UIControl` などで作成することも少なくないのではと思いますが、残念ながら `UIControl` は `menu` プロパティを持ちません。
本記事では、 `UIControl (UIView)` から `UIMenu` を呼び出す方法を書き留めておきます。

## `UIControl` にコンテキストメニューを追加する

基本的には公式ドキュメントの手順となります。
https://developer.apple.com/documentation/uikit/uicontrol/adding_context_menus_in_your_app#3698709

#### `UIContextMenuInteraction` の追加

```Swift
let menuButton = UIControl()
let interaction = UIContextMenuInteraction(delegate: self)
menuButton.addInteraction(interaction)
```

`UIControl` を長押しすると、アプリはデリゲートにコンテキストメニューを提供するよう求め、 `contextMenuInteraction(_:configurationForMenuAtLocation:)` を呼び出します。
このままだと、長押ししたときにのみメニューが表示されるので、タップしたときにも表示したい場合には以下の設定を追加します。

```Swift
menuButton.isContextMenuInteractionEnabled = true
menuButton.showsMenuAsPrimaryAction = true
```

デフォルトだと `isContextMenuInteractionEnabled` は `false` になっているようで、 [ドキュメント](https://developer.apple.com/documentation/uikit/uibutton/3601189-menu) によれば `UIButton` の `menu` プロパティを設定するとこちらのプロパティが自動で変更されるとのことですが、 `UIControl` を利用する場合は手動で設定してあげる必要があります。

#### `contextMenuInteraction` で表示したいメニューの設定

```Swift
override func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
    UIContextMenuConfiguration(identifier: nil,
                               previewProvider: nil,
                               actionProvider: { _ in
        // UIMenuにUIActionを設定する
        UIMenu(title: "",
               options: .displayInline, 
               children: [
            UIAction(title: "menu1") { _ in
                // action code
            },
            UIAction(title: "menu2") { _ in
                // action code
            },
            UIAction(title: "menu3") { _ in
                // action code
            }
        ])
    })
}
```

以上です。

## 最後に
`UIMenu` を `UIControl` から呼び出す方法について書きました。
`UIMenu` は非常に手軽にメニュー表示できるので、利用できる場面が多いのではないでしょうか。
カスタマイズ性はあまり高くないのですが、軽量に実装したいときには積極的に利用したいです。

## 参考文献

この記事は、以下の情報を参考に書きました。

- [Apple Developer - UIMenu](https://developer.apple.com/documentation/uikit/uimenu)
- [Apple Developer - menu](https://developer.apple.com/documentation/uikit/uibutton/3601189-menu)
- [Apple Developer - Add a Context Menu to a Control](https://developer.apple.com/documentation/uikit/uicontrol/adding_context_menus_in_your_app#3698709)
なぜ"Hello,  World!"なのか

**なんで"Hello, World!"なの？**

もはや、エンジニアの登竜門、義務教育的な存在になっている"Hello, World!"の出力。使い方としては、標準出力のチュートリアルとして共通となっています。!マークを付けるかどうか、大文字小文字など、微妙な違いや種類はあるものの、なぜかみんな世界に挨拶をしていますよね。

大抵のプログラミング言語の入門書では、このプログラムを作ることを最初の例題としており、新しくプログラミング言語を習得する際に最初に作るのがこのプログラムです。
そのため、「**世界一有名なプログラム**」と呼ばれることもあります。
こんなこと疑問に持つ人も少ないと思いますが、講義や参考書などでも教わっていなくて、気になったので調べてみました。

# Hello, World!の目的
以下、Wikipediaから一部抜粋。
> ハロー・ワールドは伝統的にプログラミング言語をプログラム初心者に紹介するために使われる。また、ハロー・ワールドはプログラミング言語が正しくインストールされていること、およびプログラミング言語の使用方法を理解するための健全性テストにも使用される。

上記にある通り、プログラミングの練習だけでなく、これからその環境を用いてプログラミングを行うための、動作テストのような役割も持っています。
確かに画面出力の観点で言えば、!マーク、半角スペース、大文字小文字などなど、正しく出力されれば、なんとなく安心感が湧いてきますよね。
C言語の参考書『プログラミング言語C』（第2版）では冒頭に「新しいプログラミング言語を学ぶ唯一の道は、それでプログラムを書いてみることである」との考えが示されていて、プログラムを入力して実行し、出力を確認することができれば、言語の他の要素を学ぶことは容易だとされています。

# Hello, World!の起源
この文言を使う習慣はブライアン・カーニハンとデニス・リッチーによる著書「プログラミング言語C」（**1978年**）からです。著者であるカーニハンは、インタビュー記事でこのように答えていました。
> 卵からヒヨコが出てくる漫画があるんだけど、それが Hello, World なんだ。

これに感化されて、彼はテスト文言にこれを使うことにしたのです。


実はこの前にも、カーニハンの「A Tutorial Introduction to the Language B」（**1973年**）での登場があったのですが、最初のプログラムは外部変数を説明するための例だったんです。(へー)
プログラムはターミナルに改行を含む「hello, world!」を出力するものだった。当時のB言語は文字数の長さがASCII文字の4文字までという制限があったため、この「hello, world!」はなんと、複数の文字列に分割されていたんです。最初は「hi!」を出力するもので、「hello, world!」という文言は、その応用編で複数の文字列を必要とする長い文章の出力として紹介されていました。

# スッキリしました
**プログラミングの世界の入ってきた人たちが、これからお世話になる世界に「Hello, World」と1行を作成する。まるで生まれたてのヒヨコのように。**
ChatGPTなどのAIや、自動車の自動運転技術などの最新技術を生みだしたエンジニアたちも、最初はこの一行から入ったのかな？と想像すると、我々もいろんなものを作れそうな気持ちになってきませんか？
LINEbotとMakeに苦戦

はじめての投稿（ドキドキ）
流行りの「ＤＸ」だの「システム」だのがついた部署に所属しておりますが、
エンジニアという訳でもなく、知識豊富という訳でもなく。
もっぱらシステム協力会社さんに色々と作ってもらうだけの毎日。

この度、機会に恵まれて研修でＬＩＮＥｂｏｔとＭａｋｅをお勉強。
オウム返や、天気予報をＡＰＩ連携させたり、感動したのもつかの間、、、宿題が出ました。

天気予報が一番便利なんだけどなぁ･･･と悩み
便利なものが良いんだろうな･･･と悩み
あれこれ過ごしていると、締め切りカウントダウン！

研修では、チームが編成され、出来るメンズ２名（デキメンと呼ぼう）のチームへ。
思えば、小学生の頃から宿題はのんびりしていた私。
そろそろやらねば。デキメン達が心配してくれている。
足を引っ張ってごめんよ。

良さげなＡＰＩを探しては、ふと気が付けば現実逃避。
ニャンチューバーの動画を見てほくそ笑んでいた。
カワイイものを見ると、ストレス軽減・若返りホルモンが出ると聞いてからは
毎日現実逃避。
そうだ、私の癒しの為ににゃんこの画像を連携させよう。
（あ、ちなみに、ネコ飼ってません。二本足で歩く日本語喋るペット２匹）
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516547/5818897e-bc20-377e-7a6a-b5454d409c43.png)


「ネコ」「ＡＰＩ」で検索してみた。
しめしめ、出てきた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516547/8a9f3864-6914-85dc-1e56-b3e8f4eaacbe.png)


英語のサイトだけど、フリーで連携できるようだ。
早速登録。

んーーーーーうまくいかない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516547/e3d75b4f-b58d-bc0f-b770-c471f7c672a5.png)

チョット、チョット、コレナンデスカ？
研修で見たことのないマークもついているじゃないか。
おまけに、数字もおかしい。
、、、、卒業できるのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516547/ca5f75ed-49f2-3996-ae02-3741675e2511.png)
わかるようでわからないWEB用語

今回はわかりそうでわからない、わかるようでわからないWEB用語をまとめてみました。
私自身がなんとなくわかった気になっていて詳細に説明が出来なかったので、メモがてら残します。

## コールバック関数
関数の中で呼ばれる関数のことであり、JavaScriptではDOM操作でよく利用されます。
```js
const func1 = (callback) => {
  console.log('このあとコールバック関数が呼び出されます。');
  callback();
};

const func2 = () => {
  console.log('コールバック関数です！');
}

func1(func2);
// 【出力結果】
// このあとコールバック関数が呼び出されます。
// コールバック関数です！
```

## フェッチとプリフェッチ
フェッチ（Fetch）もプリフェッチ（Prefetch）も、APIからリソースを取得する手法です。
フェッチは必要なリソースを取得するのに対して、プリフェッチは現在は必要ないが、将来的に必要となる可能性が高いリソースを背後で取得しておくことを言います。
また一般的にフェッチは`fetch関数`を用いるのに対し、プリフェッチは`link要素`を使用することができます。

## レンダリング
レンダリングとは、ブラウザがリソース（HTML、CSS、JavaScript）を受け取り、ユーザーが閲覧できるように解析して画面描写することを言います。

## 認証と認可
認証は主にログイン時に関わってきます。
ユーザー個々人のアイデンティティを確認するプロセスであり、そのユーザーが本当にアクセスしても良いユーザーであるかどうかを証明するのが認証です。
一方認可は、すでに認証されたユーザーに対して、特定のリソースや機能へのアクセス権限をそのユーザーに与えるか否かを決め、権限のないユーザーのアクセスを拒否する事ができます。
例）
AさんもBさんも、登録すればAmazonにログインでき、利用することが出来ます。（認証）
Aさんは自分自身の購入履歴を見ることは出来ますが、Bさんの購入履歴を見ることは出来ません。（認可）

## SaaS、PaaS、IaaS
SaaS、PaaS、IaaSはいずれもクラウドで提供されるクラウドサービスのことです。
違いはどこまでサービス提供者が運用管理をするかです。
SaaS、PaaS、IaaSの順でサービス提供者の管理範囲が大きいです。
### SaaS（Software as a Service）
ソフトウェアの更新からバグの修正まで、サービス提供者の方で行うので、利用者は、バージョン管理やバグを心配する必要がありません。つまりほぼお任せ状態なので、とても楽が出来るサービスです。
一方で自由度、カスタマイズ性に劣るので、差別化がしずらいです。
例えばGitHubやレンタルサーバーがこちらに当たります。

### PaaS（Platform as a Service）
開発環境までをサービス提供者で準備しているので、開発者は環境構築を気にすることなく開発を始めることが出来ます。
SaaSとは違い、アプリケーション部分は開発者にお任せで、面倒な環境構築の部分を担ってくれるので、SaaSに比べて自由度が高いです。
AWSの一部サービス（RDS等）がこちらに当たります。

### IaaS（Infrastructure as a Service）
ネットワーク、サーバなどの土台部分のみを準備します。もちろんPaaSよりも自由度が高く、カスタマイズ性も抜群です。
一方で、インフラ構築からアプリ開発までの幅広い知識が必要となります。
AWSの一部サービス（EC2等）がこちらに当たります。

## ライブラリとフレームワーク
ライブラリはそれ単体で開発することをターゲットにしておらず、開発の中で補完的な役割を担います。
部分的に使うことが容易であり、補助ツールとして様々な開発場面で役に立ちます。
また、一つのアプリ内に複数のライブラリが存在することも少なくありません。
ライブラリで有名なのに、jQueryとReactがあります。
フレームワークはそれ単体での開発も可能となっており、便利なライブラリを包括しているケースが多いです。
単体で高い完成度を誇り、ライブラリのように一つのアプリ内に複数のフレームワークが共存することはほとんどありません。
有名なのがRuby on railsや、Next.jsがあります。
spglibのcmakeでErrorが出た

# 問題
某スパコンでspglibのNov 6, 2022のverのコンパイルをするときにエラーが出た．"cmake .."のところで，次のError文を得た．
```cmake
ADD_LIBRARY called with SHARED option but the target platform does not support dynamic linking. Building a STATIC library instead. This may lead to problems.
```


# 解決方法
ここ([リンク](https://forum.psicode.org/t/cmake-error-during-psi4-core-configure-step/436))に載っていた．Crayコンパイラだとdynamicライブラリはどうやら無理？っぽい．cmakeのオプションでコンパイラをセッティングすることもできるっぽいけど([リンク](https://qiita.com/yoyomion/items/7974bb093038c21db26d))シンプルにIntelのコンパイラを設定すればいいやということで次のようにエイヤした．
```bash
export F90=ifort
export CC=icc
export CXX=icpc
```
別にF90とCXX必要ないはずだけど一応．
【学習】Linuxコマンド　Day1

# はじめに
はじめまして。
筆者は普段主にphpを用いてプログラミングを学習したり、Webアプリケーションを制作しています。が、先日、技術的にはサーバー構築について、また、これからのビジョンを話す機会があり、Linuxについての知識が不足している(しすぎてる)ことを実感し、"ただ自分の楽しくできる範囲でやっているだけじゃだめなんだぞ！"という意識が芽生え、最低でもLinuc lv1(101,102)くらいの知識、技能は習得しましょう。と思い立ち、このように記事を投稿していくこととしました。
# 今日学んだこと
- そもそもLinuxとは
- VirtualBoxを利用したテスト環境の作成
- viエディタの使い方(基本)
# そもそもLinuxとは
UNIXと同機能のOSを目指してリーナス・トーバルズという大学生(なんと一人)によって作られた。
様々なマシンのOSとして使用されており、無償、かつオープンソースであり、有志が開発に参加している。以下にLinuxのメリットとデメリットをざっと示す。
### メリット
- 無料
- スペックが低くても動作する

### デメリット
- サポートが比較的充実はしていない
- WindowsやMacに比べ直観的ではない
# テスト環境構築
見よう見まねではありますが、自分の所持しているWindowsから仮想マシンにてLinuxを動かせるようにするため以下の手順で行いました。

①OracleのHPからVirtualBoxをインストール→https://www.virtualbox.org/
②CentOS7をダウンロード→https://www.centos.org/download/
③VirtualBoxにて"新規"から仮想マシンを作成(以下は筆者が選択した内容)
- タイプ→Linux
- バージョン→Red Hat(64-bit)
- メモリーサイズ→2048MB
- ハードディスクのタイプ→VDI
- 仮想ハードディスクのサイズ→8GB

④設定→ストレージ→ディスクから②でDLしたisoを選択
⑤起動
⑥日本語を選択
⑦rootパスワードを設定(この場面でユーザを追加できますが、今回は行いませんでした。)
⑧rootで設定したパスワードを入力してログイン
⑨終わり
# viエディタを使ってみる
そもそも"viエディタ"という言葉を聞いてみてもピンと来なかったのですが、Linuxに標準で入っている文字だけのファイルを操作するためのテキストエディタの模様。もちろんコマンドラインから操作する必要がある。
まずは編集する対象のファイルが必要なので vi ●●.txtを入力、Enter。実際にエディタが開き、入力が可能となる。適当に文字を入力して以下のコマンドを試したので復習を兼ねて示しておく。
### 編集コマンド
```x```
→一文字消す
```dd```
→一行消す
```yy``` 
→一行コピー
```p```
→貼り付け
```o```
→次の行から入力
```a```
→カーソルの次の文字から入力
### ファイル操作
```:w```
→編集内容を保存
```:q```
→編集終了
```wq```
→保存して終了

# おつかれさまでした
初めてLinuxに触れてみたところ、コマンドを覚えないとスラスラと操作できるようにはならないと実感。ただし、暗記ではなく、実際に手を動かして体で覚えていく。ということが大事な気がした(ここはプログラミングと同じなのかな)
Qiitaの投稿も初めてでかつ有識者の方からすれば浅い内容だったかもしれないが、これも継続し、技能を身に着けるためのプロセスであることをお許しいただきたい。
OWASP ZAPをAzure Pipelinesで実行した

タイトルに記載の通りです。
Webアプリケーションの開発において脆弱性のチェックは頻繁にできる方がよいです。
なので色々調べてみてAzure pipielinesのreleasesの機能を利用してOWASP ZAPを日次実行するものを作り動作させました。

サンプルを丸ごと共有します。
## releses 画面
OWASP(名称任意)というレポジトリを作成しRootに「OWASPToNUnit3.xslt」というOWASP ZAPの診断結果XMLをNUnitに変換するxmlテンプレートファイルを置いておきます。
※2サイトに対して実行しているため2つ並んでいる
[参考URL](https://github.com/debolindhar/OWASPToNUnit3.xslt)

![OWASP_releases.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/c5cbcb8a-cf19-70b1-bd0a-49a0698361a3.png)

## job task1
Docker版のOWASPを実行するためにDockerをインストールする

![job1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/9082cc73-e68b-8d58-e775-b9a657cbd924.png)

## job task2
OWASP ZAPのdockerをpullしdocker runで対象とするサイトのURL(ここでは環境変数target_url)に対して実行する。
basic認証がある場合は環境変数baseを設定する

```bash
chmod -R 777  ./

docker run --rm -v $(pwd):/zap/wrk/:rw -t ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py -t $(target_url) -g gen.conf -x OWASP-ZAP-Report.xml -r scan-report.html -z " -config replacer.full_list\\(0\\).description=auth1 -config replacer.full_list\\(0\\).enabled=true -config replacer.full_list\\(0\\).matchtype=REQ_HEADER  -config replacer.full_list\\(0\\).matchstr=Authorization   -config replacer.full_list\\(0\\).regex=false  -config replacer.full_list\\(0\\).replacement=Base $(base)"
true
```

![job2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/460e9ca0-cf21-2f58-b31f-641bb4cc0aab.png)


## job task3
テンプレートを利用してNUnit形式で結果を出力する

```powershell
$XslPath = "$($Env:SYSTEM_DEFAULTWORKINGDIRECTORY)/$($Env:RELEASE_PRIMARYARTIFACTSOURCEALIAS)/OWASPToNUnit3.xslt"
$XmlInputPath = "$($Env:SYSTEM_DEFAULTWORKINGDIRECTORY)/OWASP-ZAP-Report.xml"
$XmlOutputPath = "$($Env:SYSTEM_DEFAULTWORKINGDIRECTORY)/Converted-OWASP-ZAP-Report.xml"
$XslTransform = New-Object System.Xml.Xsl.XslCompiledTransform
$XslTransform.Load($XslPath)
$XslTransform.Transform($XmlInputPath, $XmlOutputPath)
```

![job3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/c3bd8bf1-d1e4-5243-b9c7-02fd8dd351f3.png)

## job task4
Artifactにpublishする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/1bf214e7-f8d0-52bb-6084-a606674de970.png)

Artifact側のイメージはこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/d600f927-e13a-3ab7-ad01-9a83974703ba.png)


## job task5
Reportをpublishする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/284db40f-f50a-1ba6-84e9-10c9ea3bea4d.png)

## 実行後のイメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/c224fd84-654e-2faf-74db-5cc928d63a44.png)

- ×をクリックすると結果が表示できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476893/5d651bfa-d6f6-fcdb-5719-c33b5e8cac12.png)


## 参考にしたサイト
https://dzone.com/articles/owasp-zap-security-tests-in-azure-devops-pipeline
vue3のmyPluginをtypescriptで作る

nuxt3jsの場合もほぼ同じような作りです。

以下のようなtslintが反応する場合は、`declare module`が足りてない。
```
プロパティ '$myPlugin' は型 '{ $: ComponentInternalInstance; ...' に存在しません。ts(2339) 
```

```ts:main.ts
import App from '@/App.vue';
import { createApp } from 'vue';

import myPlugin from '@/plugins/myPlugin'

const app = createApp(App);
app.use(myPlugin);

app.mount('#app');
```

```ts:plugins/myplugin.ts
import { type Plugin } from 'vue';

declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $myPlugin: (msg: string) => string;
  }
}

const myFunctions = (key: string) => key + ':myplugin';

// for vue template
const myPlugin: Plugin = {
  install (app, options?: { [key: string]: any }) {
    app.config.globalProperties.$myplugin = (key: string) => myFunctions(key);
    app.provide('$myplugin', options);
  }
};

// for composables
export const $myplugin = (key: string): string => myFunctions(key);

export default myPlugin;
```

```vue:index.vue
<script setup lang="ts">
import { $myPlugin } from '@/plugins/myPlugin'
console.log($myplugin('aaa'))
</script>

<template>
  <div> {{ $myplugin('aaa') }} </div>
</template>
```
39歳微経験フリーランスエンジニアの生存戦略

37歳から未経験でエンジニアに転職し1年5ヵ月目でフリーランスエンジニアに転向したさわら(39歳)です。

先日、X(Twitter)で、

https://twitter.com/pvspqksRss1Na8n/status/1690916823506763776?s=20

と呟いてみたところ有難いことにたくさんの反応と有意義な意見を頂くことが出来ました。

私自身、なんとかエンジニアとしてのキャリアをスタートさせることが出来たものの、果たして、ここから1年後もエンジニアとしてやっていけているのか不安は尽きません。

曲がりなりにも即戦力を求められるフリーランスの私がこんなことを言うのはどうかと思うのですが、私はお世辞にもスキルのあるエンジニアではなく、正直なところ計画性も皆無で運と人当たりだけでなんとかやってきたようなところがあります。

そのため、エンジニアとしていかにバリューを出していくか、これはフリーランスエンジニアになる前、エンジニアに転職後の大きな課題でした。

そして、今後フリーランスエンジニアを続けていくにあたりこの課題はこれまでよりも重く圧し掛かってくることは明白です。

というわけで、1年後もエンジニア続けていけていられますように…という願いを込め、私なりのエンジニアとしての生存戦略を備忘録としてまとめておきます。

ちなみにエンジニアといっても多種多様かと思うのですが、後述する生存戦略はエンジニアリングと直接は関係のないところ（いってしまえばごくごく当たり前のこと）なので、私と同じWeb系のエンジニアじゃなくても転用可能かと思います。


# ■とにもかくにも隙間を見つけること
常にキャッチアップを続けることは当然として漠然とやっていても効率が悪いので、伸ばしていくべきスキルをどのように見つけるのか考えます。

## 1.周りをよく見る
慣れない内は目の前のタスクで手一杯になりがちですが、チームのメンバをよくみることは、とても大事だと思っています。ここでの着眼点はメンバのスキルセットです。誰が何が得意で何が苦手かということが分かれば、チームの生産性に寄与するためには、どこを伸ばすべきなのか見えてくるので、あとは、そこを重点的に強化することでバリューが出せるのではないかと考えます。

## 2.新しい技術は積極的に担当する
前述した周りをよくみるにも繋がる部分ですが、メンバのことをよく見ていると、そのプロジェクトや社内に、ある程度の知見あるような技術でバリューを出していくのは、正直、難しいと感じます。もちろん、微経験でも10年選手を相手に同じ土俵に立ってバチバチやれる人もいるのかも知れませんが、少なくとも私には無理です。そこで新しい取り組みについては積極的に担当することを心掛けるようにします。これにより自身の得意な土俵を作りながら皆の苦手を補うという組み合わせでバリューが出せるのではないかと考えます。

## 3.1と2のデメリット
1と2を実直に繰り返すことでバリューは出せるかも知れません。しかし、この戦略のデメリットは受動的である点です。どこを伸ばすとバリューが出せるのかというのは現場によるしチームによるので、適切に案件を選択しなくてはキャリア迷子のような状態に陥りやすいと思われます。特に未経験や微経験でアサインされる案件については選択肢も少ないので、ご縁だったり運で左右されてしまうところ大きいです。もし自身の望むスキルセットを実務で伸ばせない場合は業務外でやっていく、もしくは、力業ですが、アサインされたプロジェクトで自分のやりたい仕事を創出するくらいしかなさそうです。自分の伸ばしたいスキルと欲されているスキルがアンマッチだとモチベーションがあがらないというのも難点ですね。


# さいごに
1年後もエンジニア続けていられるように。【39歳微経験フリーランスエンジニアの生存戦略】を自分なりにまとめてみました。ここで挙げたことはごく普通の当たり前のことだとは思うのですが、そんな当たり前のことを実直にやっていくことが大切だということを自戒の意味を込め記しておきます。最後まで読んで頂きありがとうございます。1年後も元気でお会いできますように。
信頼チェーンとは

# 信頼チェーンとは何か
> 参考
> https://www.gleas.jp/news/column/certificate-chain/
>証明書チェーンとは、クライアント、サーバなどの証明書から、ルート認証局の認証局証明書までの連なりのことです。
>例えば、サーバ証明書が設定されているWebサーバに、ブラウザでアクセスすると、ブラウザはサーバ証明書の正当性を確認します。その正当性確認に使われるのが証明書チェーンです。本稿ではその仕組みを解説します。

例でいうと、あなたはブラウザーです。親友のAさん(ルート証明書)がおり、Aさんの親友Cさん(サーバ証明書)を紹介してもらいました。ブラウザーのあなたは、Aさんの紹介ならと思い、Aさんを信頼することでCさんを信頼するという連なるチェーンが作成されます。

本来の証明書では、AさんとCさんの間にBさんという(中間証明書)が存在します。これも同じで、Aさんの紹介Bさんを信頼して、Bさんの紹介Cさんを信頼するようになっております。

# 正当性の確認方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893794/96f2068d-3837-e3be-aebd-389aed9f87fb.png)
上記が、サーバ証明書(qiita.com)(Cさん)の詳細内容です。証明書の署名値というものが、Amazone RSA 2048 M01(Bさん)が信頼できる証として署名したものになります。中身はサーバ証明書(Cさん)の内容をハッシュ値に変換してBさんの秘密鍵でデジタル署名をしたものです。デジタル署名とは、秘密鍵でハッシュ値を暗号化したものです。
Bさんの公開鍵で復号化したハッシュ値とCさんの証明書のハッシュ値を比較して正当性の確認を行います。

Bさんの正当性の確認はAmazon Root CA 1(Aさん)の証明書の署名値で行います。Aさんが信頼できるかどうかはChromeの場合OSの証明書ストアにある証明書かどうかで正当性の判断を行います。証明書ストアにあるものは基本的に認証局が自らを保証する自己証明書があります。

上記のように正当性を判断を行います。

Bさんの公開鍵は基本的には、サーバ証明書をブラウザーに送信する際に一緒に中間証明書も送信します。なので、そこから公開鍵は取得することができます。

> 参考
> udemyのssl-complete
> https://www.udemy.com/course/ssl-complete-guide/
Android StudioでRの更新がされず、Unresolved referenceエラーが発生する

## はじめに
Android Studioでアプリ作成中に、色々触ってたら、Rの更新が行われずにビルドが通らなくなってしまいました。

## 開発環境
Windows 11 Pro
Android Studio Flamingo | 2022.2.1 Patch 2

## エラー状況

「ソース箇所」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/ed63a9a4-19a9-10ff-12d2-b0566a9af047.png)

「エラー内容」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/6999781a-8a05-8b8c-b9d6-87e979662c45.png)

「リソースファイル」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/8ca2d4a1-bf55-9448-91df-7c95228cb477.png)

## 調べてやったこと
正しい箇所に設置してあるし、クリーンビルドもキャッシュの破棄も、IDEの再起動もやった。
でもエラーが取れない。

## 結論
いつのまにか、android.R がインポートされてたため、Rがリソースファイルの参照を出来ていなかった！！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/93f34150-81c9-0e55-b5fd-5d75dffda6d6.png)

これを消すことによって、正しくリソースファイルが参照できるようになりました。
結構調べたけど、この結論にたどり着かなかったので、メモしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/9fd09df5-1835-173b-3131-866fee1e563f.png)


以上
スクロールバーのカスタマイズ方法


## はじめに　

設定した背景色にデフォルトのスクロールバーが合わなかったので、スクロールバーをカスタマイズする方法を調べました。

環境：　　
```json:package.json
"dependencies": {
    "react": "^18.2.0",
    "@chakra-ui/react": "^2.7.1",
    "@emotion/react": "^11.11.1",
  }
```

## CSSの適用方法　　

ReactにCSSを適用する方法は色々あるようです。　　
今回は、Chakra UIをインストールする際、同時にインストールしたEmotionを使っての方法にしました。　　

適用例：
```jsx:MyComponent.jsx
import { Text } from "@chakra-ui/react";
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <Text
      css={css`
        color: red;
      `}
    >
      赤色です。
    </Text>
  );
}

```

## スクロールバーのカスタマイズ　

WebKitベースのブラウザ（Chrome、Safariなど）と、Firefoxとで適用方法が異なります。　　

#### ::-webkit-scrollbar や ::-webkit-scrollbar-thumb など

FirefoxとiOS以外で対応しています[^1]。

#### scrollbar-width と scrollbar-color

Firefoxで対応しています[^2][^3]。

すべてのブラウザに対して共通の設定は難しいようなので、同じ項目の設定を繰り返す必要がありそうです。　　
しかし、設定内容がブラウザごとに異なるため、完全に一致させることはできないようです。　　

スクロールバーカスタマイズ例：　　

```jsx:MyComponent.jsx
import { Box } from "@chakra-ui/react";
import { css } from "@emotion/react";

function MyComponent() {
  return (
    <Box
      overflowY="auto"
      css={css`
        /* Chrome, Safari, ... */
        &::-webkit-scrollbar {
          width: 7px;
        }
        &::-webkit-scrollbar-thumb {
          background-color: #718096;
          border-radius: 5px;
        }
        /* Firefox */
        scrollbar-width: thin;
        scrollbar-color: #718096 transparent;
      `}
    >
      {/* 長い内容 */}
    </Box>
  );
}
```

### 各項目の説明

**&::-webkit-scrollbar**

```
&::-webkit-scrollbar {
  width: 7px;
}
```

この部分はWebKitベースのブラウザ（Google ChromeやSafari）に対してスクロールバーの幅を設定しています。

- width: 7px : これにより、スクロールバーの幅が7ピクセルに設定されます。

**&::-webkit-scrollbar-thumb**

```
&::-webkit-scrollbar-thumb {
  background-color: #718096;
  border-radius: 5px;
}
```

この部分は、WebKitベースのブラウザで、実際にユーザーがドラッグしてスクロールする際の「つまみ」部分（thumb）のスタイルを定義しています。

- background-color: #718096  
スクロールバーのつまみの背景色を設定しています。

- border-radius: 5px  
スクロールバーのつまみの角が丸くなり、5ピクセルの半径で丸みを帯びるよう設定しています。


**Firefox用のスタイル**

```
scrollbar-width: thin;
scrollbar-color: #718096 transparent;
```

Firefoxでは、scrollbar-widthプロパティを使用してスクロールバーの幅を制御します[^2]。しかし、WebKitベースのブラウザと異なり、具体的なピクセル数での指定はできません。　　
利用できるオプションはauto（ブラウザのデフォルト）、thin、noneの3つです。

- scrollbar-width: thin  
Firefoxでのスクロールバーの幅を狭く（細く）する設定です。

- scrollbar-color: #718096 transparent  
スクロールバーのつまみとトラック（背景）の色を設定しています[^3]。　　
つまみは#718096に、トラックは透明に設定されています。

## さいごに

ブラウザの対応状況を常に意識して情報収集する必要性を感じました。　
また、この記事を書くにあたりReactへのCSSの適用方法を改めて調べてみると、
思ったよりたくさんあったことに驚きました。
それぞれにメリットデメリットがあるようなので、実際に使って確かめてみようと思います。




[^1]: https://developer.mozilla.org/ja/docs/Web/CSS/::-webkit-scrollbar
[^2]: https://developer.mozilla.org/ja/docs/Web/CSS/scrollbar-width
[^3]: https://developer.mozilla.org/ja/docs/Web/CSS/scrollbar-color
ubuntu入れたらやることメモ

# Ubuntu入れたらやることメモ

１．ソフト導入・設定
* Opera導入
* アップデート（sudo apt -y update）
* sshサーバ導入（sudo apt -y install openssh-server）
* vi設定

２．VM設定
* ネットワークをブリッジ接続にする
* IP割り当てる
* ディスク接続
Vue RouterでAPIが404エラーになった場合エラー画面を表示する方法

## 初めに
Vue.js で 404 エラーが発生した場合、エラー画面を表示するための小ネタです。誰かのお役に立てれば幸いです。

## Vue Routerとは
Vue Router（ヴュールーター）は、Vue.js アプリケーション内でクライアント側のルーティングを管理するための公式ルーティングライブラリです。シングルページアプリケーション（SPA）を作成する際に、異なる URL パスに対して異なるコンポーネントを表示するための仕組みを提供します。

今回はRouterを利用して動的ルーティングで404エラー画面を表示します。

## 1．Vue Routerをインストール

```bash
npm install vue-router
```
## 2．Vue Routerの設定 (Vue2の場合)
```javascript
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import ErrorPage from '@/views/ErrorPage.vue';

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  // 他のルートをここに追加
   
  // 404 エラーページ用のルート
  {
    //Vue2の場合、'/*'だけでいい
    path: '/*',  // すべてのパスをキャッチ
    name: 'error',
    component: ErrorPage
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = Vue.createApp({})
app.use(router)

app.mount('#app')
```

## 2．Vue Routerの設定 (Vue3の場合)
```javascript
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
import ErrorPage from '@/views/ErrorPage.vue';

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  // 他のルートをここに追加
   
  // 404 エラーページ用のルート
  {
    //Vue3の場合、'/*'だけはだめ、正規表現を利用する
    path: '/:matchAll(.*)',  // すべてのパスをキャッチ
    name: 'error',
    component: ErrorPage
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes
});

const app = Vue.createApp({})
app.use(router)

app.mount('#app')
```
【さよなら】Firebase Dynamic Links は 25 年 8 月 25 日 にサポートが終了、その内容と代替はどうなる!?

Twitterを見ていたら流れてきた死刑宣告
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33505/4b626e22-4dcd-a2db-b4d2-9add87d08cbe.png" />
<font color="red">Firebase Dynamic Links は 2025 年 8 月 25 日に終了します。</font>

元々 Firebase Dynamic Links は 23 年 5 月 17 日に将来的にサービス廃止することは告知されていました。その後、詳細告知が 2023 年第 2 四半期 → 3 四半期に後ろ倒しになっていましたが、急に来たよ宣告告知。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33505/edf3b8bf-7994-c922-dbfe-63067d52756b.png" />

https://firebase.google.com/docs/dynamic-links?authuser=0&hl=en

※ なお日本語ページはまだ更新されていません（いつものこと

## 知っておくべきこと

##### 1. 2025 年 8 月 25 日になるとどうなるの？

Dynamic Links によって提供される<font color="red">すべてのリンクは機能しなくなり、クリックされたすべてのリンクは、HTTP 404 ステータス応答を返す</font>ようになる。

##### 2. いつまでに移行させる必要がある？

<font color="red">2025 年 8 月 25 日 MUST.</font>

※ iOS や Android アプリ内で利用している場合は、ストア公開後の浸透率を逆算してリリーススケジュールは組む必要があります。

##### 3. リンク分析データはどうなる？

2025 年 8 月 25 日に削除対象としてマークされ、<font color="red">[データ保持ポリシー](https://firebase.google.com/support/privacy?authuser=0&hl=ja#data_processing_information)に従って削除されます。</font>

それまでにリンク自体を含む Firebase Dynamic Links メタデータをエクスポートしておく必要があります。（エクスポートの方法は [エクスポートガイド](https://firebase.google.com/support/guides/export-dynamic-links?authuser=0) を見てね

##### 4. ただし無くならない機能もあるよ

それはメールリンク認証で使われている Firebase Authentication.

<font color="red">Firebase Authentication は現在、Firebase Dynamic Links を使用して Authentication リンクをカスタマイズしていますが、Firebase Dynamic Links サービスが廃止された後もこの機能が引き続き動作するように更新を提供されます。</font>

## 移行先のサービスは？

Google 的には他のディープリンクサービスのプロバイダー/ベンダーを使用することをお勧めしています。

ではどのプロバイダーを選べば良いのかは、Dynamic Links の機能をどこまで使っているかによると思います。Dynamic Links では基本 6 つの機能を提供しており、プロバイダーを含めた機能比較は次の通り。

Dynamic Links が提供している機能

* デバイスに適したストアにルーティング
* 遅延ディープリンクの提供
* 通常のディープリンクの提供
* クリックイベントの分析
* 短縮 URL を作成
* ソーシャル共有のためのメタデータの追加

代替プロバイダー ※ プロバイダーごとに利用は無料／有料などのプランがある

* Adjust
* AppsFlyer
* Bitly
* Branch
* Kochava

一応自社サービスで作るのもアリだが、そこはコスト等の兼ね合いですね。

## まとめ

今すぐどうこうの話ではありませんが、<font color="red">iOS・Androidで利用されているサービスは年内には方針を決めて対応を進めたほうが良さそう</font>ですね。

### 参考にさせて頂いたもの

* https://qiita.com/y-matsumoto/items/c244d6749f85165d8741
生成AIを使用してプログラミングに活用する例

生成AIを使用してプログラミングに活用する例を簡単にまとめました。
****
### 目次
- [コードのリファクタリング](#コードのリファクタリング)
- [変数名・メソッド名・クラス名などの命名](#変数名・メソッド名・クラス名などの命名)
- [お約束コードの生成](#お約束コードの生成)
- [要件を伝えてコード生成](#要件を伝えてコード生成)
- [番外編](#番外編)
****
## コードのリファクタリング
リファクタリングしたい該当のコードをペーストし、リファクタリングして、とChatGPTに投げれば、
すぐに読みやすいコードにリファクタリングしてくれます。
なので、コードが少し複雑な書き方になってしまい、もう少しシンプルに書けそうだけど書けない…みたいなときに生成AIに聞いてみると、良い答えが返ってくるかもしれません。
※リファクタリング後のコードが合っているかの精査は必要です。

## 変数名・メソッド名・クラス名などの命名
クラスや変数名で、「～を意味する変数名を考えて」や、
とある変数名をペーストし、「これよりもっといい変数名はある？」みたいな聞き方をすると、より良い名前を提示してくれる場合があるます。
また、[コードのリファクタリング](#コードのリファクタリング)の際に、生成AIがリファクタリングと一緒に変数名も修正してくれる場合もありました。

## お約束コードの生成
例えば、XMLのシリアライズやデシリアライズ、DB接続とか、
そういった色々なプロジェクトで同じように使われている
いわゆる「お約束コード」は、結構忘れていたりする部分もあり、
自分で書くと時間が掛かったりする場合もあると思うのですが、
生成AIで聞いてみると、良い感じに「お約束コード」を返してくれます。

## 要件を伝えてコード生成
要件をそのままChatGPTに書いて渡し、ChatGPTが書いたコードをベースに
少し修正していくというやり方です。
ただ、ChatGPTは表示できるコードの量も決まってので、
あまり多くの要件を一気に伝えずに、
要件の情報が多いと思った場合は区分けにして伝えると良い感じに返してくれると思います。

## 番外編
- ChatGPTの口調を変える
少し面白い使い方なのですが、返してくれる文章の口調は変更できます。
例えば、「・口調を侍風にして」「口調をお嬢様風にして」等を入力すると、口調を変えて話してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533049/c0d418ac-d91a-5e30-1218-e4181f966171.png)
シンボリックリンク備忘録

# はじめに
「git hooksについて知りたかったのにいつの間にかシンボリックリンクを調べていた！」
なんてことよくありますよね。

時間食っちゃうなぁ…とか思いつつ知識欲には抗えない…
## シンボリックリンクとは
>シンボリックリンクとは、オペレーティングシステム（OS）のファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。
>参照:[e-Words シンボリックリンクとは](https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF.html#:~:text=%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF%20%E3%80%90symbolic%20link%E3%80%91%20symlink,%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%E4%BB%95%E7%B5%84%E3%81%BF%E3%80%82)

何かのファイル、ディレクトリを参照できるファイルだよってことですね。
Windowsでいうショートカットにあたる。
### 利点
ディレクトリ構造が違っても容易にアクセスできる
毎回相対パスとか打つの面倒☞シンボリックリンクだと短い記述で住む
### 欠点
根本のファイルが消えたらアクセスできない
# Windowsで遊んでみた
参考記事:https://sologaku.com/pc/windows-how-to-create-symbolic-link/
環境:Windows10

はじめに、で述べたようにWindowsでのショートカットにあたる機能ですからGUIの操作で簡単に似たようなことはできるのですが逆張り大好きな我々にとってはCUIで回りくどくやるのが醍醐味というところです。

リンク先（参照したいファイル）をC:Users/user/test/test.txtとしました
☝にリンクしたファイルを保存するフォルダをC:Users/user/tempとしました
C/
│ 
└ Users
│　└ uer
│ 　 └ test
│ 　 │ 　└ test.txt 
│ 　 └ temp 

次に管理者権限でコマンドラインを開きます
コマンドは以下の通り
```
mklink　[オプション] [リンクしたファイル] [リンク先]
```
今回の場合☟(tempフォルダの下の階層に入力した文字がファイル名になります)
```
mklink C:\User\user\temp\new_link C:\User\users\test\test.txt
```
実行結果
```
C:\Users\user\temp\newlink <<===>> C:\Users\user\test\test のシンボリック リンクが作成されました
```
確認してみると、、
```
C:\WINDOWS\system32>dir C:\Users\user\temp

 C:\Users\user\temp のディレクトリ

2023/08/15  18:36    <DIR>          .
2023/08/15  18:36    <DIR>          ..
2023/08/15  18:34    <SYMLINK>      newlink2 [C:\Users\user\test\test.txt]
```
.symlink拡張子のtest.txtへのリンクがあるnewlinkファイルが作成されていることがわかります。
### フォルダのシンボリックリンクを作りたい時
```
mklink /D C:\User\user\temp\new_link C:\User\users\test\new_foldar
```
mklinkの後ろに/Dをつけます。
### リモート上のファイルのシンボリックリンクをローカルに作りたい時
参照:https://atmarkit.itmedia.co.jp/ait/articles/1306/28/news106.html

セキュリティの面で、デフォルトの状態ではリモートからローカルへのシンボリックリンクの作成はできないので設定を変更します。
`fsutil behavior query symlinkevaluation`と入力すると以下のように出ます。
```
C:\WINDOWS\system32>fsutil behavior query symlinkevaluation
ローカルからローカルへのシンボリック リンクは有効です。
ローカルからリモートへのシンボリック リンクは有効です。
リモートからローカルへのシンボリック リンクは有効です。
リモートからリモートへのシンボリック リンクは有効です。
```
`fsutil behavior set symlinkevaluation r2r:1 r2l:1`と入力すると、リモートからローカルでのシンボリックリンクの作成ができるようになります。

変更後☟
```
C:\WINDOWS\system32>fsutil behavior query symlinkevaluation
ローカルからローカルへのシンボリック リンクは有効です。
ローカルからリモートへのシンボリック リンクは有効です。
リモートからローカルへのシンボリック リンクは有効です。
リモートからリモートへのシンボリック リンクは有効です。
```
:::note info
意味
　`remote to remote`を有効(1)にします。
　`remote to local`を有効(1)にします。
:::
あとはローカル上で行ったようにコマンドを書けば動作します。
# 以上！
初めてQiitaでちゃんとした記事を書きました。
正確な情報を記述するよう心がけましたが、なにかおかしな点があればコメントお願いします。
拙い文章でしたが最後まで読んでくださりありがとうございました！
Linuxコマンドのエイリアス（alias）設定

# 概要
Linuxの全てのコマンドに対してエイリアス設定ができる。
これにより、コマンド入力の手間が省ける。

## 設定手順
1.ホームディレクトリに移動（cd ~）

2.現在のシェルのエイリアス一覧を確認
※デフォルトでも十分なくらい登録されている。
```
alias
```

3.シェルの種類を確認　※シェルによってエイリアス設定ファイルが異なるため 
```
echo $SHELL
```

4.シェル設定ファイルを開く
```
vim ~/.zshrc （zshの場合）
vim ~/.bashrc （bashの場合）
```
5.エイリアスの登録

サンプル
```
alias am='git commit --amend -m'
alias foreman='bundle exec foreman start -p 3000'
alias pop='git stash pop'
alias pull='git pull'
alias push='git push origin HEAD'
alias pushf='git push origin HEAD -f '
alias red='git rebase develop'
alias reh='gitreset --hard HEAD~'
alias res='gitreset --soft HEAD~'
alias re2='git rebase -i HEAD~2'
alias re3='git rebase -i HEAD~3'
alias re4='git rebase -i HEAD~4'
alias re5='git rebase -i HEAD~5'
alias sw='git switch'
alias swc='git switch -c'
alias swd='git switch develop'
```

6.ターミナルの再起動

7.エイリアスが登録されているか確認
```
alias
```
テスト駆動Pythonを読む

[テスト駆動Python 第2版](https://amzn.asia/d/azP1nlA) を読み始めた。
主な動機は、いまの案件でpytestを書く機会がたまにあるから。
テストの書き方もそうだけど、なにをテストするべきなのかとか、その辺も知っていけたら良いなと思っている。

pytestを使い倒したいとかはあまり思っていなくて、テストの考え方と、pytestの使い方を知りたい。
目次を見た感じ、Part 3はやらなくてよさそう。
Part 1, 2はかなり関心がある。特に、フィクスチャ、マーカー、モックはやっておきたい。

# テスト駆動Pythonの目次

[翔泳社](https://www.shoeisha.co.jp/book/detail/9784798177458) より引用

Part 1　pytestの主力機能 
第01章　はじめてのpytest 
第02章　テスト関数を書く 
第03章　pytestのフィクスチャ 
第04章　組み込みフィクスチャ 
第05章　パラメータ化 
第06章　マーカー 

Part 2　プロジェクトに取り組む 
第07章　戦略 
第08章　設定ファイル 
第09章　カバレッジ 
第10章　モック 
第11章　toxと継続的インテグレーション 
第12章　スクリプトとアプリケーションのテスト 
第13章　テストの失敗をデバッグする 

Part 3　ブースターロケット 
第14章　サードパーティプラグイン 
第15章　プラグインの作成 
第16章　高度なパラメータ化 

付録A　仮想環境 
付録B　pip
LSP参考リンク

[こちらの記事](https://qiita.com/www-tacos/items/23e63c4572c9f52b9825)でLanguage Serverを実装したときに参考にしたサイトメモを紹介しておきます。（記事にもいくつか書いてるので重複あるかも）

Python Language Server
---

https://github.com/palantir/python-language-server

https://github.com/palantir/python-jsonrpc-server

* VSCode用のPythonLSP拡張機能と、そこで使ってるJSON-RPCライブラリのセット
* これを読み解けば全部解決（読み解けるとは言ってない）

LSP仕様
---

https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/

* LSPのプロトコル仕様
* 結局、必要なJSONの形を知るには公式の仕様書を見るのが早くて確実

LSPクライアントの自作
---

https://qiita.com/vain0x/items/d050fe7c8b342ed2004e

* LSPクライアントとサーバ間通信を自作している（vscode-languageserverパッケージを使っていない）
* LSPのプロトコルについて詳しくなれそう
* 今回はクライアントがVSCode = Node.jsが動く前提なのでパッケージに頼ってよさそう？

LSP拡張機能の作成ガイド（公式）
---

https://code.visualstudio.com/api/language-extensions/language-server-extension-guide

* VSCode公式の、LSPを使った拡張機能を作るためのドキュメント
* 細かいところでわからない場合は参考になるかも、最初から参考にはならないかも

LSP拡張機能のお手軽開発例
---

https://qiita.com/Ikuyadeu/items/98458f9ab760d09660ff

* VSCodeでLSPを使った拡張機能の開発を（おそらく）最も手軽に体験できる記事
* クライアント側の仕様というか雰囲気がだいたいわかりそう
* 全部jsなのでフロント/バックのすみ分けは理解しにくいかも

言語サーバの作成例
---

https://qiita.com/lighttiger2505/items/5782debc59ae163a4d81

* JSじゃなくて別言語（今回だとSQL）の解析をNode.jsじゃなくて別サーバー（今回だとGoで作ったサーバ）に投げてJSON-RPCでやり取りする流れがみえそう

Python JSON-RPC
---

https://qiita.com/kagami-r0927/items/40f0b3b495313db3a8f8

* JSON-RPCを受け取るPythonサーバを作る参考になる
* サーバ側をPythonで作るってことはこれも必要なはず？→必要

以下は上記の記事で使ってるパッケージのレポジトリ

https://github.com/pavlov99/json-rpc

上のとは別のパッケージに関する参考記事もあり

~~https://scrapbox.io/tamago324vim/python-jsonrpc-server_を触ってみる~~ （消えてた...）

* 上記の記事で使われてるJSON-RPCのライブラリはVSCodeのPythonLSP拡張に使われてて、両方あわせて読むことで理解しやすかったので、使うなら後者の方がおすすめかも

拡張機能内からのCommand実行
---

https://stackoverflow.com/questions/43007267/how-to-run-a-system-command-from-vscode-extension

* VSCode Extension内部からコマンドを実行する参考になりそう
* ~~これでローカルサーバ立ち上げのpythonを実行する？~~ →内部的にはそうなのかもだけど、実際はclientライブラリが起動してくれる
【maven】jar とライブラリをまとめて展開用 zip 作成

## 概要
- バッチ用の jar を作成
- ライブラリの jar も lib ディレクトリにまとめて展開用 zip を作る
- 実行可能 jar ではない (Fat.jar, Uber.jar とは厳密には異なる)
- 実行する際は zip を unzip して展開後、java コマンドで
- java -cp "batch.jar;lib/*" <実行クラス> <パラメータ> として起動を想定

https://stackoverflow.com/questions/11947037/what-is-an-uber-jar-file

## 環境
- jdk 1.8
- maven 3
- maven-assembly-plugin 2.2

https://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html

## ローカルリポジトリがある場合
- 下記構成にしてプロジェクト内のローカル jar を取得可能
    - ${project.basedir}/lib/[localGroupId]/[localArtifactId]/[version]/[localArtifactId]-[version].jar

```pom.xml
	<repositories>
		<repository>
			<id>localRepositoryId</id>
			<name>localRepositoryName</name>
			<url>file://${project.basedir}/lib</url>
		</repository>
	</repositories>

    <dependencies>
		<dependency>
			<groupId>localGroupId</groupId>
			<artifactId>localArtifactId</artifactId>
			<version>1.0</version>
		</dependency>
    </dependencies>
```

## maven-jar-plugin
- pom.xml
```pom.xml
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<index>false</index>
						<manifest>
							<mainClass>[main.class.name]</mainClass>
							<addClasspath>true</addClasspath>
							<classpathPrefix>lib/</classpathPrefix>
						</manifest>
					</archive>
				</configuration>
			</plugin>
```

## maven-assembly-plugin 
- pom.xml 
```pom.xml
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-assembly-plugin</artifactId>
						<configuration>
                            <!-- ファイル名に余計な文字列を付加しない -->
							<appendAssemblyId>false</appendAssemblyId>
							<descriptors>
								<descriptor>assembly/assembly.xml</descriptor>
							</descriptors>
							<finalName>${project.artifactId}</finalName>
						</configuration>
						<executions>
							<execution>
								<phase>package</phase>
								<goals>
									<goal>single</goal>
								</goals>
							</execution>
						</executions>
					</plugin>
```

- assemby/assembly.xml
```assembly.xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
	<id>assembly</id>
	<formats>
		<format>zip</format>
	</formats>
	<includeBaseDirectory>false</includeBaseDirectory>
	<fileSets>
		<fileSet>
			<directory>target</directory>
			<outputDirectory></outputDirectory>
			<includes>
				<include>*.jar</include>
			</includes>
		</fileSet>
	</fileSets>
	<dependencySets>
		<dependencySet>
			<unpack>false</unpack>
			<scope>runtime</scope>
            <!-- 自身の jar は lib に入れない -->
			<useProjectArtifact>false</useProjectArtifact>
			<outputDirectory>lib</outputDirectory>
		</dependencySet>
	</dependencySets>
</assembly>

```

## 実行
```shell
mvn clean package -P [profile]
```

以上、お疲れ様でした！
【GitHub Copilot】複数候補を表示させる

# はじめに
こんな有益なツイートを見つけたので記事に記録しておきます

https://twitter.com/yuhattor/status/1691063796306165760?s=20

# やりかた
普通にCopilotを使います
![スクリーンショット 2023-08-15 18.55.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9c856475-a946-2ed6-7ace-434401d44804.png)

`control` + `Enter`を押します
しばらく待つと右側にたくさん出てきます
![スクリーンショット 2023-08-15 18.57.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/c5de4161-81a3-73d2-2883-f8224ac238bb.png)

# おわり
これは開発が捗りそうですね
CSVを取り込んだデータをNRQLで組み合わせる「LookupTable」

## 概要
New Relicに取り込んだデータを分析する際に使うクエリ言語「NRQL」ですが、例えばログに含まれた商品番号や店舗番号などを取り込まれたデータだけでは判断できず、別の表とつけ合わせて確認しなくてはならないので不便だと感じたことはありませんか？
この度、遂にNew RelicにCSVをアップロードできる機能「LookupTable」が追加されました！！
取り込んだCSVはJOIN句を使ってデータを連結することができますので、よりデータ分析がしやすくなります。

今回は、Logに含まれるステータスコードをあらかじめCSVに定義したわかりやすい説明にマッピングして、リスト化して表示する方法を例に、早速試してみたいと思います！

:::note info
このアップデートの詳細はこちら。
[New Relic アップデート(2023年6月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202306)
[New Relic アップデート](https://newrelic.com/jp/blog/nerdlog/new-relic-update "New Relic アップデート")
:::

## CSVをアップロードする
CSVは Logs -> Lookup tables からファイルをアップロードできます
![lookuptable_upload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/64d6ef14-f62a-bac1-c87a-ef1b0a42e383.png)
注意書きとして書かれていますが、アップロードされるTable情報は<B>難読化されません!</B>
なのでみられて困るようなデータは絶対にアップロードしないでください。
そのほかにもファイルサイズや最大行数などの制限があるので、詳細は[こちらのドキュメント](https://docs.newrelic.com/docs/logs/ui-data/lookup-tables-ui/#requirements)をご確認ください。
![lookuptable_attention.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/cf444e33-8131-c511-a295-3efdf9d61284.png)

取り込まれたデータの中身はNRQLで確認することができます。
![lookuptable_tabls.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/666d902b-8ea6-384b-df7c-e7ca900b0f15.png)
ちなみに今回の例でアップロードしたCSVファイルの中身はこちら
![lookuptable_csv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/e85ca1eb-4331-855f-2890-fe176c1c3432.png)

## CSVとNew Relicに取り込まれたデータをJoinする
では実際のデータと取り込んだCSVを連携させてみたいと思います。
ここで活用するのは先ほど出てきた「lookup」と「join」です。join句の使い方は[こちらの記事](https://qiita.com/T_OMORI/items/5c4f51ea1b3dc906940f)も合わせてみていただくとより使い方が理解できるますのでご参照ください。

例として先ほど確認したstatusCodotableが記載されているCSVファイルとログをJoinして、ステータスコードがどうゆうものなのかをわかりやすくまとめた表を作ってみます。
これはLogに含まれる「statusCode」とCSVファイルにある「status_code」を紐づけて表にしています。
![lookuptable_join.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/b5ad4f13-7fb5-19f5-df8b-2a7bd9c9a8a3.png)

断然わかりやすい！！！
「このStatus Codeの意味は？」とググらなくても大丈夫！
結果をダッシュボードに表示しておけば常にデータが確認しやすくなります。

こんな感じでNew Relicに含まれていないデータをCSVで取り込んで紐づけることが可能になります。
取り込んださまざまなデータの分析に是非ご活用ください！！

:::note info
このアップデートの詳細はこちら。[New Relic アップデート(2023年6月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202306)
:::
:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::
:::note info
[New Relic株式会社のQiita OrganizationOrganization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::
【Rails】マイグレーション入門～テーブルの作成とデータ型設定～

前回に引き続き、今回もRailsのマイグレーションについて紹介したいと思います。

#### 前回の記事

https://qiita.com/nakaizumi_slj/items/2f0c05d0465d95c5440b

この記事ではマイグレーション内でどのようにテーブルやカラムを作成、修正するかについて解説していきます。
# 目次
[テーブルの作成とカラムの追加](#テーブルの作成とカラムの追加)
[カラムのデータ型と制約](#カラムのデータ型と制約)
[マイグレーションの変更を追加する](#マイグレーションの変更を追加する)

# テーブルの作成とカラムの追加
マイグレーションファイル内では、`create_table`メソッドを使用してテーブルを作成し、そのテーブルにカラムを追加することができます。
以下は例えば"user"というテーブルを作成し、その中に"name"と"email"というカラムを追加することができます。
```ruby
class CreateUsers < ActiveRecord::Migration[7.0]
    def change
        create_table :users do |t|
            t.string :name
            t.string :email

            t.timestamps
        end
    end
end
```

上記のコードでは`create_table`メソッドのブロック内に`t.string :name`と`t.string :email`と記述されています。
これによって"user"テーブルに"name"と"email"というカラムが追加されます。


# カラムのデータ型と制約
カラムのデータ型や制約は、マイグレーションファイル内で設定することができます。
以下は、"posts"テーブルを作成し、その中に"title"カラムを追加する際に、データ型や制約を指定する例です。

```ruby
class CreatePosts < ActiveRecord::Migration[7.0]
    def change
        create_ table :posts do |t|
            t.string :title, null: false
            t.text :content

            t.timestamps
        end
    end
end
```

上記の例では、`t.string :title, null: false`という記述により、"title"カラムのデータ型は文字列で"null"制約が"false"に設定されていることを示しています。
また、`t.text :content`という記述により、"content"カラムのデータ型はテキストとなります。

以下はよく使われるデータ型です。
| 型名 | 定義| 
|:-----------|:-----------| 
string|文字列を表すデータ型。通常、短いテキストや名前などに使用されます。
text|長いテキストを表すデータ型。記事の本文やコメントなどに使用されます。
integer|整数を表すデータ型。IDやカウントなど整数値を保存するために使用されます。
float|浮動小数点数を表すデータ型。小数点以下の数値を格納する際に使用されます。
decimal|固定小数点数を表すデータ型。通常、通貨や数値計算などに使用されます。
boolean|真偽値を表すデータ型。trueまたはfalseの値を格納するために使用されます。
binary|バイナリーデータを表すデータ型。画像やファイルなどのバイナリーデータを格納する際に使用されます。
# マイグレーションの変更を追加する
すでに適用されたマイグレーションに後から変更を追加する際には、`change`メソッドの中に修正内容を記述します。以下は"user"テーブルにデータ型が"integer"の"age"カラムを追加する例です。
```ruby
class AddAgeToUsers < ActiveRecord::Migration[7.0]
    def change
        add_column :users, :age, :integer
    end
end
```
上記のコードでは`add_column`メソッドを使用して、既存のテーブルに新しいカラムを追加しています。
以下に示すのは`chenge`メソッドでサポートされているマイグレーション定義の一部です。
| 定義 | 内容| 
|:-----------|:-----------|  
|add_check_constraint|新しいチェック制約をテーブルに追加します
add_column|新しいカラムをテーブルに追加します
add_foreign_key|新しい外部キーをテーブルに追加します
add_index|新しいインデックスをテーブルに追加します
add_reference|新しい参照をテーブルに追加します
add_timestamps|タイムスタンプを追加します
change_column_default（:fromと:toの指定は省略不可） |カラムのデフォルト値を変更します
create_join_table|joinテーブルを作成します
create_table|テーブルを作成します
drop_join_table|joinテーブルを削除します
remove_column（型の指定が必須）|指定されたカラムをテーブル定義から削除します


#### 参考

https://api.rubyonrails.org/v7.0/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html

https://railsguides.jp/active_record_migrations.html