Skip to content

Commit 0dd425d

Browse files
PowerShellTeamSergei Vorobev
authored andcommitted
Integrate changes between [SD:717473] and [SD:725290]
1 parent 2280bea commit 0dd425d

28 files changed

Lines changed: 847 additions & 341 deletions

File tree

src/Microsoft.PackageManagement.CoreProviders/Bootstrap/BootstrapProvider.cs

Lines changed: 72 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ namespace Microsoft.PackageManagement.Providers.Internal.Bootstrap {
3232
using Directory = System.IO.Directory;
3333
using ErrorCategory = PackageManagement.Internal.ErrorCategory;
3434
using File = System.IO.File;
35-
using System.IO.Compression;
3635

3736
public class BootstrapProvider {
3837
private static readonly Dictionary<string, string[]> _features = new Dictionary<string, string[]> {
@@ -324,127 +323,12 @@ private bool InstallProviderFromInstaller(Package provider, Link link, string fa
324323
return false;
325324
}
326325

327-
case Iso19770_2.MediaType.NuGetPackage:
328-
return InstallNugetPackage(provider, link, fastPath, request);
329-
330326
default:
331327
request.Warning("Provider '{0}' with link '{1}' has unknown media type '{2}'.", provider.Name, link.HRef, link.MediaType);
332328
return false;
333329
}
334330
}
335331

336-
private bool InstallNugetPackage(Package provider, Link link, string fastPath, BootstrapRequest request)
337-
{
338-
// download the nuget package
339-
string downloadedNupkg = request.DownloadAndValidateFile(provider._swidtag);
340-
341-
if (downloadedNupkg != null)
342-
{
343-
// extracted folder
344-
string extractedFolder = String.Concat(FilesystemExtensions.GenerateTemporaryFileOrDirectoryNameInTempDirectory());
345-
346-
try
347-
{
348-
//unzip the file
349-
ZipFile.ExtractToDirectory(downloadedNupkg, extractedFolder);
350-
351-
if (Directory.Exists(extractedFolder))
352-
{
353-
string versionFolder = Path.Combine(request.DestinationPath(request), provider.Name, provider.Version);
354-
// tool folder is where we find things like nuget.exe
355-
string toolFolder = Path.Combine(extractedFolder, "tools");
356-
string libFolder = Path.Combine(extractedFolder, "lib");
357-
358-
// create the directory version folder if not exist
359-
if (!Directory.Exists(versionFolder))
360-
{
361-
Directory.CreateDirectory(versionFolder);
362-
}
363-
364-
// copy the tools directory
365-
if (Directory.Exists(toolFolder))
366-
{
367-
string destinationToolFolder = Path.Combine(versionFolder, "tools");
368-
369-
if (!Directory.Exists(destinationToolFolder))
370-
{
371-
Directory.CreateDirectory(destinationToolFolder);
372-
}
373-
374-
foreach (string child in Directory.EnumerateFiles(toolFolder))
375-
{
376-
try
377-
{
378-
// try copy and overwrite
379-
File.Copy(child, Path.Combine(destinationToolFolder, Path.GetFileName(child)), true);
380-
}
381-
catch (Exception e)
382-
{
383-
request.Debug(e.StackTrace);
384-
if (!(e is UnauthorizedAccessException || e is IOException))
385-
{
386-
// something wrong, delete the version folder
387-
versionFolder.TryHardToDelete();
388-
return false;
389-
}
390-
391-
// otherwise this means the file is just being used. so just moves on to copy other files
392-
}
393-
}
394-
}
395-
396-
// copy files from lib
397-
if (Directory.Exists(libFolder))
398-
{
399-
// check that the lib folder has at most 1 dll
400-
if (Directory.EnumerateFiles(libFolder).Count(file => String.Equals(Path.GetExtension(file), ".dll", StringComparison.OrdinalIgnoreCase)) > 1)
401-
{
402-
request.Warning(String.Format(CultureInfo.CurrentCulture, Resources.Messages.MoreThanOneDllExists, provider.Name));
403-
return false;
404-
}
405-
406-
foreach (string child in Directory.EnumerateFiles(libFolder))
407-
{
408-
try
409-
{
410-
File.Copy(child, Path.Combine(versionFolder, Path.GetFileName(child)), true);
411-
}
412-
catch (Exception e)
413-
{
414-
request.Debug(e.StackTrace);
415-
if (!(e is UnauthorizedAccessException || e is IOException))
416-
{
417-
// something wrong, delete the version folder
418-
versionFolder.TryHardToDelete();
419-
return false;
420-
}
421-
422-
// otherwise this means the file is just being used. so just moves on to copy other files
423-
}
424-
}
425-
}
426-
427-
// target file name is the assembly provider
428-
string targetFile = Path.Combine(versionFolder, Path.GetFileName(link.Attributes[Iso19770_2.Discovery.TargetFilename]));
429-
430-
if (File.Exists(targetFile))
431-
{
432-
request.Verbose(Resources.Messages.InstalledPackage, provider.Name, targetFile);
433-
request.YieldFromSwidtag(provider, fastPath);
434-
return true;
435-
}
436-
}
437-
}
438-
finally
439-
{
440-
downloadedNupkg.TryHardToDelete();
441-
extractedFolder.TryHardToDelete();
442-
}
443-
}
444-
445-
return false;
446-
}
447-
448332
private bool InstallPackageFile(Package provider, string fastPath, BootstrapRequest request) {
449333
// we can download and verify this package and get the core to install it.
450334
var file = request.DownloadAndValidateFile(provider._swidtag);
@@ -522,7 +406,6 @@ private bool InstallAssemblyProvider(Package provider, Link link, string fastPat
522406
return false;
523407
}
524408

525-
526409
string targetFilename = fastPath;
527410
string file = fastPath;
528411

@@ -532,7 +415,7 @@ private bool InstallAssemblyProvider(Package provider, Link link, string fastPat
532415
targetFilename = link.Attributes[Iso19770_2.Discovery.TargetFilename];
533416

534417
// download the file
535-
file = request.DownloadAndValidateFile(provider._swidtag);
418+
file = request.DownloadAndValidateFile(provider._swidtag);
536419

537420
}
538421

@@ -551,22 +434,23 @@ private bool InstallAssemblyProvider(Package provider, Link link, string fastPat
551434
//... providername\version\.dll
552435
var versionFolder = Path.Combine(request.DestinationPath(request), provider.Name, provider.Version);
553436

554-
if (!Directory.Exists(versionFolder)) {
555-
//we create it
437+
// if version folder exists, remove it
438+
if (Directory.Exists(versionFolder))
439+
{
440+
RemoveDirectory(versionFolder);
441+
}
442+
443+
// create the directory if we successfully deleted it
444+
if (!Directory.Exists(versionFolder))
445+
{
556446
Directory.CreateDirectory(versionFolder);
557447
}
558448

559449
var targetFile = Path.Combine(versionFolder, targetFilename);
560-
450+
561451
if (file != null) {
562452
try
563453
{
564-
// looks good! let's keep it
565-
if (File.Exists(targetFile)) {
566-
request.Debug("Removing old file '{0}'", targetFile);
567-
targetFile.TryHardToDelete();
568-
}
569-
570454
// is that file still there?
571455
if (File.Exists(targetFile)) {
572456
request.Error(ErrorCategory.InvalidOperation, fastPath, Constants.Messages.UnableToRemoveFile, targetFile);
@@ -575,7 +459,16 @@ private bool InstallAssemblyProvider(Package provider, Link link, string fastPat
575459

576460
request.Debug("Copying file '{0}' to '{1}'", file, targetFile);
577461
try {
578-
File.Copy(file, targetFile);
462+
if (File.Exists(file))
463+
{
464+
// if this is a file
465+
File.Copy(file, targetFile);
466+
}
467+
else if (Directory.Exists(file))
468+
{
469+
// if this is a directory, copy items over
470+
CopyDirectory(file, versionFolder);
471+
}
579472
}
580473
catch (Exception ex) {
581474
request.Debug(ex.StackTrace);
@@ -599,11 +492,61 @@ private bool InstallAssemblyProvider(Package provider, Link link, string fastPat
599492
file.TryHardToDelete();
600493
}
601494
}
602-
}
495+
}
603496

604497
return false;
605498
}
606499

500+
private void RemoveDirectory(string directoryFolder)
501+
{
502+
// remove all files
503+
foreach (var fileToBeRemoved in Directory.EnumerateFiles(directoryFolder))
504+
{
505+
fileToBeRemoved.TryHardToDelete();
506+
}
507+
508+
// remove all subdirectories
509+
foreach (var folderToBeRemoved in Directory.EnumerateDirectories(directoryFolder))
510+
{
511+
RemoveDirectory(folderToBeRemoved);
512+
}
513+
514+
try
515+
{
516+
// now try to remove the directory
517+
Directory.Delete(directoryFolder);
518+
}
519+
catch { }
520+
}
521+
522+
private void CopyDirectory(string sourceFolder, string destinationFolder)
523+
{
524+
// check that source and destination folders exist
525+
if (!sourceFolder.DirectoryExists() || !destinationFolder.DirectoryExists())
526+
{
527+
return;
528+
}
529+
530+
// copy the files over
531+
foreach (var file in Directory.EnumerateFiles(sourceFolder))
532+
{
533+
File.Copy(file, Path.Combine(destinationFolder, Path.GetFileName(file)), true);
534+
}
535+
536+
// copy the directories over
537+
foreach (var directory in Directory.EnumerateDirectories(sourceFolder))
538+
{
539+
var destinationDirName = Path.Combine(destinationFolder, Path.GetFileName(directory));
540+
541+
if (!Directory.Exists(destinationDirName))
542+
{
543+
Directory.CreateDirectory(destinationDirName);
544+
}
545+
546+
CopyDirectory(directory, destinationDirName);
547+
}
548+
}
549+
607550
private void InstallPackageFromFile(string fastPath, BootstrapRequest request)
608551
{
609552
var filePath = new Uri(fastPath).LocalPath;

src/Microsoft.PackageManagement.CoreProviders/Bootstrap/BootstrapRequest.cs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ namespace Microsoft.PackageManagement.Providers.Internal.Bootstrap {
2929
using PackageManagement.Internal.Utility.Collections;
3030
using PackageManagement.Internal.Utility.Extensions;
3131
using ErrorCategory = PackageManagement.Internal.ErrorCategory;
32+
using System.IO.Compression;
33+
using File = System.IO.File;
34+
using Directory = System.IO.Directory;
3235

3336
public abstract class BootstrapRequest : Request {
3437
internal Uri[] _urls
@@ -201,6 +204,51 @@ internal string DownloadAndValidateFile(Swidtag swidtag) {
201204
}
202205
}
203206

207+
/// <summary>
208+
/// Extract zipped package and return the unzipped folder
209+
/// </summary>
210+
/// <param name="zippedPackagePath"></param>
211+
/// <returns></returns>
212+
private string ExtractZipPackage(string zippedPackagePath)
213+
{
214+
if (zippedPackagePath != null && zippedPackagePath.FileExists())
215+
{
216+
// extracted folder
217+
string extractedFolder = FilesystemExtensions.GenerateTemporaryFileOrDirectoryNameInTempDirectory();
218+
219+
try
220+
{
221+
//unzip the file
222+
ZipFile.ExtractToDirectory(zippedPackagePath, extractedFolder);
223+
224+
// extraction fails
225+
if (!Directory.Exists(extractedFolder))
226+
{
227+
Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.FailToExtract, zippedPackagePath, extractedFolder));
228+
return string.Empty;
229+
}
230+
231+
// the zipped folder
232+
var zippedDirectory = Directory.EnumerateDirectories(extractedFolder).FirstOrDefault();
233+
234+
if (!string.IsNullOrWhiteSpace(zippedDirectory) && Directory.Exists(zippedDirectory))
235+
{
236+
return zippedDirectory;
237+
}
238+
}
239+
catch (Exception ex)
240+
{
241+
Verbose(string.Format(CultureInfo.CurrentCulture, Resources.Messages.FailToInstallZipFolder, zippedPackagePath, ex.Message));
242+
Debug(ex.StackTrace);
243+
244+
// remove the extracted folder
245+
extractedFolder.TryHardToDelete();
246+
}
247+
}
248+
249+
return string.Empty;
250+
}
251+
204252
/// <summary>
205253
/// Helper function to retry downloading a file.
206254
/// downloadFileFunction is the main function that is used to download the file when given a uri
@@ -257,7 +305,22 @@ internal string DownLoadFileFromLinks(IEnumerable<Link> links) {
257305
link.HRef);
258306

259307
// got a valid file!
260-
if (file != null && file.FileExists()) {
308+
if (file != null && file.FileExists()) {
309+
// if file is zip, unpack it and return the unpacked folder
310+
if (link.MediaType == Iso19770_2.MediaType.ZipPackage)
311+
{
312+
try
313+
{
314+
// let's extract the zipped file
315+
return ExtractZipPackage(file);
316+
}
317+
finally
318+
{
319+
// delete the zipped file
320+
file.TryHardToDelete();
321+
}
322+
}
323+
261324
return file;
262325
}
263326
}

src/Microsoft.PackageManagement.CoreProviders/resources/Microsoft.PackageManagement.Providers.Resources.Messages.resx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@
121121
<value>Fail to extract and copy to '{0}'.</value>
122122
<comment>0 - The directory we are copying to</comment>
123123
</data>
124+
<data name="FailToDeleteExistingFolder" xml:space="preserve">
125+
<value>Cannot delete existing provider folder '{0}'.</value>
126+
</data>
127+
<data name="FailToExtract" xml:space="preserve">
128+
<value>Cannot extract from '{0}' to '{1}'</value>
129+
</data>
130+
<data name="FailToInstallZipFolder" xml:space="preserve">
131+
<value>Fail to extract zip package '{0}': '{1}'</value>
132+
<comment>0 - package path, 1 - exception message</comment>
133+
</data>
124134
<data name="FindingPackage" xml:space="preserve">
125135
<value>Finding the package '{0}'.</value>
126136
<comment>0 - package name</comment>

src/Microsoft.PackageManagement.NuGetProvider/Repository/LocalPackageRepository.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,17 @@ private IEnumerable<string> GetPackageLookupPaths(string packageId, SemanticVers
240240
var partialManifestNameMatches = GetPackageFiles(partialManifestName).Where(
241241
path => FileNameMatchesPattern(packageId, version, path));
242242

243-
return filesMatchingFullName.Concat(partialNameMatches).Concat(partialManifestNameMatches);
243+
filesMatchingFullName = filesMatchingFullName.Concat(partialNameMatches).Concat(partialManifestNameMatches);
244+
}
245+
246+
// cannot find matching files, we should try to search for just packageid.nupkg
247+
if (filesMatchingFullName.Count() == 0)
248+
{
249+
// exclude version
250+
var packageWithoutVersionName = FileUtility.MakePackageFileName(true, packageId, null, NuGetConstant.PackageExtension);
251+
var packageWithoutVersionManifest = Path.ChangeExtension(packageWithoutVersionName, NuGetConstant.ManifestExtension);
252+
253+
return GetPackageFiles(packageWithoutVersionName).Concat(GetPackageFiles(packageWithoutVersionManifest));
244254
}
245255

246256
return filesMatchingFullName;

0 commit comments

Comments
 (0)