Skip to content

Latest commit

 

History

History
191 lines (137 loc) · 5.19 KB

02-create-static-files.md

File metadata and controls

191 lines (137 loc) · 5.19 KB

Create static files

Our codemod will support workspaces. For us, this means, a project that includes 1 addon and 1 test app, or many addons and equally many test apps.

workspace-root
├── packages
│   ├── addon-1
│   ├── ...
│   └── addon-n
└── tests
    ├── test-app-for-addon-1
    ├── ...
    └── test-app-for-addon-n

We learned in the previous chapter that,

  • The blueprints folder contains blueprint files, which we use to create files that our end-developers (users) will have.
  • The blueprintsRoot variable represents where the blueprint files will be saved on their machine.

Let's look at how we can create files from blueprints.

Goals:

  • Take small steps
  • Read and write blueprint files

Add blueprint files

We'll start by creating 1 file for the addon and 1 file for the test app. Both files are static (the file content never changes). In other words, there's nothing dynamic (e.g. string interpolations, conditional statements, for-loops) that would make the first step complex.

Copy-paste the following starter code:

src/blueprints/__addonLocation__/package.json
{
  "name": "addon-1",
  "version": "0.0.0"
}
src/blueprints/__testAppLocation__/package.json
{
  "name": "test-app-for-addon-1",
  "version": "0.0.0"
}

Then, scaffold a step called create-files-from-blueprints. Use findFiles() from @codemod-utils/files to find the blueprint files, then log the file paths.

Note

Need a refresher on findFiles()? Don't forget to run tests to check your code.

❯ pnpm test

[
  '__addonLocation__/package.json',
  '__testAppLocation__/package.json'
]
Solution: src/steps/create-files-from-blueprints.ts

Note, the project root for findFiles() points to blueprintsRoot, not options.projectRoot.

import { findFiles } from '@codemod-utils/files';

import type { Options } from '../types/index.js';
import { blueprintsRoot } from '../utils/blueprints.js';

export function createFilesFromBlueprints(options: Options): void {
  const blueprintFilePaths = findFiles('**/*', {
    projectRoot: blueprintsRoot,
  });

  console.log(blueprintFilePaths);
}
Solution: src/steps/index.ts
+ export * from './create-files-from-blueprints.js';
export * from './create-options.js';
Solution: src/index.ts
- import { createOptions } from './steps/index.js';
+ import { createFilesFromBlueprints, createOptions } from './steps/index.js';
import type { CodemodOptions } from './types/index.js';

export function runCodemod(codemodOptions: CodemodOptions): void {
  const options = createOptions(codemodOptions);

-   // ...
+   createFilesFromBlueprints(options);
}

Read and write blueprint files

Unlike in the main tutorial, we won't use writeFileSync() from Node.js to create files. The reason is, the folders where files will be created (i.e. folders named __addonLocation__ and __testAppLocation__) don't exist on the user's machine.

Luckily, @codemod-utils/files provides createFiles(), which creates missing folders as needed. We just need to provide this function a Map, which maps a blueprint's file path to its file content.

Solution: src/steps/create-files-from-blueprints.ts
- import { findFiles } from '@codemod-utils/files';
+ import { readFileSync } from 'node:fs';
+ import { join } from 'node:path';
+
+ import { createFiles, findFiles } from '@codemod-utils/files';

import type { Options } from '../types/index.js';
import { blueprintsRoot } from '../utils/blueprints.js';

export function createFilesFromBlueprints(options: Options): void {
  const blueprintFilePaths = findFiles('**/*', {
    projectRoot: blueprintsRoot,
  });

-   console.log(blueprintFilePaths);
+   const fileMap = new Map(
+     blueprintFilePaths.map((blueprintFilePath) => {
+       const blueprintFile = readFileSync(
+         join(blueprintsRoot, blueprintFilePath),
+         'utf8',
+       );
+ 
+       return [blueprintFilePath, blueprintFile];
+     }),
+   );
+ 
+   createFiles(fileMap, options);
}

To see the effect of create-files-from-blueprints, run ./update-test-fixtures.sh, then check the sample-project's output folder. You will see that we're already a few steps closer to creating the addon and the test app. ✨

workspace-root
├── __addonLocation__
│   └── package.json
└── __testAppLocation__
    └── package.json