public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var gitlab = new GitLabClient(this.Template.ApiUrl, this.Template.UserName, this.Template.Password, this.Template.GroupName); var milestones = await gitlab.GetMilestonesAsync(this.Template.ProjectName, null, context.CancellationToken).ConfigureAwait(false); var milestone = milestones.FirstOrDefault(m => string.Equals(m["title"]?.ToString() ?? string.Empty, this.Template.Title, StringComparison.OrdinalIgnoreCase)); if (milestone == null) { return(new GitLabMilestoneConfiguration { Exists = false }); } return(new GitLabMilestoneConfiguration { Exists = true, Title = milestone["title"]?.ToString() ?? string.Empty, Description = milestone["description"]?.ToString() ?? string.Empty, StartDate = milestone["start_date"]?.ToString(), DueDate = milestone["due_date"]?.ToString(), State = (GitLabMilestoneConfiguration.OpenOrClosed)Enum.Parse(typeof(GitLabMilestoneConfiguration.OpenOrClosed), milestone["state"]?.ToString()) }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var scriptName = this.DefaultArgument.AsString(); if (string.IsNullOrWhiteSpace(scriptName)) { this.LogError("Bad or missing script name."); return(null); } if (context.Simulation) { this.LogInformation("Executing PowerShell Script..."); return(null); } var result = await PSUtil.ExecuteScriptAssetAsync( logger : this, context : context, fullScriptName : scriptName, arguments : this.NamedArguments, outArguments : this.OutArguments, collectOutput : true, progressUpdateHandler : (s, e) => this.currentProgress = e, executionMode : PsExecutionMode.Collect ); this.collectedConfiguration = new PSPersistedConfiguration(result); return(this.collectedConfiguration); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var github = new GitHubClient(this.Template.ApiUrl, this.Template.UserName, this.Template.Password, this.Template.OrganizationName); var ownerName = AH.CoalesceString(this.Template.OrganizationName, this.Template.UserName); var release = await github.GetReleaseAsync(ownerName, this.Template.RepositoryName, this.Template.Tag, context.CancellationToken); if (release == null) { return(new GitHubReleaseConfiguration { Exists = false }); } return(new GitHubReleaseConfiguration { Tag = (string)release["tag_name"], Target = (string)release["target_commitish"], Title = (string)release["name"], Description = (string)release["body"], Draft = (bool)release["draft"], Prerelease = (bool)release["prerelease"] }); }
public async override Task <DictionaryConfiguration> CollectConfigAsync(IOperationCollectionContext context) { using (var serverContext = context.GetServerCollectionContext()) { var output = await this.ExecuteChocolateyAsync(context, "list --limit-output --local-only").ConfigureAwait(false); if (output == null) { return(null); } await serverContext.ClearAllPackagesAsync("Chocolatey").ConfigureAwait(false); foreach (var values in output) { string name = values[0]; string version = values[1]; await serverContext.CreateOrUpdatePackageAsync( packageType : "Chocolatey", packageName : name, packageVersion : version, packageUrl : null ).ConfigureAwait(false); } return(null); } }
public async override Task <DscConfiguration> CollectConfigAsync(IOperationCollectionContext context) { var job = new CollectDscModulesJob { DebugLogging = true }; job.MessageLogged += (s, e) => this.Log(e.Level, e.Message); var jobExecuter = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var result = (CollectDscModulesJob.Result) await jobExecuter.ExecuteJobAsync(job, context.CancellationToken); using (var serverContext = context.GetServerCollectionContext()) { await serverContext.ClearAllPackagesAsync("DSC Module"); foreach (var module in result.Modules) { await serverContext.CreateOrUpdatePackageAsync( packageType : "DSC Module", packageName : module.Name, packageVersion : module.Version, packageUrl : null ); } return(null); } }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var path = this.Template.Name; var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>().ConfigureAwait(false); this.LogDebug($"Looking for {path}..."); if (!await fileOps.DirectoryExistsAsync(path).ConfigureAwait(false)) { this.LogDebug("Directory does not exist."); return(new DirectoryConfiguration { Name = path, Exists = false }); } this.LogDebug("Directory exists, loading from disk..."); var config = new DirectoryConfiguration { Name = this.Template.Name }; var dir = await fileOps.GetDirectoryInfoAsync(path).ConfigureAwait(false); this.LogDebug("Directory configuration loaded."); return(config); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { if (!this.ValidateConfiguration()) { return(null); } int?exitCode; var output = new List <string>(); using (var scriptReader = this.OpenCollectScript(context)) { exitCode = await SHUtil.ExecuteScriptAsync( context, scriptReader, !string.IsNullOrWhiteSpace(this.CollectScriptAsset)?this.CollectScriptArgs : null, this, this.Verbose, !this.UseExitCode?(Action <string>) (s => { if (!string.IsNullOrWhiteSpace(s)) { output.Add(s); } }) : null ); } return(new KeyValueConfiguration { Key = this.ConfigurationKey, Value = this.UseExitCode ? exitCode?.ToString() : string.Join(Environment.NewLine, output) }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { if (!this.ValidateConfiguration()) { return(null); } ExecutePowerShellJob.Result result; if (!string.IsNullOrWhiteSpace(this.CollectScriptAsset)) { result = await PSUtil.ExecuteScriptAsync( logger : this, context : context, fullScriptName : this.CollectScriptAsset, arguments : this.CollectScriptParams ?? new Dictionary <string, RuntimeValue>(), outArguments : new Dictionary <string, RuntimeValue>(), collectOutput : !this.UseExitCode, progressUpdateHandler : (s, e) => Interlocked.Exchange(ref this.currentProgress, e) ); } else { var jobRunner = context.Agent.GetService <IRemoteJobExecuter>(); var job = new ExecutePowerShellJob { ScriptText = this.CollectScript, DebugLogging = this.DebugLogging, VerboseLogging = this.VerboseLogging, CollectOutput = !this.UseExitCode, LogOutput = this.UseExitCode, Variables = PowerShellScriptRunner.ExtractVariables(this.CollectScript, context) }; job.MessageLogged += (s, e) => this.Log(e.Level, e.Message); job.ProgressUpdate += (s, e) => Interlocked.Exchange(ref this.currentProgress, e); result = await jobRunner.ExecuteJobAsync(job, context.CancellationToken) as ExecutePowerShellJob.Result; } if (result.ExitCode != null) { this.LogDebug("Script exit code: " + result.ExitCode); } return(new KeyValueConfiguration { Key = this.ConfigurationKey, Value = this.UseExitCode ? result.ExitCode?.ToString() : string.Join(", ", result.Output) }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var path = this.Template.Name; var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>().ConfigureAwait(false); this.LogDebug($"Looking for {path}..."); if (!await fileOps.FileExistsAsync(path)) { this.LogDebug("File does not exist."); return(new FileConfiguration { Name = path, Exists = false }); } this.LogDebug("File exists, loading from disk..."); var file = await fileOps.GetFileInfoAsync(path); var config = new FileConfiguration { Name = this.Template.Name }; if (this.Template.Attributes.HasValue) { config.Attributes = file.Attributes; } if (this.Template.Contents != null) { config.Contents = await fileOps.ReadFileBytesAsync(path); } else if (this.Template.TextContents != null) { config.TextContents = await fileOps.ReadAllTextAsync(path); } if (this.Template.IsReadOnly.HasValue) { config.IsReadOnly = file.IsReadOnly; } if (this.Template.LastWriteTimeUtc != null) { config.LastWriteTimeUtc = file.LastWriteTimeUtc; } this.LogDebug("File configuration loaded."); return(config); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { IList <RegisteredPackage> packages; this.LogDebug("Connecting to machine package registry..."); using (var registry = await PackageRegistry.GetRegistryAsync(context.Agent, false).ConfigureAwait(false)) { this.LogDebug("Acquiring package registry lock..."); await registry.LockAsync(context.CancellationToken).ConfigureAwait(false); this.LogDebug($"Package registry lock acquired (token={registry.LockToken})."); this.LogInformation("Retreiving list of packages..."); packages = await registry.GetInstalledPackagesAsync().ConfigureAwait(false); this.LogInformation("Packages installed: " + packages.Count); // doesn't need to be in a finally because dispose will unlock if necessary, but prefer doing it asynchronously await registry.UnlockAsync().ConfigureAwait(false); } this.LogDebug("Recording installed packages..."); using (var collect = context.GetServerCollectionContext()) { await collect.ClearAllPackagesAsync("UPack"); foreach (var p in packages) { await collect.CreateOrUpdateUniversalPackageAsync( "UPack", string.IsNullOrWhiteSpace(p.Group)?p.Name : (p.Group + "/" + p.Name), p.Version, p.FeedUrl, new CollectedUniversalPackageData { Path = p.InstallPath, Cached = false, Date = p.InstallationDate, Reason = p.InstallationReason, Tool = p.InstalledUsing, User = p.InstalledBy } ); } } this.LogInformation("Package collection complete."); return(null); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var config = new KubernetesResourceConfiguration { ResourceType = this.Template.ResourceType, Namespace = this.Template.Namespace, Name = this.Template.Name, Exists = false }; using (var sw = new StringWriter()) { await this.RunKubeCtlAsync(context, "apply", new[] { "--dry-run", "--output", "json" }, sw.WriteLine); config.NormalizedApplied = sw.ToString(); } using (var sw = new StringWriter()) { await this.RunKubeCtlAsync(context, "create", new[] { "--dry-run", "--output", "json" }, sw.WriteLine); config.NormalizedTemplate = sw.ToString(); } var body = await this.GetCurrentConfigurationAsync(context, "json"); if (!string.IsNullOrWhiteSpace(body)) { config.NormalizedActual = body; config.Exists = true; // Use non-breaking spaces to allow easier reading in the UI. config.Spec = (await this.GetCurrentConfigurationAsync(context, "yaml")).Replace(' ', '\u00a0'); } return(config); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var buffer = new StringBuilder("upgrade --yes --limit-output --fail-on-unfound --what-if ", 200); if (!string.IsNullOrEmpty(this.Template.Source)) { buffer.Append("--source \""); buffer.Append(this.Template.Source); buffer.Append("\" "); } buffer.Append('\"'); buffer.Append(this.Template.PackageName); buffer.Append('\"'); var output = await this.ExecuteChocolateyAsync(context, buffer.ToString()); if (output == null || output.Count < 1 || output[0].Length < 4 || !string.Equals(output[0][3], "false", StringComparison.OrdinalIgnoreCase)) { // this assumes packages are never pinned this.LogInformation($"Package {this.Template.PackageName} is not installed."); return(new ChocolateyPackageConfiguration { Exists = false, PackageName = this.Template.PackageName, Source = this.Template.Source }); } var installedVersion = output[0][1]; var availableVersion = output[0][2]; this.LogInformation($"Package {this.Template.PackageName} is at version {availableVersion}."); this.LogInformation($"Version {installedVersion} is installed."); return(new ChocolateyPackageConfiguration { Exists = true, PackageName = this.Template.PackageName, Version = installedVersion, IsLatestVersion = string.Equals(installedVersion, availableVersion, StringComparison.OrdinalIgnoreCase), Source = this.Template.Source }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var gitlab = new GitLabClient(this.Template.ApiUrl, this.Template.UserName, this.Template.Password, this.Template.GroupName); var tag = await gitlab.GetTagAsync(this.Template.ProjectName, this.Template.Tag, context.CancellationToken).ConfigureAwait(false); if (tag == null || !tag.ContainsKey("release") || tag["release"] == null) { return(new GitLabReleaseConfiguration { Exists = false }); } var release = (Dictionary <string, object>)tag["release"]; return(new GitLabReleaseConfiguration { Tag = (string)release["tag_name"], Description = (string)release["description"] }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var features = await this.ExecuteChocolateyAsync(context, "feature list --limit-output"); var feature = features.Find(f => string.Equals(f[0], this.Template.Feature, StringComparison.OrdinalIgnoreCase)); if (feature == null) { this.LogError($"No such chocolatey feature: {this.Template.Feature}"); return(new ChocolateyFeatureConfiguration()); } return(new ChocolateyFeatureConfiguration { Feature = feature[0], Exists = AH.Switch <string, bool>(feature[1]) .Case("Enabled", true) .Case("Disabled", false) .End() }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var fileOps = await context.Agent.GetServiceAsync <IFileOperationsExecuter>(); var fileName = context.ResolvePath(this.FileName); if (!await fileOps.FileExistsAsync(fileName)) { return(this.GetConfiguration(null)); } using (var file = await fileOps.OpenFileAsync(fileName, FileMode.Open, FileAccess.Read)) { var doc = XDocument.Load(file); var keyElement = this.GetAppSettingsElements(doc) .Elements("add") .FirstOrDefault(e => string.Equals((string)e.Attribute("key"), this.ConfigurationKey, StringComparison.OrdinalIgnoreCase)); return(this.GetConfiguration((string)keyElement?.Attribute("value"))); } }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { string hostsPath; var fileOps = context.Agent.GetService <IFileOperationsExecuter>(); if (fileOps is ILinuxFileOperationsExecuter) { hostsPath = "/etc/hosts"; } else { var remoteMethod = context.Agent.GetService <IRemoteMethodExecuter>(); hostsPath = await remoteMethod.InvokeFuncAsync(GetHostsFilePath).ConfigureAwait(false); } this.LogDebug("Hosts file is at " + hostsPath); var entries = (from l in await fileOps.ReadAllLinesAsync(hostsPath).ConfigureAwait(false) where !string.IsNullOrWhiteSpace(l) && !CommentRegex.IsMatch(l) let e = EntryRegex.Match(l) where e.Success select new HostsEntryConfiguration { Exists = true, IpAddress = e.Groups[1].Value, HostName = e.Groups[2].Value }).ToLookup(e => e.HostName, StringComparer.OrdinalIgnoreCase); var matches = entries[this.Template.HostName]; return(matches.FirstOrDefault(e => string.Equals(e.IpAddress, this.Template.IpAddress, StringComparison.OrdinalIgnoreCase)) ?? matches.FirstOrDefault() ?? new HostsEntryConfiguration { Exists = false, IpAddress = this.Template.IpAddress, HostName = this.Template.HostName }); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { if (!this.ValidateConfiguration()) { return(null); } var result = await PSUtil.ExecuteScriptAsync( logger : this, context : context, scriptNameOrContent : AH.CoalesceString(this.CollectScriptAsset, this.CollectScript), scriptIsAsset : !string.IsNullOrWhiteSpace(this.CollectScriptAsset), arguments : this.CollectScriptParams ?? new Dictionary <string, RuntimeValue>(), outArguments : new Dictionary <string, RuntimeValue>(), collectOutput : !this.UseExitCode, progressUpdateHandler : (s, e) => Interlocked.Exchange(ref this.currentProgress, e) ); return(new KeyValueConfiguration { Key = this.ConfigurationKey, Value = this.UseExitCode ? result.ExitCode?.ToString() : string.Join(", ", result.Output) }); }
public override Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) => Dsc.CollectAsync(context, this, this.GetTemplate());
public static async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context, ILogSink log, DscConfiguration template) { if (string.IsNullOrEmpty(template.ResourceName)) { log.LogError("Bad or missing DSC Resource name."); return(null); } var jobRunner = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var propertyTypes = await GetPropertyTypesAsync(context, jobRunner, template.ResourceName, template.ModuleName, log); var collectJob = CreateJob("Get", propertyTypes, template); log.LogDebug(collectJob.ScriptText); collectJob.MessageLogged += (s, e) => log.Log(e.Level, e.Message); var result = (ExecutePowerShellJob.Result) await jobRunner.ExecuteJobAsync(collectJob, context.CancellationToken); var collectValues = result.Output?.FirstOrDefault().AsDictionary() ?? new Dictionary <string, RuntimeValue>(StringComparer.OrdinalIgnoreCase); var removeKeys = collectValues.Where(p => p.Value.ValueType == RuntimeValueType.Scalar && string.IsNullOrEmpty(p.Value.AsString())).Select(p => p.Key).ToList(); foreach (var k in removeKeys) { collectValues.Remove(k); } var testJob = CreateJob("Test", propertyTypes, template); log.LogDebug(testJob.ScriptText); testJob.MessageLogged += (s, e) => log.Log(e.Level, e.Message); var result2 = (ExecutePowerShellJob.Result) await jobRunner.ExecuteJobAsync(testJob, context.CancellationToken); var output = result2.Output; if (output.Count == 0) { log.LogError("Invoke-DscResource did not return any values."); return(null); } var testResult = output.FirstOrDefault(); bool?inDesiredState = null; if (testResult.ValueType == RuntimeValueType.Map && testResult.AsDictionary().ContainsKey("InDesiredState")) { if (bool.TryParse(testResult.AsDictionary()["InDesiredState"].AsString(), out bool d)) { inDesiredState = d; } } else { inDesiredState = testResult.AsBoolean(); } if (inDesiredState == null) { log.LogError("Invoke-DscResource did not return a boolean value or an object with an InDesiredState property."); return(null); } return(new DscConfiguration(collectValues) { ModuleName = template.ModuleName, ResourceName = template.ResourceName, ConfigurationKeyName = template.ConfigurationKeyName, InDesiredState = inDesiredState.Value }); }
protected override async Task <IEnumerable <PackageConfiguration> > CollectPackagesAsync(IOperationCollectionContext context) { using var job = new CollectDscModulesJob { DebugLogging = true }; job.MessageLogged += (s, e) => this.Log(e.Level, e.Message); var jobExecuter = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var result = (CollectDscModulesJob.Result) await jobExecuter.ExecuteJobAsync(job, context.CancellationToken); return(result.Modules.Select(i => new DscModuleConfiguration { PackageName = i.Name, PackageVersion = i.Version })); }
public override Task <ComparisonResult> CompareAsync(PersistedConfiguration other, IOperationCollectionContext context) { var diffs = this.comparisonResults.Where(d => d != null); if (diffs.Any()) { return(Task.FromResult(new ComparisonResult(diffs))); } else { return(Task.FromResult(ComparisonResult.Identical)); } }
public override Task <ComparisonResult> CompareAsync(PersistedConfiguration other, IOperationCollectionContext context) { if (other == null) { throw new ArgumentNullException(nameof(other)); } if (!(other is GitHubMilestoneConfiguration c)) { throw new InvalidOperationException("Cannot compare configurations of different types."); } return(Task.FromResult(this.Compare(c))); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { return(await this.CollectAsync((IOperationExecutionContext)context)); }
public override Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) => PsRepositoryConfiguration.CollectAsync(context, this, this.Template);
protected async override Task <IEnumerable <PackageConfiguration> > CollectPackagesAsync(IOperationCollectionContext context) { var jobRunner = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var scriptText = "$results = Get-Module -ListAvailable"; var job = new ExecutePowerShellJob { CollectOutput = true, OutVariables = new[] { "results" }, ScriptText = scriptText }; var result = (ExecutePowerShellJob.Result) await jobRunner.ExecuteJobAsync(job); var modules = (result.OutVariables["results"].AsEnumerable() ?? result.OutVariables["results"].ParseDictionary() ?? Enumerable.Empty <RuntimeValue>()) .Select(parseModule).Where(m => m != null); return(modules);
public override Task <ComparisonResult> CompareAsync(PersistedConfiguration other, IOperationCollectionContext context) { var config = (KubernetesResourceConfiguration)other; if (this.Template.Exists != config.Exists) { return(Task.FromResult(new ComparisonResult(new[] { new Difference(nameof(config.Exists), this.Template.Exists, config.Exists) }))); } if (!this.Template.Exists) { return(Task.FromResult(ComparisonResult.Identical)); } var actual = JObject.Parse(config.NormalizedActual); var template = JObject.Parse(config.NormalizedApplied); // Kubernetes has a bad habit of not telling us when immutable properties differ // during the dry run. Figure it out ourselves. var fresh = JObject.Parse(config.NormalizedTemplate); template.Merge(fresh, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Merge }); // Make sure we don't have any arrays in the template that have extra elements. FixArrayMergeLength(template, fresh); // We only care about metadata and spec - the other fields are either part of // the configuration key or stats that can change during collection. return(Task.FromResult(new ComparisonResult( GetJsonDifferences("metadata", template.Property("metadata").Value, actual.Property("metadata").Value) .Concat(GetJsonDifferences("spec", template.Property("spec").Value, actual.Property("spec").Value)) ))); }
public override async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context) { var fileOps = context.Agent.GetService <IFileOperationsExecuter>(); var client = new ProGetClient(this.Template.FeedUrl, this.Template.FeedName, this.Template.UserName, this.Template.Password, this); try { var packageId = PackageName.Parse(this.Template.PackageName); var packageInfo = await client.GetPackageInfoAsync(packageId).ConfigureAwait(false); var version = new ProGetPackageVersionSpecifier(this.Template.PackageVersion).GetBestMatch(packageInfo.versions); if (version == null) { this.LogError($"Package {this.Template.PackageName} does not have a version {this.Template.PackageVersion}."); return(null); } this.LogInformation($"Resolved package version is {version}."); if (!await fileOps.DirectoryExistsAsync(this.Template.TargetDirectory).ConfigureAwait(false)) { this.LogInformation(this.Template.TargetDirectory + " does not exist."); return(new ProGetPackageConfiguration { TargetDirectory = this.Template.TargetDirectory }); } var mask = new MaskingContext(this.Template.Includes, this.Template.Excludes); this.LogInformation(this.Template.TargetDirectory + " exists; getting remote file list..."); var remoteFileList = await fileOps.GetFileSystemInfosAsync(this.Template.TargetDirectory, mask).ConfigureAwait(false); var remoteFiles = new Dictionary <string, SlimFileSystemInfo>(remoteFileList.Count, StringComparer.OrdinalIgnoreCase); foreach (var file in remoteFileList) { var relativeName = file.FullName.Substring(this.Template.TargetDirectory.Length).Replace('\\', '/').Trim('/'); if (file is SlimDirectoryInfo) { relativeName += "/"; } remoteFiles.Add(relativeName, file); } remoteFileList = null; // async GC optimization this.LogDebug($"{this.Template.TargetDirectory} contains {remoteFiles.Count} file system entries."); this.LogInformation($"Connecting to {this.Template.FeedUrl} to get metadata for {this.Template.PackageName}:{version}..."); var versionInfo = await client.GetPackageVersionInfoAsync(packageId, version).ConfigureAwait(false); if (versionInfo.fileList == null) { this.LogError("File list is unavailable for this package; it may be an orphaned entry."); return(null); } this.LogDebug($"Package contains {versionInfo.fileList.Length} file system entries."); foreach (var entry in versionInfo.fileList) { var relativeName = entry.name; if (!mask.IsMatch(relativeName)) { continue; } var file = remoteFiles.GetValueOrDefault(relativeName); if (file == null) { this.LogInformation($"Entry {relativeName} is not present in {this.Template.TargetDirectory}."); return(new ProGetPackageConfiguration { TargetDirectory = this.Template.TargetDirectory }); } if (!entry.name.EndsWith("/")) { var fileInfo = (SlimFileInfo)file; if (entry.size != fileInfo.Size || entry.date != fileInfo.LastWriteTimeUtc) { this.LogInformation($"File {relativeName} in {this.Template.TargetDirectory} is different from file in package."); this.LogDebug($"Source info: {entry.size} bytes, {entry.date} timestamp"); this.LogDebug($"Target info: {fileInfo.Size} bytes, {fileInfo.LastWriteTimeUtc} timestamp"); return(new ProGetPackageConfiguration { TargetDirectory = this.Template.TargetDirectory }); } } } if (this.Template.DeleteExtra) { foreach (var name in remoteFiles.Keys) { if (!versionInfo.fileList.Any(entry => entry.name == name)) { this.LogInformation($"File {name} in {this.Template.TargetDirectory} does not exist in package."); return(new ProGetPackageConfiguration { TargetDirectory = this.Template.TargetDirectory }); } } } this.LogInformation($"All package files and directories are present in {this.Template.TargetDirectory}."); return(new ProGetPackageConfiguration { Current = true, TargetDirectory = this.Template.TargetDirectory }); } catch (ProGetException ex) { this.LogError(ex.FullMessage); return(null); } }