Skip to content

Commit

Permalink
nuget.exe add and nuget.exe init which are simpler and always needs a
Browse files Browse the repository at this point in the history
mandatory source and destination feed for add and init respectively.
Need to fix tests
  • Loading branch information
deepakaravindr committed Oct 15, 2015
1 parent 5eefae0 commit 5272f06
Show file tree
Hide file tree
Showing 17 changed files with 979 additions and 322 deletions.
29 changes: 15 additions & 14 deletions src/NuGet.Clients/NuGet.CommandLine/Commands/AddCommand.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
using System;
using System.IO;
using System.Threading;
using System.Threading;
using System.Threading.Tasks;
using NuGet.Configuration;
using NuGet.Packaging;

namespace NuGet.CommandLine
{
[Command(typeof(NuGetCommand), "add", "AddCommandDescription;DefaultConfigDescription",
MinArgs = 1, MaxArgs = 2, UsageDescriptionResourceName = "AddCommandUsageDescription",
[Command(typeof(NuGetCommand), "add", "AddCommandDescription",
MinArgs = 1, MaxArgs = 1, UsageDescriptionResourceName = "AddCommandUsageDescription",
UsageSummaryResourceName = "AddCommandUsageSummary", UsageExampleResourceName = "AddCommandUsageExamples")]
public class AddCommand : Command
{
[Option(typeof(NuGetCommand), "AddCommandSourceDescription", AltName = "src")]
public string Source { get; set; }

[Option(typeof(NuGetCommand), "ExpandDescription")]
public bool Expand { get; set; }

public override async Task ExecuteCommandAsync()
{
// Arguments[0] will not be null at this point.
// Because, this command has MinArgs set to 1.
var packagePath = Arguments[0];
OfflineFeedUtility.ValidatePath(packagePath);

if (!File.Exists(packagePath))
if (string.IsNullOrEmpty(Source))
{
throw new CommandLineException(
LocalizedResourceManager.GetString(nameof(NuGetResources.NupkgPath_NotFound)),
packagePath);
LocalizedResourceManager.GetString(nameof(NuGetResources.AddCommand_SourceNotProvided)));
}

Source = OfflineFeedUtility.GetEffectiveSourceFeedFolder(Source, Settings);
OfflineFeedUtility.ValidatePath(Source);
OfflineFeedUtility.ThrowIfInvalidOrNotFound(
packagePath,
isDirectory: false,
nameOfNotFoundErrorResource: nameof(NuGetResources.NupkgPath_NotFound));

// If the Source Feed Folder does not exist, it will be created.
OfflineFeedUtility.ThrowIfInvalid(Source);

var offlineFeedAddContext = new OfflineFeedAddContext(
packagePath,
Source,
Console, // IConsole is an ILogger
throwIfSourcePackageIsInvalid: true,
throwIfPackageExistsAndInvalid: true,
throwIfPackageExists: false);
throwIfPackageExists: false,
expand: Expand);

await OfflineFeedUtility.AddPackageToSource(offlineFeedAddContext, CancellationToken.None);
}
Expand Down
128 changes: 109 additions & 19 deletions src/NuGet.Clients/NuGet.CommandLine/Commands/InitCommand.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
using System.Globalization;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NuGet.Configuration;

namespace NuGet.CommandLine
{
[Command(typeof(NuGetCommand), "init", "InitCommandDescription;DefaultConfigDescription",
MinArgs = 1, MaxArgs = 2, UsageDescriptionResourceName = "InitCommandUsageDescription",
[Command(typeof(NuGetCommand), "init", "InitCommandDescription",
MinArgs = 2, MaxArgs = 2, UsageDescriptionResourceName = "InitCommandUsageDescription",
UsageSummaryResourceName = "InitCommandUsageSummary", UsageExampleResourceName = "InitCommandUsageExamples")]
public class InitCommand : Command
{
[Option(typeof(NuGetCommand), "ExpandDescription")]
public bool Expand { get; set; }

public override async Task ExecuteCommandAsync()
{
// Arguments[0] will not be null at this point.
// Because, this command has MinArgs set to 1.
// Arguments[0] or Arguments[1] will not be null at this point.
// Because, this command has MinArgs set to 2.
var source = Arguments[0];
OfflineFeedUtility.ValidatePath(source);
var destination = Arguments[1];

if (!Directory.Exists(source))
{
throw new CommandLineException(
LocalizedResourceManager.GetString(nameof(NuGetResources.InitCommand_FeedIsNotFound)),
source);
}
OfflineFeedUtility.ThrowIfInvalidOrNotFound(
source,
isDirectory: true,
nameOfNotFoundErrorResource: nameof(NuGetResources.InitCommand_FeedIsNotFound));

var destination = Arguments.Count >= 2
? Arguments[1] : SettingsUtility.GetOfflineFeed(Settings);
OfflineFeedUtility.ValidatePath(destination);
// If the Destination Feed Folder does not exist, it will be created.
OfflineFeedUtility.ThrowIfInvalid(destination);

var packagePaths = Directory.EnumerateFiles(source, "*.nupkg");
var packagePaths = GetPackageFilePaths(source, "*" + ProjectManagement.Constants.PackageExtension);

if (packagePaths.Any())
if (packagePaths.Count > 0)
{
foreach (var packagePath in packagePaths)
{
Expand All @@ -42,7 +42,8 @@ public override async Task ExecuteCommandAsync()
Console, // IConsole is an ILogger
throwIfSourcePackageIsInvalid: false,
throwIfPackageExistsAndInvalid: false,
throwIfPackageExists: false);
throwIfPackageExists: false,
expand: Expand);

await OfflineFeedUtility.AddPackageToSource(offlineFeedAddContext, CancellationToken.None);
}
Expand All @@ -57,5 +58,94 @@ public override async Task ExecuteCommandAsync()
Console.LogInformation(message);
}
}

/// <summary>
/// Helper method based on LocalPackageRepository and ExpandedPackageRepository
/// to avoid dependency on NuGet.Core. Links to the classes are
/// https://github.com/NuGet/NuGet2/blob/2.9/src/Core/Repositories/LocalPackageRepository.cs
/// AND
/// https://github.com/NuGet/NuGet2/blob/2.9/src/Core/Repositories/ExpandedPackageRepository.cs
/// </summary>
private static IReadOnlyList<string> GetPackageFilePaths(string source, string nupkgFilter)
{
var packagePaths = new List<string>();
var isV2StyleFolderSource = IsV2StyleFolderSource(source, nupkgFilter);

if (!isV2StyleFolderSource.HasValue)
{
// There are no nupkg files, v2-style or v3-style, under 'source'.
return packagePaths;
}

if (isV2StyleFolderSource.Value)
{
foreach (var idDirectory in Directory.EnumerateDirectories(source))
{
// Since we need the .nupkg file for nuget.exe init, PackageSaveMode.Nuspec is not supported.
// And, Default search option for EnumerateFiles is top directory only.
var packagesAtIdDirectory = Directory.EnumerateFiles(idDirectory, nupkgFilter);

packagePaths.AddRange(packagesAtIdDirectory);
}

var packagesAtRoot = Directory.EnumerateFiles(source, nupkgFilter);
packagePaths.AddRange(packagesAtRoot);
}
else
{
foreach (var idDirectory in Directory.EnumerateDirectories(source))
{
var packageId = Path.GetFileName(idDirectory);

foreach (var versionDirectory in Directory.EnumerateDirectories(idDirectory))
{
var packagesAtVersionDirectory = Directory.EnumerateFiles(versionDirectory, nupkgFilter);
packagePaths.AddRange(packagesAtVersionDirectory);
}
}
}

return packagePaths;
}

/// <summary>
/// Helper method based on the LazyLocalPackageRepository.cs to avoid dependency on NuGet.Core
/// https://github.com/NuGet/NuGet2/blob/2.9/src/Core/Repositories/LazyLocalPackageRepository.cs#L74
/// </summary>
/// <returns>Return true if source v2 style folder. Otherwise, false.
/// If no nupkgs were found under the source, returns null</returns>
private static bool? IsV2StyleFolderSource(string source, string nupkgFilter)
{
var packagesAtRoot = Directory.EnumerateFiles(source, nupkgFilter);

if (packagesAtRoot.Any())
{
return true;
}

foreach (var idDirectory in Directory.EnumerateDirectories(source))
{
// Since we need the .nupkg file for nuget.exe init, PackageSaveMode.Nuspec is not supported.
// And, Default search option for EnumerateFiles is top directory only.
var packagesAtIdDirectory = Directory.EnumerateFiles(idDirectory, nupkgFilter);

if (packagesAtIdDirectory.Any())
{
return true;
}

foreach (var versionDirectory in Directory.EnumerateDirectories(idDirectory))
{
var packagesAtVersionDirectory = Directory.EnumerateFiles(versionDirectory, nupkgFilter);

if (packagesAtVersionDirectory.Any())
{
return false;
}
}
}

return null;
}
}
}
4 changes: 4 additions & 0 deletions src/NuGet.Clients/NuGet.CommandLine/NuGet.CommandLine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<Compile Include="CommandLineSourceRepositoryProvider.cs" />
<Compile Include="CommandManager.cs" />
<Compile Include="CommandOutputLogger.cs" />
<Compile Include="Commands\AddCommand.cs" />
<Compile Include="Commands\Command.cs" />
<Compile Include="Commands\CommandAttribute.cs" />
<Compile Include="Commands\ConfigCommand.cs" />
Expand All @@ -56,6 +57,7 @@
<Compile Include="Commands\HelpCommand.cs" />
<Compile Include="Commands\HelpCommandMarkdownTemplate.cs" />
<Compile Include="Commands\ICommand.cs" />
<Compile Include="Commands\InitCommand.cs" />
<Compile Include="Commands\InstallCommand.cs" />
<Compile Include="Commands\ListCommand.cs" />
<Compile Include="Commands\OptionAttribute.cs" />
Expand Down Expand Up @@ -107,6 +109,8 @@
<DesignTime>True</DesignTime>
<DependentUpon>NuGetResources.resx</DependentUpon>
</Compile>
<Compile Include="OfflineFeedAddContext.cs" />
<Compile Include="OfflineFeedUtility.cs" />
<Compile Include="PackageServer.cs" />
<Compile Include="PackageSourceBuilder.cs" />
<Compile Include="Program.cs" />
Expand Down
103 changes: 103 additions & 0 deletions src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5272f06

Please sign in to comment.