LangWar

https://github.com/jyogi-web/DDD_A-to-Z

Go

React

PHP

Elixir

PostgreSQL

推し技術で戦争

ウオミー

RiTa

ぎぷそ

アリス

推しアイデア

開発活動の実績(分析・貢献ポイント)を結びつけて継続したくなる動機を作っている。

作った背景

プログラミング言語戦争楽しいよね

推し技術

A~Zの技術たち nixで楽な環境構築

プロジェクト詳細

コンセプト

技術の論争が絶えない世の中で戦って欲しい

技術の無駄使いをしたい:A~Zから始まる技術を使う(その中のテーマD)

D要素

  • プロダクトのdomainを定義する
  • D言語

A〜Z 技術対応表

アルファベット当初現在状態
AAwkAwk, AtlasDONE
BBrainfuckBrainfuckDONE
CCSSCSSDONE
DDlangDlangDONE
EElixirElixirDONE
FFrankenPHPFrankenPHPDONE
GGolang, GoogleCloudGolang, GoogleCloudDONE
HHaskellHonoDONE
IIaCIaC (OpenTofu/Terraform)DONE
JJava, Jenkins, JavaScriptJavaScriptDONE
KKotlinknipDONE
LLisp, LuaLaravelDONE
MMoonbitMoonbitDONE
NNim, なでしこ, Nixなでしこ, NixDONE
OOCamlOCamlWIP
PPHPPHPDONE
QQwik, QlangQLangWIP
RReact, Rust, R, RubyReactDONE
SScala, Svelte, SwiftScala, Swift, Springboot未達成
TTypeScript, TerraformTypeScript, TerraformDONE
U未定udd-reporterDONE
VViteVite, VueDONE
WWhitespace, wasmWebAssemblyDONE
XX.comXStateDONE
YYewyamlDONE
ZZigZig未達成

達成率: 23 / 26(WIP: O, Q 未達成: S, Z)

このA-Z技術を実現するために

環境

開発環境作成には nix を用いる https://search.nixos.org/packages で探したら言語やcli系などはたいていの技術は見つかる それをflake.nix に追加し、nix develop と打てばサクッとその技術が入ったshell環境が出来上がる!

さらに、direnvを使用すれば nix developと打つことなく勝手にflake.nixを読み込んで適応してくれるので便利や〜

デプロイ環境

今回は主にGoogleCloudCloudRunにデプロイする CloudRunはコンテナを利用したデプロイなので各サービスごとにDockerfileを作成してあげるだけで大抵の技術は同じサービスでデプロイできるという親切さ(しかも安い)

Dockerfile書いてるからめんどくさいやんけ -> nixの定義からDockerfileを書き出せるっぽい? pkgs.dockerTools.buildImageとかかな 今回は複雑に絡み合って書かれているので不適切そうってので触ってない

また、Terraformを使用して誰でもデプロイしやすい環境を整備

技術ごとに書きたいことがあれば書く

Awk

テキスト処理に特化した、行単位のパターンマッチングと言語処理を行う UNIX 由来のプログラミング言語・ツール。ログ集計やデータ整形に広く使われる。

Go(実行部分)

//go:embed awk_engine/salt_mixer.awk var saltMixerScript string func (m *AwkTextMixer) Mix(ctx context.Context, input string, salt string) (string, error) { if ctx == nil { ctx = context.Background() } if m.command == "" { m.command = "awk" } if m.timeout > 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, m.timeout) defer cancel() } scriptPath, err := m.script() if err != nil { return "", err } command := exec.CommandContext(ctx, m.command, "-f", scriptPath) command.Env = append(os.Environ(), "SALT_MIXER_SALT="+salt) command.Stdin = strings.NewReader(input) var stdout bytes.Buffer var stderr bytes.Buffer command.Stdout = &stdout command.Stderr = &stderr if err := command.Run(); err != nil { if ctx.Err() != nil { return "", fmt.Errorf("mix text with awk: %w", ctx.Err()) } return "", fmt.Errorf("mix text with awk: %w: %s", err, strings.TrimSpace(stderr.String())) } return stdout.String(), nil }

Awk (ミックス処理)

BEGIN { salt = ENVIRON["SALT_MIXER_SALT"] } { if (NR > 1) { input = input "\n" } input = input $0 } END { for (i = length(input); i >= 1; i--) { reversed = reversed substr(input, i, 1) } for (i = 1; i <= length(reversed); i++) { output = output substr(reversed, i, 1) if (i % 3 == 0) { output = output salt_char(i) } } printf "%s::%d:%d", output, length(input), length(salt) } function salt_char(pos, salt_length, salt_index) { salt_length = length(salt) if (salt_length == 0) { return "" } salt_index = (pos % salt_length) + 1 return substr(salt, salt_index, 1) }

Go 側で AWK スクリプトを埋め込み、一時ファイルとして作成して awk -f で実行。input は標準入力、salt は環境変数 SALT_MIXER_SALT で渡す。タイムアウトも設定している。

AWK 側では入力全体を連結→逆順化→3文字ごとに salt の1文字を挿入し、最後に ::入力長:ソルト長 を付与。

Brainfuck

8つの命令だけで構成された、極端にミニマルな難解プログラミング言語。チューリング完全で、言語設計や計算モデルの学習目的に使われることが多い。

Brainfuck (実装で使用した部分)

VM (命令実行)

func ExecuteBF(code string, input string) (string, error) { jumps, err := buildJumpTable(code) if err != nil { return "", err } tape := make([]byte, tapeSize) inputBytes := []byte(input) output := make([]byte, 0, len(inputBytes)) var pc, ptr, inputPos, steps int for pc < len(code) { steps++ if steps > maxInstruction { return "", ErrStepLimit } switch code[pc] { case '+': tape[ptr]++ case '-': tape[ptr]-- case '>': ptr++ if ptr >= tapeSize { return "", ErrPointerBounds } case '<': ptr-- if ptr < 0 { return "", ErrPointerBounds } case '.': output = append(output, tape[ptr]) case ',': if inputPos < len(inputBytes) { tape[ptr] = inputBytes[inputPos] inputPos++ } else { tape[ptr] = 0 } case '[': if tape[ptr] == 0 { pc = jumps[pc] } case ']': if tape[ptr] != 0 { pc = jumps[pc] } } pc++ } return string(output), nil }

moonbit

WebAssembly (Wasm) および JavaScript 向けに特別に設計された、クラウドやエッジコンピューティング向けの新しいプログラミング言語・開発ツールチェーン

UDD(ユニコーン駆動開発)ライブラリ

UDDのススメ

Vitest拡張ライブラリ https://github.com/ryumasai/vitest-udd-reporter

テストが成功するまで「それでも!」諦めないでください

vitestv4に対応してなかったので自前で移植してます 後で本家にPR出したい

image

機能一覧

リポジトリ解析

image

開発をすることでCP(contribution point)とSP(skills point)を稼ぐ リポジトリを解析→1commit=1CP/1PR=5CP換算 SPは言語の使用割合で各言語ごとのポイントとして蓄積される

マイページ

image

  • GitHubAPIを通して取得したユーザーのgithub統計
  • 所属ギルドやCP残高、これまで稼いだ合計のCPなどの情報
  • BADGESでは獲得した称号一覧を閲覧

テックニュース

image ギルドページ左下のテックニュース 所属するギルドの技術に関するニュースが表示される RSSで公式サイトや公式ブログの情報を自動取得している クリックすると該当のサイトに飛ぶ。 ↓MORE NEWSを押すとさらに多くのニュースを確認することができる image 他ギルドの技術ニュースも確認可能

ウオミー

@KOU050223