なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

dotnet build コマンドで特定のプロジェクトだけビルドから除外したい

例えば GitHub Actions などで定期的にビルドを行っている際、大部分は net8.0 だが特定のプロジェクトだけは net8.0-windows を指定している、などの理由で、ビルドから除外したいケースがあります。
そのとき、 Microsoft Learn では該当プロジェクトを除いたソリューション設定を作成するのを推奨している のですが、ビルド時に指定する Configuration を増やすのは、後々除外したいケースが増えた際、名前をどうする?とい風なのに陥りやすい気がするので、余り気乗りしません。
そこで、今回は sed コマンドである程度プログラマブルにビルドを制御する方法を紹介します。

Visual Studio ソリューションファイルは、以下のような形式のファイルです。

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34202.233
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Plana", "Plana\Plana.csproj", "{F95F626E-FB9F-4930-B531-61F87029751E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Plana.Desktop", "Plana.Desktop\Plana.Desktop.csproj", "{59CB28AE-0F24-4BA7-9243-3DB68105BB5C}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|Any CPU = Debug|Any CPU
        Release|Any CPU = Release|Any CPU
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {F95F626E-FB9F-4930-B531-61F87029751E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {F95F626E-FB9F-4930-B531-61F87029751E}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {F95F626E-FB9F-4930-B531-61F87029751E}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {F95F626E-FB9F-4930-B531-61F87029751E}.Release|Any CPU.Build.0 = Release|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Release|Any CPU.Build.0 = Release|Any CPU
        {59CB28AE-0F24-4BA7-9243-3DB68105BB5C}.Release|Any CPU.Deploy.0 = Release|Any CPU
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(NestedProjects) = preSolution
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {129FBC52-9058-4F4A-88B3-A23978C16A72}
    EndGlobalSection
EndGlobal

今回知る必要があるのは Project("{GUID}" = "{Project}", "{Path}", "{GUID}") の部分と、 {GUID}.{Configuration}|{Platform}.{Action} = {Configuration}|{Platform} の部分です。
前者はこのソリューションでビルドしたいプロジェクト (.csproj.vbproj) の設定であり、後者はどのようなビルド設定かを示します。

今回紹介する方法では、プロジェクト毎に割り振られる Project ID をベースに、これらの行を削除することで行います。
Project ID は Project の第三引数に指定されており、 GUID 形式となっています。
ちなみに第一引数はプロジェクトの形式であり、有志の方によってまとめられているので、詳しく知りたい方はこちらを参考にしてください。

同様に、ビルド設定の部分も第一引数......というよりかは先頭に存在している GUID がまさに Project ID なので、 Project ID をベースに検索することで、該当行を特定することが出来そうです。
そこでできあがったのが、以下のコマンドです:

sed -i '/^Project.*59CB28AE-0F24-4BA7-9243-3DB68105BB5C/{n;d}' ./src/Plana.sln
sed -i '/59CB28AE-0F24-4BA7-9243-3DB68105BB5C/d'               ./src/Plana.sln

ここでは Project ID = 59CB28AE-0F24-4BA7-9243-3DB68105BB5C である Plana.Desktop を対象に、プロジェクトを消します。
2 行目のコマンドは単純に GUID が含まれている行を消すだけ、1 行目は、 Project(...) で一致する行を探し、次の行に現れる EndProject を消しています。

あとは、この状態で dotnet build ./src/Plana.sln 等とすることで、該当プロジェクトを無効にした状態で --Configuration=Debug, --Configuration=Release ともに動作します。

ということで、メモでした。