/* * Copyright (C) 2018 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. * * 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 General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ import {Api} from '@openstapps/gitlab-api'; import {Project} from '@openstapps/gitlab-api/lib/types'; import {Logger} from '@openstapps/logger'; import {asyncPool} from 'async-pool-native/dist/async-pool'; import {readFile, unlink, writeFile} from 'fs'; import * as glob from 'glob'; import {promisify} from 'util'; import {PACK_IDENTIFIER} from './configuration'; /** * Instantiated logger */ export const logger = new Logger(); /** * Get projects for a list of groups * * @param api GitLab API to make requests with * @param groups List of groups */ export async function getProjects(api: Api, groups: number[]): Promise { logger.info('Fetching all projects for specified groups (' + groups.length + ')...'); const projectResults = await asyncPool(3, groups, (groupId) => { return api.getProjectsForGroup(groupId); }); const projects = flatten2dArray(projectResults); logger.log('Fetched ' + projects.length + ' project(s).'); return projects; } /** * Flatten 2d array * * @param arr Flattened array */ export function flatten2dArray(arr: T[][]): T[] { // TODO: fix this return [].concat.apply([], arr as any); } /** * Promisified version of readFile */ export const readFilePromisified = promisify(readFile); /** * Promisified version of glob */ export const globPromisified = promisify(glob); /** * Promisified version of writeFile */ export const writeFilePromisified = promisify(writeFile); /** * Promisified version of unlink */ export const unlinkPromisified = promisify(unlink); /** * Delete file if it exists and is packed by this script * * @param path Path to file to check/delete */ export async function deleteFileIfExistingAndPacked(path: string): Promise { try { const buffer = await readFilePromisified(path); const content = buffer.toString(); // check if packed by this script if (content.indexOf(PACK_IDENTIFIER) === 0) { logger.log('Found `' + path + '` which is packed by this script. Deleting it...'); return await unlinkPromisified(path); } } catch (err) { if (err.code === 'ENOENT') { return; } } } /** * Get all internal dependencies from the content of a module * * @param moduleContent Module content to analyze */ export function getAllInternalDependecies(moduleContent: string): string[] { // match all const = require(); const requireLines = moduleContent.match(/^\s*(const|var) [a-z0-9_]* = require\("([^"]+)"\)|require\('([^']+)'\);$/gmi); if (Array.isArray(requireLines)) { return requireLines.map((requireLine) => { const matches = requireLine.match(/require\("([^"]+)"\)|require\('([^']+)'\);$/i); // previously matched require line does not contain a require?! if (matches === null) { throw new Error(); } // return only the moduleName return matches[1]; }).filter((moduleName) => { // filter out internal modules beginning with './' and not ending with '.json' return /^[.]{1,2}\/(?!.*\.json$).*$/i.test(moduleName); }).map((internalModuleName) => { // cut './' from the name return internalModuleName.substring(2); }); } return []; }