diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index aa4d6ea..5c6fb8c 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -6,31 +6,36 @@ "version": "5.12.0", "commands": [ "dotnet-gitversion" - ] + ], + "rollForward": false }, "thirdlicense": { "version": "1.3.1", "commands": [ "thirdlicense" - ] + ], + "rollForward": false }, "dotnet-reportgenerator-globaltool": { "version": "5.2.0", "commands": [ "reportgenerator" - ] + ], + "rollForward": false }, "docfx": { - "version": "2.74.0", + "version": "2.77.0", "commands": [ "docfx" - ] + ], + "rollForward": false }, "gitreleasemanager.tool": { "version": "0.16.0", "commands": [ "dotnet-gitreleasemanager" - ] + ], + "rollForward": false } } } \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index a99dd8d..929f75b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -241,6 +241,7 @@ dotnet_diagnostic.CA1303.severity = none # We don't translate exception and log dotnet_diagnostic.SA1025.severity = none # Allow spaces in comments to structure info dotnet_diagnostic.IDE0045.severity = suggestion # Simplify ifs dotnet_diagnostic.IDE0046.severity = suggestion # Simplify ifs +dotnet_diagnostic.IDE0057.severity = suggestion # Slice can be simplified ### StyleCop dotnet_diagnostic.SA1101.severity = none # Do not force to prefix local calls with 'this' @@ -267,6 +268,7 @@ dotnet_diagnostic.SA0001.severity = none # Disable documentation dotnet_diagnostic.SA1402.severity = none # Multiple types in the same file dotnet_diagnostic.SA1600.severity = none # Disable documentation dotnet_diagnostic.SA1601.severity = none # Disable documentation +dotnet_diagnostic.SA1602.severity = none # Disable documentation dotnet_diagnostic.SA1201.severity = none # Allow enums inside classes dotnet_diagnostic.S1144.severity = none # Remove unused setter dotnet_diagnostic.S2094.severity = none # Remove empty class diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index fad0d31..bd14c1d 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -15,7 +15,7 @@ jobs: name: "Build" uses: ./.github/workflows/build.yml with: - dotnet_version: '8.0.100' + dotnet_version: '8.0.401' # Preview release on push to develop only # Stable release on version tag push only @@ -25,7 +25,7 @@ jobs: needs: build uses: ./.github/workflows/deploy.yml with: - dotnet_version: '8.0.100' + dotnet_version: '8.0.401' azure_nuget_feed: 'https://pkgs.dev.azure.com/SceneGate/SceneGate/_packaging/SceneGate-Preview/nuget/v3/index.json' secrets: nuget_preview_token: "az" # Dummy values as we use Azure DevOps diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2f3fe24..7ebe64f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,10 +26,15 @@ jobs: lfs: true - name: "Setup .NET SDK" - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ inputs.dotnet_version }} + - name: "Setup .NET 6.0 SDK" + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '6.0.425' + - name: "Build and test" run: dotnet run --project build/orchestrator -- --target=Default --dotnet-configuration=Release env: @@ -43,7 +48,7 @@ jobs: - name: "Publish artifacts to CI" if: ${{ matrix.is_main_build }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: "Artifacts" retention-days: 7 @@ -53,6 +58,6 @@ jobs: - name: Publish docs artifact to CI if: ${{ matrix.is_main_build }} - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: path: build/artifacts/docs diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7039796..55b91e1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v4 push_artifacts: name: "Artifacts" @@ -44,13 +44,13 @@ jobs: fetch-depth: 0 # We need full history for version number - name: "Download artifacts" - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: "Artifacts" path: "./build/artifacts/" - name: "Setup .NET SDK" - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ inputs.dotnet_version }} diff --git a/.gitignore b/.gitignore index c414d09..b5b4377 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ build/temp/ .vs/ *.csproj.user *.DotSettings.user +launchSettings.json diff --git a/build/orchestrator/BuildSystem.csproj b/build/orchestrator/BuildSystem.csproj index 560a707..a633649 100644 --- a/build/orchestrator/BuildSystem.csproj +++ b/build/orchestrator/BuildSystem.csproj @@ -11,7 +11,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Cake.Frosting.PleOps.Recipe" Version="1.0.1" /> + <PackageReference Include="Cake.Frosting.PleOps.Recipe" Version="1.0.3" /> </ItemGroup> </Project> diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index cba8860..70f56bc 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -1,14 +1,14 @@ <Project> <!-- Centralize dependency management --> <ItemGroup> - <PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" /> - <PackageVersion Include="Yarhl" Version="4.0.0-preview.283" /> - <PackageVersion Include="YamlDotNet" Version="13.7.1" /> - <PackageVersion Include="FluentAssertions" Version="6.12.0" /> - <PackageVersion Include="nunit" Version="4.0.1" /> - <PackageVersion Include="NUnit3TestAdapter" Version="4.5.0" /> - <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> - <PackageVersion Include="coverlet.collector" Version="6.0.0" /> - <PackageVersion Include="SonarAnalyzer.CSharp" Version="9.15.0.81779" /> + <PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" /> + <PackageVersion Include="Yarhl" Version="4.0.0" /> + <PackageVersion Include="YamlDotNet" Version="16.1.0" /> + <PackageVersion Include="FluentAssertions" Version="6.12.1" /> + <PackageVersion Include="nunit" Version="4.2.2" /> + <PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" /> + <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> + <PackageVersion Include="coverlet.collector" Version="6.0.2" /> + <PackageVersion Include="SonarAnalyzer.CSharp" Version="9.32.0.97167" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/src/Lemon/Containers/Converters/BinaryExeFs2NodeContainer.cs b/src/Lemon/Containers/Converters/BinaryExeFs2NodeContainer.cs index 465a3f4..98d125c 100644 --- a/src/Lemon/Containers/Converters/BinaryExeFs2NodeContainer.cs +++ b/src/Lemon/Containers/Converters/BinaryExeFs2NodeContainer.cs @@ -88,7 +88,7 @@ public NodeContainerFormat Convert(BinaryFormat source) byte[] actual = ComputeHash(container.Root.Children[i].Stream); if (!expected.SequenceEqual(actual)) { - logger.LogWarning("Wrong hash for child {name}", container.Root.Children[i].Name); + logger.LogWarning("Wrong hash for child {Name}", container.Root.Children[i].Name); } } @@ -168,15 +168,15 @@ private static byte[] ComputeHash(DataStream stream) // Read the file in blocks of 64 KB (small enough for the SOH). stream.Position = 0; int offset = 0; + int read; byte[] buffer = new byte[1024 * 64]; while (offset + buffer.Length < stream.Length) { - stream.Read(buffer, 0, buffer.Length); - offset += sha.TransformBlock(buffer, 0, buffer.Length, buffer, 0); + read = stream.Read(buffer, 0, buffer.Length); + offset += sha.TransformBlock(buffer, 0, read, buffer, 0); } - int finalSize = (int)(stream.Length - offset); - stream.Read(buffer, 0, finalSize); - sha.TransformFinalBlock(buffer, 0, finalSize); + read = stream.Read(buffer); + sha.TransformFinalBlock(buffer, 0, read); hash = sha.Hash; } diff --git a/src/Lemon/Containers/Converters/BinaryIvfc2NodeContainer.cs b/src/Lemon/Containers/Converters/BinaryIvfc2NodeContainer.cs index d0b3762..c41555b 100644 --- a/src/Lemon/Containers/Converters/BinaryIvfc2NodeContainer.cs +++ b/src/Lemon/Containers/Converters/BinaryIvfc2NodeContainer.cs @@ -84,7 +84,7 @@ public NodeContainerFormat Convert(BinaryFormat source) uint version = reader.ReadUInt32(); if (version != SupportedVersion) { - logger.LogWarning("Unsupported version: {actual}, expecting {supported}.", version, SupportedVersion); + logger.LogWarning("Unsupported version: {Actual}, expecting {Supported}.", version, SupportedVersion); } // Level 0, 1 and 2 only contain SHA-256 hashes. We can skip diff --git a/src/Lemon/Containers/Converters/Ivfc/FileSystemWriter.cs b/src/Lemon/Containers/Converters/Ivfc/FileSystemWriter.cs index 8dcbaa6..21ce4cf 100644 --- a/src/Lemon/Containers/Converters/Ivfc/FileSystemWriter.cs +++ b/src/Lemon/Containers/Converters/Ivfc/FileSystemWriter.cs @@ -126,7 +126,7 @@ private void Analyze() info.Directories++; info.DirNamesLength += NameEncoding.GetByteCount(node.Name).Pad(0x04); } else if (node.Stream == null) { - logger.LogError("Node '{path}' is not a folder or a binary file.", node.Path); + logger.LogError("Node '{Path}' is not a folder or a binary file.", node.Path); } else { info.Files++; info.FileNamesLength += NameEncoding.GetByteCount(node.Name).Pad(0x04); diff --git a/src/Lemon/Containers/Converters/Ncch2Binary.cs b/src/Lemon/Containers/Converters/Ncch2Binary.cs index c195493..be7f177 100644 --- a/src/Lemon/Containers/Converters/Ncch2Binary.cs +++ b/src/Lemon/Containers/Converters/Ncch2Binary.cs @@ -36,9 +36,7 @@ namespace SceneGate.Lemon.Containers.Converters /// </summary> /// <remarks> /// <p>This converter expects to have a node with the following binary - /// children: header_data/partition_id, header_data/maker_code - /// header_data/version, header_data/program_id, header_data/product_code, - /// header_data/flag_(0 through 7), + /// children: /// extended_header (optional), access_descriptor (optional), sdk_info.txt (optional), /// logo.bin (optional), system (optional), rom (optional).</p> /// </remarks> @@ -147,10 +145,10 @@ public BinaryFormat Convert(Ncch source) return binary; } - private void WriteFile(DataWriter writer, Node file, bool isRequired = true) + private static void WriteFile(DataWriter writer, Node file, bool isRequired = true) { if (file == null && isRequired) { - throw new System.IO.FileNotFoundException("Missing NCCH file"); + throw new FileNotFoundException("Missing NCCH file"); } else if (file == null) { return; } @@ -162,7 +160,11 @@ private void WriteFile(DataWriter writer, Node file, bool isRequired = true) file.Stream.WriteTo(writer.Stream); } - private void WriteOffsetSizeAndData(DataWriter writer, Node file, int hashRegion = 0, bool hasHashRegion = false) + private static void WriteOffsetSizeAndData( + DataWriter writer, + Node file, + int hashRegion = 0, + bool hasHashRegion = false) { if (file != null) { long position = writer.Stream.Position; @@ -189,7 +191,11 @@ private void WriteOffsetSizeAndData(DataWriter writer, Node file, int hashRegion } } - private void WriteSHA256(DataWriter writer, Node file, int hashRegion = 0, bool hasHashRegion = false) + private static void WriteSHA256( + DataWriter writer, + Node file, + int hashRegion = 0, + bool hasHashRegion = false) { if (file is null) { writer.Write(new byte[0x20]); @@ -205,7 +211,10 @@ private void WriteSHA256(DataWriter writer, Node file, int hashRegion = 0, bool int hashSize = hashRegion * 0x200; byte[] buffer = new byte[hashSize]; file.Stream.Position = 0; - file.Stream.Read(buffer, 0, hashSize); + int read = file.Stream.Read(buffer, 0, hashSize); + if (read != hashSize) { + throw new EndOfStreamException(); + } writer.Write(sha256.ComputeHash(buffer)); } else { diff --git a/src/Lemon/Containers/Converters/NodeContainer2BinaryCia.cs b/src/Lemon/Containers/Converters/NodeContainer2BinaryCia.cs index 38abc23..773cd05 100644 --- a/src/Lemon/Containers/Converters/NodeContainer2BinaryCia.cs +++ b/src/Lemon/Containers/Converters/NodeContainer2BinaryCia.cs @@ -106,7 +106,7 @@ public BinaryFormat Convert(NodeContainerFormat source) return binary; } - private void WriteHeader(DataWriter writer, Node root) + private static void WriteHeader(DataWriter writer, Node root) { writer.Write(HeaderSize); writer.Write(CiaType); @@ -120,7 +120,7 @@ private void WriteHeader(DataWriter writer, Node root) writer.WritePadding(0x00, BlockSize); } - private void WriteFile(DataWriter writer, Node file, bool isRequired = true) + private static void WriteFile(DataWriter writer, Node file, bool isRequired = true) { if (file == null && isRequired) { throw new FileNotFoundException("Missing CIA file"); @@ -138,7 +138,7 @@ private void WriteFile(DataWriter writer, Node file, bool isRequired = true) writer.WritePadding(0x00, BlockSize); } - private void UpdateTitleMetadata(TitleMetadata title, Node content) + private static void UpdateTitleMetadata(TitleMetadata title, Node content) { // Update size and HASH title chunks (CIA content children) // The hashes of the records and TMD will be updated when writing. @@ -175,7 +175,7 @@ private static byte[] SHA256FromStream(DataStream stream) } } - private void WriteContent(DataWriter writer, Node content, TitleMetadata title) + private static void WriteContent(DataWriter writer, Node content, TitleMetadata title) { int contentBitset = 0; long contentSize = 0; diff --git a/src/nuget.config b/src/nuget.config index 402a95f..f3028dd 100644 --- a/src/nuget.config +++ b/src/nuget.config @@ -3,15 +3,10 @@ <packageSources> <clear/> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> - <add key="SceneGate-Preview" value="https://pkgs.dev.azure.com/SceneGate/SceneGate/_packaging/SceneGate-Preview/nuget/v3/index.json" /> </packageSources> <packageSourceMapping> <packageSource key="nuget.org"> <package pattern="*" /> </packageSource> - <packageSource key="SceneGate-Preview"> - <package pattern="Yarhl*" /> - <package pattern="Texim" /> - </packageSource> </packageSourceMapping> </configuration>