* A dynamic analysis of code can be performed on certain languages.
## Will _all_ files be analyzed?
-By default, only files that are recognized by a language analyzer are loaded into the project during analysis. For example if your SonarQube instance had only SonarJava SonarJS on board, all .java and .js files would be loaded, but .xml files would be ignored. However, it is possible to import all text files in a project by setting **Settings > Exclusions > Files > Import unknown files** to true.
+By default, only files that are recognized by a language analyzer are loaded into the project during analysis. For example if your SonarQube instance had only SonarJava SonarJS on board, all .java and .js files would be loaded, but .xml files would be ignored. However, it is possible to import all text files in a project by setting [**Settings > Exclusions > Files > Import unknown files**](/#sonarqube-admin#/admin/settings?category=exclusions) to true.
## What happens during analysis?
During analysis, data is requested from the server, the files provided to the analysis are analyzed, and the resulting data is sent back to the server at the end in the form of a report, which is then analyzed asynchronously server-side.
* You want to ensure stronger requirements on some of your applications (internal frameworks for example).
* Etc.
-Which is why you can define as many quality profiles as you wish even though it is recommended to have as few Quality Profiles as possible to ensure consistency across the projects in your company. To manage quality profiles, go to **Quality Profiles** (top bar), where you'll find profiles grouped by language.
+Which is why you can define as many quality profiles as you wish even though it is recommended to have as few Quality Profiles as possible to ensure consistency across the projects in your company. To manage quality profiles, go to <!-- sonarqube -->[**Quality Profiles**](/#sonarqube#/profiles)<!-- /sonarqube --><!-- sonarcloud -->**Quality Profiles** page of your organization<!-- /sonarcloud -->, where you'll find profiles grouped by language.
Each language plugin comes with a predefined, built-in profile (usually called "Sonar way") so that you can get started very quickly with SonarQube analyses. This is why as soon as you install a new language plugin, at least one quality profile will be available for you. Each language must have a default profile (marked with the Default tag). Projects that are not explicitly associated with a specific profile will be analyzed using the language's default profile.
import * as React from 'react';
import { Link } from 'react-router';
import DetachIcon from '../icons-components/DetachIcon';
+import { isSonarCloud } from '../../helpers/system';
interface OwnProps {
customProps?: {
type Props = OwnProps & React.AnchorHTMLAttributes<HTMLAnchorElement>;
const SONARCLOUD_LINK = '/#sonarcloud#/';
+const SONARQUBE_LINK = '/#sonarqube#/';
+const SONARQUBE_ADMIN_LINK = '/#sonarqube-admin#/';
export default class DocLink extends React.PureComponent<Props> {
+ static contextTypes = {
+ canAdmin: () => null
+ };
+
handleClickOnAnchor = (event: React.MouseEvent<HTMLAnchorElement>) => {
const { customProps, href = '#' } = this.props;
if (customProps && customProps.onAnchorClick) {
}
if (href && href.startsWith('/')) {
- let url = `/documentation/${href.substr(1)}`;
if (href.startsWith(SONARCLOUD_LINK)) {
- url = `/${href.substr(SONARCLOUD_LINK.length)}`;
+ return <SonarCloudLink url={href}>{children}</SonarCloudLink>;
+ } else if (href.startsWith(SONARQUBE_LINK)) {
+ return <SonarQubeLink url={href}>{children}</SonarQubeLink>;
+ } else if (href.startsWith(SONARQUBE_ADMIN_LINK)) {
+ return (
+ <SonarQubeAdminLink canAdmin={this.context.canAdmin} url={href}>
+ {children}
+ </SonarQubeAdminLink>
+ );
+ } else {
+ const url = '/documentation' + href;
+ return (
+ <Link to={url} {...other}>
+ {children}
+ </Link>
+ );
}
- return (
- <Link to={url} {...other}>
- {children}
- </Link>
- );
}
return (
);
}
}
+
+interface SonarCloudLinkProps {
+ children: React.ReactNode;
+ url: string;
+}
+
+function SonarCloudLink({ children, url }: SonarCloudLinkProps) {
+ if (!isSonarCloud()) {
+ return <>{children}</>;
+ } else {
+ const to = `/${url.substr(SONARCLOUD_LINK.length)}`;
+ return <Link to={to}>{children}</Link>;
+ }
+}
+
+interface SonarQubeLinkProps {
+ children: React.ReactNode;
+ url: string;
+}
+
+function SonarQubeLink({ children, url }: SonarQubeLinkProps) {
+ if (isSonarCloud()) {
+ return <>{children}</>;
+ } else {
+ const to = `/${url.substr(SONARQUBE_LINK.length)}`;
+ return (
+ <Link target="_blank" to={to}>
+ {children}
+ </Link>
+ );
+ }
+}
+
+interface SonarQubeAdminLinkProps {
+ canAdmin: boolean;
+ children: React.ReactNode;
+ url: string;
+}
+
+function SonarQubeAdminLink({ canAdmin, children, url }: SonarQubeAdminLinkProps) {
+ if (isSonarCloud() || !canAdmin) {
+ return <>{children}</>;
+ } else {
+ const to = `/${url.substr(SONARQUBE_ADMIN_LINK.length)}`;
+ return (
+ <Link target="_blank" to={to}>
+ {children}
+ </Link>
+ );
+ }
+}
import * as React from 'react';
import { shallow } from 'enzyme';
import DocLink from '../DocLink';
+import { isSonarCloud } from '../../../helpers/system';
+
+jest.mock('../../../helpers/system', () => ({
+ isSonarCloud: jest.fn(() => false)
+}));
it('should render simple link', () => {
- expect(shallow(<DocLink href="http://sample.com" />)).toMatchSnapshot();
+ expect(shallow(<DocLink href="http://sample.com">link text</DocLink>)).toMatchSnapshot();
});
it('should render documentation link', () => {
- expect(shallow(<DocLink href="/foo/bar" />)).toMatchSnapshot();
+ expect(shallow(<DocLink href="/foo/bar">link text</DocLink>)).toMatchSnapshot();
+});
+
+it('should render sonarcloud link on sonarcloud', () => {
+ (isSonarCloud as jest.Mock).mockImplementationOnce(() => true);
+ const wrapper = shallow(<DocLink href="/#sonarcloud#/foo/bar">link text</DocLink>);
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('SonarCloudLink').dive()).toMatchSnapshot();
+});
+
+it('should not render sonarcloud link on sonarcloud', () => {
+ (isSonarCloud as jest.Mock).mockImplementationOnce(() => false);
+ const wrapper = shallow(<DocLink href="/#sonarcloud#/foo/bar">link text</DocLink>);
+ expect(wrapper.find('SonarCloudLink').dive()).toMatchSnapshot();
+});
+
+it('should render sonarqube link on sonarqube', () => {
+ const wrapper = shallow(<DocLink href="/#sonarqube#/foo/bar">link text</DocLink>);
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('SonarQubeLink').dive()).toMatchSnapshot();
+});
+
+it('should not render sonarqube link on sonarcloud', () => {
+ (isSonarCloud as jest.Mock).mockImplementationOnce(() => true);
+ const wrapper = shallow(<DocLink href="/#sonarqube#/foo/bar">link text</DocLink>);
+ expect(wrapper.find('SonarQubeLink').dive()).toMatchSnapshot();
+});
+
+it('should render sonarqube admin link on sonarqube for admin', () => {
+ const wrapper = shallow(<DocLink href="/#sonarqube-admin#/foo/bar">link text</DocLink>, {
+ context: { canAdmin: true }
+ });
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('SonarQubeAdminLink').dive()).toMatchSnapshot();
+});
+
+it('should not render sonarqube admin link on sonarqube for non-admin', () => {
+ const wrapper = shallow(<DocLink href="/#sonarqube-admin#/foo/bar">link text</DocLink>);
+ expect(wrapper.find('SonarQubeAdminLink').dive()).toMatchSnapshot();
});
-it('should render sonarcloud link', () => {
- expect(shallow(<DocLink href="/#sonarcloud#/foo/bar" />)).toMatchSnapshot();
+it('should not render sonarqube admin link on sonarcloud', () => {
+ (isSonarCloud as jest.Mock).mockImplementationOnce(() => true);
+ const wrapper = shallow(<DocLink href="/#sonarqube-admin#/foo/bar">link text</DocLink>, {
+ context: { canAdmin: true }
+ });
+ expect(wrapper.find('SonarQubeAdminLink').dive()).toMatchSnapshot();
});
it.skip('should render documentation anchor', () => {
- expect(shallow(<DocLink href="#quality-profiles" />)).toMatchSnapshot();
+ expect(shallow(<DocLink href="#quality-profiles">link text</DocLink>)).toMatchSnapshot();
});
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`should not render sonarcloud link on sonarcloud 1`] = `
+<React.Fragment>
+ link text
+</React.Fragment>
+`;
+
+exports[`should not render sonarqube admin link on sonarcloud 1`] = `
+<React.Fragment>
+ link text
+</React.Fragment>
+`;
+
+exports[`should not render sonarqube admin link on sonarqube for non-admin 1`] = `
+<React.Fragment>
+ link text
+</React.Fragment>
+`;
+
+exports[`should not render sonarqube link on sonarcloud 1`] = `
+<React.Fragment>
+ link text
+</React.Fragment>
+`;
+
exports[`should render documentation link 1`] = `
<Link
onlyActiveOnIndex={false}
style={Object {}}
to="/documentation/foo/bar"
-/>
+>
+ link text
+</Link>
`;
exports[`should render simple link 1`] = `
href="http://sample.com"
rel="noopener noreferrer"
target="_blank"
- />
+ >
+ link text
+ </a>
<DetachIcon
className="text-muted little-spacer-left little-spacer-right vertical-baseline"
size={12}
</React.Fragment>
`;
-exports[`should render sonarcloud link 1`] = `
+exports[`should render sonarcloud link on sonarcloud 1`] = `
+<SonarCloudLink
+ url="/#sonarcloud#/foo/bar"
+>
+ link text
+</SonarCloudLink>
+`;
+
+exports[`should render sonarcloud link on sonarcloud 2`] = `
+<Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/foo/bar"
+>
+ link text
+</Link>
+`;
+
+exports[`should render sonarqube admin link on sonarqube for admin 1`] = `
+<SonarQubeAdminLink
+ canAdmin={true}
+ url="/#sonarqube-admin#/foo/bar"
+>
+ link text
+</SonarQubeAdminLink>
+`;
+
+exports[`should render sonarqube admin link on sonarqube for admin 2`] = `
+<Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/foo/bar"
+>
+ link text
+</Link>
+`;
+
+exports[`should render sonarqube link on sonarqube 1`] = `
+<SonarQubeLink
+ url="/#sonarqube#/foo/bar"
+>
+ link text
+</SonarQubeLink>
+`;
+
+exports[`should render sonarqube link on sonarqube 2`] = `
<Link
onlyActiveOnIndex={false}
style={Object {}}
+ target="_blank"
to="/foo/bar"
-/>
+>
+ link text
+</Link>
`;