From fa5eeadb1b94f58c6324ca96c458b2b757c86ff6 Mon Sep 17 00:00:00 2001 From: Mateusz Duda Date: Mon, 11 Mar 2024 15:53:13 +0100 Subject: [PATCH] fixed async stuff --- README.md | 6 +++ package.json | 2 +- src/Commands/runReportForCommitCommand.ts | 2 +- src/Commands/runReportForCommitListCommand.ts | 54 +++++++++---------- src/HTMLCreator/CSSOverrides.ts | 1 + src/Report/AdfUtils.ts | 5 ++ src/Report/JiraBuilder.ts | 33 ++++++++++-- src/Report/ReportGenerator.ts | 7 ++- src/Scope/ConfigFile.ts | 15 +++++- 9 files changed, 90 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index f0259a2..c7b88a3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ npm i scope-tags -D - Option `gitCommitCountLimit` is a maximum number of commits to search for when doing rev walk on git push hook - used just on the user side while running commands `--verify-unpushed-commits` or `--skip`. It this number is reached you'll get a warning and ignoring it may result in some files being ommited from tag verification. +- Option `logsURL` is used to link to logs directly from generated reports - makes it easier to see all changes which were made to that build. It is optional, if not present the link won't be added to reports. The URL should contain build tag (`"buildTag"` specified in build metadata file) somewhere. + +``` + "logsURL" +``` + ### Features to do - [x] Import `ts-morph` library diff --git a/package.json b/package.json index 38cab65..8092d78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scope-tags", - "version": "0.1.18", + "version": "0.1.20", "description": "Output human readable test scope report for QA", "main": "dist/scope.js", "types": "dist/scope.d.ts", diff --git a/src/Commands/runReportForCommitCommand.ts b/src/Commands/runReportForCommitCommand.ts index fb4fa14..b4a302f 100644 --- a/src/Commands/runReportForCommitCommand.ts +++ b/src/Commands/runReportForCommitCommand.ts @@ -44,7 +44,7 @@ export function runReportForCommitCommand(args: Array, root: string) { } }) - const generator = new ReportGenerator(repository, tagsDefinitionFile, fileTagsDatabase, referenceFinders); + const generator = new ReportGenerator(repository, tagsDefinitionFile, fileTagsDatabase, configFile, referenceFinders); const relevancyManager = new RelevancyManager(); repository.getCommitByHash(hash).then(async (commit: Commit) => { diff --git a/src/Commands/runReportForCommitListCommand.ts b/src/Commands/runReportForCommitListCommand.ts index 4ad8231..c000d84 100644 --- a/src/Commands/runReportForCommitListCommand.ts +++ b/src/Commands/runReportForCommitListCommand.ts @@ -1,4 +1,3 @@ -import { Commit } from "nodegit"; import { GitRepository } from "../Git/GitRepository"; import { ExternalMapReferenceFinder } from "../References/ExternalMapReferenceFinder"; import { IReferenceFinder } from "../References/IReferenceFinder"; @@ -14,7 +13,7 @@ import { Logger } from "../Logger/Logger"; const os = require("os"); -export function runReportForCommitListCommand(args: Array, root: string) { +export async function runReportForCommitListCommand(args: Array, root: string) { // Checks if all files from the commit are present in database (or excluded) const buildDataFile = args[1]; @@ -59,52 +58,53 @@ export function runReportForCommitListCommand(args: Array, root: string) } }) - const generator = new ReportGenerator(repository, tagsDefinitionFile, fileTagsDatabase, referenceFinders); + const generator = new ReportGenerator(repository, tagsDefinitionFile, fileTagsDatabase, configFile, referenceFinders); const relevancyTagger = new RelevancyManager(); const buildIntegration = new BuildIntegration(buildDataFile, configFile); const uniqueIssues = buildIntegration.getUniqueIssues(); let totalCommitCount = 0; - uniqueIssues.forEach(issue => { + for (const issue of uniqueIssues) { console.log(`[Scope tags]: Checking commits of issue '${issue}'`); - const commits = buildIntegration.getIssueCommits(issue); + const issueCommits = buildIntegration.getIssueCommits(issue); const buildTag = buildIntegration.getBuildTag(); Logger.setConfigurationProperty("Build tag", buildTag); - repository.getCommitsByHashes(commits.map(commit => commit.hash)).then(async (commits: Commit[]) => { - for (const commit of commits) { - console.log(`[Scope tags]: Found '${commit.summary()}'`); - } + // const commits = await repository.getCommitsByHashes(commits.map(commit => commit.hash)).then(async (commits: Commit[]) => { + const commits = await repository.getCommitsByHashes(issueCommits.map(commit => commit.hash)); - Logger.pushIssueInfo(issue, commits); + for (const commit of commits) { + console.log(`[Scope tags]: Found '${commit.summary()}'`); + } - totalCommitCount += commits.length; + Logger.pushIssueInfo(issue, commits); - console.log(`[Scope tags]: Loading relevancy map...'`); - const relevancyMap = relevancyTagger.loadRelevancyMapFromCommits(commits); + totalCommitCount += commits.length; - console.log(`[Scope tags]: Generating report for issue '${issue}'...'`); - const report = await generator.generateReportForCommits(commits, projects[0].name, buildTag, false, relevancyMap); + console.log(`[Scope tags]: Loading relevancy map...'`); + const relevancyMap = relevancyTagger.loadRelevancyMapFromCommits(commits); - if (generator.isReportEmpty(report)) { - console.log(`[Scope tags]: Report ommited because no tags for modified files were found'`); - return; - } + console.log(`[Scope tags]: Generating report for issue '${issue}'...'`); + const report = await generator.generateReportForCommits(commits, projects[0].name, buildTag, false, relevancyMap); - const commentReportJSON = generator.getReportAsJiraComment(report, false); + if (generator.isReportEmpty(report)) { + console.log(`[Scope tags]: Report ommited because no tags for modified files were found'`); + return; + } + + const commentReportJSON = generator.getReportAsJiraComment(report, false); - console.log(`[Scope tags]: Posting report as comment for issue '${issue}'...'`); + console.log(`[Scope tags]: Posting report as comment for issue '${issue}'...'`); - await buildIntegration.updateIssue({ - issue: issue, - report: commentReportJSON, - hostname: os.hostname(), - }); + await buildIntegration.updateIssue({ + issue: issue, + report: commentReportJSON, + hostname: os.hostname(), }); - }); + } if (logFilePath) { if (fileExists(logFilePath)) { diff --git a/src/HTMLCreator/CSSOverrides.ts b/src/HTMLCreator/CSSOverrides.ts index 791f07b..b6f7c5e 100644 --- a/src/HTMLCreator/CSSOverrides.ts +++ b/src/HTMLCreator/CSSOverrides.ts @@ -1,6 +1,7 @@ export const CSSOverrides = ` :root { --justify-important: left; + --width-content: 1800px; } hr { diff --git a/src/Report/AdfUtils.ts b/src/Report/AdfUtils.ts index 6c2986c..2e9e4fd 100644 --- a/src/Report/AdfUtils.ts +++ b/src/Report/AdfUtils.ts @@ -70,6 +70,11 @@ export function applyMark(mark: any, maybeNode: any) { return node; } +export const link = (attrs: any) => (maybeNode: any) => applyMark({ + type: 'link', + attrs +}, maybeNode); + function isDuplicateMark(node: any, type: any) { if (node.marks && node.marks.some((mark: any) => mark.type === type)) { return true; diff --git a/src/Report/JiraBuilder.ts b/src/Report/JiraBuilder.ts index 3fd1311..02e4d7e 100644 --- a/src/Report/JiraBuilder.ts +++ b/src/Report/JiraBuilder.ts @@ -1,5 +1,16 @@ import { formatDate } from "./TimeUtils"; -import { expand, table, doc, tableRow, tableHeader, nestedExpand, p, strong } from "./AdfUtils"; +import { + expand, + table, + doc, + tableRow, + tableHeader, + nestedExpand, + p, + strong, + text, + link, +} from "./AdfUtils"; import { getScriptVersion } from "../scope"; import { ReferencedFileInfo } from "../References/IReferenceFinder"; @@ -34,7 +45,8 @@ export class JiraBuilder { date: Date, projectName: string, buildTag: string, - printToConsole = false + printToConsole = false, + logURL?: string ): string { let tableTitle = `'${projectName}' scope tags v${getScriptVersion()} │ ${formatDate(date, "Europe/Warsaw")}`; tableTitle += buildTag ? ` │ ${buildTag}` : ""; @@ -47,9 +59,13 @@ export class JiraBuilder { ...{ attrs: { layout: "full-width" } } }; + const expandContent = logURL ? [reportTable, this._createLink(logURL, "Go to build logs")] : [reportTable]; + const expandTable = expand( { title: tableTitle }, - )(reportTable); + )( + ...expandContent + ); const adfDocument = doc(expandTable); @@ -114,6 +130,17 @@ export class JiraBuilder { }); } + private _createLink(url: string, description: string) { + const adfText = text(description); + + const adfLink = link({ + href: url, + title: description + })(adfText); + + return p(adfLink); + } + // Enables to paste the generated ADF to the online viewer public debugPrintADF(document: any) { console.log(` diff --git a/src/Report/ReportGenerator.ts b/src/Report/ReportGenerator.ts index cb2a954..3df9b6b 100644 --- a/src/Report/ReportGenerator.ts +++ b/src/Report/ReportGenerator.ts @@ -9,6 +9,7 @@ import { JiraBuilder, ModuleInfo, ReportTableRow, TagInfo } from "./JiraBuilder" import { RelevancyMap } from "../Relevancy/RelevancyManager"; import { Relevancy } from "../Relevancy/Relevancy"; import { Logger } from "../Logger/Logger"; +import { ConfigFile } from "../Scope/ConfigFile"; export type ModuleReport = { module: Module["name"], @@ -41,7 +42,8 @@ export class ReportGenerator { private _repository: GitRepository, private _tagsDefinitionFile: TagsDefinitionFile, private _fileTagsDatabase: FileTagsDatabase, - private _referenceFinders: Array + private _configFile: ConfigFile, + private _referenceFinders: Array, ) { } public async generateReportForCommit(commit: Commit, projectName: string, relevancyMap: RelevancyMap): Promise { @@ -301,7 +303,8 @@ export class ReportGenerator { report.date, report.projectName, report.jobName, - printToConsole + printToConsole, + this._configFile.getLogsURL(report.jobName), ); } diff --git a/src/Scope/ConfigFile.ts b/src/Scope/ConfigFile.ts index ba2ee1c..9051261 100644 --- a/src/Scope/ConfigFile.ts +++ b/src/Scope/ConfigFile.ts @@ -15,10 +15,12 @@ export type ConfigFileType = { updateIssueURL?: string, ignoredExtensions?: Array, viewIssueURL?: string, // Used only for linking to issues in HTML logs + logsURL?: string, }; export class ConfigFile implements IJSONFileDatabase { private static PATH = ".scope/config.json"; + private static LOGURL_BUILD_REPLACE_TAG = "__BUILD__"; private _root: string; private _config: ConfigFileType; @@ -70,7 +72,18 @@ export class ConfigFile implements IJSONFileDatabase { return false; } - public getViewIssueUrl(): any { + public getViewIssueUrl(): string | undefined { return this._config.viewIssueURL; } + + public getLogsURL(buildTag: string): string | undefined { + if (!buildTag) { + console.log("[ConfigFile] Could not create logs URL because of empty buildTag"); + return; + } else if (!this._config.logsURL?.includes(ConfigFile.LOGURL_BUILD_REPLACE_TAG)) { + console.log(`[ConfigFile] Could not create logs URL because logsURL does not include required tag '${ConfigFile.LOGURL_BUILD_REPLACE_TAG}'`); + return; + } + return this._config.logsURL?.replace(ConfigFile.LOGURL_BUILD_REPLACE_TAG, buildTag); + } }