2025年3月26日水曜日

Windows で Gitea を試す

オンプレに Git サーバーを立てる機運だったので、 なるだけ簡単、かつ、Windows サーバーで動くやつとして Gitea を試す。

前提

  • OS: Windows 11 Pro 23H2 ビルド 22631.5039
  • Gitea: 1.23.5

ダウンロード

Gitea Official Website から Windows 版のバイナリをダウンロード。

名前を gitea.exe に変更し、 C:\gitea\gitea.exe に配置する。

初期設定

サーバーを起動し、アクセスする

以下コマンドで gitea サーバーを立ち上げ http://localhost:3000 へアクセスする。 初回アクセス時に初期設定を行うための画面が表示される。

.\gitea.exe web

初期設定入力

今回は以下の通り入力した。下記項目以外はデフォルト。

入力したら Giteaをインストール ボタンを押下。

必須設定

項目
データベースのタイプ SQLite3
パス C:\gitea\data\gitea.db
サイトタイトル Mikoto’s Gitea
リポジトリのルートパス C:\gitea\data\gitea-repositories
Git LFS ルートパス C:\g itea\data\lfs
実行ユーザー名 mikoto
サーバードメイン mnmain
SSHサーバーのポート 8022
Gitea HTTPポート 3000
GiteaのベースURL http://mnmain:3000/
ログの保存先パス C:\gitea\log

オプション設定 - サーバーと外部サービスの設定

項目
OpenIDを使ったサインインを有効にする チェックを外す
ページ閲覧にサインインが必要 チェックを入れる

オプション設定 - 管理者アカウントの設定

項目
管理者ユーザー名 mikoto
メールアドレス mikoto2000@gmail.com
パスワード ひみつ
パスワード確認 ひみつ

しばらくすると、管理者でログインした画面が表示されるが、ベース URL が違うため、改めて http://mnmain:3000 にアクセスしなおす。

HTTPS 設定

証明書の生成

なんと、自己証明書も作れちゃうらしい。

cd c:\gitea
.\gitea.exe cert --host mnmain --ca

設定ファイルの編集

C:\gitea\custom\conf\app.ini に設定ファイルがあるので、これを編集する。

今回編集するのは server セクション。

  • ROOT_URLhttphttps に変更
  • 以下 3 行を追加
    • PROTOCOL = https
    • CERT_FILE = C:\gitea\cert.pem
    • KEY_FILE = C:\gitea\key.pem

設定が完了したらもう一度 .\gitea.exe web を起動して https://mnmain:3000 にアクセス。

警告が出るが無視して進むと https で接続できる。

SSH サーバーの設定

Windows で実行する場合は、 Gitea 組み込みの SSH サーバーを使用するのが無難そうなので、その設定を行う。

組み込み SSH サーバーの有効化

C:\gitea\custom\conf\app.ini を編集する。

編集するのは SERVER セクション。 以下項目を追加する。

  • START_SSH_SERVER = true
    • 組み込み SSH サーバーを起動する

新規登録の禁止化

C:\gitea\custom\conf\app.ini を編集する。

DISABLE_REGISTRATIONtrue にする。

Windows サービス化

サービス化用に設定変更

C:\gitea\custom\conf\app.ini を編集する。

今回は RUN_USERmnmain$ (<コンピューター名>$) に修正。

サービスへの登録

コマンドプロンプト を管理者で開き、以下コマンドを実行。

sc.exe create gitea start= auto binPath= "\"c:\gitea\gitea.exe\" web --config \"c:\gitea\custom\conf\app.ini\""

後は Windows のサービスから 開始 を選択すれば OK.

公開鍵の登録

GitHub と同じで、 SSH 経由の操作は、公開鍵を用いて行われる。

公開鍵の登録方法は以下の通り。

  1. 右上の自分のアイコンをクリック -> 設定 -> SSH / GPG キー を選択
  2. SSHキーの管理キーを追加 ボタンを押下
  3. SSH の公開鍵を入力する

以上。

参考資料

変更履歴

日付 内容
2025/3/26 新規作成
2025/4/20 管理者ユーザーを明示的に追加する手順を追加
組み込み SSH サーバーによる接続について追加

Vim のマクロを使って気持ち良くなった話 - 表のデータを TS の enum にする

こんなデータから、こんなデータを作りたい

PDF に以下のような表がありました。

項目1 項目2
1
2
× 3

実際は行が 200 行くらいあります。

これを、以下のような TypeScript の enum にしたいのです。

enum Type {
    松 = 1;
    竹 = 2;
    梅 = 3;
}

どうやったか?

まず、 PDF の表から文字列をコピペすると、以下のようなテキストデータになりました。

松
〇
1
竹
〇
2
梅
×
3

これを、前述の enum の形式にして、 200@q で気持ちよくなりたいわけです。

処理する順番としては以下のようにしました。

  1. 「項目2」 を消す
  2. 「項目1」の行末尾に = を追加
  3. 「項目1」と「値」 の行を結合
  4. 「3.」で結合した末尾に ; を追加
  5. 次の行の先頭にカーソルを配置

こうしてできた文字列を enum 内にコピペしてフォーマッタをかければ enum 定義の完成です。

ではやってみましょう。

<ここにカーソルがある>松
〇
1
竹
〇
2
梅
×
3

という状態から始め、 jddk で「項目2」の行を削除します。(1.)

<ここにカーソルがある>松
1
竹
〇
2
梅
×
3

つづいて A = <Esc> で「項目1」の末尾に = を追加します。(2.)

すると以下の状態になりますになります。

松 = <ここにカーソルがある>
1
竹
〇
2
梅
×
3

J で行を結合します。(3.)

松 = <ここにカーソルがある>1
竹
〇
2
梅
×
3

A;<Esc> で末尾に ; を追加します。(4.)

松 = 1;<ここにカーソルがある>
竹
〇
2
梅
×
3

マクロの連続実行ができるように、j^ で次の行の先頭にカーソルを持っていきます。(5.)

松 = 1;
<ここにカーソルがある>竹
〇
2
梅
×
3

この操作を記録して、 200@q とかすれば、他の項目も全て enum の形式になります。やったね。

2025年3月19日水曜日

Vim のマクロを使って気持ち良くなった話 - モックの JSON データ作成・編集編

モックデータの新規作成

こんなデータを作りたい

ホストにぶら下がっているエッジが大量にあり、そのエッジのステータスを取得する API がある。 その API のモックデータを作りたい。

{
    "type", "電球",
    "number", 1,
    "name", "電球1",
},
{
    "type", "電球",
    "number", 2,
    "name", "電球2",
},
{
    "type", "電球",
    "number", 3,
    "name", "電球3",
},
... これが 120 個くらい続く

どうしたか?

何個かデータを追加していくと、キー操作のパターンが見えてきました。

{
    "type", "電球",
    "number", 1,
    "name", "電球1",
},
<ここにカーソルがある>{
    "type", "電球",
    "number", 2,
    "name", "電球2",
},

上記状態で、qqVjjjjyjjjjpjj<C-a>j<C-a>kkkq としたあと、 117@q と打って気持ちよくなりました。 (実際は何個かやって感覚をつかんでからなので、 114@q くらいだった気がする…)

モックデータの修正

こんなデータを作りたい、既にデータはある

先ほど作ったデータが、実は間違いでした…。 本当は「電球60個に人感センサ60個」なのでした。

{
    "type", "電球",
    "number", 1,
    "name", "電球1",
},
{
    "type", "電球",
    "number", 2,
    "name", "電球2",
},
{
    "type", "電球",
    "number", 3,
    "name", "電球3",
},
... これが 60 個続く
{
    "type", "人感センサ",
    "number", 61,
    "name", "人感センサ1",
},
{
    "type", "人感センサ",
    "number", 62,
    "name", "人感センサ2",
},
{
    "type", "人感センサ",
    "number", 63,
    "name", "人感センサ3",
},
... これが 60 個続く

どうしたか?

このデータだけ見ると、「人感センサについてさっきと同じことすればいいじゃん」と思うでしょう。その通りです。

ただ、考えるのが面倒でこのデータには入れていませんが、既に使われているモックデータのため、「type, name 以外のパラメーターを変更したくない」という制約があったのです。

なんでそんな状況になったか覚えていませんが、そんな状況だったのです。

という事で、制約を守った編集ができるような手順を、マクロ含みで考えました。

まずは、61 個目以降のtype, name の数値部分以外を人感センサに一括置換します。

そうすると、以下のようなデータになります。

{
    "type", "電球",
    "number", 1,
    "name", "電球1",

},
{
    "type", "電球",
    "number", 2,
    "name", "電球2",
},
{
    "type", "電球",
    "number", 3,
    "name", "電球3",
},
... これが 60 個続く
{
    "type", "人感センサ",
    "number", 61,
    "name", "人感センサ61",
},
{
    "type", "人感センサ",
    "number", 62,
    "name", "人感センサ62",
},
{
    "type", "人感センサ",
    "number", 63,
    "name", "人感センサ63",
},
... これが 60 個続く

後は簡単ですね。

以下の位置にカーソルを移動し、 qq60<C-x>jjjjj^q59@q で完了です。

{
    "type", "電球",
    "number", 1,
    "name", "電球1",
},
{
    "type", "電球",
    "number", 2,
    "name", "電球2",
},
{
    "type", "電球",
    "number", 3,
    "name", "電球3",
},
... これが 60 個続く
{
    "type", "人感センサ",
    "number", 61,
<ここにカーソルがある>    "name", "人感センサ61",
},
{
    "type", "人感センサ",
    "number", 62,
    "name", "人感センサ62",
},
{
    "type", "人感センサ",
    "number", 63,
    "name", "人感センサ63",
},
... これが 60 個続く

これで気持ちよくなれました。

以上です。

2025年3月15日土曜日

Maven で Servlet 開発する

新人研修で JSP&Servlet をやるっぽいので素振りをした。

前提

  • Docker: Docker version 27.4.0, build bde2b89
  • 使用コンテナ: maven:3, tomcat:11

compose.yaml の作成

services:
  app:
    image: maven:3
    volumes:
      - .:/workspaces
      # tomcat11 との共有ディレクトリ
      # ビルドした war ファイルをここに格納する
      - firststep-webapps:/tomcat-webapps
    command: "sleep infinity"
  tomcat:
    image: tomcat:11
    volumes:
      - firststep-webapps:/usr/local/tomcat/webapps
    ports:
      - 8080:8080
volumes:
  firststep-webapps:
    driver: local

開発環境の起動

docker compose up -d

開発環境へ接続

docker compose exec app bash

Maven プロジェクトの作成

ひな形の作成

mvn archetype:generate -DgroupId=dev.mikoto2000.study.servlet -DartifactId=firststep -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

ただし、このプロジェクトは依存が足りなかったり Servlet が jakarta になる前のものだったりするので、 pom.xmlweb.xml を修正する。

pom.xml の修正

${PROJECT_ROOT}/pom.xml に以下依存を追加する。

    <!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <version>6.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/jakarta.servlet.jsp.jstl/jakarta.servlet.jsp.jstl-api -->
    <dependency>
      <groupId>jakarta.servlet.jsp.jstl</groupId>
      <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
      <version>3.0.2</version>
    </dependency>

web.xml の修正

${PROJECT_ROOT}/src/main/webapp/WEB-INF/web.xml を修正。

before:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

after:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <display-name>MyApp</display-name>
</web-app>

開発

実装

${PROJECT_ROOT}/src/main/java/dev/mikoto2000/study/servlet/firststep/HelloServlet.java に Servlet を実装する。

package dev.mikoto2000.study.servlet.firststep;

import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
      response.setContentType("text/html;charset=UTF-8");
      response.getWriter().println("<h1>Hello, Servlet!</h1>");
  }
}

ビルド

mvn package

${PROJECT_ROOT}/target/firststep.war が作成される。

デプロイ

/tomcat-webapps が tomcat のアプリデプロイディレクトリと共有されているので、 war ファイルをそこにコピーする。

cp target/firststep.war /tomcat-webapps/

動作確認

http://localhost:8080/firststep/hello へアクセスすると、 Hello, Servlet! が表示される。

以上。