Install NuGet package with dependencies into same folder - powershell

I have a project (a PowerShell module) that relies upon a NuGet package, whose assemblies are loaded into my module via the Add-Type cmdlet. I would like to install this package via NuGet instead of manually copying it into the correct folder. This would save me from committing it's binaries to source control. Also: when thinking about CI/CD, I'd hate to have them in my repo.
I know I can curate a packages.config file and use nuget install instead. But this command installs the package together with it's dependencies into a separate folder and therefore the framework will (runtime) not find the required dependencies.
I know I could also provide a script that performs the nuget install and then copies the required .dll files into a single folder. But I would have to deal with the fact that the package might have different versions for different target frameworks and I'd need to handle the compatibility. Or maybe the package has other additional required files that I know nothing about.
So here my question: there has got to be a simpler way to do this? Something less ... circuitous and cumbersome?

Related

How do I correctly install nuget packages outside of VS and keep track of them?

I'm trying to use nuget.exe outside of Visual Studio as part of our build infrastructure. The idea is that the various build tools are fetched by a bootstrapper script that initializes a working copy. The bootstrapper does this by using a file that specifies the required tools and their version.
Broken approach 1 - use manually edited packages.config
At first, it seemed like a good idea to keep a manually edited packages.config file and use nuget restore to install them during bootstrapping. However, this does not work for tools that have dependencies, unless I list every single dependency in the packages.config as well, a much to arduous approach to be feasible, because I found no easy way to recursively find all dependencies of a package.
See also using nuget.exe commandline to install dependency .
Broken approach 2 - use nuget install to update packages.config
The second idea was then to use nuget install to install the packages, and let that command update the packages.config, very similar to the Install-Package cmdlet in the package manager console. But, surprisingly, nuget install does not support this! It either takes a packages.config or a package ID as parameter, but I found no way to update the packages.config with the new package and its dependencies.
This problem can also be found in another (two year old) SO question, see nuget.exe install not updating packages.config (or .csproj)?.
Is there a working (and non-hacky) approach at all?
This must be a problem that many people face when using nuget outside of VS, so what is the best approach in that case?
Of course, I could just parse the packages.config and emit a nuget install for each package, but I really don't want to re-invent the dependency management part of nuget, this is what I'm using nuget for in the first place. So I'm left with the feeling that either an -WithDependencies switch on nuget restore or an -UpdatePackagesConfig switch on nuget install is missing...
Note that there are other SO questions regarding the broken approaches described above. What I'd like to know it what the best approach is to solve the root problem, i.e. manage packages with dependencies outside of VS.
nuget install does not currently make changes to the project file.
nuget install can be used to either restore the NuGet packages listed in a packages.config file or download and extract them.
If you do not need the project being modified then your solution of reading the packages in the packages.config file and calling nuget install seems like a reasonable approach.
If you need the project to be modified then you could look at one of the following:
Ripple - a command line tool that adds extra features to NuGet. It has a ripple install command line which is similar to nuget install but it also updates the project file. It has a lot of other features for supporting build servers so this might be a good fit.
NuGet packages outside of Visual Studio with SharpDevelop - this was an experiment I put together to see whether full NuGet support could be achieved, including PowerShell scripts, from the command line without using Visual Studio. It uses PowerShell and quite a bit of SharpDevelop.
Customise NuGet.exe to do what you need. nuget update, for example, does modify the project file, at least for file references, but will not run PowerShell scripts. So you could take the NuGet.exe source code and extend it.
Of the above only 3) would give you exactly what you need. The other two would require a bit of work to read the packages from the packages.config file or some other list and then install them.
See my answer to Why does the nuget command line tool not follow dependencies?
nuget install My.Package.Id will follow dependencies. However, if you want to install multiple packages, you will need to create a batch file with a separate nuget install command for each package. These are top-level packages. You don't need to "install" the dependencies, as they will get downloaded automatically.
If you ultimately want a packages.config file, I imagine you can generate one by enumerating all the packages that were downloaded. However, you would have to take care not to include multiple versions of the same package.
I believe that how nuget 3 works with project.json files may do what you are looking for. Essentially my understanding is that the unit of dependency becomes the package and not necessarily individual assemblies. From what I recall, the idea is the have only one place to manage these types of package references which the project (IDE/Editor), package manager, and other command line tools can use.
What I don't understand and feel somewhat frustrated about is that it appears that the project.json concept is being canceled. I don't know if plans are to reintroduce it at anytime in the future. In the mean time I keep on hearing updated info on tooling that takes advantage of project.json such as nuget so where you can actually rely on this is something that is unclear to me at this point.

Get current version of package outside of Visual Studio

We are migrating over to using packages and NuGet for managing our dependencies on 3rd party components. This works well when referencing packages from within Visual Studio or building on the build server via msbuild.
However there are a number of files that we would like to access in our build scripts and installers. Previously these would be in source control with a well known path, now as the version of the package that we are consuming changes so the path to the package and hence the files is changing.
Is there a simple way I can get the path to a given package? The best solution I currently have is to search for all packages.config files and extract the package version from them.
Examples of the files that we need to access are
The NUnit console executable from the NUnit.Runners package for running unit tests.
License files from various packages that we redistribute with our installer.
Using the packages.config file is a pretty good solution. NuGet itself uses two approaches:
Reading the package information from the packages.config and using that to resolve to the packages path.
Enumerating all the directories in the packages directory.
You could use NuGet.Core to do either of the above if you do not want to write the code yourself. The classes that can be used are the DefaultPackagePathResolver, the PackageReferenceFile and LocalPackageRepository or SharedPackageRepository.
One problem with the second approach is that sometimes NuGet may occasionally leave behind NuGet packages that are not necessarily referenced by a project. In that case looking at the package directories may give you the incorrect information.
The only other approach I can think of might be to read the project files looking for the assembly references. Although that would not work for a solution level package such as NUnit.Runners.

How to best use NuGet for source file deployment

I would like to use NuGet packages for building packages for core helper libraries which I would like to add as source files into other projects. I want to use source files instead of libraries for several reasons, the main one being that I need them in SharePoint Projects, which is on the one hand much easier to deploy than additional libraries, and on the other hand helps to reduce version conflicts.
I know that I can add the source files as content to NuGet Packages, which would install them with the package. But this won't work together with package restore, and I don't want to have these files checked into source control in all projects.
Is it somehow possible to make a NuGet package which doesn't copy the files to the project, but instead adds file links, which point back to the file in the package folder, to the project? I think this approach would solve my use case.
Thanks
pascal
It is possible to add linked files with the use of PowerShell scripts, for example with this NuGet script: http://www.nuget.org/packages/Baseclass.Contrib.Nuget.Linked/

Can a NuGet package declare a dependency without adding that dependency to the project?

I've created a NuGet package that contains some custom MSBuild tasks named MyCompany.MSBuild. These tasks have a dependency on Newtonsoft.Json. This means that after my package is installed in a project, Newtonsoft.Json.dll will have to be in the same directory as MyCompany.MSBuild.dll.
I could easily accomplish this by bundling my own copy of Newtonsoft.Json.dll in my package, but I wonder if there's a better way that means I won't have to update my package whenever a new version of Newtonsoft.Json comes out.
If I declare Newtonsoft.Json as a dependency, NuGet will install that package into the project when somebody installs my package, which isn't what I want to have happen.
How can I specify a dependency in my package without having NuGet install it and add project references? Additionally, how can I copy that package's assembly to my own package's folder after it is installed?
A package with a "hidden" dependency is something absolutely undesiderable in my opinion...
I know it's not a real answer but... Have you considered to use JavascriptSerializer instead of Newtonsoft.Json? It's a bit slower but your package will be absolutely self-contained: less pain for you and for your users.

Selective installation by using NuGet Package

I have created versions of NuGet packages,uploaded and it is working fine.
I have set of libraries in my package which has been populated in different directories inside the package.
Some users might require a particular directory of my NuGet package, and some of the libraries might not be needed. While installation I should prompt users that which part they need to install.
One Solution:Logical seperation of packages may be one solution. Like packing libraries in separate packages, and required packages can be installed.
But If it has been made selective installation, then it would be more easier. I have no idea whether NuGet have such an option. Any help would be appreciated.
NuGet has support for framework versions and platforms using conventions, you can read up on them in the docs. You can group them by target framework version or by target framework profile.
If you want to selectively install libraries, you are saying you want to selectively install dependencies: you should split them up in separate NuGet packages and declare your dependencies. These dependencies also can be grouped.
If your condition cannot be defined using framework version or profile, you should come up with your own entry-level NuGet packages and bring down the proper dependency chain (or use PowerShell hooks for this).