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

feat!: bundle template files as 1 json file #32

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ coverage/
tabtab/
test/tabtab.log
/types
/lib/templates/data.json
2 changes: 1 addition & 1 deletion examples/tabtab-test-complete/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const init = async () => {
console.error('shell argument is required');
return;
}
const completion = await tabtab.getCompletionScript({
const completion = tabtab.getCompletionScript({
name: 'tabtab-test',
completer: 'tabtab-test',
shell,
Expand Down
18 changes: 6 additions & 12 deletions lib/filename.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ const { COMPLETION_FILE_EXT } = require('./constants');
/**
* Get a template file name for the SHELL provided.
* @param {import('./constants').SupportedShell} shell
* @returns {String}
* @returns {typeof COMPLETION_FILE_EXT[import('./constants').SupportedShell]}
*/
const templateFileName = shell => {
const completionFileExt = shell => {
const ext = COMPLETION_FILE_EXT[shell];
if (!ext) {
throw new Error(`Unsupported shell: ${shell}`);
}
return `completion.${ext}`;
return ext;
};

/**
Expand All @@ -20,10 +20,7 @@ const templateFileName = shell => {
* @returns {String}
*/
const completionFileName = (name, shell) => {
const ext = COMPLETION_FILE_EXT[shell];
if (!ext) {
throw new Error(`Unsupported shell: ${shell}`);
}
const ext = completionFileExt(shell);
return `${name}.${ext}`;
};

Expand All @@ -33,15 +30,12 @@ const completionFileName = (name, shell) => {
* @returns {String}
*/
const tabtabFileName = shell => {
const ext = COMPLETION_FILE_EXT[shell];
if (!ext) {
throw new Error(`Unsupported shell: ${shell}`);
}
const ext = completionFileExt(shell);
return `__tabtab.${ext}`;
};

module.exports = {
templateFileName,
completionFileExt,
completionFileName,
tabtabFileName,
};
6 changes: 3 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ const getShellFromEnv = env => {
* @param {String} options.name - The package configured for completion
* @param {String} options.completer - The program the will act as the completer for the `name` program
* @param {SupportedShell} options.shell
* @returns {Promise.<String>}
* @returns {String}
*/
const getCompletionScript = async ({ name, completer, shell }) => {
const getCompletionScript = ({ name, completer, shell }) => {
if (!name) throw new TypeError('options.name is required');
if (!completer) throw new TypeError('options.completer is required');
if (!shell) throw new TypeError('options.shell is required');
const completionScriptContent = await installer.getCompletionScript({ name, completer, shell });
const completionScriptContent = installer.getCompletionScript({ name, completer, shell });
return completionScriptContent
}

Expand Down
21 changes: 6 additions & 15 deletions lib/installer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const path = require('path');
const untildify = require('untildify');
const { promisify } = require('util');
const { tabtabDebug, exists } = require('./utils');
const { SUPPORTED_SHELLS } = require('./constants')
const { SUPPORTED_SHELLS } = require('./constants');
const { getTemplate } = require('./templates');

const debug = tabtabDebug('tabtab:installer');

Expand All @@ -18,7 +19,6 @@ const {
} = require('./constants');

const {
templateFileName,
completionFileName,
tabtabFileName,
} = require('./filename');
Expand All @@ -27,14 +27,6 @@ const {
* @typedef {import('./constants').SupportedShell} SupportedShell
*/

/**
* Helper to return the correct script template based on the SHELL provided
*
* @param {SupportedShell} shell - Shell to base the check on, defaults to system shell.
* @returns {String} The template script content, defaults to Bash for shell we don't know yet
*/
const scriptFromShell = shell => path.join(__dirname, 'templates', templateFileName(shell));

/**
* Helper to return the expected location for SHELL config file, based on the
* provided shell value.
Expand Down Expand Up @@ -245,11 +237,10 @@ const writeToTabtabScript = async ({ name, shell }) => {
* @param {String} options.name - The package configured for completion
* @param {String} options.completer - The program the will act as the completer for the `name` program
* @param {SupportedShell} options.shell
* @returns {Promise.<String>}
* @returns {String}
*/
const getCompletionScript = async ({ name, completer, shell }) => {
const templatePath = scriptFromShell(shell);
const templateContent = await readFile(templatePath, 'utf8');
const getCompletionScript = ({ name, completer, shell }) => {
const templateContent = getTemplate(shell);
const scriptContent = templateContent
.replaceAll('{pkgname}', name)
.replaceAll('{completer}', completer)
Expand All @@ -274,7 +265,7 @@ const writeToCompletionScript = async ({ name, completer, shell }) => {
);

try {
const filecontent = await getCompletionScript({ name, completer, shell })
const filecontent = getCompletionScript({ name, completer, shell })
debug('Writing completion script to', filename);
await mkdir(path.dirname(filename), { recursive: true });
await writeFile(filename, filecontent);
Expand Down
19 changes: 19 additions & 0 deletions lib/templates/bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /usr/bin/env node
const fs = require('fs');
const path = require('path');

const templateFiles = fs.readdirSync(__dirname).filter(name => name.startsWith('completion.'));

/** @type {Record.<String, String>} */
const jsonData = {}

for (const templateFileName of templateFiles) {
const templateFilePath = path.join(__dirname, templateFileName);
const templateContent = fs.readFileSync(templateFilePath, 'utf-8');
const ext = templateFileName.replace('completion.', '');
jsonData[ext] = templateContent;
}

const jsonFilePath = path.join(__dirname, 'data.json');
const jsonText = JSON.stringify(jsonData);
fs.writeFileSync(jsonFilePath, jsonText);
13 changes: 13 additions & 0 deletions lib/templates/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { completionFileExt } = require('../filename');
const data = require('./data.json');

/**
*
* @param {import('../constants').SupportedShell} shell
* @returns {String}
*/
const getTemplate = shell => data[completionFileExt(shell)];

module.exports = {
getTemplate,
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
"node": ">=18"
},
"scripts": {
"test": "c8 mocha --timeout 5000",
"test": "pnpm bundle-templates && c8 mocha --timeout 5000",
"typecheck": "pnpm run build && tsc -p test --noEmit",
"build": "tsc -p lib",
"bundle-templates": "node lib/templates/bundle.js",
"build": "pnpm run bundle-templates && tsc -p lib",
"prepublishOnly": "pnpm run build",
"mocha": "mocha --timeout 5000",
"coverage": "c8 report --reporter=text-lcov | coveralls",
Expand Down
4 changes: 2 additions & 2 deletions test/getCompletionScript.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const { COMPLETION_FILE_EXT } = require('../lib/constants');

describe('getCompletionScript gets the right completion script for', () => {
for (const shell of SUPPORTED_SHELLS) {
it(shell, async () => {
const received = await getCompletionScript({
it(shell, () => {
const received = getCompletionScript({
name: 'foo',
completer: 'foo-complete',
shell
Expand Down
1 change: 1 addition & 0 deletions tsconfig.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"module": "Node16",
"strictNullChecks": true,
"target": "ES2022",
"resolveJsonModule": true,
}
}
Loading