2012-07-24 23 views
19

特定のパッケージのバージョンを主張している:フレームワーク*パッケージは、私たちのローカルリポジトリに座っているNuGetのパッケージを復元し、私は次のようpackages.configでプロジェクトまし

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="Framework.Infrastructure.Core" version="1.4.0.6" /> 
    <package id="Framework.Infrastructure.Extensions" version="1.4.0.6" /> 
</packages> 

を。

私はパッケージの復元を有効にし、内部のrepoをソースに追加しました。しかし、私は(基本的にnuget install packages.config -sources....を行います)packages.configからパッケージを復元しようとすると、私は次のエラーを取得:

error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Extensions' 
error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Core'. 

をリポジトリはもはやパッケージの1.4.0.6バージョンが含まれていない(ありました数ヶ月前に関連する)、むしろそれの新しいバージョン(例えば、1.5.1.6)。

NuGetが新しいバージョンのパッケージを見つけられないのはなぜですか?最新のバージョンが確実にダウンロードされるようにpackages.configで指定できる構文はありますか?

要するに、私ができるパッケージを更新するカスタムスクリプトを書くのに手間がかかりませんか?

ありがとうございます。

答えて

39

パッケージの復元が意味することを誤解している人がいると思います。この機能は、パッケージをバージョン管理にチェックインする必要がないという目的のみで、NuGetに追加されました。多くの人々がコミットするバイナリが自分のリポジトリのサイズを爆発させていると不平を言いました。リポジトリ全体がローカルにダウンロードされ、Fooのすべてのバージョンを含むgitのようなDVCSを使用するとさらに悪化します。

パッケージの復元は、正確には何ですか?基本的には、各プロジェクトのpackages.configを見て、一覧表示されているパッケージの特定のバージョンをプルダウンします。それはあなたのパッケージフォルダを削除した後、git reset --hardを実行して(フォルダがチェックインされたと仮定して)それらを戻すようなものです。

なぜこれが重要ですか?なぜ最新のパッケージバージョンにアップグレードしないのですか?自動ビルドを行うパッケージ復元の最も一般的な使用例を考えれば、それはあなたにヒントを与えるはずです。ビルドサーバーは、開発者がテストし、コミットしたプロジェクトのみをビルドする必要があります。ビルドサーバーにパッケージの更新時期を決定させる場合は、誰にもテストされていないプロジェクトがあります。開発者は、いつアップグレードを行うかを決めるべきです。

パッケージをインストールまたは更新することは、単に.nupkgファイルをプルダウンして参照を追加することではないことに注意してください。多くのパッケージには、.configファイルの更新、コードの追加などの副作用があります。パッケージをインストールすると、これらの副作用はすべてローカルコピーで発生します。これで、コードをコミットしてパッケージファイルを除外することができます。

別の開発者またはビルドサーバーがコードをチェックアウトすると、パッケージファイルを除いたコードと同じ副作用コードが表示されます。パッケージのリストアはこれらのファイルをNuGetリポジトリから取り除くだけで、今度はこのプロジェクトで作業するために必要なものすべてを手に入れました。

NuGetチームは、常に正しいバージョンをプルダウンできるように、すべてのバージョンのパッケージを管理することを約束しています。しかし、数ヶ月前にNuGetサーバーがダウンしたときに見たように、パッケージのリストアがほとんど損なわれ、多くの人がビルドできませんでした。

あなた自身のNuGetリポジトリ(単純なファイル共有がそうするでしょう)をセットアップし、そこで使用するすべてのパッケージのコピーを保管することをお勧めします。この方法では、ビルドの外部サーバーに依存しません。そして、NuGetチームが行うように、パッケージのすべてのバージョンを保持する必要があります。こうすることで、プロジェクトの古いバージョンをビルドしてビルドする必要がある場合は、正しいパッケージバージョンを使用できるようになります。

この機能がどのように機能するのか、それがなぜこのように機能するのかを説明したいと思います。

0

nugetからパッケージを削除して再インストールするだけであれば、versionプロパティは最新のバージョンを参照します。

nugetから再インストールする前に古い参照を削除するには、手動でpackages.configを編集する必要があります(最近、nugetが新しいパッケージをインストールすることを許可していない状況があるため古いパッケージが存在する)

+0

それはパッケージの復元のポイントを無視しますか? –

+0

はい、それはありますが、最新のバージョンを取得するためのパッケージ構文の設定があればOPが言及されています。これが一度実行されると、リポジトリを使用している誰もが、パッケージリストアを使用してプロジェクトを取得できます。 – dougajmcdonald

+1

問題のプロジェクトは、私たちの内部プロジェクト用に行っているカスタムソリューションテンプレートの一部です。開発者は、テンプレートから新しいソリューションを作成し、インフラストラクチャパッケージへの参照を含む構造全体を適切な場所に配置して準備を整えることが考えられます。私は問題解決に必要なすべてのプロジェクトを行き来し、必要に応じてパッケージを再インストールするカスタムスクリプトを書いても問題はありませんが、テンプレートを使って作業してもらうことは間違っています... –

0

PowerShellモジュールを作成し、テンプレート作成時に実行する必要のあるNuGetパッケージにラップしました。スクリプトは、ソリューション内の各C#プロジェクトを調べ、「packages.config」(存在する場合)を見つけて、そこに記載されている各パッケージを削除して再インストールします。

一般的なアプローチと小さなバグの点で、改善の余地があることは明らかです(たとえば、インストールセクションのnugetコマンドは、フルネームでスペースを含むソリューションでは実行されません)。しかし、これはスタートです。

ファイルNuGet-RestorePackagesInAllProjects.psm1パッケージの

$NuGetSources = "https://nuget.org/api/v2/;" # put your internal sources here as needed 

function NuGet-RestorePackagesInAllProjects { 
    # get the solution directory 
    $solutionDir = (get-childitem $dte.Solution.FullName).DirectoryName 

    # for each C# project in the solution, process packages.config file, if there is one 
    $dte.Solution.Projects | Where-Object { $_.Type -eq "C#" } | ForEach-Object { 
     $currentProject = $_ 
     $currentProjectName = $currentProject.ProjectName 
     $currentProjectDir = (get-childitem $_.FullName).DirectoryName 

     Write-Host ******* Starting processing $currentProjectName 

     # get the packages.config file for the current project 
     $packagesFile = $currentProject.ProjectItems | Where-Object { $_.Name -eq "packages.config" } 

     # if there's no packages.config, print a message and continue to the next project 
     if ($packagesFile -eq $null -or $packagesFile.count -gt 1) { 
      write-host ------- Project $currentProjectName doesn''t have packages.config 
      return 
     } 

     # read the contents of packages.config file and extract the list of packages in it 
     $fileName = $currentProjectDir + "\packages.config" 
     [xml]$content = Get-Content $fileName 
     $packageList = $content.packages.package | % { $_.id } 

     # for each package in the packages.config, uninstall the package (or simply remove the line from the file, if the uninstall fails) 
     $packageList | ForEach-Object { 
      $currentPackage = $_ 

      write-host Uninstalling $currentPackage from $currentProjectName 

      try { 
       Uninstall-Package $currentPackage -ProjectName $currentProjectName -RemoveDependencies -Force 
      } 
      catch { 
       write-host '!!!!!!! $_.Exception.Message is' $_.Exception.Message 
       $node = $content.SelectSingleNode("//package[@id='$currentPackage']") 
       [Void]$node.ParentNode.RemoveChild($node) 
       $content.Save($fileName) 
      } 
     } 

     # download each package into the $(SolutionDir)packages folder, and install it into the current project from there 
     $packageList | ForEach-Object { 
      $currentPackage = $_ 
      $localPackagesDir = $solutionDir + "\packages" 
      $cmd = $solutionDir + "\.nuget\nuget.exe install " + $currentPackage + " -Source """ + $NuGetSources + """ -o " + $localPackagesDir 

      write-host Installing $currentPackage to $currentProjectName 
      invoke-expression -command $cmd 
      Install-Package $currentPackage -ProjectName $currentProjectName -Source $localPackagesDir 
     } 

     Write-Host ******* Finished processing $currentProjectName 
    } 
} 

Export-ModuleMember NuGet-RestorePackagesInAllProjects 

ファイル

param($installPath, $toolsPath, $package) Import-Module (Join-Path $toolsPath NuGet-RestorePackagesInAllProjects.psm1) Enable-PackageRestore NuGet-RestorePackagesInAllProjects 

init.ps1 .nuspecファイル

<?xml version="1.0" encoding="utf-16"?> 
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> 
    <metadata> 
     <id>NuGet-RestorePackagesInAllProjects</id> 
     <version>0.5.0</version> 
     <title>Custom NuGet Package Restore</title> 
     <authors>Me (c) 2012</authors> 
     <owners /> 
     <requireLicenseAcceptance>false</requireLicenseAcceptance> 
     <description>Restore all packages in a given solution from packages.config in each project. For each packages.config, uninstalls all packages and then re-install them again from the sources specified in the script.</description> 
     <dependencies> 
      <dependency id="NuGetPowerTools" /> 
     </dependencies> 
    </metadata> 
    <files> 
     <file src="init.ps1" target="tools\init.ps1" /> 
     <file src="NuGet-RestorePackagesInAllProjects.psm1" target="tools\NuGet-RestorePackagesInAllProjects.psm1" /> 
    </files> 
</package> 
8

NuGet documentation for Versioningを読むことをお勧めします。バージョン番号(および範囲)をpackages.configファイルでどのように利用して、Update-Packageコマンドがアップグレード可能なバージョンであるかを知ることができるようにする方法について説明します。

パッケージ復元機能は、パッケージを自動的に更新するものではありません。この情報を

、最高のワークフローはIMOである:あなたが本当に古い(またはプレリリース)バージョンを必要としない限り、

  • はあなたが追加された新しい依存関係の最新安定版をインストールし
  • CIビルドでパッケージ復元を使用すると、でなく、チェックインNuGetパッケージをVCS
    • あなたは私はあなたが可能性降下物と

を対処するための時間を持っている自信

  • のための偉大なテストスイートを持っている最新バージョン
  • から新しいAPI呼び出しやバグ修正を必要としますパッケージを定期的にアップグレードすることを奨励しないでくださいとちょうど。パッケージのバージョンを更新する際にリスクがあるため、十分に機能する場合は、古い依存関係のままでプロジェクトをそのままにしておく方が良いです。

    NuGetパッケージは、最もストレスのないパッケージアップグレードのエクスペリエンスを可能にするための良い規則を持っていますが、これは強制されていない(信頼しています。多くのパッケージ発行者がSemVerに従わないため)それに頼ることはありません。パッケージがマイナーバージョンの増加だけで更新されたとしても、十分なテストがなければ、新しいバージョンがあなたのコードで動作することは確実ではありません。

    要約すると、パッケージは自動的ににアップグレードするのが悪い考えです。開発者が特定のパッケージを更新するために明示的に選択することを、十分な理由がある場合にのみ行うようにする方がよいでしょう。

  • +3

    バージョン管理の問題は、バージョン管理仕様に基づいて 'version =" 1.4.0.6 "のバージョン(packages.configのデフォルトで)は' version> = 1.4.0.6'に変換されるべきですが、そうではありません。そして、 "update"はpackages.configをまったく使用していないので(これは 'packages'ディレクトリ内のフォルダのみを使用するようです)、もしあなたがパッケージを持っていなければ、" update "は何もしませんpackages.configファイルがある場合)。 –

    +4

    @FuriCuriあなたが記述するバージョン範囲は、 '.nuspec'ファイルでのみ使用され、' packages.config'では使用されません。パッケージ間の依存関係を記述するために使用されます。あなたのプロジェクトで依存関係を指定するときは、常に特定のバージョンを参照する 'packages.config'ファイルを使用します。そして、そうです、プロジェクトが最近ビルドされ、すべてのNuGet依存関係が '/ packages'ディレクトリに存在しない限り、' Update-Package'コマンドは機能しません。これは不便でも直感的ではないかもしれませんが、バグだとは思われません。 NuGetの操作方法です。 –

    +1

    私は参照してください。さて、私はここでそれについて説明しましたhttps://nuget.codeplex.com/workitem/3264最大の問題は、プロジェクトを復元するために、リポジトリでは使用できなくなった旧バージョンを参照するいくつかのパッケージがあることですしかし、新しいバージョンがあります)、パッケージのpackages.configと.projファイルにナゲットアップデートバージョンを作成する方法がありません。 –

    関連する問題