Skip to content

Commit

Permalink
feat(tasks): adds lift command
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Feb 18, 2021
1 parent cccfe73 commit b1cef1f
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/tasks/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './lift';
export * from './list';
132 changes: 132 additions & 0 deletions src/tasks/commands/lift.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { Task, Context } from '../../definitions';
import { getAbsolutePath } from '../../helpers/paths';
import { isCancelled } from '../../utils';
import { select } from '../transform/select';
import { write } from '../create/write';
import { print } from '../create/print';
import { parse } from '../consume/parse';
import { run } from '../consume/run';
import { Members } from 'type-core';
import { into } from 'pipettes';
import chalk from 'chalk';
import fs from 'fs-extra';

export interface LiftOptions {
purge?: boolean;
mode?: 'default' | 'confirm' | 'dry' | 'audit';
}

export function lift(tasks: Task.Record, options?: LiftOptions): Task.Async {
return async (ctx: Context): Promise<void> => {
const opts = Object.assign({ purge: false, mode: 'default' }, options);

const pkgPath = getAbsolutePath('package.json', ctx);
const pkgExists = await fs.pathExists(pkgPath);
if (!pkgExists) {
throw Error(`Couldn't retrieve package.json on path: ${ctx.cwd}`);
}
const content = await fs.readFile(pkgPath);
const pkg = JSON.parse(content.toString());

const pkgScripts: Members<string> = pkg.scripts || {};
const taskScripts = Object.keys(parse(tasks)).reduce(
(acc: Members<string>, name) => ({ ...acc, [name]: `kpo ${name} --` }),
{}
);

pkg.scripts = opts.purge ? taskScripts : { ...pkg.scripts, ...taskScripts };

const isDefault = !['confirm', 'dry', 'audit'].includes(opts.mode);

if (isDefault) {
return run(write(pkgPath, pkg, { exists: 'overwrite' }), ctx);
}

if (await isCancelled(ctx)) return;
printChanges(pkgScripts, taskScripts, ctx, {
purge: opts.purge,
audit: opts.mode === 'audit'
});

if (opts.mode === 'confirm') {
return run(
select(
{ message: 'Continue?', default: 'y' },
{
y: write(pkgPath, pkg, { exists: 'overwrite' }),
n: null
}
),
ctx
);
}
};
}

function printChanges(
pkgScripts: Members<string>,
taskScripts: Members<string>,
context: Context,
options: { purge: boolean; audit: boolean }
): void {
const pkgScriptNames = Object.keys(pkgScripts);
const taskScriptNames = Object.keys(taskScripts);

const addScriptNames: string[] = [];
const keepScriptNames: string[] = [];
const replaceScriptNames: string[] = [];
const removeScriptNames: string[] = [];

for (const name of pkgScriptNames) {
if (!taskScriptNames.includes(name)) {
options.purge ? removeScriptNames.push(name) : keepScriptNames.push(name);
} else {
const pkgValue = pkgScripts[name];
const taskValue = taskScripts[name];
pkgValue === taskValue
? keepScriptNames.push(name)
: replaceScriptNames.push(name);
}
}
for (const name of taskScriptNames) {
if (!pkgScriptNames.includes(name)) {
addScriptNames.push(name);
}
}

const strArr: string[] = [];
const areChangesPending = Boolean(
addScriptNames.length ||
replaceScriptNames.length ||
removeScriptNames.length
);

if (areChangesPending) {
if (addScriptNames.length) {
strArr.push(
chalk.bold.green('Scripts to add'),
addScriptNames.join(', ') + '\n'
);
}
if (replaceScriptNames.length) {
strArr.push(
chalk.bold.yellow('Scripts to replace'),
replaceScriptNames.join(', ') + '\n'
);
}
if (removeScriptNames.length) {
strArr.push(
chalk.bold.red('Scripts to remove'),
removeScriptNames.join(', ') + '\n'
);
}
} else {
strArr.push(chalk.bold('No pending scripts changes'));
}

into(context, print(strArr.join('\n')));

if (options.audit && areChangesPending) {
throw Error(`There are pending scripts changes`);
}
}

0 comments on commit b1cef1f

Please sign in to comment.