Skip to content

Commit 82d7177

Browse files
committed
Merge branch 'feature/jump-to-module' into release
2 parents 053b92c + 81acaa4 commit 82d7177

File tree

14 files changed

+214
-74
lines changed

14 files changed

+214
-74
lines changed

.cursor/rules/commands.mdc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
description: Describes how to create and register new commands
3+
globs: src/command/*.ts
4+
alwaysApply: false
5+
---
6+
- Commands are located in `src/command` directory
7+
- Commands must extend the [Command.ts](mdc:src/command/Command.ts) abstract class or any other class that inherits it
8+
- Command name must be defined in format: `magentoToolbox.commandName`
9+
- New commands must be added to [index.ts](mdc:src/command/index.ts) file so that they are loaded. Commands also need to be added to [package.json](mdc:package.json) under contributes -> commands
10+
- Commands that only generate files based on a pre-defined template can extend the [SimpleTemplateGeneratorCommand.ts](mdc:src/command/SimpleTemplateGeneratorCommand.ts) class

.cursor/rules/tests.mdc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
description: Describes how to write tests
3+
globs: *.test.ts
4+
alwaysApply: false
5+
---
6+
- Tests are located in the src/test directory
7+
- Utilities for tests can be found in this file [util.ts](mdc:src/test/util.ts)
8+
- Some parts of the extension require the ExtensionContext to be present. To make sure it's set, tests should run the setup function from [setup.ts](mdc:src/test/setup.ts)
9+
- Tests are written using Mocha framework (`mocha` package) in Typescript and must end with .test.ts file extension. Do NOT use `chai`
10+
- Test spies, stubs and mocks can be written using the Sinon.js library
11+
- Reference files for tests are stored in the test-resources directory

package.json

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,111 +57,143 @@
5757
"commands": [
5858
{
5959
"command": "magento-toolbox.generateModule",
60-
"title": "Magento Toolbox: Generate Module"
60+
"title": "Generate Module",
61+
"category": "Magento Toolbox"
6162
},
6263
{
6364
"command": "magento-toolbox.generateBlock",
64-
"title": "Magento Toolbox: Generate Block"
65+
"title": "Generate Block",
66+
"category": "Magento Toolbox"
6567
},
6668
{
6769
"command": "magento-toolbox.indexWorkspace",
68-
"title": "Magento Toolbox: Index Workspace"
70+
"title": "Index Workspace",
71+
"category": "Magento Toolbox"
6972
},
7073
{
7174
"command": "magento-toolbox.generateContextPlugin",
72-
"title": "Magento Toolbox: Generate Plugin"
75+
"title": "Generate Plugin",
76+
"category": "Magento Toolbox"
7377
},
7478
{
7579
"command": "magento-toolbox.copyMagentoPath",
76-
"title": "Magento Toolbox: Copy Magento Path"
80+
"title": "Copy Magento Path",
81+
"category": "Magento Toolbox"
7782
},
7883
{
7984
"command": "magento-toolbox.generateXmlCatalog",
80-
"title": "Magento Toolbox: Generate XML URN Catalog"
85+
"title": "Generate XML URN Catalog",
86+
"category": "Magento Toolbox"
8187
},
8288
{
8389
"command": "magento-toolbox.generateObserver",
84-
"title": "Magento Toolbox: Generate Observer"
90+
"title": "Generate Observer",
91+
"category": "Magento Toolbox"
8592
},
8693
{
8794
"command": "magento-toolbox.generateEventsXml",
88-
"title": "Magento Toolbox: Generate Events XML"
95+
"title": "Generate Sample events.xml",
96+
"category": "Magento Toolbox"
8997
},
9098
{
9199
"command": "magento-toolbox.generateGraphqlSchemaFile",
92-
"title": "Magento Toolbox: Generate GraphQL Schema File"
100+
"title": "Generate Sample schema.graphqls",
101+
"category": "Magento Toolbox"
93102
},
94103
{
95104
"command": "magento-toolbox.generateRoutesXmlFile",
96-
"title": "Magento Toolbox: Generate Routes XML"
105+
"title": "Generate Sample routes.xml",
106+
"category": "Magento Toolbox"
97107
},
98108
{
99109
"command": "magento-toolbox.generateAclXmlFile",
100-
"title": "Magento Toolbox: Generate ACL XML"
110+
"title": "Generate Sample acl.xml",
111+
"category": "Magento Toolbox"
101112
},
102113
{
103114
"command": "magento-toolbox.generateDiXmlFile",
104-
"title": "Magento Toolbox: Generate DI XML"
115+
"title": "Generate Sample di.xml",
116+
"category": "Magento Toolbox"
105117
},
106118
{
107119
"command": "magento-toolbox.generateWebapiXmlFile",
108-
"title": "Magento Toolbox: Generate Webapi XML"
120+
"title": "Generate Sample webapi.xml",
121+
"category": "Magento Toolbox"
109122
},
110123
{
111124
"command": "magento-toolbox.generatePreference",
112-
"title": "Magento Toolbox: Generate Preference"
125+
"title": "Generate Preference",
126+
"category": "Magento Toolbox"
113127
},
114128
{
115129
"command": "magento-toolbox.generateLayoutXmlFile",
116-
"title": "Magento Toolbox: Generate Layout XML"
130+
"title": "Generate Layout XML",
131+
"category": "Magento Toolbox"
117132
},
118133
{
119134
"command": "magento-toolbox.generatePageTypesXmlFile",
120-
"title": "Magento Toolbox: Generate Page Types XML"
135+
"title": "Generate Sample page_types.xml",
136+
"category": "Magento Toolbox"
121137
},
122138
{
123139
"command": "magento-toolbox.generateCrontabXmlFile",
124-
"title": "Magento Toolbox: Generate Crontab XML"
140+
"title": "Generate Sample crontab.xml",
141+
"category": "Magento Toolbox"
125142
},
126143
{
127144
"command": "magento-toolbox.generateEmailTemplatesXmlFile",
128-
"title": "Magento Toolbox: Generate Email Templates XML"
145+
"title": "Generate Sample email_templates.xml",
146+
"category": "Magento Toolbox"
129147
},
130148
{
131149
"command": "magento-toolbox.generateSectionsXmlFile",
132-
"title": "Magento Toolbox: Generate Sections XML"
150+
"title": "Generate Sample sections.xml",
151+
"category": "Magento Toolbox"
133152
},
134153
{
135154
"command": "magento-toolbox.generateFieldsetXmlFile",
136-
"title": "Magento Toolbox: Generate Fieldset XML"
155+
"title": "Generate Sample fieldset.xml",
156+
"category": "Magento Toolbox"
137157
},
138158
{
139159
"command": "magento-toolbox.generateViewXmlFile",
140-
"title": "Magento Toolbox: Generate View XML"
160+
"title": "Generate Sample view.xml",
161+
"category": "Magento Toolbox"
141162
},
142163
{
143164
"command": "magento-toolbox.generateIndexerXmlFile",
144-
"title": "Magento Toolbox: Generate Indexer XML"
165+
"title": "Generate Sample indexer.xml",
166+
"category": "Magento Toolbox"
145167
},
146168
{
147169
"command": "magento-toolbox.generateMviewXmlFile",
148-
"title": "Magento Toolbox: Generate MVIEW XML"
170+
"title": "Generate Sample mview.xml",
171+
"category": "Magento Toolbox"
149172
},
150173
{
151174
"command": "magento-toolbox.generateWidgetXmlFile",
152-
"title": "Magento Toolbox: Generate Widget XML"
175+
"title": "Generate Sample widget.xml",
176+
"category": "Magento Toolbox"
153177
},
154178
{
155179
"command": "magento-toolbox.generateExtensionAttributesXmlFile",
156-
"title": "Magento Toolbox: Generate Extension Attributes XML"
180+
"title": "Generate Sample extension_attributes.xml",
181+
"category": "Magento Toolbox"
157182
},
158183
{
159184
"command": "magento-toolbox.generateSystemXmlFile",
160-
"title": "Magento Toolbox: Generate System XML"
185+
"title": "Generate Sample system.xml",
186+
"category": "Magento Toolbox"
161187
},
162188
{
163189
"command": "magento-toolbox.generateConfigXmlFile",
164-
"title": "Magento Toolbox: Generate Config XML"
190+
"title": "Generate Sample config.xml",
191+
"category": "Magento Toolbox"
192+
},
193+
{
194+
"command": "magento-toolbox.jumpToModule",
195+
"title": "Jump to Module",
196+
"category": "Magento Toolbox"
165197
}
166198
],
167199
"menus": {

src/command/JumpToModuleCommand.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Command } from 'command/Command';
2+
import { window } from 'vscode';
3+
import IndexManager from 'indexer/IndexManager';
4+
import ModuleIndexer from 'indexer/module/ModuleIndexer';
5+
import { Uri } from 'vscode';
6+
7+
export default class JumpToModuleCommand extends Command {
8+
constructor() {
9+
super('magento-toolbox.jumpToModule');
10+
}
11+
12+
public async execute(...args: any[]): Promise<void> {
13+
const moduleIndexData = IndexManager.getIndexData(ModuleIndexer.KEY);
14+
15+
if (!moduleIndexData) {
16+
window.showErrorMessage('Module index data not found');
17+
return;
18+
}
19+
20+
const moduleName = await window.showQuickPick(moduleIndexData.getModuleOptions(), {
21+
placeHolder: 'Enter module name (e.g. Magento_Catalog)',
22+
});
23+
24+
if (!moduleName) {
25+
return;
26+
}
27+
28+
const module = moduleIndexData.getModule(moduleName.label);
29+
30+
if (!module) {
31+
window.showErrorMessage(`Module ${moduleName} not found`);
32+
return;
33+
}
34+
35+
const moduleXmlPath = Uri.file(`${module.path}/etc/module.xml`);
36+
37+
const document = await window.showTextDocument(moduleXmlPath);
38+
}
39+
}

src/command/SimpleTemplateGeneratorCommand.ts

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import IndexManager from 'indexer/IndexManager';
22
import { Command } from './Command';
3-
import { Uri, window } from 'vscode';
3+
import { Uri, WorkspaceFolder } from 'vscode';
44
import ModuleIndexer from 'indexer/module/ModuleIndexer';
55
import FileGeneratorManager from 'generator/FileGeneratorManager';
66
import TemplateGenerator from 'generator/TemplateGenerator';
@@ -36,28 +36,50 @@ export abstract class SimpleTemplateGeneratorCommand extends Command {
3636
return data;
3737
}
3838

39-
public async execute(uri?: Uri): Promise<void> {
40-
const moduleIndex = IndexManager.getIndexData(ModuleIndexer.KEY);
41-
let contextModule: string | undefined;
39+
public async getWizardData(contextModule: string | undefined): Promise<TemplateWizardData> {
40+
const wizard = new SimpleTemplateWizard();
41+
const data = await wizard.show(
42+
this.getWizardTitle(),
43+
contextModule,
44+
this.getAreas(),
45+
this.getWizardFields(),
46+
this.getWizardValidation()
47+
);
4248

43-
const contextUri = uri || window.activeTextEditor?.document.uri;
49+
return data;
50+
}
51+
52+
public getContextModule(contextUri: Uri | undefined): string | undefined {
53+
if (!contextUri) {
54+
return undefined;
55+
}
56+
57+
const moduleIndex = IndexManager.getIndexData(ModuleIndexer.KEY);
4458

4559
if (moduleIndex && contextUri) {
4660
const module = moduleIndex.getModuleByUri(contextUri);
4761

4862
if (module) {
49-
contextModule = module.name;
63+
return module.name;
5064
}
5165
}
5266

53-
const wizard = new SimpleTemplateWizard();
54-
const data = await wizard.show(
55-
this.getWizardTitle(),
56-
contextModule,
57-
this.getAreas(),
58-
this.getWizardFields(),
59-
this.getWizardValidation()
60-
);
67+
return undefined;
68+
}
69+
70+
protected getWorkspaceFolder(): WorkspaceFolder {
71+
const workspaceFolder = Common.getActiveWorkspaceFolder();
72+
73+
if (!workspaceFolder) {
74+
throw new Error('No active workspace folder');
75+
}
76+
77+
return workspaceFolder;
78+
}
79+
80+
public async execute(uri?: Uri): Promise<void> {
81+
const contextModule = this.getContextModule(uri);
82+
const data = await this.getWizardData(contextModule);
6183

6284
const manager = new FileGeneratorManager([
6385
new TemplateGenerator(this.getFilePath(data), this.getTemplateName(data), {
@@ -66,12 +88,7 @@ export abstract class SimpleTemplateGeneratorCommand extends Command {
6688
}),
6789
]);
6890

69-
const workspaceFolder = Common.getActiveWorkspaceFolder();
70-
71-
if (!workspaceFolder) {
72-
window.showErrorMessage('No active workspace folder');
73-
return;
74-
}
91+
const workspaceFolder = this.getWorkspaceFolder();
7592

7693
await manager.generate(workspaceFolder.uri);
7794
await manager.writeFiles();

src/command/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ export { default as GenerateWidgetXmlFileCommand } from './GenerateWidgetXmlFile
2525
export { default as GenerateExtensionAttributesXmlFileCommand } from './GenerateExtensionAttributesXmlFileCommand';
2626
export { default as GenerateSystemXmlFileCommand } from './GenerateSystemXmlFileCommand';
2727
export { default as GenerateConfigXmlFileCommand } from './GenerateConfigXmlFileCommand';
28+
export { default as JumpToModuleCommand } from './JumpToModuleCommand';

src/generator/util/GenerateFromTemplate.ts renamed to src/generator/HandlebarsTemplateRenderer.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,20 @@ import FileSystem from 'util/FileSystem';
44
import { Uri } from 'vscode';
55
import Logger from 'util/Logger';
66

7-
export default class GenerateFromTemplate {
8-
public static async generate(template: string, data?: Record<string, any>): Promise<string> {
7+
export default class HandlebarsTemplateRenderer {
8+
protected handlebars: typeof Handlebars;
9+
10+
public constructor() {
11+
this.handlebars = create();
12+
this.registerHelpers();
13+
this.registerPartials();
14+
}
15+
16+
public async render(template: string, data?: Record<string, any>): Promise<string> {
917
try {
1018
const templatePath = this.getTemplatePath(template);
1119
const templateContent = await FileSystem.readFile(Uri.file(templatePath));
12-
const handlebars = create();
13-
this.registerHelpers(handlebars);
14-
this.registerPartials(handlebars);
15-
const compiledTemplate = handlebars.compile(templateContent);
20+
const compiledTemplate = this.handlebars.compile(templateContent);
1621
const content = compiledTemplate(data);
1722
return content;
1823
} catch (error) {
@@ -21,20 +26,20 @@ export default class GenerateFromTemplate {
2126
}
2227
}
2328

24-
protected static getTemplatePath(templateName: string): string {
29+
public getTemplatePath(templateName: string): string {
2530
return resolve(FileSystem.getExtensionPath('templates/handlebars'), templateName + '.hbs');
2631
}
2732

28-
protected static registerHelpers(handlebars: typeof Handlebars): void {
29-
handlebars.registerHelper('ifeq', (a: string, b: string, options: any) => {
33+
protected registerHelpers(): void {
34+
this.handlebars.registerHelper('ifeq', (a: string, b: string, options: any) => {
3035
if (a === b) {
3136
return options.fn(this);
3237
}
3338
return options.inverse(this);
3439
});
3540
}
3641

37-
protected static registerPartials(handlebars: typeof Handlebars): void {
38-
handlebars.registerPartial('fileHeader', '{{#if fileHeader}}\n{{{fileHeader}}}\n{{/if}}');
42+
protected registerPartials(): void {
43+
this.handlebars.registerPartial('fileHeader', '{{#if fileHeader}}\n{{{fileHeader}}}\n{{/if}}');
3944
}
4045
}

0 commit comments

Comments
 (0)