private async Task <PersonalAccessTokens> GetPersonalAccessTokensAsync(IErrorsAndInfos errorsAndInfos) { var personalAccessTokensSecret = new PersonalAccessTokensSecret(); var personalAccessTokens = await vSecretRepository.GetAsync(personalAccessTokensSecret, errorsAndInfos); return(personalAccessTokens); }
public async Task ResolveAsync(IFolderResolver folderResolver, IErrorsAndInfos errorsAndInfos) { foreach (var backbendFolder in this) { backbendFolder.SetFolder(await folderResolver.ResolveAsync(backbendFolder.Name, errorsAndInfos)); } }
public async Task ResolveFoldersAsync(IFolderResolver folderResolver, IErrorsAndInfos errorsAndInfos) { foreach (var dvinApp in this) { await dvinApp.ResolveFoldersAsync(folderResolver, errorsAndInfos); } }
public async Task <TResult> GetAsync <TResult>(ISecret <TResult> secret, IErrorsAndInfos errorsAndInfos) where TResult : class, ISecretResult <TResult>, new() { TResult valueOrDefault; SaveSample(secret, false); var encrypted = secret is IEncryptedSecret <TResult>; var fileName = FileName(secret, false, encrypted); if (!File.Exists(fileName)) { if (SecretShouldDefaultSecretsBeStored == null) { SecretShouldDefaultSecretsBeStored = new SecretShouldDefaultSecretsBeStored(); await GetAsync(SecretShouldDefaultSecretsBeStored, errorsAndInfos); } var shouldDefaultSecretsBeStored = await ValueOrDefaultAsync(SecretShouldDefaultSecretsBeStored, errorsAndInfos); if (!shouldDefaultSecretsBeStored.AutomaticallySaveDefaultSecretIfAbsent) { SaveSample(secret, true); var defaultFileName = FileName(secret, true, encrypted); errorsAndInfos.Errors.Add(string.Format(Properties.Resources.PleaseLoadSecretSampleAdjustAndThenSaveAs, defaultFileName, fileName)); return(null); } await SetAsync(secret, errorsAndInfos); return(await ValueOrDefaultAsync(secret, errorsAndInfos)); } if (Values.ContainsKey(secret.Guid)) { valueOrDefault = await ValueOrDefaultAsync(secret, errorsAndInfos); return(valueOrDefault); } var xml = await ReadFromFileAsync(secret, false, encrypted, errorsAndInfos); if (string.IsNullOrEmpty(xml)) { return(null); } valueOrDefault = XmlDeserializer.Deserialize <TResult>(xml); if (!IsGenericType(valueOrDefault.GetType())) { foreach (var property in valueOrDefault.GetType().GetProperties().Where(p => p.GetValue(valueOrDefault) == null)) { SaveSample(secret, true); var defaultFileName = FileName(secret, true, encrypted); errorsAndInfos.Errors.Add(string.Format(Properties.Resources.AddedPropertyNotFoundInLoadedSecret, property.Name, fileName, defaultFileName)); } } Values[secret.Guid] = valueOrDefault; return(valueOrDefault); }
public async Task <DvinApp> GetTashAppAsync(IErrorsAndInfos errorsAndInfos) { using (_SimpleLogger.BeginScope(SimpleLoggingScopeId.Create(nameof(GetTashAppAsync)))) { var methodNamesFromStack = _MethodNamesFromStackFramesExtractor.ExtractMethodNamesFromStackFrames(); _SimpleLogger.LogInformationWithCallStack("Returning tash app", methodNamesFromStack); return(await DvinRepository.LoadAsync(TashAppId, errorsAndInfos)); } }
public void VerifyThatThereAreNoUncommittedChanges(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos) { var files = FilesWithUncommittedChanges(repositoryFolder); foreach (var file in files) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.UncommittedChangeTo, file)); } }
public static async Task WriteErrorsAsync(this IDataPresenter dataPresenter, IErrorsAndInfos errorsAndInfos) { var errors = errorsAndInfos.Errors.ToList(); foreach (var error in errors) { await dataPresenter.WriteLineAsync(error); } }
public async Task SetAsync <TResult>(ISecret <TResult> secret, IErrorsAndInfos errorsAndInfos) where TResult : class, ISecretResult <TResult>, new() { var valueOrDefault = await ValueOrDefaultAsync(secret, errorsAndInfos); var xml = XmlSerializer.Serialize(valueOrDefault); var encrypted = secret is IEncryptedSecret <TResult>; await WriteToFileAsync(secret, xml, false, encrypted, errorsAndInfos); Values[secret.Guid] = valueOrDefault; }
public bool IsGlobalDotNetCakeInstalled(IErrorsAndInfos errorsAndInfos) { vProcessRunner.RunProcess(DotNetExecutableFileName, DotNetToolListArguments, vWorkingFolder, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(false); } var line = errorsAndInfos.Infos.FirstOrDefault(l => l.StartsWith(CakeToolId)); return(line?.Substring(CakeToolId.Length).TrimStart().StartsWith(PinnedCakeToolVersion) == true); }
public async Task <DvinApp> LoadAsync(string id, IErrorsAndInfos errorsAndInfos) { var dvinApps = await LoadAsync(false, errorsAndInfos); var dvinApp = dvinApps.FirstOrDefault(d => d.Id == id); if (dvinApp != null) { await dvinApp.ResolveFoldersAsync(FolderResolver, errorsAndInfos); } return(dvinApp); }
public static string ErrorsPlusRelevantInfos(this IErrorsAndInfos errorsAndInfos) { if (!errorsAndInfos.AnyErrors()) { return(""); } var components = new List <string>(); components.AddRange(errorsAndInfos.Errors); components.AddRange(errorsAndInfos.Infos.Where(i => (i.StartsWith("Failed") || i.Contains(".trx")) && !components.Contains(i))); return(string.Join("\r\n", components)); }
private async Task <IList <DvinApp> > LoadAsync(bool resolve, IErrorsAndInfos errorsAndInfos) { var dvinAppsSecret = new SecretDvinApps(); var secretDvinApps = await SecretRepository.GetAsync(dvinAppsSecret, errorsAndInfos); if (!resolve || errorsAndInfos.AnyErrors()) { return(secretDvinApps); } await secretDvinApps.ResolveFoldersAsync(FolderResolver, errorsAndInfos); return(secretDvinApps); }
public void Reset(IFolder repositoryFolder, string headTipIdSha, IErrorsAndInfos errorsAndInfos) { using var repo = new Repository(repositoryFolder.FullName, new RepositoryOptions()); var commit = repo.Head.Commits.FirstOrDefault(c => c.Sha == headTipIdSha); if (commit == null) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.CommitNotFound, headTipIdSha)); } else { repo.Reset(ResetMode.Hard, commit); repo.RemoveUntrackedFiles(); } }
public void CallCake(string scriptFileFullName, string target, IErrorsAndInfos errorsAndInfos) { if (!File.Exists(scriptFileFullName)) { errorsAndInfos.Errors.Add(string.Format(Properties.Resources.FileNotFound, scriptFileFullName)); return; } var scriptFileFolder = new Folder(scriptFileFullName.Substring(0, scriptFileFullName.LastIndexOf('\\'))); var arguments = "cake \"" + scriptFileFullName + "\""; if (target != "") { arguments = arguments + " --target \"" + target + "\""; } vProcessRunner.RunProcess(DotNetExecutableFileName, arguments, scriptFileFolder, errorsAndInfos); }
public async Task <IFolder> ResolveAsync(string folderToResolve, IErrorsAndInfos errorsAndInfos) { if (folderToResolve == null) { return(null); } await FindReplacementsIfNecessaryAsync(); foreach (var(key, value) in Replacements.Where(replacement => folderToResolve.Contains(replacement.Key))) { folderToResolve = folderToResolve.Replace(key, value); } if (!folderToResolve.Contains("$(")) { return(new Folder(folderToResolve)); } var startIndex = -1; int endIndex; var machineDriveSecretFileName = SecretRepository.FileName(new MachineDrivesSecret(), false, false); var logicalFolderSecretFileName = SecretRepository.FileName(new LogicalFoldersSecret(), false, false); var missingPlaceHolders = new List <string>(); do { startIndex = folderToResolve.IndexOf("$(", startIndex + 1, StringComparison.Ordinal); if (startIndex >= 0) { endIndex = folderToResolve.IndexOf(")", startIndex, StringComparison.Ordinal); missingPlaceHolders.Add("'" + folderToResolve.Substring(startIndex, endIndex - startIndex + 1) + "'"); } else { endIndex = -1; } } while (startIndex >= 0 && endIndex > startIndex); errorsAndInfos.Errors.Add(missingPlaceHolders.Count == 1 ? string.Format(Properties.Resources.FolderPlaceholderNotFound, missingPlaceHolders[0], machineDriveSecretFileName, logicalFolderSecretFileName) : string.Format(Properties.Resources.FolderPlaceholdersNotFound, string.Join(", ", missingPlaceHolders), machineDriveSecretFileName, logicalFolderSecretFileName)); return(new Folder(folderToResolve)); }
public async Task <IEnumerable <BackbendFolderToBeArchived> > AnalyzeAsync(IErrorsAndInfos errorsAndInfos) { var result = new List <BackbendFolderToBeArchived>(); var backbendFolders = await SecretRepository.GetAsync(new BackbendFoldersSecret(), errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(result); } await backbendFolders.ResolveAsync(FolderResolver, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(result); } var archiveFolderFinderSecret = await SecretRepository.GetAsync(new ArchiveFolderFinderSecret(), errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(result); } var archiveFolderFinder = await SecretRepository.CompileCsLambdaAsync <string, string>(archiveFolderFinderSecret); if (archiveFolderFinder == null) { errorsAndInfos.Errors.Add(Properties.Resources.CouldNotCompileFolderFinder); return(result); } foreach (var backbendFolder in backbendFolders) { AnalyzeFolderAsync(backbendFolder, archiveFolderFinder, result); foreach (var subFolder in Directory.GetDirectories(backbendFolder.GetFolder().FullName).Select(f => new BackbendFolder { Name = f })) { subFolder.SetFolder(new Folder(subFolder.Name)); AnalyzeFolderAsync(subFolder, archiveFolderFinder, result); } } return(result); }
private void CloneRepository(IFolder folder, string branch, IErrorsAndInfos errorsAndInfos) { if (folder.GitSubFolder().Exists()) { return; } if (folder.Exists()) { var deleter = new FolderDeleter(); Assert.IsTrue(deleter.CanDeleteFolder(folder)); deleter.DeleteFolder(folder); } const string url = "https://github.com/aspenlaub/PakledCore.git"; vGitUtilities.Clone(url, branch, new Folder(folder.FullName), new CloneOptions { BranchName = branch }, true, errorsAndInfos); }
public void InstallGlobalDotNetCakeIfNecessary(IErrorsAndInfos errorsAndInfos) { if (IsGlobalDotNetCakeInstalled(errorsAndInfos)) { return; } if (errorsAndInfos.AnyErrors()) { return; } vProcessRunner.RunProcess(DotNetExecutableFileName, DotNetInstallCakeToolArguments, vWorkingFolder, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return; } if (IsGlobalDotNetCakeInstalled(errorsAndInfos)) { return; } errorsAndInfos.Errors.Add(Properties.Resources.CouldNotInstallCakeTool); }
public IList <IPosting> ReadPostings(string fileName, IErrorsAndInfos errorsAndInfos) { var postings = new List <IPosting>(); if (!File.Exists(fileName)) { errorsAndInfos.Errors.Add($"File \"{fileName}\" does not exist"); return(postings); } var lines = File.ReadAllLines(fileName).ToList(); for (var i = 0; i < lines.Count; i++) { if (!TryReadPostings(lines[i], out var posting)) { continue; } var unreadableLines = new List <string>(); for (var j = i + 1; j < lines.Count && j < i + 2 && !TryReadPostings(lines[j], out _); j++) { unreadableLines.Add(lines[j].Trim()); } if (unreadableLines.Any()) { posting = new Posting { Amount = posting.Amount, Date = posting.Date, Remark = posting.Remark + '/' + string.Join('/', unreadableLines) }; } postings.Add(posting); } return(postings); }
private void CleanUpFolder(IFolder folder, IErrorsAndInfos errorsAndInfos) { if (!folder.Exists()) { return; } if (!FolderDeleter.CanDeleteFolder(folder)) { errorsAndInfos.Errors.Add($"Folder deleter refuses to delete {folder.FullName}"); return; } try { foreach (var file in Directory.GetFiles(folder.FullName, "*.*", SearchOption.AllDirectories)) { File.SetAttributes(file, FileAttributes.Normal); } FolderDeleter.DeleteFolder(folder); } catch (Exception e) { errorsAndInfos.Errors.Add($"Could not delete {folder.FullName}"); errorsAndInfos.Errors.Add(e.Message); } }
public static async Task ResolveFoldersAsync(this IDvinApp dvinApp, IFolderResolver folderResolver, IErrorsAndInfos errorsAndInfos) { dvinApp.AreFoldersBeingResolved = true; dvinApp.SolutionFolder = (await folderResolver.ResolveAsync(dvinApp.SolutionFolder, errorsAndInfos)).FullName; dvinApp.ReleaseFolder = (await folderResolver.ResolveAsync(dvinApp.ReleaseFolder, errorsAndInfos)).FullName; dvinApp.PublishFolder = (await folderResolver.ResolveAsync(dvinApp.PublishFolder, errorsAndInfos)).FullName; dvinApp.ExceptionLogFolder = (await folderResolver.ResolveAsync(dvinApp.ExceptionLogFolder, errorsAndInfos)).FullName; dvinApp.AreFoldersBeingResolved = false; }
public static Process Start(this IDvinApp dvinApp, IFileSystemService fileSystemService, IErrorsAndInfos errorsAndInfos) { if (dvinApp.IsPortListenedTo()) { errorsAndInfos.Errors.Add($"Another process already listens to port {dvinApp.Port}"); return(null); } if (!fileSystemService.FolderExists(dvinApp.PublishFolder)) { errorsAndInfos.Errors.Add($"Folder \"{dvinApp.PublishFolder}\" not found"); return(null); } var runner = new ProcessStarter(); var process = runner.StartProcess("dotnet", dvinApp.Executable, dvinApp.PublishFolder, errorsAndInfos); return(process); }
public static void ValidatePubXml(this IDvinApp dvinApp, IFileSystemService fileSystemService, IErrorsAndInfos errorsAndInfos) { if (!fileSystemService.FolderExists(dvinApp.SolutionFolder)) { errorsAndInfos.Errors.Add($"Folder \"{dvinApp.SolutionFolder}\" not found"); return; } var solutionFolder = new Folder(dvinApp.SolutionFolder); var pubXmlFiles = fileSystemService.ListFilesInDirectory(solutionFolder, "*.pubxml", SearchOption.AllDirectories); if (pubXmlFiles.Count != 1) { errorsAndInfos.Errors.Add($"Found {pubXmlFiles.Count} pubxml files in secret {dvinApp.Id} dvin app"); return; } XDocument document; var pubXmlFile = pubXmlFiles[0]; try { document = XDocument.Parse(fileSystemService.ReadAllText(pubXmlFile)); } catch { errorsAndInfos.Errors.Add($"Could not parse {pubXmlFile}"); return; } var namespaceManager = new XmlNamespaceManager(new NameTable()); namespaceManager.AddNamespace("cp", CsProjNamespace); var publishUrlElementValue = document.XPathSelectElement("./cp:Project/cp:PropertyGroup/cp:publishUrl", namespaceManager)?.Value; if (string.IsNullOrWhiteSpace(publishUrlElementValue)) { errorsAndInfos.Errors.Add($"publishUrl element not found in {pubXmlFile}"); return; } if (!publishUrlElementValue.StartsWith(@"$(MSBuildThisFileDirectory)")) { errorsAndInfos.Errors.Add($"publishUrl element in {pubXmlFile} does not start with $(MSBuildThisFileDirectory)"); return; } var publishFolder = new Folder(dvinApp.PublishFolder); int pos; for (pos = 0; pos < pubXmlFile.Length && pos < publishFolder.FullName.Length && pubXmlFile[pos] == publishFolder.FullName[pos]; pos++) { } for (pos--; pos > 0 && pubXmlFile[pos] != '\\'; pos--) { } if (pos <= 0) { errorsAndInfos.Errors.Add($"{pubXmlFile} and {publishFolder.FullName} do not share a common prefix"); return; } var expectedPublishUrlElement = "$(MSBuildThisFileDirectory)" + string.Join("", pubXmlFile.Substring(pos + 1).ToCharArray().Where(c => c == '\\').Select(_ => @"..\")) + publishFolder.FullName.Substring(pos + 1); if (publishUrlElementValue == expectedPublishUrlElement) { return; } errorsAndInfos.Errors.Add($"publishUrl element in {pubXmlFile} should be {expectedPublishUrlElement}, but it is {publishUrlElementValue}"); }
public static void ValidatePubXml(this IDvinApp dvinApp, IErrorsAndInfos errorsAndInfos) { ValidatePubXml(dvinApp, new FileSystemService(), errorsAndInfos); }
public static void Publish(this IDvinApp dvinApp, IFileSystemService fileSystemService, bool ignoreMissingReleaseBuild, IErrorsAndInfos errorsAndInfos) { if (!ignoreMissingReleaseBuild && !dvinApp.HasAppBeenBuiltAfterLatestSourceChanges(fileSystemService)) { errorsAndInfos.Errors.Add($"No release build for dvin app {dvinApp.Id}"); return; } if (!fileSystemService.FolderExists(dvinApp.PublishFolder)) { errorsAndInfos.Errors.Add($"Folder \"{dvinApp.PublishFolder}\" not found"); return; } if (!fileSystemService.FolderExists(dvinApp.SolutionFolder)) { errorsAndInfos.Errors.Add($"Folder \"{dvinApp.SolutionFolder}\" not found"); return; } var publishedFiles = Artifacts(fileSystemService, new Folder(dvinApp.PublishFolder)); var lastPublishedAt = publishedFiles.Any() ? publishedFiles.Max(f => fileSystemService.LastWriteTime(f)) : DateTime.Now; MakeCopiesOfAssemblies(new Folder(dvinApp.PublishFolder), fileSystemService); var projectFile = fileSystemService.ListFilesInDirectory(new Folder(dvinApp.SolutionFolder), "*.csproj", SearchOption.AllDirectories).FirstOrDefault(f => f.EndsWith(dvinApp.Id + ".csproj")); if (projectFile == null) { errorsAndInfos.Errors.Add($"No project file found for dvin app {dvinApp.Id} (must end with {dvinApp.Id}.csproj)"); return; } var processStarter = new ProcessStarter(); var arguments = $"publish \"{projectFile}\" -c Release --no-restore -o \"{dvinApp.PublishFolder}\""; using (var process = processStarter.StartProcess("dotnet", arguments, "", errorsAndInfos)) { if (process != null) { processStarter.WaitForExit(process); } } if (errorsAndInfos.Infos.Any(i => i.Contains("Could not copy"))) { errorsAndInfos.Errors.Add($"The publish process could not copy files for dvin app {dvinApp.Id}, make sure dotnet and the app are not running"); return; } publishedFiles = Artifacts(fileSystemService, new Folder(dvinApp.PublishFolder)); if (!publishedFiles.Any() || lastPublishedAt >= publishedFiles.Max(f => fileSystemService.LastWriteTime(f))) { errorsAndInfos.Errors.Add($"Nothing was published for dvin app {dvinApp.Id}"); } DeleteUnusedFileCopies(new Folder(dvinApp.PublishFolder), fileSystemService); }
public static void Publish(this IDvinApp dvinApp, IFileSystemService fileSystemService, IErrorsAndInfos errorsAndInfos) { Publish(dvinApp, fileSystemService, false, errorsAndInfos); }
protected async Task <object> RunJsonWebRequestAsync(string url, string owner, IErrorsAndInfos errorsAndInfos) { var request = (HttpWebRequest)WebRequest.Create(url); request.Method = WebRequestMethods.Http.Get; request.UserAgent = GetType().Namespace; var personalAccessTokens = await GetPersonalAccessTokensAsync(errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(null); } var personalAccessToken = personalAccessTokens.FirstOrDefault(p => p.Owner == owner && p.Purpose == "API"); if (personalAccessToken != null) { request.Headers.Add("Authorization", "token " + personalAccessToken.Token); } ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; var response = (HttpWebResponse)request.GetResponse(); Stream responseStream; try { responseStream = response.GetResponseStream(); } catch { errorsAndInfos.Errors.Add(Properties.Resources.CouldNotGetListOfPullRequests); return(null); } string text; using (var sr = new StreamReader(responseStream)) { text = await sr.ReadToEndAsync(); } return(JsonConvert.DeserializeObject(text)); }
protected async Task <IList <IPullRequest> > GetPullRequestsAsync(IFolder repositoryFolder, string state, IErrorsAndInfos errorsAndInfos) { var pullRequests = new List <IPullRequest>(); vGitUtilities.IdentifyOwnerAndName(repositoryFolder, out var owner, out var name, errorsAndInfos); if (errorsAndInfos.AnyErrors()) { return(pullRequests); } var url = $"https://api.github.com/repos/{owner}/{name}/pulls?state=" + state; var result = await RunJsonWebRequestAsync(url, owner, errorsAndInfos) as JArray; if (errorsAndInfos.AnyErrors()) { return(pullRequests); } if (result == null) { errorsAndInfos.Errors.Add(Properties.Resources.CouldNotGetListOfPullRequests); return(pullRequests); } pullRequests.AddRange(result.Select(detailResult => CreatePullRequest(detailResult))); return(pullRequests); }
public async Task <bool> HasPullRequestForThisBranchAndItsHeadTipAsync(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos) { var pullRequests = await GetPullRequestsAsync(repositoryFolder, "all", errorsAndInfos); var checkedOutBranch = vGitUtilities.CheckedOutBranch(repositoryFolder); var headTipIdSha = vGitUtilities.HeadTipIdSha(repositoryFolder); return(pullRequests.Any(p => p.Branch == checkedOutBranch && p.Sha == headTipIdSha)); }
public async Task <int> GetNumberOfPullRequestsAsync(IFolder repositoryFolder, IErrorsAndInfos errorsAndInfos) { return((await GetPullRequestsAsync(repositoryFolder, "all", errorsAndInfos)).Count); }