Skip to content

Commit

Permalink
feat(core): support projectData with relative paths
Browse files Browse the repository at this point in the history
  • Loading branch information
rainerhahnekamp committed Aug 29, 2024
1 parent d6a8952 commit 9636ec0
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 28 deletions.
73 changes: 68 additions & 5 deletions packages/core/src/lib/api/get-project-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FsPath, toFsPath } from '../file-info/fs-path';
import { init, ProjectInfo } from '../main/init';
import { calcTagsForModule } from '../tags/calc-tags-for-module';
import { traverseFileInfo } from '../modules/traverse-file-info';
import getFs from '../fs/getFs';

export type ProjectDataEntry = {
module: string;
Expand Down Expand Up @@ -33,9 +34,11 @@ function calcOrGetTags(
}

/**
* Traverses through the imports of the entryFile
* Traverses through the imports of the entryFileAbsolute
* and returns the complete dependency graph.
*
* All paths are absolute.
*
* Each node contains the module, tags and imports.
*
* ```json5
Expand All @@ -54,10 +57,47 @@ function calcOrGetTags(
* }
* ```
*
* @param entryFile absolute path to the entry file, e.g. main.ts
* @param entryFileAbsolute absolute path to the entry file, e.g. /project/src/main.ts
*/
export function getProjectData(entryFileAbsolute: string): ProjectData;
/**
* Traverses through the imports of the entryFileRelative
* and returns the complete dependency graph.
*
* All paths are relative to the cwd.
*
* Each node contains the module, tags and imports.
*
* ```json5
* {
* 'src/main.ts': {
* module: '.',
* tags: ['root'],
* imports: ['src/holidays/feature/index.ts'],
* },
* 'src/holidays/feature/index.ts': {
* module: 'src/holidays/feature',
* tags: ['domain:holidays', 'type:feature'],
* imports: ['src/holidays/feature/holidays-container.component.ts'],
* },
* // ...
* }
* ```
*
* @param entryFileRelative relative path to the entry file, e.g. main.ts
* @param cwd absolute path to the entry file, e.g. /project/src
*/
export function getProjectData(entryFile: string): ProjectData {
const projectInfo = init(toFsPath(entryFile));
export function getProjectData(
entryFileRelative: string,
cwd: string,
): ProjectData;

export function getProjectData(entryFile: string, cwd?: string): ProjectData {
const fs = getFs();
const absoluteEntryFile =
cwd === undefined ? entryFile : fs.join(cwd, entryFile);

const projectInfo = init(toFsPath(absoluteEntryFile));

const data: ProjectData = {};
const tagsCache: Record<string, string[]> = {};
Expand All @@ -73,5 +113,28 @@ export function getProjectData(entryFile: string): ProjectData {
imports: fileInfo.imports.map((fileInfo) => fileInfo.path),
};
}
return data;

return relativizeIfRequired(data, cwd);
}

function relativizeIfRequired(data: ProjectData, cwd?: string): ProjectData {
if (cwd === undefined) {
return data;
}

const fs = getFs();
const relative = (path: FsPath) => fs.relativeTo(cwd, path) || '.';

const relativizedData: ProjectData = {};
for (const [modulePath, moduleData] of Object.entries(data)) {
relativizedData[relative(toFsPath(modulePath))] = {
module: relative(toFsPath(moduleData.module)),
tags: moduleData.tags,
imports: moduleData.imports.map((importPath) =>
relative(toFsPath(importPath)),
),
};
}

return relativizedData;
}
18 changes: 3 additions & 15 deletions packages/core/src/lib/cli/export-data.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import { getEntryFromCliOrConfig } from './internal/get-entry-from-cli-or-config';
import { cli } from './cli';
import { getProjectData, ProjectData } from '../api/get-project-data';
import { FsPath, toFsPath } from '../file-info/fs-path';
import { getProjectData } from '../api/get-project-data';
import getFs from '../fs/getFs';

export function exportData(...args: string[]): void {
const fs = getFs();
const projectInfo = getEntryFromCliOrConfig(args[0]);
const relative = (path: FsPath) => fs.relativeTo(projectInfo.rootDir, path) || '.';

const projectData = getProjectData(projectInfo.fileInfo.path);
const data: ProjectData = {};

for (const [modulePath, moduleData] of Object.entries(projectData)) {
data[relative(toFsPath(modulePath))] = {
module: relative(toFsPath(moduleData.module)),
tags: moduleData.tags,
imports: moduleData.imports.map((importPath) => relative(toFsPath(importPath))),
};
}
const entryFile = getEntryFromCliOrConfig(args[0], false);

const data = getProjectData(entryFile, fs.cwd());
cli.log(JSON.stringify(data, null, ' '));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import { init, ProjectInfo } from '../../main/init';
import { parseConfig } from '../../config/parse-config';
import { toFsPath } from '../../file-info/fs-path';

export function getEntryFromCliOrConfig(entryFile?: string): ProjectInfo {
export function getEntryFromCliOrConfig(entryFile?: string): ProjectInfo;
export function getEntryFromCliOrConfig(entryFile?: string, runInit?: boolean): string;

export function getEntryFromCliOrConfig(entryFile = '', runInit = true): ProjectInfo | string {
const fs = getFs();
if (entryFile) {
return init(toFsPath(fs.join(fs.cwd(), entryFile)));
return runInit ? init(toFsPath(fs.join(fs.cwd(), entryFile))) : entryFile;
}

const potentialConfigFile = fs.join(fs.cwd(), 'sheriff.config.ts');
if (fs.exists(potentialConfigFile)) {
const sheriffConfig = parseConfig(potentialConfigFile);
if (sheriffConfig.entryFile) {
return init(toFsPath(fs.join(fs.cwd(), sheriffConfig.entryFile)));
return runInit ? init(toFsPath(fs.join(fs.cwd(), sheriffConfig.entryFile))) : sheriffConfig.entryFile;
} else {
throw new Error(
'No entry file found in sheriff.config.ts. Please provide one via the CLI ',
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/lib/cli/tests/export-data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { exportData } from '../export-data';
import { verifyCliWrappers } from './verify-cli-wrapper';

describe('export data', () => {
verifyCliWrappers('export', 'src/main.ts');
verifyCliWrappers('export', 'src/main.ts', false);

it('should test a simple application', () => {
const { allLogs } = mockCli();
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/lib/cli/tests/verify-cli-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { main } from '../main';
import { mockCli } from './helpers/mock-cli';

// Helper Functions to avoid redundancy in the CLI commands
export function verifyCliWrappers(...args: string[]) {
export function verifyCliWrappers(...args: unknown[]) {
it(`should call getEntryFromCliOrConfig`, () => {
mockCli();

Expand All @@ -23,9 +23,9 @@ export function verifyCliWrappers(...args: string[]) {
'getEntryFromCliOrConfig',
);

main(...args);
main(...args.map(String));

expect(spy).toHaveBeenCalledWith('src/main.ts');
expect(spy).toHaveBeenCalledWith(...args.slice(1));
});

it('should use the error handler', () => {
Expand All @@ -39,7 +39,7 @@ export function verifyCliWrappers(...args: string[]) {
});

const spy = vitest.spyOn(handleErrorFile, 'handleError');
main(...args);
main(...args.map(String));

expect(spy).toHaveBeenCalledOnce();
});
Expand Down

0 comments on commit 9636ec0

Please sign in to comment.