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

What if Watchman CLI is missing... #2643

Closed
wants to merge 8 commits into from
Closed
3 changes: 1 addition & 2 deletions packages/relay-compiler/bin/RelayCompilerMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ Ensure that one such file exists in ${srcDir} or its parents.
verbose: options.verbose,
quiet: options.quiet,
});

const useWatchman = options.watchman && (await WatchmanClient.isAvailable());

const schema = getSchema(schemaPath);
Expand Down Expand Up @@ -270,7 +269,7 @@ Ensure that one such file exists in ${srcDir} or its parents.
// TODO: allow passing in a flag or detect?
sourceControl: null,
});
if (!options.validate && !options.watch && options.watchman) {
if (!options.validate && !options.watch && useWatchman) {
// eslint-disable-next-line no-console
console.log('HINT: pass --watch to keep watching for changes.');
}
Expand Down
21 changes: 20 additions & 1 deletion packages/relay-compiler/core/GraphQLWatchmanClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,38 @@
'use strict';

const watchman = require('fb-watchman');
const childProcess = require('child_process');

const MAX_ATTEMPT_LIMIT = 5;

function delay(delayMs: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, delayMs));
}

function hasWatchmanInstalled(): Promise<boolean> {
return new Promise(resolve => {
const proc = childProcess.spawn('watchman', ['--version']);
proc.on('error', () => {
resolve(false);
});
proc.on('close', code => {
if (code === 0) {
resolve(true);
}
});
});
}

class GraphQLWatchmanClient {
_client: any;
_attemptLimit: number;

static isAvailable(): Promise<boolean> {
return new Promise(resolve => {
return new Promise(async resolve => {
const hasWatchman = await hasWatchmanInstalled();
if (!hasWatchman) {
return resolve(false);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

TIL about command ! ✨

How about using the exit status, though? (And made it async too, although it probably matters very little overall.)

const exec = require("util").promisify(require("child_process").exec)
undefined
> exec("command -v does-not-exist").then(() => console.log("Exists!")).catch(() => console.log("Does not exist!"))
Promise {  }
> Does not exist!
> exec("command -v ls").then(() => console.log("Exists!")).catch(() => console.log("Does not exist!"))
Promise {  }
> Exists!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just realized that this won't work on windows. I will add something else.

const client = new GraphQLWatchmanClient(MAX_ATTEMPT_LIMIT);
client.on('error', () => {
resolve(false);
Expand Down