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

New menu for selecting output directory for "create" commands #1187

Merged
merged 13 commits into from
Mar 28, 2019
116 changes: 53 additions & 63 deletions packages/salesforcedx-vscode-core/src/commands/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { channelService } from '../channels';
import { nls } from '../messages';
import { notificationService, ProgressNotification } from '../notifications';
import { isSfdxProjectOpened } from '../predicates';
import { SfdxPackageDirectories } from '../sfdxProject';
import { taskViewService } from '../statuses';
import { telemetryService } from '../telemetry';
import { getRootWorkspacePath, hasRootWorkspace } from '../util';
Expand Down Expand Up @@ -216,85 +217,74 @@ export class SelectFileName
}
}

export abstract class SelectDirPath
export class SelectOutputDir
implements ParametersGatherer<{ outputdir: string }> {
private explorerDir: string | undefined;
private globKeyWord: string | undefined;

public constructor(explorerDir?: vscode.Uri, globKeyWord?: string) {
this.explorerDir = explorerDir ? explorerDir.fsPath : explorerDir;
this.globKeyWord = globKeyWord;
private typeDir: string;
private typeDirRequired: boolean | undefined;
public static readonly defaultOutput = path.join('main', 'default');
public static readonly customDirOption = `$(file-directory) ${nls.localize(
'custom_output_directory'
)}`;

public constructor(typeDir: string, typeDirRequired?: boolean) {
this.typeDir = typeDir;
this.typeDirRequired = typeDirRequired;
}

public abstract globDirs(srcPath: string, priorityKeyword?: string): string[];

public async gather(): Promise<
CancelResponse | ContinueResponse<{ outputdir: string }>
> {
const rootPath = getRootWorkspacePath();
let outputdir;
if (rootPath) {
let packageDirs: string[] = [];
try {
packageDirs = await SfdxPackageDirectories.getPackageDirectoryPaths();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool handling for multiple packages.

} catch (e) {
if (
!this.explorerDir &&
this.globDirs(rootPath, this.globKeyWord).length === 0
e.name !== 'NoPackageDirectoryPathsFound' &&
e.name !== 'NoPackageDirectoriesFound'
) {
notificationService.showErrorMessage(
nls.localize(
'parameter_directory_strict_not_available',
this.globKeyWord
)
);
return { type: 'CANCEL' };
throw e;
}
outputdir = this.explorerDir
? path.relative(rootPath, this.explorerDir)
: await vscode.window.showQuickPick(
this.globDirs(rootPath, this.globKeyWord),
{
placeHolder: nls.localize('parameter_gatherer_enter_dir_name')
} as vscode.QuickPickOptions
);
}
let dirOptions = this.getDefaultOptions(packageDirs);
let outputdir = await this.showMenu(dirOptions);

if (outputdir === SelectOutputDir.customDirOption) {
dirOptions = this.getCustomOptions(getRootWorkspacePath());
outputdir = await this.showMenu(dirOptions);
}

return outputdir
? { type: 'CONTINUE', data: { outputdir } }
: { type: 'CANCEL' };
}
}
export class SelectPrioritizedDirPath extends SelectDirPath {
public globDirs(srcPath: string, priorityKeyword?: string): string[] {
const unprioritizedRelDirs = new glob.GlobSync(
path.join(srcPath, '**/')
).found.map(value => {
let relativePath = path.relative(srcPath, path.join(value, '/'));
relativePath = path.join(relativePath, '');
return relativePath;
});
if (priorityKeyword) {
const notPrioritized: string[] = [];
const prioritized = unprioritizedRelDirs.filter(dir => {
if (dir.includes(priorityKeyword)) {
return true;
} else {
notPrioritized.push(dir);
}
});
return prioritized.concat(notPrioritized);
}
return unprioritizedRelDirs;

public getDefaultOptions(packageDirectories: string[]): string[] {
const options = packageDirectories.map(packageDir =>
path.join(packageDir, SelectOutputDir.defaultOutput, this.typeDir)
);
options.push(SelectOutputDir.customDirOption);
return options;
}
}

export class SelectStrictDirPath extends SelectDirPath {
public globDirs(srcPath: string, priorityKeyword?: string): string[] {
const globPattern = priorityKeyword
? path.join(srcPath, '**/', priorityKeyword + '/')
: path.join(srcPath, '**/');
const relativeDirs = new glob.GlobSync(globPattern).found.map(value => {
let relativePath = path.relative(srcPath, path.join(value, '/'));
relativePath = path.join(relativePath, '');
return relativePath;
});
return relativeDirs;
public getCustomOptions(rootPath: string): string[] {
return new glob.GlobSync(path.join(rootPath, '**', path.sep)).found.map(
value => {
let relativePath = path.relative(rootPath, path.join(value, '/'));
relativePath = path.join(
relativePath,
this.typeDirRequired && !relativePath.endsWith(this.typeDir)
? this.typeDir
: ''
);
return relativePath;
}
);
}

public async showMenu(options: string[]): Promise<string | undefined> {
return await vscode.window.showQuickPick(options, {
placeHolder: nls.localize('parameter_gatherer_enter_dir_name')
} as vscode.QuickPickOptions);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ import {
CompositeParametersGatherer,
FilePathExistsChecker,
SelectFileName,
SelectPrioritizedDirPath,
SelectOutputDir,
SfdxCommandlet,
SfdxCommandletExecutor,
SfdxWorkspaceChecker
} from './commands';
const APEX_FILE_EXTENSION = '.cls';
const APEX_CLASS_METADATA_DIR = 'classes';

class ForceApexClassCreateExecutor extends SfdxCommandletExecutor<
DirFileNameSelection
Expand All @@ -56,7 +57,12 @@ class ForceApexClassCreateExecutor extends SfdxCommandletExecutor<
}).execute(cancellationToken);

execution.processExitSubject.subscribe(async data => {
this.logMetric(execution.command.logName, startTime);
const dirType = response.data.outputdir.endsWith(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These template commands badly need to be refactored to avoid having so much duplicated code. I started doing so but stuck it in another branch to separate it from this work. I'll make a story for it.

path.join(SelectOutputDir.defaultOutput, APEX_CLASS_METADATA_DIR)
)
? 'defaultDir'
: 'customDir';
this.logMetric(`${execution.command.logName}_${dirType}`, startTime);
if (
data !== undefined &&
data.toString() === '0' &&
Expand Down Expand Up @@ -89,11 +95,8 @@ const workspaceChecker = new SfdxWorkspaceChecker();
const fileNameGatherer = new SelectFileName();
const filePathExistsChecker = new FilePathExistsChecker(APEX_FILE_EXTENSION);

export async function forceApexClassCreate(explorerDir?: any) {
const outputDirGatherer = new SelectPrioritizedDirPath(
explorerDir,
'classes'
);
export async function forceApexClassCreate() {
const outputDirGatherer = new SelectOutputDir(APEX_CLASS_METADATA_DIR);
const parameterGatherer = new CompositeParametersGatherer<
DirFileNameSelection
>(fileNameGatherer, outputDirGatherer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import {
CompositeParametersGatherer,
FilePathExistsChecker,
SelectFileName,
SelectPrioritizedDirPath,
SelectOutputDir,
SfdxCommandlet,
SfdxCommandletExecutor,
SfdxWorkspaceChecker
} from './commands';

const APEX_TRIGGER_EXTENSION = '.trigger';
const APEX_TRIGGER_METADATA_DIR = 'triggers';

export class ForceApexTriggerCreateExecutor extends SfdxCommandletExecutor<
DirFileNameSelection
Expand All @@ -57,12 +58,13 @@ export class ForceApexTriggerCreateExecutor extends SfdxCommandletExecutor<
}).execute(cancellationToken);

execution.processExitSubject.subscribe(async data => {
this.logMetric(execution.command.logName, startTime);
if (
data !== undefined &&
data.toString() === '0' &&
hasRootWorkspace()
) {
const dirType = response.data.outputdir.endsWith(
path.join(SelectOutputDir.defaultOutput, APEX_TRIGGER_METADATA_DIR)
)
? 'defaultDir'
: 'customDir';
this.logMetric(`${execution.command.logName}_${dirType}`, startTime);
if (data !== undefined && data.toString() === '0' && hasRootWorkspace()) {
vscode.workspace
.openTextDocument(
path.join(
Expand All @@ -89,11 +91,8 @@ const workspaceChecker = new SfdxWorkspaceChecker();
const fileNameGatherer = new SelectFileName();
const filePathExistsChecker = new FilePathExistsChecker(APEX_TRIGGER_EXTENSION);

export async function forceApexTriggerCreate(explorerDir?: any) {
const outputDirGatherer = new SelectPrioritizedDirPath(
explorerDir,
'triggers'
);
export async function forceApexTriggerCreate() {
const outputDirGatherer = new SelectOutputDir(APEX_TRIGGER_METADATA_DIR);
const parameterGatherer = new CompositeParametersGatherer<
DirFileNameSelection
>(fileNameGatherer, outputDirGatherer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import {
CompositeParametersGatherer,
LightningFilePathExistsChecker,
SelectFileName,
SelectStrictDirPath,
SelectOutputDir,
SfdxCommandlet,
SfdxCommandletExecutor,
SfdxWorkspaceChecker
} from './commands';

const LIGHTNING_APP_EXTENSION = '.app';
const LIGHTNING_METADATA_DIR = 'aura';

class ForceLightningAppCreateExecutor extends SfdxCommandletExecutor<
DirFileNameSelection
Expand All @@ -57,12 +58,13 @@ class ForceLightningAppCreateExecutor extends SfdxCommandletExecutor<
}).execute(cancellationToken);

execution.processExitSubject.subscribe(async data => {
this.logMetric(execution.command.logName, startTime);
if (
data !== undefined &&
data.toString() === '0' &&
hasRootWorkspace()
) {
const dirType = response.data.outputdir.endsWith(
path.join(SelectOutputDir.defaultOutput, LIGHTNING_METADATA_DIR)
)
? 'defaultDir'
: 'customDir';
this.logMetric(`${execution.command.logName}_${dirType}`, startTime);
if (data !== undefined && data.toString() === '0' && hasRootWorkspace()) {
vscode.workspace
.openTextDocument(
path.join(
Expand Down Expand Up @@ -91,8 +93,8 @@ const workspaceChecker = new SfdxWorkspaceChecker();
const fileNameGatherer = new SelectFileName();
const lightningFilePathExistsChecker = new LightningFilePathExistsChecker();

export async function forceLightningAppCreate(explorerDir?: any) {
const outputDirGatherer = new SelectStrictDirPath(explorerDir, 'aura');
export async function forceLightningAppCreate() {
const outputDirGatherer = new SelectOutputDir(LIGHTNING_METADATA_DIR, true);
const parameterGatherer = new CompositeParametersGatherer<
DirFileNameSelection
>(fileNameGatherer, outputDirGatherer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import {
CompositeParametersGatherer,
LightningFilePathExistsChecker,
SelectFileName,
SelectStrictDirPath,
SelectOutputDir,
SfdxCommandlet,
SfdxCommandletExecutor,
SfdxWorkspaceChecker
} from './commands';

const LIGHTNING_CMP_EXTENSION = '.cmp';
const LIGHTNING_METADATA_DIR = 'aura';

class ForceLightningComponentCreateExecutor extends SfdxCommandletExecutor<
DirFileNameSelection
Expand All @@ -57,12 +58,13 @@ class ForceLightningComponentCreateExecutor extends SfdxCommandletExecutor<
}).execute(cancellationToken);

execution.processExitSubject.subscribe(async data => {
this.logMetric(execution.command.logName, startTime);
if (
data !== undefined &&
data.toString() === '0' &&
hasRootWorkspace()
) {
const dirType = response.data.outputdir.endsWith(
path.join(SelectOutputDir.defaultOutput, LIGHTNING_METADATA_DIR)
)
? 'defaultDir'
: 'customDir';
this.logMetric(`${execution.command.logName}_${dirType}`, startTime);
if (data !== undefined && data.toString() === '0' && hasRootWorkspace()) {
vscode.workspace
.openTextDocument(
path.join(
Expand Down Expand Up @@ -91,8 +93,8 @@ const workspaceChecker = new SfdxWorkspaceChecker();
const fileNameGatherer = new SelectFileName();
const lightningFilePathExistsChecker = new LightningFilePathExistsChecker();

export async function forceLightningComponentCreate(explorerDir?: any) {
const outputDirGatherer = new SelectStrictDirPath(explorerDir, 'aura');
export async function forceLightningComponentCreate() {
const outputDirGatherer = new SelectOutputDir(LIGHTNING_METADATA_DIR, true);
const parameterGatherer = new CompositeParametersGatherer<
DirFileNameSelection
>(fileNameGatherer, outputDirGatherer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@ import {
CompositeParametersGatherer,
LightningFilePathExistsChecker,
SelectFileName,
SelectStrictDirPath,
SelectOutputDir,
SfdxCommandlet,
SfdxCommandletExecutor,
SfdxWorkspaceChecker
} from './commands';

const LIGHTNING_EVT_EXTENSION = '.evt';
const LIGHTNING_METADATA_DIR = 'aura';

class ForceLightningEventCreateExecutor extends SfdxCommandletExecutor<
DirFileNameSelection
Expand All @@ -57,12 +58,13 @@ class ForceLightningEventCreateExecutor extends SfdxCommandletExecutor<
}).execute(cancellationToken);

execution.processExitSubject.subscribe(async data => {
this.logMetric(execution.command.logName, startTime);
if (
data !== undefined &&
data.toString() === '0' &&
hasRootWorkspace()
) {
const dirType = response.data.outputdir.endsWith(
path.join(SelectOutputDir.defaultOutput, LIGHTNING_METADATA_DIR)
)
? 'defaultDir'
: 'customDir';
this.logMetric(`${execution.command.logName}_${dirType}`, startTime);
if (data !== undefined && data.toString() === '0' && hasRootWorkspace()) {
vscode.workspace
.openTextDocument(
path.join(
Expand Down Expand Up @@ -91,8 +93,8 @@ const workspaceChecker = new SfdxWorkspaceChecker();
const fileNameGatherer = new SelectFileName();
const lightningFilePathExistsChecker = new LightningFilePathExistsChecker();

export async function forceLightningEventCreate(explorerDir?: any) {
const outputDirGatherer = new SelectStrictDirPath(explorerDir, 'aura');
export async function forceLightningEventCreate() {
const outputDirGatherer = new SelectOutputDir(LIGHTNING_METADATA_DIR, true);
const parameterGatherer = new CompositeParametersGatherer<
DirFileNameSelection
>(fileNameGatherer, outputDirGatherer);
Expand Down
Loading