Skip to content

Commit

Permalink
Add .folder field to file object
Browse files Browse the repository at this point in the history
  • Loading branch information
dpilafian committed Apr 17, 2024
1 parent 96aaa2b commit ad38005
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 16 deletions.
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ _Find and replace strings, regex patterns, or template outputs in text files (CL

[![License:MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/center-key/replacer-util/blob/main/LICENSE.txt)
[![npm](https://img.shields.io/npm/v/replacer-util.svg)](https://www.npmjs.com/package/replacer-util)
[![Build](https://github.com/center-key/replacer-util/workflows/build/badge.svg)](https://github.com/center-key/replacer-util/actions/workflows/run-spec-on-push.yaml)
[![Build](https://github.com/center-key/replacer-util/actions/workflows/run-spec-on-push.yaml/badge.svg)](https://github.com/center-key/replacer-util/actions/workflows/run-spec-on-push.yaml)

**replacer-util** searches for text to substitute with a replacement string or with values from your project's **package.json** file, such as the project version number. 
It can also insert path metadata and concatenate output to generate content such as a file of HTML links. 
**LiquidJS** powers the template outputs and enables **replacer-util** to act as a static site generator complete with filter formatters and `render` tags for including partials. 

<img src=https://raw.githubusercontent.com/center-key/replacer-util/main/screenshot.png
Expand Down Expand Up @@ -146,16 +147,19 @@ const msg2: string = 'This file is: my-app.ts';
```

Example outputs and formatters:
| Source file text | Example output value | Note |
| ------------------------------ | ------------------------- | ---------------------------------------------- |
| `{{package.name}}` | `my-project` | Value from `name` field in **package.json** |
| `{{package.version}}` | `3.1.4` | Value from `version` field in **package.json** |
| `{{package.version\|size}}` | `5` | Length of the version number string |
| `{{file.name}}` | `password-reset` | Source filename without the file extension |
| `{{file.path}}` | `web/password-reset.html` | Full path to source file |
| `<a href={{webRoot}}>Home</a>` | `<a href=../..>Home</a>` | Link is relative to the source folder |
| `{{"now"\|date:"%Y-%m-%d"}}` | `2024-01-21` | Build date timestamp |
| `{{myVariable\|upcase}}` | `DARK MODE` | Custom variable set with: `{% assign myVariable = 'dark mode' %}` |
| Source file text | Example output value | Note |
| ------------------------------ | ------------------------ | ---------------------------------------------- |
| `{{package.name}}` | `my-project` | Value from `name` field in **package.json** |
| `{{package.version}}` | `3.1.4` | Value from `version` field in **package.json** |
| `{{package.version\|size}}` | `5` | Length of the version number string |
| `{{file.path}}` | `src/web/sign-in.html` | Full path to source file |
| `{{file.folder}}` | `web` | Name of parent folder of the source file |
| `{{file.base}}` | `sign-in.html` | Source filename with the file extension |
| `{{file.name}}` | `sign-in` | Source filename without the file extension |
| `{{file.ext}}` | `.html` | File extension of the source file |
| `<a href={{webRoot}}>Home</a>` | `<a href=../..>Home</a>` | Link is relative to the source folder |
| `{{"now"\|date:"%Y-%m-%d"}}` | `2024-01-21` | Build date timestamp |
| `{{myVariable\|upcase}}` | `DARK MODE` | Custom variable set with: `{% assign myVariable = 'dark mode' %}` |

_**Note:** Use the `--no-liquid` flag if characters in your source files are inadvertently being interpreted as templating commands and causing errors._

Expand Down
3 changes: 2 additions & 1 deletion replacer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ const replacer = {
const parsedPath = path.parse(origin);
const dir = slash(parsedPath.dir);
const filePath = dir + '/' + slash(parsedPath.base);
return { ...parsedPath, dir: dir, path: filePath };
const folder = path.basename(dir);
return { ...parsedPath, dir: dir, folder: folder, path: filePath };
};
const getWebRoot = (origin: string) => {
const depth = origin.substring(source.length).split('/').length - 2;
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/target/bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions spec/fixtures/target/file-parts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
folder->source base->mock1.html name->mock1 ext->.html dir->spec/fixtures/source path->spec/fixtures/source/mock1.html
folder->source base->mock1.js name->mock1 ext->.js dir->spec/fixtures/source path->spec/fixtures/source/mock1.js
folder->source base->mock1.min.css name->mock1.min ext->.css dir->spec/fixtures/source path->spec/fixtures/source/mock1.min.css
folder->subfolder-a base->mock2.html name->mock2 ext->.html dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.html
folder->subfolder-a base->mock2.js name->mock2 ext->.js dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.js
folder->subfolder-a base->mock2.min.css name->mock2.min ext->.css dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.min.css
folder->subfolder-b base->mock3.html name->mock3 ext->.html dir->spec/fixtures/source/subfolder-b path->spec/fixtures/source/subfolder-b/mock3.html
folder->subfolder-bb base->mock4.html name->mock4 ext->.html dir->spec/fixtures/source/subfolder-b/subfolder-bb path->spec/fixtures/source/subfolder-b/subfolder-bb/mock4.html
2 changes: 1 addition & 1 deletion spec/fixtures/target/mock1.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ <h2>Find and replace strings or template outputs in text files (CLI tool designe
banner: '🔍🔍🔍 replacer-util v1.2.5 🔍🔍🔍',
description: 'Find and replace strings or template outputs in text files (CLI tool designed for use in npm package.json scripts)',
code: 'mock1',
file: '{"root":"","dir":"spec/fixtures/source","base":"mock1.html","ext":".html","name":"mock1","path":"spec/fixtures/source/mock1.html"}',
file: '{"root":"","dir":"spec/fixtures/source","base":"mock1.html","ext":".html","name":"mock1","folder":"source","path":"spec/fixtures/source/mock1.html"}',
year: '2024',
list1: 'A.I. module, A.I. module, A.I. module',
list2: 'A.I. module, iNsEcT, INSECT, A.I. module',
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/target/subfolder-a/mock2.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const info2 = {
banner: '🔍🔍🔍 replacer-util v1.2.5 🔍🔍🔍',
description: 'Find and replace strings or template outputs in text files (CLI tool designed for use in npm package.json scripts)',
code: 'mock2',
file: '{"root":"","dir":"spec/fixtures/source/subfolder-a","base":"mock2.js","ext":".js","name":"mock2","path":"spec/fixtures/source/subfolder-a/mock2.js"}',
file: '{"root":"","dir":"spec/fixtures/source/subfolder-a","base":"mock2.js","ext":".js","name":"mock2","folder":"subfolder-a","path":"spec/fixtures/source/subfolder-a/mock2.js"}',
year: '2024',
list1: 'A.I. module, A.I. module, A.I. module',
list2: 'A.I. module, iNsEcT, INSECT, A.I. module',
Expand Down
2 changes: 1 addition & 1 deletion spec/fixtures/target/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ <h2>Find and replace strings or template outputs in text files (CLI tool designe
banner: '🔍🔍🔍 replacer-util v1.2.5 🔍🔍🔍',
description: 'Find and replace strings or template outputs in text files (CLI tool designed for use in npm package.json scripts)',
code: 'mock1',
file: '{"root":"","dir":"spec/fixtures/source","base":"mock1.html","ext":".html","name":"mock1","path":"spec/fixtures/source/mock1.html"}',
file: '{"root":"","dir":"spec/fixtures/source","base":"mock1.html","ext":".html","name":"mock1","folder":"source","path":"spec/fixtures/source/mock1.html"}',
year: '2024',
list1: 'insect, insect, insect',
list2: 'insect, iNsEcT, INSECT, insect',
Expand Down
18 changes: 18 additions & 0 deletions spec/mocha.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,24 @@ describe('Executing the CLI', () => {
assertDeepStrictEqual(actual, expected);
});

it('to concatenate file metadata generates the correct list of file parts', () => {
const fileParts = ['folder', 'base', 'name', 'ext', 'dir', 'path'];
const template = fileParts.map(part => `${part}-{{gt}}{{file.${part}}}`).join('{{space}}');
run('replacer spec/fixtures/source spec/fixtures/target --content=' + template + ' --concat=file-parts.txt');
const actual = fs.readFileSync('spec/fixtures/target/file-parts.txt').toString().trim().split('\n');
const expected = [
'folder->source base->mock1.html name->mock1 ext->.html dir->spec/fixtures/source path->spec/fixtures/source/mock1.html',
'folder->source base->mock1.js name->mock1 ext->.js dir->spec/fixtures/source path->spec/fixtures/source/mock1.js',
'folder->source base->mock1.min.css name->mock1.min ext->.css dir->spec/fixtures/source path->spec/fixtures/source/mock1.min.css',
'folder->subfolder-a base->mock2.html name->mock2 ext->.html dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.html',
'folder->subfolder-a base->mock2.js name->mock2 ext->.js dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.js',
'folder->subfolder-a base->mock2.min.css name->mock2.min ext->.css dir->spec/fixtures/source/subfolder-a path->spec/fixtures/source/subfolder-a/mock2.min.css',
'folder->subfolder-b base->mock3.html name->mock3 ext->.html dir->spec/fixtures/source/subfolder-b path->spec/fixtures/source/subfolder-b/mock3.html',
'folder->subfolder-bb base->mock4.html name->mock4 ext->.html dir->spec/fixtures/source/subfolder-b/subfolder-bb path->spec/fixtures/source/subfolder-b/subfolder-bb/mock4.html',
];
assertDeepStrictEqual(actual, expected);
});

it('with --header and --concat flags creates the expected bundle file', () => {
run('replacer --cd=spec/fixtures source --ext=.js target --header=//{{bang}}\\ 👾:\\ {{file.base}} --concat=bundle.js');
const actual = ['bundle.js', fs.readdirSync('spec/fixtures/target')?.includes('bundle.js')];
Expand Down

0 comments on commit ad38005

Please sign in to comment.