簡體   English   中英

使用命令行檢查nuget包是否存在

[英]Check if nuget package exists using command line

如何使用 powershell 或 Visual Studio 外的命令行檢查指定包源(nuget 服務器)中是否存在具有特定版本的 nuget 包?

設想:

我有私人 NuGet 服務器,我想在其中推送我自己的包。 我在 TFS 構建期間自動創建了包。 我想念的是檢查包之前是否已上傳並發布到 NuGet 服務器。

我不知道您的私有 NuGet 服務器是否實現了與 nuget.org 相同的服務器 Api,但我會假設它確實如此。 https://docs.microsoft.com/en-us/nuget/api/registration-base-url-resource描述了可用於檢查包是否已發布並獲取其版本的 API。 nuget list命令不同,它通過包 ID 執行精確匹配。

例如,假設您想知道 AjaxMin 包是否已發布。 執行nuget list ajaxmin不是很有幫助:

C:\> nuget.exe list ajaxmin
BundleTransformer.MicrosoftAjax 1.10.0
Bundler.NET 1.5.7
CodeSlice.Web.Baler.Extensions.AjaxMinifier 0.2.0
combres 2.3.0.4
combres.log4net 2.3.0.4
combres.mvc 2.3.0.4
Delegate.AjaxMinBuilder 1.1.2
DotLessMinification 0.42.1
AjaxMin 5.14.5506.26202
NUglify 1.5.1
NUglify 1.5.13
Pvc.Ajaxmin 0.0.2
RequestReduce 1.8.76
WebMarkupMin.Core 2.6.0
WebMarkupMin.MsAjax 2.6.0
Web.Optimization.Bundles.AjaxMin 0.0.8
Web.Optimization.Bundles.YUI 0.0.8
C:\>

是的,您可以過濾輸出,但我覺得工作量太大。 您可以通過使用服務器 Api 更精確。 觀察:

C:\> $url = 'https://api.nuget.org/v3/registration3-gz-semver2/ajaxmin/index.json'
C:\> $res = Invoke-RestMethod $url
C:\> $res.items.items.catalogEntry.version
4.12.4057.21792
4.13.4076.28499
4.19.4141.18463
4.30.4295.16112
4.36.4337.24224
4.37.4345.34101
4.39.4362.37207
4.40.4369.35534
4.41.4378.21434
4.42.4387.23950
4.43.4392.20083
4.44.4396.18853
4.45.4416.14249
4.46.4422.26284
4.47.4452.34008
4.48.4489.28432
4.49.4503.16524
4.50.4504.34801
4.51.4507.18296
4.52.4518.14738
4.53.4526.21623
4.54.4533.37029
4.55.4545.19776
4.56.4560.33404
4.58.4566.27257
4.59.4576.13504
4.60.4609.17023
4.61.4617.31171
4.62.4618.15628
4.63.4630.14654
4.64.4630.17932
4.66.4633.35991
4.67.4639.17289
4.68.4663.23906
4.69.4665.24361
4.70.4668.12892
4.71.4679.26350
4.72.4679.35523
4.73.4685.17669
4.74.4698.25434
4.75.4713.17606
4.76.4714.20550
4.77.4723.25304
4.78.4724.23869
4.80.4763.16598
4.81.4769.14860
4.82.4784.14537
4.83.4785.14876
4.84.4790.14417
4.85.4828.21154
4.86.4836.34222
4.89.4861.30057
4.90.4864.13402
4.91.4875.26882
4.92.4896.13361
4.93.4902.12739
4.94.4916.15482
4.95.4924.12392
4.96.4941.15389
4.97.4951.28483
5.0.5007.14585
5.1.5007.23730
5.2.5021.15814
5.3.5068.16463
5.4.5085.25629
5.5.5091.22839
5.6.5100.19204
5.7.5124.21499
5.8.5172.27710
5.9.5229.26438
5.10.5260.16959
5.11.5295.12309
5.12.5436.22734
5.13.5463.15282
5.14.5506.26202
C:\>

我們得到了包的所有版本。 現在,如果您想檢查某個事先已知的版本是否已發布 - 您可以:

C:\> $url = 'https://api.nuget.org/v3/registration3-gz-semver2/ajaxmin/5.14.5506.26202.json'
C:\> $res = Invoke-RestMethod $url
C:\> $res


@id            : https://api.nuget.org/v3/registration3-gz-semver2/ajaxmin/5.14.5506.26202.json
@type          : {Package, http://schema.nuget.org/catalog#Permalink}
catalogEntry   : https://api.nuget.org/v3/catalog0/data/2018.10.06.23.54.33/ajaxmin.5.14.5506.26202.json
listed         : True
packageContent : https://api.nuget.org/v3-flatcontainer/ajaxmin/5.14.5506.26202/ajaxmin.5.14.5506.26202.nupkg
published      : 2015-01-28T22:45:45.577+00:00
registration   : https://api.nuget.org/v3/registration3-gz-semver2/ajaxmin/index.json
@context       : @{@vocab=http://schema.nuget.org/schema#; xsd=http://www.w3.org/2001/XMLSchema#; catalogEntry=; registration=; packageContent=; published=}



C:\>

現在如果我們要求一個不存在的版本會發生什么? 開始了:

C:\> $url = 'https://api.nuget.org/v3/registration3-gz-semver2/ajaxmin/5.14.5506.26196.json'
C:\> $res = Invoke-RestMethod $url
Invoke-RestMethod : BlobNotFoundThe specified blob does not exist.
RequestId:cd1579e6-801e-007d-5eba-64ac9d000000
Time:2019-09-06T13:53:54.6832811Z
At line:1 char:8
+ $res = Invoke-RestMethod $url
+        ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
C:\>

要求一個不存在的包裹怎么樣? 讓我們搜索ajaxmi(沒有'n'):

C:\> $url = 'https://api.nuget.org/v3/registration3-gz-semver2/ajaxmi/index.json'
C:\> $res = Invoke-RestMethod $url
Invoke-RestMethod : BlobNotFoundThe specified blob does not exist.
RequestId:23d96274-b01e-0018-3bba-641dc0000000
Time:2019-09-06T13:55:35.5288968Z
At line:1 char:8
+ $res = Invoke-RestMethod $url
+        ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
C:\>

你可以很容易地從 PowerShell 調用這個 CMD 腳本,下面是示例。 您可以通過$LastExitCode來確定如何繼續, 0表示您可以發布:

check_nupkg.bat

@echo off
SetLocal EnableDelayedExpansion EnableExtensions
pushd "%~dp0"

set "pkg_name=%~1"
set "pkg_version=%~2"

call nuget list %pkg_name% -AllVersions -Prerelease|findstr /i /r /c:"^%pkg_name% %pkg_version%$" -N>nul 2>&1

if not "%errorlevel%"=="0" (
    echo This package can be published
    exit /b 0
) else (
    echo This package has already been published.
    exit /b 1
)

C:\\stuff>.\\check_nupkg.bat "lolspeak" "1.0.0"

This package has already been published.

C:\\stuff>check_nupkg.bat "lolspeak" "11.0.0"

This package can be published

我使用的基於其他一些答案的方法最近失效了,所以我想更全面地描述我們如何發現 URL 並進行實際驗證。

NuGet.org 提供了一個服務索引,該索引提供了按類型索引的基本 URL 列表。 此服務索引可從https://api.nuget.org/v3/index.json

它以以下結構返回數據(為簡潔起見被截斷):

PS> Invoke-RESTmethod -uri 'https://api.nuget.org/v3/index.json'

version resources
------- ---------
3.0.0   {@{@id=https://azuresearch-usnc.nuget.org/query; ... 

換句話說,服務索引提供了一組可用的 API 版本和一組相應的資源(即端點/可查詢 API)。 這些資源對應於具有非常具體的功能並且都應該被記錄下來的 URL。 在撰寫本文時,我們只有 3.0.0 版本作為選項,所以讓我們檢查這些資源,我們可以看到這些端點的樣子,將輸出過濾到與包注冊和元數據相關的端點:

PS> (Invoke-RESTmethod -uri 'https://api.nuget.org/v3/index.json' | `
    ? { $_.version -eq '3.0.0' }).resources | `
    ? { $_.'@type' -like '*Registration*' } | `
    select-object -Property '@id','@type'

@id                                                @type
---                                                -----
https://api.nuget.org/v3/registration4/            RegistrationsBaseUrl
https://api.nuget.org/v3/registration4/            RegistrationsBaseUrl/3.0.0-rc
https://api.nuget.org/v3/registration4/            RegistrationsBaseUrl/3.0.0-beta
https://api.nuget.org/v3/registration4-gz/         RegistrationsBaseUrl/3.4.0
https://api.nuget.org/v3/registration4-gz-semver2/ RegistrationsBaseUrl/3.6.0
https://api.nuget.org/v3/registration4-gz-semver2/ RegistrationsBaseUrl/Versioned

我在輸出中留下的一個有用屬性是存在一個comment屬性,它提供了對端點的有用描述。 例如,對於RegistrationsBaseUrl我們有以下注釋:

存儲 NuGet 包注冊信息的 Azure 存儲的基本 URL

從上面可以看出,我們的基本 URL 將是上面左側的 URL 之一。 檢查@type RegistrationsBaseUrl 的文檔

這些注冊沒有被壓縮(意味着它們使用隱含的內容編碼:身份)。 SemVer 2.0.0 包不包括在此配置單元中。

根據我的需要,我想包括 SemVer 2.0.0,所以我想使用不同的端點。 再次檢查文檔

這些注冊使用 Content-Encoding: gzip 壓縮。 SemVer 2.0.0 軟件包包含在此配置單元中。

因此,根據較早的查詢結果,我需要以下網址:

https://api.nuget.org/v3/registration4-gz-semver2/

通過閱讀文檔,我們了解到我們對我們嘗試查詢的包的注冊頁面感興趣。 URL 語法將是:

$BASEURL/<PackageName>/<PackageVersion>.json

使用 Newtonsoft.Json 作為示例包並擴展:

https://api.nuget.org/v3/registration4-gz-semver2/newtonsoft.json/12.0.3.json

現在我們知道了如何獲取 URL,以及它可以隨時間變化並且應該動態檢索的事實,讓我們編寫一些 PowerShell 來確定 NuGet 包是否已發布到給定源:

param (
  [Parameter(Mandatory=$true)] 
  [string]$Id,
  [Parameter(Mandatory=$true)] 
  [string]$Version,
  [Parameter(Mandatory=$false)] 
  [string]$source = "https://api.nuget.org/v3/index.json"
)

$resources = (invoke-restmethod -uri $source | ? { $_.version -eq '3.0.0' }).resources
$baseUrl = ($resources | ? { $_.'@type' -eq 'RegistrationsBaseUrl/3.6.0' }).'@id'

try
{
  $packageName = $Id.ToLowerInvariant()
  $packageVersion = $Version.ToLower()

  # Use supported HEAD method for performance
  Invoke-RestMethod -uri "$($baseUrl)$($packageName)/$($packageVersion).json" -Method HEAD > $null 2>&1
  # method didn't throw so the NuGet package exists
  $true
}
catch
{
  # method threw, so the NuGet package doesn't exist
  $false
}

它的用法如下所示:

PS>  Get-NuGetPackageExists.ps1 -Id Newtonsoft.Json -Version 10.0.2
True

您也可以使用瀏覽器(或任何可以發送 HTTP-GET 請求的工具)通過獲取包描述來檢查服務器上的包是否存在。 例如,我們收到System.Collections.Immutable包的描述,我們得到 404 非現有包的狀態代碼。 這些網址區分大小寫。

如果您使用 PowerShell 5.0,它內置了 PackageManagement cmdlet。 您可以使用這些來發現和安裝各種軟件包。 這是參考https://technet.microsoft.com/en-us/library/dn890706.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM