mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rrm] Improve init & config loading experience
This commit is contained in:
committed by
Dan Abramov
parent
c9165e0dd1
commit
14fd16b67b
@@ -3,7 +3,7 @@
|
||||
This is a WIP tool that is being used to manage React releases.
|
||||
|
||||
General prereqs:
|
||||
- A separate clone of React, checked out to this branch (currently `release-manager`). This clone should be a sibling to your primary working copy of React. I have these 2 as siblings: `react/` & `react@release-manager`.
|
||||
- A separate clone of React, checked out to this branch (currently `release-manager`). This clone can be anywhere, so long as it is a separate working copy. Ideally this is where you are most comfortable working on React.
|
||||
- Your `react` clone should have the latest commits fetched before running commands. You may need to rebase or reset & re-run commands if not.
|
||||
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
const chalk = require('chalk');
|
||||
const Vorpal = require('vorpal');
|
||||
const GitHubAPI = require('github-api');
|
||||
const untildify = require('untildify');
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
|
||||
const child_process = require('child_process');
|
||||
const execSync = child_process.execSync;
|
||||
@@ -17,7 +19,14 @@ const vorpal = new Vorpal();
|
||||
// Expects to be in a checkout of react that is a sibling of the react checkout you want to operate on
|
||||
// eg ~/code/react@release-manager/scripts/release-manager & ~/code/react
|
||||
// TODO: Make this an argument to the script
|
||||
const PATH_TO_REPO = path.resolve('../../../react');
|
||||
let PATH_TO_REPO = null;
|
||||
|
||||
const PATH_TO_CONFIG = path.resolve(os.homedir(), '.react-release-manager.json');
|
||||
|
||||
const DEFAULT_CONFIG = {
|
||||
githubToken: null,
|
||||
reactPath: path.resolve('../../../react'),
|
||||
};
|
||||
|
||||
// Quick dry run opt-in. This allows quick debugging of execInRepo without
|
||||
// actually running the command, ensuring no accidental publishing.
|
||||
@@ -92,24 +101,30 @@ const app = {
|
||||
// TODO: write this. This should make it possible to start without a config
|
||||
// and go through the init process to create one and then re-init the github
|
||||
// setup.
|
||||
this.config = this.loadConfig();
|
||||
},
|
||||
|
||||
loadConfig() {
|
||||
try {
|
||||
// TODO: validate config
|
||||
let config = JSON.parse(fs.readFileSync(PATH_TO_CONFIG, 'utf8'));
|
||||
config.reactPath = path.normalize(untildify(config.reactPath));
|
||||
PATH_TO_REPO = config.reactPath;
|
||||
return config;
|
||||
} catch (e) {
|
||||
console.error('Attempt to load config file failed. Please run `init` command for initial setup or make sure ~/.react-release-manager.json is valid JSON. Using a default config which may not work properly.');
|
||||
return DEFAULT_CONFIG;
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
// Config
|
||||
try {
|
||||
this.config = JSON.parse(fs.readFileSync('./.config.json', 'utf8'));
|
||||
} catch (e) {
|
||||
this.config = {
|
||||
token: null,
|
||||
};
|
||||
console.error('Could not read .config.json. Rate limits are much stricter as a result. Run init to setup.');
|
||||
}
|
||||
this.config = this.loadConfig();
|
||||
|
||||
this.PATH_TO_REPO = PATH_TO_REPO;
|
||||
this.PATH_TO_CONFIG = PATH_TO_CONFIG;
|
||||
|
||||
// GITHUB
|
||||
this.github = new GitHubAPI({
|
||||
token: this.config.token,
|
||||
token: this.config.githubToken,
|
||||
});
|
||||
this.ghrepo = this.github.getRepo('facebook', 'react');
|
||||
this.ghissues = this.github.getIssues('facebook', 'react');
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
|
||||
const chalk = require('chalk');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const untildify = require('untildify');
|
||||
|
||||
const FILENAME = '.config.json';
|
||||
|
||||
module.exports = function(vorpal, options) {
|
||||
module.exports = function(vorpal, app) {
|
||||
vorpal
|
||||
.command('init')
|
||||
.description('Initializes a .config.json file for use')
|
||||
.action(function(args, cb) {
|
||||
fs.stat(FILENAME, (err, stats) => {
|
||||
fs.stat(app.PATH_TO_CONFIG, (err, stats) => {
|
||||
if (stats) {
|
||||
this.log('Config file exists, nothing to do.');
|
||||
cb();
|
||||
@@ -23,14 +23,40 @@ module.exports = function(vorpal, options) {
|
||||
|
||||
this.prompt([
|
||||
{
|
||||
name: 'token',
|
||||
name: 'githubToken',
|
||||
type: 'input',
|
||||
message: `${chalk.bold('GitHub token?')} ${chalk.grey('(needs "repo" privs)')} `,
|
||||
},
|
||||
{
|
||||
name: 'reactPath',
|
||||
type: 'input',
|
||||
message: `${chalk.bold('Location of local React checkout?')} `,
|
||||
validate: (input) => {
|
||||
let npath = path.normalize(untildify(input));
|
||||
|
||||
if (npath === '.') {
|
||||
return 'Cannot be `.`';
|
||||
}
|
||||
|
||||
let stats;
|
||||
try {
|
||||
stats = fs.statSync(npath);
|
||||
} catch (e) {
|
||||
return `Error: ${e}`;
|
||||
}
|
||||
|
||||
if (!stats.isDirectory()) {
|
||||
return `${npath} is not a directory.`;
|
||||
}
|
||||
|
||||
// TODO: Look for markers indicating this is a React checkout.
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]).then((answers) => {
|
||||
fs.writeFile(FILENAME, JSON.stringify(answers, null, 2), (err) => {
|
||||
fs.writeFile(app.PATH_TO_CONFIG, JSON.stringify(answers, null, 2), (err) => {
|
||||
if (err) {
|
||||
this.log('ERROR WRITING .config.json', err);
|
||||
this.log('Error writing config file.', err);
|
||||
}
|
||||
cb();
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ module.exports = function(vorpal, app) {
|
||||
// just npm publish pkg1.tgz && npm publish pkg2.tgz. This
|
||||
// avoided the need to cd and publish.
|
||||
const tgz = glob.sync('build/packages/*.tgz', {
|
||||
cwd: app.PATH_TO_REPO,
|
||||
cwd: app.config.reactPath,
|
||||
});
|
||||
|
||||
// Just in case they didn't actually prep this.
|
||||
|
||||
@@ -117,13 +117,13 @@ module.exports = function(vorpal, app) {
|
||||
fields: ['version', 'peerDependencies.react'],
|
||||
},
|
||||
].forEach((opts) => {
|
||||
updateJSON.apply(this, [path.join(app.PATH_TO_REPO, opts.file), opts.fields, newVersion]);
|
||||
updateJSON.apply(this, [path.join(app.config.reactPath, opts.file), opts.fields, newVersion]);
|
||||
});
|
||||
|
||||
// We also need to update src/ReactVersion.js which has the version in
|
||||
// string form in JS code. We'll just do a string replace.
|
||||
|
||||
const PATH_TO_REACTVERSION = path.join(app.PATH_TO_REPO, 'src/ReactVersion.js');
|
||||
const PATH_TO_REACTVERSION = path.join(app.config.reactPath, 'src/ReactVersion.js');
|
||||
|
||||
let reactVersionContents = fs.readFileSync(PATH_TO_REACTVERSION, 'utf8');
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"glob": "^7.0.5",
|
||||
"opn": "^4.0.2",
|
||||
"semver": "^5.3.0",
|
||||
"untildify": "^3.0.2",
|
||||
"vorpal": "^1.10.10"
|
||||
},
|
||||
"devDependencies": {},
|
||||
|
||||
Reference in New Issue
Block a user