• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gturi / nca / 8277672099

14 Mar 2024 08:32AM UTC coverage: 86.091% (+0.1%) from 85.979%
8277672099

push

github

web-flow
Merge pull request #213 from gturi/feature/nca-alias-command

Feature/nca alias command

221 of 316 branches covered (69.94%)

Branch coverage included in aggregate %.

598 of 661 new or added lines in 62 files covered. (90.47%)

1 existing line in 1 file now uncovered.

1116 of 1237 relevant lines covered (90.22%)

1211.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/command/alias/add-alias-command.ts
1
import path from 'path';
161✔
2
import yargs from "yargs";
3
import shelljs from 'shelljs';
161✔
4
import { PositionalArgument } from '../../model/api/positional-argument';
5
import { PositionalArgumentType } from '../../model/api/positional-argument-type';
161✔
6
import { AnyObj } from "../../util/custom-types";
7
import { YargsUtils } from '../../util/yargs-utils';
161✔
8
import { NcaConfig } from "../../config/nca-config";
161✔
9
import { StringUtils } from "../../util/string-utils";
161✔
10
import { FileSystemUtils } from '../../util/file-system-utils';
161✔
11
import { PackageJsonLoader } from '../../loader/package-json-loader';
161✔
12
import { NodeUtils } from '../../util/node-utils';
161✔
13
import { hideBin } from 'yargs/helpers';
161✔
14
import { ProcessArgumentUtils } from '../../util/process-arguments-utils';
161✔
15
import { NcaCommandTemplate } from '../../model/internal/nca-command-template';
161✔
16

17
export class AddAliasCommand extends NcaCommandTemplate {
161✔
18

19
  override getCommandName(): string {
20
    return YargsUtils.getCommand('add', this.getPositionalArguments());
161✔
21
  }
22

23
  override getCommandDescription(): string {
24
    return 'create a global alias for a nca command which can be invoked without "nca" prefix';
161✔
25
  }
26

27
  override getPositionalArguments(): PositionalArgument[] {
28
    const positionalArgument: PositionalArgument = {
322✔
29
      name: 'command',
30
      description: 'nca command that will be executed when using the alias',
31
      type: PositionalArgumentType.StringList,
32
      required: true
33
    }
34
    return [positionalArgument];
322✔
35
  }
36

37
  override getHandler<T = AnyObj>(args: yargs.ArgumentsCamelCase<T>): void {
38
    const commandArray = this.getCommandArray();
29✔
39

40
    // TODO: it would be nice to allow to specify the alias name using the -n option
41
    const aliasName = this.getAliasName(args.n as string | undefined, commandArray);
29✔
42

43
    this.updateAliasPackageJsonWithNewAlias(aliasName);
29✔
44

45
    this.createScriptToExecuteNcaCommand(aliasName, commandArray);
29✔
46

47

48
    NodeUtils.linkLocalAliases();
29✔
49

50
    console.log(`Alias '${aliasName}' successfully created`);
29✔
51
  }
52

53
  private getCommandArray(): string[] {
54
    const commandArray = hideBin(process.argv);
29✔
55

56
    commandArray.splice(0, 2); // remove ['alias', 'add']
29✔
57

58
    this.removeNcaPrefix(commandArray);
29✔
59

60
    return ProcessArgumentUtils.sanitizeCommandArray(commandArray);
29✔
61
  }
62

63
  private removeNcaPrefix(commandArray: string[]): void {
64
    if (commandArray.length > 0 && commandArray[0] === 'nca') {
29✔
65
      commandArray.shift();
10✔
66
    }
67

68
    if (commandArray.length === 0) {
29!
NEW
69
      throw new Error('Command cannot be empty');
×
70
    }
71
  }
72

73
  private getAliasName(name: string | undefined, commandArray: string[]): string {
74
    return StringUtils.ifNotEmptyOrDefault(name, () => commandArray[0]);
29✔
75
  }
76

77
  private getAliasCode(commandArray: string[]): string {
78
    const command = JSON.stringify(commandArray);
29✔
79
    return [
29✔
80
      `#!/usr/bin/env node`,
81
      '',
82
      `'use strict';`,
83
      '',
84
      '',
85
      `const commandArray = ${command};`,
86
      '',
87
      `if (require.main === module) {`,
88
      `  const spawnSync = require('child_process').spawnSync;`,
89
      '',
90
      `  const args = process.argv.slice(2)`,
91
      // wrap the args between double quotes if they contain a space
92
      '    .map(arg => /\\s/.test(arg) ? `"${arg}"` : arg);',
93
      '',
94
      `  spawnSync('nca', commandArray.concat(args), { stdio: 'inherit', shell: true });`,
95
      `} else {`,
96
      `  exports.commandArray = commandArray;`,
97
      `}`
98
    ].join('\n') + '\n';
99
  }
100

101
  private updateAliasPackageJsonWithNewAlias(aliasName: string): void {
102
    const packageJsonLoader = new PackageJsonLoader();
29✔
103

104
    packageJsonLoader.addAlias(aliasName);
29✔
105

106
    packageJsonLoader.writeOnDisk();
29✔
107
  }
108

109
  private createScriptToExecuteNcaCommand(aliasName: string, commandArray: string[]) {
110
    const aliasCode = this.getAliasCode(commandArray);
29✔
111
    const aliasCodePath = path.join(NcaConfig.getAliasSourceFolderPath(), aliasName);
29✔
112

113
    FileSystemUtils.createFolderIfNotExists(NcaConfig.getAliasSourceFolderPath());
29✔
114
    FileSystemUtils.writeFile(aliasCodePath, aliasCode);
29✔
115
    shelljs.chmod('u+x', aliasCodePath);
29✔
116
  }
117
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc