Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: migrate upgrade command to TS and remove legacy implementation #684

Merged
merged 2 commits into from
Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
],
],
plugins: [
require.resolve('@babel/plugin-proposal-class-properties'),
require.resolve('@babel/plugin-transform-strict-mode'),
[require.resolve('@babel/plugin-transform-modules-commonjs'), {lazy: true}],
[
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"micromatch": "^3.1.10",
"mkdirp": "^0.5.1",
"string-length": "^2.0.0",
"typescript": "^3.4.5"
"typescript": "^3.6.2"
},
"devDependencies": {
"@babel/plugin-proposal-class-properties": "^7.5.5"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we need it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests are failing without this transform, not yet sure why

}
}
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"react-native": "^0.60.0"
},
"devDependencies": {
"@types/semver": "^6.0.2",
"slash": "^3.0.0",
"snapshot-diff": "^0.5.0"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import commander from 'commander';
import path from 'path';

import type {CommandT, ConfigT} from 'types';

// $FlowFixMe - converted to TS
import commands from './commands';
import init from './commands/init/initCompat';
import assertRequiredOptions from './tools/assertRequiredOptions';
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/doctor/doctor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import chalk from 'chalk';
import envinfo from 'envinfo';
import {logger} from '@react-native-community/cli-tools';
import {getHealthchecks, HEALTHCHECK_TYPES} from './healthchecks';
// $FlowFixMe - converted to TS
import {getLoader} from '../../tools/loader';
import printFixOptions, {KEYS} from './printFixOptions';
import runAutomaticFix, {AUTOMATIC_FIX_LEVELS} from './runAutomaticFix';
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/doctor/healthchecks/cocoaPods.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import {isSoftwareInstalled} from '../checkInstallation';
// $FlowFixMe - converted to TS
import {installCocoaPods} from '../../../tools/installPods';
import {type HealthCheckInterface} from '../types';

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/doctor/healthchecks/common.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import logger from '@react-native-community/cli-tools/build/logger';
import {logger} from '@react-native-community/cli-tools';
import chalk from 'chalk';

// Space is necessary to keep correct ordering on screen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
PACKAGE_MANAGERS,
doesSoftwareNeedToBeFixed,
} from '../checkInstallation';
// $FlowFixMe - converted to TS
import {install} from '../../../tools/install';
import type {EnvironmentInfo, HealthCheckInterface} from '../types';

Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/doctor/healthchecks/watchman.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import Ora from 'ora';
import versionRanges from '../versionRanges';
import {doesSoftwareNeedToBeFixed} from '../checkInstallation';
// $FlowFixMe - converted to TS
import {install} from '../../../tools/install';
import type {EnvironmentInfo} from '../types';

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/doctor/runAutomaticFix.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import chalk from 'chalk';
import ora from 'ora';
import logger from '../../tools/logger';
import {logger} from '@react-native-community/cli-tools';
import {HEALTHCHECK_TYPES} from './healthchecks';
import type {EnvironmentInfo} from './types';

Expand Down
32 changes: 0 additions & 32 deletions packages/cli/src/commands/index.js

This file was deleted.

40 changes: 40 additions & 0 deletions packages/cli/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {Command} from '@react-native-community/cli-types';

// @ts-ignore - JS file
import server from './server/server';
// @ts-ignore - JS file
import bundle from './bundle/bundle';
// @ts-ignore - JS file
import ramBundle from './bundle/ramBundle';
// @ts-ignore - JS file
import link from './link/link'; // eslint-disable-line
// @ts-ignore - JS file
import unlink from './link/unlink'; // eslint-disable-line
// @ts-ignore - JS file
import install from './install/install'; // eslint-disable-line
// @ts-ignore - JS file
import uninstall from './install/uninstall'; // eslint-disable-line
import upgrade from './upgrade/upgrade';
// @ts-ignore - JS file
import info from './info/info'; // eslint-disable-line
// @ts-ignore - JS file
import config from './config/config'; // eslint-disable-line
// @ts-ignore - JS file
import init from './init';
// @ts-ignore - JS file
import doctor from './doctor';

export default [
server,
bundle,
ramBundle,
link,
unlink,
install,
uninstall,
upgrade,
info,
config,
init,
doctor,
] as Command[];
2 changes: 2 additions & 0 deletions packages/cli/src/commands/init/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import {
} from './template';
import {changePlaceholderInTemplate} from './editTemplate';
import * as PackageManager from '../../tools/packageManager';
// $FlowFixMe - converted to TS
import installPods from '../../tools/installPods';
import {processTemplateName} from './templateName';
import banner from './banner';
// $FlowFixMe - converted to TS
import {getLoader} from '../../tools/loader';
import {CLIError} from '@react-native-community/cli-tools';

Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/commands/link/__tests__/link-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import makeHook from '../makeHook';

jest.mock('chalk', () => ({grey: str => str, bold: str => str}));
jest.mock('../../../tools/config');
jest.mock('../../../tools/logger');
jest.mock('../makeHook', () => {
return jest.fn(() => {
return jest.fn(() => Promise.resolve());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// @flow
import execa from 'execa';
import path from 'path';
import fs from 'fs';
import snapshotDiff from 'snapshot-diff';
import stripAnsi from 'strip-ansi';
import upgrade from '../upgrade';
import {fetch, logger} from '@react-native-community/cli-tools';
import loadConfig from '../../../tools/config';
import loadConfig from '../../../tools/config'; // eslint-disable-line
import merge from '../../../tools/merge';

jest.mock('https');
Expand Down Expand Up @@ -56,7 +55,9 @@ jest.mock('@react-native-community/cli-tools', () => ({
}));

const mockFetch = (value = '', status = 200) => {
(fetch: any).mockImplementation(() => Promise.resolve({data: value, status}));
(fetch as jest.Mock).mockImplementation(() =>
Promise.resolve({data: value, status}),
);
};

const mockExecaDefault = (command, args) => {
Expand Down Expand Up @@ -85,9 +86,6 @@ const currentVersion = '0.57.8';
const newVersion = '0.58.4';
const olderVersion = '0.56.0';
const ctx = loadConfig();
const opts = {
legacy: false,
};

const samplePatch = jest
.requireActual('fs')
Expand All @@ -101,34 +99,30 @@ const flushOutput = () => stripAnsi(logs.join('\n'));
beforeEach(() => {
jest.clearAllMocks();
jest.restoreAllMocks();
// $FlowFixMe
fs.writeFileSync = jest.fn(filename => mockPushLog('[fs] write', filename));
// $FlowFixMe
fs.unlinkSync = jest.fn((...args) => mockPushLog('[fs] unlink', args));
logs = [];
(execa: any).mockImplementation(mockExecaDefault);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaDefault);
Object.defineProperty(process, 'platform', {
value: 'darwin',
});
});

afterEach(() => {
// $FlowFixMe
fs.writeFileSync = jest.requireMock('fs').writeFileSync;
// $FlowFixMe
fs.unlinkSync = jest.requireMock('fs').unlinkSync;
});

test('uses latest version of react-native when none passed', async () => {
await upgrade.func([], ctx, opts);
await upgrade.func([], ctx);
expect(execa).toBeCalledWith('npm', ['info', 'react-native', 'version']);
}, 60000);

test('applies patch in current working directory when nested', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation(mockExecaNested);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaNested);
const config = {...ctx, root: '/project/root/NestedApp'};
await upgrade.func([newVersion], config, opts);
await upgrade.func([newVersion], config);

expect(execa).toBeCalledWith('git', [
'apply',
Expand All @@ -141,33 +135,33 @@ test('applies patch in current working directory when nested', async () => {
});

test('errors when invalid version passed', async () => {
await upgrade.func(['next'], ctx, opts);
await upgrade.func(['next'], ctx);
expect(logger.error).toBeCalledWith(
'Provided version "next" is not allowed. Please pass a valid semver version',
);
}, 60000);

test('errors when older version passed', async () => {
await upgrade.func([olderVersion], ctx, opts);
await upgrade.func([olderVersion], ctx);
expect(logger.error).toBeCalledWith(
`Trying to upgrade from newer version "${currentVersion}" to older "${olderVersion}"`,
);
await upgrade.func(['0.57.10'], ctx, opts);
await upgrade.func(['0.57.10'], ctx);
expect(logger.error).not.toBeCalledWith(
`Trying to upgrade from newer version "${currentVersion}" to older "0.57.10"`,
);
}, 60000);

test('warns when dependency upgrade version is in semver range', async () => {
await upgrade.func([currentVersion], ctx, opts);
await upgrade.func([currentVersion], ctx);
expect(logger.warn).toBeCalledWith(
`Specified version "${currentVersion}" is already installed in node_modules and it satisfies "^0.57.8" semver range. No need to upgrade`,
);
}, 60000);

test('fetches empty patch and installs deps', async () => {
mockFetch();
await upgrade.func([newVersion], ctx, opts);
await upgrade.func([newVersion], ctx);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
info Diff has no changes to apply, proceeding further
Expand All @@ -192,7 +186,6 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
android: {packageName: 'com.testapp'},
},
}),
opts,
);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
Expand All @@ -215,18 +208,22 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
success Upgraded React Native to v0.58.4 🎉. Now you can review and commit the changes"
`);
expect(
snapshotDiff(samplePatch, (fs.writeFileSync: any).mock.calls[0][1], {
contextLines: 1,
}),
snapshotDiff(
samplePatch,
(fs.writeFileSync as jest.Mock).mock.calls[0][1],
{
contextLines: 1,
},
),
).toMatchSnapshot(
'RnDiffApp is replaced with app name (TestApp and com.testapp)',
);
}, 60000);
test('fetches regular patch, adds remote, applies patch, installs deps, removes remote when updated from nested directory', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation(mockExecaNested);
((execa as unknown) as jest.Mock).mockImplementation(mockExecaNested);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually make it ((execa as any) as jest.Mock), which might be a little bit smaller. It doesn't really matter here :P

const config = {...ctx, root: '/project/root/NestedApp'};
await upgrade.func([newVersion], config, opts);
await upgrade.func([newVersion], config);
expect(flushOutput()).toMatchInlineSnapshot(`
"info Fetching diff between v0.57.8 and v0.58.4...
[fs] write tmp-upgrade-rn.patch
Expand All @@ -250,7 +247,7 @@ test('fetches regular patch, adds remote, applies patch, installs deps, removes
}, 60000);
test('cleans up if patching fails,', async () => {
mockFetch(samplePatch, 200);
(execa: any).mockImplementation((command, args) => {
((execa as unknown) as jest.Mock).mockImplementation((command, args) => {
mockPushLog('$', 'execa', command, args);
if (command === 'npm' && args[3] === '--json') {
return Promise.resolve({
Expand All @@ -270,7 +267,7 @@ test('cleans up if patching fails,', async () => {
return Promise.resolve({stdout: ''});
});
try {
await upgrade.func([newVersion], ctx, opts);
await upgrade.func([newVersion], ctx);
} catch (error) {
expect(error.message).toBe(
'Upgrade failed. Please see the messages above for details',
Expand Down Expand Up @@ -313,12 +310,15 @@ test('works with --name-ios and --name-android', async () => {
android: {packageName: 'co.uk.customandroid.app'},
},
}),
opts,
);
expect(
snapshotDiff(samplePatch, (fs.writeFileSync: any).mock.calls[0][1], {
contextLines: 1,
}),
snapshotDiff(
samplePatch,
(fs.writeFileSync as jest.Mock).mock.calls[0][1],
{
contextLines: 1,
},
),
).toMatchSnapshot(
'RnDiffApp is replaced with app name (CustomIos and co.uk.customandroid.app)',
);
Expand Down
Loading