以下の内容はhttps://tech.guitarrapc.com/entry/2025/02/20/235900より取得しました。


setup-dotnetと同じglobal.jsonの解釈をC#で用意する

GitHub Actionsのsetup-dotnetアクションは、global.jsonを解釈して.NET SDKをインストールできます。ただ、global.jsonサポートは限定的でバージョン直指定かrollForwardlatestFeatureのみ対応しています。 気まぐれでC#でもサクッと同じものを用意したのでメモにおいておきます。特に意味はないけど、setup-dotnetと同じ解釈をしつつ何かツールに組み込むなら使えるか?1

setup-dotnetのglobal.json解釈

setup-dotnetのglobal.json解釈は、getVersionFromGlobalJson関数で行っています。(ソースコード)

function getVersionFromGlobalJson(globalJsonPath: string): string {
  let version = '';
  const globalJson = JSON5.parse(
    // .trim() is necessary to strip BOM https://github.com/nodejs/node/issues/20649
    fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim(),
    // is necessary as JSON5 supports wider variety of options for numbers: https://www.npmjs.com/package/json5#numbers
    (key, value) => {
      if (key === 'version' || key === 'rollForward') return String(value);
      return value;
    }
  );
  if (globalJson.sdk && globalJson.sdk.version) {
    version = globalJson.sdk.version;
    const rollForward = globalJson.sdk.rollForward;
    if (rollForward && rollForward === 'latestFeature') {
      const [major, minor] = version.split('.');
      version = `${major}.${minor}`;
    }
  }
  return version;
}

C#ポート

C#でTypeScriptと同様の処理を書きます。

// port of TypeScript https://github.com/actions/setup-dotnet/blob/83c0c1a6c843e2d7e6b14cc940a4a8c77243829b/src/setup-dotnet.ts#L99C1-L119C2
using System.Text.Json;
using System.Text.Json.Serialization;

// global.json spec https://docs.microsoft.com/en-us/dotnet/core/tools/global-json
string GetVersionFromGlobalJson(string json)
{
    JsonSerializerOptions options = new()
    {
        ReadCommentHandling = JsonCommentHandling.Skip,
        AllowTrailingCommas = true,
    };
    options.Converters.Add(new JsonStringEnumConverter());
    GlobalJson globalJson = JsonSerializer.Deserialize<GlobalJson>(json, options)!;

    var version = "";
    if (globalJson.Sdk is { } sdk && sdk.Version is not null)
    {
        version = sdk.Version;
        var rollForawrd = sdk.RollForward;
        if (rollForawrd is not null && rollForawrd == GlobalJson.RollForwardType.latestFeature)
        {
            var split = sdk.Version.Split(".", StringSplitOptions.RemoveEmptyEntries);
            var (major, minor) = split.Length >= 2 ? (split[0], split[1]) : ("0", "0");
            version = $"{major}.{minor}";
        }
    }
    return version;
}

record GlobalJson()
{
    [JsonPropertyName("sdk")]
    public required SdkInfo Sdk { get; init; }

    public record SdkInfo()
    {
        [JsonPropertyName("version")]
        public string? Version { get; init; }

        [JsonPropertyName("allowPrerelease")]
        public bool? AllowPrerelease { get; init; }

        [JsonPropertyName("rollForward")]
        public RollForwardType? RollForward { get; init; }
    }

    public enum RollForwardType
    {
        patch,
        feature,
        minor,
        major,
        latestPatch,
        latestFeature,
        latestMinor,
        latestMajor,
        disable,
    }
}

呼び出してみましょう。

args = ["../../../../global.json"];
var filePath = Path.GetFullPath(args[0]);
if (!File.Exists(filePath))
{
    Console.WriteLine($"global.jsonが見つかりません。 {filePath}");
    return;
}

string json = File.ReadAllText(filePath);

var version = GetVersionFromGlobalJson(json);
Console.WriteLine(version);

以下のglobal.jsonなら、9.0.200が出力されます。

{
  "sdk": {
    "version": "9.0.200"
  }
}

以下のglobal.jsonなら、9.0が出力されます。

{
  "sdk": {
    "version": "9.0.103",
    "rollForward": "latestFeature"
  }
}

おまけ

latestFeature以外のバージョンをどう解決するかは、現在インストールされているdotnet sdk一覧やプロジェクトのTargetFrameworkも解釈が必要で面倒なんですね。なのでsetup-dotnetでもサポート薄い2のはなるほどという感じでした。やりやすくはなさそう。

おまけのおまけ

setup-dotnet的には、出力結果のバージョン文字列はinstall-dotnetのバージョン指定に使われています。(ソースコード)

dotnetInstaller = new DotnetCoreInstaller(version, quality);

渡し先のDotnetVersionResolver.createDotnetVersion()がdotnet-installへの引数解決場所で、なるほど地道だった。


  1. 使うのか?
  2. というかサポートしない



以上の内容はhttps://tech.guitarrapc.com/entry/2025/02/20/235900より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14