Select Git revision
GitlabManager.ts
Forked from
Dojo Project (HES-SO) / Projects / UI / DojoCLI
Source project has a limited visibility.
GitlabManager.ts 7.74 KiB
import ora from 'ora';
import fs from 'fs-extra';
import { spawn } from 'child_process';
import { NotificationSettingSchema, UserSchema } from '@gitbeaker/rest';
import * as GitlabCore from '@gitbeaker/core';
import SharedGitlabManager from '../shared/managers/SharedGitlabManager';
import GlobalHelper from '../helpers/GlobalHelper';
type getGitlabUser = (param: number | string) => Promise<UserSchema | undefined>
class GitlabManager extends SharedGitlabManager {
constructor() {
super('', GlobalHelper.refreshGitlabTokenFunction.bind(GlobalHelper));
}
public async testToken(verbose: boolean = true): Promise<[ boolean, boolean ]> {
if ( verbose ) {
ora('Checking Gitlab token: ').start().info();
}
const result: [ boolean, boolean ] = [ false, false ];
type NotificationSettings = { level: string }
let notificationSettings: NotificationSettings = { level: 'error' };
// Test read access
{
const spinnerRead: ora.Ora = ora({
text : `Read access`,
indent: 4
});
if ( verbose ) {
spinnerRead.start();
}
try {
notificationSettings = await this.getNotificationSettings();
result[0] = true;
if ( verbose ) {
spinnerRead.succeed();
}
} catch ( e ) {
if ( verbose ) {
spinnerRead.fail();
}
}
}
// Test write access
{
const spinnerWrite: ora.Ora = ora({
text : `Write access`,
indent: 4
});
if ( verbose ) {
spinnerWrite.start();
}
const someLevelTypes = [ 'disabled', 'participating' ];
try {
const oldSettings = notificationSettings;
const newSettings = { level: someLevelTypes[someLevelTypes[0] === oldSettings.level ? 1 : 0] };
await this.setNotificationSettings(newSettings);
await this.setNotificationSettings(oldSettings);
result[1] = true;
if ( verbose ) {
spinnerWrite.succeed();
}
} catch ( e ) {
if ( verbose ) {
spinnerWrite.fail();
}
}
}
return result;
}
public getNotificationSettings(): Promise<NotificationSettingSchema> {
return this.executeGitlabRequest(() => this.api.NotificationSettings.show());
}
public setNotificationSettings(newSettings: GitlabCore.EditNotificationSettingsOptions) {
return this.executeGitlabRequest(() => this.api.NotificationSettings.edit(newSettings));
}
private async getGitlabUsers(paramsToSearch: Array<string | number>, searchFunction: getGitlabUser, verbose: boolean = false, verboseIndent: number = 0): Promise<Array<UserSchema | undefined>> {
try {
return await Promise.all(paramsToSearch.map(async param => {
const spinner: ora.Ora = ora({
text : `Getting user ${ param }`,
indent: verboseIndent
});
if ( verbose ) {
spinner.start();
}
const user = await searchFunction(param);
if ( user ) {
if ( verbose ) {
spinner.succeed(`${ user.username } (${ user.id })`);
}
return user;
} else {
if ( verbose ) {
spinner.fail(`${ param }`);
}
return undefined;
}
}));
} catch ( e ) {
return [ undefined ];
}
}
public async getUsersById(ids: Array<number>, verbose: boolean = false, verboseIndent: number = 0): Promise<Array<UserSchema | undefined>> {
return this.getGitlabUsers(ids, this.getUserById.bind(this) as getGitlabUser, verbose, verboseIndent);
}
public async getUsersByUsername(usernames: Array<string>, verbose: boolean = false, verboseIndent: number = 0): Promise<Array<UserSchema | undefined>> {
return this.getGitlabUsers(usernames, this.getUserByUsername.bind(this) as getGitlabUser, verbose, verboseIndent);
}
public async fetchMembers(options: { members_id?: Array<number>, members_username?: Array<string> }): Promise<Array<UserSchema> | undefined> {
if ( options.members_id || options.members_username ) {
ora('Checking Gitlab members:').start().info();
}
let members: Array<UserSchema> = [];
async function isUsersExists<T>(context: unknown, functionName: string, paramsToSearch: Array<T>): Promise<boolean> {
const users = await ((context as { [functionName: string]: (arg: Array<T>, verbose: boolean, verboseIndent: number) => Promise<Array<UserSchema | undefined>> })[functionName])(paramsToSearch, true, 8);
if ( users.every(user => user) ) {
members = members.concat(users as Array<UserSchema>);
return true;
} else {
return false;
}
}
let result = true;
if ( options.members_id ) {
ora({
text : 'Fetching members by id:',
indent: 4
}).start().info();
result = await isUsersExists(this, 'getUsersById', options.members_id);
}
if ( options.members_username ) {
ora({
text : 'Fetching members by username:',
indent: 4
}).start().info();
result = result && await isUsersExists(this, 'getUsersByUsername', options.members_username);
}
return result ? members.removeObjectDuplicates(gitlabUser => gitlabUser.id) : undefined;
}
public async cloneRepository(clonePath: string | boolean, repositorySshUrl: string, folderName?: string, verbose: boolean = false, verboseIndent: number = 0) {
let path = './';
if ( typeof clonePath === 'string' ) {
path = clonePath;
fs.mkdirSync(path, { recursive: true });
}
let cloningSpinner!: ora.Ora;
if ( verbose ) {
cloningSpinner = ora({
text : 'Cloning the repository...',
indent: verboseIndent
}).start();
}
try {
await new Promise<void>((resolve, reject) => {
const gitClone = spawn(`git clone ${ repositorySshUrl } "${ folderName ?? '' }"`, {
cwd : path,
shell: true
});
gitClone.on('exit', code => {
code !== null && code === 0 ? resolve() : reject();
});
});
if ( verbose ) {
cloningSpinner.succeed('Repository cloned');
}
} catch ( error ) {
if ( verbose ) {
cloningSpinner.fail('Error while cloning the repository');
}
}
}
}
export default new GitlabManager();