Skip to content

Commit 6a9ab39

Browse files
committed
Modified file reader to only read codify.json files for now (this removes multi-file support for now)
1 parent 51ed202 commit 6a9ab39

5 files changed

Lines changed: 103 additions & 86 deletions

File tree

README.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,15 @@ describe the command here
4848

4949
```
5050
USAGE
51-
$ codify apply [FILE] [-f] [-n <value>]
51+
$ codify apply [FILE] [-f] [-n <value>] [-p <value>]
5252
5353
ARGUMENTS
5454
FILE file to read
5555
5656
FLAGS
5757
-f, --force
5858
-n, --name=<value> name to print
59+
-p, --path=<value> path to project
5960
6061
DESCRIPTION
6162
describe the command here
@@ -64,7 +65,8 @@ EXAMPLES
6465
$ codify apply
6566
```
6667

67-
_See code: [src/commands/apply.ts](https://github.com/kevinwang5658/codify/blob/v0.0.0/src/commands/apply.ts)_
68+
_See
69+
code: [src/commands/apply/index.ts](https://github.com/kevinwang5658/codify/blob/v0.0.0/src/commands/apply/index.ts)_
6870

6971
## `codify hello PERSON`
7072

@@ -114,10 +116,10 @@ Display help for codify.
114116

115117
```
116118
USAGE
117-
$ codify help [COMMANDS] [-n]
119+
$ codify help [COMMANDS...] [-n]
118120
119121
ARGUMENTS
120-
COMMANDS Command to show help for.
122+
COMMANDS... Command to show help for.
121123
122124
FLAGS
123125
-n, --nested-commands Include all nested commands in the output.
@@ -182,10 +184,10 @@ Installs a plugin into the CLI.
182184

183185
```
184186
USAGE
185-
$ codify plugins:install PLUGIN...
187+
$ codify plugins add plugins:install PLUGIN...
186188
187189
ARGUMENTS
188-
PLUGIN Plugin to install.
190+
PLUGIN... Plugin to install.
189191
190192
FLAGS
191193
-f, --force Run yarn install with force flag.
@@ -220,10 +222,10 @@ Displays installation properties of a plugin.
220222

221223
```
222224
USAGE
223-
$ codify plugins:inspect PLUGIN...
225+
$ codify plugins inspect PLUGIN...
224226
225227
ARGUMENTS
226-
PLUGIN [default: .] Plugin to inspect.
228+
PLUGIN... [default: .] Plugin to inspect.
227229
228230
FLAGS
229231
-h, --help Show CLI help.
@@ -247,10 +249,10 @@ Installs a plugin into the CLI.
247249

248250
```
249251
USAGE
250-
$ codify plugins:install PLUGIN...
252+
$ codify plugins install PLUGIN...
251253
252254
ARGUMENTS
253-
PLUGIN Plugin to install.
255+
PLUGIN... Plugin to install.
254256
255257
FLAGS
256258
-f, --force Run yarn install with force flag.
@@ -287,15 +289,15 @@ Links a plugin into the CLI for development.
287289

288290
```
289291
USAGE
290-
$ codify plugins:link PLUGIN
292+
$ codify plugins link PLUGIN
291293
292294
ARGUMENTS
293295
PATH [default: .] path to plugin
294296
295297
FLAGS
296-
-h, --help Show CLI help.
298+
-h, --help Show CLI help.
297299
-v, --verbose
298-
--[no-]install Install dependencies after linking the plugin.
300+
--[no-]install Install dependencies after linking the plugin.
299301
300302
DESCRIPTION
301303
Links a plugin into the CLI for development.
@@ -317,7 +319,7 @@ Removes a plugin from the CLI.
317319

318320
```
319321
USAGE
320-
$ codify plugins:uninstall PLUGIN...
322+
$ codify plugins remove plugins:uninstall PLUGIN...
321323
322324
ARGUMENTS
323325
PLUGIN plugin to uninstall
@@ -340,7 +342,7 @@ Removes a plugin from the CLI.
340342

341343
```
342344
USAGE
343-
$ codify plugins:uninstall PLUGIN...
345+
$ codify plugins uninstall PLUGIN...
344346
345347
ARGUMENTS
346348
PLUGIN plugin to uninstall
@@ -366,7 +368,7 @@ Removes a plugin from the CLI.
366368

367369
```
368370
USAGE
369-
$ codify plugins:uninstall PLUGIN...
371+
$ codify plugins unlink plugins:uninstall PLUGIN...
370372
371373
ARGUMENTS
372374
PLUGIN plugin to uninstall

src/orchestrators/plan.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ interface PlanOchestratorResponse {
1111
}
1212

1313
export const PlanOrchestrator = {
14-
async run(rootDirectory: string, destroyPlugins = true): Promise<PlanOchestratorResponse> {
15-
const project = await Parser.parseProject(rootDirectory);
14+
async run(path: string, destroyPlugins = true): Promise<PlanOchestratorResponse> {
15+
const project = await Parser.parseProject(path);
1616

1717
const pluginCollection = new PluginCollection();
1818
const dependencyMap = await pluginCollection.initialize(project);

src/parser/index.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
1+
import { ConfigBlock } from '../entities/index.js';
12
import { Project } from '../entities/project.js';
23
import { ProjectConfig } from '../entities/project-config.js';
34
import { ResourceConfig } from '../entities/resource-config.js';
45
import { InternalError } from '../utils/errors.js';
56
import { ConfigClass } from './language-definition.js';
67
import { FileParser } from './parser/index.js';
78
import { JsonFileParser } from './parser/json/file-parser.js';
8-
import { ProjectReader } from './reader/index.js';
9-
import { ConfigBlock } from '../entities/index.js';
9+
import { FileReader } from './reader/index.js';
1010

1111
export class Parser {
1212

1313
static readonly supportedParsers: Record<string, FileParser> = {
1414
'json': new JsonFileParser(),
1515
}
1616

17-
static async parseProject(directory: string): Promise<Project> {
18-
const configReader = new ProjectReader();
19-
const loadedProject = await configReader.readProject(directory);
17+
static async parseProject(path: string): Promise<Project> {
18+
const fileReader = new FileReader();
19+
const configFile = await fileReader.readConfigOrThrow(path);
2020

21-
const configBlocksResult = await Promise.all(loadedProject.files.map((file) => {
22-
const parser = Parser.supportedParsers[file.fileType];
23-
if (!parser) {
24-
throw new InternalError(`Unsupported file format loaded into parser: ${file.fileName}`);
25-
}
26-
27-
return parser.parse(file);
28-
}));
21+
const parser = Parser.supportedParsers[configFile.fileType];
22+
if (!parser) {
23+
throw new InternalError(`Unsupported file format loaded into parser: ${configFile.fileName}`);
24+
}
2925

30-
const configBlocks = configBlocksResult.flat(1);
26+
const configBlocks = await parser.parse(configFile);
3127
const projectConfig = Parser.findProjectConfig(configBlocks);
3228

3329
return new Project(

src/parser/reader/index.test.ts

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,67 @@
11
import mock from 'mock-fs';
2-
import { beforeEach, describe, it } from 'vitest';
3-
import { deepEqual, equal } from 'node:assert';
2+
import { beforeEach, describe, expect, it } from 'vitest';
43

5-
import { File } from './entities/file.js';
6-
import { ProjectReader } from './index.js';
4+
import { FileReader } from './index.js';
75

86
describe('Config loader tests', () => {
9-
let parser: ProjectReader;
7+
let fileReader: FileReader;
108

119
beforeEach(() => {
12-
parser = new ProjectReader();
10+
fileReader = new FileReader();
1311
})
1412

15-
it('it loads config files correctly', async () => {
13+
it('it loads codify.json files', async () => {
1614
const dir = 'path/to/fake/dir';
1715
mock({
1816
[dir]: {
19-
'homebrew.json': '[]',
20-
'nvm.json': '[]',
21-
'providers.json': '[]'
17+
'codify.json': '[]',
2218
}
2319
});
2420

25-
const project = await parser.readProject(dir);
26-
27-
equal(project.files.length, 3);
28-
equal(project.rootDirectory, dir);
29-
deepEqual(project.files[0], new File({
30-
contents: '[]',
31-
fileName: 'homebrew.json',
32-
fileType: 'json'
33-
}));
34-
deepEqual(project.files[1], new File({ contents: '[]', fileName: 'nvm.json', fileType: 'json' }));
35-
deepEqual(project.files[2], new File({
36-
contents: '[]',
37-
fileName: 'providers.json',
38-
fileType: 'json'
39-
}));
21+
const file = await fileReader.readConfigOrThrow(dir + '/codify.json');
22+
expect(file.fileName).eq('codify.json');
23+
expect(file.fileType).eq('json');
24+
expect(file.contents).eq('[]');
25+
mock.restore();
26+
})
27+
28+
it('it doesn\'t load other .json files', async () => {
29+
const dir = 'path/to/fake/dir';
30+
mock({
31+
[dir]: {
32+
'other.json': '[]',
33+
}
34+
});
35+
36+
expect(async () => await fileReader.readConfigOrThrow(dir + 'other.json')).to.throw;
37+
mock.restore();
38+
})
39+
40+
it('it loads directories with codify.json', async () => {
41+
const dir = 'path/to/fake/dir';
42+
mock({
43+
[dir]: {
44+
'codify.json': '[]',
45+
}
46+
});
47+
48+
const file = await fileReader.readConfigOrThrow(dir + '/codify.json');
49+
50+
expect(file.fileName).eq('codify.json');
51+
expect(file.fileType).eq('json');
52+
expect(file.contents).eq('[]');
53+
mock.restore();
54+
})
55+
56+
it('it doesn\'t load directories without codify.json', async () => {
57+
const dir = 'path/to/fake/dir';
58+
mock({
59+
[dir]: {
60+
'other.json': '[]',
61+
}
62+
});
4063

64+
expect(async () => await fileReader.readConfigOrThrow(dir)).to.throw;
4165
mock.restore();
4266
})
4367
})

src/parser/reader/index.ts

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,48 @@
11
import * as fs from 'node:fs/promises';
22
import * as path from 'node:path';
3-
4-
import { Parser } from '../index.js';
53
import { File } from './entities/file.js';
6-
import { LoadedProject } from './entities/project.js';
4+
5+
const CODIFY_FILE_NAME = 'codify.json';
6+
const NO_CONFIG_FOUND_ERROR_MESSAGE = 'No configuration found. Codify configuration files must be named codify.json'
77

88
/**
99
* This class loads relevant files in the project directory into memory so that they can be compiled
1010
* TODO: Rename this to reader. A loader has a different meaning for compilers
1111
*/
12-
export class ProjectReader {
12+
export class FileReader {
1313

14-
async readProject(directory: string): Promise<LoadedProject> {
14+
async readConfigOrThrow(directory: string): Promise<File> {
1515
try {
16-
const project: LoadedProject = {
17-
files: [],
18-
rootDirectory: directory,
16+
const stat = await fs.stat(directory);
17+
if (stat.isFile() && path.basename(directory) === CODIFY_FILE_NAME) {
18+
return await this.readFile(directory);
19+
} else if (stat.isDirectory()) {
20+
return await this.readDirectory(directory, CODIFY_FILE_NAME)
21+
} else {
22+
throw new Error(NO_CONFIG_FOUND_ERROR_MESSAGE);
1923
}
2024

21-
const dir = await fs.readdir(directory);
22-
await Promise.all(dir
23-
.map(async (fileName) => {
24-
if (!this.isFileTypeSupported(fileName)) {
25-
return;
26-
}
27-
28-
const parsedFile = await this.readFile(fileName, directory);
29-
project.files.push(parsedFile);
30-
})
31-
);
32-
33-
return project;
34-
3525
} catch (error) {
3626
console.log(error);
3727
throw error;
3828
}
3929
}
4030

41-
private async readFile(fileName: string, directory: string): Promise<File> {
42-
const fileLocation = path.join(directory, fileName);
43-
const fileType = fileName.lastIndexOf('.') === -1 ? '' : fileName.split('.').pop()!;
31+
private async readDirectory(directory: string, fileName: string): Promise<File> {
32+
const dir = await fs.readdir(directory);
4433

45-
return new File({ contents: await fs.readFile(fileLocation, 'utf8'), fileName, fileType });
34+
if (!dir.includes(CODIFY_FILE_NAME)) {
35+
throw new Error(NO_CONFIG_FOUND_ERROR_MESSAGE);
36+
}
37+
38+
const fileLocation = path.join(directory, fileName);
39+
return this.readFile(fileLocation);
4640
}
4741

48-
private isFileTypeSupported(fileName: string): boolean {
49-
const parser = Object.entries(Parser.supportedParsers).find(([k]) => fileName.endsWith(k));
42+
private async readFile(fileLocation: string): Promise<File> {
43+
const fileName = path.basename(fileLocation);
44+
const fileType = fileName.lastIndexOf('.') === -1 ? '' : fileName.split('.').pop()!;
5045

51-
return parser !== null && parser !== undefined;
46+
return new File({ contents: await fs.readFile(fileLocation, 'utf8'), fileName, fileType });
5247
}
5348
}

0 commit comments

Comments
 (0)