File: Prepare.ts

package info (click to toggle)
node-corepack 0.24.0-5
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 262,916 kB
  • sloc: javascript: 94; makefile: 18; sh: 12
file content (109 lines) | stat: -rw-r--r-- 3,961 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import {Command, Option, UsageError} from 'clipanion';
import {mkdir}                       from 'fs/promises';
import path                          from 'path';

import * as folderUtils              from '../../folderUtils';
import {Context}                     from '../../main';
import * as specUtils                from '../../specUtils';
import {Descriptor}                  from '../../types';

export class PrepareCommand extends Command<Context> {
  static paths = [
    [`prepare`],
  ];

  activate = Option.Boolean(`--activate`, false, {
    description: `If true, this release will become the default one for this package manager`,
  });

  all = Option.Boolean(`--all`, false, {
    description: `If true, all available default package managers will be installed`,
  });

  json = Option.Boolean(`--json`, false, {
    description: `If true, the output will be the path of the generated tarball`,
  });

  output = Option.String(`-o,--output`, {
    description: `If true, the installed package managers will also be stored in a tarball`,
    tolerateBoolean: true,
  });

  specs = Option.Rest();

  async execute() {
    if (this.all && this.specs.length > 0)
      throw new UsageError(`The --all option cannot be used along with an explicit package manager specification`);

    const specs: Array<string | Descriptor> = this.all
      ? await this.context.engine.getDefaultDescriptors()
      : this.specs;

    const installLocations: Array<string> = [];

    if (specs.length === 0) {
      const lookup = await specUtils.loadSpec(this.context.cwd);
      switch (lookup.type) {
        case `NoProject`:
          throw new UsageError(`Couldn't find a project in the local directory - please explicit the package manager to pack, or run this command from a valid project`);

        case `NoSpec`:
          throw new UsageError(`The local project doesn't feature a 'packageManager' field - please explicit the package manager to pack, or update the manifest to reference it`);

        default: {
          specs.push(lookup.spec);
        }
      }
    }

    for (const request of specs) {
      const spec = typeof request === `string`
        ? specUtils.parseSpec(request, `CLI arguments`, {enforceExactVersion: false})
        : request;

      const resolved = await this.context.engine.resolveDescriptor(spec, {allowTags: true});
      if (resolved === null)
        throw new UsageError(`Failed to successfully resolve '${spec.range}' to a valid ${spec.name} release`);

      if (!this.json) {
        if (this.activate) {
          this.context.stdout.write(`Preparing ${spec.name}@${spec.range} for immediate activation...\n`);
        } else {
          this.context.stdout.write(`Preparing ${spec.name}@${spec.range}...\n`);
        }
      }

      const installSpec = await this.context.engine.ensurePackageManager(resolved);
      installLocations.push(installSpec.location);

      if (this.activate) {
        await this.context.engine.activatePackageManager(resolved);
      }
    }

    if (this.output) {
      const outputName = typeof this.output === `string`
        ? this.output
        : `corepack.tgz`;

      const baseInstallFolder = folderUtils.getInstallFolder();
      const outputPath = path.resolve(this.context.cwd, outputName);

      if (!this.json)
        this.context.stdout.write(`Packing the selected tools in ${path.basename(outputPath)}...\n`);

      const {default: tar} = await import(`tar`);
      // Recreate the folder in case it was deleted somewhere else:
      await mkdir(baseInstallFolder, {recursive: true});
      await tar.c({gzip: true, cwd: baseInstallFolder, file: path.resolve(outputPath)}, installLocations.map(location => {
        return path.relative(baseInstallFolder, location);
      }));

      if (this.json) {
        this.context.stdout.write(`${JSON.stringify(outputPath)}\n`);
      } else {
        this.context.stdout.write(`All done!\n`);
      }
    }
  }
}