.

iT邦幫忙

1

把專案的Nuget套件替換成Source Code專案來Debug

  • 分享至 

  • xImage
  •  

前情提要

  • 問題起源:工作上平常開發的幾個專案,有個共用的元件,被抽出封裝成 Nuget 套件的形式在使用,因為日常開發經常需要改動這個共用元件,流程就會是:

    1. 先修改共用元件專案,發 PR 進 Code 後,發佈新的 NuGet 版本
    2. 再升級到使用該元件的專案繼續開發和測試
    3. 如果發現問題,就可能要再次重複前面的步驟來回一次
  • 我的痛點:有時候動到元件裡一些稍微複雜的功能,像第三方 API Client 的串接,就會一直來來回回,令我困擾的事就出現了,例如:

    • 本機測試來回:因為每次修改共用元件後,都需要重新升級 NuGet 套件版本,發佈後再回到主專案升級,才能測試功能是否正常,導致測試發現問題的時候,就要一直來回才能繼續測。
    • NuGet 套件是在進版後才發現問題:一直把沒有測過的功能上版,看著一堆修復的 commit 覺得無奈。
    • Debug 進不去共元元件裡面看(超困擾)
  • 結論:我有個夢想,我想在本機直接對 Nuget 套件 Debug,邊改邊測,直到功能正常再發共用元件的 PR,於是我寫了點 PowerShell~
    (也許 TDD 的開發模式,或是寫點 Mock Code 可以解決這個問題,但我不想更改我的夢想所以先放著(?


方法原理

目的:把專案的 Nuget 套件替換成 Source Code 專案來 Debug

  1. 使用 PowerShell,移除 NuGet 套件,改用參考專案的方式接上 Source Code
  2. 本機 Debug 開發測試
  3. 測試完再把參考專案移除,把 NuGet 套件復原

作法

  1. 移除 NuGet 套件,改用參考專案

    • 把下面內容存成.ps1檔,把前置參數設定好($pkgProjFile 和 $slnFile),執行
    # Set variables for the NuGet package and solution paths
    $pkgProjFile= "C:\......\XXX.csproj"  # 替換成 NuGet 原始碼專案路徑
    $slnFile = "C:\......\XXX.sln"  # 替換成你的使用端專案 Solution 路徑
    $pkgName = "XXXXXX"  # 替換成你的 NuGet 套件名稱
    
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    # Initialize an empty array to store project files that reference the NuGet package
    $projFilesToMunge = @()
    
    # Get all project files in the solution
    $projects = dotnet sln $slnFile list | ForEach-Object { $_ -replace '\s', '' } | Where-Object { $_ -like '*.csproj' }
    # Get the directory of the solution file
    $slnDirectory = Split-Path -Path $slnFile
    
    # Check each project for the NuGet package
    echo "正在尋找有引用 $pkgName 套件的專案..."
    foreach ($projFile in $projects) {
        $projFilePath = Join-Path -Path $slnDirectory -ChildPath $projFile
        echo "正在確認: $projFilePath"
        $packageList = dotnet list $projFilePath package
        $packageMatch = $packageList | Select-String -Pattern $pkgName
    
        if ($packageMatch) {
            # Add project file to the list if it references the NuGet package
            $projFilesToMunge += $projFilePath
        }
    }
    echo "需修改的專案:"
    echo $projFilesToMunge
    
    echo "添加專案 $pkgProjFile 到解決方案..."
    # Add the source code project to the solution
    dotnet sln $slnFile add $pkgProjFile 
    
    echo "開始替換nuget套件為實體專案..."
    # Remove NuGet package and add project reference for each project
    foreach ($projFile in $projFilesToMunge) {
       dotnet remove $projFile package $pkgName  # 移除 NuGet 套件
       dotnet add $projFile reference $pkgProjFile  # 添加專案引用
    }
    Write-Host "按 Enter 鍵結束..."
    Read-Host | Out-Null
    
  2. 本機 Debug 開發測試

    • 下中斷點,下監看式,找到誰忘了注入,找出誰變成null等.....
  3. 把參考專案移除,把 NuGet 套件還原

    • 把下面內容存成.ps1檔,把前置參數設定好($pkgProjFile 和 $slnFile),執行
    • PS:這步是直接使用 Git 的 discard change,復原.csproj檔,所以會提示是否真的要還原這些檔案,這個暫解是因為我在用 .dotnet 還原的時候一直無法成功。
    # Set variables for the NuGet package and solution paths
    $pkgProjFile= "C:\......\XXX.csproj"  # 替換成 NuGet 原始碼專案路徑
    $slnFile = "C:\......\XXX.sln"  # 替換成你的使用端專案 Solution 路徑
    $pkgName = "XXXXXX"  # 替換成你的 NuGet 套件名稱
    
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    # Initialize an empty array to store project files that reference the NuGet project
    $projFilesToMunge = @()
    
    # Get all project files in the solution
    $projects = dotnet sln $slnFile list | ForEach-Object { $_ -replace '\s', '' } | Where-Object { $_ -like '*.csproj' }
    # Get the directory of the solution file
    $slnDirectory = Split-Path -Path $slnFile
    
    # Check each project for the ProjectReference in the csproj file
    echo "正在尋找有引用 $pkgProjFile 的專案..."
    foreach ($projFile in $projects) {
        $projFilePath = Join-Path -Path $slnDirectory -ChildPath $projFile
        echo "正在確認: $projFilePath"
        $referenceList = dotnet list $projFilePath reference
    
        foreach ($reference in $referenceList) {
            # 只處理有效的路徑,排除非專案引用行
            if ($reference -like "*csproj") {
            $porjectDir = Join-Path -Path $slnDirectory -ChildPath (Split-Path -Path $projFile)
                $resolvedPath = Resolve-Path -Path (Join-Path -Path $porjectDir -ChildPath $reference)
                $resolvedPath = [System.IO.Path]::GetFullPath($resolvedPath)
                # 檢查路徑是否有效並且是否匹配目標專案
                if ($resolvedPath -eq $pkgProjFile) {
                echo "耶,找到了 $projFilePath"
                    $projFilesToMunge += $projFilePath
                }
            }
        }
    }
    
    echo "需還原的專案:"
    echo $projFilesToMunge
    
    Write-Host "即將使用git版控還原以上專案檔,按 Enter 鍵以繼續..."
    Read-Host | Out-Null
    
    cd $slnDirectory
    echo "開始暴力還原專案引用為 NuGet 套件..."
    # Remove project reference and add NuGet package for each project
    # 使用 Git 暴力丟棄專案檔案的變更
    foreach ($projFile in $projFilesToMunge) {
       git restore $projFile
       #dotnet remove $projFile reference $pkgProjFile  # 移除專案引用
       #dotnet add $projFile package $pkgName --version $nugetVersion  # 還原為 NuGet 套件,$nugetVersion指定要還原的 NuGet 套件版本
       echo "已還原: $projFile"
    }
    
    # Optional: Remove the source code project from the solution
    echo "從解決方案移除專案 $pkgProjFile ..."
    dotnet sln $slnFile remove $pkgProjFile
    Write-Host "按 Enter 鍵結束..."
    Read-Host | Out-Null
    

以上是我跟 ChatGPT 搏鬥的結果,雖然最後用 Git 還原我還沒有更好的解法,但目前還算是堪用

這是我為了實現能 Debug 開發而花了點時間整理出的腳本,希望某天誰有一樣的想法的時候,可以幫助到你


圖片
  直播研討會

尚未有邦友留言

立即登入留言