Skip to content

Commit 71aade9

Browse files
authored
fix(transloco): fixed file matching on Windows OS (#797)
1 parent e327f3b commit 71aade9

File tree

2 files changed

+93
-63
lines changed

2 files changed

+93
-63
lines changed

libs/transloco-schematics/src/migrate/ngx-translate-migration.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,20 @@ export function run(path) {
100100
const serviceCallRgx = ({ map, func }) =>
101101
new RegExp(
102102
`(?:(?:\\s*|this\\.)${sanitizedName})(?:\\s*\\t*\\r*\\n*)*\\.(?:\\s*\\t*\\r*\\n*)*(${getTarget(
103-
map
103+
map,
104104
)})[\\r\\t\\n\\s]*${func ? '\\(' : '(?!\\()'}`,
105-
'g'
105+
'g',
106106
);
107107
const getTarget = (t) => Object.keys(t).join('|');
108108
return [
109109
{ func: true, map: functionsMap },
110110
{ func: false, map: propsMap },
111111
].reduce((acc, curr) => {
112112
return acc.replace(serviceCallRgx(curr), (str) =>
113-
str.replace(new RegExp(getTarget(curr.map)), (func) => curr.map[func])
113+
str.replace(
114+
new RegExp(getTarget(curr.map)),
115+
(func) => curr.map[func],
116+
),
114117
);
115118
}, match);
116119
},
@@ -158,14 +161,21 @@ export function run(path) {
158161
async function migrate(matchersArr, filesType) {
159162
console.log(`\nMigrating ${filesType} files 📜`);
160163
let spinner;
164+
const isWindows = process.platform === 'win32';
165+
161166
for (let i = 0; i < matchersArr.length; i++) {
162167
const { step, matchers } = matchersArr[i];
163168
const msg = `Step ${i + 1}/${matchersArr.length}: Migrating ${step}`;
164169
spinner = ora().start(msg);
165170
const noFilesFound = [];
166171
for (const matcher of matchers) {
167172
try {
168-
await replaceInFile(matcher);
173+
await replaceInFile({
174+
...matcher,
175+
glob: {
176+
windowsPathsNoEscape: isWindows,
177+
},
178+
});
169179
} catch (e) {
170180
if (e.message.includes('No files match the pattern')) {
171181
noFilesFound.push(e.message);
@@ -176,7 +186,7 @@ export function run(path) {
176186
}
177187
spinner.succeed(msg);
178188
noFilesFound.forEach((pattern) =>
179-
console.log('\x1b[33m%s\x1b[0m', `⚠️ ${pattern}`)
189+
console.log('\x1b[33m%s\x1b[0m', `⚠️ ${pattern}`),
180190
);
181191
}
182192
}
@@ -187,7 +197,7 @@ export function run(path) {
187197
console.log('\n 🌵 Done! 🌵');
188198
console.log('Welcome to a better translation experience 🌐');
189199
console.log(
190-
'\nFor more information about this script please visit 👉 https://jsverse.github.io/transloco/docs/migration/ngx\n'
200+
'\nFor more information about this script please visit 👉 https://jsverse.github.io/transloco/docs/migration/ngx\n',
191201
);
192202
});
193203
}
Lines changed: 77 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,57 @@
11
// noinspection AngularUndefinedBinding
22

33
import * as nodePath from 'node:path';
4-
import {readFile} from 'node:fs/promises';
4+
import { readFile } from 'node:fs/promises';
55

6-
import {replaceInFile, ReplaceInFileConfig} from 'replace-in-file';
7-
import {glob} from 'glob';
6+
import { replaceInFile, ReplaceInFileConfig } from 'replace-in-file';
7+
import { glob } from 'glob';
88

9-
import {PIPE_IN_BINDING_REGEX, PIPE_REGEX, run} from '../migrate/ngx-translate-migration';
9+
import {
10+
PIPE_IN_BINDING_REGEX,
11+
PIPE_REGEX,
12+
run,
13+
} from '../migrate/ngx-translate-migration';
1014

1115
jest.mock('replace-in-file');
1216

1317
describe('ngx-translate migration', () => {
14-
1518
describe('Positive regex tests', () => {
16-
1719
describe('Pipe in binding', () => {
1820
test.each([
1921
{
2022
testCase: `<component [header]="'hello.world' | translate">`,
21-
match: [`]="'hello.world' | translate"`]
23+
match: [`]="'hello.world' | translate"`],
2224
},
2325
{
2426
testCase: `<component [header]="'hello.world' | translate | anotherPipe">`,
25-
match: [`]="'hello.world' | translate | anotherPipe"`]
27+
match: [`]="'hello.world' | translate | anotherPipe"`],
2628
},
2729
{
2830
testCase: `<component [header]="'hello' | translate:params | anotherPipe">`,
29-
match: [`]="'hello' | translate:params | anotherPipe"`]
31+
match: [`]="'hello' | translate:params | anotherPipe"`],
3032
},
3133
{
3234
testCase: `<component [title]="titleMap[reportType] | translate">`,
33-
match: [`]="titleMap[reportType] | translate"`]
35+
match: [`]="titleMap[reportType] | translate"`],
3436
},
3537
{
3638
testCase: `<component [matTooltip]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')">`,
37-
match: [`]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')"`]
39+
match: [
40+
`]="('foo.bar' | translate) + ': ' + (value | number: '1.0-2')"`,
41+
],
3842
},
3943
{
4044
testCase: `<compnent [title]="'Hello, ' + ('mom' | translate) | fooBar">`,
41-
match: [`]="'Hello, ' + ('mom' | translate) | fooBar"`]
45+
match: [`]="'Hello, ' + ('mom' | translate) | fooBar"`],
4246
},
4347
{
4448
testCase: `<edge-wizard-step [label]="'Restore Options' | translate" [validatingMessage]="'Processing archive...'|translate"`,
45-
match: [`]="'Restore Options' | translate"`, `]="'Processing archive...'|translate"`]
46-
}
47-
])('Case: $testCase; Match: $match', ({testCase, match}) => {
49+
match: [
50+
`]="'Restore Options' | translate"`,
51+
`]="'Processing archive...'|translate"`,
52+
],
53+
},
54+
])('Case: $testCase; Match: $match', ({ testCase, match }) => {
4855
const regex = new RegExp(PIPE_IN_BINDING_REGEX, 'gm');
4956
const result = testCase.match(regex);
5057

@@ -56,33 +63,35 @@ describe('ngx-translate migration', () => {
5663
test.each([
5764
{
5865
testCase: `<component>{{ "hello.world" | translate }}</component>`,
59-
match: [`{{ "hello.world" | translate }}`]
66+
match: [`{{ "hello.world" | translate }}`],
6067
},
6168
{
6269
testCase: `<component>{{ "hello.world" | translate | anotherPipe | oneMore }}</component>`,
63-
match: [`{{ "hello.world" | translate | anotherPipe | oneMore }}`]
70+
match: [`{{ "hello.world" | translate | anotherPipe | oneMore }}`],
6471
},
6572
{
6673
testCase: `<component>{{ "hello" | translate: { name: 'John' } }}</component>`,
67-
match: [`{{ "hello" | translate: { name: 'John' } }}`]
74+
match: [`{{ "hello" | translate: { name: 'John' } }}`],
6875
},
6976
{
7077
testCase: `<component>{{ titleMap[reportType] | translate }}</component>`,
71-
match: [`{{ titleMap[reportType] | translate }}`]
78+
match: [`{{ titleMap[reportType] | translate }}`],
7279
},
7380
{
7481
testCase: `<component>{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}</component>`,
75-
match: [`{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}`]
82+
match: [
83+
`{{ ('foo.bar' | translate) + ': ' + (value | number: '1.0-2') }}`,
84+
],
7685
},
7786
{
7887
testCase: `<compnent>{{ 'Hello, ' + ('mom' | translate) | fooBar }}</compnent>`,
79-
match: [`{{ 'Hello, ' + ('mom' | translate) | fooBar }}`]
88+
match: [`{{ 'Hello, ' + ('mom' | translate) | fooBar }}`],
8089
},
8190
{
8291
testCase: `{{"1" | translate}} {{errorCounter}} {{"2" | translate}}`,
83-
match: [`{{"1" | translate}}`, `{{"2" | translate}}`]
84-
}
85-
])('Case: $testCase; Match: $match', ({testCase, match}) => {
92+
match: [`{{"1" | translate}}`, `{{"2" | translate}}`],
93+
},
94+
])('Case: $testCase; Match: $match', ({ testCase, match }) => {
8695
const regex = new RegExp(PIPE_REGEX, 'gm');
8796
const result = testCase.match(regex);
8897

@@ -92,106 +101,117 @@ describe('ngx-translate migration', () => {
92101
});
93102

94103
describe('Negative regex tests', () => {
95-
96104
describe('Pipe in binding', () => {
97105
test.each([
98106
{
99-
testCase: `<component [header]="'hello.world' | transloco">`
107+
testCase: `<component [header]="'hello.world' | transloco">`,
100108
},
101109
{
102-
testCase: `<component [header]="'hello.world' | somePipe | anotherPipe">`
110+
testCase: `<component [header]="'hello.world' | somePipe | anotherPipe">`,
103111
},
104112
{
105-
testCase: `<component [header]="'hello' | transloco:params | anotherPipe">`
113+
testCase: `<component [header]="'hello' | transloco:params | anotherPipe">`,
106114
},
107115
{
108-
testCase: `<component [title]="titleMap[reportType] | fooBar">`
116+
testCase: `<component [title]="titleMap[reportType] | fooBar">`,
109117
},
110118
{
111-
testCase: `<component [matTooltip]="('foo.bar' | transloco) + ': ' + (value | number: '1.0-2')">`
119+
testCase: `<component [matTooltip]="('foo.bar' | transloco) + ': ' + (value | number: '1.0-2')">`,
112120
},
113121
{
114-
testCase: `<compnent [title]="'Hello World ' + ('mom' | transloco) | fooBar">`
122+
testCase: `<compnent [title]="'Hello World ' + ('mom' | transloco) | fooBar">`,
115123
},
116124
{
117125
testCase: `<a [title]="'admin.1' | lowercase
118126
| translate"
119-
</a>`
120-
}
121-
])('Case: $testCase', ({testCase}) => {
127+
</a>`,
128+
},
129+
])('Case: $testCase', ({ testCase }) => {
122130
const regex = new RegExp(PIPE_IN_BINDING_REGEX, 'gm');
123131
const result = testCase.match(regex);
124132

125133
expect(result).toBeNull();
126134
});
127135
});
128-
136+
129137
describe('Pipe', () => {
130138
test.each([
131139
{
132-
testCase: `<component>{{ "hello.world" | transloco }}</component>`
140+
testCase: `<component>{{ "hello.world" | transloco }}</component>`,
133141
},
134142
{
135-
testCase: `<component>{{ "hello.world" | transloco | anotherPipe | oneMore }}</component>`
143+
testCase: `<component>{{ "hello.world" | transloco | anotherPipe | oneMore }}</component>`,
136144
},
137145
{
138-
testCase: `<component>{{ "hello" | transloco: { name: 'John' } }}</component>`
146+
testCase: `<component>{{ "hello" | transloco: { name: 'John' } }}</component>`,
139147
},
140148
{
141-
testCase: `<component>{{ titleMap[reportType] | somePipe }}</component>`
149+
testCase: `<component>{{ titleMap[reportType] | somePipe }}</component>`,
142150
},
143151
{
144-
testCase: `<component>{{ ('foo.bar' | transloco) + ': ' + (value | number: '1.0-2') }}</component>`
152+
testCase: `<component>{{ ('foo.bar' | transloco) + ': ' + (value | number: '1.0-2') }}</component>`,
145153
},
146154
{
147-
testCase: `<compnent>{{ 'Hello, ' + ('mom' | transloco) | fooBar }}</compnent>`
148-
}
149-
])('Case: $testCase', ({testCase}) => {
155+
testCase: `<compnent>{{ 'Hello, ' + ('mom' | transloco) | fooBar }}</compnent>`,
156+
},
157+
])('Case: $testCase', ({ testCase }) => {
150158
const regex = new RegExp(PIPE_REGEX, 'gm');
151159
const result = testCase.match(regex);
152160

153161
expect(result).toBeNull();
154162
});
155163
});
156-
157164
});
158165

159166
describe('HTML template', () => {
160-
161167
it('should replace html template content', async () => {
162168
const replacements: Record<string, string> = {},
163169
isWindows = process.platform === 'win32';
164-
170+
165171
(replaceInFile as unknown as jest.Mock).mockImplementation(
166172
async (config: ReplaceInFileConfig): Promise<void> => {
167173
const path = config.files as string,
168174
regex = config.from as RegExp,
169175
replacer = config.to as (match: string) => string;
170-
171-
const files = await glob(path, {windowsPathsNoEscape: isWindows});
172-
176+
177+
const files = await glob(path, { windowsPathsNoEscape: isWindows });
178+
173179
for (const fullPath of files) {
174180
const filename = nodePath.parse(fullPath).base,
175-
content = replacements[filename] ?? await readFile(fullPath, {encoding: 'utf-8'});
176-
181+
content =
182+
replacements[filename] ??
183+
(await readFile(fullPath, { encoding: 'utf-8' }));
184+
177185
replacements[filename] = content.replace(regex, replacer);
178186
}
179-
}
187+
},
180188
);
181189

182-
const ngxTranslateTemplatePath = './src/tests/templates/pipes/ngx-translate';
190+
const ngxTranslateTemplatePath =
191+
'./src/tests/templates/pipes/ngx-translate';
183192

184193
await run(ngxTranslateTemplatePath);
185194

195+
expect(replaceInFile).toHaveBeenLastCalledWith(
196+
expect.objectContaining({
197+
glob: {
198+
windowsPathsNoEscape: isWindows,
199+
},
200+
}),
201+
);
202+
186203
const filenames = Object.keys(replacements);
187204

188-
for(const filename of filenames) {
189-
const resultPath = nodePath.join(__dirname, './templates/pipes/transloco', filename),
190-
resultContent = await readFile(resultPath, {encoding: 'utf-8'});
205+
for (const filename of filenames) {
206+
const resultPath = nodePath.join(
207+
__dirname,
208+
'./templates/pipes/transloco',
209+
filename,
210+
),
211+
resultContent = await readFile(resultPath, { encoding: 'utf-8' });
191212

192213
expect(replacements[filename]).toBe(resultContent);
193214
}
194215
});
195-
196216
});
197217
});

0 commit comments

Comments
 (0)