🫵

Go 1.11以上のプロジェクトルートディレクトリを探す方法

2023/05/14に公開

Go 1.11以上のプロジェクトルートディレクトリを探す方法を紹介します。
os.Getwd() で取得したワーキングディレクトリから、forループで下の階層に辿っていき、
go.modがあれば、そのディレクトリをプロジェクトルートディレクトリとして返します。

// ProjectRoot returns the project root directory abs path.
func ProjectRoot() string {
	currentDir, err := os.Getwd()
	if err != nil {
		return ""
	}

	for {
		_, err := os.ReadFile(filepath.Join(currentDir, "go.mod"))
		if os.IsNotExist(err) {
			if currentDir == filepath.Dir(currentDir) {
				return ""
			}
			currentDir = filepath.Dir(currentDir)
			continue
		} else if err != nil {
			return ""
		}
		break
	}
	return currentDir
}

つかいどころ

相対パスでファイルを読み込むコードが存在すると、子ディレクトリから実行した際にファイルが見つからずにエラーになることがあります。
プロジェクトルートの絶対パス + ファイルパスの形式でファイル読み込みできるようにしておけば
どのディレクトリからでもファイルを読み込むことができます。

参考

mockgenのコードを見ていて発見しました。

https://github.com/golang/mock/blob/5b455625bd2c8ffbcc0de6a0873f864ba3820904/mockgen/mockgen.go#L701-L721

Discussion