🌺

初めてのコード規約作成

2023/12/11に公開

42Tokyo Advent Calendar 2023 の 11日目を担当する、42Tokyoの nakashi94(yutnakas) です。

入学時期は2023年5月ですが、東京都とから離れた場所に住んでいるので 42Tokyo の校舎にあまり行くことができず悲しいです。。。

昨日の記事
昨日は @nemukyoku(ふるまい) さんがHaskellで楽しむ抽象的なプログラミングという記事を書かれていました。
Haskellが関数型の言語というざっくりとした知識しかないので、自分の記事を投稿し終えたら読んでみようと思います!

概要

初めてのコード規約作成

コード規約とはを簡単に説明したのちに、Azure Pipelines で使用する、.azuredevopsディレクトリ内のコード規約について公開できる範囲でまとめます。

コード規約とは

コード規約とは、ソースコードを記述する際に則る規約で、コーディング際の共通の認識となるものです。

例えば、ディレクトリ構成やファイル、関数などの命名規則が挙げられ、特にチーム開発をするうえで定められます。

コード規約を定める目的

コード規約を定める目的は以下の三つが考えられます。

  • 可読性の向上
  • 保守性の向上
  • コミュニケーションコストの削減

可読性の向上

柔軟な書き方が可能なプログラミング言語を使用してソースコードを記述する場合、プログラマ個人の個性がソースコードに反映されます。
このプログラマの個性を抑えて、一貫性のある記述をすることでソースコードの可読性を向上させます。

例えば yaml ファイルで以下の記述は同様の意味を表します。

isSpace: true
isSpace: yes
isSpace: on

一見、柔軟な書き方をすることが可能なため便利そうに見えますが、これはチーム開発をするうえでは障害になる、プログラマの個性につながります。

実際に書き方を統一ていないチームと統一したチームのコードがそれぞれ以下の通りとします。

統一していない
isAscii:     yes
isLower:     on
isNumber:    true
isPrintable: no
isSpace:     off
isUpper:     false
統一している
isAscii:     true
isLower:     true
isNumber:    true
isPrintable: false
isSpace:     fasle
isUpper:     false

比較してみるとどちらのコードが可読性が高いか一目瞭然ですね。

このように、コード規約によって開発者の個性を抑えて一貫性の記述をすることで可読性が向上します。

保守性の向上

長期的な開発を進めていくうえで似たようなふるまいをする関数などが複数作成されたり、俗人化したコードが作成されたりします。しかし、コード規約によって特定のふるまいする関数がどこに存在するのか明確になり、かつ、コードの俗人化を抑制することができるため、保守性が向上します。

コミュニケーションコストの削減

ソースコードに変更を行う際に、意思決定を迅速に行うことが可能になり、コミュニケーションコストを削減することが可能になります。

例えば、コード規約が定められていない場合と定めらている場合について考えてみます。

コード規約が定められていない場合、プロジェクトのディレクトリ内に新たにディレクトリやファイルを作成する際に、チームメンバーに確認してから作成したり、コードレビューの際に議論をしたりと何かとコミュニケーションが発生します。

一方、コード規約が定められている場合は、個人での意思決定が可能となり、確認やコードレビューの際に発生するコミュニケーションコストを削減することができます。

Azure pipelines

https://azure.microsoft.com/ja-jp/products/devops/pipelines

https://learn.microsoft.com/ja-jp/azure/devops/pipelines/get-started/what-is-azure-pipelines?view=azure-devops

Azure Pipelines では、自動的にコード プロジェクトがビルドおよびテストされます。 すべての主要な言語とプロジェクトの種類がサポートされており、継続的インテグレーション、継続的デリバリー、継続的テストを組み合わせて、コードをビルドしてテストし、任意の宛先に配信します。

実際に適応したコード規約

ディレクトリ構成

作成したディレクトリ構成は以下のようになります。

.azuredevops/workflows
├── {機能1}
│   ├── data
│   ├── dev 
│   ├── prod
│   ├── srcs
│   ├── scripts
│   │   ├── bash
│   │   │   ├── bin
│   │   │   ├── lib
│   │   │   └── hoge.sh
│   │   └── powershell
│   │       ├── bin
│   │       ├── lib
│   │       └── hoge.ps1
│   └── templates
│
├── {機能2}
...

それぞれのディレクトリやファイルの説明は以下の通りです。

  • data: 定数を記述したファイルを配置するディレクトリ。
  • dev: 開発環境のパイプラインで使用する YAML ファイルを配置するディレクトリ。
  • prod: 本番環境のパイプラインで使用する YAML ファイルを配置するディレクトリ。
  • srcs: Powershell と Bash のスクリプト以外のプログラミング言語で記述されたスクリプトを配置するディレクトリ
  • scripts: Powershell と Bash のスクリプトを配置するディレクトリ
  • scripts/bash: Bash のスクリプトを配置するディレクトリ
  • scripts/bash/bin: Bash のスクリプト内で使用する実行ファイルを配置するディレクトリ
  • scripts/bash/lib: Bash のスクリプト内で使用する汎用的な関数を記述したファイルを配置するディレクトリ
  • scripts/bash/hoge.sh: YAML ファイルから呼び出される Bash のスクリプト
  • scripts/powershell: PowerShell のスクリプトを配置するディレクトリ
  • scripts/powershell/bin: PowerShell のスクリプト内で使用する実行ファイルを配置するディレクトリ
  • scripts/powershell/lib: PowerShell のスクリプト内で使用する汎用的な関数を記述したファイルを配置するディレクトリ
  • scripts/powershell/hoge.ps1: YAML ファイルから呼び出される PowerShell のスクリプト

対応したスクリプト

今回コード規約を適応したディレクトリ.azuredevopsには機能ごとに分割したディレクトリを含む、主に以下の3種類のファイルが含まれており、これらにコード規約を定めました。

  • PowerShell script
  • Bash script
  • YAML ファイル

これから実際に作成したコード規約の一部を種類ごとにまとめます。

コード規約

PowerShell script

  • 関数名はVerb-Nounの形式にする。
    Verbはpowershellで使用することを強く推奨されている動詞、パスカルケース推奨動詞
    Nounは名詞で操作するオブジェクト名、パスカルケース
    例)Add-Content : ファイルに書き込むスクリプトファイル名
    Get-ContentFromSharePoint : SharePointからファイルを取得するスクリプトファイル名
  • ファイル名も関数名と同様の形式で命名する
  • 変数名はキャメルケース
  • 引数受け渡し、受け取り、まとめられた変数宣言、初期化を行うときはは原則、変数をアルファベット順に並べる
  • その他コード規約はこちらのPSScriptAnalyzerのコード規約に従う

Bash script

  • ファイル名、関数名、変数名はすべて小文字でスネークケース
  • 引数受け渡し、受け取り、まとめられた変数宣言、初期化を行うときはは原則、変数をアルファベット順に並べる
  • その他のコード規約はこちらのShellCheckに従う

YAML ファイル

  • 引数受け渡し、受け取り、まとめられた変数宣言、初期化を行うときはは原則、変数をアルファベット順に並べる
  • templatesディレクトリ内のyamlファイルで親のyamlファイルからパラメータを受け取っている場合はprametersブロックを定義する
  • yamlファイルの定義はAzure Pipelineで使用されるJson Schemaに従って記述する

lint と formatter の導入

拡張機能をインストールする

今回作成したコード規約をコーディング時に反映させるために、VS Codeにlintとフォーマッターの拡張機能をインストールします。
インストールする拡張機能は以下の4つです。

  • ms-vscode.powershell
  • timonwong.shellcheck
  • foxundermoon.shell-format
  • redhat.vscode-yaml

settings.jsonを編集する

settings.jsonを例えば以下のように編集し、インストールした拡張機能をコーディング時に反映されるようにします。

settings.json
{
    ...
+   // powershell settings
+   "powershell.scriptAnalysis.settingsPath": "./.vscode/PSScriptAnalyzerSettings.psd1",
+   "powershell.scriptAnalysis.enable": true,
+   "[powershell]": {
+       "editor.defaultFormatter": "ms-vscode.powershell",
+       "editor.formatOnSave": true,
+       "editor.tabSize": 4
+   },
+   // bashscript settings
+   "shellcheck.enable": true,
+   "[shellscript]": {
+       "editor.defaultFormatter": "foxundermoon.shell-format",
+       "editor.formatOnSave": true,
+       "editor.tabSize": 2
+   },
+   // yamlfile settings
+   "yaml.format.enable": true,
+   "yaml.schemas": {
+       "https://raw.githubusercontent.com/TRUE84/azure-pipelines-vscode/master/service-schema.json": "/*"
+   },
+   "[yaml]":{
+       "editor.defaultFormatter": "redhat.vscode-yaml",
+       "editor.formatOnSave": true,
+       "editor.tabSize": 2
+   }
}

参考資料

おまけ1

Terraform のファイルに関する自動フォーマットに関して、こちらの拡張機能hashicorp.terraformを VS Code にインストールし、以下の設定をsettings.jsonに追記することで反映させることが可能になります。

settings.json
{
    ...
+   // terraform settings
+   "[terraform]": {
+       "editor.defaultFormatter": "hashicorp.terraform",
+       "editor.formatOnSave": true,
+       "editor.tabSize": 2
+   },
+   "[terraform-vars]": {
+       "editor.defaultFormatter": "hashicorp.terraform",
+       "editor.formatOnSave": true,
+       "editor.tabSize": 2
+   }
}

おまけ2

42Tokyo の 42Cursus 最初の課題でC言語の自作ライブラリを作成する課題があります。
こちらで作成した課題は長期間にわたって管理していくことになるので、独自のコード規約を適応させるべきですね。
例えば自分の場合だと、以下のような記述が混同しています。

if (hoge == NULL) {
	return (NULL)
}
if (piyo == NULL)
	return (NULL)

コーディングをしている最中は気にならなかったのですが、実際に自分で作成したコードを保守していくときに可読性に影響を与えます。
このようなところを簡易的なコード規約を作成して、それを遵守しながらコーディングする癖をつけていかないといけないなと改めて感じました。

Discussion