xref: /expo/tools/src/promote-packages/helpers.ts (revision a272999e)
1import chalk from 'chalk';
2
3import * as Changelogs from '../Changelogs';
4import { GitDirectory } from '../Git';
5import logger from '../Logger';
6import { Package } from '../Packages';
7import { Parcel } from './types';
8
9const { cyan, green, magenta, red, gray } = chalk;
10
11/**
12 * Wraps `Package` object into a parcels - convenient wrapper providing more package-related helpers.
13 */
14export async function createParcelAsync(pkg: Package): Promise<Parcel> {
15  return {
16    pkg,
17    pkgView: await pkg.getPackageViewAsync(),
18    changelog: Changelogs.loadFrom(pkg.changelogPath),
19    gitDir: new GitDirectory(pkg.path),
20    state: {},
21  };
22}
23
24/**
25 * Formats version change from version A to version B.
26 */
27export function formatVersionChange(
28  fromVersion: string | null | undefined,
29  toVersion: string
30): string {
31  const from = fromVersion ? cyan.bold(fromVersion) : gray.bold('none');
32  const to = cyan.bold(toVersion);
33  return `from ${from} to ${to}`;
34}
35
36/**
37 * Prints a lists of packages to promote or demote.
38 */
39export function printPackagesToPromote(parcels: Parcel[]): void {
40  const toPromote = parcels.filter(({ state }) => !state.isDemoting);
41  const toDemote = parcels.filter(({ state }) => state.isDemoting);
42
43  printPackagesToPromoteInternal(
44    toPromote,
45    `Following packages would be ${green.bold('promoted')}:`
46  );
47  printPackagesToPromoteInternal(
48    toDemote,
49    `Following packages could be ${red.bold('demoted')} ${gray(`(requires --demote flag)`)}:`
50  );
51}
52
53function printPackagesToPromoteInternal(parcels: Parcel[], headerText: string): void {
54  if (parcels.length > 0) {
55    logger.log('  ', magenta(headerText));
56
57    for (const { pkg, state } of parcels) {
58      logger.log(
59        '    ',
60        green(pkg.packageName),
61        formatVersionChange(state.versionToReplace, pkg.packageVersion)
62      );
63    }
64  }
65}
66