Skip to content

Commit

Permalink
Merge pull request #6 from DRFR0ST/draft/gifted-silence
Browse files Browse the repository at this point in the history
Add init and dev add commands
  • Loading branch information
DRFR0ST authored Sep 25, 2022
2 parents b7d07e2 + 99b82c1 commit c3125a8
Show file tree
Hide file tree
Showing 7 changed files with 495 additions and 29 deletions.
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@drfrost/xum",
"version": "1.0.0-alpha.4",
"version": "1.0.0-alpha.5",
"description": "Extremely Universal Manager - A cli app that unifies all Node package managers.",
"main": "dist/index.js",
"repository": "https://github.com/DRFR0ST/xum",
Expand All @@ -19,10 +19,14 @@
},
"dependencies": {
"commander": "^9.4.0",
"inquirer": "^9.1.2",
"node-emoji": "^1.11.0",
"preferred-pm": "^3.0.3"
},
"devDependencies": {
"@types/inquirer": "^9.0.1",
"@types/node": "^18.7.18",
"@types/node-emoji": "^1.8.2",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"@zoltu/typescript-transformer-append-js-extension": "^1.0.1",
Expand Down
53 changes: 44 additions & 9 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,54 @@
import { PackageManager } from './types';
import { PackageManager, PackageManagerCommand } from './types';

export const SUPPORTED_MANAGERS: PackageManager[] = ['npm', 'yarn', 'pnpm'];

export const PM_LOCK_FILE: Record<PackageManager, string> = {
npm: 'package-lock.json',
yarn: 'yarn.lock',
pnpm: 'pnpm-lock.yaml',
};

export const MAP_ADD_COMMAND: Record<PackageManager, string> = {
npm: 'install',
yarn: 'add',
pnpm: 'install',
export const MAP_ADD_COMMAND: Record<PackageManager, PackageManagerCommand> = {
npm: {
command: 'install',
flags: [],
},
yarn: {
command: 'add',
flags: [],
},
pnpm: {
command: 'install',
flags: [],
},
};

export const MAP_ADD_DEV_COMMAND: Record<PackageManager, PackageManagerCommand> = {
npm: {
command: 'install',
flags: ['--save-dev'],
},
yarn: {
command: 'add',
flags: ['-D'],
},
pnpm: {
command: 'install',
flags: ['--save-dev'],
},
};

export const MAP_REMOVE_COMMAND: Record<PackageManager, string> = {
npm: 'uninstall',
yarn: 'remove',
pnpm: 'uninstall',
export const MAP_REMOVE_COMMAND: Record<PackageManager, PackageManagerCommand> = {
npm: {
command: 'uninstall',
flags: [],
},
yarn: {
command: 'remove',
flags: [],
},
pnpm: {
command: 'uninstall',
flags: [],
},
};
14 changes: 13 additions & 1 deletion src/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Command } from 'commander';
import { MAP_ADD_COMMAND, MAP_REMOVE_COMMAND } from './constants';
import { MAP_ADD_COMMAND, MAP_ADD_DEV_COMMAND, MAP_REMOVE_COMMAND } from './constants';
import { execute, packageManagerInfo } from './utils';

export const initHandler = async (e: unknown, cmd: Command) => {
const forcedManager = cmd?.getOptionValue?.('manager');

execute('init', undefined, forcedManager);
};

export const installHandler = async (e: unknown, cmd: Command) => {
const forcedManager = cmd?.getOptionValue?.('manager');

Expand All @@ -20,6 +26,12 @@ export const addHandler = async (packages: string[], e: unknown, cmd: Command) =
execute(MAP_ADD_COMMAND, packages, forcedManager);
};

export const addDevHandler = async (ee: unknown, packages: string[], e: unknown, cmd: Command) => {
const forcedManager = cmd?.getOptionValue?.('manager');

execute(MAP_ADD_DEV_COMMAND, packages, forcedManager);
};

export const removeHandler = async (packages: string[], e: unknown, cmd: Command) => {
const forcedManager = cmd?.getOptionValue?.('manager');

Expand Down
22 changes: 21 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Command } from 'commander';
import {
addDevHandler,
addHandler,
infoHandler,
initHandler,
installHandler,
removeHandler,
runHandler,
Expand All @@ -12,10 +14,19 @@ const program = new Command('xum');

program
.description('Extremely Universal Manager - A cli app that unifies all Node package managers.')
.version('1.0.0-alpha.4');
.version('1.0.0-alpha.5');

program.command('info').description('Print detected package manager').action(infoHandler);

program
.command('init')
.option(
'-m, --manager <manager>',
'Force using a specified package manager.\nExample: xum install -m pnpm',
)
.description('Create a new package.json file')
.action(initHandler);

program
.command('install')
.option(
Expand Down Expand Up @@ -43,6 +54,15 @@ program
.description('Add dependencies')
.action(addHandler);

program
.command('dev add packages...')
.option(
'-m, --manager <manager>',
'Force using a specified package manager.\nExample: xum install -m pnpm',
)
.description('Add dev dependencies')
.action(addDevHandler);

program
.command('remove packages...')
.option(
Expand Down
5 changes: 5 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export type PackageManager = 'npm' | 'yarn' | 'pnpm';

export type PackageManagerCommand = {
command: string;
flags: string[];
};
80 changes: 65 additions & 15 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { exec, ExecException } from 'node:child_process';
import { ExecException, spawn } from 'node:child_process';
import preferredPM from 'preferred-pm';
import { PackageManager } from './types';
import { PackageManager, PackageManagerCommand } from './types';
import fs from 'fs';
import path from 'node:path';
import { PM_LOCK_FILE } from './constants';
import { PM_LOCK_FILE, SUPPORTED_MANAGERS } from './constants';
import emoji from 'node-emoji';
import inquirer from 'inquirer';

const __dirname = path.dirname('./');

export async function execute(
command: string | Record<PackageManager, string>,
command: string | Record<PackageManager, PackageManagerCommand>,
args: string[] = [],
manager?: PackageManager,
) {
Expand All @@ -17,28 +19,62 @@ export async function execute(
if (!manager) {
pm = (await preferredPM(__dirname)) as typeof pm;

if (!pm) throw new Error('Package manager could not be identified.');
if (!pm) {
await execute(command, args, await promptForPackageManager());
return;
}
} else {
pm = {
name: manager,
version: '-',
};
if (!SUPPORTED_MANAGERS.includes(manager)) {
await execute(command, args, await promptForPackageManager());
return;
} else {
pm = {
name: manager,
version: '-',
};
}
}
let cmd: string = command as string;
let flags: string[] = [];

if (typeof command !== 'string') command = command[pm.name];
if (typeof command !== 'string') {
flags = command[pm.name].flags;
cmd = command[pm.name].command;
}

reportAdditionalManagers(pm.name);
console.log('Executing', `${pm.name} ${command} ${args.join(' ')}`);
return exec(`${pm.name} ${command} ${args.join(' ')}`, execCallback);
console.log(
emoji.emojify(':hourglass: '),
'Executing',
`${pm.name} ${cmd} ${args.join(' ')} ${flags.join(' ')}`,
);

const process = spawn(pm.name, [cmd, ...args, ...flags], { shell: true, stdio: 'inherit' });

process.stdout?.on('data', function (data) {
console.log(emoji.emojify(':information_source: '), data.toString());
});

process.stderr?.on('data', function (data) {
console.log(emoji.emojify(':warning: '), data.toString());
});

process.on('exit', function (code) {
if (code === 0) {
console.log(emoji.emojify(':white_check_mark: Done'));
} else {
console.log(emoji.emojify(':x: '), code?.toString());
}
});
}

export const execCallback = (error: ExecException | null, stdout: string, stderr: string) => {
if (error) {
console.error(`exec error: ${error}`);
console.error(`An error occurred during command execution.`, error);
return;
}
console.log(`${stdout}`);
console.error(`${stderr}`);
console.log(stdout);
console.error(stderr);
};

export const packageManagerInfo = async () => {
Expand All @@ -62,3 +98,17 @@ export const reportAdditionalManagers = (manager: PackageManager) => {
export const fileExists = (path: string) => {
return fs.existsSync(path);
};

export const promptForPackageManager = async () => {
return (
await inquirer.prompt([
{
type: 'list',
name: 'pick-pm',
message: 'Package manager could not be detected. Which one should be used instead?',
default: 'npm',
choices: ['npm', 'yarn', 'pnpm'],
},
])
)?.['pick-pm'];
};
Loading

0 comments on commit c3125a8

Please sign in to comment.