Skip to content

Commit

Permalink
feat(batch): batch feature skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
tomastrajan committed Mar 19, 2023
1 parent 1d1aa91 commit 237fa06
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 45 deletions.
38 changes: 38 additions & 0 deletions lib/batch/batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Argv } from 'yargs';

import { runner } from '../utils/process';
import { createLogger } from '../services/logger.service';

import { initWorkspaceTask } from './tasks/init-workspace.task';
import { initJobTask } from './tasks/init-job.task';
import { runJobsTask } from './tasks/run-jobs.task';
import { retrieveSettingsTask } from '../tasks/retrieve-settings.task';

const logger = createLogger('BATCH');

export const command = 'batch';

export const aliases = ['b'];

export const describe =
'Check out and analyze multiple project repositories and upload results to Omniboard.dev';

export const builder = (yargs: Argv) =>
yargs
.option('job-path', {
type: 'string',
default: './omniboard-job.json',
description: 'Location of Omniboard batch job file',
})
.option('workspace-path', {
type: 'string',
default: './omniboard-workspace',
description: 'Location where the Omniboard batch workspace is stored',
});

export const handler = async (argv: any) =>
runner(
[retrieveSettingsTask, initJobTask, initWorkspaceTask, runJobsTask],
argv,
logger
);
27 changes: 27 additions & 0 deletions lib/batch/tasks/init-job-repo.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ListrTask } from 'listr2';

import { Context } from '../../interface';
import {
getRepoNameFromUrl,
cloneRepo,
pullLatest,
} from '../../services/git.service';
import { directoryExists, pathJoin } from '../../services/fs.service';

export function initJobRepo(job: string): ListrTask {
return {
title: 'Init job repo',
task: async (ctx: Context, task) => {
const { workspacePath, verbose } = ctx.options;
const repoName = getRepoNameFromUrl(job);
const repoPath = pathJoin(workspacePath, repoName);
if (!directoryExists(repoPath)) {
await cloneRepo(job, workspacePath);
task.title = `${task.title}, cloned`;
} else {
await pullLatest(repoPath);
task.title = `${task.title}, updated`;
}
},
};
}
27 changes: 27 additions & 0 deletions lib/batch/tasks/init-job.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ListrTask } from 'listr2';

import { BatchJob, Context } from '../../interface';
import { readJson, writeJson } from '../../services/fs.service';

const DEFAULT_JOB: BatchJob = {
running: '',
queue: [],
completed: [],
failed: [],
};

export const initJobTask: ListrTask = {
title: 'Init job',
task: async (ctx: Context, task) => {
const { jobPath } = ctx.options;
let job = readJson(jobPath);
if (!job) {
job = DEFAULT_JOB;
writeJson(jobPath, job);
task.title = `${task.title} - created new job file at ${jobPath}`;
} else {
task.title = `${task.title} successful, found ${job.queue?.length} jobs`;
}
ctx.batchJob = job;
},
};
13 changes: 13 additions & 0 deletions lib/batch/tasks/init-workspace.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ListrTask } from 'listr2';

import { Context } from '../../interface';
import { ensureDirectoryExists } from '../../services/fs.service';

export const initWorkspaceTask: ListrTask = {
title: 'Init workspace',
task: async (ctx: Context, task) => {
const { workspacePath } = ctx.options;
ensureDirectoryExists(workspacePath);
task.title = `${task.title} successful, workspace initialized ${workspacePath}`;
},
};
14 changes: 14 additions & 0 deletions lib/batch/tasks/run-job.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ListrTask } from 'listr2';

import { Context } from '../../interface';

import { initJobRepo } from './init-job-repo.task';

export function runJobTaskFactory(job: string): ListrTask {
return {
title: `${job}`,
task: async (ctx: Context, task) => {
return task.newListr([initJobRepo(job)]);
},
};
}
13 changes: 13 additions & 0 deletions lib/batch/tasks/run-jobs.task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ListrTask } from 'listr2';

import { Context } from '../../interface';

import { runJobTaskFactory } from './run-job.task';

export const runJobsTask: ListrTask = {
title: 'Run jobs',
task: async (ctx: Context, task) =>
task.newListr(
ctx.batchJob.queue.map((queuedJob) => runJobTaskFactory(queuedJob))
),
};
2 changes: 2 additions & 0 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import yargs, { Argv } from 'yargs';
import * as analyzeCommand from './commands/analyze';
import * as testCheckCommand from './commands/test-check';
import * as testConnectionCommand from './commands/test-connection';
import * as batchCommand from './batch/batch';
import { apiMiddleware } from './middlewares/api.middleware';
import { loggerMiddleware } from './middlewares/logger.middleware';

Expand All @@ -29,6 +30,7 @@ import { loggerMiddleware } from './middlewares/logger.middleware';
.command(analyzeCommand)
.command(testCheckCommand)
.command(testConnectionCommand)
.command(batchCommand)
.option('verbose', {
type: 'boolean',
default: false,
Expand Down
11 changes: 11 additions & 0 deletions lib/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export interface Options {
apiKey?: string;
silent: boolean;
sanitizeRepoUrl: boolean;
// batch
jobPath: string;
workspacePath: string;
}

export interface Context {
Expand Down Expand Up @@ -36,6 +39,14 @@ export interface Context {
};
handledCheckFailures: Error[];
processedResults?: any;
batchJob: BatchJob;
}

export interface BatchJob {
running: string;
queue: string[];
completed: string[];
failed: string[];
}

export interface CustomProjectResolver {
Expand Down
18 changes: 16 additions & 2 deletions lib/services/fs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ export function readXmlAsDom(

export function writeJson(destinationPath: string, data: any) {
const { base, dir } = path.parse(destinationPath);
const stringifiedData = JSON.stringify(data, null, 2);
const dataAsString = JSON.stringify(data, null, 2);
fs.mkdirSync(dir, { recursive: true });
fs.writeFileSync(destinationPath, stringifiedData);
fs.writeFileSync(destinationPath, dataAsString);
}

export function readFile(path: string) {
Expand All @@ -105,3 +105,17 @@ export function getFileSize(path: string) {
export function getHumanReadableFileSize(size: number) {
return filesize(size);
}

export function ensureDirectoryExists(path: string) {
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true });
}
}

export function directoryExists(path: string) {
return fs.existsSync(path);
}

export function pathJoin(...parts: string[]) {
return path.join(...parts);
}
14 changes: 14 additions & 0 deletions lib/services/git.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { run } from './shell.service';

export function getRepoNameFromUrl(url: string): string {
const parts = url.split('/');
return parts[parts.length - 1].replace(/\.git$/, '');
}

export async function cloneRepo(url: string, targetDir: string) {
return await run(`git clone --depth 1 ${url}`, targetDir);
}

export async function pullLatest(targetDir: string) {
return await run(`git checkout --force && git pull`, targetDir);
}
20 changes: 20 additions & 0 deletions lib/services/shell.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import cp from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(cp.exec);
const MAX_BUFFER_SIZE = 1 * 1024 * 1024;

export async function run(
command: string,
targetDir: string
): Promise<CommandResult> {
return await execAsync(command, {
cwd: targetDir,
maxBuffer: MAX_BUFFER_SIZE,
});
}

export interface CommandResult {
stdout: string;
stderr: string;
}
1 change: 1 addition & 0 deletions lib/utils/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const runner = async (
results: { checks: {} },
definitions: {},
handledCheckFailures: [],
batchJob: { running: '', queue: [], completed: [], failed: [] },
};
await new Listr(tasks, {
rendererFallback: () => options?.verbose,
Expand Down
88 changes: 45 additions & 43 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 237fa06

Please sign in to comment.