/// <summary> /// Enable package retention and update settings. /// </summary> public static async Task <bool> UpdateRetentionSettings(SleetContext context, int stableVersionMax, int prereleaseVersionMax) { var exitCode = true; var log = context.Log; var feedSettings = context.SourceSettings; feedSettings.RetentionMaxStableVersions = stableVersionMax; feedSettings.RetentionMaxPrereleaseVersions = prereleaseVersionMax; await FeedSettingsUtility.SaveSettings(context.Source, feedSettings, log, context.Token); // Commit changes to source exitCode = await context.Source.Commit(log, context.Token); if (exitCode) { await log.LogAsync(LogLevel.Minimal, $"Successfully updated package retention settings. Stable: {stableVersionMax} Prerelease: {prereleaseVersionMax}."); await log.LogAsync(LogLevel.Minimal, $"Run prune to apply the new settings and remove packages from the feed."); } else { await log.LogAsync(LogLevel.Error, "Failed to update package retention settings."); } return(exitCode); }
/// <summary> /// Run prune /// 1. Lock the feed /// 2. Verify client compat /// 3. Prune packges /// 4. Commit /// </summary> public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, RetentionPruneCommandContext pruneContext, ILogger log) { var exitCode = true; log.LogMinimal($"Pruning packages in {source.BaseURI}"); var token = CancellationToken.None; // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Prune", log, token)) { // Validate source await UpgradeUtility.EnsureCompatibility(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; exitCode = await PrunePackages(context, pruneContext); } return(exitCode); }
/// <summary> /// Remove package retention settings. /// </summary> public static async Task <bool> DisableRetention(SleetContext context) { var exitCode = true; var log = context.Log; var feedSettings = context.SourceSettings; feedSettings.RetentionMaxStableVersions = null; feedSettings.RetentionMaxPrereleaseVersions = null; await FeedSettingsUtility.SaveSettings(context.Source, feedSettings, log, context.Token); // Commit changes to source exitCode = await context.Source.Commit(log, context.Token); if (exitCode) { await log.LogAsync(LogLevel.Minimal, "Package retention disabled."); } else { await log.LogAsync(LogLevel.Error, "Failed to disable retention settings."); } return(exitCode); }
public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, bool enableCatalog, bool enableSymbols, ILogger log, CancellationToken token) { var feedSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); feedSettings.CatalogEnabled = enableCatalog; feedSettings.SymbolsEnabled = enableSymbols; return(await InitAsync(settings, source, feedSettings, log, token)); }
/// <summary> /// Lock the feed and delete all packages given. /// </summary> public static async Task <bool> DeletePackagesAsync(LocalSettings settings, ISleetFileSystem source, IEnumerable <PackageIdentity> packagesToDelete, string reason, bool force, ILogger log) { var success = true; var token = CancellationToken.None; log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Delete", log, token)) { // Validate source await SourceUtility.ValidateFeedForClient(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; var packageIndex = new PackageIndex(context); var existingPackageSets = await packageIndex.GetPackageSetsAsync(); var packages = new HashSet <PackageIdentity>(packagesToDelete); if (string.IsNullOrEmpty(reason)) { reason = string.Empty; } await RemovePackages(force, log, context, existingPackageSets, packages); // Save all log.LogMinimal($"Committing changes to {source.BaseURI.AbsoluteUri}"); success &= await source.Commit(log, token); } if (success) { log.LogMinimal($"Successfully deleted packages."); } else { log.LogError($"Failed to delete packages."); } return(success); }
private static async Task <bool> CreateSettingsAsync(ISleetFileSystem source, FeedSettings feedSettings, ILogger log, CancellationToken token, DateTimeOffset now, JObject serviceIndexJson) { AddServiceIndexEntry(source.BaseURI, "sleet.settings.json", "http://schema.emgarten.com/sleet#SettingsFile/1.0.0", "Sleet feed settings.", serviceIndexJson); // Create new file. var result = await CreateFromTemplateAsync(source, log, now, "Settings", "sleet.settings.json", token); // Write out the current settings. await FeedSettingsUtility.SaveSettings(source, feedSettings, log, token); return(result); }
/// <summary> /// Push packages to a feed. /// This assumes the feed is already locked. /// </summary> public static async Task <bool> PushPackages(LocalSettings settings, ISleetFileSystem source, List <PackageInput> packages, bool force, bool skipExisting, ILogger log, CancellationToken token) { var exitCode = true; var now = DateTimeOffset.UtcNow; // Verify no duplicate packages CheckForDuplicates(packages); // Get sleet.settings.json await log.LogAsync(LogLevel.Minimal, "Reading feed"); var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token, PerfTracker = source.LocalCache.PerfTracker }; await log.LogAsync(LogLevel.Verbose, "Reading existing package index"); // Push var packageIndex = new PackageIndex(context); var existingPackageSets = await packageIndex.GetPackageSetsAsync(); await PushPackages(packages, context, existingPackageSets, force, skipExisting, log); // Prune packages await PrunePackages(packages, context); // Save all await log.LogAsync(LogLevel.Minimal, $"Committing changes to {source.BaseURI.AbsoluteUri}"); await source.Commit(log, token); if (exitCode) { await log.LogAsync(LogLevel.Minimal, "Successfully pushed packages."); } else { await log.LogAsync(LogLevel.Error, "Failed to push packages."); } return(exitCode); }
public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, ILogger log) { var exitCode = true; log.LogMinimal($"Stats for {source.BaseURI}"); var token = CancellationToken.None; // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Stats", log, token)) { // Validate source await UpgradeUtility.EnsureFeedVersionMatchesTool(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; var packageIndex = new PackageIndex(context); var existingPackageSets = await packageIndex.GetPackageSetsAsync(); var uniqueIds = existingPackageSets.Packages.Index .Concat(existingPackageSets.Symbols.Index) .Select(e => e.Id).Distinct(StringComparer.OrdinalIgnoreCase); log.LogMinimal($"Packages: {existingPackageSets.Packages.Index.Count}"); log.LogMinimal($"Symbols Packages: {existingPackageSets.Symbols.Index.Count}"); log.LogMinimal($"Unique package ids: {uniqueIds.Count()}"); } return(exitCode); }
/// <summary> /// Enable/Disable retention and commit /// </summary> public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, int stableVersionMax, int prereleaseVersionMax, bool disableRetention, ILogger log) { var exitCode = false; log.LogMinimal($"Updating package retention settings in {source.BaseURI}"); var token = CancellationToken.None; // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Prune", log, token)) { // Validate source await UpgradeUtility.EnsureCompatibility(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; if (disableRetention && stableVersionMax < 1 && prereleaseVersionMax < 1) { // Remove settings exitCode = await DisableRetention(context); } else if (stableVersionMax > 0 && prereleaseVersionMax > 0) { // Add max version settings exitCode = await UpdateRetentionSettings(context, stableVersionMax, prereleaseVersionMax); } } return(exitCode); }
public static async Task <bool> RunAsync( LocalSettings settings, ISleetFileSystem source, bool unsetAll, bool getAll, IEnumerable <string> getSettings, IEnumerable <string> unsetSettings, IEnumerable <string> setSettings, ILogger log, CancellationToken token) { log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Feed settings", log, token)) { // Validate source await UpgradeUtility.EnsureCompatibility(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; var success = await ApplySettingsAsync(context, unsetAll, getAll, getSettings, unsetSettings, setSettings); log.LogMinimal($"Run 'recreate' to rebuild the feed with the new settings."); return(success); } }
/// <summary> /// Validate packages. This does not lock or verify the version of the feed. /// </summary> public static async Task <bool> Validate(LocalSettings settings, ISleetFileSystem source, ILogger log, CancellationToken token) { var success = true; // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; // Create all services var services = new List <ISleetService>(); var registrations = new Registrations(context); var flatContainer = new FlatContainer(context); var search = new Search(context); var autoComplete = new AutoComplete(context); var packageIndex = new PackageIndex(context); if (context.SourceSettings.CatalogEnabled) { // Add the catalog only if it is enabled var catalog = new Catalog(context); services.Add(catalog); } services.Add(registrations); services.Add(flatContainer); services.Add(search); if (context.SourceSettings.SymbolsEnabled) { var symbols = new Symbols(context); services.Add(symbols); } // Verify against the package index var indexedPackages = await packageIndex.GetPackagesAsync(); var allIndexIds = indexedPackages.Select(e => e.Id).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); // Get symbols packages from index var indexedSymbolsPackages = await packageIndex.GetSymbolsPackagesAsync(); var allIndexSymbolsIds = indexedSymbolsPackages.Select(e => e.Id).Distinct(StringComparer.OrdinalIgnoreCase).ToList(); // Verify auto complete log.LogMinimal($"Validating {autoComplete.Name}"); var autoCompleteIds = await autoComplete.GetPackageIds(); var missingACIds = allIndexIds.Except(autoCompleteIds).ToList(); var extraACIds = autoCompleteIds.Except(allIndexIds).ToList(); if (missingACIds.Count() > 0 || extraACIds.Count() > 0) { log.LogError("Missing autocomplete packages: " + string.Join(", ", missingACIds)); log.LogError("Extra autocomplete packages: " + string.Join(", ", extraACIds)); success = false; } else { log.LogMinimal("Autocomplete packages valid"); } // Verify everything else foreach (var service in services) { log.LogMinimal($"Validating {service.Name}"); var validatableService = service as IValidatableService; if (validatableService != null) { // Run internal validations if the service supports it. var messages = await validatableService.ValidateAsync(); success &= messages.All(e => e.Level != LogLevel.Error); foreach (var message in messages) { await log.LogAsync(message); } } else { var allPackagesService = service as IPackagesLookup; var byIdService = service as IPackageIdLookup; var allSymbolsPackagesService = service as ISymbolsPackagesLookup; var symbolsByIdService = service as ISymbolsPackageIdLookup; var servicePackages = new HashSet <PackageIdentity>(); var serviceSymbolsPackages = new HashSet <PackageIdentity>(); // Non-Symbols packages if (allPackagesService != null) { // Use get all if possible servicePackages.UnionWith(await allPackagesService.GetPackagesAsync()); } else if (byIdService != null) { foreach (var id in allIndexIds) { servicePackages.UnionWith(await byIdService.GetPackagesByIdAsync(id)); } } else { log.LogError($"Unable to get packages for {service.Name}"); continue; } var diff = new PackageDiff(indexedPackages, servicePackages); if (diff.HasErrors) { log.LogError(diff.ToString()); success = false; } else { log.LogMinimal(diff.ToString()); log.LogMinimal($"{service.Name} packages valid"); } // Symbols packages if (allSymbolsPackagesService != null) { // Use get all if possible serviceSymbolsPackages.UnionWith(await allSymbolsPackagesService.GetSymbolsPackagesAsync()); } else if (symbolsByIdService != null) { foreach (var id in allIndexSymbolsIds) { serviceSymbolsPackages.UnionWith(await symbolsByIdService.GetSymbolsPackagesByIdAsync(id)); } } else { // Symbols are not supported by this service continue; } var symbolsDiff = new PackageDiff(indexedSymbolsPackages, serviceSymbolsPackages); if (symbolsDiff.HasErrors) { log.LogError(symbolsDiff.ToString()); success = false; } else { log.LogMinimal(symbolsDiff.ToString()); log.LogMinimal($"{service.Name} symbols packages valid"); } } } if (success) { log.LogMinimal($"Feed valid"); } else { log.LogError($"Feed invalid!"); } return(success); }
/// <summary> /// Download packages. This method does not lock the feed or verify the client version. /// </summary> public static async Task <bool> DownloadPackages(LocalSettings settings, ISleetFileSystem source, string outputPath, bool ignoreErrors, bool skipExisting, ILogger log, CancellationToken token) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentException("Missing output path parameter!"); } var success = true; // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); // Find all packages var packageIndex = new PackageIndex(context); var flatContainer = new FlatContainer(context); var symbols = new Symbols(context); // Discover all packages var packages = new List <KeyValuePair <PackageIdentity, ISleetFile> >(); packages.AddRange((await packageIndex.GetPackagesAsync()).Select(e => new KeyValuePair <PackageIdentity, ISleetFile>(e, context.Source.Get(flatContainer.GetNupkgPath(e))))); packages.AddRange((await packageIndex.GetSymbolsPackagesAsync()).Select(e => new KeyValuePair <PackageIdentity, ISleetFile>(e, symbols.GetSymbolsNupkgFile(e)))); log.LogMinimal($"Downloading nupkgs to {outputPath}"); // Run downloads var tasks = packages.Select(e => new Func <Task <bool> >(() => DownloadPackageAsync(outputPath, skipExisting, log, e, token))); var results = await TaskUtils.RunAsync(tasks, useTaskRun : true, token : CancellationToken.None); var downloadSuccess = results.All(e => e); success &= downloadSuccess; if (packages.Count < 1) { log.LogWarning("The feed does not contain any packages."); } if (downloadSuccess) { if (packages.Count > 0) { log.LogMinimal("Successfully downloaded packages."); } } else { var message = $"Failed to download all packages!"; if (ignoreErrors) { log.LogWarning(message); } else { log.LogError(message); } } return(success); }
public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, string packageId, string version, string reason, bool force, ILogger log) { var success = true; var token = CancellationToken.None; var now = DateTimeOffset.UtcNow; log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); // Check if already initialized using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, log, token)) { // Validate source await SourceUtility.ValidateFeedForClient(source, log, token); // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; var packageIndex = new PackageIndex(context); var packages = new List <PackageIdentity>(); if (!string.IsNullOrEmpty(version)) { // Delete a single version of the package var packageVersion = NuGetVersion.Parse(version); packages.Add(new PackageIdentity(packageId, packageVersion)); } else { // Delete all versions of the package packages.AddRange(await packageIndex.GetPackagesByIdAsync(packageId)); } if (string.IsNullOrEmpty(reason)) { reason = string.Empty; } foreach (var package in packages) { var exists = await packageIndex.Exists(package); var symbolsExists = await packageIndex.SymbolsExists(package); if (!exists && !symbolsExists) { log.LogInformation($"{package.ToString()} does not exist."); if (force) { // ignore failures continue; } else { throw new InvalidOperationException($"Package does not exists: {package.ToString()}"); } } var message = $"Removing {package.ToString()}"; if (exists && symbolsExists) { message = $"Removing {package.ToString()} and symbols package for {package.ToString()}"; } else if (symbolsExists) { message = $"Removing symbols package {package.ToString()}"; } await log.LogAsync(LogLevel.Information, message); await SleetUtility.RemovePackage(context, package); } // Save all log.LogMinimal($"Committing changes to {source.BaseURI.AbsoluteUri}"); success &= await source.Commit(log, token); } if (success) { log.LogMinimal($"Successfully deleted packages."); } else { log.LogError($"Failed to delete packages."); } return(success); }
/// <summary> /// Download packages. This method does not lock the feed or verify the client version. /// </summary> public static async Task <bool> DownloadPackages(LocalSettings settings, ISleetFileSystem source, string outputPath, bool ignoreErrors, ILogger log, CancellationToken token) { if (string.IsNullOrEmpty(outputPath)) { throw new ArgumentException("Missing output path parameter!"); } var success = true; // Get sleet.settings.json var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); // Find all packages var packageIndex = new PackageIndex(context); var flatContainer = new FlatContainer(context); var symbols = new Symbols(context); // Discover all packages var packages = new List <KeyValuePair <PackageIdentity, ISleetFile> >(); packages.AddRange((await packageIndex.GetPackagesAsync()).Select(e => new KeyValuePair <PackageIdentity, ISleetFile>(e, context.Source.Get(flatContainer.GetNupkgPath(e))))); packages.AddRange((await packageIndex.GetSymbolsPackagesAsync()).Select(e => new KeyValuePair <PackageIdentity, ISleetFile>(e, symbols.GetSymbolsNupkgFile(e)))); var tasks = new List <Task <bool> >(MaxThreads); var downloadSuccess = true; log.LogMinimal($"Downloading nupkgs to {outputPath}"); foreach (var pair in packages) { if (tasks.Count >= MaxThreads) { downloadSuccess &= await CompleteTask(tasks); } var package = pair.Key; var nupkgFile = pair.Value; var fileName = UriUtility.GetFileName(nupkgFile.EntityUri); // id/id.version.nupkg or id/id.version.symbols.nupkg var outputNupkgPath = Path.Combine(outputPath, package.Id.ToLowerInvariant(), fileName.ToLowerInvariant()); log.LogInformation($"Downloading {outputNupkgPath}"); tasks.Add(nupkgFile.CopyTo(outputNupkgPath, overwrite: true, log: log, token: token)); } while (tasks.Count > 0) { downloadSuccess &= await CompleteTask(tasks); } success &= downloadSuccess; if (packages.Count < 1) { log.LogWarning("The feed does not contain any packages."); } if (downloadSuccess) { if (packages.Count > 0) { log.LogMinimal("Successfully downloaded packages."); } } else { var message = $"Failed to download all packages!"; if (ignoreErrors) { log.LogWarning(message); } else { log.LogError(message); } } return(success); }
public static async Task <bool> ApplySettingsAsync( ISleetFileSystem source, bool unsetAll, bool getAll, IEnumerable <string> getSettings, IEnumerable <string> unsetSettings, IEnumerable <string> setSettings, ILogger log, CancellationToken token) { var feedSettings = FeedSettingsUtility.GetSettingsFileFromFeed(source); var feedSettingsJson = await feedSettings.GetJson(log, CancellationToken.None); var settings = FeedSettingsUtility.GetSettings(feedSettingsJson); var getKeys = new SortedSet <string>(getSettings, StringComparer.OrdinalIgnoreCase); var setKeys = new SortedSet <string>(setSettings, StringComparer.OrdinalIgnoreCase); var unsetKeys = new SortedSet <string>(unsetSettings, StringComparer.OrdinalIgnoreCase); if ((getKeys.Count + setKeys.Count + unsetKeys.Count) == 0 && !unsetAll && !getAll) { throw new ArgumentException("No arguments specified."); } if (getAll) { getKeys.UnionWith(settings.Keys); } if (unsetAll) { unsetKeys.UnionWith(settings.Keys); } if (getKeys.Count > 0 && (setKeys.Count + unsetKeys.Count) > 0) { throw new ArgumentException("Invalid combination of arguments. Get may not be combined with set or unset."); } // Get foreach (var key in getKeys) { if (!settings.TryGetValue(key, out var value)) { value = "not found!"; } log.LogMinimal($"{key} : {value}"); } // Unset foreach (var key in unsetKeys) { if (settings.ContainsKey(key)) { settings.Remove(key); } } // Set var setKeysSeen = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var input in setKeys) { var parts = input.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length != 2 || string.IsNullOrEmpty(parts[0]?.Trim()) || string.IsNullOrEmpty(parts[1]?.Trim())) { throw new ArgumentException("Value must be in the form {key}:{value}. Invalid: '" + input + "'"); } var key = parts[0].Trim().ToLowerInvariant(); var value = parts[1].Trim(); if (!setKeysSeen.Add(key)) { throw new ArgumentException($"Duplicate values for '{key}'. This value may only be set once."); } if (settings.ContainsKey(key)) { settings[key] = value; } else { settings.Add(key, value); } } if (setKeys.Count > 0 || unsetKeys.Count > 0) { FeedSettingsUtility.Set(feedSettingsJson, settings); log.LogMinimal($"Updating settings"); await feedSettings.Write(feedSettingsJson, log, token); // Save all log.LogMinimal($"Committing changes to {source.BaseURI.AbsoluteUri}"); return(await source.Commit(log, token)); } return(true); }
public static async Task <bool> RunAsync(LocalSettings settings, ISleetFileSystem source, string tmpPath, bool force, ILogger log) { var success = true; var cleanNupkgs = true; var token = CancellationToken.None; LocalCache localCache = null; // Use the tmp path if provided if (string.IsNullOrEmpty(tmpPath)) { localCache = new LocalCache(); } else { localCache = new LocalCache(tmpPath); } log.LogMinimal($"Reading feed {source.BaseURI.AbsoluteUri}"); using (var feedLock = await SourceUtility.VerifyInitAndLock(settings, source, "Recreate", log, token)) { if (!force) { // Validate source await UpgradeUtility.EnsureCompatibility(source, log : log, token : token); } // Read settings and persist them in the new feed. var feedSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); try { var downloadSuccess = await DownloadCommand.DownloadPackages(settings, source, localCache.Root.FullName, force, log, token); if (!force && !downloadSuccess) { log.LogError("Unable to recreate the feed due to errors download packages. Use --force to skip this check."); return(false); } var destroySuccess = await DestroyCommand.Destroy(settings, source, log, token); if (!force && !destroySuccess) { log.LogError("Unable to completely remove the old feed before recreating. Use --force to skip this check."); return(false); } var initSuccess = await InitCommand.InitAsync(settings, source, feedSettings, log, token); if (!initSuccess) { cleanNupkgs = false; log.LogError("Unable to initialize the new feed. The feed is currently broken and must be repaired manually."); success = false; return(false); } // Skip pushing for empty feeds if (Directory.GetFiles(localCache.Root.FullName, "*.*", SearchOption.AllDirectories).Length > 0) { var pushSuccess = await PushCommand.PushPackages(settings, source, new List <string>() { localCache.Root.FullName }, force : true, skipExisting : true, log : log, token : token); if (!pushSuccess) { cleanNupkgs = false; log.LogError("Unable to push packages to the new feed. Try pushing the nupkgs again manually."); success = false; return(false); } } var validateSuccess = await ValidateCommand.Validate(settings, source, log, token); if (!validateSuccess) { cleanNupkgs = false; log.LogError("Something went wrong when recreating the feed. Feed validation has failed."); success = false; return(false); } } finally { if (cleanNupkgs) { // Delete downloaded nupkgs log.LogInformation($"Removing local nupkgs from {localCache.Root.FullName}"); localCache.Dispose(); } else { var message = $"Encountered an error while recreating the feed. You may need to manually create the feed and push the nupkgs again. Nupkgs have been saved to: {localCache.Root.FullName}"; if (force) { log.LogWarning(message); } else { log.LogError(message); } } } log.LogMinimal("Feed recreation complete."); } return(success); }
public static async Task <bool> PushPackages(LocalSettings settings, ISleetFileSystem source, List <string> inputs, bool force, bool skipExisting, ILogger log, CancellationToken token) { var exitCode = true; var now = DateTimeOffset.UtcNow; var packages = new List <PackageInput>(); try { // Get packages packages.AddRange(GetPackageInputs(inputs, now, log)); // Get sleet.settings.json await log.LogAsync(LogLevel.Minimal, "Reading feed"); var sourceSettings = await FeedSettingsUtility.GetSettingsOrDefault(source, log, token); // Settings context used for all operations var context = new SleetContext() { LocalSettings = settings, SourceSettings = sourceSettings, Log = log, Source = source, Token = token }; // Fetch feed await SleetUtility.FetchFeed(context); await log.LogAsync(LogLevel.Information, "Reading existing package index"); var packageIndex = new PackageIndex(context); foreach (var package in packages) { await PushPackage(package, context, packageIndex, force, skipExisting, log); } // Save all await log.LogAsync(LogLevel.Minimal, $"Committing changes to {source.BaseURI.AbsoluteUri}"); await source.Commit(log, token); } finally { // Close all zip readers foreach (var package in packages) { package.Dispose(); } } if (exitCode) { await log.LogAsync(LogLevel.Minimal, "Successfully pushed packages."); } else { await log.LogAsync(LogLevel.Error, "Failed to push packages."); } return(exitCode); }