Dotnet/Dotnet.psm1

enum ProjectType {
    Console
    ClassLibrary
    MinimalApi
    ControllerApi
}

function IsInGitRepo {
    try {
        git status 2>$null
        return $true
    }
    catch {
        return $false
    }
}

function New-CsSolution {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [ProjectType]
        $ProjectType,
        [Parameter(Mandatory = $false)]
        [string]
        $ProjectName = $null,
        [Parameter(Mandatory = $false)]
        [switch]
        $NoTestProject = $false,
        [Parameter(Mandatory = $false)]
        [string]
        $SdkVersion = "8.0.0"
    )

    $PSNativeCommandUseErrorActionPreference = $true
    $ErrorActionPreference = "Stop"
    Set-StrictMode -Version Latest

    $PSDefaultParameterValues['*:Encoding'] = 'utf8'
    $OutputEncoding = [System.Text.Encoding]::UTF8


    if (IsInGitRepo) {
        Write-Host "Cannot create solution in git repo" -ForegroundColor Red
        exit 1
    }

    if ([string]::IsNullOrWhiteSpace($ProjectName)) {
        Write-Host "No project name provided, using current folder name"
        $ProjectName = (Get-Location).Path.Split("\")[-1]
    }

    Write-Host "Using project name " -NoNewline
    Write-Host $ProjectName -ForegroundColor Yellow

    dotnet new globaljson --sdk-version $SdkVersion --roll-forward latestMinor | Write-Verbose
    dotnet new gitignore | Write-Verbose
    "`n# Verify.Net`n*.received.*" >> ".gitignore"

    Copy-Item (Join-Path $PSScriptRoot "template-files\editorconfig") "./.editorconfig"
    Write-Output "* text=auto" | Out-File ".gitattributes"

    dotnet new sln -n $ProjectName  | Write-Verbose

    Write-Host "Creating main project"
    switch ($ProjectType) {
        Console {
            dotnet new console -o $ProjectName | Write-Verbose
        }
        ClassLibrary {
            dotnet new classlib -o $ProjectName | Write-Verbose
        }
        MinimalApi {
            dotnet new webapi -o $ProjectName | Write-Verbose
        }
        ControllerApi {
            dotnet new webapi --use-controllers -o $ProjectName | Write-Verbose
        }
    }
    dotnet sln "$ProjectName.sln" add "$ProjectName" | Write-Verbose

    if (-not $NoTestProject) {
        Write-Host "Creating test project"

        dotnet new xunit -o "$ProjectName.Tests" | Write-Verbose
        dotnet sln "$ProjectName.sln" add "$ProjectName.Tests" | Write-Verbose
        Set-Location "$ProjectName.Tests"
        dotnet add reference "../$ProjectName" | Write-Verbose

        # Update all packages
        $listPackage = (dotnet list package --format json) | ConvertFrom-Json
        foreach ($package in $listPackage.projects[0].frameworks[0].topLevelPackages) {
            dotnet add package $($package.id) | Write-Verbose
        }

        # Coverlet
        dotnet add package coverlet.collector | Write-Verbose
        Copy-Item (Join-Path $PSScriptRoot "template-files\code-coverage.ps1") "./code-coverage.ps1"
        Copy-Item (Join-Path $PSScriptRoot "template-files\coverlet.runsettings.xml") "./coverlet.runsettings.xml"

        # Fluent Assertion
        dotnet add package FluentAssertions | Write-Verbose
        dotnet add package FluentAssertions.Analyzers | Write-Verbose

        # Verify
        dotnet add package Verify.Xunit | Write-Verbose

        if ($ProjectType -eq [ProjectType]::ControllerApi || $ProjectType -eq [ProjectType]::MinimalApi) {
            dotnet add package Microsoft.AspNetCore.Mvc.Testing | Write-Verbose

            $csProj = "./$ProjectName.Tests.csproj"
            $oldString = "Sdk=""Microsoft.NET.Sdk"""
            $newString = "Sdk=""Microsoft.NET.Sdk.Web"""
            (Get-Content -Raw $csProj) -replace $oldString, $newString | Set-Content $csProj
        }

        Set-Location ".."
    }

    git init

    Write-Host "Adding husky"
    dotnet new tool-manifest
    dotnet tool install Husky
    dotnet husky install
    dotnet husky add pre-commit -c "dotnet husky run --group pre-commit"
    dotnet husky add pre-push -c "dotnet husky run --group pre-push"
    Copy-Item (Join-Path $PSScriptRoot "template-files\husky-tasks.json") "./.husky/task-runner.json" -Force

    Write-Host "Adding report generator"
    dotnet tool install dotnet-reportgenerator-globaltool

    git add .
    git commit -m "Initial commit"
    git branch -m main
}