Skip to content

Commit

Permalink
Merge pull request #1392 from flexn-io/fix/rnv_command
Browse files Browse the repository at this point in the history
rnv standalone command fixes
  • Loading branch information
mihaiblaga89 committed Feb 14, 2024
2 parents 5034fe7 + dfd694d commit 162fc66
Show file tree
Hide file tree
Showing 117 changed files with 672 additions and 254 deletions.
4 changes: 2 additions & 2 deletions packages/cli/src/prompt.ts
Expand Up @@ -51,8 +51,8 @@ export const inquirerPrompt = async (params: PromptParams): Promise<Record<strin
return resp;
};

export const inquirerSeparator = () => {
return new inquirer.Separator();
export const inquirerSeparator = (text?: string) => {
return new inquirer.Separator(text);
};

export const pressAnyKeyToContinue = () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/api/index.ts
Expand Up @@ -40,8 +40,8 @@ export const inquirerPrompt: RnvApiPrompt['inquirerPrompt'] = (opts) => {
return getApi().prompt.inquirerPrompt(opts);
};

export const inquirerSeparator: RnvApiPrompt['inquirerSeparator'] = () => {
return getApi().prompt.inquirerSeparator();
export const inquirerSeparator: RnvApiPrompt['inquirerSeparator'] = (text?: string) => {
return getApi().prompt.inquirerSeparator(text);
};

export const generateOptions: RnvApiPrompt['generateOptions'] = (inputData, isMultiChoice, mapping, renderMethod) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/api/types.ts
Expand Up @@ -37,7 +37,7 @@ export type RnvApiPrompt = {
renderMethod?: PromptRenderFn
) => PromptOptions;
pressAnyKeyToContinue: () => Promise<any>;
inquirerSeparator: () => any;
inquirerSeparator: (text?: string) => any;
};

export type RnvContextAnalytics = {
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/constants.ts
Expand Up @@ -122,6 +122,8 @@ export const SUPPORTED_PLATFORMS = [
export const TASK_RUN = 'run';
export const TASK_CONFIGURE = 'configure';
export const TASK_DOCTOR = 'doctor';
export const TASK_NEW = 'new';
export const TASK_HELP = 'help';
export const TASK_BUILD = 'build';
export const TASK_INFO = 'info';
export const TASK_START = 'start';
Expand All @@ -131,6 +133,8 @@ export const TASK_PACKAGE = 'package';
export const TASK_DEPLOY = 'deploy';
export const TASK_LOG = 'log';
export const TASK_CLEAN = 'clean';
export const TASK_LINK = 'link';
export const TASK_UNLINK = 'unlink';
export const TASK_INSTALL = 'install';
export const TASK_PUBLISH = 'publish';
export const TASK_STATUS = 'status';
Expand Down Expand Up @@ -172,6 +176,9 @@ export const TASK_WORKSPACE_CONFIGURE = 'workspace configure';
export const TASK_CONFIGURE_SOFT = 'configureSoft';
export const TASK_KILL = 'kill';
export const TASK_EJECT = 'eject';
export const TASK_TELEMETRY_DISABLE = 'telemetry disable';
export const TASK_TELEMETRY_ENABLE = 'telemetry enable';
export const TASK_TELEMETRY_STATUS = 'telemetry status';

export const INJECTABLE_CONFIG_PROPS: Array<ConfigPropKey> = [
'id',
Expand All @@ -188,3 +195,12 @@ export const INJECTABLE_CONFIG_PROPS: Array<ConfigPropKey> = [
export const INJECTABLE_RUNTIME_PROPS = ['appId', 'scheme', 'timestamp', 'localhost', 'target', 'port'] as const;

export const REMOTE_DEBUGGER_ENABLED_PLATFORMS = [TIZEN, TIZEN_MOBILE, TIZEN_WATCH];

export const DEFAULT_TASK_DESCRIPTIONS: Record<string, string> = {
[TASK_RUN]: 'Run your app on target device or emulator',
[TASK_PACKAGE]: 'Package source files into bundle',
[TASK_BUILD]: 'Build project binary',
[TASK_CONFIGURE]: 'Configure current project',
[TASK_START]: 'Starts bundler / server',
[TASK_EXPORT]: 'Export the app into deployable binary',
};
121 changes: 88 additions & 33 deletions packages/core/src/tasks/index.ts
Expand Up @@ -8,11 +8,11 @@ import {
getEngineSubTasks,
registerAllPlatformEngines,
} from '../engines';
import { TASK_CONFIGURE_SOFT } from '../constants';
import { DEFAULT_TASK_DESCRIPTIONS, TASK_CONFIGURE_SOFT } from '../constants';
import { RnvContext } from '../context/types';
import { RnvTask, RnvTaskMap, TaskItemMap, TaskObj } from './types';
import { RnvTask, RnvTaskMap, TaskItemMap, TaskObj, TaskOption } from './types';
import { RnvEngine } from '../engines/types';
import { inquirerPrompt, pressAnyKeyToContinue } from '../api';
import { inquirerPrompt, inquirerSeparator, pressAnyKeyToContinue } from '../api';
import { getApi } from '../api/provider';
import { RenativeConfigTaskKey } from '../schema/types';
import { checkIfProjectAndNodeModulesExists } from '../projects/dependencyManager';
Expand Down Expand Up @@ -41,24 +41,44 @@ export const initializeTask = async (c: RnvContext, task: string) => {
return true;
};

const _getTaskOption = ({ taskInstance, hasMultipleSubTasks }: TaskObj) => {
if (hasMultipleSubTasks) {
return `${taskInstance.task.split(' ')[0]}...`;
}
const _getTaskOption = ({ taskInstance }: TaskObj): TaskOption => {
const asArray = taskInstance.task.split(' ');
const output: TaskOption = {
value: taskInstance.task,
command: '',
name: '',
asArray,
isPriorityOrder: taskInstance.isPriorityOrder,
description: taskInstance.description,
isGlobalScope: taskInstance.isGlobalScope,
isPrivate: taskInstance.isPrivate,
};

if (taskInstance.description && taskInstance.description !== '') {
return `${taskInstance.task.split(' ')[0]} ${chalk().grey(`(${taskInstance.description})`)}`;
output.description = taskInstance.description;
output.name = `${taskInstance.task} ${chalk().grey(`(${taskInstance.description})`)}`;
} else {
output.name = taskInstance.task;
}
return `${taskInstance.task.split(' ')[0]}`;
output.command = asArray[0];
output.subCommand = asArray[1];

return output;
};

const _getTaskObj = (taskInstance: RnvTask) => {
const key = taskInstance.task.split(' ')[0];
let hasMultipleSubTasks = false;
if (taskInstance.task.includes(' ')) hasMultipleSubTasks = true;
const key = taskInstance.task;
const taskNameArr = key.split(' ');
let parent: null | string = null;
if (taskNameArr.length > 1) {
taskNameArr.pop();
parent = taskNameArr.join(' ');
}

return {
key,
taskInstance,
hasMultipleSubTasks,
parent,
};
};

Expand All @@ -68,45 +88,80 @@ export const findSuitableTask = async (c: RnvContext, specificTask?: string): Pr
let task = '';
if (!specificTask) {
if (!c.command) {
const suitableTaskInstances: Record<string, TaskObj> = {};
const suitableTasks: Record<string, TaskOption> = {};
REGISTERED_ENGINES.forEach((engine) => {
Object.values(engine.tasks).forEach((taskInstance) => {
const taskObj = _getTaskObj(taskInstance);
suitableTaskInstances[taskObj.key] = taskObj;
let taskObj: TaskOption = _getTaskOption(_getTaskObj(taskInstance));
if (!suitableTasks[taskObj.value]) {
suitableTasks[taskObj.value] = taskObj;
} else {
taskObj = suitableTasks[taskObj.value];
// In case of multiple competing tasks (same task name but coming from different engines)
// We try to revert to generic description instead.
taskObj.description = DEFAULT_TASK_DESCRIPTIONS[taskObj.value] || taskObj.description;
// In case of multiple competing tasks we assume they are "commonly used"
taskObj.isPriorityOrder = true;
}
});
});
Object.values(CUSTOM_TASKS).forEach((taskInstance) => {
const taskObj = _getTaskObj(taskInstance);
suitableTaskInstances[taskObj.key] = taskObj;
const taskObj = _getTaskOption(_getTaskObj(taskInstance));
suitableTasks[taskObj.value] = taskObj;
});

const taskInstances = Object.values(suitableTaskInstances);
let tasks;
const taskInstances = Object.values(suitableTasks);
let tasks: TaskOption[];

let defaultCmd: string | undefined = 'new';
let tasksCommands;
let filteredTasks;
let addendum = '';
if (!c.paths.project.configExists) {
filteredTasks = taskInstances.filter((v) => v.taskInstance.isGlobalScope);
tasks = filteredTasks.map((v) => _getTaskOption(v)).sort();
tasksCommands = filteredTasks.map((v) => v.taskInstance.task.split(' ')[0]).sort();
tasks = taskInstances.filter((v) => v.isGlobalScope && !v.isPrivate).sort();
addendum = ' (Not a ReNative project. options will be limited)';
} else {
tasks = taskInstances.map((v) => _getTaskOption(v)).sort();
tasksCommands = taskInstances.map((v) => v.taskInstance.task.split(' ')[0]).sort();
defaultCmd = tasks.find((v) => v.startsWith('run'));
tasks = taskInstances.filter((v) => !v.isPrivate).sort();
defaultCmd = tasks.find((v) => v.value === 'run')?.name;
}

const { command } = await inquirerPrompt({
const commonTasks: TaskOption[] = [];
const ungroupedTasks: TaskOption[] = [];
const groupedTasks: TaskOption[] = [];
const taskGroups: Record<string, TaskOption> = {};
tasks.forEach((task) => {
if (task.subCommand) {
if (!taskGroups[task.command]) {
const groupTask: TaskOption = {
name: `${task.command}...`,
command: task.command,
value: task.command,
};
taskGroups[task.command] = groupTask;
groupedTasks.push(groupTask);
}
} else if (task.isPriorityOrder) {
commonTasks.push(task);
} else {
ungroupedTasks.push(task);
}
});

const mergedTasks = [
inquirerSeparator('─────────── Common tasks ───────────'),
...commonTasks,
inquirerSeparator('─────────── More tasks ─────────────'),
...ungroupedTasks,
...groupedTasks,
];

const { selectedTask } = await inquirerPrompt({
type: 'list',
default: defaultCmd,
name: 'command',
name: 'selectedTask',
message: `Pick a command${addendum}`,
choices: tasks,
choices: mergedTasks,
pageSize: 15,
logMessage: 'Welcome to the brave new world...',
});
c.command = tasksCommands[tasks.indexOf(command)];
c.command = selectedTask;
}
if (c.command) task = c.command;
if (c.subCommand) task += ` ${c.subCommand}`;
Expand Down Expand Up @@ -343,7 +398,7 @@ export const executeOrSkipTask = async (c: RnvContext, task: string, parentTask:

const ACCEPTED_CONDITIONS = ['platform', 'target', 'appId', 'scheme'] as const;

type ACKey = typeof ACCEPTED_CONDITIONS[number];
type ACKey = (typeof ACCEPTED_CONDITIONS)[number];

const _logSkip = (task: string) => {
logInfo(`Original RNV task ${chalk().white(task)} marked to ignore. SKIPPING...`);
Expand Down
17 changes: 16 additions & 1 deletion packages/core/src/tasks/types.ts
Expand Up @@ -9,6 +9,21 @@ export type RnvTask = {
forceBuildHookRebuild?: boolean;
fn?: RnvTaskFn;
fnHelp?: RnvTaskFn;
isPrivate?: boolean;
isPriorityOrder?: boolean;
};

export type TaskOption = {
name: string;
value: string;
command: string;
asArray?: string[];
subCommand?: string;
subTasks?: TaskOption[];
description?: string;
isGlobalScope?: boolean;
isPrivate?: boolean;
isPriorityOrder?: boolean;
};

export type RnvTaskParameter = {
Expand Down Expand Up @@ -38,5 +53,5 @@ export type TaskItemMap = Record<
export type TaskObj = {
key: string;
taskInstance: RnvTask;
hasMultipleSubTasks?: boolean;
// hasMultipleSubTasks?: boolean;
};
5 changes: 4 additions & 1 deletion packages/engine-core/src/tasks/task.rnv.app.configure.ts
Expand Up @@ -19,6 +19,7 @@ import {
inquirerPrompt,
RnvContext,
inquirerSeparator,
RnvTask,
} from '@rnv/core';

const _loadAppConfigIDfromDir = (dirName: string, appConfigsDir: string) => {
Expand Down Expand Up @@ -204,10 +205,12 @@ export const taskRnvAppConfigure = async (c: RnvContext) => {
return true;
};

export default {
const Task: RnvTask = {
description: 'Configure project with specific appConfig',
fn: taskRnvAppConfigure,
task: TASK_APP_CONFIGURE,
params: PARAMS.withBase(PARAMS.withConfigure()),
platforms: [],
};

export default Task;
6 changes: 4 additions & 2 deletions packages/engine-core/src/tasks/task.rnv.app.create.ts
Expand Up @@ -15,6 +15,7 @@ import {
logTask,
TASK_APP_CREATE,
PARAMS,
RnvTask,
} from '@rnv/core';
import { ConfigFileApp } from '@rnv/core/lib/schema/configFiles/types';

Expand Down Expand Up @@ -163,11 +164,12 @@ export const taskRnvAppCreate: RnvTaskFn = async (c) => {
return true;
};

export default {
const Task: RnvTask = {
description: 'Create new app config',
fn: taskRnvAppCreate,
task: TASK_APP_CREATE,
params: PARAMS.withBase(),
skipPlatforms: true,
platforms: [],
};

export default Task;
13 changes: 10 additions & 3 deletions packages/engine-core/src/tasks/task.rnv.clean.ts
Expand Up @@ -13,6 +13,8 @@ import {
isSystemWin,
RnvTaskFn,
inquirerPrompt,
RnvTask,
TASK_CLEAN,
} from '@rnv/core';

function clearWindowsCacheFiles() {
Expand Down Expand Up @@ -198,17 +200,22 @@ export const taskRnvClean: RnvTaskFn = async (c) => {
logDebug('watchman not installed. skipping');
}

await executeAsync(c, 'npx rimraf -I $TMPDIR/metro-* && npx rimraf -I $TMPDIR/react-* && npx rimraf -I $TMPDIR/haste-*');
await executeAsync(
c,
'npx rimraf -I $TMPDIR/metro-* && npx rimraf -I $TMPDIR/react-* && npx rimraf -I $TMPDIR/haste-*'
);
}
}
return true;
};

export default {
const Task: RnvTask = {
description: 'Automatically removes all node_modules and lock in your project and its dependencies',
fn: taskRnvClean,
task: 'clean',
task: TASK_CLEAN,
params: PARAMS.withBase(),
platforms: [],
isGlobalScope: true,
};

export default Task;
6 changes: 4 additions & 2 deletions packages/engine-core/src/tasks/task.rnv.config.ts
@@ -1,4 +1,4 @@
import { logTask, PARAMS, RnvTaskFn, executeTask, TASK_CONFIGURE_SOFT, SUPPORTED_PLATFORMS } from '@rnv/core';
import { logTask, PARAMS, RnvTaskFn, executeTask, TASK_CONFIGURE_SOFT, SUPPORTED_PLATFORMS, RnvTask } from '@rnv/core';

const TASK_CONFIG = 'config';

Expand All @@ -12,10 +12,12 @@ export const taskRnvConfig: RnvTaskFn = async (c, _, originTask) => {
return true;
};

export default {
const Task: RnvTask = {
description: 'Display RNV config',
fn: taskRnvConfig,
task: TASK_CONFIG,
params: PARAMS.withBase(),
platforms: [...SUPPORTED_PLATFORMS],
};

export default Task;

0 comments on commit 162fc66

Please sign in to comment.