Compare commits

...
11 Commits
Author SHA1 Message Date
Mike Grabowski 890342ed88 [0.37.0] Bump version numbers 2016-11-08 00:19:54 +01:00
Martin Konicek 1ecc24a4eb [0.37.0-rc.4] Bump version numbers 2016-11-05 19:41:24 +00:00
Martin Konicek 4d0ce9022a CLI: Only use yarn if global CLI uses it
Summary:
Check that 'react-native init' itself used yarn to install React Native.
When using an old global react-native-cli@1.0.0 (or older), we don't want to install React Native with npm, and React + Jest with yarn. Let's be safe and not mix yarn and npm in a single project.

**Test plan**

Publish the code in this PR to Sinopia, use that when creating a new project.

Using old CLI:

    npm install -g react-native-cli@1.0.0
    react-native init AwesomeApp

The generated project doesn't contain `yarn.lock` (everything was installed with the npm client).

 ---

Using new CLI:

    npm install -g react-native-cli@1.2.0
    react-native init AwesomeApp

The generated project contains `yarn.lock`, output shows that yarn is used to install React Native, React, Jest.

 ---

In both cases the project runs and Reload JS works:

![screenshot 2016-11-04 17 20 50](https://cloud.githubusercontent.com/assets/346214/20015719/719effb0-a2b4-11e6-84a0-43474314009b.png)
Closes https://github.com/facebook/react-native/pull/10752

Differential Revision: D4131812

Pulled By: bestander

fbshipit-source-id: efaaf97a27005e2c2d10cae5d07afe108d5c0dee
2016-11-05 19:40:43 +00:00
Martin Konicek 0b27d21455 [0.37.0-rc.3] Bump version numbers 2016-11-03 21:05:36 +00:00
Martin Konicek cedf4dd617 Use yarn when available
Summary:
**Motivation**

`react-native init` takes minutes even on a fast network. Yarn makes it much quicker.

When yarn is not installed on the system:

<img width="440" alt="screenshot 2016-10-31 22 21 19" src="https://cloud.githubusercontent.com/assets/346214/19873897/7bad5662-9fb9-11e6-85fb-ad4879949dad.png">

When yarn is installed:

<img width="441" alt="screenshot 2016-10-31 22 02 20" src="https://cloud.githubusercontent.com/assets/346214/19873898/7baf4c56-9fb9-11e6-96b3-007f93d2438a.png">

Also added the option `react-native init AwesomeApp --npm` as a fallback in case yarn is not stable enough for some people (I saw some Github issues that yarn hangs for example; for me it works great though).

**Test plan**
1. Publish to Sinopia: https://github.com/facebook/react-native/tree/master/react-native-cli
2. `react-native init AwesomeApp`

***Tested the following setups***

- New CLI - uses yarn, new react-native - uses yarn
- Old CLI (1.0.0) - doesn't use yarn, new react-native - uses yarn
-
Closes https://github.com/facebook/react-native/pull/10626

Differential Revision: D4110883

Pulled By: bestander

fbshipit-source-id: 8a3427e2bc9158cf5fadd8ddf5b31e4b50ce6453
2016-11-03 21:04:25 +00:00
Mike Grabowski 1142efae44 [0.37.0-rc.2] Bump version numbers 2016-11-02 22:51:44 +01:00
Mike Grabowski 2d3fcf245b Merge branch '0.37-stable' of github.com:facebook/react-native into 0.37-stable 2016-11-02 22:51:00 +01:00
Mike Grabowski d282168548 [0.37.0-rc.1] Bump version numbers 2016-11-01 22:25:49 +01:00
James IdeandMike Grabowski a69581a073 Fix missing methods in Keyboard module
Summary:
They keyboard module is an instance of `NativeEventEmitter` which is an instance of `EventEmitter`. But the exported module only has a small subset of the APIs. This broke existing codebases which are using the methods not exported currently.

The PR just reassigns the variable before exporting so that the actual module is exported instead of the dummy object used for documentation. It also fixes a layout issue in the documentation.
Closes https://github.com/facebook/react-native/pull/10671

Differential Revision: D4110355

fbshipit-source-id: a6757f3ca8c2494970ba221b10a7e6e9a5f2d64d
2016-11-01 22:24:50 +01:00
Ovidiu Viorel IepureandKonstantin Raev 4b1731727a Circle CI releases now work with Java 8
Reviewed By: bestander

Differential Revision: D4095313

fbshipit-source-id: 1806db054bbca86f6394af077baeccac4e7efbe1
2016-10-28 16:02:30 +01:00
Mike Grabowski 4f50fc8392 [0.37.0-rc.0] Bump version numbers 2016-10-26 00:07:23 +02:00
9 changed files with 198 additions and 74 deletions
+50 -21
View File
@@ -11,20 +11,41 @@
*/
'use strict';
const invariant = require('fbjs/lib/invariant');
const NativeEventEmitter = require('NativeEventEmitter');
const KeyboardObserver = require('NativeModules').KeyboardObserver;
const dismissKeyboard = require('dismissKeyboard');
const KeyboardEventEmitter = new NativeEventEmitter(KeyboardObserver);
type KeyboardEventName =
| 'keyboardWillShow'
| 'keyboardDidShow'
| 'keyboardWillHide'
| 'keyboardDidHide'
| 'keyboardWillChangeFrame'
| 'keyboardDidChangeFrame';
type KeyboardEventData = {
endCoordinates: {
width: number,
height: number,
screenX: number,
screenY: number,
},
};
type KeyboardEventListener = (e: KeyboardEventData) => void;
// The following object exists for documentation purposes
// Actual work happens in
// https://github.com/facebook/react-native/blob/master/Libraries/EventEmitter/NativeEventEmitter.js
/**
* `Keyboard` component to control keyboard events.
* `Keyboard` module to control keyboard events.
*
* ### Usage
*
* The Keyboard component allows you to listen for native events and react to them, as
* The Keyboard module allows you to listen for native events and react to them, as
* well as make changes to the keyboard, like dismissing it.
*
*```
@@ -60,16 +81,17 @@ const KeyboardEventEmitter = new NativeEventEmitter(KeyboardObserver);
* }
*```
*/
module.exports = {
let Keyboard = {
/**
* The `addListener` function connects a JavaScript function to an identified native
* keyboard notification event.
*
* This function then returns the reference to the listener.
*
* @param {string} nativeEvent The `nativeEvent` is the string that identifies the event you're listening for. This
* @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for. This
*can be any of the following:
*
* - `keyboardWillShow`
* - `keyboardDidShow`
* - `keyboardWillHide`
@@ -77,10 +99,20 @@ module.exports = {
* - `keyboardWillChangeFrame`
* - `keyboardDidChangeFrame`
*
* @param {function} jsFunction function to be called when the event fires.
* @param {function} callback function to be called when the event fires.
*/
addListener (nativeEvent: string, jsFunction: Function) {
return KeyboardEventEmitter.addListener(nativeEvent, jsFunction);
addListener(eventName: KeyboardEventName, callback: KeyboardEventListener) {
invariant(false, 'Dummy method used for documentation');
},
/**
* Removes a specific listener.
*
* @param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for.
* @param {function} callback function to be called when the event fires.
*/
removeListener(eventName: KeyboardEventName, callback: Function) {
invariant(false, 'Dummy method used for documentation');
},
/**
@@ -88,24 +120,21 @@ module.exports = {
*
* @param {string} eventType The native event string listeners are watching which will be removed.
*/
removeAllListeners (eventType: string) {
KeyboardEventEmitter.removeAllListeners(eventType);
},
/**
* Removes a specific subscription.
*
* @param {EmitterSubscription} subscription The subscription emitter to be removed.
*/
removeSubscription (subscription: Object) {
KeyboardEventEmitter.removeSubscription(subscription);
removeAllListeners(eventName: KeyboardEventName) {
invariant(false, 'Dummy method used for documentation');
},
/**
* Dismisses the active keyboard and removes focus.
*/
dismiss () {
dismissKeyboard();
dismiss() {
invariant(false, 'Dummy method used for documentation');
}
};
// Throw away the dummy object and reassign it to original module
Keyboard = KeyboardEventEmitter;
Keyboard.dismiss = dismissKeyboard;
module.exports = Keyboard;
+1 -1
View File
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "React"
s.version = package['version']
s.version = "0.37.0"
s.summary = package['description']
s.description = <<-DESC
React Native apps are built using the React JS
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.37.0
GROUP=com.facebook.react
POM_NAME=ReactNative
+9 -2
View File
@@ -54,6 +54,14 @@ def configureReactNativePom(def pom) {
}
}
if (JavaVersion.current().isJava8Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
}
afterEvaluate { project ->
task androidJavadoc(type: Javadoc) {
@@ -84,8 +92,7 @@ afterEvaluate { project ->
artifacts {
archives androidSourcesJar
// TODO Make Javadoc generation work with Java 1.8, currently only works with 1.7
// archives androidJavadocJar
archives androidJavadocJar
}
version = VERSION_NAME
+64 -8
View File
@@ -8,10 +8,50 @@
*/
'use strict';
var execSync = require('child_process').execSync;
var fs = require('fs');
var path = require('path');
var yeoman = require('yeoman-generator');
var semver = require('semver')
var utils = require('../generator-utils');
var yeoman = require('yeoman-generator');
// Use Yarn if available, it's much faster than the npm client.
// Return the version of yarn installed on the system, null if yarn is not available.
function getYarnVersionIfAvailable() {
let yarnVersion;
try {
// execSync returns a Buffer -> convert to string
if (process.platform.startsWith('win')) {
yarnVersion = (execSync('yarn --version').toString() || '').trim();
} else {
yarnVersion = (execSync('yarn --version 2>/dev/null').toString() || '').trim();
}
} catch (error) {
return null;
}
// yarn < 0.16 has a 'missing manifest' bug
try {
if (semver.gte(yarnVersion, '0.16.0')) {
return yarnVersion;
} else {
return null;
}
} catch (error) {
console.error('Cannot parse yarn version: ' + yarnVersion);
return null;
}
}
/**
* Check that 'react-native init' itself used yarn to install React Native.
* When using an old global react-native-cli@1.0.0 (or older), we don't want
* to install React Native with npm, and React + Jest with yarn.
* Let's be safe and not mix yarn and npm in a single project.
* @param projectDir e.g. /Users/martin/AwesomeApp
*/
function isGlobalCliUsingYarn(projectDir) {
return fs.existsSync(path.join(projectDir, 'yarn.lock'));
}
module.exports = yeoman.generators.NamedBase.extend({
constructor: function() {
@@ -36,6 +76,12 @@ module.exports = yeoman.generators.NamedBase.extend({
type: Boolean,
defaults: false
});
// Temporary option until yarn becomes stable.
this.option('npm', {
desc: 'Use the npm client, even if yarn is available.',
type: Boolean,
defaults: false
});
// this passes command line arguments down to the composed generators
var args = {args: arguments[0], options: this.options};
@@ -112,12 +158,24 @@ module.exports = yeoman.generators.NamedBase.extend({
return;
}
this.npmInstall(`react@${reactVersion}`, { '--save': true, '--save-exact': true });
const yarnVersion = (!this.options['npm']) && getYarnVersionIfAvailable() && isGlobalCliUsingYarn(this.destinationRoot());
console.log('Installing React...');
if (yarnVersion) {
execSync(`yarn add react@${reactVersion}`);
} else {
this.npmInstall(`react@${reactVersion}`, { '--save': true, '--save-exact': true });
}
if (!this.options['skip-jest']) {
this.npmInstall(`jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion}`.split(' '), {
saveDev: true,
'--save-exact': true
});
console.log('Installing Jest...');
if (yarnVersion) {
execSync(`yarn add jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion} --dev --exact`);
} else {
this.npmInstall(`jest babel-jest jest-react-native babel-preset-react-native react-test-renderer@${reactVersion}`.split(' '), {
saveDev: true,
'--save-exact': true
});
}
fs.writeFileSync(
path.join(
this.destinationRoot(),
@@ -125,7 +183,6 @@ module.exports = yeoman.generators.NamedBase.extend({
),
'{\n"presets": ["react-native"]\n}'
);
this.fs.copy(
this.templatePath('__tests__'),
this.destinationPath('__tests__'),
@@ -133,7 +190,6 @@ module.exports = yeoman.generators.NamedBase.extend({
nodir: false
}
);
var packageJSONPath = path.join(
this.destinationRoot(),
'package.json'
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.37.0",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -223,4 +223,4 @@
"eslint-plugin-flowtype": "^2.20.0",
"eslint-plugin-react": "^6.4.1"
}
}
}
+70 -24
View File
@@ -38,6 +38,7 @@
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var execSync = require('child_process').execSync;
var spawn = require('child_process').spawn;
var chalk = require('chalk');
var prompt = require('prompt');
@@ -74,6 +75,33 @@ var REACT_NATIVE_PACKAGE_JSON_PATH = function() {
);
};
// Use Yarn if available, it's much faster than the npm client.
// Return the version of yarn installed on the system, null if yarn is not available.
function getYarnVersionIfAvailable() {
let yarnVersion;
try {
// execSync returns a Buffer -> convert to string
if (process.platform.startsWith('win')) {
yarnVersion = (execSync('yarn --version').toString() || '').trim();
} else {
yarnVersion = (execSync('yarn --version 2>/dev/null').toString() || '').trim();
}
} catch (error) {
return null;
}
// yarn < 0.16 has a 'missing manifest' bug
try {
if (semver.gte(yarnVersion, '0.16.0')) {
return yarnVersion;
} else {
return null;
}
} catch (error) {
console.error('Cannot parse yarn version: ' + yarnVersion);
return null;
}
}
checkForVersionArgument();
var cli;
@@ -102,8 +130,8 @@ if (cli) {
);
process.exit(1);
} else {
if (!argv.verbose) console.log('This may take some time...');
init(commands[1], argv.verbose, argv.version);
const rnPackage = argv.version;
init(commands[1], argv.verbose, rnPackage, argv.npm);
}
break;
default:
@@ -117,7 +145,7 @@ if (cli) {
}
}
function validatePackageName(name) {
function validateProjectName(name) {
if (!name.match(/^[$A-Z_][0-9A-Z_$]*$/i)) {
console.error(
'"%s" is not a valid name for a project. Please use a valid identifier ' +
@@ -137,17 +165,24 @@ function validatePackageName(name) {
}
}
function init(name, verbose, rnPackage) {
validatePackageName(name);
/**
* @param name Project name, e.g. 'AwesomeApp'.
* @param verbose If true, will run 'npm install' in verbose mode (for debugging).
* @param rnPackage Version of React Native to install, e.g. '0.38.0'.
* @param forceNpmClient If true, always use the npm command line client,
* don't use yarn even if available.
*/
function init(name, verbose, rnPackage, forceNpmClient) {
validateProjectName(name);
if (fs.existsSync(name)) {
createAfterConfirmation(name, verbose, rnPackage);
createAfterConfirmation(name, verbose, rnPackage, forceNpmClient);
} else {
createProject(name, verbose, rnPackage);
createProject(name, verbose, rnPackage, forceNpmClient);
}
}
function createAfterConfirmation(name, verbose, rnPackage) {
function createAfterConfirmation(name, verbose, rnPackage, forceNpmClient) {
prompt.start();
var property = {
@@ -160,7 +195,7 @@ function createAfterConfirmation(name, verbose, rnPackage) {
prompt.get(property, function (err, result) {
if (result.yesno[0] === 'y') {
createProject(name, verbose, rnPackage);
createProject(name, verbose, rnPackage, forceNpmClient);
} else {
console.log('Project initialization canceled');
process.exit();
@@ -168,7 +203,7 @@ function createAfterConfirmation(name, verbose, rnPackage) {
});
}
function createProject(name, verbose, rnPackage) {
function createProject(name, verbose, rnPackage, forceNpmClient) {
var root = path.resolve(name);
var projectName = path.basename(root);
@@ -192,20 +227,18 @@ function createProject(name, verbose, rnPackage) {
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson));
process.chdir(root);
console.log('Installing react-native package from npm...');
if (verbose) {
runVerbose(root, projectName, rnPackage);
runVerbose(root, projectName, rnPackage, forceNpmClient);
} else {
run(root, projectName, rnPackage);
run(root, projectName, rnPackage, forceNpmClient);
}
}
function getInstallPackage(rnPackage) {
var packageToInstall = 'react-native';
var valideSemver = semver.valid(rnPackage);
if (valideSemver) {
packageToInstall += '@' + valideSemver;
var isValidSemver = semver.valid(rnPackage);
if (isValidSemver) {
packageToInstall += '@' + isValidSemver;
} else if (rnPackage) {
// for tar.gz or alternative paths
packageToInstall = rnPackage;
@@ -213,23 +246,36 @@ function getInstallPackage(rnPackage) {
return packageToInstall;
}
function run(root, projectName, rnPackage) {
exec('npm install --save --save-exact ' + getInstallPackage(rnPackage), function(e, stdout, stderr) {
if (e) {
function run(root, projectName, rnPackage, forceNpmClient) {
const yarnVersion = (!forceNpmClient) && getYarnVersionIfAvailable();
let installCommand;
if (yarnVersion) {
console.log('Using yarn v' + yarnVersion);
console.log('Installing ' + getInstallPackage(rnPackage) + '...');
installCommand = 'yarn add ' + getInstallPackage(rnPackage) + ' --exact';
} else {
console.log('Installing ' + getInstallPackage(rnPackage) + ' from npm...');
if (!forceNpmClient) {
console.log('Consider installing yarn to make this faster: https://yarnpkg.com');
}
installCommand = 'npm install --save --save-exact ' + getInstallPackage(rnPackage);
}
exec(installCommand, function(err, stdout, stderr) {
if (err) {
console.log(stdout);
console.error(stderr);
console.error('`npm install --save --save-exact react-native` failed');
console.error('Command `' + installCommand + '` failed.');
process.exit(1);
}
checkNodeVersion();
cli = require(CLI_MODULE_PATH());
cli.init(root, projectName);
});
}
function runVerbose(root, projectName, rnPackage) {
function runVerbose(root, projectName, rnPackage, forceNpmClient) {
// Use npm client, yarn doesn't support --verbose yet
console.log('Installing ' + getInstallPackage(rnPackage) + ' from npm. This might take a while...');
var proc = spawn(/^win/.test(process.platform) ? 'npm.cmd' : 'npm', ['install', '--verbose', '--save', '--save-exact', getInstallPackage(rnPackage)], {stdio: 'inherit'});
proc.on('close', function (code) {
if (code !== 0) {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-native-cli",
"version": "1.0.0",
"version": "1.1.0",
"license": "BSD-3-Clause",
"description": "The React Native CLI tools",
"main": "index.js",
-14
View File
@@ -50,7 +50,6 @@
require(`shelljs/global`);
const buildBranch = process.env.CIRCLE_BRANCH;
const requiredJavaVersion = `1.7`;
let branchVersion;
if (buildBranch.indexOf(`-stable`) !== -1) {
@@ -88,19 +87,6 @@ if (tagsWithVersion[0].indexOf(`-rc`) === -1) {
}
// -------- Generating Android Artifacts with JavaDoc
// Java -version outputs to stderr 0_o
const javaVersion = exec(`java -version`).stderr;
if (javaVersion.indexOf(requiredJavaVersion) === -1) {
echo(`Java version must be 1.7.x in order to generate Javadoc. Check: java -version`);
exit(1);
}
// Uncomment Javadoc generation
if (sed(`-i`, `// archives androidJavadocJar`, `archives androidJavadocJar`, `ReactAndroid/release.gradle`).code) {
echo(`Couldn't enable Javadoc generation`);
exit(1);
}
if (exec(`./gradlew :ReactAndroid:installArchives`).code) {
echo(`Couldn't generate artifacts`);
exit(1);