Skip to content

Commit 67363b2

Browse files
committed
chore: Documented how to support Windows
1 parent f8eaf38 commit 67363b2

File tree

11 files changed

+396
-58
lines changed

11 files changed

+396
-58
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ npx @codemod-utils/cli <your-codemod-name>
3131

3232
- [Main tutorial](./tutorials/main-tutorial/00-introduction.md)
3333
- [Create blueprints](./tutorials/create-blueprints/00-introduction.md)
34+
- [Support Windows](./tutorials/support-windows/00-introduction.md)
3435
- [Update CSS files](./tutorials/update-css-files/00-introduction.md)
3536
- [Update `<template>` tags](./tutorials/update-template-tags/00-introduction.md)
3637

packages/tests/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ In the example above (an "acceptance" test), `inputProject` and `outputProject`
9494
<summary>Example</summary>
9595

9696
```ts
97-
const oldFile = createFile([
97+
const oldFile = normalizeFile([
9898
`import Component from '@glimmer/component';`,
9999
``,
100100
`export default class Hello extends Component {}`,
@@ -105,7 +105,7 @@ const newFile = transform(oldFile);
105105

106106
assert.strictEqual(
107107
newFile,
108-
createFile([
108+
normalizeFile([
109109
`import Component from '@glimmer/component';`,
110110
``,
111111
`import styles from './hello.module.css';`,

tutorials/create-blueprints/03-define-options.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ See if you can complete the starter code shown above. The requirements are:
282282
<summary>Solution: <code>src/steps/create-options.ts</code></summary>
283283

284284
```diff
285-
+ import { join } from 'node:path';
285+
+ import { join, sep } from 'node:path';
286286
+
287287
import type { CodemodOptions, Options } from '../types/index.js';
288288

@@ -296,12 +296,12 @@ export function createOptions(codemodOptions: CodemodOptions): Options {
296296

297297
return {
298298
+ addon: {
299-
+ location: join('packages', addonLocation),
299+
+ location: join('packages', addonLocation).replaceAll(sep, '/'),
300300
+ name: addonName,
301301
+ },
302302
projectRoot,
303303
+ testApp: {
304-
+ location: join('tests', addonLocation),
304+
+ location: join('tests', addonLocation).replaceAll(sep, '/'),
305305
+ name: `test-app-for-${dasherize(addonName)}`,
306306
+ },
307307
};

tutorials/main-tutorial/05-step-1-update-acceptance-tests-part-2.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,11 +594,14 @@ Currently, `data.moduleName` is hard-coded. We can derive the test module name f
594594
595595
<summary>Solution: <code>src/steps/rename-acceptance-tests.ts</code></summary>
596596
597+
It's important to note that Windows uses `\` as the file separator, while the entity name uses `/` (independently of the operating system). We can use `relative()` and `sep` to normalize values.
598+
597599
The implementation for `renameModule()` remains unchanged and has been hidden for simplicity.
598600
599601
```diff
600602
import { readFileSync, writeFileSync } from 'node:fs';
601-
import { join } from 'node:path';
603+
- import { join } from 'node:path';
604+
+ import { join, relative, sep } from 'node:path';
602605

603606
import { AST } from '@codemod-utils/ast-javascript';
604607
- import { findFiles } from '@codemod-utils/files';
@@ -614,10 +617,10 @@ type Data = {
614617
+ function getModuleName(filePath: string): string {
615618
+ let { dir, name } = parseFilePath(filePath);
616619
+
617-
+ dir = dir.replace(/^tests\/acceptance(\/)?/, '');
620+
+ dir = relative('tests/acceptance', dir);
618621
+ name = name.replace(/-test$/, '');
619622
+
620-
+ const entityName = join(dir, name);
623+
+ const entityName = join(dir, name).replaceAll(sep, '/');
621624
+
622625
+ // a.k.a. friendlyTestDescription
623626
+ return ['Acceptance', entityName].join(' | ');

tutorials/main-tutorial/06-step-2-update-integration-tests.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ type Data = {
120120
function getModuleName(filePath: string): string {
121121
let { dir, name } = parseFilePath(filePath);
122122

123-
dir = dir.replace(/^tests\/acceptance(\/)?/, '');
123+
dir = relative('tests/acceptance', dir);
124124
name = name.replace(/-test$/, '');
125125

126-
const entityName = join(dir, name);
126+
const entityName = join(dir, name).replaceAll(sep, '/');
127127

128128
// a.k.a. friendlyTestDescription
129129
return ['Acceptance', entityName].join(' | ');
@@ -179,7 +179,7 @@ I highlighted only how `getModuleName()` and `renameModule()` differ between `re
179179

180180
```diff
181181
import { readFileSync, writeFileSync } from 'node:fs';
182-
import { join } from 'node:path';
182+
import { join, relative, sep } from 'node:path';
183183

184184
import { AST } from '@codemod-utils/ast-javascript';
185185
import { findFiles, parseFilePath } from '@codemod-utils/files';
@@ -194,11 +194,11 @@ type Data = {
194194
function getModuleName(filePath: string): string {
195195
let { dir, name } = parseFilePath(filePath);
196196

197-
- dir = dir.replace(/^tests\/acceptance(\/)?/, '');
198-
+ dir = dir.replace(/^tests\/integration(\/)?/, '');
197+
- dir = relative('tests/acceptance', dir);
198+
+ dir = relative('tests/integration', dir);
199199
name = name.replace(/-test$/, '');
200200

201-
const entityName = join(dir, name);
201+
const entityName = join(dir, name).replaceAll(sep, '/');
202202

203203
// a.k.a. friendlyTestDescription
204204
- return ['Acceptance', entityName].join(' | ');
@@ -339,10 +339,10 @@ We say that an [iterative method](https://en.wikipedia.org/wiki/Iterative_method
339339
function getModuleName(filePath: string): string {
340340
let { dir, name } = parseFilePath(filePath);
341341
342-
dir = dir.replace(/^tests\/integration(\/)?/, '');
342+
dir = relative('tests/integration', dir);
343343
name = name.replace(/-test$/, '');
344344
345-
const entityName = join(dir, name);
345+
const entityName = join(dir, name).replaceAll(sep, '/');
346346
347347
// a.k.a. friendlyTestDescription
348348
return ['Integration', entityName].join(' | ');
@@ -355,7 +355,7 @@ Let's correct the overshoot by adding the entity type (here, we represent it as
355355
function getModuleName(filePath: string): string {
356356
let { dir, name } = parseFilePath(filePath);
357357
358-
dir = dir.replace(/^tests\/integration(\/)?/, '');
358+
dir = relative('tests/integration', dir);
359359
name = name.replace(/-test$/, '');
360360
361361
const entityType = /* ... */;
@@ -387,6 +387,8 @@ const entityName = join(remainingPath, name);
387387
Let me first show you the solution for `parseEntity()`, then explain the particular approach.
388388
389389
```ts
390+
import { sep } from 'node:path';
391+
390392
const folderToEntityType = new Map([
391393
['components', 'Component'],
392394
['helpers', 'Helper'],
@@ -397,12 +399,12 @@ function parseEntity(dir: string): {
397399
entityType: string | undefined;
398400
remainingPath: string;
399401
} {
400-
const [folder, ...remainingPaths] = dir.split('/');
402+
const [folder, ...remainingPaths] = dir.split(sep);
401403
const entityType = folderToEntityType.get(folder!);
402404
403405
return {
404406
entityType,
405-
remainingPath: remainingPaths.join('/'),
407+
remainingPath: remainingPaths.join(sep),
406408
};
407409
}
408410
```
@@ -419,7 +421,7 @@ The implementations for `renameModule()` and `renameIntegrationTests()` remain u
419421
420422
```diff
421423
import { readFileSync, writeFileSync } from 'node:fs';
422-
import { join } from 'node:path';
424+
import { join, relative, sep } from 'node:path';
423425
424426
import { AST } from '@codemod-utils/ast-javascript';
425427
import { findFiles, parseFilePath } from '@codemod-utils/files';
@@ -441,24 +443,24 @@ type Data = {
441443
+ entityType: string | undefined;
442444
+ remainingPath: string;
443445
+ } {
444-
+ const [folder, ...remainingPaths] = dir.split('/');
446+
+ const [folder, ...remainingPaths] = dir.split(sep);
445447
+ const entityType = folderToEntityType.get(folder!);
446448
+
447449
+ return {
448450
+ entityType,
449-
+ remainingPath: remainingPaths.join('/'),
451+
+ remainingPath: remainingPaths.join(sep),
450452
+ };
451453
+ }
452454
+
453455
function getModuleName(filePath: string): string {
454456
let { dir, name } = parseFilePath(filePath);
455457
456-
dir = dir.replace(/^tests\/integration(\/)?/, '');
458+
dir = relative('tests/integration', dir);
457459
name = name.replace(/-test$/, '');
458460
459-
- const entityName = join(dir, name);
461+
- const entityName = join(dir, name).replaceAll(sep, '/');
460462
+ const { entityType, remainingPath } = parseEntity(dir);
461-
+ const entityName = join(remainingPath, name);
463+
+ const entityName = join(remainingPath, name).replaceAll(sep, '/');
462464
463465
// a.k.a. friendlyTestDescription
464466
- return ['Integration', entityName].join(' | ');

tutorials/main-tutorial/07-step-3-update-unit-tests.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Note that, because `'instance-initializers'` and `'utils'` need to be mapped to
2323

2424
```diff
2525
import { readFileSync, writeFileSync } from 'node:fs';
26-
import { join } from 'node:path';
26+
import { join, relative, sep } from 'node:path';
2727

2828
import { AST } from '@codemod-utils/ast-javascript';
2929
import { findFiles, parseFilePath } from '@codemod-utils/files';
@@ -57,24 +57,24 @@ function parseEntity(dir: string): {
5757
entityType: string | undefined;
5858
remainingPath: string;
5959
} {
60-
const [folder, ...remainingPaths] = dir.split('/');
60+
const [folder, ...remainingPaths] = dir.split(sep);
6161
const entityType = folderToEntityType.get(folder!);
6262

6363
return {
6464
entityType,
65-
remainingPath: remainingPaths.join('/'),
65+
remainingPath: remainingPaths.join(sep),
6666
};
6767
}
6868

6969
function getModuleName(filePath: string): string {
7070
let { dir, name } = parseFilePath(filePath);
7171

72-
- dir = dir.replace(/^tests\/integration(\/)?/, '');
73-
+ dir = dir.replace(/^tests\/unit(\/)?/, '');
72+
- dir = relative('tests/integration', dir);
73+
+ dir = relative('tests/unit', dir);
7474
name = name.replace(/-test$/, '');
7575

7676
const { entityType, remainingPath } = parseEntity(dir);
77-
const entityName = join(remainingPath, name);
77+
const entityName = join(remainingPath, name).replaceAll(sep, '/');
7878

7979
// a.k.a. friendlyTestDescription
8080
- return ['Integration', entityType, entityName].join(' | ');

0 commit comments

Comments
 (0)