diff --git a/NuSave.Core/IPackageExtensions.cs b/NuSave.Core/IPackageExtensions.cs
index e038158..3cc524d 100644
--- a/NuSave.Core/IPackageExtensions.cs
+++ b/NuSave.Core/IPackageExtensions.cs
@@ -9,10 +9,5 @@ public static string GetFileName(this IPackage package)
{
return $"{package.Id}.{package.Version}.nupkg".ToLower();
}
-
- public static string GetHierarchialDirPath(this IPackage package, string baseDir)
- {
- return Path.Combine(baseDir, package.Id.ToLower(), package.Version.ToString());
- }
}
}
diff --git a/NuSave.Core/MsBuildPackageRef.cs b/NuSave.Core/MsBuildPackageRef.cs
new file mode 100644
index 0000000..38b1ab6
--- /dev/null
+++ b/NuSave.Core/MsBuildPackageRef.cs
@@ -0,0 +1,8 @@
+namespace NuSave.Core
+{
+ public class MsBuildPackageRef
+ {
+ public string Include { get; set; }
+ public string Version { get; set; }
+ }
+}
diff --git a/NuSave.Core/NuSave.Core.csproj b/NuSave.Core/NuSave.Core.csproj
index 7f94b4b..ea5f4c5 100644
--- a/NuSave.Core/NuSave.Core.csproj
+++ b/NuSave.Core/NuSave.Core.csproj
@@ -52,6 +52,7 @@
+
diff --git a/NuSave.Core/NuSave.cs b/NuSave.Core/NuSave.cs
index 3f739ed..000923c 100644
--- a/NuSave.Core/NuSave.cs
+++ b/NuSave.Core/NuSave.cs
@@ -6,6 +6,7 @@
using System.Linq;
using System.Net;
using System.Threading;
+using System.Xml.Linq;
namespace NuSave.Core
{
@@ -34,7 +35,7 @@ public Downloader(
{
_source = source;
_outputDirectory = outputDirectory;
- _id = id ?? throw new ArgumentException("id cannot be null");
+ _id = id;
_version = version;
_allowPreRelease = allowPreRelease;
_allowUnlisted = allowUnlisted;
@@ -72,7 +73,8 @@ public void Download()
{
try
{
- webClient.DownloadFile(dataServcePackage.DownloadUrl, Path.Combine(_outputDirectory, package.GetFileName()));
+ string nugetPackageOutputPath = GetNuGetPackagePath(package.Id, package.Version.ToString());
+ webClient.DownloadFile(dataServcePackage.DownloadUrl, nugetPackageOutputPath);
break;
}
catch (WebException e)
@@ -86,7 +88,7 @@ public void Download()
}
}
- public void ResolveDependencies()
+ public void ResolveDependencies(string csprojPath = null)
{
if (_toDownload != null && _toDownload.Count > 1)
{
@@ -100,26 +102,95 @@ public void ResolveDependencies()
Console.ResetColor();
}
- ResolveDependencies(Package);
+ if (csprojPath == null)
+ {
+ IPackage package = string.IsNullOrWhiteSpace(_version) ?
+ Repository.FindPackage(_id) :
+ Repository.FindPackage(_id, SemanticVersion.Parse(_version), _allowPreRelease, _allowUnlisted);
+
+ if (package == null) throw new Exception("Could not resolve package");
+
+ ResolveDependencies(package);
+ }
+ else
+ {
+ XNamespace @namespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+ XDocument csprojDoc = XDocument.Load(csprojPath);
+
+ IEnumerable references = csprojDoc
+ .Element(@namespace + "Project")
+ .Elements(@namespace + "ItemGroup")
+ .Elements(@namespace + "PackageReference")
+ .Select(e => new MsBuildPackageRef()
+ {
+ Include = e.Attribute("Include").Value,
+ Version = e.Element(@namespace + "Version").Value
+ });
+ ResolveDependencies(references);
+
+ IEnumerable dotnetCliToolReferences = csprojDoc
+ .Element(@namespace + "Project")
+ .Elements(@namespace + "ItemGroup")
+ .Elements(@namespace + "DotNetCliToolReference")
+ .Select(e => new MsBuildPackageRef()
+ {
+ Include = e.Attribute("Include").Value,
+ Version = e.Element(@namespace + "Version").Value
+ });
+ ResolveDependencies(dotnetCliToolReferences);
+ }
if (_json)
{
Console.WriteLine(JsonConvert.SerializeObject(GetDependencies()));
}
}
+
+ void ResolveDependencies(IEnumerable references)
+ {
+ foreach (var packageRef in references)
+ {
+ Console.ForegroundColor = ConsoleColor.Green;
+ Console.WriteLine($"{packageRef.Include} {packageRef.Version}");
+ Console.ResetColor();
+
+ ResolveDependencies(packageRef);
+ }
+ }
+
+ string GetNuGetPackagePath(string id, string version)
+ {
+ return Path.Combine(_outputDirectory, $"{id}.{version}.nupkg".ToLower());
+ }
+
+ string GetNuGetHierarchialDirPath(string id, string version)
+ {
+ return Path.Combine(_outputDirectory, id.ToLower(), version);
+ }
bool PackageExists(string id, string version)
{
- string nupkgFileName = $"{id}.{version}.nupkg".ToLower();
+ string nugetPackagePath = GetNuGetPackagePath(id, version);
+ if (File.Exists(nugetPackagePath)) return true;
- if (File.Exists(Path.Combine(_outputDirectory, nupkgFileName))) return true;
- if (Directory.Exists(Path.Combine(_outputDirectory, id.ToLower(), version))) return true;
+ string nuGetHierarchialDirPath = GetNuGetHierarchialDirPath(id, version);
+ if (Directory.Exists(nuGetHierarchialDirPath)) return true;
return false;
- }
+ }
+
+ void ResolveDependencies(MsBuildPackageRef msBuildpackageRef)
+ {
+ IPackage nugetPackage = Repository.FindPackage(msBuildpackageRef.Include, SemanticVersion.Parse(msBuildpackageRef.Version), true, true);
+ ResolveDependencies(nugetPackage);
+ }
void ResolveDependencies(IPackage package)
{
+ if (PackageExists(package.Id, package.Version.ToString())) return;
+
+ _toDownload.Add(package);
+
foreach (var set in package.DependencySets)
{
foreach (var dependency in set.Dependencies)
@@ -129,17 +200,25 @@ void ResolveDependencies(IPackage package)
var found = Repository.FindPackage(
dependency.Id,
dependency.VersionSpec,
- _allowPreRelease,
- _allowUnlisted);
-
- if (!_toDownload.Any(p => p.Title == found.Title && p.Version == found.Version))
+ true,
+ true);
+ if (found == null)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine($"Could not resolve dependency: {dependency.Id} {dependency.VersionSpec.ToString()}");
+ Console.ResetColor();
+ }
+ else
{
- _toDownload.Add(found);
- if (!_silent)
+ if (!_toDownload.Any(p => p.Title == found.Title && p.Version == found.Version))
{
- Console.WriteLine($"{found.Id} {found.Version}");
+ _toDownload.Add(found);
+ if (!_silent)
+ {
+ Console.WriteLine($"{found.Id} {found.Version}");
+ }
+ ResolveDependencies(found);
}
- ResolveDependencies(found);
}
}
}
@@ -176,25 +255,6 @@ public List GetDependencies()
return list;
}
- IPackage _package;
- IPackage Package
- {
- get
- {
- if (_package == null)
- {
- _package = string.IsNullOrWhiteSpace(_version) ?
- Repository.FindPackage(_id) :
- Repository.FindPackage(_id, SemanticVersion.Parse(_version), _allowPreRelease, _allowUnlisted);
-
- if (_package == null) throw new Exception("Could not resolve package");
-
- _toDownload.Add(_package);
- }
- return _package;
- }
- }
-
IPackageRepository _repository;
IPackageRepository Repository
{
diff --git a/NuSave/Program.cs b/NuSave/Program.cs
index fea3439..e6f421f 100644
--- a/NuSave/Program.cs
+++ b/NuSave/Program.cs
@@ -12,6 +12,7 @@ static void Main(string[] args)
{
CommandLineApplication app = new CommandLineApplication();
+ var msbuildProject = app.Option("-msbuildProject", "MSBuild Project file", CommandOptionType.SingleValue);
var source = app.Option("-source", "Package source", CommandOptionType.SingleValue);
var packageId = app.Option("-id", "Package ID", CommandOptionType.SingleValue);
var outputDirectory = app.Option("-outputDirectory", "Output directory", CommandOptionType.SingleValue);
@@ -46,7 +47,15 @@ static void Main(string[] args)
silent: silent.HasValue(),
json: json.HasValue());
- downloader.ResolveDependencies();
+ if (msbuildProject.HasValue())
+ {
+ downloader.ResolveDependencies(msbuildProject.Value());
+ }
+ else
+ {
+ downloader.ResolveDependencies();
+ }
+
if (!noDownload.HasValue())
{
downloader.Download();
diff --git a/README.md b/README.md
index 752afcf..137e865 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,15 @@ Don't forget to add the location of `NuSave.exe` to the `$PATH`.
.NET Framework 4.6.2 is need to build and run `NuSave`.
-## Commands
+## More
+
+### Download nuget packages from a .csproj MSBuild project
+
+```shell
+NuSave -msbuildProject "/path/to/project.csproj" -outputDirectory "/path/to/output/dir"
+```
+
+### Pipe the JSON result to PowerShell's `Out-GridView`
`NuSave` is able to output the dependency list without downloading it, and formatting the output as JSON, that way you can pipe the content to another program that will use this information to do other tasks, this can be the case for build scripts. The following command will pipe the content to PowerShell's `Out-GridView` :
@@ -32,37 +40,7 @@ The result:
![outgridview](https://raw.githubusercontent.com/anass-b/NuSave/master/readme/outgridview.png)
-#### -?
-
-Help.
-
-### -outputDirectory
-
-The directory where to save the downloaded packages.
-
-### -version
-
-Specifies the package version that needs to be downloaded.
-
-### -allowPreRelease
-
-Enabled of pre-release packages.
-
-### -allowUnlisted
-
-Enabled unlisted packages.
-
-### -silent
-
-No console output.
-
-### -json
-
-Get a clean output with no messages "except on errors", which is JSON formatted.
-
-### -noDownload
-
-Don't download the packages, just get a list of packages that will be downloaded if we omit this option.
+Check `NuSave -help` for more command line options.