Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

First cut of plugin to add references via nuget

When ReSharper tries to import a type from an assembly referenced in
another project and that assembly is a nuget package, this plugin will
use nuget to add the package (and all dependencies)
  • Loading branch information...
commit 0385e18782d9d493f634b55119d8e201faae813e 1 parent 05c7b2f
@citizenmatt citizenmatt authored
View
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
View
64 .gitignore
@@ -1,6 +1,60 @@
-# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
-bin
-obj
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.vspscc
+.builds
+*.dotCover
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+_dotCover*
+
+# Others
+[Bb]in
+[Oo]bj
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+
+############
+## Windows
+############
+
+# Windows image file caches
+Thumbs.db
+
+# Folder config file
+Desktop.ini
+
+
-# mstest test results
-TestResults
View
BIN  packages/NuGet.VisualStudio.2.1.0/NuGet.VisualStudio.2.1.0.nupkg
Binary file not shown
View
15 packages/NuGet.VisualStudio.2.1.0/NuGet.VisualStudio.2.1.0.nuspec
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
+ <metadata>
+ <id>NuGet.VisualStudio</id>
+ <version>2.1.0</version>
+ <authors>Outercurve Foundation</authors>
+ <owners>Outercurve Foundation</owners>
+ <licenseUrl>http://nuget.codeplex.com/license</licenseUrl>
+ <projectUrl>http://nuget.codeplex.com/</projectUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <description>APIs for invoking NuGet services in Visual Studio.</description>
+ <copyright>© Outercurve Foundation. All rights reserved.</copyright>
+ <tags>nuget</tags>
+ </metadata>
+</package>
View
BIN  packages/NuGet.VisualStudio.2.1.0/lib/net40/NuGet.VisualStudio.dll
Binary file not shown
View
7 packages/NuGet.VisualStudio.2.1.0/tools/install.ps1
@@ -0,0 +1,7 @@
+param($installPath, $toolsPath, $package, $project)
+
+$vsRef = $project.Object.References.Item("NuGet.VisualStudio")
+if ($vsRef -and !$vsRef.EmbedInteropTypes)
+{
+ $vsRef.EmbedInteropTypes = $true
+}
View
4 packages/repositories.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<repositories>
+ <repository path="..\src\resharper-nuget\packages.config" />
+</repositories>
View
5 src/nuget.config
@@ -0,0 +1,5 @@
+<configuration>
+ <config>
+ <add key="repositoryPath" value="..\packages" />
+ </config>
+</configuration>
View
20 src/resharper-nuget.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "resharper-nuget", "resharper-nuget\resharper-nuget.csproj", "{7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
View
14 src/resharper-nuget/ExposeNuGetServices.cs
@@ -0,0 +1,14 @@
+using JetBrains.VsIntegration.Application;
+using Microsoft.VisualStudio.ComponentModelHost;
+
+namespace JetBrains.ReSharper.Plugins.NuGet
+{
+ [WrapVsInterfaces]
+ public class ExposeNuGetServices : IExposeVsServices
+ {
+ public void Register(VsServiceProviderComponentContainer.VsServiceMap map)
+ {
+ map.QueryService<SComponentModel>().As<IComponentModel>();
+ }
+ }
+}
View
111 src/resharper-nuget/NuGetApi.cs
@@ -0,0 +1,111 @@
+using System;
+using EnvDTE;
+using JetBrains.Application;
+using JetBrains.Application.Progress;
+using JetBrains.ProjectModel;
+using JetBrains.ProjectModel.Transaction;
+using JetBrains.Threading;
+using JetBrains.Util;
+using JetBrains.VsIntegration.ProjectModel;
+using Microsoft.VisualStudio.ComponentModelHost;
+using NuGet.VisualStudio;
+using System.Linq;
+
+namespace JetBrains.ReSharper.Plugins.NuGet
+{
+ [ShellComponent]
+ public class NuGetApi
+ {
+ private readonly VSSolutionManager vsSolutionManager;
+ private readonly IThreading threading;
+ private readonly IVsPackageInstallerServices vsPackageInstallerServices;
+ private readonly IVsPackageInstaller vsPackageInstaller;
+
+ public NuGetApi(IComponentModel componentModel,
+ VSSolutionManager vsSolutionManager,
+ IThreading threading)
+ {
+ this.vsSolutionManager = vsSolutionManager;
+ this.threading = threading;
+ try
+ {
+ vsPackageInstallerServices = componentModel.GetService<IVsPackageInstallerServices>();
+ vsPackageInstaller = componentModel.GetService<IVsPackageInstaller>();
+ }
+ catch (Exception e)
+ {
+ // NuGet isn't installed
+ }
+ }
+
+ private bool IsNuGetAvailable
+ {
+ get { return vsPackageInstallerServices != null && vsPackageInstaller != null; }
+ }
+
+ public bool IsNuGetPackageAssembly(FileSystemPath location)
+ {
+ return IsNuGetAvailable && IsPackageAssembly(location);
+ }
+
+ private bool IsPackageAssembly(FileSystemPath location)
+ {
+ // We're talking to NuGet via COM. Make sure we're on the UI thread
+ var isPackageAssembly = false;
+ threading.Dispatcher.Invoke("NuGet", () =>
+ {
+ isPackageAssembly = GetPackageFromAssemblyLocation(location) != null;
+ });
+
+ return isPackageAssembly;
+ }
+
+ public bool InstallAssemblyAsNuGetPackage(FileSystemPath assemblyLocation, IProject project)
+ {
+ if (!IsNuGetAvailable)
+ return false;
+
+ var installed = false;
+
+ // We talking to NuGet via COM. Make sure we're on the UI thread
+ threading.Dispatcher.Invoke("NuGet", () =>
+ {
+ installed = DoInstallAssemblyAsNuGetPackage(assemblyLocation, project);
+ });
+
+ return installed;
+ }
+
+ private bool DoInstallAssemblyAsNuGetPackage(FileSystemPath assemblyLocation, IProject project)
+ {
+ var metadata = GetPackageFromAssemblyLocation(assemblyLocation);
+ if (metadata == null)
+ return false;
+
+ var vsProject = GetVsProject(project);
+ if (vsProject == null)
+ return false;
+
+ // Passing in the package's install path and a null version is enough for NuGet to install the existing
+ // package into the current project
+ // TODO: Need to add some error handling here. What can go wrong?
+ vsPackageInstaller.InstallPackage(metadata.InstallPath, vsProject, metadata.Id, (Version) null, false);
+
+ return true;
+ }
+
+ private IVsPackageMetadata GetPackageFromAssemblyLocation(FileSystemPath assemblyLocation)
+ {
+ return vsPackageInstallerServices.GetInstalledPackages().FirstOrDefault(p => assemblyLocation.FullPath.StartsWith(p.InstallPath));
+ }
+
+ private Project GetVsProject(IProject project)
+ {
+ var projectModelSynchronizer = vsSolutionManager.GetProjectModelSynchronizer(project.GetSolution());
+ var projectInfo = projectModelSynchronizer.GetProjectInfoByProject(project);
+ return projectInfo != null ? projectInfo.GetExtProject() : null;
+ }
+ }
+}
+
+
View
58 src/resharper-nuget/NuGetModuleReferencer.cs
@@ -0,0 +1,58 @@
+using JetBrains.Application.Progress;
+using JetBrains.ProjectModel;
+using JetBrains.ReSharper.Psi;
+using JetBrains.ReSharper.Psi.Module;
+using JetBrains.Util;
+
+namespace JetBrains.ReSharper.Plugins.NuGet
+{
+ [ModuleReferencer(Priority = NuGetModuleReferencerPriority)]
+ public class NuGetModuleReferencer : IModuleReferencer
+ {
+ // Must be greater than GenericModuleReferencer's priority
+ private const int NuGetModuleReferencerPriority = 100;
+
+ private readonly NuGetApi nuget;
+
+ public NuGetModuleReferencer(NuGetApi nuget)
+ {
+ this.nuget = nuget;
+ }
+
+ public bool CanReferenceModule(IPsiModule module, IPsiModule moduleToReference)
+ {
+ return IsNuGetAssembly(moduleToReference);
+ }
+
+ public bool ReferenceModuleWithType(IPsiModule module, ITypeElement typeToReference)
+ {
+ var assemblyModule = typeToReference.Module as IAssemblyPsiModule;
+ var projectModule = module as IProjectPsiModule;
+ if (assemblyModule == null || projectModule == null)
+ return false;
+
+ if (nuget.InstallAssemblyAsNuGetPackage(assemblyModule.Assembly.Location, projectModule.Project))
+ {
+ // TODO: I wish we didn't have to do this
+ // When NuGet references the assemblies, they are queued up to be processed, but after
+ // this method completes. Which means the import type part of the process fails to find
+ // the type to import. We force an update which works through the system early. It would
+ // be nice to find out if we can process the proper import notifications instead
+ using (var cookie = module.GetSolution().CreateTransactionCookie(DefaultAction.Commit, "ReferenceModuleWithType", NullProgressIndicator.Instance))
+ cookie.AddModuleReference(projectModule.Project, assemblyModule.ContainingProjectModule);
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool IsNuGetAssembly(IPsiModule module)
+ {
+ var assemblyModule = module as IAssemblyPsiModule;
+ if (assemblyModule == null)
+ return false;
+
+ return nuget.IsNuGetPackageAssembly(assemblyModule.Assembly.Location);
+ }
+ }
+}
View
22 src/resharper-nuget/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using JetBrains.Application.PluginSupport;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("JetBrains.ReSharper.Plugins.NuGet")]
+[assembly: AssemblyDescription("NuGet support for ReSharper")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("JetBrains")]
+[assembly: AssemblyProduct("JetBrains.ReSharper.Plugins.NuGet")]
+[assembly: AssemblyCopyright("Copyright © JetBrains, 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: AssemblyVersion("0.1.0.0")]
+[assembly: AssemblyFileVersion("0.1.0.0")]
+
+// The following information is displayed by ReSharper in the Plugins dialog
+[assembly: PluginTitle("NuGet support for ReSharper")]
+[assembly: PluginDescription("Adds support for NuGet references in ReSharper")]
+[assembly: PluginVendor("JetBrains")]
View
4 src/resharper-nuget/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="NuGet.VisualStudio" version="2.1.0" targetFramework="net45" />
+</packages>
View
10 src/resharper-nuget/resharper-nuget-debugging.proj
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <!-- See http://blogs.clariusconsulting.net/kzu/how-to-set-the-startup-program-for-debugging-a-project-for-the-entire-team/ -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+ <StartAction>Program</StartAction>
+ <StartProgram>C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe</StartProgram>
+ <StartArguments>/ReSharper.Plugin JetBrains.ReSharper.Plugins.NuGet.dll /ReSharper.Internal</StartArguments>
+ <StartWorkingDirectory>$(MSBuildProjectDirectory)\bin\Debug\</StartWorkingDirectory>
+ </PropertyGroup>
+</Project>
View
77 src/resharper-nuget/resharper-nuget.csproj
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{7AF55DF9-33DA-4E50-B6E5-ADE407376D4E}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>JetBrains.ReSharper.Plugins.NuGet</RootNamespace>
+ <AssemblyName>JetBrains.ReSharper.Plugins.NuGet</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>JET_MODE_ASSERT;DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ </Reference>
+ <Reference Include="Microsoft.VisualStudio.ComponentModelHost, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.ComponentModelHost.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.VisualStudio.OLE.Interop, Version=7.1.40304.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+ <Reference Include="NuGet.VisualStudio">
+ <HintPath>..\..\packages\NuGet.VisualStudio.2.1.0\lib\net40\NuGet.VisualStudio.dll</HintPath>
+ <EmbedInteropTypes>True</EmbedInteropTypes>
+ </Reference>
+ <Reference Include="PresentationCore" />
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.Composition" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ <Reference Include="WindowsBase" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="ExposeNuGetServices.cs" />
+ <Compile Include="NuGetApi.cs" />
+ <Compile Include="NuGetModuleReferencer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ReSharperSdkTargets Condition=" '$(ReSharperSdkTargets)' == '' ">$(MSBuildExtensionsPath)\JetBrains\ReSharper.SDK\v7.0</ReSharperSdkTargets>
+ </PropertyGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(ReSharperSdkTargets)\Plugin.Targets" />
+ <Import Project="resharper-nuget-debugging.proj" />
+</Project>

0 comments on commit 0385e18

Please sign in to comment.
Something went wrong with that request. Please try again.