Skip to content

Commit

Permalink
Downloading packages from .csproj/MSBuild files
Browse files Browse the repository at this point in the history
  • Loading branch information
Anass Bouassaba committed Dec 13, 2016
1 parent d330d66 commit b700fca
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 73 deletions.
5 changes: 0 additions & 5 deletions NuSave.Core/IPackageExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
}
8 changes: 8 additions & 0 deletions NuSave.Core/MsBuildPackageRef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace NuSave.Core
{
public class MsBuildPackageRef
{
public string Include { get; set; }
public string Version { get; set; }
}
}
1 change: 1 addition & 0 deletions NuSave.Core/NuSave.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MsBuildPackageRef.cs" />
<Compile Include="IPackageExtensions.cs" />
<Compile Include="NuSave.cs" />
<Compile Include="SimplifiedPackageInfo.cs" />
Expand Down
130 changes: 95 additions & 35 deletions NuSave.Core/NuSave.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Net;
using System.Threading;
using System.Xml.Linq;

namespace NuSave.Core
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -86,7 +88,7 @@ public void Download()
}
}

public void ResolveDependencies()
public void ResolveDependencies(string csprojPath = null)
{
if (_toDownload != null && _toDownload.Count > 1)
{
Expand All @@ -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<MsBuildPackageRef> 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<MsBuildPackageRef> 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<MsBuildPackageRef> 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)
Expand All @@ -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);
}
}
}
Expand Down Expand Up @@ -176,25 +255,6 @@ public List<SimplifiedPackageInfo> 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
{
Expand Down
11 changes: 10 additions & 1 deletion NuSave/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down
42 changes: 10 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` :

Expand All @@ -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.



0 comments on commit b700fca

Please sign in to comment.