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

Standardise configuration mechanism #254

Merged
merged 50 commits into from
Apr 1, 2019
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
f5f6271
Initial commit
grabbou Mar 20, 2019
9734a8f
Clean up main entry point
grabbou Mar 20, 2019
3ab1c46
Fixes some typos
orta Mar 20, 2019
703098f
Update configuration
grabbou Mar 20, 2019
4f17675
Resolve conflicts
grabbou Mar 20, 2019
32da7cf
update
grabbou Mar 20, 2019
942db96
Tweaks to types
grabbou Mar 20, 2019
dcb0362
types and tweaks
grabbou Mar 20, 2019
93090f8
Save another chunk of work
grabbou Mar 20, 2019
933512a
WIP part 2'
grabbou Mar 26, 2019
9815ff2
Simplify diff by removing things we can tweak later
grabbou Mar 26, 2019
e50001a
Wip 3: Legacy link config
grabbou Mar 26, 2019
2b3e016
Updates
grabbou Mar 26, 2019
bfc9ed7
Update name:
grabbou Mar 26, 2019
2180a5a
Add deprecation messages for soon-to-be-deprecated rnpm configuration
grabbou Mar 26, 2019
7abcaeb
Both array and string were acceptable in rnpm configuration
grabbou Mar 26, 2019
225d739
Share root
grabbou Mar 26, 2019
623b643
Documentation and refining the code
grabbou Mar 26, 2019
3c7f36b
Start wrapping it up
grabbou Mar 26, 2019
b3cbf3b
Fix some simple flow errors
grabbou Mar 26, 2019
db90f50
Fix flow errors except for tests
grabbou Mar 26, 2019
4b67b8b
Override configuration
grabbou Mar 27, 2019
34224eb
Simplify typing changes
grabbou Mar 27, 2019
717687b
Fix remaining flow errors
grabbou Mar 27, 2019
50674d7
Validate dependencies separately
grabbou Mar 27, 2019
752104b
Use Joi to validate schema
grabbou Mar 27, 2019
8a491a8
Read Joi validated config
grabbou Mar 27, 2019
1f1da28
Rewrite configuration once again
grabbou Mar 28, 2019
089669b
Further simplification
grabbou Mar 28, 2019
c2c30e7
Simplify code again
grabbou Mar 28, 2019
d71658b
Print deprecation warning
grabbou Mar 28, 2019
5c13c1a
Fix flow
grabbou Mar 28, 2019
a575d6c
Add basic error handling of Joi errors
grabbou Mar 28, 2019
7b67f2e
wip
grabbou Mar 29, 2019
6005390
chore: setup e2e tests (#264)
thymikee Mar 28, 2019
5941d8f
Add first snapshot test using e2e utils
grabbou Mar 29, 2019
8d08a00
Test for root too
grabbou Mar 29, 2019
b6e97cd
Merge remote-tracking branch 'origin/master' into feat/config
thymikee Mar 29, 2019
bf370c4
Add two more tests
grabbou Mar 29, 2019
7cbb0a3
Merge branch 'feat/config' of github.com:react-native-community/react…
grabbou Mar 29, 2019
3ca95eb
Add more tests and fix ESLint environment
grabbou Apr 1, 2019
44ec987
Test for RNPM compatibility
grabbou Apr 1, 2019
730257d
Smaller snapshots and one extra test
grabbou Apr 1, 2019
953d53f
Address feedback
grabbou Apr 1, 2019
c77a13b
Fix tests
grabbou Apr 1, 2019
ed103db
Fix the tests - again
grabbou Apr 1, 2019
b8afacd
revert eslint change and remove unused 'union' var
thymikee Apr 1, 2019
441fc74
Address feedback
grabbou Apr 1, 2019
1ba2c80
Update snapshot names
grabbou Apr 1, 2019
e5a5a94
Update types
grabbou Apr 1, 2019
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
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module.exports = {
},
overrides: [
{
files: ['**/__mocks__/**', '**/__fixtures__/**', 'testSetup.js'],
files: ['**/__mocks__/**', '**/__tests__/**', '**/__fixtures__/**', 'testSetup.js'],
thymikee marked this conversation as resolved.
Show resolved Hide resolved
env: {
jest: true,
},
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"commander": "^2.19.0",
"compression": "^1.7.1",
"connect": "^3.6.5",
"cosmiconfig": "^5.1.0",
"deepmerge": "^3.2.0",
"denodeify": "^1.2.1",
"envinfo": "^7.1.0",
"errorhandler": "^1.5.0",
Expand All @@ -32,6 +34,7 @@
"glob": "^7.1.1",
"graceful-fs": "^4.1.3",
"inquirer": "^3.0.6",
"joi": "^14.3.1",
"lodash": "^4.17.5",
"metro": "^0.53.1",
"metro-config": "^0.53.1",
Expand Down
52 changes: 5 additions & 47 deletions packages/cli/src/cliEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,21 @@
import chalk from 'chalk';
import childProcess from 'child_process';
import commander from 'commander';
import minimist from 'minimist';
import path from 'path';

import type {CommandT, ContextT} from './tools/types.flow';
import getLegacyConfig from './tools/getLegacyConfig';

import {getCommands} from './commands';
import init from './commands/init/init';
import assertRequiredOptions from './tools/assertRequiredOptions';
import logger from './tools/logger';
import findPlugins from './tools/findPlugins';
import {setProjectDir} from './tools/PackageManager';
import pkgJson from '../package.json';
import loadConfig from './tools/config';

commander
.option('--version', 'Print CLI version')
.option('--projectRoot [string]', 'Path to the root of the project')
.option('--reactNativePath [string]', 'Path to React Native')
.option('--verbose', 'Increase logging verbosity');

commander.on('command:*', () => {
Expand Down Expand Up @@ -117,15 +116,6 @@ const addCommand = (command: CommandT, ctx: ContextT) => {
opt.default,
),
);

/**
* We want every command (like "start", "link") to accept below options.
* To achieve that we append them to regular options of each command here.
* This way they'll be displayed in the commands --help menus.
*/
cmd
.option('--projectRoot [string]', 'Path to the root of the project')
.option('--reactNativePath [string]', 'Path to React Native');
};

async function run() {
Expand Down Expand Up @@ -156,43 +146,11 @@ async function setupAndRun() {
}
}

/**
* At this point, commander arguments are not parsed yet because we need to
* add all the commands and their options. That's why we resort to using
* minimist for parsing some global options.
*/
const options = minimist(process.argv.slice(2));

const root = options.projectRoot
? path.resolve(options.projectRoot)
: process.cwd();

const reactNativePath = options.reactNativePath
? path.resolve(options.reactNativePath)
: (() => {
try {
return path.dirname(
// $FlowIssue: Wrong `require.resolve` type definition
require.resolve('react-native/package.json', {
paths: [root],
}),
);
} catch (_ignored) {
throw new Error(
'Unable to find React Native files. Make sure "react-native" module is installed in your project dependencies.',
);
}
})();

const ctx = {
...getLegacyConfig(root),
Copy link
Member Author

Choose a reason for hiding this comment

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

Note: time to drop getLegacyConfig - doing it here.

reactNativePath,
root,
};
const ctx = loadConfig();

setProjectDir(ctx.root);

const commands = getCommands(ctx.root);
const commands = getCommands(ctx);

commands.forEach(command => addCommand(command, ctx));

Expand Down
11 changes: 11 additions & 0 deletions packages/cli/src/commands/config/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @flow
*/
import {type ContextT} from '../../tools/types.flow';
export default {
name: 'config',
description: 'Print CLI configuration',
func: async (argv: string[], ctx: ContextT) => {
console.log(JSON.stringify(ctx, null, 2));
},
};
28 changes: 16 additions & 12 deletions packages/cli/src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import path from 'path';

import findPlugins from '../tools/findPlugins';
import logger from '../tools/logger';

import type {
Expand All @@ -13,6 +12,8 @@ import type {
LocalCommandT,
} from '../tools/types.flow';

import {type ContextT} from '../tools/types.flow';

import server from './server/server';
import runIOS from './runIOS/runIOS';
import runAndroid from './runAndroid/runAndroid';
Expand All @@ -27,6 +28,7 @@ import upgrade from './upgrade/upgrade';
import logAndroid from './logAndroid/logAndroid';
import logIOS from './logIOS/logIOS';
import info from './info/info';
import config from './config/config';

/**
* List of built-in commands
Expand All @@ -47,6 +49,7 @@ const loadLocalCommands: Array<LocalCommandT> = [
logAndroid,
logIOS,
info,
config,
];

/**
Expand All @@ -55,10 +58,11 @@ const loadLocalCommands: Array<LocalCommandT> = [
* This checks all CLI plugins for presence of 3rd party packages that define commands
* and loads them
*/
const loadProjectCommands = (root: string): Array<ProjectCommandT> => {
const plugins = findPlugins(root);

return plugins.commands.reduce((acc: Array<CommandT>, pathToCommands) => {
const loadProjectCommands = ({
root,
commands,
}: ContextT): Array<ProjectCommandT> => {
return commands.reduce((acc: Array<ProjectCommandT>, cmdPath: string) => {
/**
* `pathToCommand` is a path to a file where commands are defined, relative to `node_modules`
* folder.
Expand All @@ -67,12 +71,12 @@ const loadProjectCommands = (root: string): Array<ProjectCommandT> => {
* into consideration.
*/
const name =
pathToCommands[0] === '@'
? pathToCommands
cmdPath[0] === '@'
? cmdPath
.split(path.sep)
.slice(0, 2)
.join(path.sep)
: pathToCommands.split(path.sep)[0];
: cmdPath.split(path.sep)[0];

const pkg = require(path.join(root, 'node_modules', name, 'package.json'));

Expand All @@ -81,7 +85,7 @@ const loadProjectCommands = (root: string): Array<ProjectCommandT> => {
| Array<ProjectCommandT> = require(path.join(
root,
'node_modules',
pathToCommands,
cmdPath,
));

if (Array.isArray(requiredCommands)) {
Expand All @@ -90,14 +94,14 @@ const loadProjectCommands = (root: string): Array<ProjectCommandT> => {
);
}

return acc.concat({...requiredCommands});
return acc.concat({...requiredCommands, pkg});
}, []);
};

/**
* Loads all the commands inside a given `root` folder
*/
export function getCommands(root: string): Array<CommandT> {
export function getCommands(ctx: ContextT): Array<CommandT> {
return [
...loadLocalCommands,
{
Expand All @@ -111,6 +115,6 @@ export function getCommands(root: string): Array<CommandT> {
);
},
},
...loadProjectCommands(root),
...loadProjectCommands(ctx),
];
}
12 changes: 11 additions & 1 deletion packages/cli/src/commands/info/__tests__/info.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ jest.mock('../../../tools/logger', () => ({
log: jest.fn(),
}));

const ctx = {reactNativePath: '', root: ''};
const ctx = {
root: '',
reactNativePath: '',
dependencies: {},
platforms: {},
commands: [],
haste: {
platforms: [],
providesModuleNodeModules: [],
},
};

beforeEach(() => {
jest.resetAllMocks();
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/link/getDependencyConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default function getDependencyConfig(
Object.keys(availablePlatforms).forEach(platform => {
platformConfigs[platform] = availablePlatforms[platform].dependencyConfig(
folder,
// $FlowIssue: Flow can't match platform config with its appropriate config function
config[platform] || {},
);
});
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/commands/link/getProjectConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default function getProjectConfig(
logger.debug(`Getting project config for ${getPlatformName(platform)}...`);
platformConfigs[platform] = availablePlatforms[platform].projectConfig(
ctx.root,
// $FlowIssue: Flow can't match platform config with its appropriate config function
config[platform] || {},
);
});
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/src/commands/link/linkAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ function linkAll(

const projectAssets = getAssets(context.root);
const dependencies = getProjectDependencies(context.root);
const depenendenciesConfig = dependencies.map(dependnecy =>
getDependencyConfig(context, platforms, dependnecy),
const dependenciesConfig = dependencies.map(dependency =>
getDependencyConfig(context, platforms, dependency),
);

const assets = dedupeAssets(
depenendenciesConfig.reduce(
dependenciesConfig.reduce(
(acc, dependency) => acc.concat(dependency.assets),
projectAssets,
),
);

const tasks = flatten(
depenendenciesConfig.map(config => [
dependenciesConfig.map(config => [
() => promisify(config.commands.prelink || commandStub),
() => linkDependency(platforms, project, config),
() => promisify(config.commands.postlink || commandStub),
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/src/commands/upgrade/__tests__/upgrade.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ const olderVersion = '0.56.0';
const ctx = {
root: '/project/root',
reactNativePath: '',
commands: [],
platforms: {},
dependencies: {},
haste: {
providesModuleNodeModules: [],
platforms: [],
},
};
const opts = {
legacy: false,
Expand Down
Loading