UNPKG

6.81 kBPlain TextView Raw
1#!/usr/bin/env node
2
3import * as chalk from 'chalk';
4import * as yargsParser from 'yargs-parser';
5
6import * as AutoPublishIfApplicable from './commands/internal/auto-publish-if-applicable';
7import * as CommitAndTagVersion from './commands/commit-and-tag-version';
8import * as CopyAndCommitVersionForSubpackage from './commands/copy-and-commit-version-for-subpackage';
9import * as CreateChangelog from './commands/internal/create-changelog';
10import * as CreateReleaseAnnouncement from './commands/internal/create-release-announcement';
11import * as FailOnPreVersionDependencies from './commands/fail-on-pre-version-dependencies';
12import * as NpmInstallOnly from './commands/npm-install-only';
13import * as PrepareVersion from './commands/prepare-version';
14import * as PublishNpmPackage from './commands/publish-npm-package';
15import * as SetupGitAndNpmConnections from './commands/internal/setup-git-and-npm-connections';
16import * as UpdateGithubRelease from './commands/update-github-release';
17import * as UpgradeDependenciesWithPreVersions from './commands/upgrade-dependencies-with-pre-versions';
18import * as PublishReleasenotesOnSlack from './commands/publish-releasenotes-on-slack';
19import * as GetVersion from './commands/get-version';
20import * as SetVersion from './commands/set-version';
21import * as IsNugetPackagePublished from './legacy/is-nuget-package-published';
22import * as ReplaceDistTagsWithRealVersions from './commands/replace-dist-tags-with-real-versions';
23
24import { getGitBranch } from './git/git';
25import { PRIMARY_BRANCHES } from './versions/increment_version';
26import { PACKAGE_MODE_DOTNET, PACKAGE_MODE_NODE, PACKAGE_MODE_PYTHON } from './contracts/modes';
27
28const COMMAND_HANDLERS = {
29 'commit-and-tag-version': CommitAndTagVersion,
30 'copy-and-commit-version-for-subpackage': CopyAndCommitVersionForSubpackage,
31 'fail-on-pre-version-dependencies': FailOnPreVersionDependencies,
32 'prepare-version': PrepareVersion,
33 'publish-npm-package': PublishNpmPackage,
34 'npm-install-only': NpmInstallOnly,
35 'update-github-release': UpdateGithubRelease,
36 'upgrade-dependencies-with-pre-versions': UpgradeDependenciesWithPreVersions,
37 'publish-releasenotes-on-slack': PublishReleasenotesOnSlack,
38 'get-version': GetVersion,
39 'set-version': SetVersion,
40 'is-nuget-package-published': IsNugetPackagePublished,
41 'replace-dist-tags-with-real-versions': ReplaceDistTagsWithRealVersions,
42};
43
44// Internal commands are only used to develop ci_tools and are not intended for public consumption.
45const INTERNAL_COMMAND_HANDLERS = {
46 'auto-publish-if-applicable': AutoPublishIfApplicable,
47 'create-changelog': CreateChangelog,
48 'create-release-announcement': CreateReleaseAnnouncement,
49 'update-github-release': UpdateGithubRelease,
50 'setup-git-and-npm-connections': SetupGitAndNpmConnections,
51};
52
53const DEFAULT_MODE = PACKAGE_MODE_NODE;
54
55async function run(originalArgv: string[]): Promise<void> {
56 const [, , ...args] = originalArgv;
57 const argv = yargsParser(args, { alias: { help: ['h'] }, default: { mode: DEFAULT_MODE } });
58 const mode = argv.mode;
59
60 if (args.length === 0 || (args.length === 1 && argv.help === true)) {
61 printHelp();
62 process.exit(1);
63 }
64
65 if (mode !== PACKAGE_MODE_NODE && mode !== PACKAGE_MODE_DOTNET && mode !== PACKAGE_MODE_PYTHON) {
66 console.error('Mode must be set to `dotnet`, `node` or `python`. \nDefault is `node`');
67 process.exit(1);
68 }
69
70 const [commandName, ...restArgs] = args;
71
72 const commandHandler = COMMAND_HANDLERS[commandName] || INTERNAL_COMMAND_HANDLERS[commandName];
73
74 if (commandHandler == null) {
75 console.error(`No handler found for command: ${commandName}`);
76 process.exit(1);
77 }
78
79 enforceUniversalCommandLineSwitches(commandHandler, commandName, args);
80
81 try {
82 await commandHandler.run(...restArgs);
83 } catch (error) {
84 console.error(error);
85 process.exit(1);
86 }
87}
88
89function enforceUniversalCommandLineSwitches(commandHandler: any, commandName: string, args: string[]): void {
90 const badge = `[${commandName}]\t`;
91 const argv = yargsParser(args, { alias: { help: ['h'] } });
92
93 if (argv.help) {
94 printHelpForCommand(commandHandler, commandName);
95 process.exit(0);
96 }
97
98 if (argv.onlyOnPrimaryBranches && argv.exceptOnPrimaryBranches) {
99 console.error(chalk.red(`${badge}Both --only-on-primary-branches and --except-on-primary-branches given.`));
100 console.error(chalk.red(`${badge}This can not work! Aborting.`));
101 process.exit(1);
102 } else if (argv.onlyOnPrimaryBranches) {
103 ensureOnPrimaryBranchOrExit(badge);
104 } else if (argv.exceptOnPrimaryBranches) {
105 ensureNotOnPrimaryBranchOrExit(badge);
106 }
107
108 if (argv.onlyOnBranch) {
109 ensureOnBranchOrExit(badge, argv.onlyOnBranch);
110 }
111}
112
113function ensureOnBranchOrExit(badge: string, requestedBranchName: string): void {
114 const branchName = getGitBranch();
115 const currentlyOnBranch = requestedBranchName === branchName;
116
117 if (!currentlyOnBranch) {
118 console.log(chalk.yellow(`${badge}--only-on-branch given: ${requestedBranchName}`));
119 console.log(chalk.yellow(`${badge}Current branch is '${branchName}'.`));
120 console.log(chalk.yellow(`${badge}Nothing to do here. Exiting.`));
121
122 process.exit(0);
123 }
124}
125
126function ensureOnPrimaryBranchOrExit(badge: string): void {
127 const branchName = getGitBranch();
128 const currentlyOnPrimaryBranch = PRIMARY_BRANCHES.includes(branchName);
129
130 if (!currentlyOnPrimaryBranch) {
131 console.log(chalk.yellow(`${badge}--only-on-primary-branches given.`));
132 console.log(
133 chalk.yellow(`${badge}Current branch is '${branchName}' (primary branches are ${PRIMARY_BRANCHES.join(', ')}).`)
134 );
135 console.log(chalk.yellow(`${badge}Nothing to do here. Exiting.`));
136
137 process.exit(0);
138 }
139}
140
141function ensureNotOnPrimaryBranchOrExit(badge: string): void {
142 const branchName = getGitBranch();
143 const currentlyOnPrimaryBranch = PRIMARY_BRANCHES.includes(branchName);
144
145 if (currentlyOnPrimaryBranch) {
146 console.log(chalk.yellow(`${badge}--except-on-primary-branches given.`));
147 console.log(
148 chalk.yellow(`${badge}Current branch is '${branchName}' (primary branches are ${PRIMARY_BRANCHES.join(', ')}).`)
149 );
150 console.log(chalk.yellow(`${badge}Nothing to do here. Exiting.`));
151
152 process.exit(0);
153 }
154}
155
156function printHelp(): void {
157 console.log('Usage: ci_tools <COMMAND>');
158 console.log('');
159 console.log('COMMAND can be any of:');
160 Object.keys(COMMAND_HANDLERS).forEach((commandName: string): void => console.log(` ${commandName}`));
161}
162
163function printHelpForCommand(commandHandler: any, commandName: string): void {
164 if (commandHandler.printHelp != null) {
165 commandHandler.printHelp();
166 return;
167 }
168
169 console.log(`Usage: ci_tools ${commandName}`);
170 console.log('');
171 console.log('No further instructions available.');
172}
173
174run(process.argv);