@ts-for-gir/cli 3.3.0 → 4.0.0-beta.10

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.
@@ -12,16 +12,17 @@ import { GeneratorType, Generator } from '@ts-for-gir/generator-base'
12
12
  import { TypeDefinitionGenerator } from '@ts-for-gir/generator-typescript'
13
13
  import { HtmlDocGenerator } from '@ts-for-gir/generator-html-doc'
14
14
 
15
- import type { InheritanceTable, GenerateConfig, GirModulesGrouped } from '@ts-for-gir/lib'
15
+ import type { OptionsGeneration, NSRegistry } from '@ts-for-gir/lib'
16
16
 
17
17
  export class GenerationHandler {
18
18
  log: Logger
19
19
  generator: Generator
20
+
20
21
  constructor(
21
- private readonly config: GenerateConfig,
22
+ private readonly config: OptionsGeneration,
22
23
  type: GeneratorType,
23
24
  ) {
24
- this.log = new Logger(config.environment, config.verbose, 'GenerationHandler')
25
+ this.log = new Logger(config.verbose, 'GenerationHandler')
25
26
 
26
27
  switch (type) {
27
28
  case GeneratorType.TYPES:
@@ -35,46 +36,35 @@ export class GenerationHandler {
35
36
  }
36
37
  }
37
38
 
38
- private finalizeInheritance(inheritanceTable: InheritanceTable): void {
39
- for (const clsName of Object.keys(inheritanceTable)) {
40
- let p: string | string[] = inheritanceTable[clsName][0]
41
- while (p) {
42
- p = inheritanceTable[p]
43
- if (p) {
44
- p = p[0]
45
- inheritanceTable[clsName].push(p)
46
- }
47
- }
48
- }
49
- }
50
-
51
- public async start(girModules: GirModule[], girModulesGrouped: GirModulesGrouped[]): Promise<void> {
52
- this.log.info(START_MODULE(this.config.environment, this.config.buildType))
39
+ public async start(girModules: GirModule[], registry: NSRegistry): Promise<void> {
40
+ this.log.info(START_MODULE)
53
41
 
54
42
  if (girModules.length == 0) {
55
43
  this.log.error(ERROR_NO_MODULE_SPECIFIED)
56
44
  }
57
45
 
58
- GirModule.allGirModules = girModules
59
-
60
46
  this.log.info(FILE_PARSING_DONE)
61
47
 
62
- const inheritanceTable: InheritanceTable = {}
63
- for (const girModule of girModules) girModule.init(inheritanceTable)
48
+ this.log.info(TSDATA_PARSING_DONE)
49
+
50
+ if (this.config.outdir) {
51
+ await mkdir(this.config.outdir, { recursive: true })
52
+ }
64
53
 
65
- this.finalizeInheritance(inheritanceTable)
54
+ // TODO: Put this somewhere that makes sense
55
+ registry.transform({
56
+ inferGenerics: true,
57
+ verbose: this.config.verbose,
58
+ })
66
59
 
67
- this.log.info(TSDATA_PARSING_DONE)
60
+ await this.generator.start(registry)
68
61
 
69
62
  for (const girModule of girModules) {
70
- if (this.config.outdir) {
71
- await mkdir(this.config.outdir, { recursive: true })
72
- }
73
63
  this.log.log(` - ${girModule.packageName} ...`)
74
- girModule.start(girModules)
64
+ await this.generator.generate(registry, girModule)
75
65
  }
76
66
 
77
- await this.generator.start(girModules, girModulesGrouped, inheritanceTable)
67
+ await this.generator.finish(registry, girModules)
78
68
 
79
69
  this.log.success(GENERATING_TYPES_DONE)
80
70
  }
@@ -3,9 +3,8 @@
3
3
  */
4
4
 
5
5
  import inquirer, { ListQuestion, Answers } from 'inquirer'
6
- import glob from 'tiny-glob'
7
- import { basename } from 'path'
8
- import { readFile } from 'fs/promises'
6
+ import { glob } from 'glob'
7
+ import { basename, join } from 'path'
9
8
  import { bold } from 'colorette'
10
9
  import {
11
10
  DependencyManager,
@@ -15,14 +14,13 @@ import {
15
14
  splitModuleName,
16
15
  union,
17
16
  isIterable,
18
- girParser,
19
17
  WARN_NO_GIR_FILE_FOUND_FOR_PACKAGE,
20
18
  } from '@ts-for-gir/lib'
21
19
  import { Config } from './config.js'
22
20
 
23
21
  import type {
24
22
  GirModulesGroupedMap,
25
- GenerateConfig,
23
+ OptionsGeneration,
26
24
  GirModuleResolvedBy,
27
25
  GirModulesGrouped,
28
26
  DependencyMap,
@@ -35,8 +33,8 @@ export class ModuleLoader {
35
33
  dependencyManager: DependencyManager
36
34
  /** Transitive module dependencies */
37
35
  modDependencyMap: DependencyMap = {}
38
- constructor(protected readonly config: GenerateConfig) {
39
- this.log = new Logger('', config.verbose, 'ModuleLoader')
36
+ constructor(protected readonly config: OptionsGeneration) {
37
+ this.log = new Logger(config.verbose, 'ModuleLoader')
40
38
  this.dependencyManager = DependencyManager.getInstance(config)
41
39
  }
42
40
 
@@ -176,7 +174,7 @@ export class ModuleLoader {
176
174
  * @param girModulesGroupedMap
177
175
  * @param packageName
178
176
  */
179
- protected findPackageNamesDependOnPackage(
177
+ protected findGirFilesDependOnPackage(
180
178
  girModulesGroupedMap: GirModulesGroupedMap,
181
179
  packageName: string,
182
180
  ): GirModuleResolvedBy[] {
@@ -201,13 +199,13 @@ export class ModuleLoader {
201
199
  * @param girModulesGroupedMap
202
200
  * @param packageName
203
201
  */
204
- protected findPackageNamesDependOnPackages(
202
+ protected findGirFilesDependOnPackages(
205
203
  girModulesGroupedMap: GirModulesGroupedMap,
206
204
  packageNames: string[],
207
205
  ): GirModuleResolvedBy[] {
208
206
  let girModules: GirModuleResolvedBy[] = []
209
207
  for (const packageName of packageNames) {
210
- girModules = girModules.concat(this.findPackageNamesDependOnPackage(girModulesGroupedMap, packageName))
208
+ girModules = [...girModules, ...this.findGirFilesDependOnPackage(girModulesGroupedMap, packageName)]
211
209
  }
212
210
  return girModules
213
211
  }
@@ -270,10 +268,7 @@ export class ModuleLoader {
270
268
  while (goBack) {
271
269
  versionAnswer = await this.askForVersionsPrompt(girModulesGrouped)
272
270
  // Check modules that depend on the unchosen modules
273
- wouldIgnoreDeps = this.findPackageNamesDependOnPackages(
274
- girModulesGroupedMap,
275
- versionAnswer.unselected,
276
- )
271
+ wouldIgnoreDeps = this.findGirFilesDependOnPackages(girModulesGroupedMap, versionAnswer.unselected)
277
272
  // Do not check dependencies that have already been ignored
278
273
  wouldIgnoreDeps = wouldIgnoreDeps.filter((dep) => !ignore.includes(dep.packageName))
279
274
  ignoreDepsAnswer = await this.askIgnoreDepsPrompt(wouldIgnoreDeps)
@@ -356,7 +351,7 @@ export class ModuleLoader {
356
351
  * @param girModule
357
352
  */
358
353
  protected extendDependencyMapByGirModule(girModule: GirModule): void {
359
- this.modDependencyMap[girModule.packageName] = girModule.dependencies
354
+ this.modDependencyMap[girModule.packageName] = girModule.dependencies!
360
355
  }
361
356
 
362
357
  /**
@@ -364,11 +359,11 @@ export class ModuleLoader {
364
359
  * is required so that all dependencies can be found internally when generating the dependency imports for the module .d.ts file
365
360
  * @param girModules
366
361
  */
367
- protected setTraverseDependenciesForModules(girModules: GirModuleResolvedBy[]): void {
362
+ protected async initGirModules(girModules: GirModuleResolvedBy[]): Promise<void> {
368
363
  for (const girModule of girModules) {
369
364
  const result: { [name: string]: Dependency } = {}
370
365
  this.traverseDependencies(girModule.packageName, result)
371
- girModule.module.transitiveDependencies = Object.values(result)
366
+ await girModule.module.initTransitiveDependencies(Object.values(result))
372
367
  }
373
368
  }
374
369
 
@@ -383,10 +378,8 @@ export class ModuleLoader {
383
378
  return null
384
379
  }
385
380
 
386
- this.log.log(`Parsing ${dependency.path}...`)
387
- const fileContents = await readFile(dependency.path, 'utf8')
388
- const result = girParser(fileContents)
389
- const girModule = new GirModule(result, this.config)
381
+ this.log.log(`Loading ${dependency.packageName}...`)
382
+ const girModule = await GirModule.load(dependency, this.config, this.dependencyManager)
390
383
  // Figure out transitive module dependencies
391
384
  this.extendDependencyMapByGirModule(girModule)
392
385
  return girModule
@@ -451,6 +444,7 @@ export class ModuleLoader {
451
444
  packageName: girModule.packageName,
452
445
  module: girModule,
453
446
  resolvedBy,
447
+ path: dependency.path,
454
448
  }
455
449
  girModules.push(addModule)
456
450
  newModuleFound = true
@@ -466,21 +460,13 @@ export class ModuleLoader {
466
460
  }
467
461
 
468
462
  // Figure out transitive module dependencies
469
- this.setTraverseDependenciesForModules(girModules)
463
+ await this.initGirModules(girModules)
470
464
 
471
465
  // Load girModules for dependencies
472
466
  for (const girModule of girModules) {
473
467
  // Load dependencies
474
468
  const transitiveDependencies = girModule.module.transitiveDependencies
475
469
  if (transitiveDependencies.length > 0) {
476
- for (const transitiveDependency of transitiveDependencies) {
477
- if (ignoreDependencies.includes(transitiveDependency.packageName)) {
478
- this.log.warn(
479
- `Load dependency "${transitiveDependency.packageName}" which is in the ignore list, if this should really be ignored also ignore "${girModule.packageName}"`,
480
- )
481
- }
482
- }
483
-
484
470
  await this.loadGirModules(
485
471
  transitiveDependencies,
486
472
  ignoreDependencies,
@@ -490,6 +476,7 @@ export class ModuleLoader {
490
476
  )
491
477
  }
492
478
  }
479
+
493
480
  return {
494
481
  loaded: girModules,
495
482
  failed: failedGirModules,
@@ -501,56 +488,65 @@ export class ModuleLoader {
501
488
  * @param modules
502
489
  * @param ignore
503
490
  */
504
- protected async findPackageNames(modules: string[], ignore: string[] = []): Promise<Set<string>> {
505
- const foundModules = new Set<string>()
506
-
507
- for (let i = 0; i < modules.length; i++) {
508
- if (modules[i]) {
509
- const filename = `${modules[i]}.gir`
510
- let files: string[] = []
511
- for (const girDirectory of this.config.girDirectories) {
512
- try {
513
- files = files.concat(await glob(filename, { cwd: girDirectory }))
514
- } catch (error) {
515
- this.log.warn(`Error on finding "${filename}" in "${girDirectory}"`, error)
516
- }
517
- }
491
+ protected async findGirFiles(globPackageNames: string[], ignore: string[] = []): Promise<Set<string>> {
492
+ const foundFiles = new Set<string>()
518
493
 
519
- let globModules = files.map((file) => basename(file, '.gir'))
520
- // Filter out the ignored modules
521
- globModules = globModules.filter((mod) => {
522
- const isIgnored = ignore.includes(mod)
523
- if (isIgnored) {
524
- this.log.warn(`Ignore ${mod}`)
525
- }
526
- return !isIgnored
527
- })
528
- globModules.forEach((mod) => foundModules.add(mod))
494
+ for (let i = 0; i < globPackageNames.length; i++) {
495
+ if (!globPackageNames[i]) {
496
+ continue
529
497
  }
498
+ const filename = `${globPackageNames[i]}.gir`
499
+ const pattern = this.config.girDirectories.map((girDirectory) => join(girDirectory, filename))
500
+ const ignoreGirs = ignore.map((girDirectory) => girDirectory + '.gir')
501
+ const files = await glob(pattern, { ignore: ignoreGirs })
502
+ files.forEach((file) => foundFiles.add(file))
530
503
  }
531
- return foundModules
504
+
505
+ return foundFiles
532
506
  }
533
507
 
534
- protected packageNamesToDependencies(packageNames: Set<string>): Dependency[] {
535
- return Array.from(packageNames).map((packageName) => {
508
+ protected async girFilePathToDependencies(girFiles: Set<string>): Promise<Dependency[]> {
509
+ const dependencies: Dependency[] = []
510
+ for (const girFile of girFiles) {
511
+ const packageName = basename(girFile, '.gir')
536
512
  const { namespace, version } = splitModuleName(packageName)
537
- return this.dependencyManager.get(namespace, version)
538
- })
513
+ const dep = await this.dependencyManager.get(namespace, version)
514
+ dependencies.push(dep)
515
+ }
516
+
517
+ return dependencies
539
518
  }
540
519
 
541
520
  /**
542
- * Loads all found `packageNames` and sorts out those that the user does not want to use including their dependencies
521
+ * Loads all found `packageNames`
543
522
  * @param girDirectories
544
523
  * @param packageNames
524
+ * @param doNotAskForVersionOnConflict Set this to false if you want to get a prompt for each version conflict
545
525
  */
546
526
  public async getModulesResolved(
547
527
  packageNames: string[],
548
528
  ignore: string[] = [],
549
529
  doNotAskForVersionOnConflict = true,
550
530
  ): Promise<{ keep: GirModuleResolvedBy[]; grouped: GirModulesGroupedMap; ignore: string[]; failed: Set<string> }> {
551
- const foundPackageNames = await this.findPackageNames(packageNames, ignore)
552
- const dependencies = this.packageNamesToDependencies(foundPackageNames)
553
- const { loaded, failed } = await this.loadGirModules(dependencies, ignore)
531
+ const girFiles = await this.findGirFiles([...packageNames], ignore)
532
+ // Always require these because GJS does...
533
+ const GLib = await this.dependencyManager.get('GLib', '2.0')
534
+ const Gio = await this.dependencyManager.get('Gio', '2.0')
535
+ const GObject = await this.dependencyManager.get('GObject', '2.0')
536
+
537
+ const dependencies = await this.girFilePathToDependencies(girFiles)
538
+
539
+ const { loaded, failed } = await this.loadGirModules(
540
+ [
541
+ GLib,
542
+ Gio,
543
+ GObject,
544
+ ...dependencies.filter(
545
+ (dep) => dep.namespace !== 'GLib' && dep.namespace !== 'Gio' && dep.namespace !== 'GObject',
546
+ ),
547
+ ],
548
+ ignore,
549
+ )
554
550
  let keep: GirModuleResolvedBy[] = []
555
551
  if (doNotAskForVersionOnConflict) {
556
552
  keep = loaded
@@ -566,7 +562,7 @@ export class ModuleLoader {
566
562
  }
567
563
 
568
564
  /**
569
- * Find modules with the possibility to use wild cards for module names. E.g. `Gtk*` or `'*'`
565
+ * Find modules
570
566
  * @param girDirectories
571
567
  * @param modules
572
568
  */
@@ -574,10 +570,17 @@ export class ModuleLoader {
574
570
  modules: string[],
575
571
  ignore: string[] = [],
576
572
  ): Promise<{ grouped: GirModulesGroupedMap; loaded: GirModuleResolvedBy[]; failed: string[] }> {
577
- const foundPackageNames = await this.findPackageNames(modules, ignore)
578
- const dependencies = this.packageNamesToDependencies(foundPackageNames)
573
+ const girFiles = await this.findGirFiles(modules, ignore)
574
+ const dependencies = await this.girFilePathToDependencies(girFiles)
579
575
  const { loaded, failed } = await this.loadGirModules(dependencies, ignore)
580
576
  const grouped = this.groupGirFiles(loaded)
581
577
  return { grouped, loaded, failed: Array.from(failed) }
582
578
  }
579
+
580
+ /** Start parsing the gir modules */
581
+ public parse(girModules: GirModuleResolvedBy[]): void {
582
+ for (const girModule of girModules) {
583
+ girModule.module.parse()
584
+ }
585
+ }
583
586
  }
package/src/start.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import yargs from 'yargs'
3
3
  import { hideBin } from 'yargs/helpers'
4
4
 
5
- import { generate, list, doc } from './commands/index.js'
5
+ import { generate, list, doc, copy } from './commands/index.js'
6
6
  import { Config } from './config.js'
7
7
 
8
8
  void yargs(hideBin(process.argv))
@@ -11,6 +11,7 @@ void yargs(hideBin(process.argv))
11
11
  .usage(Config.usage)
12
12
  .command(generate.command, generate.description, generate.builder, generate.handler)
13
13
  .command(list.command, list.description, list.builder, list.handler)
14
+ .command(copy.command, copy.description, copy.builder, copy.handler)
14
15
  .command(doc.command, doc.description, doc.builder, doc.handler)
15
16
  .demandCommand(1)
16
17
  .help().argv