/// <summary> /// Performs a cleanup and consistency check for the package store. /// </summary> /// <param name="packageIndex">Interface used to ensure that the package index is correct.</param> /// <exception cref="ArgumentNullException"><paramref name="packageIndex"/> is null.</exception> public override void Clean(IPackageIndex packageIndex) { if (packageIndex == null) { throw new ArgumentNullException("packageIndex"); } InitPackageStore(); _logger.Debug("Clean('" + packageIndex + "') called"); if (_fileSystemOperations.DirectoryExists(RootPath)) { _logger.DebugFormat("Enumerating directories in {0}...", RootPath); IEnumerable <string> packageDirectories; try { packageDirectories = _fileSystemOperations.EnumerateDirectories(RootPath); } catch (Exception ex) { _logger.Error(string.Format("Could not access RootPath '{0}'. Skipping feed cleanup.", RootPath), ex); return; } foreach (var packageDirectory in packageDirectories) { _logger.DebugFormat("Enumerating all nupkg files in packageDirectory '{0}'", packageDirectory); bool any = false; var packageFileNames = _fileSystemOperations.EnumerateFiles(packageDirectory, "*.nupkg"); foreach (var fileName in packageFileNames) { _logger.DebugFormat("Inspecting package '{0}'", fileName); var localFileName = _fileSystemOperations.GetFileName(fileName); any = true; try { using (var stream = TryOpenStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) { if (stream != null) { _logger.DebugFormat("Validating {0}...", localFileName); if (packageIndex.ValidatePackage(stream)) { _logger.DebugFormat("Verifying that {0} is the correct file name...", localFileName); stream.Position = 0; var package = NuGetPackage.ReadFromNupkgFile(stream); var expectedFileName = package.Id + "." + package.Version + ".nupkg"; if (!string.Equals(localFileName, expectedFileName, StringComparison.OrdinalIgnoreCase)) { _logger.WarnFormat("File {0} has incorrect name; should be {1}", localFileName, expectedFileName); _logger.DebugFormat("Renaming {0} to {1}...", localFileName, expectedFileName); var fullExpectedFileName = Path.Combine(packageDirectory, expectedFileName); if (File.Exists(fullExpectedFileName)) { try { _logger.Debug("Deleting target file '" + fullExpectedFileName + "'"); _fileSystemOperations.DeleteFile(fullExpectedFileName); } catch (Exception ex) { _logger.Error("Exception while deleting target file '" + fullExpectedFileName + "'", ex); } } try { _logger.DebugFormat("Moving package from '{0}' to '{1}'.", fileName, fullExpectedFileName); _fileSystemOperations.MoveFile(fileName, fullExpectedFileName); _logger.Debug("Package renamed."); } catch (Exception ex) { _logger.Error("Could not rename package.", ex); } } } } } } catch (Exception ex) { _logger.Error(string.Format("Could not validate '{0}'", fileName), ex); StoredProcs.PackageIndexingErrors_LogIndexingError(FeedId, localFileName, ex.Message, Encoding.UTF8.GetBytes(ex.StackTrace ?? string.Empty) ).Execute(); } } if (!any) { try { _logger.DebugFormat("Deleting empty directory {0}...", packageDirectory); _fileSystemOperations.DeleteDirectory(packageDirectory); } catch { _logger.Warn("Directory could not be deleted; it may not be empty."); } } } packageIndex.RemoveRemaining(); } else { _logger.DebugFormat("Package root path '{0}' not found. Nothing to do.", RootPath); } }
public override void Import(IBuildImporterContext context) { var configurer = (NuGetConfigurer)this.GetExtensionConfigurer(); if (configurer.AlwaysClearNuGetCache) { this.LogDebug("Clearing NuGet cache..."); if (NuGetConfigurer.ClearCache()) { this.LogDebug("Cache cleared!"); } else { this.LogWarning("Error clearing cache; a file may be locked."); } } var nugetExe = configurer != null ? configurer.NuGetExe : null; if (string.IsNullOrEmpty(nugetExe)) { nugetExe = Path.Combine(Path.GetDirectoryName(typeof(NuGetBuildImporter).Assembly.Location), "nuget.exe"); } var packageSource = Util.CoalesceStr(this.PackageSource, configurer != null ? configurer.PackageSource : null); var args = "install \"" + this.PackageId + "\" -ExcludeVersion -NoCache"; if (!string.IsNullOrEmpty(this.PackageVersion)) { args += " -Version \"" + this.PackageVersion + "\""; } if (this.IncludePrerelease) { args += " -Prerelease"; } if (!string.IsNullOrEmpty(packageSource)) { args += " -Source \"" + packageSource + "\""; } var tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { Directory.CreateDirectory(tempPath); args += " -OutputDirectory \"" + tempPath + "\""; if (!string.IsNullOrWhiteSpace(this.AdditionalArguments)) { args += " " + this.AdditionalArguments; } this.LogDebug($"Executing {nugetExe} {args}"); this.LogInformation("Executing NuGet..."); using (var process = new LocalProcess(new RemoteProcessStartInfo { FileName = nugetExe, Arguments = args })) { process.OutputDataReceived += this.Process_OutputDataReceived; process.ErrorDataReceived += this.Process_ErrorDataReceived; process.Start(); process.WaitForExit(); if (process.ExitCode != 0) { this.LogError($"NuGet failed with exit code {process.ExitCode}."); return; } } this.LogInformation("NuGet indicated successful package install."); var packageRootPath = Path.Combine(tempPath, this.PackageId); var artifactName = this.PackageId; if (this.CaptureIdAndVersion || this.IncludeVersionInArtifactName) { try { var nupkgPath = Path.Combine(packageRootPath, this.PackageId + ".nupkg"); this.LogDebug($"Attempting to gather metadata from {nupkgPath}..."); var nuspec = NuGetPackage.ReadFromNupkgFile(nupkgPath); var packageId = nuspec.Id; var packageVersion = nuspec.Version.OriginalString; if (this.CaptureIdAndVersion) { this.LogDebug("Setting $ImportedPackageId = " + packageId); SetBuildVariable(context, "ImportedPackageId", packageId); this.LogDebug("Setting $ImportedPackageVersion = " + packageVersion); SetBuildVariable(context, "ImportedPackageVersion", packageVersion); } if (this.IncludeVersionInArtifactName) { artifactName = packageId + "." + packageVersion; } } catch (Exception ex) { this.LogError("Could not read package metadata: " + ex.ToString()); return; } } var rootCapturePath = Path.Combine(packageRootPath, (this.PackageArtifactRoot ?? string.Empty).Replace('/', '\\').TrimStart('/', '\\')); this.LogDebug($"Capturing files in {rootCapturePath}..."); var rootEntry = Util.Files.GetDirectoryEntry( new GetDirectoryEntryCommand { Path = rootCapturePath, IncludeRootPath = true, Recurse = true } ).Entry; using (var agent = BuildMasterAgent.CreateLocalAgent()) { var fileOps = agent.GetService <IFileOperationsExecuter>(); var matches = Util.Files.Comparison.GetMatches(rootCapturePath, rootEntry, new[] { "!\\" + this.PackageId + ".nupkg", "*" }); var artifactId = new ArtifactIdentifier(context.ApplicationId, context.ReleaseNumber, context.BuildNumber, context.DeployableId, artifactName); this.LogInformation($"Creating artifact {artifactName}..."); using (var artifact = new ArtifactBuilder(artifactId)) { artifact.RootPath = rootCapturePath; foreach (var match in matches) { artifact.Add(match, fileOps); } artifact.Commit(); } this.LogInformation("Artifact created."); } } finally { try { DirectoryEx.Delete(tempPath); } catch { } } }