Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read packages from packages.config #17

Merged
merged 4 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/NuGetUtility/Extensions/ProjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public static bool IsPackageReferenceProject(this IProject project)
!project.HasPackagesConfigFile();
}

public static string GetPackagesConfigPath(this IProject project)
{
return Path.Join(Path.GetDirectoryName(project.FullPath), PackagesConfigFileName);
}

private static bool HasPackagesConfigFile(this IProject project)
{
return project.GetEvaluatedIncludes().Any(include => include?.Equals(PackagesConfigFileName) ?? false);
Expand Down
1 change: 1 addition & 0 deletions src/NuGetUtility/NuGetUtility.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
<PackageReference Include="NuGet.Commands" Version="6.8.0" />
<PackageReference Include="NuGet.Packaging" Version="6.8.0" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.0" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ public IEnumerable<PackageIdentity> GetInstalledPackages(string projectPath, boo
return Enumerable.Empty<PackageIdentity>();
}

return GetInstalledPackagesFromAssetsFile(includeTransitive, project);
if (project.IsPackageReferenceProject())
return GetInstalledPackagesFromAssetsFile(includeTransitive, project);

return PackagesConfigReader.GetPackages(project.GetPackagesConfigPath());
}

private IEnumerable<PackageIdentity> GetInstalledPackagesFromAssetsFile(bool includeTransitive,
Expand Down
48 changes: 39 additions & 9 deletions src/NuGetUtility/Wrapper/MsBuildWrapper/MsBuildAbstraction.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Management;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
Expand All @@ -12,10 +13,17 @@ namespace NuGetUtility.Wrapper.MsBuildWrapper
public class MsBuildAbstraction : IMsBuildAbstraction
{
private const string CollectPackageReferences = "CollectPackageReferences";
private readonly Dictionary<string, string> _project_props = new();

public MsBuildAbstraction()
{
RegisterMsBuildLocatorIfNeeded();

// to support VC-projects we need to workaround : https://github.com/3F/MvsSln/issues/1
// adding 'VCTargetsPath' to Project::GlobalProperties seem to be enough

if (GetBestVCTargetsPath() is string path)
_project_props.Add("VCTargetsPath", $"{path}\\");
}

public IEnumerable<PackageReference> GetPackageReferencesFromProjectForFramework(IProject project,
Expand All @@ -40,16 +48,9 @@ public IProject GetProject(string projectPath)
{
ProjectRootElement rootElement = TryGetProjectRootElement(projectPath);

var project = new Project(rootElement);
var projectWrapper = new ProjectWrapper(project);

if (!projectWrapper.IsPackageReferenceProject())
{
throw new MsBuildAbstractionException(
$"Invalid project structure detected. Currently only PackageReference projects are supported (Project: {project.FullPath})");
}
var project = new Project(rootElement, _project_props, null);

return projectWrapper;
return new ProjectWrapper(project);
}

public IEnumerable<string> GetProjectsFromSolution(string inputPath)
Expand All @@ -59,6 +60,35 @@ public IEnumerable<string> GetProjectsFromSolution(string inputPath)
return sln.ProjectsInOrder.Select(p => p.AbsolutePath);
}

private static string? GetBestVCTargetsPath()
{
var cpp_props = new List<FileInfo>();

foreach (string path in GetVisualStudioInstallPaths())
cpp_props.AddRange(new DirectoryInfo(path).GetFiles("Microsoft.Cpp.Default.props", SearchOption.AllDirectories));

// if multiple, assume most recent 'LastWriteTime' property is 'best'
return cpp_props.OrderBy(f => f.LastWriteTime).LastOrDefault()?.DirectoryName;
}

private static IEnumerable<string> GetVisualStudioInstallPaths()
{
// https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2022#using-windows-management-instrumentation-wmi

var result = new List<string>();

if (OperatingSystem.IsWindows())
{
var mmc = new ManagementClass("root/cimv2/vs:MSFT_VSInstance");

foreach (ManagementBaseObject? vs_instance in mmc.GetInstances())
if (vs_instance["InstallLocation"] is string install_path)
result.Add(install_path);
}

return result;
}

private static void RegisterMsBuildLocatorIfNeeded()
{
if (!MSBuildLocator.IsRegistered)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Xml.Linq;
using NuGetUtility.Wrapper.NuGetWrapper.Versioning;

namespace NuGetUtility.Wrapper.NuGetWrapper.Packaging.Core
{
public static class PackagesConfigReader
{
public static IEnumerable<PackageIdentity> GetPackages(string path)
{
var document = XDocument.Load(path);

var reader = new NuGet.Packaging.PackagesConfigReader(document);

return reader.GetPackages().Select(p => new PackageIdentity(p.PackageIdentity.Id, new WrappedNuGetVersion(p.PackageIdentity.Version)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,13 @@ public void GetInstalledPackagesShould_ReturnEmptyEnumerableForProjectsWithoutPa

[Test]
[Platform(Include = "Win")]
public void GetInstalledPackagesShould_ThrowMsBuildAbstractionException_If_ProjectUsesPackagesConfig()
public void GetInstalledPackagesShould_ReturnPackagesForPackagesConfigProject()
{
string path = Path.GetFullPath("../../../../targets/PackagesConfigProject/PackagesConfigProject.csproj");

MsBuildAbstractionException? exception = Assert.Throws<MsBuildAbstractionException>(() => _uut!.GetInstalledPackages(path, false));
Assert.That(exception?.Message, Is.EqualTo($"Invalid project structure detected. Currently only PackageReference projects are supported (Project: {path})"));
IEnumerable<PackageIdentity> result = _uut!.GetInstalledPackages(path, false);

Assert.That(result.Count, Is.EqualTo(1));
}
}
}