@@ -215,6 +215,7 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender | |||
{selectedTutorial === TutorialModes.Jenkins && ( | |||
<JenkinsTutorial | |||
almBinding={almBinding} | |||
baseUrl={baseUrl} | |||
component={component} | |||
projectBinding={projectBinding} | |||
/> |
@@ -494,6 +494,7 @@ exports[`should render correctly: jenkins tutorial 1`] = ` | |||
"key": "key", | |||
} | |||
} | |||
baseUrl="http://localhost:9000" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], |
@@ -36,6 +36,7 @@ import WebhookStep from './WebhookStep'; | |||
export interface JenkinsTutorialProps { | |||
almBinding?: AlmSettingsInstance; | |||
baseUrl: string; | |||
branchesEnabled: boolean; | |||
component: T.Component; | |||
projectBinding?: ProjectAlmBindingResponse; | |||
@@ -54,7 +55,7 @@ enum Steps { | |||
const USER_SETTING_SKIP_BITBUCKET_PREREQS = 'tutorials.jenkins.skipBitbucketPreReqs'; | |||
export function JenkinsTutorial(props: JenkinsTutorialProps) { | |||
const { almBinding, branchesEnabled, component, projectBinding, skipPreReqs } = props; | |||
const { almBinding, baseUrl, branchesEnabled, component, projectBinding, skipPreReqs } = props; | |||
const hasSelectAlmStep = projectBinding?.alm === undefined; | |||
const [alm, setAlm] = React.useState<AlmKeys | undefined>(projectBinding?.alm); | |||
@@ -133,7 +134,12 @@ export function JenkinsTutorial(props: JenkinsTutorialProps) { | |||
projectBinding={projectBinding} | |||
/> | |||
<JenkinsfileStep alm={alm} component={component} open={step === Steps.Jenkinsfile} /> | |||
<JenkinsfileStep | |||
alm={alm} | |||
component={component} | |||
baseUrl={baseUrl} | |||
open={step === Steps.Jenkinsfile} | |||
/> | |||
</> | |||
)} | |||
</> |
@@ -18,12 +18,15 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { AlmKeys } from '../../../types/alm-settings'; | |||
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature'; | |||
import AllSet from '../components/AllSet'; | |||
import RenderOptions from '../components/RenderOptions'; | |||
import Step from '../components/Step'; | |||
import { BuildTools } from '../types'; | |||
import CFamilly from './buildtool-steps/CFamilly'; | |||
import DotNet from './buildtool-steps/DotNet'; | |||
import Gradle from './buildtool-steps/Gradle'; | |||
import Maven from './buildtool-steps/Maven'; | |||
@@ -31,25 +34,34 @@ import Other from './buildtool-steps/Other'; | |||
export interface JenkinsfileStepProps { | |||
alm: AlmKeys; | |||
baseUrl: string; | |||
component: T.Component; | |||
hasCLanguageFeature: boolean; | |||
open: boolean; | |||
} | |||
// To remove when CFamily is includ in this tutorial | |||
type BuildToolsWithoutCFamily = Exclude<BuildTools, BuildTools.CFamily>; | |||
export interface LanguageProps { | |||
component: T.Component; | |||
baseUrl: string; | |||
} | |||
const BUILDTOOL_COMPONENT_MAP: { | |||
[x in BuildToolsWithoutCFamily]: React.ComponentType<{ component: T.Component }>; | |||
[x in BuildTools]: React.ComponentType<LanguageProps>; | |||
} = { | |||
[BuildTools.Maven]: Maven, | |||
[BuildTools.Gradle]: Gradle, | |||
[BuildTools.DotNet]: DotNet, | |||
[BuildTools.CFamily]: CFamilly, | |||
[BuildTools.Other]: Other | |||
}; | |||
export default function JenkinsfileStep(props: JenkinsfileStepProps) { | |||
const { alm, component, open } = props; | |||
const [buildTool, setBuildTool] = React.useState<BuildToolsWithoutCFamily | undefined>(undefined); | |||
export function JenkinsfileStep(props: JenkinsfileStepProps) { | |||
const { alm, component, hasCLanguageFeature, baseUrl, open } = props; | |||
const [buildTool, setBuildTool] = React.useState<BuildTools>(); | |||
const buildToolOrder = Object.keys(BUILDTOOL_COMPONENT_MAP); | |||
if (!hasCLanguageFeature) { | |||
buildToolOrder.splice(buildToolOrder.indexOf(BuildTools.CFamily), 1); | |||
} | |||
return ( | |||
<Step | |||
finished={false} | |||
@@ -62,13 +74,18 @@ export default function JenkinsfileStep(props: JenkinsfileStepProps) { | |||
<RenderOptions | |||
checked={buildTool} | |||
name="buildtool" | |||
onCheck={value => setBuildTool(value as BuildToolsWithoutCFamily)} | |||
onCheck={value => setBuildTool(value as BuildTools)} | |||
optionLabelKey="onboarding.build" | |||
options={Object.keys(BUILDTOOL_COMPONENT_MAP)} | |||
options={buildToolOrder} | |||
/> | |||
{buildTool === BuildTools.CFamily && ( | |||
<Alert variant="info" className="spacer-top abs-width-600"> | |||
{translate('onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup')} | |||
</Alert> | |||
)} | |||
</li> | |||
{buildTool !== undefined && | |||
React.createElement(BUILDTOOL_COMPONENT_MAP[buildTool], { component })} | |||
React.createElement(BUILDTOOL_COMPONENT_MAP[buildTool], { component, baseUrl })} | |||
</ol> | |||
{buildTool !== undefined && ( | |||
<> | |||
@@ -83,3 +100,5 @@ export default function JenkinsfileStep(props: JenkinsfileStepProps) { | |||
/> | |||
); | |||
} | |||
export default withCLanguageFeature(JenkinsfileStep); |
@@ -132,6 +132,7 @@ it('should correctly select an ALM if no project is bound', () => { | |||
function shallowRender(props: Partial<JenkinsTutorialProps> = {}) { | |||
return shallow<JenkinsTutorialProps>( | |||
<JenkinsTutorial | |||
baseUrl="" | |||
branchesEnabled={true} | |||
component={mockComponent()} | |||
projectBinding={mockProjectBitbucketBindingResponse()} |
@@ -25,11 +25,13 @@ import RenderOptions from '../../components/RenderOptions'; | |||
import Step from '../../components/Step'; | |||
import { renderStepContent } from '../../test-utils'; | |||
import { BuildTools } from '../../types'; | |||
import JenkinsfileStep, { JenkinsfileStepProps } from '../JenkinsfileStep'; | |||
import { JenkinsfileStep, JenkinsfileStepProps } from '../JenkinsfileStep'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('Step wrapper'); | |||
wrapper.setProps({ hasCLanguageFeature: true }); | |||
expect(wrapper).toMatchSnapshot('Step wrapper with C'); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot('initial content'); | |||
}); | |||
@@ -71,7 +73,9 @@ function shallowRender(props: Partial<JenkinsfileStepProps> = {}) { | |||
return shallow<JenkinsfileStepProps>( | |||
<JenkinsfileStep | |||
alm={AlmKeys.BitbucketCloud} | |||
baseUrl="nice_url" | |||
component={mockComponent()} | |||
hasCLanguageFeature={false} | |||
open={true} | |||
{...props} | |||
/> |
@@ -45,8 +45,9 @@ exports[`should render correctly: branches not enabled 1`] = ` | |||
} | |||
} | |||
/> | |||
<JenkinsfileStep | |||
<Connect(withCLanguageFeature(JenkinsfileStep)) | |||
alm="bitbucket" | |||
baseUrl="" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -128,8 +129,9 @@ exports[`should render correctly: default 1`] = ` | |||
} | |||
} | |||
/> | |||
<JenkinsfileStep | |||
<Connect(withCLanguageFeature(JenkinsfileStep)) | |||
alm="bitbucket" | |||
baseUrl="" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], |
@@ -25,6 +25,7 @@ exports[`should render correctly for .NET 1`] = ` | |||
/> | |||
</li> | |||
<DotNet | |||
baseUrl="nice_url" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -85,6 +86,7 @@ exports[`should render correctly for Gradle 1`] = ` | |||
/> | |||
</li> | |||
<Gradle | |||
baseUrl="nice_url" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -145,6 +147,7 @@ exports[`should render correctly for Maven 1`] = ` | |||
/> | |||
</li> | |||
<Maven | |||
baseUrl="nice_url" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -205,6 +208,7 @@ exports[`should render correctly for Other 1`] = ` | |||
/> | |||
</li> | |||
<Other | |||
baseUrl="nice_url" | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
@@ -250,6 +254,16 @@ exports[`should render correctly: Step wrapper 1`] = ` | |||
/> | |||
`; | |||
exports[`should render correctly: Step wrapper with C 1`] = ` | |||
<Step | |||
finished={false} | |||
open={true} | |||
renderForm={[Function]} | |||
stepNumber={3} | |||
stepTitle="onboarding.tutorial.with.jenkins.jenkinsfile.title" | |||
/> | |||
`; | |||
exports[`should render correctly: initial content 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
@@ -268,6 +282,7 @@ exports[`should render correctly: initial content 1`] = ` | |||
"maven", | |||
"gradle", | |||
"dotnet", | |||
"cfamily", | |||
"other", | |||
] | |||
} |
@@ -0,0 +1,131 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 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. | |||
*/ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { CompilationInfo } from '../../components/CompilationInfo'; | |||
import DefaultProjectKey from '../../components/DefaultProjectKey'; | |||
import RenderOptions from '../../components/RenderOptions'; | |||
import { OSs } from '../../types'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface CFamillyProps { | |||
component: T.Component; | |||
baseUrl: string; | |||
} | |||
const YAML_MAP: Record<OSs, (baseUrl: string) => string> = { | |||
[OSs.Linux]: baseUrl => `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
sh "mkdir -p .sonar" | |||
sh "curl -sSLo build-wrapper-linux-x86.zip ${baseUrl}/static/cpp/build-wrapper-linux-x86.zip" | |||
sh "unzip -o build-wrapper-linux-x86.zip -d .sonar" | |||
} | |||
stage('Build') { | |||
sh ".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>" | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output" | |||
} | |||
} | |||
}`, | |||
[OSs.MacOS]: baseUrl => `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
sh ''' | |||
mkdir -p .sonar | |||
curl -sSLo build-wrapper-macosx-x86.zip ${baseUrl}/static/cpp/build-wrapper-macosx-x86.zip | |||
unzip -o build-wrapper-macosx-x86.zip -d .sonar | |||
''' | |||
} | |||
stage('Build') { | |||
sh ''' | |||
.sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command> | |||
''' | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output" | |||
} | |||
} | |||
}`, | |||
[OSs.Windows]: baseUrl => `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
powershell ''' | |||
$path = "$HOME/.sonar/build-wrapper-win-x86.zip" | |||
rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue | |||
rm $path -Force -ErrorAction SilentlyContinue | |||
mkdir $HOME/.sonar | |||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |||
(New-Object System.Net.WebClient).DownloadFile(${baseUrl}/static/cpp/build-wrapper-win-x86.zip", $path) | |||
Add-Type -AssemblyName System.IO.Compression.FileSystem | |||
[System.IO.Compression.ZipFile]::ExtractToDirectory($path, "$HOME/.sonar") | |||
''' | |||
} | |||
stage('Build') { | |||
powershell ''' | |||
$env:Path += ";$HOME/.sonar/build-wrapper-win-x86" | |||
build-wrapper-win-x86-64 --out-dir bw-output <your clean build command> | |||
''' | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
powershell "\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output" | |||
} | |||
} | |||
}` | |||
}; | |||
export default function CFamilly({ baseUrl, component }: CFamillyProps) { | |||
const [os, setOs] = React.useState<OSs>(); | |||
return ( | |||
<> | |||
<DefaultProjectKey component={component} /> | |||
<li> | |||
{translate('onboarding.build.other.os')} | |||
<RenderOptions | |||
checked={os} | |||
name="flavorComponent" | |||
optionLabelKey="onboarding.build.other.os" | |||
onCheck={value => setOs(value as OSs)} | |||
options={Object.values(OSs)} | |||
/> | |||
</li> | |||
{os && ( | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet={YAML_MAP[os](baseUrl)}> | |||
<CompilationInfo /> | |||
</CreateJenkinsfileBulletPoint> | |||
)} | |||
</> | |||
); | |||
} |
@@ -25,12 +25,14 @@ import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import SentenceWithHighlights from '../../components/SentenceWithHighlights'; | |||
export interface CreateJenkinsfileBulletPointProps { | |||
snippet: string; | |||
alertTranslationKeyPart?: string; | |||
children?: React.ReactNode; | |||
otherAlert?: JSX.Element; | |||
snippet: string; | |||
} | |||
export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBulletPointProps) { | |||
const { snippet, alertTranslationKeyPart } = props; | |||
const { children, snippet, alertTranslationKeyPart, otherAlert } = props; | |||
return ( | |||
<li className="abs-width-600"> | |||
@@ -38,9 +40,9 @@ export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBul | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
{alertTranslationKeyPart !== undefined && ( | |||
{alertTranslationKeyPart && ( | |||
<Alert className="spacer-top" variant="info"> | |||
<p className="text-middle"> | |||
<div className="text-middle"> | |||
<SentenceWithHighlights | |||
highlightKeys={['default', 'in_jenkins']} | |||
translationKey={`${alertTranslationKeyPart}.replace`} | |||
@@ -64,10 +66,12 @@ export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBul | |||
</> | |||
} | |||
/> | |||
</p> | |||
{otherAlert} | |||
</div> | |||
</Alert> | |||
)} | |||
<CodeSnippet snippet={snippet} /> | |||
{children} | |||
</li> | |||
); | |||
} |
@@ -21,13 +21,10 @@ import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import RenderOptions from '../../components/RenderOptions'; | |||
import { OSs } from '../../types'; | |||
import { LanguageProps } from '../JenkinsfileStep'; | |||
import DotNetCore from './DotNetCore'; | |||
import DotNetFramework from './DotNetFramework'; | |||
export interface DotNetProps { | |||
component: T.Component; | |||
} | |||
export interface DotNetCoreFrameworkProps { | |||
component: T.Component; | |||
os: OSDotNet; | |||
@@ -42,7 +39,7 @@ const DotOS: { [key in keyof typeof DotNetFlavor]: OSDotNet } = { | |||
linux_core: OSs.Linux | |||
}; | |||
export default function DotNet({ component }: DotNetProps) { | |||
export default function DotNet({ component }: LanguageProps) { | |||
const [flavorComponent, setFlavorComponet] = React.useState<keyof typeof DotNetFlavor>(); | |||
const DotNetTutorial = flavorComponent && DotNetFlavor[flavorComponent]; | |||
return ( |
@@ -21,12 +21,9 @@ import * as React from 'react'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import { buildGradleSnippet } from '../../utils'; | |||
import { LanguageProps } from '../JenkinsfileStep'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface GradleProps { | |||
component: T.Component; | |||
} | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
@@ -38,7 +35,7 @@ const JENKINSFILE_SNIPPET = `node { | |||
} | |||
}`; | |||
export default function Gradle({ component }: GradleProps) { | |||
export default function Gradle({ component }: LanguageProps) { | |||
return ( | |||
<> | |||
<li className="abs-width-600"> |
@@ -21,12 +21,9 @@ import * as React from 'react'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import { mavenPomSnippet } from '../../utils'; | |||
import { LanguageProps } from '../JenkinsfileStep'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface MavenProps { | |||
component: T.Component; | |||
} | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
@@ -39,7 +36,7 @@ const JENKINSFILE_SNIPPET = `node { | |||
} | |||
}`; | |||
export default function Maven({ component }: MavenProps) { | |||
export default function Maven({ component }: LanguageProps) { | |||
return ( | |||
<> | |||
<li className="abs-width-600"> |
@@ -19,12 +19,9 @@ | |||
*/ | |||
import * as React from 'react'; | |||
import DefaultProjectKey from '../../components/DefaultProjectKey'; | |||
import { LanguageProps } from '../JenkinsfileStep'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface OtherProps { | |||
component: T.Component; | |||
} | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
@@ -37,7 +34,7 @@ const JENKINSFILE_SNIPPET = `node { | |||
} | |||
}`; | |||
export default function Other({ component }: OtherProps) { | |||
export default function Other({ component }: LanguageProps) { | |||
return ( | |||
<> | |||
<DefaultProjectKey component={component} /> |
@@ -0,0 +1,41 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 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. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import RenderOptions from '../../../components/RenderOptions'; | |||
import { OSs } from '../../../types'; | |||
import CFamilly, { CFamillyProps } from '../CFamilly'; | |||
it('should render correctly for', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
it.each([[OSs.Linux], [OSs.MacOS], [OSs.Windows]])('should render correctly for %s', os => { | |||
const wrapper = shallowRender(); | |||
wrapper.find(RenderOptions).simulate('check', os); | |||
expect(wrapper).toMatchSnapshot(os); | |||
}); | |||
function shallowRender(props: Partial<CFamillyProps> = {}) { | |||
return shallow<CFamillyProps>( | |||
<CFamilly component={mockComponent()} baseUrl="nice_url_sample" {...props} /> | |||
); | |||
} |
@@ -20,12 +20,13 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import DotNet, { DotNetProps } from '../DotNet'; | |||
import { LanguageProps } from '../../JenkinsfileStep'; | |||
import DotNet from '../DotNet'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<DotNetProps> = {}) { | |||
return shallow<DotNetProps>(<DotNet component={mockComponent()} {...props} />); | |||
function shallowRender(props: Partial<LanguageProps> = {}) { | |||
return shallow<LanguageProps>(<DotNet component={mockComponent()} baseUrl="" {...props} />); | |||
} |
@@ -20,12 +20,13 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Gradle, { GradleProps } from '../Gradle'; | |||
import { LanguageProps } from '../../JenkinsfileStep'; | |||
import Gradle from '../Gradle'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<GradleProps> = {}) { | |||
return shallow<GradleProps>(<Gradle component={mockComponent()} {...props} />); | |||
function shallowRender(props: Partial<LanguageProps> = {}) { | |||
return shallow<LanguageProps>(<Gradle component={mockComponent()} baseUrl="" {...props} />); | |||
} |
@@ -20,12 +20,13 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Maven, { MavenProps } from '../Maven'; | |||
import { LanguageProps } from '../../JenkinsfileStep'; | |||
import Maven from '../Maven'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<MavenProps> = {}) { | |||
return shallow<MavenProps>(<Maven component={mockComponent()} {...props} />); | |||
function shallowRender(props: Partial<LanguageProps> = {}) { | |||
return shallow<LanguageProps>(<Maven component={mockComponent()} baseUrl="" {...props} />); | |||
} |
@@ -20,12 +20,13 @@ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Other, { OtherProps } from '../Other'; | |||
import { LanguageProps } from '../../JenkinsfileStep'; | |||
import Other from '../Other'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<OtherProps> = {}) { | |||
return shallow<OtherProps>(<Other component={mockComponent()} {...props} />); | |||
function shallowRender(props: Partial<LanguageProps> = {}) { | |||
return shallow<LanguageProps>(<Other component={mockComponent()} baseUrl="" {...props} />); | |||
} |
@@ -0,0 +1,266 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly for 1`] = ` | |||
<Fragment> | |||
<DefaultProjectKey | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
<li> | |||
onboarding.build.other.os | |||
<RenderOptions | |||
name="flavorComponent" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build.other.os" | |||
options={ | |||
Array [ | |||
"linux", | |||
"win", | |||
"mac", | |||
] | |||
} | |||
/> | |||
</li> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly for linux: linux 1`] = ` | |||
<Fragment> | |||
<DefaultProjectKey | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
<li> | |||
onboarding.build.other.os | |||
<RenderOptions | |||
checked="linux" | |||
name="flavorComponent" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build.other.os" | |||
options={ | |||
Array [ | |||
"linux", | |||
"win", | |||
"mac", | |||
] | |||
} | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
sh \\"mkdir -p .sonar\\" | |||
sh \\"curl -sSLo build-wrapper-linux-x86.zip nice_url_sample/static/cpp/build-wrapper-linux-x86.zip\\" | |||
sh \\"unzip -o build-wrapper-linux-x86.zip -d .sonar\\" | |||
} | |||
stage('Build') { | |||
sh \\".sonar/build-wrapper-linux-x86/build-wrapper-linux-x86-64 --out-dir bw-output <your clean build command>\\" | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh \\"\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output\\" | |||
} | |||
} | |||
}" | |||
> | |||
<CompilationInfo /> | |||
</CreateJenkinsfileBulletPoint> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly for mac: mac 1`] = ` | |||
<Fragment> | |||
<DefaultProjectKey | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
<li> | |||
onboarding.build.other.os | |||
<RenderOptions | |||
checked="mac" | |||
name="flavorComponent" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build.other.os" | |||
options={ | |||
Array [ | |||
"linux", | |||
"win", | |||
"mac", | |||
] | |||
} | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
sh ''' | |||
mkdir -p .sonar | |||
curl -sSLo build-wrapper-macosx-x86.zip nice_url_sample/static/cpp/build-wrapper-macosx-x86.zip | |||
unzip -o build-wrapper-macosx-x86.zip -d .sonar | |||
''' | |||
} | |||
stage('Build') { | |||
sh ''' | |||
.sonar/build-wrapper-macosx-x86/build-wrapper-macosx-x86 --out-dir bw-output <your clean build command> | |||
''' | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh \\"\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output\\" | |||
} | |||
} | |||
}" | |||
> | |||
<CompilationInfo /> | |||
</CreateJenkinsfileBulletPoint> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly for win: win 1`] = ` | |||
<Fragment> | |||
<DefaultProjectKey | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
<li> | |||
onboarding.build.other.os | |||
<RenderOptions | |||
checked="win" | |||
name="flavorComponent" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build.other.os" | |||
options={ | |||
Array [ | |||
"linux", | |||
"win", | |||
"mac", | |||
] | |||
} | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('Download Build Wrapper') { | |||
powershell ''' | |||
$path = \\"$HOME/.sonar/build-wrapper-win-x86.zip\\" | |||
rm build-wrapper-win-x86 -Recurse -Force -ErrorAction SilentlyContinue | |||
rm $path -Force -ErrorAction SilentlyContinue | |||
mkdir $HOME/.sonar | |||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |||
(New-Object System.Net.WebClient).DownloadFile(nice_url_sample/static/cpp/build-wrapper-win-x86.zip\\", $path) | |||
Add-Type -AssemblyName System.IO.Compression.FileSystem | |||
[System.IO.Compression.ZipFile]::ExtractToDirectory($path, \\"$HOME/.sonar\\") | |||
''' | |||
} | |||
stage('Build') { | |||
powershell ''' | |||
$env:Path += \\";$HOME/.sonar/build-wrapper-win-x86\\" | |||
build-wrapper-win-x86-64 --out-dir bw-output <your clean build command> | |||
''' | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
powershell \\"\${scannerHome}/bin/sonar-scanner -Dsonar.cfamily.build-wrapper-output=bw-output\\" | |||
} | |||
} | |||
}" | |||
> | |||
<CompilationInfo /> | |||
</CreateJenkinsfileBulletPoint> | |||
</Fragment> | |||
`; |
@@ -26,7 +26,7 @@ exports[`should render correctly: with alert 1`] = ` | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
<p | |||
<div | |||
className="text-middle" | |||
> | |||
<SentenceWithHighlights | |||
@@ -68,7 +68,7 @@ exports[`should render correctly: with alert 1`] = ` | |||
</React.Fragment> | |||
} | |||
/> | |||
</p> | |||
</div> | |||
</Alert> | |||
<CodeSnippet | |||
snippet="foo { bar() }" |
@@ -18,15 +18,14 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { connect } from 'react-redux'; | |||
import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getLanguages, Store } from '../../../store/rootReducer'; | |||
import { withCLanguageFeature } from '../../hoc/withCLanguageFeature'; | |||
import RenderOptions from '../components/RenderOptions'; | |||
import { BuildTools, ManualTutorialConfig, OSs } from '../types'; | |||
interface Props { | |||
languages: T.Languages; | |||
hasCLanguageFeature: boolean; | |||
config?: ManualTutorialConfig; | |||
onDone: (config: ManualTutorialConfig) => void; | |||
} | |||
@@ -60,9 +59,9 @@ export class BuildToolForm extends React.PureComponent<Props, State> { | |||
render() { | |||
const { config } = this.state; | |||
const { languages } = this.props; | |||
const { hasCLanguageFeature } = this.props; | |||
const buildTools = [BuildTools.Maven, BuildTools.Gradle, BuildTools.DotNet]; | |||
if (languages['c']) { | |||
if (hasCLanguageFeature) { | |||
buildTools.push(BuildTools.CFamily); | |||
} | |||
buildTools.push(BuildTools.Other); | |||
@@ -97,8 +96,4 @@ export class BuildToolForm extends React.PureComponent<Props, State> { | |||
} | |||
} | |||
const mapStateToProps = (state: Store) => ({ | |||
languages: getLanguages(state) | |||
}); | |||
export default connect(mapStateToProps)(BuildToolForm); | |||
export default withCLanguageFeature(BuildToolForm); |
@@ -24,7 +24,7 @@ import { BuildToolForm } from '../BuildToolForm'; | |||
it('renders correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ languages: {} })).toMatchSnapshot('without C'); | |||
expect(shallowRender({ hasCLanguageFeature: false })).toMatchSnapshot('without C'); | |||
expect(shallowRender().setState({ config: { buildTool: BuildTools.Maven } })).toMatchSnapshot( | |||
'with "maven" selected' | |||
); | |||
@@ -49,6 +49,6 @@ it('correctly calls the onDone prop', () => { | |||
function shallowRender(props: Partial<BuildToolForm['props']> = {}) { | |||
return shallow<BuildToolForm>( | |||
<BuildToolForm onDone={jest.fn()} languages={{ c: { key: 'c', name: 'test' } }} {...props} /> | |||
<BuildToolForm onDone={jest.fn()} hasCLanguageFeature={true} {...props} /> | |||
); | |||
} |
@@ -3770,6 +3770,7 @@ onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help1.sentence.path=Man | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence=The name is located under the {path} section, in the {name} field. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence.path=SonarQube Scanner > SonarQube Scanner installations | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence.name=Name | |||
onboarding.tutorial.with.jenkins.jenkinsfile.cfamilly.agent_setup=We assume the Jenkins agent has the necessary tools to build your project. | |||
onboarding.tutorial.with.azure_pipelines.os=What is your agent host? |