diff --git a/build.gradle b/build.gradle index b5827976aa..70188931d8 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ dependencies { implementation group: 'org.apache.ant', name: 'ant', version: '1.10.12' implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.9.0' implementation group: 'org.fusesource.jansi', name: 'jansi', version: '2.4.0' + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.17.0' testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: jUnitVersion testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: jUnitVersion diff --git a/config/blurbs.md b/config/blurbs.md new file mode 100644 index 0000000000..6ccea2c23e --- /dev/null +++ b/config/blurbs.md @@ -0,0 +1,2 @@ +https://github.com/reposense/testrepo-Alpha/tree/master +Master branch of testrepo-Alpha diff --git a/docs/ug/blurbs.md b/docs/ug/blurbs.md new file mode 100644 index 0000000000..4219a83fb3 --- /dev/null +++ b/docs/ug/blurbs.md @@ -0,0 +1,5 @@ +https://github.com/reposense/RepoSense/tree/cypress +Cypress branch of RepoSense +------------------------------------ +https://github.com/reposense/publish-RepoSense/tree/master +Publishing branch of RepoSense diff --git a/docs/ug/cli.md b/docs/ug/cli.md index 550713969c..02f5cab297 100644 --- a/docs/ug/cli.md +++ b/docs/ug/cli.md @@ -68,7 +68,7 @@ partial credit.
**`--config CONFIG_DIRECTORY`**: Specifies that config files located in `CONFIG_DIRECTORY` should be used to customize the report. -* Parameter: `CONFIG_DIRECTORY` The directory containing the config files. Should contain a `repo-config.csv` file. Optionally, can contain an `author-config.csv` file or/and a `group-config.csv` file or/and a `report-config.json` file. +* Parameter: `CONFIG_DIRECTORY` The directory containing the config files. Should contain a `repo-config.csv` file. Optionally, can contain an `author-config.csv` file or/and a `group-config.csv` file or/and a `report-config.json` file or/and a `blurbs.md` file. * Alias: `-c` * Example: `java -jar RepoSense.jar --config ./config` diff --git a/docs/ug/configFiles.md b/docs/ug/configFiles.md index 1797f8e4ea..5a9c1745c2 100644 --- a/docs/ug/configFiles.md +++ b/docs/ug/configFiles.md @@ -209,3 +209,17 @@ Note: Symbols such as `"`, `!`, `/` etc. in your author name will be omitted, wh
+ + + +
+ +## `blurbs.md` + +You can optionally use `blurbs.md` to add blurbs in Markdown syntax for repository branches. These blurbs will be seen when grouping by `Repo/Branch`. ([example](https://github.com/reposense/RepoSense/blob/master/docs/ug/blurbs.md)) + +**Format**: +* First line in section: Link to the repository branch. +* Second line onwards: Blurb content. +* Delimiter: ``. Everything on the line after the delimiter will be ignored. +
diff --git a/docs/ug/customizingReports.md b/docs/ug/customizingReports.md index da6ad7f49e..531ae94442 100644 --- a/docs/ug/customizingReports.md +++ b/docs/ug/customizingReports.md @@ -62,8 +62,9 @@ In both instances, it is **necessary to commit any changes** for them to be dete -### Add a title +### Personalizing Reports +#### Add a title A title component can be added by creating a file titled `title.md` in the assets directory. You can specify the assets directory according to the reference below: {{ embed("Appendix: **CLI syntax reference → `assets` flag**", "cli.md#section-assets") }} @@ -73,3 +74,10 @@ The title can render a combination of Markdown/HTML and plaintext ([example](htt Do note that the width of the title is bound by the width of the left panel. For more information on how to use Markdown, see the [Markdown Guide](https://www.markdownguide.org/). + +#### Add blurbs for branches +A blurb can be added for a repository branch by creating a file titled `blurbs.md` in the config directory. The blurbs will be visible when grouping by `Repo/Branch`. The format of the file is given below: +{{ embed("Appendix: **Config files format**", "configFiles.md#section-blurbs") }} + +Specifying the config directory can be done as follows: +{{ embed("Appendix: **CLI syntax reference → `config` flag**", "cli.md#section-config") }} diff --git a/frontend/cypress/config/blurbs.md b/frontend/cypress/config/blurbs.md new file mode 100644 index 0000000000..aec0130427 --- /dev/null +++ b/frontend/cypress/config/blurbs.md @@ -0,0 +1,11 @@ +https://github.com/reposense/RepoSense/tree/cypress +first blurb +------------------------------------ +https://gitlab.com/reposense/testrepo-gitlab/-/tree/main +unseen blurb +------------------------------------ +https://github.com/reposense/publish-RepoSense/tree/master +## third blurb in h2 markdown tag +------------------------------------ +https://github.com/reposense/RepoSense-auth-helper/tree/master +

second blurb in h1 tag

diff --git a/frontend/cypress/tests/chartView/chartView_blurbs.cy.js b/frontend/cypress/tests/chartView/chartView_blurbs.cy.js new file mode 100644 index 0000000000..71c5d62902 --- /dev/null +++ b/frontend/cypress/tests/chartView/chartView_blurbs.cy.js @@ -0,0 +1,34 @@ +describe('blurbs', () => { + it('shows blurbs', () => { + cy.get('.markdown.blurb') + .first() + .should('contain', 'first blurb'); + + cy.get('.markdown.blurb') + .eq(1) + .should('contain', 'second blurb'); + + cy.get('.markdown.blurb') + .eq(2) + .should('contain', 'third blurb'); + }); + + it('has the correct number of valid blurbs', () => { + cy.get('.markdown.blurb') + .should('have.length', 3); + }); + + it('processes markdown in blurbs', () => { + cy.get('.markdown.blurb') + .eq(1) + .find('h1') + .contains('second blurb in h1 tag'); + }); + + it('processes html in blurbs', () => { + cy.get('.markdown.blurb') + .eq(2) + .find('h2') + .contains('third blurb in h2 markdown tag'); + }); +}); diff --git a/frontend/src/app.vue b/frontend/src/app.vue index fa6b442f4a..0c2959d0a6 100644 --- a/frontend/src/app.vue +++ b/frontend/src/app.vue @@ -122,6 +122,7 @@ const app = defineComponent({ reportGenerationTime, errorMessages, names, + blurbMap, } = summary; this.creationDate = creationDate; this.reportGenerationTime = reportGenerationTime; @@ -134,6 +135,7 @@ const app = defineComponent({ this.getUsers(); this.renderTabHash(); this.userUpdated = true; + this.$store.commit('setBlurbMap', blurbMap); } catch (error) { window.alert(error); } finally { diff --git a/frontend/src/components/c-markdown-chunk.vue b/frontend/src/components/c-markdown-chunk.vue new file mode 100644 index 0000000000..47dccb392d --- /dev/null +++ b/frontend/src/components/c-markdown-chunk.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/frontend/src/components/c-summary-charts.vue b/frontend/src/components/c-summary-charts.vue index 437b23e5ea..bb0822eeb6 100644 --- a/frontend/src/components/c-summary-charts.vue +++ b/frontend/src/components/c-summary-charts.vue @@ -141,9 +141,8 @@ ) font-awesome-icon.icon-button(icon="clipboard") span.tooltip-text(v-bind:ref="`summary-charts-${i}-copy-iframe`") Click to copy iframe link for group - .tooltip.summary-chart__title--percentile( - v-if="sortGroupSelection.includes('totalCommits')" + v-if="sortGroupSelection.includes('totalCommits')" ) {{ getPercentile(i) }} %  span.tooltip-text.right-aligned {{ getPercentileExplanation(i) }} .summary-charts__title--tags( @@ -158,6 +157,14 @@ ) font-awesome-icon(icon="tags") span  {{ tag }} + + .blurbWrapper( + v-if="filterGroupSelection === 'groupByRepos'", + ) + c-markdown-chunk.blurb( + v-bind:markdown-text="getBlurb(repo[0])" + ) + .summary-charts__fileType--breakdown(v-if="filterBreakdown") template(v-if="filterGroupSelection !== 'groupByNone'") .summary-charts__fileType--breakdown__legend( @@ -337,6 +344,7 @@ import brokenLinkDisabler from '../mixin/brokenLinkMixin'; import tooltipPositioner from '../mixin/dynamicTooltipMixin'; import cRamp from './c-ramp.vue'; import cStackedBarChart from './c-stacked-bar-chart.vue'; +import cMarkdownChunk from './c-markdown-chunk.vue'; import { Bar, Repo, User } from '../types/types'; import { FilterGroupSelection, FilterTimeFrame, SortGroupSelection } from '../types/summary'; import { StoreState, ZoomInfo } from '../types/vuex.d'; @@ -347,6 +355,7 @@ export default defineComponent({ components: { cRamp, cStackedBarChart, + cMarkdownChunk, }, mixins: [brokenLinkDisabler, tooltipPositioner], props: { @@ -984,10 +993,41 @@ export default defineComponent({ return [...new Set(repo.flatMap((r) => r.commits).flatMap((c) => c.commitResults).flatMap((r) => r.tags))] .filter(Boolean) as Array; }, + + getBlurb(repo: User): string { + const link = this.getRepoLink(repo); + if (!link) { + return ''; + } + const blurb: string | undefined = this.$store.state.blurbMap[link]; + if (!blurb) { + return ''; + } + return blurb; + }, }, }); diff --git a/frontend/src/store/store.ts b/frontend/src/store/store.ts index c69d2a4204..2781cf2e8c 100644 --- a/frontend/src/store/store.ts +++ b/frontend/src/store/store.ts @@ -18,6 +18,7 @@ export default createStore({ loadingOverlayCount: 0, loadingOverlayMessage: '', isTabActive: true, + blurbMap: {}, } as StoreState, mutations: { updateTabZoomInfo(state: StoreState, info: ZoomInfo) { @@ -82,6 +83,9 @@ export default createStore({ file.wasCodeLoaded = file.wasCodeLoaded || file.active; }); }, + setBlurbMap(state: StoreState, blurbMap: { [key: string]: string }) { + state.blurbMap = blurbMap; + }, }, actions: { // Actions are called with dispatch diff --git a/frontend/src/types/vuex.d.ts b/frontend/src/types/vuex.d.ts index cedee8c21d..abf06d15b8 100644 --- a/frontend/src/types/vuex.d.ts +++ b/frontend/src/types/vuex.d.ts @@ -47,6 +47,7 @@ interface StoreState { loadingOverlayCount: number; loadingOverlayMessage: string; isTabActive: boolean; + blurbMap: { [key: string]: string }; } declare module '@vue/runtime-core' { diff --git a/frontend/src/types/window.ts b/frontend/src/types/window.ts index b8a0a60524..dd2f1abd5e 100644 --- a/frontend/src/types/window.ts +++ b/frontend/src/types/window.ts @@ -24,6 +24,7 @@ interface Api { reportGenerationTime: string; errorMessages: { [key: string]: ErrorMessage }; names: string[]; + blurbMap: { [key: string]: string }; } | null>; loadCommits: (repoName: string) => Promise; loadAuthorship: (repoName: string) => Promise; diff --git a/frontend/src/types/zod/summary-type.ts b/frontend/src/types/zod/summary-type.ts index 4ee1635406..316ce68f1b 100644 --- a/frontend/src/types/zod/summary-type.ts +++ b/frontend/src/types/zod/summary-type.ts @@ -45,6 +45,9 @@ export const summarySchema = z.object({ isUntilDateProvided: z.boolean(), isAuthorshipAnalyzed: z.boolean().default(false), // for backwards compatability supportedDomainUrlMap: supportedDomainUrlMapSchema, + blurbs: z.object({ + urlBlurbMap: z.record(z.string(), z.string()), + }), }); // Export typescript types diff --git a/frontend/src/utils/api.ts b/frontend/src/utils/api.ts index 940dedffa7..573180fc89 100644 --- a/frontend/src/utils/api.ts +++ b/frontend/src/utils/api.ts @@ -233,11 +233,14 @@ window.api = { window.REPOS[repoName] = repo; names.push(repoName); }); + + const blurbMap: { [key: string]: string } = data.blurbs.urlBlurbMap; return { creationDate: reportGeneratedTime, reportGenerationTime, errorMessages, names, + blurbMap, }; }, diff --git a/src/main/java/reposense/RepoSense.java b/src/main/java/reposense/RepoSense.java index be54dd663b..36daa4d751 100644 --- a/src/main/java/reposense/RepoSense.java +++ b/src/main/java/reposense/RepoSense.java @@ -10,6 +10,7 @@ import net.sourceforge.argparse4j.helper.HelpScreenException; import reposense.git.GitConfig; +import reposense.model.BlurbMap; import reposense.model.CliArguments; import reposense.model.RepoConfiguration; import reposense.model.ReportConfiguration; @@ -17,6 +18,7 @@ import reposense.parser.ArgsParser; import reposense.parser.exceptions.InvalidCsvException; import reposense.parser.exceptions.InvalidHeaderException; +import reposense.parser.exceptions.InvalidMarkdownException; import reposense.parser.exceptions.ParseException; import reposense.report.ReportGenerator; import reposense.system.LogsManager; @@ -43,6 +45,7 @@ public static void main(String[] args) { CliArguments cliArguments = ArgsParser.parse(args); List configs = null; ReportConfiguration reportConfig = new ReportConfiguration(); + BlurbMap blurbMap = new BlurbMap(); if (cliArguments.isViewModeOnly()) { ReportServer.startServer(SERVER_PORT_NUMBER, cliArguments.getReportDirectoryPath().toAbsolutePath()); @@ -51,6 +54,7 @@ public static void main(String[] args) { configs = RunConfigurationDecider.getRunConfiguration(cliArguments).getRepoConfigurations(); reportConfig = cliArguments.getReportConfiguration(); + blurbMap = cliArguments.getBlurbMap(); RepoConfiguration.setFormatsToRepoConfigs(configs, cliArguments.getFormats()); RepoConfiguration.setDatesToRepoConfigs(configs, cliArguments.getSinceDate(), cliArguments.getUntilDate()); @@ -80,7 +84,9 @@ public static void main(String[] args) { cliArguments.isSinceDateProvided(), cliArguments.isUntilDateProvided(), cliArguments.getNumCloningThreads(), cliArguments.getNumAnalysisThreads(), TimeUtil::getElapsedTime, cliArguments.getZoneId(), cliArguments.isFreshClonePerformed(), - cliArguments.isAuthorshipAnalyzed(), cliArguments.getOriginalityThreshold()); + cliArguments.isAuthorshipAnalyzed(), cliArguments.getOriginalityThreshold(), + blurbMap + ); FileUtil.zipFoldersAndFiles(reportFoldersAndFiles, cliArguments.getOutputFilePath().toAbsolutePath(), ".json"); @@ -97,6 +103,8 @@ public static void main(String[] args) { logger.log(Level.WARNING, e.getMessage(), e); } catch (HelpScreenException e) { // help message was printed by the ArgumentParser; it is safe to exit. + } catch (InvalidMarkdownException ex) { + logger.log(Level.SEVERE, ex.getMessage(), ex); } LogsManager.moveLogFileToOutputFolder(); diff --git a/src/main/java/reposense/model/BlurbMap.java b/src/main/java/reposense/model/BlurbMap.java new file mode 100644 index 0000000000..478a3d0c1f --- /dev/null +++ b/src/main/java/reposense/model/BlurbMap.java @@ -0,0 +1,46 @@ +package reposense.model; + +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Represents the mapping between the repo URL to the associated blurb. + */ +public class BlurbMap { + @JsonProperty("urlBlurbMap") + private final Map urlBlurbMap; + + public BlurbMap() { + this.urlBlurbMap = new HashMap<>(); + } + + public Map getAllMappings() { + return new HashMap<>(this.urlBlurbMap); + } + + /** + * Adds a key-value record into the {@code BlurbMap}. + * + * @param key Key value. + * @param value Blurb value. + */ + public void withRecord(String key, String value) { + this.urlBlurbMap.put(key, value); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (obj instanceof BlurbMap) { + BlurbMap bm = (BlurbMap) obj; + return bm.urlBlurbMap.equals(this.urlBlurbMap); + } + + return false; + } +} diff --git a/src/main/java/reposense/model/CliArguments.java b/src/main/java/reposense/model/CliArguments.java index d1b3564002..5f50e476de 100644 --- a/src/main/java/reposense/model/CliArguments.java +++ b/src/main/java/reposense/model/CliArguments.java @@ -51,6 +51,7 @@ public class CliArguments { private Path groupConfigFilePath; private Path reportConfigFilePath; private ReportConfiguration reportConfiguration; + private BlurbMap blurbMap; /** * Constructs a {@code CliArguments} object without any parameters. @@ -161,6 +162,10 @@ public ReportConfiguration getReportConfiguration() { return reportConfiguration; } + public BlurbMap getBlurbMap() { + return blurbMap; + } + public boolean isViewModeOnly() { return isViewModeOnly; } @@ -211,6 +216,7 @@ public boolean equals(Object other) { && Objects.equals(this.authorConfigFilePath, otherCliArguments.authorConfigFilePath) && Objects.equals(this.groupConfigFilePath, otherCliArguments.groupConfigFilePath) && Objects.equals(this.reportConfigFilePath, otherCliArguments.reportConfigFilePath) + && Objects.equals(this.blurbMap, otherCliArguments.blurbMap) && this.isAuthorshipAnalyzed == otherCliArguments.isAuthorshipAnalyzed && Objects.equals(this.originalityThreshold, otherCliArguments.originalityThreshold); } @@ -487,6 +493,16 @@ public Builder originalityThreshold(double originalityThreshold) { return this; } + /** + * Adds the {@code blurbMap} to CliArguments. + * + * @param blurbMap The blurb map. + */ + public Builder blurbMap(BlurbMap blurbMap) { + this.cliArguments.blurbMap = blurbMap; + return this; + } + /** * Builds CliArguments. * diff --git a/src/main/java/reposense/parser/ArgsParser.java b/src/main/java/reposense/parser/ArgsParser.java index 35d6afc3a4..c6c3f34aa7 100644 --- a/src/main/java/reposense/parser/ArgsParser.java +++ b/src/main/java/reposense/parser/ArgsParser.java @@ -25,9 +25,11 @@ import net.sourceforge.argparse4j.inf.MutuallyExclusiveGroup; import net.sourceforge.argparse4j.inf.Namespace; import reposense.RepoSense; +import reposense.model.BlurbMap; import reposense.model.CliArguments; import reposense.model.FileType; import reposense.model.ReportConfiguration; +import reposense.parser.exceptions.InvalidMarkdownException; import reposense.parser.exceptions.ParseException; import reposense.parser.types.AlphanumericArgumentType; import reposense.parser.types.AnalysisThreadsArgumentType; @@ -91,6 +93,7 @@ public class ArgsParser { "Config path not provided, using the config folder as default."; private static final String MESSAGE_INVALID_CONFIG_PATH = "%s is malformed."; private static final String MESSAGE_INVALID_CONFIG_JSON = "%s Ignoring the report config provided."; + private static final String MESSAGE_INVALID_MARKDOWN_BLURBS = "%s Ignoring the blurb file provided."; private static final String MESSAGE_SINCE_D1_WITH_PERIOD = "You may be using --since d1 with the --period flag. " + "This may result in an incorrect date range being analysed."; private static final String MESSAGE_SINCE_DATE_LATER_THAN_UNTIL_DATE = @@ -346,6 +349,7 @@ public static CliArguments parse(String[] args) throws HelpScreenException, Pars } addReportConfigToBuilder(cliArgumentsBuilder, results); + addBlurbMapToBuilder(cliArgumentsBuilder, results); addAnalysisDatesToBuilder(cliArgumentsBuilder, results); boolean isViewModeOnly = reportFolderPath != null @@ -397,6 +401,31 @@ private static void addReportConfigToBuilder(CliArguments.Builder builder, Names builder.reportConfiguration(reportConfig); } + /** + * Adds the blurbMap field to the given {@code builder}. + * + * @param builder Builder to be supplied with the reportConfig field. + * @param results Parsed results of the user-supplied CLI arguments. + */ + private static void addBlurbMapToBuilder(CliArguments.Builder builder, Namespace results) { + BlurbMap blurbMap = new BlurbMap(); + Path configFolderPath = results.get(CONFIG_FLAGS[0]); + + // Blurbs are parsed regardless + Path blurbConfigPath = configFolderPath.resolve(BlurbMarkdownParser.DEFAULT_BLURB_FILENAME); + + try { + blurbMap = new BlurbMarkdownParser(blurbConfigPath).parse(); + } catch (InvalidMarkdownException ex) { + logger.warning(String.format(MESSAGE_INVALID_MARKDOWN_BLURBS, ex.getMessage())); + } catch (IOException ioe) { + // IOException thrown as blurbs.md is not found. + // Ignore exception as the file is optional. + } + + builder.blurbMap(blurbMap); + } + /** * Adds the sinceDate and untilDate fields for analysis to the given {@code builder}. * diff --git a/src/main/java/reposense/parser/BlurbMarkdownParser.java b/src/main/java/reposense/parser/BlurbMarkdownParser.java new file mode 100644 index 0000000000..8c3e5a0f67 --- /dev/null +++ b/src/main/java/reposense/parser/BlurbMarkdownParser.java @@ -0,0 +1,151 @@ +package reposense.parser; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.regex.Pattern; + +import reposense.model.BlurbMap; +import reposense.parser.exceptions.InvalidMarkdownException; + +/** + * Parses the Markdown file and retrieves the mappings from URLs to blurbs from the blurbs + * configuration file. + */ +public class BlurbMarkdownParser extends MarkdownParser { + public static final Pattern DELIMITER = Pattern.compile("(.*)"); + public static final String DEFAULT_BLURB_FILENAME = "blurbs.md"; + + private static final class UrlRecord { + private final String url; + private final int nextPosition; + + public UrlRecord(String url, int nextPosition) { + this.url = url; + this.nextPosition = nextPosition; + } + + public String getUrl() { + return url; + } + + public int getNextPosition() { + return nextPosition; + } + } + + private static final class BlurbRecord { + private final List blurb; + private final int nextPosition; + + public BlurbRecord(List blurb, int nextPosition) { + this.blurb = blurb; + this.nextPosition = nextPosition; + } + + public List getBlurb() { + return blurb; + } + + public int getNextPosition() { + return nextPosition; + } + } + + public BlurbMarkdownParser(Path markdownPath) throws FileNotFoundException { + super(markdownPath); + } + + /** + * Parses the markdown file containing the url to blurb mapping and returns a + * {@code BlurbMap} containing the mappings between the url and blurbs. + * + * @return {@code BlurbMap} object. + * @throws IOException if there are any issues opening or parsing the {@code blurbs.md} file. + */ + @Override + public BlurbMap parse() throws IOException, InvalidMarkdownException { + logger.log(Level.INFO, "Parsing Blurbs..."); + // read all the lines first + List mdLines = Files.readAllLines(this.markdownPath); + + // if the file is empty, then we throw the exception and let the adder handle + if (mdLines.isEmpty()) { + throw new InvalidMarkdownException("Empty blurbs.md file"); + } + + // prepare the blurb map + BlurbMap blurbMap = new BlurbMap(); + + // define temporary local variables to track blurbs + String url = ""; + StringBuilder blurb = new StringBuilder(); + int counter = 0; + + while (counter < mdLines.size()) { + // extract the url record first + // this is guaranteed to be in the first line or else we fail + UrlRecord urlRecord = this.getUrlRecord(mdLines, counter); + url = urlRecord.getUrl(); + counter = urlRecord.getNextPosition(); + + // then extract the blurb record next + // we extract until the delimiter is found and then we will stop + BlurbRecord blurbRecord = this.getBlurbRecord(mdLines, counter); + List blurbExtracted = blurbRecord.getBlurb(); + for (String string : blurbExtracted) { + blurb.append(string); + } + counter = blurbRecord.getNextPosition(); + + // add the recorded entry into the BlurbMap + // strip the trailing /n + blurbMap.withRecord(url, blurb.toString().stripTrailing()); + blurb.setLength(0); + } + + // return the built BlurbMap instance + logger.log(Level.INFO, "Blurbs parsed successfully!"); + return blurbMap; + } + + private UrlRecord getUrlRecord(List lines, int position) throws InvalidMarkdownException { + // checks if url is valid + // adapted from https://www.baeldung.com/java-validate-url + try { + String url = lines.get(position).strip(); + new URL(url).toURI(); + return new UrlRecord(lines.get(position), position + 1); + } catch (MalformedURLException | URISyntaxException ex) { + throw new InvalidMarkdownException("URL provided is not valid!"); + } + } + + private BlurbRecord getBlurbRecord(List lines, int position) { + int lineSize = lines.size(); + int posCounter = position; + List blurbs = new ArrayList<>(); + + while (posCounter < lineSize) { + String currLine = lines.get(posCounter); + + if (BlurbMarkdownParser.DELIMITER.matcher(currLine).matches()) { + break; + } else { + currLine += "\n"; + blurbs.add(currLine); + } + + posCounter++; + } + + return new BlurbRecord(blurbs, posCounter + 1); + } +} diff --git a/src/main/java/reposense/parser/MarkdownParser.java b/src/main/java/reposense/parser/MarkdownParser.java new file mode 100644 index 0000000000..93ca3cb95d --- /dev/null +++ b/src/main/java/reposense/parser/MarkdownParser.java @@ -0,0 +1,32 @@ +package reposense.parser; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.logging.Logger; + +import reposense.parser.exceptions.InvalidMarkdownException; +import reposense.system.LogsManager; + +/** + * Parses Markdown file according to the "" tag. + * + * @param Generic Type {@code T}. + */ +public abstract class MarkdownParser { + protected static final Logger logger = LogsManager.getLogger(MarkdownParser.class); + + protected Path markdownPath; + + public MarkdownParser(Path markdownPath) throws FileNotFoundException { + if (markdownPath == null || !Files.exists(markdownPath)) { + throw new FileNotFoundException("Markdown file does not exist at the given path.\n" + + "Use '-help' to list all the available subcommands and some concept guides."); + } + + this.markdownPath = markdownPath; + } + + public abstract T parse() throws IOException, InvalidMarkdownException; +} diff --git a/src/main/java/reposense/parser/exceptions/InvalidMarkdownException.java b/src/main/java/reposense/parser/exceptions/InvalidMarkdownException.java new file mode 100644 index 0000000000..fc6b2fd71a --- /dev/null +++ b/src/main/java/reposense/parser/exceptions/InvalidMarkdownException.java @@ -0,0 +1,10 @@ +package reposense.parser.exceptions; + +/** + * Represents the error thrown when Markdown files cannot be parsed. + */ +public class InvalidMarkdownException extends Exception { + public InvalidMarkdownException(String message) { + super(message); + } +} diff --git a/src/main/java/reposense/report/ReportGenerator.java b/src/main/java/reposense/report/ReportGenerator.java index fd1f9744bd..ab0b19ec6e 100644 --- a/src/main/java/reposense/report/ReportGenerator.java +++ b/src/main/java/reposense/report/ReportGenerator.java @@ -41,12 +41,14 @@ import reposense.git.exception.GitBranchException; import reposense.git.exception.GitCloneException; import reposense.model.Author; +import reposense.model.BlurbMap; import reposense.model.CommitHash; import reposense.model.RepoConfiguration; import reposense.model.RepoLocation; import reposense.model.ReportConfiguration; import reposense.model.StandaloneConfig; import reposense.parser.StandaloneConfigJsonParser; +import reposense.parser.exceptions.InvalidMarkdownException; import reposense.report.exception.NoAuthorsWithCommitsFoundException; import reposense.system.LogsManager; import reposense.util.FileUtil; @@ -112,14 +114,17 @@ public class ReportGenerator { * @param shouldFreshClone The boolean variable for whether to clone a repo again during tests. * @param shouldAnalyzeAuthorship The boolean variable for whether to further analyze authorship. * @param originalityThreshold The double variable for originality threshold in analyze authorship. + * @param blurbMap The {@code BlurbMap}. * @return the list of file paths that were generated. * @throws IOException if templateZip.zip does not exist in jar file. + * @throws InvalidMarkdownException if the blurb markdown file cannot be parsed properly. */ public List generateReposReport(List configs, String outputPath, String assetsPath, ReportConfiguration reportConfig, String generationDate, LocalDateTime cliSinceDate, LocalDateTime untilDate, boolean isSinceDateProvided, boolean isUntilDateProvided, int numCloningThreads, int numAnalysisThreads, Supplier reportGenerationTimeProvider, ZoneId zoneId, - boolean shouldFreshClone, boolean shouldAnalyzeAuthorship, double originalityThreshold) throws IOException { + boolean shouldFreshClone, boolean shouldAnalyzeAuthorship, double originalityThreshold, BlurbMap blurbMap) + throws IOException, InvalidMarkdownException { prepareTemplateFile(outputPath); if (Files.exists(Paths.get(assetsPath))) { FileUtil.copyDirectoryContents(assetsPath, outputPath, assetsFilesWhiteList); @@ -138,7 +143,7 @@ public List generateReposReport(List configs, String ou new SummaryJson(configs, reportConfig, generationDate, reportSinceDate, untilDate, isSinceDateProvided, isUntilDateProvided, RepoSense.getVersion(), ErrorSummary.getInstance().getErrorSet(), - reportGenerationTimeProvider.get(), zoneId, shouldAnalyzeAuthorship), + reportGenerationTimeProvider.get(), zoneId, shouldAnalyzeAuthorship, blurbMap), getSummaryResultPath(outputPath)); summaryPath.ifPresent(reportFoldersAndFiles::add); diff --git a/src/main/java/reposense/report/SummaryJson.java b/src/main/java/reposense/report/SummaryJson.java index f709fb0998..1e65acad2b 100644 --- a/src/main/java/reposense/report/SummaryJson.java +++ b/src/main/java/reposense/report/SummaryJson.java @@ -6,6 +6,7 @@ import java.util.Map; import java.util.Set; +import reposense.model.BlurbMap; import reposense.model.RepoConfiguration; import reposense.model.ReportConfiguration; import reposense.model.SupportedDomainUrlMap; @@ -29,11 +30,13 @@ public class SummaryJson { private final boolean isUntilDateProvided; private final Map> supportedDomainUrlMap; private final boolean isAuthorshipAnalyzed; + private final BlurbMap blurbs; public SummaryJson(List repos, ReportConfiguration reportConfig, String reportGeneratedTime, - LocalDateTime sinceDate, LocalDateTime untilDate, boolean isSinceDateProvided, boolean isUntilDateProvided, - String repoSenseVersion, Set> errorSet, String reportGenerationTime, ZoneId zoneId, - boolean isAuthorshipAnalyzed) { + LocalDateTime sinceDate, LocalDateTime untilDate, boolean isSinceDateProvided, + boolean isUntilDateProvided, String repoSenseVersion, Set> errorSet, + String reportGenerationTime, ZoneId zoneId, + boolean isAuthorshipAnalyzed, BlurbMap blurbs) { this.repos = repos; this.reportGeneratedTime = reportGeneratedTime; this.reportGenerationTime = reportGenerationTime; @@ -47,5 +50,6 @@ public SummaryJson(List repos, ReportConfiguration reportConf this.zoneId = zoneId; this.supportedDomainUrlMap = SupportedDomainUrlMap.getDefaultDomainUrlMap(); this.isAuthorshipAnalyzed = isAuthorshipAnalyzed; + this.blurbs = blurbs; } } diff --git a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDate/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDate/expected/summary.json index c809a19ae0..f17b82ee29 100644 --- a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDate/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDate/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-10-01","untilDate":"2017-11-01","isSinceDateProvided":false,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-10-01", + "untilDate": "2017-11-01", + "isSinceDateProvided": false, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateFindPreviousAuthors/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateFindPreviousAuthors/expected/summary.json index c809a19ae0..f17b82ee29 100644 --- a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateFindPreviousAuthors/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateFindPreviousAuthors/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-10-01","untilDate":"2017-11-01","isSinceDateProvided":false,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-10-01", + "untilDate": "2017-11-01", + "isSinceDateProvided": false, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateWithShallowCloning/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateWithShallowCloning/expected/summary.json index c809a19ae0..f17b82ee29 100644 --- a/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateWithShallowCloning/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/30daysFromUntilDateWithShallowCloning/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-10-01","untilDate":"2017-11-01","isSinceDateProvided":false,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-10-01", + "untilDate": "2017-11-01", + "isSinceDateProvided": false, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/ConfigSystemTest/blurbs.md b/src/systemtest/resources/ConfigSystemTest/blurbs.md new file mode 100644 index 0000000000..e8a130cc46 --- /dev/null +++ b/src/systemtest/resources/ConfigSystemTest/blurbs.md @@ -0,0 +1,14 @@ +https://www.github.com/user/repo/branch +first blurb + +https://www.github.com/user/repo/branch2 +## **second** blurb + +![link](link) to repository + +this is what i have done for my cs2103t project + +https://www.github.com/user/repo/branch3 +*third blurb* + +third blurb with HTML content diff --git a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRange/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRange/expected/summary.json index f0d69e7d5b..f274f98e7d 100644 --- a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRange/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRange/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-09-30","untilDate":"2019-03-02","isSinceDateProvided":true,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-09-30", + "untilDate": "2019-03-02", + "isSinceDateProvided": true, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeFindPreviousAuthors/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeFindPreviousAuthors/expected/summary.json index f0d69e7d5b..f274f98e7d 100644 --- a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeFindPreviousAuthors/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeFindPreviousAuthors/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-09-30","untilDate":"2019-03-02","isSinceDateProvided":true,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-09-30", + "untilDate": "2019-03-02", + "isSinceDateProvided": true, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeWithShallowCloning/expected/summary.json b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeWithShallowCloning/expected/summary.json index f0d69e7d5b..f274f98e7d 100644 --- a/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeWithShallowCloning/expected/summary.json +++ b/src/systemtest/resources/ConfigSystemTest/sinceBeginningDateRangeWithShallowCloning/expected/summary.json @@ -1 +1,91 @@ -{"reportGeneratedTime":"Tue Jul 24 17:45:15 SGT 2018","reportGenerationTime":"15 second(s)","zoneId":"Asia/Singapore","reportTitle":"RepoSense Report Test Title","repos":[{"location":{"location":"https://github.com/reposense/testrepo-Alpha.git","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Alpha[master]","outputFolderName":"reposense_testrepo-Alpha_master"},{"location":{"location":"https://github.com/reposense/testrepo-Beta.git","repoName":"testrepo-Beta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Beta[master]","outputFolderName":"reposense_testrepo-Beta_master"},{"location":{"location":"https://github.com/reposense/testrepo-Charlie.git","repoName":"testrepo-Charlie","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Charlie[master]","outputFolderName":"reposense_testrepo-Charlie_master"},{"location":{"location":"https://github.com/reposense/testrepo-Delta.git","repoName":"testrepo-Delta","organization":"reposense","domainName":"github"},"branch":"master","displayName":"reposense/testrepo-Delta[master]","outputFolderName":"reposense_testrepo-Delta_master"}],"errorSet":[{"repoName":"ttps://github.com/reposense/testrepo-Beta.git","errorMessage":"ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL."},{"repoName":"reposense/testrepo-Delta[nonExistentBranch]","errorMessage":"Branch \"nonExistentBranch\" does not exist."}],"sinceDate":"2017-09-30","untilDate":"2019-03-02","isSinceDateProvided":true,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jul 24 17:45:15 SGT 2018", + "reportGenerationTime": "15 second(s)", + "zoneId": "Asia/Singapore", + "reportTitle": "RepoSense Report Test Title", + "repos": [ + { + "location": { + "location": "https://github.com/reposense/testrepo-Alpha.git", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Alpha[master]", + "outputFolderName": "reposense_testrepo-Alpha_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Beta.git", + "repoName": "testrepo-Beta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Beta[master]", + "outputFolderName": "reposense_testrepo-Beta_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Charlie.git", + "repoName": "testrepo-Charlie", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Charlie[master]", + "outputFolderName": "reposense_testrepo-Charlie_master" + }, + { + "location": { + "location": "https://github.com/reposense/testrepo-Delta.git", + "repoName": "testrepo-Delta", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "reposense/testrepo-Delta[master]", + "outputFolderName": "reposense_testrepo-Delta_master" + } + ], + "errorSet": [ + { + "repoName": "ttps://github.com/reposense/testrepo-Beta.git", + "errorMessage": "ttps://github.com/reposense/testrepo-Beta.git is an invalid remote URL." + }, + { + "repoName": "reposense/testrepo-Delta[nonExistentBranch]", + "errorMessage": "Branch \"nonExistentBranch\" does not exist." + } + ], + "sinceDate": "2017-09-30", + "untilDate": "2019-03-02", + "isSinceDateProvided": true, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://www.github.com/user/repo/branch": "first blurb", + "https://www.github.com/user/repo/branch2": "## **second** blurb\n\n![link](link) to repository\n\nthis is what i have done for my cs2103t project", + "https://www.github.com/user/repo/branch3": "*third blurb*\n\nthird blurb with HTML content" + } + } +} diff --git a/src/systemtest/resources/LocalRepoSystemTest/testRelativePathing/summary.json b/src/systemtest/resources/LocalRepoSystemTest/testRelativePathing/summary.json index 73eb7dd989..33db57133d 100644 --- a/src/systemtest/resources/LocalRepoSystemTest/testRelativePathing/summary.json +++ b/src/systemtest/resources/LocalRepoSystemTest/testRelativePathing/summary.json @@ -1 +1,47 @@ -{"reportGeneratedTime":"Tue Jan 31 23:48:33 2023 UTC+08:00","reportGenerationTime":" 0.71 second(s)","zoneId":"UTC+08:00","reportTitle":"RepoSense Report","repos":[{"location":{"location":"parent1/../parent1/./test-repo","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"parent1/test-repo[master]","outputFolderName":"parent1_test-repo_master"}],"errorSet":[],"sinceDate":"2018-02-05","untilDate":"2023-01-31","isSinceDateProvided":true,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jan 31 23:48:33 2023 UTC+08:00", + "reportGenerationTime": " 0.71 second(s)", + "zoneId": "UTC+08:00", + "reportTitle": "RepoSense Report", + "repos": [ + { + "location": { + "location": "parent1/../parent1/./test-repo", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "parent1/test-repo[master]", + "outputFolderName": "parent1_test-repo_master" + } + ], + "errorSet": [], + "sinceDate": "2018-02-05", + "untilDate": "2023-01-31", + "isSinceDateProvided": true, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://github.com/reposense/testrepo-Alpha/tree/master": "Master branch of testrepo-Alpha" + } + } +} diff --git a/src/systemtest/resources/LocalRepoSystemTest/testSameFinalDirectory/summary.json b/src/systemtest/resources/LocalRepoSystemTest/testSameFinalDirectory/summary.json index fffce375ea..a5662f38b5 100644 --- a/src/systemtest/resources/LocalRepoSystemTest/testSameFinalDirectory/summary.json +++ b/src/systemtest/resources/LocalRepoSystemTest/testSameFinalDirectory/summary.json @@ -1 +1,58 @@ -{"reportGeneratedTime":"Tue Jan 31 23:34:35 2023 UTC+08:00","reportGenerationTime":" 0.74 second(s)","zoneId":"UTC+08:00","reportTitle":"RepoSense Report","repos":[{"location":{"location":"parent1/test-repo","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"parent1/test-repo[master]","outputFolderName":"parent1_test-repo_master"},{"location":{"location":"parent2/test-repo","repoName":"testrepo-Alpha","organization":"reposense","domainName":"github"},"branch":"master","displayName":"parent2/test-repo[master]","outputFolderName":"parent2_test-repo_master"}],"errorSet":[],"sinceDate":"2018-02-05","untilDate":"2023-01-31","isSinceDateProvided":true,"isUntilDateProvided":true,"supportedDomainUrlMap":{"NOT_RECOGNIZED":{"BRANCH":"","REPO_URL":"UNSUPPORTED","BASE_URL":"UNSUPPORTED","HISTORY_PATH":"","COMMIT_PATH":"","BLAME_PATH":""},"github":{"BRANCH":"tree/$BRANCH","REPO_URL":"https://github.com/$ORGANIZATION/$REPO_NAME/","BASE_URL":"https://github.com/","HISTORY_PATH":"commits/$BRANCH/$FILE_PATH","COMMIT_PATH":"commit/$COMMIT_HASH","BLAME_PATH":"blame/$BRANCH/$FILE_PATH"}}} +{ + "reportGeneratedTime": "Tue Jan 31 23:34:35 2023 UTC+08:00", + "reportGenerationTime": " 0.74 second(s)", + "zoneId": "UTC+08:00", + "reportTitle": "RepoSense Report", + "repos": [ + { + "location": { + "location": "parent1/test-repo", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "parent1/test-repo[master]", + "outputFolderName": "parent1_test-repo_master" + }, + { + "location": { + "location": "parent2/test-repo", + "repoName": "testrepo-Alpha", + "organization": "reposense", + "domainName": "github" + }, + "branch": "master", + "displayName": "parent2/test-repo[master]", + "outputFolderName": "parent2_test-repo_master" + } + ], + "errorSet": [], + "sinceDate": "2018-02-05", + "untilDate": "2023-01-31", + "isSinceDateProvided": true, + "isUntilDateProvided": true, + "supportedDomainUrlMap": { + "NOT_RECOGNIZED": { + "BRANCH": "", + "REPO_URL": "UNSUPPORTED", + "BASE_URL": "UNSUPPORTED", + "HISTORY_PATH": "", + "COMMIT_PATH": "", + "BLAME_PATH": "" + }, + "github": { + "BRANCH": "tree/$BRANCH", + "REPO_URL": "https://github.com/$ORGANIZATION/$REPO_NAME/", + "BASE_URL": "https://github.com/", + "HISTORY_PATH": "commits/$BRANCH/$FILE_PATH", + "COMMIT_PATH": "commit/$COMMIT_HASH", + "BLAME_PATH": "blame/$BRANCH/$FILE_PATH" + } + }, + "blurbs": { + "urlBlurbMap": { + "https://github.com/reposense/testrepo-Alpha/tree/master": "Master branch of testrepo-Alpha" + } + } +} diff --git a/src/test/java/reposense/model/BlurbMapTest.java b/src/test/java/reposense/model/BlurbMapTest.java new file mode 100644 index 0000000000..463d0611aa --- /dev/null +++ b/src/test/java/reposense/model/BlurbMapTest.java @@ -0,0 +1,33 @@ +package reposense.model; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BlurbMapTest { + @Test + public void blurbBuilder_testIfBuildsSuccessfully_success() { + BlurbMap builder = new BlurbMap(); + builder.withRecord("hello", "world"); + BlurbMap newBuilder = new BlurbMap(); + newBuilder.withRecord("hello", "world"); + + Assertions.assertEquals(builder, newBuilder); + } + + @Test + public void blurbBuilder_testIfBuildsEmpty_success() { + BlurbMap map1 = new BlurbMap(); + BlurbMap map2 = new BlurbMap(); + Assertions.assertEquals(map1, map2); + } + + @Test + public void blurbBuilder_testIfUnequal_success() { + BlurbMap builder1 = new BlurbMap(); + BlurbMap builder2 = new BlurbMap(); + + builder1.withRecord("this", "builder"); + builder2.withRecord("other", "builder"); + Assertions.assertNotEquals(builder1, builder2); + } +} diff --git a/src/test/java/reposense/parser/BlurbMarkdownParserTest.java b/src/test/java/reposense/parser/BlurbMarkdownParserTest.java new file mode 100644 index 0000000000..43531b7b31 --- /dev/null +++ b/src/test/java/reposense/parser/BlurbMarkdownParserTest.java @@ -0,0 +1,101 @@ +package reposense.parser; + +import static reposense.util.TestUtil.loadResource; + +import java.nio.file.Path; +import java.util.List; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import reposense.parser.exceptions.InvalidMarkdownException; + +public class BlurbMarkdownParserTest { + private static final Path EMPTY_BLURB_TESTER = loadResource(BlurbMarkdownParserTest.class, + "BlurbMarkdownParserTest/empty_blurbs.md"); + private static final Path MALFORMED_URL_TESTER = loadResource(BlurbMarkdownParserTest.class, + "BlurbMarkdownParserTest/malformed_url_blurb.md"); + private static final Path MALFORMED_DELIMITER_TESTER = loadResource(BlurbMarkdownParserTest.class, + "BlurbMarkdownParserTest/malformed_delimiter_blurb.md"); + private static final Path MULTILINE_BLURB_TESTER = loadResource(BlurbMarkdownParserTest.class, + "BlurbMarkdownParserTest/multiline_blurb.md"); + private static final Path MULTIPLE_BLURB_TESTER = loadResource(BlurbMarkdownParser.class, + "BlurbMarkdownParserTest/multiple_blurbs.md"); + + @Test + public void parse_emptyBlurbTest_throwsException() { + Assertions.assertThrows( + InvalidMarkdownException.class, () -> new BlurbMarkdownParser(EMPTY_BLURB_TESTER).parse() + ); + } + + @Test + public void parse_malformedUrlBlurbTest_throwsException() { + Assertions.assertThrows( + InvalidMarkdownException.class, () -> new BlurbMarkdownParser(MALFORMED_URL_TESTER).parse() + ); + } + + @Test + public void parse_malformedDelimiterBlurbTest_success() throws Exception { + BlurbMarkdownParser bmp = new BlurbMarkdownParser(MALFORMED_DELIMITER_TESTER); + Map bm = bmp.parse().getAllMappings(); + Assertions.assertTrue(bm.containsKey("https://github.com/reposense/testrepo-Alpha/tree/master")); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Alpha/tree/master"), + "Master branch of testrepo-Alpha\n" + + "" + ); + } + + @Test + public void parse_multilineBlurbTest_success() throws Exception { + BlurbMarkdownParser bmp = new BlurbMarkdownParser(MULTILINE_BLURB_TESTER); + Map bm = bmp.parse().getAllMappings(); + Assertions.assertTrue(bm.containsKey("https://github.com/reposense/testrepo-Alpha/tree/master")); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Alpha/tree/master"), + "Master branch of testrepo-Alpha\n" + + "A\n" + + "long\n" + + "line\n" + + "of\n" + + "description\n" + + "of\n" + + "testrepo\n" + + "Alpha" + ); + } + + @Test + public void parse_multipleBlurbTest_success() throws Exception { + BlurbMarkdownParser bmp = new BlurbMarkdownParser(MULTIPLE_BLURB_TESTER); + Map bm = bmp.parse().getAllMappings(); + Assertions.assertTrue(bm.keySet().containsAll( + List.of("https://github.com/reposense/testrepo-Alpha/tree/master", + "https://github.com/reposense/testrepo-Beta/tree/master", + "https://github.com/reposense/testrepo-Gamma/tree/master", + "https://github.com/reposense/testrepo-Sigma/tree/master") + )); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Alpha/tree/master"), + "Master branch of testrepo-Alpha" + ); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Beta/tree/master"), + "Master branch of testrepo-Beta" + ); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Gamma/tree/master"), + "Master branch of testrepo-Gamma" + ); + Assertions.assertEquals( + bm.get("https://github.com/reposense/testrepo-Sigma/tree/master"), + "Master branch of testrepo-Sigma" + ); + } +} diff --git a/src/test/resources/BlurbMarkdownParserTest/empty_blurbs.md b/src/test/resources/BlurbMarkdownParserTest/empty_blurbs.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/test/resources/BlurbMarkdownParserTest/malformed_delimiter_blurb.md b/src/test/resources/BlurbMarkdownParserTest/malformed_delimiter_blurb.md new file mode 100644 index 0000000000..95f0ba1c44 --- /dev/null +++ b/src/test/resources/BlurbMarkdownParserTest/malformed_delimiter_blurb.md @@ -0,0 +1,7 @@ +https://github.com/reposense/testrepo-Alpha/tree/master +Master branch of testrepo-Alpha + +but this is legal and will be ignored diff --git a/src/test/resources/BlurbMarkdownParserTest/malformed_url_blurb.md b/src/test/resources/BlurbMarkdownParserTest/malformed_url_blurb.md new file mode 100644 index 0000000000..3b68b169c7 --- /dev/null +++ b/src/test/resources/BlurbMarkdownParserTest/malformed_url_blurb.md @@ -0,0 +1,2 @@ +://github/reposense/testrepo-Alp +Malformed URL Test diff --git a/src/test/resources/BlurbMarkdownParserTest/multiline_blurb.md b/src/test/resources/BlurbMarkdownParserTest/multiline_blurb.md new file mode 100644 index 0000000000..a2a4711e01 --- /dev/null +++ b/src/test/resources/BlurbMarkdownParserTest/multiline_blurb.md @@ -0,0 +1,10 @@ +https://github.com/reposense/testrepo-Alpha/tree/master +Master branch of testrepo-Alpha +A +long +line +of +description +of +testrepo +Alpha diff --git a/src/test/resources/BlurbMarkdownParserTest/multiple_blurbs.md b/src/test/resources/BlurbMarkdownParserTest/multiple_blurbs.md new file mode 100644 index 0000000000..b49af3b1e7 --- /dev/null +++ b/src/test/resources/BlurbMarkdownParserTest/multiple_blurbs.md @@ -0,0 +1,12 @@ +https://github.com/reposense/testrepo-Alpha/tree/master +Master branch of testrepo-Alpha + +https://github.com/reposense/testrepo-Beta/tree/master +Master branch of testrepo-Beta + +https://github.com/reposense/testrepo-Gamma/tree/master +Master branch of testrepo-Gamma + +https://github.com/reposense/testrepo-Sigma/tree/master +Master branch of testrepo-Sigma +