Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add init and dev add commands #6

Merged
merged 1 commit into from
Sep 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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