},
plugins: [
{
- resolve: 'gatsby-source-filesystem',
+ resolve: `sonarsource-source-filesystem`,
options: { name: 'src', path: `${__dirname}/src/` }
},
'gatsby-plugin-react-helmet',
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+const { sourceNodes, setFieldsOnGraphQLNodeType } = require('gatsby-source-filesystem/gatsby-node');
+
+exports.sourceNodes = sourceNodes;
+exports.setFieldsOnGraphQLNodeType = setFieldsOnGraphQLNodeType;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+const { createFilePath, createRemoteFileNode } = require('gatsby-source-filesystem');
+const fs = require('fs-extra');
+
+function loadNodeContent(fileNode) {
+ const content = fs.readFileSync(fileNode.absolutePath, 'utf-8');
+ return new Promise((resolve, reject) => {
+ let newContent = cutSonarCloudContent(content);
+ newContent = removeRemainingContentTags(newContent);
+ resolve(newContent);
+ });
+}
+
+function removeRemainingContentTags(content) {
+ const regexBase = '<!-- \\/?(sonarqube|sonarcloud|static) -->';
+ return content
+ .replace(new RegExp(`^${regexBase}(\n|\r|\r\n|$)`, 'gm'), '') // First, remove single-line ones, including ending carriage-returns.
+ .replace(new RegExp(`${regexBase}`, 'g'), ''); // Now remove all remaining ones.
+}
+
+function cutSonarCloudContent(content) {
+ const beginning = '<!-- sonarcloud -->';
+ const ending = '<!-- /sonarcloud -->';
+
+ let newContent = content;
+ let start = newContent.indexOf(beginning);
+ let end = newContent.indexOf(ending);
+ while (start !== -1 && end !== -1) {
+ newContent = newContent.substring(0, start) + newContent.substring(end + ending.length);
+ start = newContent.indexOf(beginning);
+ end = newContent.indexOf(ending);
+ }
+
+ return newContent;
+}
+
+exports.createFilePath = createFilePath;
+exports.createRemoteFileNode = createRemoteFileNode;
+exports.loadNodeContent = loadNodeContent;
--- /dev/null
+{
+ "name": "sonarsource-source-filesystem",
+ "version": "1.0.0",
+ "description": "",
+ "main": "create-file-node.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC"
+}
render() {
const page = this.props.data.markdownRemark;
- let htmlWithInclusions = cutSonarCloudContent(page.html).replace(
- /<p>@include (.*)<\/p>/,
- (_, path) => {
- const chunk = data.allMarkdownRemark.edges.find(edge => edge.node.fields.slug === path);
- return chunk ? chunk.node.html : '';
- }
- );
+ let htmlWithInclusions = page.html.replace(/<p>@include (.*)<\/p>/, (_, path) => {
+ const chunk = data.allMarkdownRemark.edges.find(edge => edge.node.fields.slug === path);
+ return chunk ? chunk.node.html : '';
+ });
const realHeadingsList = removeExtraHeadings(page.html, page.headings);
+
htmlWithInclusions = removeTableOfContents(htmlWithInclusions);
htmlWithInclusions = createAnchorForHeadings(htmlWithInclusions, realHeadingsList);
htmlWithInclusions = replaceDynamicLinks(htmlWithInclusions);
function removeTableOfContents(content) {
return content.replace(/<h[1-9]>Table Of Contents<\/h[1-9]>/i, '');
}
-
-function cutSonarCloudContent(content) {
- const beginning = '<!-- sonarcloud -->';
- const ending = '<!-- /sonarcloud -->';
-
- let newContent = content;
- let start = newContent.indexOf(beginning);
- let end = newContent.indexOf(ending);
- while (start !== -1 && end !== -1) {
- newContent = newContent.substring(0, start) + newContent.substring(end + ending.length);
- start = newContent.indexOf(beginning);
- end = newContent.indexOf(ending);
- }
-
- return newContent;
-}
import * as React from 'react';
import { shallow } from 'enzyme';
import DocMarkdownBlock from '../DocMarkdownBlock';
-import { isSonarCloud } from '../../../helpers/system';
const CONTENT_WITH_TOC = `
## Table of Contents
).toMatchSnapshot();
});
-it('should cut sonarqube/sonarcloud/static content', () => {
- const content = `
-some
-
-<!-- sonarqube -->
-sonarqube
-<!-- /sonarqube -->
-
-<!-- sonarcloud -->
-sonarcloud
-<!-- /sonarcloud -->
-
-<!-- static -->
-static
-<!-- /static -->
-
-<!-- sonarqube -->
- long
-
- multiline
-<!-- /sonarqube -->
-
-text`;
-
- (isSonarCloud as jest.Mock).mockImplementation(() => false);
- expect(shallowRender({ content })).toMatchSnapshot();
-
- (isSonarCloud as jest.Mock).mockImplementation(() => true);
- expect(shallowRender({ content })).toMatchSnapshot();
-});
-
it('should render with custom props for links', () => {
expect(
shallowRender({
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`should cut sonarqube/sonarcloud/static content 1`] = `
-<div
- className="markdown"
->
- <div
- className="markdown-content"
- >
- <Block
- key="h-1"
- >
- <p
- key="h-2"
- >
- some
- </p>
-
-
- <p
- key="h-3"
- >
- sonarqube
- </p>
-
-
- <p
- key="h-4"
- >
- long
- </p>
-
-
- <p
- key="h-5"
- >
- multiline
- </p>
-
-
- <p
- key="h-6"
- >
- text
- </p>
- </Block>
- </div>
-</div>
-`;
-
-exports[`should cut sonarqube/sonarcloud/static content 2`] = `
-<div
- className="markdown"
->
- <div
- className="markdown-content"
- >
- <Block
- key="h-1"
- >
- <p
- key="h-2"
- >
- some
- </p>
-
-
- <p
- key="h-3"
- >
- sonarcloud
- </p>
-
-
- <p
- key="h-4"
- >
- text
- </p>
- </Block>
- </div>
-</div>
-`;
-
exports[`should render a TOC if available 1`] = `
<div
className="markdown"
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should cut sonarqube/sonarcloud/static content 1`] = `
+"
+This text has inline text for SonarQube. Donec sed nulla magna.
+
+This is text for SonarQube, multi-line. Consectetur adipiscing elit. Duis dignissim nulla at massa iaculis interdum.
+Aenean sit amet lacus a tortor ullamcorper interdum. Donec sed nulla magna.
+
+
+
+
+
+This is text for SonarQube, single line.
+
+* In hac habitasse
+* Duis sagittis semper sapien nec tempor
+* This is a bullet point for SonarQube
+
+* Platea dictumst
+
+Duis sagittis semper sapien nec tempor. Nullam vehicula nisi vitae nisi interdum aliquam.
+
+| Parameter Name | Description |
+| --------------------- | ------------------ |
+| sonar.pullrequest.github.repository | SLUG of the GitHub Repo |
+| sonar.pullrequest.github.endpoint | The API url for your GitHub instance. |
+"
+`;
+
+exports[`should cut sonarqube/sonarcloud/static content 2`] = `
+"
+This text has inline text for SonarCloud. Donec sed nulla magna.
+
+
+
+This is text for SonarCloud, multi-line. In hac habitasse platea dictumst. Duis sagittis semper sapien nec tempor. Nullam vehicula nisi vitae nisi interdum aliquam. Mauris volutpat nunc non fermentum rhoncus. Aenean laoreet, orci vitae tempor bibendum,
+metus nisl euismod neque, vitae euismod nibh nisl eu velit. Vivamus luctus suscipit elit vel semper.
+
+
+
+
+
+* In hac habitasse
+* Duis sagittis semper sapien nec tempor
+
+* This is a bullet point for SonarCloud
+* Platea dictumst
+
+Duis sagittis semper sapien nec tempor. Nullam vehicula nisi vitae nisi interdum aliquam.
+
+| Parameter Name | Description |
+| --------------------- | ------------------ |
+| sonar.pullrequest.github.repository | SLUG of the GitHub Repo |
+
+"
+`;
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { getFrontMatter, separateFrontMatter, filterContent } from '../markdown';
+import { isSonarCloud } from '../system';
jest.mock('../system', () => ({
getInstance: () => 'SonarQube',
- isSonarCloud: () => false
+ isSonarCloud: jest.fn().mockReturnValue(false)
}));
it('returns parsed frontmatter of one item', () => {
filterContent('This is {instance} content. It replaces all {instance}{instance} messages')
).toBe('This is SonarQube content. It replaces all SonarQubeSonarQube messages');
});
+
+it('should cut sonarqube/sonarcloud/static content', () => {
+ const content = `
+This text has inline text for <!-- sonarqube -->SonarQube<!-- /sonarqube --><!-- sonarcloud -->SonarCloud<!-- /sonarcloud -->. Donec sed nulla magna.
+
+<!-- sonarqube -->
+This is text for SonarQube, multi-line. Consectetur adipiscing elit. Duis dignissim nulla at massa iaculis interdum.
+Aenean sit amet lacus a tortor ullamcorper interdum. Donec sed nulla magna.
+<!-- /sonarqube -->
+
+<!-- sonarcloud -->
+This is text for SonarCloud, multi-line. In hac habitasse platea dictumst. Duis sagittis semper sapien nec tempor. Nullam vehicula nisi vitae nisi interdum aliquam. Mauris volutpat nunc non fermentum rhoncus. Aenean laoreet, orci vitae tempor bibendum,
+metus nisl euismod neque, vitae euismod nibh nisl eu velit. Vivamus luctus suscipit elit vel semper.
+<!-- /sonarcloud -->
+
+<!-- static -->
+This is static text.
+<!-- /static -->
+
+<!-- sonarqube -->
+This is text for SonarQube, single line.
+<!-- /sonarqube -->
+
+* In hac habitasse
+* Duis sagittis semper sapien nec tempor
+<!-- sonarqube -->* This is a bullet point for SonarQube<!-- /sonarqube -->
+<!-- sonarcloud -->* This is a bullet point for SonarCloud<!-- /sonarcloud -->
+* Platea dictumst
+
+Duis sagittis semper sapien nec tempor. Nullam vehicula nisi vitae nisi interdum aliquam.
+
+| Parameter Name | Description |
+| --------------------- | ------------------ |
+| sonar.pullrequest.github.repository | SLUG of the GitHub Repo |
+<!-- sonarqube -->
+| sonar.pullrequest.github.endpoint | The API url for your GitHub instance. |
+<!-- /sonarqube -->
+`;
+
+ expect(filterContent(content)).toMatchSnapshot();
+
+ (isSonarCloud as jest.Mock).mockReturnValueOnce(true);
+ expect(filterContent(content)).toMatchSnapshot();
+});
* @returns {string}
*/
function filterContent(content) {
+ const regexBase = '<!-- \\/?(sonarqube|sonarcloud|static) -->';
const { isSonarCloud, getInstance } = require('./system');
const contentWithInstance = content.replace(/{instance}/gi, getInstance());
const contentWithoutStatic = cutConditionalContent(contentWithInstance, 'static');
- return isSonarCloud()
+ const filteredContent = isSonarCloud()
? cutConditionalContent(contentWithoutStatic, 'sonarqube')
: cutConditionalContent(contentWithoutStatic, 'sonarcloud');
+ return filteredContent
+ .replace(new RegExp(`^${regexBase}(\n|\r|\r\n|$)`, 'gm'), '') // First, remove single-line ones, including ending carriage-returns.
+ .replace(new RegExp(`${regexBase}`, 'g'), ''); // Now remove all remaining ones.
}
/**