Skip to content

Commit

Permalink
Merge pull request #2 from gautier-lefebvre/feature/extra-variables
Browse files Browse the repository at this point in the history
Feature/extra variables
  • Loading branch information
gautier-lefebvre authored Jun 25, 2023
2 parents de61b39 + 0ca4ec2 commit bfe64af
Show file tree
Hide file tree
Showing 29 changed files with 452 additions and 148 deletions.
23 changes: 22 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,28 @@
"class-methods-use-this": "off",
"no-await-in-loop": "off",
"no-continue": "off",
"no-plusplus": "off"
"no-plusplus": "off",
"prefer-destructuring": "off",

"import/order": [
"warn",
{
"groups": [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"object"
],
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"newlines-between": "always"
}
]
},

"overrides": [
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.1.0]
### Added
- Prompt the user for any extra variable found inside a file template content that was not resolved from the template configuration, template file name, or global variables.

## [1.0.0]
### Fixed
- Fixed the order of commands in explorer context so New File is always the first.
Expand Down
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ Moreover, the variables `foo` and `bar` will be available to you in your file te

### Inside file template groups

Your file template groups have an additional setting so you can configure whether or not all file templates or the group share the same variable values.
Your file template groups have an additional setting so you can configure whether or not all file templates of the group share the same variable values.

If yes, and you have file templates with file names `{{foo}}.{{bar}}.jsx` and `{{foo}}.md`, you will be prompted once for `foo` and once for `bar`.

Expand All @@ -261,6 +261,14 @@ When defining a template in `ejs`, these are the provided variables, in ascendin
- **fileName** *(string)* - The name of your file (with extension).
- **baseFileName** *(string)* - The name of your file, without the extensions. E.g. if your generated file name is `foo.module.scss`, baseFileName is `foo`.

### Extra variables

Any extra variable found inside a file template will be prompted:
* independently for each template if the template is used as a standalone, or within a group not sharing its variables.
* once per different variable if the template is used within a group sharing its variables.

Note: to find extra variables inside a `ejs` template, I have to try to render the file for each extra variable, so this might affect performance if there are a lot of them.

### Example

Considering the following:
Expand Down Expand Up @@ -293,17 +301,31 @@ Other file templates in your file template group with file names:
The current file template with file name:
- `{{name}}.jsx`

And file template content:
```jsx
import { memo } from 'react';

export const <%= baseFileName %> = memo(function <%= baseFileName %>() {
return (
<div>
<%= someExtraVariable %>
</div>
);
});
```

Inside your file template content, you have access to:
- **foo**: `'yolo'` (overridden in the local configuration).
- **bar**: `'bbb` (global configuration).
- **baz**: overridden and prompted to the user in `{{name}}.{{baz}}.{{id}}.whatever`.
- **name**: overridden in your current template file name.
- **id**: prompted to the user in `{{name}}.{{baz}}.{{id}}.whatever`.
- **bar**: `'bbb'` (global configuration).
- **baz**: overridden and prompted to you from `{{name}}.{{baz}}.{{id}}.whatever`.
- **name**: prompted to you from your current template file name.
- **id**: prompted to you from `{{name}}.{{baz}}.{{id}}.whatever`.
- **groupTemplates**: computed when creating the file using the file template.
- **timestamp**: computed when creating the file using the file template.
- **relativeFilePath**: computed when creating the file using the file template.
- **fileName**: computed when creating the file using the file template.
- **baseFileName**: computed when creating the file using the file template.
- **someExtraVariable**: prompted to you when creating the file because it was not resolved from the variables above.

## Release Notes

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "file-template-manager",
"displayName": "File template manager",
"description": "Create files from templates",
"version": "1.0.0",
"version": "1.1.0",
"publisher": "gautier-lfbvr",
"homepage": "https://github.com/gautier-lefebvre/vscode-file-template-manager#readme",
"repository": {
Expand Down
26 changes: 15 additions & 11 deletions src/commands/createFileFromTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import {
commands,
FileSystemError,
Uri,
window,
workspace,
} from 'vscode';

import { COMMANDS } from '../constants';
import { renderFile } from '../domain/renderer';
import { TemplateRenderer } from '../domain/renderer/templateRenderer';
import { Template } from '../domain/templates/data/template';
import { generateFileName } from '../domain/templates/data/template/utils';

import { promptUserForTemplatesVariablesValues } from './utils/templateGroups';
import { getTemplatesOfWorkspaceFolderQuickPickItems, getGlobalTemplatesQuickPickItems } from './utils/templates';

Expand Down Expand Up @@ -51,18 +53,21 @@ export const createFileFromTemplate = async (baseFolderUri: Uri): Promise<void>

if (!template) { return; }

const fileNameVariablesPerTemplates = await promptUserForTemplatesVariablesValues(
const templateRenderer = new TemplateRenderer(template);

const variablesPerTemplates = await promptUserForTemplatesVariablesValues(
true,
[template],
[templateRenderer],
baseFolderUri,
);

if (!fileNameVariablesPerTemplates) { return; }
if (!variablesPerTemplates) { return; }

const fileNameVariables = fileNameVariablesPerTemplates[template.metadata.id];
const templateVariables = variablesPerTemplates[templateRenderer.template.metadata.id];

const fileUri = Uri.joinPath(
baseFolderUri,
generateFileName(template.metadata.fileTemplateName, fileNameVariables),
generateFileName(templateRenderer.template.metadata.fileTemplateName, templateVariables),
);

try {
Expand All @@ -78,14 +83,13 @@ export const createFileFromTemplate = async (baseFolderUri: Uri): Promise<void>
if (actionSelected !== OVERWRITE_ACTION) { return; }
} catch (err) {
// Ignore FileNotFound.
if (err.code !== 'FileNotFound') { throw err; }
if (!(err instanceof FileSystemError && err.code === 'FileNotFound')) { throw err; }
}

await renderFile(
await templateRenderer.renderToFile(
fileUri,
template,
fileNameVariables,
[template],
templateVariables,
[templateRenderer.template],
);

await window.showTextDocument(fileUri);
Expand Down
41 changes: 25 additions & 16 deletions src/commands/createFilesFromTemplateGroup.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {
commands, Uri, window, workspace,
commands,
FileSystemError,
Uri,
window,
workspace,
} from 'vscode';

import { COMMANDS } from '../constants';
import { FolderType } from '../domain/config/types';
import { renderFile } from '../domain/renderer';
import { Template } from '../domain/templates/data/template';
import { TemplateRenderer } from '../domain/renderer/templateRenderer';
import { generateFileName } from '../domain/templates/data/template/utils';
import { TemplateGroup } from '../domain/templates/data/templateGoup';
import { templatesService } from '../domain/templates/services';
import { compact } from '../utils/array';

import { getGlobalTemplateGroupsQuickPickItems, getTemplateGroupsOfWorkspaceFolderQuickPickItems, promptUserForTemplatesVariablesValues } from './utils/templateGroups';

export const createFilesFromTemplateGroup = async (baseFolderUri: Uri): Promise<void> => {
Expand Down Expand Up @@ -58,22 +63,27 @@ export const createFilesFromTemplateGroup = async (baseFolderUri: Uri): Promise<
? templatesService.getGlobalTemplateById(templateId)
: templatesService.getTemplateOfWorkspaceFolderById(workspaceFolder.uri, templateId)
))),
);
).map((template) => new TemplateRenderer(template));

const templatesVariablesValues = await promptUserForTemplatesVariablesValues(
const variablesPerTemplates = await promptUserForTemplatesVariablesValues(
templateGroup.metadata.templatesUseSameVariables,
templatesOfGroup,
baseFolderUri,
);

if (!templatesVariablesValues) { return; }
if (!variablesPerTemplates) { return; }

const filesUris = await Promise.all(templatesOfGroup.map(
async (template): Promise<{ template: Template, fileUri: Uri, exists: boolean }> => {
const { fileTemplateName, id } = template.metadata;
async (templateRenderer): Promise<{
templateRenderer: TemplateRenderer;
fileUri: Uri;
exists: boolean;
}> => {
const { fileTemplateName, id } = templateRenderer.template.metadata;

const fileUri = Uri.joinPath(
baseFolderUri,
generateFileName(fileTemplateName, templatesVariablesValues[id]),
generateFileName(fileTemplateName, variablesPerTemplates[id]),
);

let exists = false;
Expand All @@ -82,14 +92,14 @@ export const createFilesFromTemplateGroup = async (baseFolderUri: Uri): Promise<
await workspace.fs.stat(fileUri);
exists = true;
} catch (err) {
if (err.code === 'FileNotFound') {
if (err instanceof FileSystemError && err.code === 'FileNotFound') {
exists = false;
} else {
throw err;
}
}

return { template, fileUri, exists };
return { templateRenderer, fileUri, exists };
},
));

Expand All @@ -111,12 +121,11 @@ export const createFilesFromTemplateGroup = async (baseFolderUri: Uri): Promise<
}

// Create each file.
await Promise.all(filesUris.map(({ template, fileUri }) => (
renderFile(
await Promise.all(filesUris.map(({ templateRenderer, fileUri }) => (
templateRenderer.renderToFile(
fileUri,
template,
templatesVariablesValues[template.metadata.id],
templatesOfGroup,
variablesPerTemplates[templateRenderer.template.metadata.id],
templatesOfGroup.map(({ template }) => template),
)
)));

Expand Down
3 changes: 2 additions & 1 deletion src/commands/createTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { window } from 'vscode';

import { Template } from '../domain/templates/data/template';
import { FolderType } from '../domain/config/types';
import { Template } from '../domain/templates/data/template';
import { templatesService } from '../domain/templates/services';

import { FolderQuickPickItem, getCreateTemplateFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import { showFileTemplateNameInputBox, showOnlyAsPartOfGroupQuickPick, showTemplateNameInputBox } from './utils/templates';

Expand Down
1 change: 1 addition & 0 deletions src/commands/createTemplateGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { window } from 'vscode';
import { FolderType } from '../domain/config/types';
import { TemplateGroup } from '../domain/templates/data/templateGoup';
import { templatesService } from '../domain/templates/services';

import { FolderQuickPickItem, getCreateTemplateGroupFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import { askUserToCreateTemplate, showTemplateGroupNameInputBox, showTemplatesUseSameVariablesQuickPick } from './utils/templateGroups';
import { getTemplateQuickPickItemsOfSelectedFolder, mapTemplateToQuickPickItem } from './utils/templates';
Expand Down
1 change: 1 addition & 0 deletions src/commands/editTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { commands, window } from 'vscode';

import { COMMANDS } from '../constants';
import { Template } from '../domain/templates/data/template';

import { getTemplateFoldersQuickPickItems } from './utils/folders';
import { getTemplateQuickPickItemsOfSelectedFolder } from './utils/templates';

Expand Down
3 changes: 2 additions & 1 deletion src/commands/editTemplateGroupMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { window } from 'vscode';

import { FolderType } from '../domain/config/types';
import { templatesService } from '../domain/templates/services';

import { getTemplateGroupFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import { getTemplateQuickPickItemsOfSelectedFolder, mapTemplateToQuickPickItem } from './utils/templates';
import {
askUserToCreateTemplate,
askUserToCreateTemplateGroup,
getTemplateGroupQuickPickItemsOfSelectedFolder,
showTemplateGroupNameInputBox,
showTemplatesUseSameVariablesQuickPick,
} from './utils/templateGroups';
import { getTemplateQuickPickItemsOfSelectedFolder, mapTemplateToQuickPickItem } from './utils/templates';

export const editTemplateGroupMetadata = async (): Promise<void> => {
const foldersQuickPickItems = getTemplateGroupFoldersQuickPickItems();
Expand Down
3 changes: 2 additions & 1 deletion src/commands/editTemplateMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { commands, window } from 'vscode';
import { COMMANDS } from '../constants';

import { COMMANDS } from '../constants';
import { FolderType } from '../domain/config/types';
import { templatesService } from '../domain/templates/services';

import { getTemplateFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import {
getTemplateQuickPickItemsOfSelectedFolder,
Expand Down
1 change: 1 addition & 0 deletions src/commands/removeTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { window } from 'vscode';

import { FolderType } from '../domain/config/types';
import { templatesService } from '../domain/templates/services';

import { getTemplateFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import { getTemplateQuickPickItemsOfSelectedFolder } from './utils/templates';

Expand Down
1 change: 1 addition & 0 deletions src/commands/removeTemplateGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { window } from 'vscode';

import { FolderType } from '../domain/config/types';
import { templatesService } from '../domain/templates/services';

import { getTemplateGroupFoldersQuickPickItems, WorkspaceFolderQuickPickItem } from './utils/folders';
import { getTemplateGroupQuickPickItemsOfSelectedFolder } from './utils/templateGroups';

Expand Down
Loading

0 comments on commit bfe64af

Please sign in to comment.