diff --git a/.github/workflows/CheckLicense.yml b/.github/workflows/CheckLicense.yml new file mode 100644 index 000000000..4a06708c0 --- /dev/null +++ b/.github/workflows/CheckLicense.yml @@ -0,0 +1,21 @@ +name: "Validate License Header" + +on: + push: + branches: [ main, develop, 'feature/**' ] + pull_request: + branches: [ main, develop, 'feature/**' ] + +jobs: + test: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1.8.1 + with: + dotnet-version: 5.0.301 + - name: Setup C# Interactive + run: dotnet tool install -g dotnet-script + - name: Validate + run: dotnet script Tools/LicenseHeader/Validate.csx . diff --git a/Tools/LicenseHeader/Validate.csx b/Tools/LicenseHeader/Validate.csx new file mode 100644 index 000000000..81b152402 --- /dev/null +++ b/Tools/LicenseHeader/Validate.csx @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#nullable enable + +if (Args.Count != 1) { + WriteLine("対象のディレクトリを指定してください。"); + return; +} + +string dir = Path.GetFullPath(Args[0]); +string[] files = Directory.GetFiles(dir, "*", SearchOption.AllDirectories); +var invalid_files = new List(); + +WriteLine("対象のディレクトリ:" + dir); +WriteLine(); + +for (int i = 0; i < files.Length; ++i) { + string file = files[i]; + string ext = Path.GetExtension(file); + WriteLine("\"{0}\" を確認しています . . .", file); + if (!Ignore(file) && ext is ".cs" or ".csx" or ".strings" or ".xml" or ".xaml" or ".resx" + or ".axml" or ".storyboard" or ".bat" or ".cmd" or ".sh" or ".tf" or ".yml" or ".feature") { + using (var fs = new FileStream(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) + using (var sr = new StreamReader(fs, true)) { + if (Validate(sr.ReadToEnd())) { + WriteLine("ライセンス通知は記述されています。"); + } else { + invalid_files.Add(file); + ForegroundColor = ConsoleColor.Red; + WriteLine("ライセンス通知は記述されていません。"); + ResetColor(); + } + } + } else { + WriteLine("このファイルは無視されます。"); + } + WriteLine(); +} + +WriteLine(); + +int count = invalid_files.Count; +if (count == 0) { + WriteLine("ライセンス通知は全てのファイルに記述されています。"); +} else { + var sb = new StringBuilder(); + sb.AppendLine("ライセンス通知が記述されていないファイルがあります。"); + for (int i = 0; i < count; ++i) { + sb.Append(" - ").AppendLine(invalid_files[i]); + } + ForegroundColor = ConsoleColor.Red; + WriteLine(sb.ToString()); + Environment.Exit(-1); +} + + +/*================================================================================================*/ + +const string HEADER_LINE_1 = "This Source Code Form is subject to the terms of the Mozilla Public"; +const string HEADER_LINE_2 = "License, v. 2.0. If a copy of the MPL was not distributed with this"; +const string HEADER_LINE_3 = "file, You can obtain one at http://mozilla.org/MPL/2.0/."; +const string HEADER_LINE_3s = "file, You can obtain one at https://mozilla.org/MPL/2.0/."; + +/// 検証 +public static bool Validate(string data) +{ + if ((data.Contains(HEADER_LINE_1) && data.Contains(HEADER_LINE_2)) && + (data.Contains(HEADER_LINE_3) || data.Contains(HEADER_LINE_3s))) { + return true; + } else { + return false; + } +} + +/// 除外設定 +public static bool Ignore(string file) +{ + return file.EndsWith(".designer.cs") + || file.EndsWith(".Designer.cs") + || file.EndsWith(".feature.cs") + || file.Contains("Xamarin.ExposureNotification") + || file.Contains("bin") + || file.Contains("Bin") + || file.Contains("obj") + || file.Contains("Obj") + || file.Contains(".github"); +}