Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • ask-user-to-delete-exercises-on-duplicates
  • jw_sonar
  • jw_sonar_backup
  • main
  • move-to-esm-only
  • open_tool_for_self_hosting
  • v5.0
  • v6.0
  • v4.1
  • v4.2
10 results

Target

Select target project
  • dojo_project/projects/shared/nodeclientsharedcode
1 result
Select Git revision
  • ask-user-to-delete-exercises-on-duplicates
  • jw_sonar
  • jw_sonar_backup
  • main
  • move-to-esm-only
  • open_tool_for_self_hosting
  • v5.0
  • v6.0
  • v4.1
  • v4.2
10 results
Show changes
Commits on Source (3)
...@@ -2,7 +2,7 @@ class ClientsSharedConfig { ...@@ -2,7 +2,7 @@ class ClientsSharedConfig {
public apiURL: string; public apiURL: string;
public assignment: { public assignment: {
filename: string, neededFiles: Array<string> filename: string, neededFiles: Array<string>, name: string, secret: string;
}; };
public gitlab: { public gitlab: {
...@@ -19,13 +19,14 @@ class ClientsSharedConfig { ...@@ -19,13 +19,14 @@ class ClientsSharedConfig {
results: string; results: string;
}; };
constructor() { constructor() {
this.apiURL = process.env.API_URL || ''; this.apiURL = process.env.API_URL || '';
this.assignment = { this.assignment = {
filename : process.env.ASSIGNMENT_FILENAME || '', filename : process.env.ASSIGNMENT_FILENAME || '',
neededFiles: JSON.parse(process.env.EXERCISE_NEEDED_FILES || '[]') neededFiles: JSON.parse(process.env.EXERCISE_NEEDED_FILES || '[]'),
name : process.env.DOJO_ASSIGNMENT_NAME || '',
secret: process.env.DOJO_ASSIGNMENT_SECRET || ''
}; };
this.gitlab = { this.gitlab = {
......
...@@ -13,6 +13,9 @@ import ExerciseDockerCompose from './ExerciseDockerCompose'; ...@@ -13,6 +13,9 @@ import ExerciseDockerCompose from './ExerciseDockerCompose';
import util from 'util'; import util from 'util';
import Assignment, { Language } from '../../models/Assignment'; import Assignment, { Language } from '../../models/Assignment';
import ClientsSharedAssignmentHelper from './ClientsSharedAssignmentHelper'; import ClientsSharedAssignmentHelper from './ClientsSharedAssignmentHelper';
import { spawnSync } from 'node:child_process';
import SharedConfig from '../../../shared/config/SharedConfig';
import Config from '../../../config/Config';
const execAsync = util.promisify(exec); const execAsync = util.promisify(exec);
...@@ -79,7 +82,7 @@ class AssignmentValidator { ...@@ -79,7 +82,7 @@ class AssignmentValidator {
this.finished(false, code); this.finished(false, code);
} }
run(doDown: boolean = false) { run(doDown: boolean = false, runSonar: boolean = false) {
(async () => { (async () => {
let dockerComposeFile: DojoDockerCompose; let dockerComposeFile: DojoDockerCompose;
let assignmentFile: AssignmentFile; let assignmentFile: AssignmentFile;
...@@ -127,17 +130,15 @@ class AssignmentValidator { ...@@ -127,17 +130,15 @@ class AssignmentValidator {
{ {
this.newStep('ASSIGNMENT_CHECKING', 'Please wait while we are checking the assignment...'); this.newStep('ASSIGNMENT_CHECKING', 'Please wait while we are checking the assignment...');
this.newSubStep('ASSIGNMENT_EXISTS', 'Checking if the assignment exists'); const resp = await ClientsSharedAssignmentHelper.getAssignmentByName(Config.assignment.name);
const resp = await ClientsSharedAssignmentHelper.getAssignmentFromPath(this.folderAssignment);
if (resp == undefined) { if (resp == undefined) {
this.emitError(`The assignment doesn't exist. An assignment must be created with "assignment create" before checking it.`, `Assignment doesn't exists`, AssignmentCheckerError.ASSIGNMENT_MISSING); this.emitError(`The assignment doesn't exist. An assignment must be created with "assignment create" before checking it.`, `Assignment doesn't exists`, AssignmentCheckerError.ASSIGNMENT_MISSING);
return; return;
} else { } else {
assignment = resp; assignment = resp;
} }
this.endSubStep('Assignment exists', false);
this.endStep('Assignment exists and is valid', false); this.endStep('Assignment exists', false);
} }
...@@ -274,7 +275,53 @@ class AssignmentValidator { ...@@ -274,7 +275,53 @@ class AssignmentValidator {
/* /*
//////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 6: Run //////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 6: Sonar analysis
- Analyse the project with SonarCube
*/
if (assignment.useSonar && runSonar)
{
this.newStep('ASSIGNMENT_SONAR', 'Please wait while we are running Sonar analysis on the assignment...');
let additionalParams: string[] = [];
this.newSubStep('SONAR_BUILD', 'Build files');
const buildProcess = spawnSync('docker', ['build', '--tag', 'dojo-sonar-scanner', '/sonar']);
if ( buildProcess.status !== 0 ) {
this.emitError(`Build sonar image failed`, 'Sonar analysis failure', AssignmentCheckerError.SONAR_ANALYSIS_FAILED);
console.log(buildProcess.stdout.toString())
console.log(buildProcess.stderr.toString())
return;
}
if ([Language.c, Language.cpp, Language.objc].includes(assignment.language) && assignmentFile.buildLine != undefined) {
const process = spawnSync('docker run -v ./:/usr/src dojo-sonar-scanner /usr/local/bin/build-wrapper-linux-x86-64 --out-dir bw-output ' + assignmentFile.buildLine, [], { shell: true })
if ( process.status !== 0 ) {
this.emitError(`Failed to build files using buildLine`, 'Sonar analysis failure', AssignmentCheckerError.SONAR_ANALYSIS_FAILED);
console.log(process.stdout.toString())
console.log(process.stderr.toString())
return;
}
additionalParams = ['-Dsonar.cfamily.build-wrapper-output=/usr/src/bw-output'];
}
this.endSubStep('Sonar files build success', false);
this.newSubStep('SONAR_RUN', 'Run sonar analysis');
const process = spawnSync('docker', ['run', '-v', './:/usr/src', 'dojo-sonar-scanner' , 'sonar-scanner', '-Dsonar.qualitygate.wait=true', '-Dsonar.projectKey=' + assignment.sonarKey, '-Dsonar.sources=.', '-Dsonar.host.url=' + SharedConfig.sonar.url, '-Dsonar.login=' + SharedConfig.sonar.token, ...additionalParams])
if ( process.status !== 0 ) {
this.emitError(`Sonar gate failed`, 'Sonar analysis failure', AssignmentCheckerError.SONAR_ANALYSIS_FAILED);
return;
}
this.endSubStep('Sonar gate passed', false);
this.endStep('Sonar analysis success', false);
}
/*
//////////////////////////////////////////////////////////////////////////////////////////////////////////// Step 7: Run
- Make a run of the assignment (If the return code is 0, the assignment is not valid because it means that there no need of modification for succeed the exercise) - Make a run of the assignment (If the return code is 0, the assignment is not valid because it means that there no need of modification for succeed the exercise)
*/ */
{ {
......
...@@ -29,10 +29,11 @@ class ClientsSharedAssignmentHelper { ...@@ -29,10 +29,11 @@ class ClientsSharedAssignmentHelper {
})); }));
} }
private async getAssignment(url: string): Promise<Assignment | undefined> { private async getAssignment(nameOrUrl: string): Promise<Assignment | undefined> {
try { try {
return (await axios.get<DojoBackendResponse<Assignment>>(`${ ClientsSharedConfig.apiURL }${ ApiRoute.ASSIGNMENT_GET }`.replace('{{nameOrUrl}}', encodeURIComponent(url)))).data.data; return (await axios.get<DojoBackendResponse<Assignment>>(`${ ClientsSharedConfig.apiURL }${ ApiRoute.ASSIGNMENT_GET }`.replace('{{nameOrUrl}}', encodeURIComponent(nameOrUrl)))).data.data;
} catch ( error ) { } catch ( error ) {
console.log(error);
return undefined; return undefined;
} }
} }
...@@ -42,6 +43,10 @@ class ClientsSharedAssignmentHelper { ...@@ -42,6 +43,10 @@ class ClientsSharedAssignmentHelper {
return Array.from(content.matchAll(regexp), m => m[1])[0]; return Array.from(content.matchAll(regexp), m => m[1])[0];
} }
async getAssignmentByName(name: string): Promise<Assignment | undefined> {
return await this.getAssignment(name);
}
async getAssignmentFromPath(path: string): Promise<Assignment | undefined> { async getAssignmentFromPath(path: string): Promise<Assignment | undefined> {
const fullPath = join(path, "./.git/config"); const fullPath = join(path, "./.git/config");
if (!existsSync(fullPath)) { if (!existsSync(fullPath)) {
...@@ -49,7 +54,6 @@ class ClientsSharedAssignmentHelper { ...@@ -49,7 +54,6 @@ class ClientsSharedAssignmentHelper {
} }
const content = readFileSync(fullPath, 'utf-8'); const content = readFileSync(fullPath, 'utf-8');
const url = await this.extractOriginUrl(content); const url = await this.extractOriginUrl(content);
return await this.getAssignment(url); return await this.getAssignment(url);
} }
} }
......