@ts-for-gir/cli 4.0.0-beta.25 → 4.0.0-beta.26
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 +84 -2
- package/bin/ts-for-gir.js +43 -0
- package/package.json +30 -36
- package/src/commands/analyze.ts +344 -0
- package/src/commands/command-builder.ts +30 -0
- package/src/commands/copy.ts +71 -76
- package/src/commands/doc.ts +58 -46
- package/src/commands/generate.ts +97 -77
- package/src/commands/index.ts +6 -4
- package/src/commands/json.ts +104 -0
- package/src/commands/list.ts +81 -90
- package/src/config/config-loader.ts +203 -0
- package/src/config/config-writer.ts +52 -0
- package/src/config/defaults.ts +61 -0
- package/src/config/index.ts +8 -0
- package/src/config/options.ts +292 -0
- package/src/config.ts +3 -456
- package/src/formatters/typescript-formatter.ts +24 -0
- package/src/generation-handler.ts +122 -67
- package/src/index.ts +4 -4
- package/src/module-loader/dependency-resolver.ts +100 -0
- package/src/module-loader/file-finder.ts +56 -0
- package/src/module-loader/index.ts +8 -0
- package/src/module-loader/module-grouper.ts +77 -0
- package/src/module-loader/prompt-handler.ts +111 -0
- package/src/module-loader.ts +280 -580
- package/src/start.ts +18 -14
- package/src/types/command-args.ts +110 -0
- package/src/types/command-definition.ts +15 -0
- package/src/types/commands.ts +35 -0
- package/src/types/index.ts +15 -0
- package/src/types/report-types.ts +34 -0
- package/lib/commands/copy.d.ts +0 -12
- package/lib/commands/copy.js +0 -78
- package/lib/commands/copy.js.map +0 -1
- package/lib/commands/doc.d.ts +0 -12
- package/lib/commands/doc.js +0 -38
- package/lib/commands/doc.js.map +0 -1
- package/lib/commands/generate.d.ts +0 -12
- package/lib/commands/generate.js +0 -70
- package/lib/commands/generate.js.map +0 -1
- package/lib/commands/index.d.ts +0 -4
- package/lib/commands/index.js +0 -5
- package/lib/commands/index.js.map +0 -1
- package/lib/commands/list.d.ts +0 -12
- package/lib/commands/list.js +0 -79
- package/lib/commands/list.js.map +0 -1
- package/lib/config.d.ts +0 -108
- package/lib/config.js +0 -409
- package/lib/config.js.map +0 -1
- package/lib/generation-handler.d.ts +0 -10
- package/lib/generation-handler.js +0 -48
- package/lib/generation-handler.js.map +0 -1
- package/lib/index.d.ts +0 -4
- package/lib/index.js +0 -5
- package/lib/index.js.map +0 -1
- package/lib/module-loader.d.ts +0 -154
- package/lib/module-loader.js +0 -465
- package/lib/module-loader.js.map +0 -1
- package/lib/start.d.ts +0 -2
- package/lib/start.js +0 -16
- package/lib/start.js.map +0 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles dependency resolution and traversal for GIR modules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Dependency, DependencyMap, GirModule, GirModuleResolvedBy, GirModulesGroupedMap } from "@ts-for-gir/lib";
|
|
6
|
+
import { isIterable } from "@ts-for-gir/lib";
|
|
7
|
+
|
|
8
|
+
export class DependencyResolver {
|
|
9
|
+
private modDependencyMap: DependencyMap = {};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Extends the modDependencyMap by the current Module,
|
|
13
|
+
* should be called for each girModule so that the modDependencyMap is complete
|
|
14
|
+
*/
|
|
15
|
+
extendDependencyMapByGirModule(girModule: GirModule): void {
|
|
16
|
+
this.modDependencyMap[girModule.packageName] = girModule.dependencies || [];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Figure out transitive module dependencies
|
|
21
|
+
*/
|
|
22
|
+
traverseDependencies(packageName: string, result: { [name: string]: Dependency } = {}): void {
|
|
23
|
+
const deps = this.modDependencyMap[packageName];
|
|
24
|
+
if (isIterable(deps)) {
|
|
25
|
+
for (const dep of deps) {
|
|
26
|
+
if (result[dep.packageName]) continue;
|
|
27
|
+
result[dep.packageName] = dep;
|
|
28
|
+
this.traverseDependencies(dep.packageName, result);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get transitive dependencies for a package
|
|
35
|
+
*/
|
|
36
|
+
getTransitiveDependencies(packageName: string): Dependency[] {
|
|
37
|
+
const result: { [name: string]: Dependency } = {};
|
|
38
|
+
this.traverseDependencies(packageName, result);
|
|
39
|
+
return Object.values(result);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Find modules that depend on the module with the name 'packageName'
|
|
44
|
+
*/
|
|
45
|
+
findModulesDependingOnPackage(
|
|
46
|
+
girModulesGroupedMap: GirModulesGroupedMap,
|
|
47
|
+
packageName: string,
|
|
48
|
+
): GirModuleResolvedBy[] {
|
|
49
|
+
const girModules: GirModuleResolvedBy[] = [];
|
|
50
|
+
|
|
51
|
+
for (const girModulesGrouped of Object.values(girModulesGroupedMap)) {
|
|
52
|
+
for (const girModuleResolvedBy of girModulesGrouped.modules) {
|
|
53
|
+
if (girModuleResolvedBy.packageName === packageName) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
for (const dep of girModuleResolvedBy.module.dependencies) {
|
|
57
|
+
if (dep.packageName === packageName && !girModules.includes(girModuleResolvedBy)) {
|
|
58
|
+
girModules.push(girModuleResolvedBy);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return girModules;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Find modules that depend on the modules with the names in `packageNames`
|
|
69
|
+
*/
|
|
70
|
+
findModulesDependingOnPackages(
|
|
71
|
+
girModulesGroupedMap: GirModulesGroupedMap,
|
|
72
|
+
packageNames: string[],
|
|
73
|
+
): GirModuleResolvedBy[] {
|
|
74
|
+
let girModules: GirModuleResolvedBy[] = [];
|
|
75
|
+
|
|
76
|
+
for (const packageName of packageNames) {
|
|
77
|
+
girModules = [...girModules, ...this.findModulesDependingOnPackage(girModulesGroupedMap, packageName)];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return girModules;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns a girModule found by `packageName` property
|
|
85
|
+
*/
|
|
86
|
+
findGirModuleByFullNames(
|
|
87
|
+
girModules: (GirModuleResolvedBy | GirModule)[],
|
|
88
|
+
packageNames: string[],
|
|
89
|
+
): Array<GirModuleResolvedBy | GirModule> {
|
|
90
|
+
return girModules.filter((girModule) => packageNames.includes(girModule.packageName));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Checks if a girModules with the `packageNames` exists
|
|
95
|
+
*/
|
|
96
|
+
existsGirModules(girModules: (GirModuleResolvedBy | GirModule)[], packageName: string): boolean {
|
|
97
|
+
const foundModule = this.findGirModuleByFullNames(girModules, [packageName]);
|
|
98
|
+
return foundModule.length > 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles finding GIR files in the filesystem
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { basename, join } from "node:path";
|
|
6
|
+
import type { Dependency, DependencyManager } from "@ts-for-gir/lib";
|
|
7
|
+
import { splitModuleName } from "@ts-for-gir/lib";
|
|
8
|
+
import { glob } from "glob";
|
|
9
|
+
|
|
10
|
+
export class FileFinder {
|
|
11
|
+
constructor(
|
|
12
|
+
private readonly girDirectories: string[],
|
|
13
|
+
private readonly dependencyManager: DependencyManager,
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Find modules with the possibility to use wild cards for module names. E.g. `Gtk*` or `'*'`
|
|
18
|
+
* @param globPackageNames Module names with potential wildcards
|
|
19
|
+
* @param ignore Modules to ignore
|
|
20
|
+
*/
|
|
21
|
+
async findGirFiles(globPackageNames: string[], ignore: string[] = []): Promise<Set<string>> {
|
|
22
|
+
const foundFiles = new Set<string>();
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < globPackageNames.length; i++) {
|
|
25
|
+
if (!globPackageNames[i]) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const filename = `${globPackageNames[i]}.gir`;
|
|
30
|
+
const pattern = this.girDirectories.map((girDirectory) => join(girDirectory, filename));
|
|
31
|
+
const ignoreGirs = ignore.map((girDirectory) => `${girDirectory}.gir`);
|
|
32
|
+
const files = await glob(pattern, { ignore: ignoreGirs });
|
|
33
|
+
|
|
34
|
+
files.forEach((file) => foundFiles.add(file));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return foundFiles;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Convert GIR file paths to Dependency objects
|
|
42
|
+
* @param girFiles Set of GIR file paths
|
|
43
|
+
*/
|
|
44
|
+
async girFilePathToDependencies(girFiles: Set<string>): Promise<Dependency[]> {
|
|
45
|
+
const dependencies: Dependency[] = [];
|
|
46
|
+
|
|
47
|
+
for (const girFile of girFiles) {
|
|
48
|
+
const packageName = basename(girFile, ".gir");
|
|
49
|
+
const { namespace, version } = splitModuleName(packageName);
|
|
50
|
+
const dep = await this.dependencyManager.get(namespace, version);
|
|
51
|
+
dependencies.push(dep);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return dependencies;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module loader components exports
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export { DependencyResolver } from "./dependency-resolver.ts";
|
|
6
|
+
export { FileFinder } from "./file-finder.ts";
|
|
7
|
+
export { ModuleGrouper } from "./module-grouper.ts";
|
|
8
|
+
export { PromptHandler } from "./prompt-handler.ts";
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles grouping of GIR modules and conflict resolution
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { GirModuleResolvedBy, GirModulesGrouped, GirModulesGroupedMap } from "@ts-for-gir/lib";
|
|
6
|
+
import { splitModuleName } from "@ts-for-gir/lib";
|
|
7
|
+
|
|
8
|
+
export class ModuleGrouper {
|
|
9
|
+
/**
|
|
10
|
+
* Groups Gir modules by name id
|
|
11
|
+
* E.g. Gtk-3.0 and Gtk-4.0 will be grouped
|
|
12
|
+
*/
|
|
13
|
+
groupGirFiles(resolveGirModules: Set<GirModuleResolvedBy> | GirModuleResolvedBy[]): GirModulesGroupedMap {
|
|
14
|
+
const girModulesGrouped: GirModulesGroupedMap = {};
|
|
15
|
+
|
|
16
|
+
for (const resolveGirModule of resolveGirModules) {
|
|
17
|
+
const { namespace } = splitModuleName(resolveGirModule.packageName);
|
|
18
|
+
const id = namespace.toLowerCase();
|
|
19
|
+
|
|
20
|
+
if (!girModulesGrouped[id]) {
|
|
21
|
+
girModulesGrouped[id] = {
|
|
22
|
+
namespace: namespace,
|
|
23
|
+
modules: [resolveGirModule],
|
|
24
|
+
hasConflict: false,
|
|
25
|
+
};
|
|
26
|
+
} else {
|
|
27
|
+
girModulesGrouped[id].modules.push(resolveGirModule);
|
|
28
|
+
girModulesGrouped[id].hasConflict = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return girModulesGrouped;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Sorts out the module the user has not selected via cli prompt
|
|
37
|
+
* @param girModulesGrouped Grouped modules
|
|
38
|
+
* @param selected Users selected module packageName
|
|
39
|
+
*/
|
|
40
|
+
sortVersionsByAnswer(
|
|
41
|
+
girModulesGrouped: GirModulesGrouped,
|
|
42
|
+
selected: string[],
|
|
43
|
+
): { keep: Set<GirModuleResolvedBy>; ignore: string[] } {
|
|
44
|
+
const keep = new Set<GirModuleResolvedBy>();
|
|
45
|
+
let ignore: string[] = [];
|
|
46
|
+
|
|
47
|
+
if (!girModulesGrouped.hasConflict) {
|
|
48
|
+
keep.add(girModulesGrouped.modules[0]);
|
|
49
|
+
} else {
|
|
50
|
+
const keepModules = this.findGirModuleByFullNames(girModulesGrouped.modules, selected);
|
|
51
|
+
const girModulePackageNames = girModulesGrouped.modules.map((resolveGirModule) => resolveGirModule.packageName);
|
|
52
|
+
|
|
53
|
+
if (!keepModules || keepModules.length <= 0) {
|
|
54
|
+
throw new Error("Module not found!");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
for (const keepModule of keepModules) {
|
|
58
|
+
keep.add(keepModule);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const toIgnore = girModulePackageNames.filter((packageName) => !selected.includes(packageName));
|
|
62
|
+
ignore = ignore.concat(toIgnore);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
keep,
|
|
67
|
+
ignore,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Find modules by package names
|
|
73
|
+
*/
|
|
74
|
+
private findGirModuleByFullNames(girModules: GirModuleResolvedBy[], packageNames: string[]): GirModuleResolvedBy[] {
|
|
75
|
+
return girModules.filter((girModule) => packageNames.includes(girModule.packageName));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handles CLI prompts for module version conflicts and ignored modules
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { select } from "@inquirer/prompts";
|
|
6
|
+
import type { AnswerVersion, GirModuleResolvedBy, GirModulesGrouped } from "@ts-for-gir/lib";
|
|
7
|
+
import { Logger } from "@ts-for-gir/lib";
|
|
8
|
+
import { bold } from "colorette";
|
|
9
|
+
import { addToConfig, configFilePath } from "../config.ts";
|
|
10
|
+
|
|
11
|
+
export class PromptHandler {
|
|
12
|
+
private readonly log: Logger;
|
|
13
|
+
|
|
14
|
+
constructor(verbose: boolean) {
|
|
15
|
+
this.log = new Logger(verbose, "PromptHandler");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Ask if user wants to ignore dependencies
|
|
20
|
+
*/
|
|
21
|
+
async askIgnoreDepsPrompt(deps: GirModuleResolvedBy[] | Set<GirModuleResolvedBy>): Promise<"Yes" | "No" | "Go back"> {
|
|
22
|
+
const size = (deps as GirModuleResolvedBy[]).length || (deps as Set<GirModuleResolvedBy>).size || 0;
|
|
23
|
+
|
|
24
|
+
if (size > 0) {
|
|
25
|
+
// Show dependencies that would be ignored
|
|
26
|
+
this.log.log(bold("\nThe following modules have the ignored modules as dependencies:"));
|
|
27
|
+
for (const dep of deps) {
|
|
28
|
+
this.log.log(`- ${dep.packageName}`);
|
|
29
|
+
}
|
|
30
|
+
this.log.log(bold("\n"));
|
|
31
|
+
|
|
32
|
+
// Ask if user wants to ignore these dependencies
|
|
33
|
+
return select<"Yes" | "No" | "Go back">({
|
|
34
|
+
message: "Do you want to ignore them too?",
|
|
35
|
+
choices: [
|
|
36
|
+
{ value: "Yes", name: "Yes" },
|
|
37
|
+
{ value: "No", name: "No" },
|
|
38
|
+
{ value: "Go back", name: "Go back" },
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// No dependencies found
|
|
44
|
+
this.log.log(bold("\nNo dependencies found on the ignored modules"));
|
|
45
|
+
return select<"Yes" | "Go back">({
|
|
46
|
+
message: "Do you want to continue?",
|
|
47
|
+
choices: [
|
|
48
|
+
{ value: "Yes", name: "Yes" },
|
|
49
|
+
{ value: "Go back", name: "Go back" },
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Ask for module version selection
|
|
56
|
+
*/
|
|
57
|
+
async askForVersionsPrompt(girModulesGrouped: GirModulesGrouped): Promise<AnswerVersion> {
|
|
58
|
+
const choices = ["All", ...girModulesGrouped.modules.map((module) => module.packageName)];
|
|
59
|
+
|
|
60
|
+
const selected = await select<string>({
|
|
61
|
+
message: `Multiple versions of '${girModulesGrouped.namespace}' found, which one do you want to use?`,
|
|
62
|
+
choices: choices.map((choice) => ({
|
|
63
|
+
value: choice,
|
|
64
|
+
name: choice,
|
|
65
|
+
})),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (selected === "All") {
|
|
69
|
+
return {
|
|
70
|
+
selected: choices.filter((choice) => choice !== "All"),
|
|
71
|
+
unselected: [],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
selected: [selected],
|
|
77
|
+
unselected: choices.filter((choice) => choice !== selected && choice !== "All"),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Ask if user wants to add ignored modules to config
|
|
83
|
+
*/
|
|
84
|
+
async askAddToIgnoreToConfigPrompt(ignoredModules: string[] | Set<string>): Promise<void> {
|
|
85
|
+
const shouldAdd = await select<"Yes" | "No">({
|
|
86
|
+
message: `Do you want to add the ignored modules to your config so that you don't need to select them again next time?\n Config path: '${configFilePath}'`,
|
|
87
|
+
choices: [
|
|
88
|
+
{ value: "No", name: "No" },
|
|
89
|
+
{ value: "Yes", name: "Yes" },
|
|
90
|
+
],
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (shouldAdd === "Yes") {
|
|
94
|
+
await addToConfig({
|
|
95
|
+
ignore: Array.from(ignoredModules),
|
|
96
|
+
});
|
|
97
|
+
this.log.log(`Add ignored modules to '${configFilePath}'`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Show ignored modules
|
|
103
|
+
*/
|
|
104
|
+
showIgnoredModules(ignore: string[]): void {
|
|
105
|
+
if (ignore && ignore.length > 0) {
|
|
106
|
+
const ignoreLogList = `- ${ignore.join("\n- ")}`;
|
|
107
|
+
this.log.log(bold("\n The following modules will be ignored:"));
|
|
108
|
+
this.log.log(`\n${ignoreLogList}\n`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|