@cloud-ru/ft-deps-validator 1.1.1 → 1.1.2-preview-9ce1a08.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -15
- package/dist/cjs/Checker/MonorepoChecker.d.ts +10 -0
- package/dist/cjs/Checker/MonorepoChecker.js +57 -0
- package/dist/cjs/Checker/RepoChecker.d.ts +8 -0
- package/dist/cjs/Checker/RepoChecker.js +36 -0
- package/dist/cjs/Checker/__tests__/MonorepoChecker.spec.js +305 -0
- package/dist/cjs/Checker/__tests__/RepoChecker.spec.js +116 -0
- package/dist/cjs/Checker/index.d.ts +2 -0
- package/dist/cjs/Checker/index.js +7 -0
- package/dist/cjs/Config/MonorepoConfig.d.ts +12 -0
- package/dist/cjs/Config/MonorepoConfig.js +42 -0
- package/dist/cjs/Config/RepoConfig.d.ts +10 -0
- package/dist/cjs/Config/RepoConfig.js +27 -0
- package/dist/cjs/Config/__tests__/MonorepoConfig.spec.js +296 -0
- package/dist/cjs/Config/__tests__/RepoConfig.spec.d.ts +1 -0
- package/dist/cjs/Config/__tests__/RepoConfig.spec.js +99 -0
- package/dist/cjs/Config/index.d.ts +2 -0
- package/dist/cjs/Config/index.js +7 -0
- package/dist/cjs/Report/__tests__/Report.spec.d.ts +1 -0
- package/dist/cjs/Report/__tests__/Report.spec.js +176 -0
- package/dist/cjs/Report/index.d.ts +11 -0
- package/dist/cjs/Report/index.js +55 -0
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/index.js +13 -57
- package/dist/{esm/types/config.d.ts → cjs/types.d.ts} +14 -3
- package/dist/cjs/utils/__tests__/getCliArguments.spec.d.ts +1 -0
- package/dist/cjs/utils/__tests__/getCliArguments.spec.js +70 -0
- package/dist/cjs/utils/getCliArguments.d.ts +6 -6
- package/dist/cjs/utils/getCliArguments.js +1 -27
- package/dist/cjs/utils/getConfigFile.d.ts +4 -3
- package/dist/cjs/utils/getConfigFile.js +3 -9
- package/dist/cjs/utils/getEnvironment.d.ts +3 -0
- package/dist/cjs/utils/getEnvironment.js +50 -0
- package/dist/cjs/utils/readPackageJsonFile.d.ts +9 -0
- package/dist/cjs/utils/readPackageJsonFile.js +28 -0
- package/dist/esm/Checker/MonorepoChecker.d.ts +10 -0
- package/dist/esm/Checker/MonorepoChecker.js +53 -0
- package/dist/esm/Checker/RepoChecker.d.ts +8 -0
- package/dist/esm/Checker/RepoChecker.js +29 -0
- package/dist/esm/Checker/__tests__/MonorepoChecker.spec.d.ts +1 -0
- package/dist/esm/Checker/__tests__/MonorepoChecker.spec.js +300 -0
- package/dist/esm/Checker/__tests__/RepoChecker.spec.d.ts +1 -0
- package/dist/esm/Checker/__tests__/RepoChecker.spec.js +111 -0
- package/dist/esm/Checker/index.d.ts +2 -0
- package/dist/esm/Checker/index.js +2 -0
- package/dist/esm/Config/MonorepoConfig.d.ts +12 -0
- package/dist/esm/Config/MonorepoConfig.js +35 -0
- package/dist/esm/Config/RepoConfig.d.ts +10 -0
- package/dist/esm/Config/RepoConfig.js +20 -0
- package/dist/esm/Config/__tests__/MonorepoConfig.spec.d.ts +1 -0
- package/dist/esm/Config/__tests__/MonorepoConfig.spec.js +291 -0
- package/dist/esm/Config/__tests__/RepoConfig.spec.d.ts +1 -0
- package/dist/esm/Config/__tests__/RepoConfig.spec.js +94 -0
- package/dist/esm/Config/index.d.ts +2 -0
- package/dist/esm/Config/index.js +2 -0
- package/dist/esm/Report/__tests__/Report.spec.d.ts +1 -0
- package/dist/esm/Report/__tests__/Report.spec.js +174 -0
- package/dist/esm/Report/index.d.ts +11 -0
- package/dist/esm/Report/index.js +51 -0
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +14 -55
- package/dist/{cjs/types/config.d.ts → esm/types.d.ts} +14 -3
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils/__tests__/getCliArguments.spec.d.ts +1 -0
- package/dist/esm/utils/__tests__/getCliArguments.spec.js +68 -0
- package/dist/esm/utils/getCliArguments.d.ts +6 -6
- package/dist/esm/utils/getCliArguments.js +1 -27
- package/dist/esm/utils/getConfigFile.d.ts +4 -3
- package/dist/esm/utils/getConfigFile.js +3 -9
- package/dist/esm/utils/getEnvironment.d.ts +3 -0
- package/dist/esm/utils/getEnvironment.js +42 -0
- package/dist/esm/utils/readPackageJsonFile.d.ts +9 -0
- package/dist/esm/utils/readPackageJsonFile.js +20 -0
- package/package.json +2 -2
- package/src/Checker/MonorepoChecker.ts +45 -0
- package/src/Checker/RepoChecker.ts +23 -0
- package/src/Checker/__tests__/MonorepoChecker.spec.ts +330 -0
- package/src/Checker/__tests__/RepoChecker.spec.ts +132 -0
- package/src/Checker/index.ts +2 -0
- package/src/Config/MonorepoConfig.ts +51 -0
- package/src/Config/RepoConfig.ts +30 -0
- package/src/Config/__tests__/MonorepoConfig.spec.ts +348 -0
- package/src/Config/__tests__/RepoConfig.spec.ts +131 -0
- package/src/Config/index.ts +2 -0
- package/src/Report/__tests__/Report.spec.ts +221 -0
- package/src/Report/index.ts +75 -0
- package/src/index.ts +14 -67
- package/src/{types/config.ts → types.ts} +15 -3
- package/src/utils/__tests__/getCliArguments.spec.ts +89 -0
- package/src/utils/getCliArguments.ts +1 -35
- package/src/utils/getConfigFile.ts +7 -11
- package/src/utils/getEnvironment.ts +53 -0
- package/src/utils/readPackageJsonFile.ts +20 -0
- package/dist/cjs/types/cliArguments.d.ts +0 -4
- package/dist/cjs/types/config.js +0 -2
- package/dist/cjs/types/state.d.ts +0 -6
- package/dist/cjs/types/state.js +0 -2
- package/dist/cjs/utils/getMonorepoPrefix.d.ts +0 -6
- package/dist/cjs/utils/getMonorepoPrefix.js +0 -33
- package/dist/cjs/utils/initializeState.d.ts +0 -8
- package/dist/cjs/utils/initializeState.js +0 -40
- package/dist/esm/types/cliArguments.d.ts +0 -4
- package/dist/esm/types/state.d.ts +0 -6
- package/dist/esm/utils/getMonorepoPrefix.d.ts +0 -6
- package/dist/esm/utils/getMonorepoPrefix.js +0 -27
- package/dist/esm/utils/initializeState.d.ts +0 -8
- package/dist/esm/utils/initializeState.js +0 -34
- package/src/types/cliArguments.ts +0 -5
- package/src/types/state.ts +0 -6
- package/src/utils/getMonorepoPrefix.ts +0 -32
- package/src/utils/initializeState.ts +0 -51
- /package/dist/{esm/types/cliArguments.js → cjs/Checker/__tests__/MonorepoChecker.spec.d.ts} +0 -0
- /package/dist/{esm/types/config.js → cjs/Checker/__tests__/RepoChecker.spec.d.ts} +0 -0
- /package/dist/{esm/types/state.js → cjs/Config/__tests__/MonorepoConfig.spec.d.ts} +0 -0
- /package/dist/cjs/{types/cliArguments.js → types.js} +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Results } from 'depcheck';
|
|
2
|
+
|
|
3
|
+
import { logError, logInfo } from '../utils/console';
|
|
4
|
+
|
|
5
|
+
type Messages = ['info' | 'error', number, string][];
|
|
6
|
+
|
|
7
|
+
export type CheckState = Partial<
|
|
8
|
+
Pick<Results, 'dependencies' | 'missing'> & {
|
|
9
|
+
wrongVersions: string[];
|
|
10
|
+
internalAsDev: string[];
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export class Report {
|
|
15
|
+
private storage: Record<string, CheckState> = {};
|
|
16
|
+
|
|
17
|
+
public add(folder: string, state: CheckState) {
|
|
18
|
+
if (this.storage[folder]) {
|
|
19
|
+
throw new Error(`There is check state in storage already for: ${folder}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
this.storage[folder] = state;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public printResultAndGetExitCode(): 1 | 0 {
|
|
26
|
+
let exitCode: 1 | 0 = 0;
|
|
27
|
+
|
|
28
|
+
for (const [
|
|
29
|
+
packageName,
|
|
30
|
+
{ dependencies = [], internalAsDev = [], wrongVersions = [], missing = {} },
|
|
31
|
+
] of Object.entries(this.storage)) {
|
|
32
|
+
const messages: Messages = [['info', 0, packageName]];
|
|
33
|
+
|
|
34
|
+
if (wrongVersions.length) {
|
|
35
|
+
messages.push(['error', 1, 'wrong version of internal packages:']);
|
|
36
|
+
wrongVersions.forEach(dep => messages.push(['error', 2, dep]));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (internalAsDev.length) {
|
|
40
|
+
messages.push(['error', 1, 'incorrect usage as dev dep of internal packages:']);
|
|
41
|
+
internalAsDev.forEach(dep => messages.push(['error', 2, dep]));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (dependencies.length) {
|
|
45
|
+
messages.push(['error', 1, 'unused dependencies:']);
|
|
46
|
+
dependencies.forEach(dep => messages.push(['error', 2, dep]));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const missingEntities = Object.entries(missing);
|
|
50
|
+
if (missingEntities.length) {
|
|
51
|
+
messages.push(['error', 1, 'missing dependencies:']);
|
|
52
|
+
for (const [packageName, files] of missingEntities) {
|
|
53
|
+
messages.push(['error', 2, packageName]);
|
|
54
|
+
for (const file of files) {
|
|
55
|
+
messages.push(['error', 2, file]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (messages.length > 1) {
|
|
61
|
+
exitCode = 1;
|
|
62
|
+
this.printMessages(messages);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return exitCode;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private printMessages(messages: Messages) {
|
|
70
|
+
for (const [level, tabs, message] of messages) {
|
|
71
|
+
const log = level === 'info' ? logInfo : logError;
|
|
72
|
+
log(`${'\t'.repeat(tabs)}${message}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,77 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import { logDebug, logError, logInfo } from './utils/console';
|
|
7
|
-
import { getCliArguments } from './utils/getCliArguments';
|
|
8
|
-
import { getConfigFile } from './utils/getConfigFile';
|
|
9
|
-
import { initializeState } from './utils/initializeState';
|
|
1
|
+
import { MonorepoChecker, RepoChecker } from './Checker';
|
|
2
|
+
import { MonorepoConfig } from './Config';
|
|
3
|
+
import { RepoConfig } from './Config/RepoConfig';
|
|
4
|
+
import { logError } from './utils/console';
|
|
5
|
+
import { getEnvironment, isMonorepoEnv } from './utils/getEnvironment';
|
|
10
6
|
|
|
11
7
|
(async () => {
|
|
12
8
|
try {
|
|
13
|
-
const
|
|
14
|
-
const configFile = getConfigFile(args.cwd);
|
|
15
|
-
|
|
16
|
-
const config = configFile ? Object.assign(args, configFile) : args;
|
|
17
|
-
|
|
18
|
-
const options = {
|
|
19
|
-
ignoreBinPackage: false,
|
|
20
|
-
skipMissing: false,
|
|
21
|
-
ignorePatterns: config.ignorePatterns.map(pattern => pattern.toString()),
|
|
22
|
-
ignoreMatches: config.ignoreMatches.map(match => match.toString()),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const folders = globSync(config.rootPackagesFolderPattern, {
|
|
26
|
-
ignore: config.ignoredPackagesFolderFiles.map(path => path.toString()),
|
|
27
|
-
});
|
|
28
|
-
const state = initializeState({
|
|
29
|
-
cwd: args.cwd,
|
|
30
|
-
folders,
|
|
31
|
-
prefix: config.prefix,
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
for (const folder of folders) {
|
|
35
|
-
const { dependencies, missing: missingDepsPerPackage } = await depCheck(folder, options);
|
|
9
|
+
const env = getEnvironment();
|
|
36
10
|
|
|
37
|
-
|
|
11
|
+
const checker = isMonorepoEnv(env)
|
|
12
|
+
? new MonorepoChecker(new MonorepoConfig(env))
|
|
13
|
+
: new RepoChecker(new RepoConfig(env));
|
|
38
14
|
|
|
39
|
-
|
|
40
|
-
state.missing.push(missingDepsPerPackage);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
15
|
+
const report = await checker.check();
|
|
43
16
|
|
|
44
|
-
|
|
45
|
-
logInfo('Dependencies have been checked. Everything is ok.');
|
|
46
|
-
process.exit(0);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
17
|
+
const exitCode = report.printResultAndGetExitCode();
|
|
49
18
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (state.internalAsDev.length) {
|
|
56
|
-
logError(
|
|
57
|
-
'You have to fix wrong usage of internal packages in dev dependencies (either delete them or move to dependencies):',
|
|
58
|
-
);
|
|
59
|
-
state.internalAsDev.forEach(logDebug);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (state.unusedDeps.length) {
|
|
63
|
-
logError('You have to fix following unused dependencies:');
|
|
64
|
-
state.unusedDeps.forEach(logDebug);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (state.missing.length) {
|
|
68
|
-
logError('You have to fix following missed dependencies:');
|
|
69
|
-
state.missing.forEach(x => logDebug(JSON.stringify(x, null, 2)));
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
process.exit(1);
|
|
73
|
-
} catch (err) {
|
|
74
|
-
console.error(err);
|
|
19
|
+
process.exit(exitCode);
|
|
20
|
+
} catch (e: unknown) {
|
|
21
|
+
logError(`${e}`);
|
|
75
22
|
process.exit(1);
|
|
76
23
|
}
|
|
77
24
|
})();
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
type BaseEnvType = {
|
|
2
2
|
/** Directories names that should be ignored */
|
|
3
3
|
ignorePatterns?: string[];
|
|
4
4
|
/** Names of packages that should be ignored */
|
|
5
5
|
ignoreMatches?: string[];
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type RawRepoEnvType = BaseEnvType & { packages?: Record<string, BaseEnvType> };
|
|
9
|
+
|
|
10
|
+
export type RawMonorepoEnvType = {
|
|
8
11
|
/** One or more paths that should be ignored in packages folder */
|
|
9
12
|
ignoredPackagesFolderFiles?: string[];
|
|
10
13
|
/** Folder containing packages (glob pattern, e.g., "packages/*" or "apps/*") */
|
|
11
14
|
rootPackagesFolderPattern?: string;
|
|
15
|
+
} & RawRepoEnvType;
|
|
16
|
+
|
|
17
|
+
export type RepoEnvType = RawRepoEnvType & {
|
|
18
|
+
cwd: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type MonorepoEnvType = RawMonorepoEnvType & {
|
|
22
|
+
cwd: string;
|
|
23
|
+
rootPackagesFolderPattern: string;
|
|
12
24
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { getCliArguments } from '../getCliArguments';
|
|
4
|
+
|
|
5
|
+
describe('@cloud-ru/ft-deps-validator/getCliArguments', () => {
|
|
6
|
+
const originalArgv = process.argv;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
process.argv = originalArgv;
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return empty object when no arguments provided', () => {
|
|
14
|
+
process.argv = ['node', 'script.js'];
|
|
15
|
+
const result = getCliArguments();
|
|
16
|
+
|
|
17
|
+
expect(result.cwd).toBeUndefined();
|
|
18
|
+
expect(result.rootPackagesFolderPattern).toBeUndefined();
|
|
19
|
+
expect(result.ignoredPackagesFolderFiles).toBeUndefined();
|
|
20
|
+
expect(result.ignorePatterns).toBeUndefined();
|
|
21
|
+
expect(result.ignoreMatches).toBeUndefined();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should parse cwd option', () => {
|
|
25
|
+
const testCwd = '/test/directory';
|
|
26
|
+
process.argv = ['node', 'script.js', '--cwd', testCwd];
|
|
27
|
+
const result = getCliArguments();
|
|
28
|
+
|
|
29
|
+
expect(result.cwd).toBe(testCwd);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should parse cwd option with alias -d', () => {
|
|
33
|
+
const testCwd = '/test/directory';
|
|
34
|
+
process.argv = ['node', 'script.js', '-d', testCwd];
|
|
35
|
+
const result = getCliArguments();
|
|
36
|
+
|
|
37
|
+
expect(result.cwd).toBe(testCwd);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should parse rootPackagesFolderPattern option', () => {
|
|
41
|
+
const pattern = 'apps/*';
|
|
42
|
+
process.argv = ['node', 'script.js', '--rootPackagesFolderPattern', pattern];
|
|
43
|
+
const result = getCliArguments();
|
|
44
|
+
|
|
45
|
+
expect(result.rootPackagesFolderPattern).toBe(pattern);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should parse rootPackagesFolderPattern option with alias -p', () => {
|
|
49
|
+
const pattern = 'apps/*';
|
|
50
|
+
process.argv = ['node', 'script.js', '-p', pattern];
|
|
51
|
+
const result = getCliArguments();
|
|
52
|
+
|
|
53
|
+
expect(result.rootPackagesFolderPattern).toBe(pattern);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should parse ignoredPackagesFolderFiles option', () => {
|
|
57
|
+
const files = ['file1.json', 'file2.json'];
|
|
58
|
+
process.argv = ['node', 'script.js', '--ignoredPackagesFolderFiles', ...files];
|
|
59
|
+
const result = getCliArguments();
|
|
60
|
+
|
|
61
|
+
expect(result.ignoredPackagesFolderFiles).toEqual(files);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should parse ignorePatterns option', () => {
|
|
65
|
+
const patterns = ['test', 'build'];
|
|
66
|
+
process.argv = ['node', 'script.js', '--ignorePatterns', ...patterns];
|
|
67
|
+
const result = getCliArguments();
|
|
68
|
+
|
|
69
|
+
expect(result.ignorePatterns).toEqual(patterns);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should parse ignoreMatches option', () => {
|
|
73
|
+
const matches = ['package1', 'package2'];
|
|
74
|
+
process.argv = ['node', 'script.js', '--ignoreMatches', ...matches];
|
|
75
|
+
const result = getCliArguments();
|
|
76
|
+
|
|
77
|
+
expect(result.ignoreMatches).toEqual(matches);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should parse multiple options together', () => {
|
|
81
|
+
const testCwd = '/test/directory';
|
|
82
|
+
const pattern = 'apps/*';
|
|
83
|
+
process.argv = ['node', 'script.js', '--cwd', testCwd, '--rootPackagesFolderPattern', pattern];
|
|
84
|
+
const result = getCliArguments();
|
|
85
|
+
|
|
86
|
+
expect(result.cwd).toBe(testCwd);
|
|
87
|
+
expect(result.rootPackagesFolderPattern).toBe(pattern);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -1,48 +1,27 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
|
|
3
1
|
import yargs from 'yargs';
|
|
4
2
|
|
|
5
3
|
export function getCliArguments() {
|
|
6
|
-
|
|
4
|
+
return yargs(process.argv.slice(2))
|
|
7
5
|
.option('cwd', {
|
|
8
6
|
alias: 'd',
|
|
9
7
|
type: 'string',
|
|
10
|
-
default: process.cwd(),
|
|
11
8
|
description: 'working directory (default: current working directory, cwd)',
|
|
12
9
|
})
|
|
13
|
-
.option('prefix', {
|
|
14
|
-
type: 'string',
|
|
15
|
-
description: 'monorepo prefix (if skipped will try to find automatically)',
|
|
16
|
-
})
|
|
17
10
|
.option('rootPackagesFolderPattern', {
|
|
18
11
|
alias: 'p',
|
|
19
12
|
type: 'string',
|
|
20
|
-
default: 'packages/*',
|
|
21
13
|
description: 'folder containing packages (glob pattern, e.g., "packages/*" or "apps/*")',
|
|
22
14
|
})
|
|
23
15
|
.option('ignoredPackagesFolderFiles', {
|
|
24
16
|
type: 'array',
|
|
25
|
-
default: ['packages/tsconfig.cjs.json', 'packages/tsconfig.esm.json'],
|
|
26
17
|
description: 'specify one or more paths that should be ignored in packages folder',
|
|
27
18
|
})
|
|
28
19
|
.option('ignorePatterns', {
|
|
29
20
|
type: 'array',
|
|
30
|
-
default: ['stories', 'dist', '__tests__', '__e2e__'],
|
|
31
21
|
description: 'specify one or more directories names that should be ignored',
|
|
32
22
|
})
|
|
33
23
|
.option('ignoreMatches', {
|
|
34
24
|
type: 'array',
|
|
35
|
-
default: [
|
|
36
|
-
'react',
|
|
37
|
-
'react-dom',
|
|
38
|
-
'react-docgen-typescript',
|
|
39
|
-
'@snack-uikit/figma-tokens',
|
|
40
|
-
'@sbercloud/figma-tokens-cloud-platform',
|
|
41
|
-
'@sbercloud/figma-tokens-mlspace',
|
|
42
|
-
'@sbercloud/figma-tokens-admin',
|
|
43
|
-
'@sbercloud/figma-tokens-web',
|
|
44
|
-
'@sbercloud/figma-tokens-giga-id',
|
|
45
|
-
],
|
|
46
25
|
description: 'specify one or more packages that should be ignored',
|
|
47
26
|
})
|
|
48
27
|
.locale('en')
|
|
@@ -50,17 +29,4 @@ export function getCliArguments() {
|
|
|
50
29
|
.alias('h', 'help')
|
|
51
30
|
.alias('v', 'version')
|
|
52
31
|
.parseSync();
|
|
53
|
-
|
|
54
|
-
const cwd = path.resolve(parsed.cwd);
|
|
55
|
-
|
|
56
|
-
const rootPackagesFolderPattern = path.resolve(cwd, parsed.rootPackagesFolderPattern);
|
|
57
|
-
|
|
58
|
-
const ignoredPackagesFolderFiles = parsed.ignoredPackagesFolderFiles.map(file => path.resolve(cwd, file.toString()));
|
|
59
|
-
|
|
60
|
-
return {
|
|
61
|
-
...parsed,
|
|
62
|
-
cwd,
|
|
63
|
-
rootPackagesFolderPattern,
|
|
64
|
-
ignoredPackagesFolderFiles,
|
|
65
|
-
};
|
|
66
32
|
}
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { Config } from '../types/config';
|
|
4
|
+
import { RawMonorepoEnvType, RawRepoEnvType } from '../types';
|
|
6
5
|
|
|
7
6
|
const CONFIG_FILE_NAME = 'deps-validator.config.json';
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
type PossibleConfig = RawMonorepoEnvType & RawRepoEnvType;
|
|
9
|
+
|
|
10
|
+
export function getConfigFile(cwd: string): PossibleConfig {
|
|
10
11
|
const configPath = path.resolve(cwd, CONFIG_FILE_NAME);
|
|
11
12
|
|
|
12
13
|
if (!fs.existsSync(configPath)) {
|
|
13
|
-
return
|
|
14
|
+
return { packages: {} };
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const config = JSON.parse(configContent) as Config;
|
|
19
|
-
return config;
|
|
20
|
-
} catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
17
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
18
|
+
return JSON.parse(configContent) as PossibleConfig;
|
|
23
19
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import { MonorepoEnvType, RepoEnvType } from '../types';
|
|
5
|
+
import { getCliArguments } from './getCliArguments';
|
|
6
|
+
import { getConfigFile } from './getConfigFile';
|
|
7
|
+
|
|
8
|
+
export function getEnvironment(): MonorepoEnvType | RepoEnvType {
|
|
9
|
+
const defaultConfig = {
|
|
10
|
+
cwd: process.cwd(),
|
|
11
|
+
ignoredPackagesFolderFiles: ['packages/tsconfig.cjs.json', 'packages/tsconfig.esm.json'],
|
|
12
|
+
ignorePatterns: ['stories', 'dist', '__tests__', '__e2e__'],
|
|
13
|
+
ignoreMatches: [
|
|
14
|
+
'react',
|
|
15
|
+
'react-dom',
|
|
16
|
+
'react-docgen-typescript',
|
|
17
|
+
'@snack-uikit/figma-tokens',
|
|
18
|
+
'@sbercloud/figma-tokens-cloud-platform',
|
|
19
|
+
'@sbercloud/figma-tokens-mlspace',
|
|
20
|
+
'@sbercloud/figma-tokens-admin',
|
|
21
|
+
'@sbercloud/figma-tokens-web',
|
|
22
|
+
'@sbercloud/figma-tokens-giga-id',
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const configFile = getConfigFile(defaultConfig.cwd);
|
|
27
|
+
const configArguments = getCliArguments();
|
|
28
|
+
const rootIsNotPassed = !configFile.rootPackagesFolderPattern && !configArguments.ignoredPackagesFolderFiles;
|
|
29
|
+
|
|
30
|
+
const rawConfig = Object.assign(
|
|
31
|
+
defaultConfig,
|
|
32
|
+
/* конфиг файл имеет меньший приоритет перед cli-аргументами */
|
|
33
|
+
configFile,
|
|
34
|
+
configArguments,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
if (rootIsNotPassed) {
|
|
38
|
+
/*
|
|
39
|
+
Если папку не передали в конфиге, то проверим на наличие папки сами,
|
|
40
|
+
если она есть, то считаем что это монорепа
|
|
41
|
+
*/
|
|
42
|
+
if (fs.existsSync(path.resolve(defaultConfig.cwd, './packages'))) {
|
|
43
|
+
rawConfig.rootPackagesFolderPattern = 'packages/*';
|
|
44
|
+
} else {
|
|
45
|
+
delete rawConfig.rootPackagesFolderPattern;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return rawConfig;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const isMonorepoEnv = (env: MonorepoEnvType | RepoEnvType): env is MonorepoEnvType =>
|
|
53
|
+
Boolean('rootPackagesFolderPattern' in env);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
|
|
5
|
+
type PackageJson = {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
dependencies: Record<string, string>;
|
|
9
|
+
devDependencies: Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const readPackageJsonFile = async (folder: string): Promise<PackageJson> => {
|
|
13
|
+
const file = await fsp.readFile(path.relative(folder, './package.json'), 'utf8');
|
|
14
|
+
return JSON.parse(file);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const readPackageJsonFileSync = (folder: string): PackageJson => {
|
|
18
|
+
const file = fs.readFileSync(path.resolve(folder, './package.json'), 'utf8');
|
|
19
|
+
return JSON.parse(file);
|
|
20
|
+
};
|
package/dist/cjs/types/config.js
DELETED
package/dist/cjs/types/state.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getMonorepoPrefix = getMonorepoPrefix;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
function getMonorepoPrefix({ cwd, folders }) {
|
|
9
|
-
var _a;
|
|
10
|
-
try {
|
|
11
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
12
|
-
const rootPkg = require(path_1.default.resolve(cwd, 'package.json'));
|
|
13
|
-
return rootPkg.name || null;
|
|
14
|
-
}
|
|
15
|
-
catch (_b) {
|
|
16
|
-
if (folders.length < 1) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
try {
|
|
20
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
21
|
-
const firstPkg = require(path_1.default.resolve(folders[0], 'package.json'));
|
|
22
|
-
// Extract monorepo scope from package name (e.g., "@cloud-ru" from "@cloud-ru/ft-deps-validator")
|
|
23
|
-
const match = (_a = firstPkg.name) === null || _a === void 0 ? void 0 : _a.match(/^(@[^/]+)/);
|
|
24
|
-
if (match) {
|
|
25
|
-
return match[1];
|
|
26
|
-
}
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
catch (_c) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initializeState = initializeState;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const getMonorepoPrefix_1 = require("./getMonorepoPrefix");
|
|
9
|
-
function initializeState({ cwd, folders, prefix }) {
|
|
10
|
-
const internalPackages = {};
|
|
11
|
-
const initialState = {
|
|
12
|
-
wrongVersions: [],
|
|
13
|
-
internalAsDev: [],
|
|
14
|
-
unusedDeps: [],
|
|
15
|
-
missing: [],
|
|
16
|
-
};
|
|
17
|
-
const monorepoName = prefix || (0, getMonorepoPrefix_1.getMonorepoPrefix)({ cwd, folders });
|
|
18
|
-
if (!monorepoName) {
|
|
19
|
-
throw new Error('[ERROR] Prefix was not specified and was not found');
|
|
20
|
-
}
|
|
21
|
-
const monorepoPackageRegexp = new RegExp(`${monorepoName}\\/`);
|
|
22
|
-
for (const folder of folders) {
|
|
23
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
24
|
-
const pkg = require(path_1.default.resolve(folder, 'package.json'));
|
|
25
|
-
internalPackages[pkg.name] = pkg.version;
|
|
26
|
-
}
|
|
27
|
-
for (const folder of folders) {
|
|
28
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
29
|
-
const pkg = require(path_1.default.resolve(folder, 'package.json'));
|
|
30
|
-
const usedInternal = Object.keys(pkg.dependencies || {}).filter(x => monorepoPackageRegexp.test(x));
|
|
31
|
-
usedInternal.forEach(dep => {
|
|
32
|
-
if (pkg.dependencies[dep] !== internalPackages[dep]) {
|
|
33
|
-
initialState.wrongVersions.push(`Error in ${pkg.name}: ${dep} has ${pkg.dependencies[dep]}, but correct version is ${internalPackages[dep]}`);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
const usedInternalDev = Object.keys(pkg.devDependencies || {}).filter(x => monorepoPackageRegexp.test(x));
|
|
37
|
-
usedInternalDev.forEach(dep => initialState.internalAsDev.push(`Error in ${pkg.name}: ${dep}`));
|
|
38
|
-
}
|
|
39
|
-
return initialState;
|
|
40
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
export function getMonorepoPrefix({ cwd, folders }) {
|
|
3
|
-
var _a;
|
|
4
|
-
try {
|
|
5
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
6
|
-
const rootPkg = require(path.resolve(cwd, 'package.json'));
|
|
7
|
-
return rootPkg.name || null;
|
|
8
|
-
}
|
|
9
|
-
catch (_b) {
|
|
10
|
-
if (folders.length < 1) {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
try {
|
|
14
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
15
|
-
const firstPkg = require(path.resolve(folders[0], 'package.json'));
|
|
16
|
-
// Extract monorepo scope from package name (e.g., "@cloud-ru" from "@cloud-ru/ft-deps-validator")
|
|
17
|
-
const match = (_a = firstPkg.name) === null || _a === void 0 ? void 0 : _a.match(/^(@[^/]+)/);
|
|
18
|
-
if (match) {
|
|
19
|
-
return match[1];
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
catch (_c) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { getMonorepoPrefix } from './getMonorepoPrefix';
|
|
3
|
-
export function initializeState({ cwd, folders, prefix }) {
|
|
4
|
-
const internalPackages = {};
|
|
5
|
-
const initialState = {
|
|
6
|
-
wrongVersions: [],
|
|
7
|
-
internalAsDev: [],
|
|
8
|
-
unusedDeps: [],
|
|
9
|
-
missing: [],
|
|
10
|
-
};
|
|
11
|
-
const monorepoName = prefix || getMonorepoPrefix({ cwd, folders });
|
|
12
|
-
if (!monorepoName) {
|
|
13
|
-
throw new Error('[ERROR] Prefix was not specified and was not found');
|
|
14
|
-
}
|
|
15
|
-
const monorepoPackageRegexp = new RegExp(`${monorepoName}\\/`);
|
|
16
|
-
for (const folder of folders) {
|
|
17
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
18
|
-
const pkg = require(path.resolve(folder, 'package.json'));
|
|
19
|
-
internalPackages[pkg.name] = pkg.version;
|
|
20
|
-
}
|
|
21
|
-
for (const folder of folders) {
|
|
22
|
-
// eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
|
|
23
|
-
const pkg = require(path.resolve(folder, 'package.json'));
|
|
24
|
-
const usedInternal = Object.keys(pkg.dependencies || {}).filter(x => monorepoPackageRegexp.test(x));
|
|
25
|
-
usedInternal.forEach(dep => {
|
|
26
|
-
if (pkg.dependencies[dep] !== internalPackages[dep]) {
|
|
27
|
-
initialState.wrongVersions.push(`Error in ${pkg.name}: ${dep} has ${pkg.dependencies[dep]}, but correct version is ${internalPackages[dep]}`);
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
const usedInternalDev = Object.keys(pkg.devDependencies || {}).filter(x => monorepoPackageRegexp.test(x));
|
|
31
|
-
usedInternalDev.forEach(dep => initialState.internalAsDev.push(`Error in ${pkg.name}: ${dep}`));
|
|
32
|
-
}
|
|
33
|
-
return initialState;
|
|
34
|
-
}
|