使用命令行

时间:2016-02-25 15:05:53

标签: powershell command-line nuget

如何在visual studio外部使用powershell或命令行检查指定包源(nuget服务器)中是否存在具有特定版本的nuget包?

情景:

我有私人NuGet服务器,我想推送自己的包。我在TFS构建期间自动创建了包。我想念的是检查包是否先前上传并发布到NuGet服务器。

5 个答案:

答案 0 :(得分:1)

我不知道您的私有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:\>

答案 1 :(得分:1)

基于其他答案的我最近使用的方法中断了,所以我想更全面地描述我们如何发现URL并进行实际验证。

NuGet.org提供了一个service index,其中提供了按类型索引的基本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,所有URL都应记录在案。在撰写本文时,我们仅提供版本3.0.0作为选项,因此让我们检查一下这些资源,我们可以看到这些端点的外观,将输出过滤到与package registration and metadata相关的端点:

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之一。在the docs中检查@type RegistrationsBaseUrl:

这些注册未压缩(这意味着它们使用暗示的Content-Encoding:身份)。在此配置单元中排除了 SemVer 2.0.0程序包。

出于我的需要,我想包括SemVer 2.0.0,所以我想使用其他端点。再次检查the docs

这些注册使用Content-Encoding:gzip压缩。该配置单元中包含SemVer 2.0.0软件包。

因此,根据之前的查询结果,我需要以下网址:

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

在阅读文档时,我们了解到我们对要查询的软件包的Registration Page感兴趣。 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

答案 2 :(得分:0)

此外,仅通过获取软件包描述,您就可以使用浏览器(或任何可以发送HTTP-GET请求的工具)检查服务器上的软件包是否存在。例如,我们收到了对软件包System.Collections.Immutable的描述,并获得了non existing package的404状态代码。这些网址区分大小写。

答案 3 :(得分:0)

您可以从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

答案 4 :(得分:-2)

如果您使用PowerShell 5.0,则内置了PackageManagement cmdlet。您可以使用它们来发现和安装各种包。这是参考https://technet.microsoft.com/en-us/library/dn890706.aspx