Skip to content
This repository has been archived by the owner on Jun 17, 2021. It is now read-only.

Commit

Permalink
Bi directional communication (#100)
Browse files Browse the repository at this point in the history
* Use 'child.stdin.write' to send 'eject' command

* Fix bug where app would crash after ejecting with modal open

* Cleanup

* Improve fix to use getDerivedStateFromProps
  • Loading branch information
joshwcomeau authored Jul 24, 2018
1 parent befbcab commit 1a9cd1e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
15 changes: 15 additions & 0 deletions src/components/TaskRunnerPane/TaskRunnerPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ class TaskRunnerPane extends Component<Props, State> {
selectedTaskId: null,
};

static getDerivedStateFromProps(props, state) {
// It's possible that this task is deleted while the modal is open;
// For example, This can happen when ejecting the project, since the
// create-react-app "eject" task removes itself upon completion.
const selectedTaskExists = props.tasks.some(
task => task.id === state.selectedTaskId
);

if (!selectedTaskExists) {
return { selectedTaskId: null };
}

return null;
}

handleToggleTask = taskId => {
const { tasks, runTask, abortTask } = this.props;

Expand Down
30 changes: 21 additions & 9 deletions src/middlewares/task.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,8 @@ export default (store: any) => (next: any) => (action: any) => {
additionalArgs.push('--', '--coverage');
}

/* Bypasses 'Are you sure?' check when ejecting CRA
*
* TODO: add windows support
*/
const command =
project.type === 'create-react-app' && name === 'eject'
? 'echo yes | npm'
: 'npm';
const child = childProcess.spawn(
command,
'npm',
['run', name, ...additionalArgs],
{
cwd: projectPath,
Expand All @@ -158,6 +150,20 @@ export default (store: any) => (next: any) => (action: any) => {
next(attachTaskMetadata(task, child.pid));

child.stdout.on('data', data => {
// The 'eject' task prompts the user, to ask if they're sure.
// We can bypass this prompt, as our UI already has an alert that
// confirms this action.
// TODO: Eject deserves its own Redux action, to avoid cluttering up
// this generic "RUN_TASK" action.
// TODO: Is there a way to "future-proof" this, in case the CRA
// confirmation copy changes?
const isEjectPrompt = data
.toString()
.includes('Are you sure you want to eject? This action is permanent');

if (isEjectPrompt) {
sendCommandToProcess(child, 'y');
}
next(receiveDataFromTaskExecution(task, data.toString()));
});

Expand Down Expand Up @@ -270,3 +276,9 @@ const getDevServerCommand = (
throw new Error('Unrecognized project type: ' + projectType);
}
};

const sendCommandToProcess = (child: any, command: string) => {
// Commands have to be suffixed with '\n' to signal that the command is
// ready to be sent. Same as a regular command + hitting the enter key.
child.stdin.write(`${command}\n`);
};

0 comments on commit 1a9cd1e

Please sign in to comment.