Skip to content
Snippets Groups Projects
Commit 75fedb26 authored by michael.minelli's avatar michael.minelli
Browse files

Merge branch 'add-sonar-integration' into v3.6

parents 9e3f29d2 fca59c4d
No related branches found
No related tags found
1 merge request!2Add missing header status code (linked to backend issue #19)
......@@ -8,26 +8,26 @@ import zlib from 'zlib';
class ArchiveHelper {
private async explore(absoluteBasePath: string, rootPath: string, pack: tar.Pack) {
for ( let file of await fs.promises.readdir(rootPath) ) {
if ( file === 'output.tar' ) {
continue;
}
file = path.join(rootPath, file);
const stat = await fs.promises.stat(file);
if ( stat.isDirectory() ) {
await this.explore(absoluteBasePath, file, pack);
continue;
}
const entry = pack.entry({
name: file.replace(absoluteBasePath, ''),
size: stat.size
}, (err) => {
if ( err ) {
throw err;
for ( const file of await fs.promises.readdir(rootPath) ) {
let filename = file;
if ( filename !== 'output.tar' ) {
filename = path.join(rootPath, filename);
const stat = await fs.promises.stat(filename);
if ( stat.isDirectory() ) {
await this.explore(absoluteBasePath, filename, pack);
} else {
const entry = pack.entry({
name: filename.replace(absoluteBasePath, ''),
size: stat.size
}, err => {
if ( err ) {
throw err;
}
});
const readStream = fs.createReadStream(filename);
readStream.pipe(entry);
}
});
const stream = fs.createReadStream(file);
stream.pipe(entry);
}
}
}
......@@ -55,7 +55,7 @@ class ArchiveHelper {
await this.compress(folderPath, tarDataStream);
data = await (new Promise((resolve) => {
data = await (new Promise(resolve => {
tarDataStream.on('close', () => {
resolve(data);
});
......
......@@ -8,15 +8,14 @@ import Json5FileValidator from '../Json5FileValidator';
class SharedAssignmentHelper {
validateDescriptionFile(filePathOrStr: string, isFile: boolean = true, version: number = 1): { content: AssignmentFile | undefined, isValid: boolean, error: string | null } {
switch ( version ) {
case 1:
return Json5FileValidator.validateFile(AssignmentFile, filePathOrStr, isFile);
default:
return {
content: undefined,
isValid: false,
error : `Version ${ version } not supported`
};
if ( version === 1 ) {
return Json5FileValidator.validateFile(AssignmentFile, filePathOrStr, isFile);
} else {
return {
content: undefined,
isValid: false,
error : `Version ${ version } not supported`
};
}
}
......@@ -24,7 +23,7 @@ class SharedAssignmentHelper {
const pipelines = await SharedGitlabManager.getRepositoryPipelines(repositoryId, 'main');
if ( pipelines.length > 0 ) {
const lastPipeline = pipelines[0];
if ( lastPipeline.status != GitlabPipelineStatus.SUCCESS ) {
if ( lastPipeline.status !== GitlabPipelineStatus.SUCCESS ) {
return {
isPublishable: false,
lastPipeline : lastPipeline,
......
class LazyVal<T> {
private val: T | undefined = undefined;
private readonly valLoader: () => Promise<T> | T;
constructor(private valLoader: () => Promise<T> | T) {}
constructor(valLoader: () => Promise<T> | T) {
this.valLoader = valLoader;
}
get value(): Promise<T> {
return new Promise<T>((resolve) => {
return new Promise<T>(resolve => {
if ( this.val === undefined ) {
Promise.resolve(this.valLoader()).then((value: T) => {
this.val = value;
......
......@@ -14,8 +14,9 @@ class Toolbox {
const files = await fs.readdir(dirPath);
await Promise.all(files.map(async file => {
if ( (await fs.stat(dirPath + '/' + file)).isDirectory() ) {
arrayOfFiles = await this.getAllFiles(dirPath + '/' + file, arrayOfFiles);
const filePath = path.join(dirPath, file);
if ( (await fs.stat(filePath)).isDirectory() ) {
arrayOfFiles = await this.getAllFiles(filePath, arrayOfFiles);
} else {
arrayOfFiles.push(path.join(dirPath, file));
}
......
......@@ -64,9 +64,7 @@ function registerStringCapitalizeName() {
function registerStringConvertWithEnvVars() {
String.prototype.convertWithEnvVars = function (this: string): string {
return this.replace(/\${?([a-zA-Z0-9_]+)}?/g, (_match: string, p1: string) => {
return process.env[p1] || '';
});
return this.replace(/\${?([a-zA-Z0-9_]+)}?/g, (_match: string, p1: string) => process.env[p1] || '');
};
}
......
......@@ -51,32 +51,36 @@ class RecursiveFilesStats {
return this.getFiles(`${ path.resolve(rootPath) }/`, rootPath, options, [], callback);
}
private async getFiles(absoluteBasePath: string, rootPath: string, options: RecursiveReaddirFilesOptions = {}, files: IFileDirStat[] = [], callback?: Callback): Promise<IFileDirStat[]> {
const {
ignored, include, exclude, filter
} = options;
private async getFilesDirsStat(rootPath: string, options: RecursiveReaddirFilesOptions): Promise<Array<IFileDirStat>> {
const filesData = await fs.promises.readdir(rootPath);
const fileDir: IFileDirStat[] = filesData.map((file) => ({
name: file, path: path.join(rootPath, file)
})).filter((item) => {
if ( include && include.test(item.path) ) {
return filesData.map(file => ({
name: file,
path: path.join(rootPath, file)
})).filter(item => {
if ( options.include && options.include.test(item.path) ) {
return true;
}
if ( exclude && exclude.test(item.path) ) {
if ( options.exclude && options.exclude.test(item.path) ) {
return false;
}
if ( ignored ) {
return !ignored.test(item.path);
if ( options.ignored ) {
return !options.ignored.test(item.path);
}
return true;
});
}
private async getFiles(absoluteBasePath: string, rootPath: string, options: RecursiveReaddirFilesOptions = {}, files: IFileDirStat[] = [], callback?: Callback): Promise<IFileDirStat[]> {
const fileDir: Array<IFileDirStat> = await this.getFilesDirsStat(rootPath, options);
if ( callback ) {
fileDir.map(async (item: IFileDirStat) => {
const stat = await this.getStat(item.path, absoluteBasePath, options);
if ( stat.isDirectory!() ) {
await this.getFiles(absoluteBasePath, item.path, options, [], callback);
}
callback(item.path, stat);
fileDir.forEach(item => {
this.getStat(item.path, absoluteBasePath, options).then(stat => {
if ( stat.isDirectory!() ) {
this.getFiles(absoluteBasePath, item.path, options, [], callback).then();
}
callback(item.path, stat);
});
});
} else {
await Promise.all(fileDir.map(async (item: IFileDirStat) => {
......@@ -89,9 +93,9 @@ class RecursiveFilesStats {
}
}));
}
return files.filter((item) => {
if ( filter && typeof filter === 'function' ) {
return filter(item);
return files.filter(item => {
if ( options.filter && typeof options.filter === 'function' ) {
return options.filter(item);
}
return true;
});
......@@ -124,10 +128,7 @@ class RecursiveFilesStats {
delete stat.ctimeMs;
delete stat.birthtimeMs;
delete stat.atime;
//delete stat.mtime;
delete stat.ctime;
//delete stat.birthtime;
//delete stat.mode;
}
return stat;
......
......@@ -23,7 +23,11 @@ winston.addColors(colors);
const format = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format(info => ({
...info,
level: info.level.toUpperCase()
}))(), SharedConfig.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.prettyPrint(), winston.format.errors({ stack: true }), winston.format.align(), winston.format.printf((info) => `[${ info.timestamp }] (${ process.pid }) ${ info.level } ${ info.message } ${ info.metadata ? `\n${ JSON.stringify(info.metadata) }` : '' } ${ info.stack ? `\n${ info.stack }` : '' } `));
}))(), SharedConfig.production ? winston.format.uncolorize() : winston.format.colorize({ all: true }), winston.format.prettyPrint(), winston.format.errors({ stack: true }), winston.format.align(), winston.format.printf(info => {
const metadata = info.metadata ? `\n${ JSON.stringify(info.metadata) }` : '';
const stack = info.stack ? `\n${ info.stack }` : '';
return `[${ info.timestamp }] (${ process.pid }) ${ info.level } ${ info.message } ${ metadata } ${ stack } `;
}));
const commonTransportOptions = {
handleRejections: true,
......@@ -54,11 +58,11 @@ if ( SharedConfig.production ) {
}) ]);
}
const logger = winston.createLogger({
levels,
format,
transports,
exitOnError: false
});
const WinstonLogger = winston.createLogger({
levels,
format,
transports,
exitOnError: false
});
export default logger;
export default WinstonLogger;
......@@ -5,7 +5,7 @@ import { z } from 'zod';
const AssignmentFile = z.object({
dojoAssignmentVersion: z.number(),
version : z.number(),
immutable : z.array(ImmutableFileDescriptor.transform(value => value as ImmutableFileDescriptor)),
immutable : z.array(ImmutableFileDescriptor),
result : z.object({
container: z.string(),
volume : z.string().optional()
......
......@@ -11,9 +11,12 @@ enum DojoStatusCode {
ASSIGNMENT_NOT_PUBLISHED = 205,
EXERCISE_CORRECTION_NOT_EXIST = 206,
EXERCISE_CORRECTION_ALREADY_EXIST = 207,
ASSIGNMENT_NAME_CONFLICT = 208,
EXERCISE_CREATION_GITLAB_ERROR = 302,
EXERCISE_CREATION_INTERNAL_ERROR = 303,
MAX_EXERCISE_PER_ASSIGNMENT_REACHED = 304
MAX_EXERCISE_PER_ASSIGNMENT_REACHED = 304,
GITLAB_TEMPLATE_NOT_FOUND = 401,
GITLAB_TEMPLATE_ACCESS_UNAUTHORIZED = 402,
}
......
const projectIdRoute = '/projects/{{id}}';
enum GitlabRoute {
NOTIFICATION_SETTINGS = '/notification_settings',
PROFILE_GET = '/user',
USERS_GET = '/users',
REPOSITORY_GET = '/projects/{{id}}',
REPOSITORY_CREATE = '/projects', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
REPOSITORY_DELETE = '/projects/{{id}}', // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
REPOSITORY_EDIT = '/projects/{{id}}',
REPOSITORY_DELETE = projectIdRoute, // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values
REPOSITORY_EDIT = projectIdRoute,
REPOSITORY_FORK = '/projects/{{id}}/fork',
REPOSITORY_MEMBER_ADD = '/projects/{{id}}/members',
REPOSITORY_MEMBERS_GET = '/projects/{{id}}/members/all',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment