diff --git a/.github/workflows/githubactionsbuilds.yml b/.github/workflows/githubactionsbuilds.yml index 9461f78..b498c89 100644 --- a/.github/workflows/githubactionsbuilds.yml +++ b/.github/workflows/githubactionsbuilds.yml @@ -19,14 +19,15 @@ jobs: needs: generate_version_number runs-on: windows-2022 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup .NET Core @ Latest - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v3 with: - java-version: '15' # The JDK version to make available on the path. + distribution: 'zulu' + java-version: '19' # The JDK version to make available on the path. java-package: jdk # (jre, jdk, or jdk+fx) - defaults to jdk architecture: x64 # (x64 or x86) - defaults to x64 - name: Install tools @@ -51,7 +52,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: dotnet-sonarscanner end /d:sonar.login=${{secrets.SONARQUBETOKEN}} - name: Run CodeCov #codecov -f ".\DeveImageOptimizer.Tests\TestResults\Coverage\coverage.opencover.xml" - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v3 with: #token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos files: .\DeveImageOptimizer.Tests\TestResults\Coverage\coverage.opencover.xml # optional @@ -64,11 +65,11 @@ jobs: needs: generate_version_number runs-on: windows-2022 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 # We need to fetch the entire Git history in order to verify the authenticity. - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - name: Build with dotnet @@ -80,9 +81,9 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup .NET Core - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - name: dotnet restore @@ -96,9 +97,9 @@ jobs: needs: generate_version_number runs-on: windows-2022 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup .NET Core @ Latest - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: 7.0.x - name: dotnet restore @@ -115,15 +116,15 @@ jobs: run: .\Scripts\GoPackage.ps1 shell: powershell - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: DeveImageOptimizer7z path: ./Scripts/Output/DeveImageOptimizer.7z - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: DeveImageOptimizerZip path: ./Scripts/Output/DeveImageOptimizer.zip - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: DeveImageOptimizerNuGet path: | @@ -136,7 +137,7 @@ jobs: if: github.ref == 'refs/heads/master' steps: - name: Download all artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: path: ./artifacts/ @@ -175,7 +176,7 @@ jobs: if: github.ref == 'refs/heads/master' steps: - name: Download all artifacts - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: DeveImageOptimizerNuGet path: ./artifacts/DeveImageOptimizerNuGet/ diff --git a/.github/workflows/githubactionsdockertest.yml b/.github/workflows/githubactionsdockertest.yml index 49360c6..ad8abc5 100644 --- a/.github/workflows/githubactionsdockertest.yml +++ b/.github/workflows/githubactionsdockertest.yml @@ -21,7 +21,7 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v1 with: @@ -29,7 +29,7 @@ jobs: password: ${{ secrets.DOCKERHUBTOKEN }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:latest platforms: all @@ -37,7 +37,7 @@ jobs: run: echo ${{ steps.qemu.outputs.platforms }} - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Builder instance name run: echo ${{ steps.buildx.outputs.name }} - name: Available platforms @@ -52,7 +52,7 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v1 with: @@ -60,7 +60,7 @@ jobs: password: ${{ secrets.DOCKERHUBTOKEN }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:qemu-v5.2.0 platforms: all @@ -68,7 +68,7 @@ jobs: run: echo ${{ steps.qemu.outputs.platforms }} - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Builder instance name run: echo ${{ steps.buildx.outputs.name }} - name: Available platforms @@ -83,7 +83,7 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v1 with: @@ -91,7 +91,7 @@ jobs: password: ${{ secrets.DOCKERHUBTOKEN }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: crazymax/binfmt:v6.0.0-rc4 platforms: all @@ -99,7 +99,7 @@ jobs: run: echo ${{ steps.qemu.outputs.platforms }} - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Builder instance name run: echo ${{ steps.buildx.outputs.name }} - name: Available platforms @@ -114,7 +114,7 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v1 with: @@ -122,7 +122,7 @@ jobs: password: ${{ secrets.DOCKERHUBTOKEN }} - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:qemu-v6.0.0 platforms: all @@ -130,7 +130,7 @@ jobs: run: echo ${{ steps.qemu.outputs.platforms }} - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Builder instance name run: echo ${{ steps.buildx.outputs.name }} - name: Available platforms @@ -145,7 +145,7 @@ jobs: needs: generate_version_number runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Login to Docker Hub uses: docker/login-action@v1 with: @@ -156,7 +156,7 @@ jobs: docker run --rm --privileged aptman/qus -s -- -p - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Builder instance name run: echo ${{ steps.buildx.outputs.name }} - name: Available platforms @@ -171,10 +171,10 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:latest platforms: all @@ -188,10 +188,10 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:qemu-v5.2.0 platforms: all @@ -205,10 +205,10 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: crazymax/binfmt:v6.0.0-rc4 platforms: all @@ -222,10 +222,10 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up QEMU id: qemu - uses: docker/setup-qemu-action@v1 + uses: docker/setup-qemu-action@v2 with: image: tonistiigi/binfmt:qemu-v6.0.0 platforms: all @@ -239,7 +239,7 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup qus run: | docker run --rm --privileged aptman/qus -s -- -p @@ -253,7 +253,7 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Test docker run run: | docker pull --platform linux/arm64 devedse/deveimageoptimizerconsoleapp @@ -264,7 +264,7 @@ jobs: needs: [generate_version_number, build_docker_linux] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Test docker run run: | docker pull --platform linux/amd64 devedse/deveimageoptimizerconsoleapp @@ -275,7 +275,7 @@ jobs: needs: generate_version_number runs-on: windows-2022 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 # - name: Login to Docker Hub # uses: docker/login-action@v1 # with: @@ -285,7 +285,7 @@ jobs: run: echo ${{ secrets.DOCKERHUBTOKEN }} | docker login -u devedse --password-stdin # - name: Set up QEMU # id: qemu - # uses: docker/setup-qemu-action@v1 + # uses: docker/setup-qemu-action@v2 # with: # image: tonistiigi/binfmt:latest # platforms: all @@ -293,7 +293,7 @@ jobs: # run: echo ${{ steps.qemu.outputs.platforms }} # - name: Set up Docker Buildx # id: buildx - # uses: docker/setup-buildx-action@v1 + # uses: docker/setup-buildx-action@v2 # - name: Builder instance name # run: echo ${{ steps.buildx.outputs.name }} # - name: Available platforms diff --git a/DeveImageOptimizer.Tests/FileProcessingDirect/FileProcessorTests.cs b/DeveImageOptimizer.Tests/FileProcessingDirect/FileProcessorTests.cs index 24441bd..976dd8c 100644 --- a/DeveImageOptimizer.Tests/FileProcessingDirect/FileProcessorTests.cs +++ b/DeveImageOptimizer.Tests/FileProcessingDirect/FileProcessorTests.cs @@ -240,5 +240,75 @@ public async Task CorrectlyOptimizesCompleteDirectoryAndDoesntSkipFailedFilesInP Assert.Equal(1, results.Count(t => t.OptimizationResult == OptimizationResult.Failed)); } } + + + + [SkippableFact] + public async Task CorrectlyOptimizesCompleteDirectoryButDoesntOptimizePngIfConfigurationIsSetLikeThat() + { + var config = ConfigCreator.CreateTestConfig(false); + config.OptimizePng = false; + + var testName = $"{nameof(FileProcessorTests)}_{nameof(CorrectlyOptimizesCompleteDirectoryButDoesntOptimizePngIfConfigurationIsSetLikeThat)}"; + var fileNameFileProcessedStateRememberer = Path.Combine(FolderHelperMethods.Internal_AssemblyDirectory.Value, $"{testName}.txt"); + var fileNameDirProcessedStateRememberer = Path.Combine(FolderHelperMethods.Internal_AssemblyDirectory.Value, $"{testName}-dir.txt"); + + string sampleDirToOptimize = FileProcessingTestsHelpers.PrepareTestOptimizeDir("SampleDirToOptimize", fileNameFileProcessedStateRememberer, fileNameDirProcessedStateRememberer, testName); + + //Optimize first time + { + var rememberer = new FileProcessedStateRememberer(false, fileNameFileProcessedStateRememberer); + var dirRememberer = new DirProcessedStateRememberer(true, fileNameDirProcessedStateRememberer); + var fp = new DeveImageOptimizerProcessor(config, null, rememberer, dirRememberer); + + var results = (await fp.ProcessDirectory(sampleDirToOptimize)).ToList(); + + Assert.Equal(4, results.Count); + Assert.Equal(3, results.Count(t => t.OptimizationResult == OptimizationResult.Success)); + Assert.Equal(1, results.Count(t => t.OptimizationResult == OptimizationResult.Skipped)); + + foreach (var result in results.Where(t => t.OptimizationResult == OptimizationResult.Success)) + { + Assert.True(result.OriginalSize > result.OptimizedSize); + } + } + + //Optimize second time + { + var rememberer = new FileProcessedStateRememberer(false, fileNameFileProcessedStateRememberer); + var dirRememberer = new DirProcessedStateRememberer(true, fileNameDirProcessedStateRememberer); + var fp = new DeveImageOptimizerProcessor(config, null, rememberer, dirRememberer); + + var results = (await fp.ProcessDirectory(sampleDirToOptimize)).ToList(); + + Assert.Equal(4, results.Count); + foreach (var result in results) + { + Assert.Equal(OptimizationResult.Skipped, result.OptimizationResult); + Assert.True(result.OriginalSize == result.OptimizedSize); + } + } + + config.OptimizePng = true; + + //Optimize third time with config changed + { + var rememberer = new FileProcessedStateRememberer(false, fileNameFileProcessedStateRememberer); + var dirRememberer = new DirProcessedStateRememberer(true, fileNameDirProcessedStateRememberer); + var fp = new DeveImageOptimizerProcessor(config, null, rememberer, dirRememberer); + + var results = (await fp.ProcessDirectory(sampleDirToOptimize)).ToList(); + + Assert.Equal(4, results.Count); + + Assert.Equal(3, results.Count(t => t.OptimizationResult == OptimizationResult.Skipped)); + Assert.Equal(1, results.Count(t => t.OptimizationResult == OptimizationResult.Success)); + + foreach (var result in results.Where(t => t.OptimizationResult == OptimizationResult.Success)) + { + Assert.True(result.OriginalSize > result.OptimizedSize); + } + } + } } } diff --git a/DeveImageOptimizer/ConstantsFileExtensions.cs b/DeveImageOptimizer/ConstantsFileExtensions.cs index ae1ed13..08287a2 100644 --- a/DeveImageOptimizer/ConstantsFileExtensions.cs +++ b/DeveImageOptimizer/ConstantsFileExtensions.cs @@ -1,4 +1,7 @@ -using System.Linq; +using DeveImageOptimizer.FileProcessing; +using System.IO; +using System.Linq; +using static System.Net.Mime.MediaTypeNames; namespace DeveImageOptimizer { @@ -14,5 +17,33 @@ static ConstantsFileExtensions() { AllValidExtensions = JPGExtensions.Concat(PNGExtensions).Concat(GIFExtensions).Concat(BMPExtensions).ToArray(); } + + public static bool ShouldSkipBasedOnConfiguration(DeveImageOptimizerConfiguration configuration, string fileExtension) + { + var upperExt = fileExtension.ToUpper(); + + //Check skipping + switch (upperExt) + { + case var e when !configuration.OptimizeJpg && JPGExtensions.Contains(e.ToUpperInvariant()): + { + return true; + } + case var e when !configuration.OptimizePng && PNGExtensions.Contains(e.ToUpperInvariant()): + { + return true; + } + case var e when !configuration.OptimizeGif && GIFExtensions.Contains(e.ToUpperInvariant()): + { + return true; + } + case var e when !configuration.OptimizeBmp && BMPExtensions.Contains(e.ToUpperInvariant()): + { + return true; + } + } + + return false; + } } } diff --git a/DeveImageOptimizer/FileProcessing/DeveImageOptimizerConfiguration.cs b/DeveImageOptimizer/FileProcessing/DeveImageOptimizerConfiguration.cs index 569d2d5..990bfdf 100644 --- a/DeveImageOptimizer/FileProcessing/DeveImageOptimizerConfiguration.cs +++ b/DeveImageOptimizer/FileProcessing/DeveImageOptimizerConfiguration.cs @@ -59,5 +59,10 @@ public class DeveImageOptimizerConfiguration /// Whether to do a Pixel by Pixel comparison after every optimization step. This is a real debug feature that should not be used normally. /// public bool VerifyImageAfterEveryOptimizationStep { get; set; } = false; + + public bool OptimizeJpg { get; set; } = true; + public bool OptimizePng { get; set; } = true; + public bool OptimizeGif { get; set; } = true; + public bool OptimizeBmp { get; set; } = true; } } diff --git a/DeveImageOptimizer/FileProcessing/FileOptimizerProcessor.cs b/DeveImageOptimizer/FileProcessing/FileOptimizerProcessor.cs index 9f995ef..74f5c08 100644 --- a/DeveImageOptimizer/FileProcessing/FileOptimizerProcessor.cs +++ b/DeveImageOptimizer/FileProcessing/FileOptimizerProcessor.cs @@ -9,7 +9,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading.Tasks; +using static System.Net.Mime.MediaTypeNames; namespace DeveImageOptimizer.FileProcessing { @@ -32,6 +34,14 @@ public async Task OptimizeFile(OptimizableFile file) throw new FileOptimizerNotFoundException(Configuration.FileOptimizerPath); } + var ext = Path.GetExtension(file.Path).ToUpperInvariant(); + if (ConstantsFileExtensions.ShouldSkipBasedOnConfiguration(Configuration, ext)) + { + Console.WriteLine($"=== Skipping image: {file.Path} due to extension '{ext}' being disabled in configuration ==="); + file.SetSkipped(); + return; + } + var w = Stopwatch.StartNew(); var tempFiles = new List();