mirror of
https://github.com/expo/watchman.git
synced 2026-11-15 09:38:05 -10:00
168 lines
5.6 KiB
JavaScript
168 lines
5.6 KiB
JavaScript
var watchman = require('fb-watchman');
|
|
var client = new watchman.Client();
|
|
|
|
client.on('end', function() {
|
|
// Called when the connection to watchman is terminated
|
|
console.log('client ended');
|
|
});
|
|
|
|
client.on('error', function(error) {
|
|
console.error('Error while talking to watchman: ', error);
|
|
});
|
|
|
|
client.command(['version'], function(error, resp) {
|
|
if (error) {
|
|
console.error('Error getting version:', error);
|
|
return;
|
|
}
|
|
console.log('Talking to watchman version', resp.version);
|
|
});
|
|
|
|
// Example of the error case
|
|
client.command(['invalid-command-never-will-work'], function(error, resp) {
|
|
if (error) {
|
|
console.error('failed to subscribe: ', error);
|
|
return;
|
|
}
|
|
});
|
|
|
|
// Initiate a watch. You can repeatedly ask to watch the same dir without
|
|
// error; Watchman will re-use an existing watch.
|
|
client.command(['watch-project', process.cwd()], function(error, resp) {
|
|
if (error) {
|
|
console.error('Error initiating watch:', error);
|
|
return;
|
|
}
|
|
|
|
// It is considered to be best practice to show any 'warning' or 'error'
|
|
// information to the user, as it may suggest steps for remediation
|
|
if ('warning' in resp) {
|
|
console.log('warning: ', resp.warning);
|
|
}
|
|
|
|
// The default subscribe behavior is to deliver a list of all current files
|
|
// when you first subscribe, so you don't need to walk the tree for yourself
|
|
// on startup. If you don't want this behavior, you should issue a `clock`
|
|
// command and use it to give a logical time constraint on the subscription.
|
|
// See further below for an example of this.
|
|
|
|
// watch-project may re-use an existing watch at a higher level in the
|
|
// filesystem. It will tell us the relative path to the directory that
|
|
// we expressed interest in, so we need to adjust for it in our results
|
|
var path_prefix = '';
|
|
var root = resp['watch'];
|
|
if ('relative_path' in resp) {
|
|
path_prefix = resp['relative_path'];
|
|
console.log('(re)using project watch at ', root, ', our dir is relative: ',
|
|
path_prefix);
|
|
}
|
|
|
|
function get_relative_name(proj_rel) {
|
|
if (path_prefix.length == 0) {
|
|
return proj_rel;
|
|
}
|
|
if (proj_rel.substr(0, path_prefix.length) == path_prefix) {
|
|
return proj_rel.substr(path_prefix.length + 1);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Subscribe to notifications about .js files
|
|
// https://facebook.github.io/watchman/docs/cmd/subscribe.html
|
|
client.command(['subscribe', root, 'mysubscription', {
|
|
// Match any .js file under process.cwd()
|
|
// https://facebook.github.io/watchman/docs/file-query.html#expressions
|
|
// Has more on the supported expression syntax
|
|
expression: ["allof",
|
|
["match", "*.js"],
|
|
// focus on the relative path from the project to the path
|
|
// of interest
|
|
['dirname', path_prefix]
|
|
],
|
|
// Which fields we're interested in
|
|
fields: ["name", "size", "exists", "type"]
|
|
}],
|
|
function(error, resp) {
|
|
if (error) {
|
|
// Probably an error in the subscription criteria
|
|
console.error('failed to subscribe: ', error);
|
|
return;
|
|
}
|
|
console.log('subscription ' + resp.subscribe + ' established');
|
|
}
|
|
);
|
|
|
|
// Subscription results are emitted via the subscription event.
|
|
// Note that this emits for all subscriptions. If you have
|
|
// subscriptions with different `fields` you will need to check
|
|
// the subscription name and handle the differing data accordingly
|
|
client.on('subscription', function(resp) {
|
|
// Each entry in `resp.files` will have the fields you requested
|
|
// in your subscription. The default is:
|
|
// { name: 'example.js',
|
|
// size: 1680,
|
|
// new: true,
|
|
// exists: true,
|
|
// mode: 33188 }
|
|
//
|
|
// Names are relative to resp.root; join them together to
|
|
// obtain a fully qualified path.
|
|
//
|
|
// `resp` looks like this in practice:
|
|
//
|
|
// { root: '/private/tmp/foo',
|
|
// subscription: 'mysubscription',
|
|
// files: [ { name: 'node_modules/fb-watchman/index.js',
|
|
// size: 4768,
|
|
// exists: true,
|
|
// mode: 33188 } ] }
|
|
console.log(resp.root, resp.subscription);
|
|
for (var i in resp.files) {
|
|
var f = resp.files[i];
|
|
// Fixup name for watch-project offset
|
|
if (resp.subscription == 'mysubscription') {
|
|
// we requested a set of fields in this subscription
|
|
f.name = get_relative_name(f.name);
|
|
} else {
|
|
// the other subscription we set up returns only the name
|
|
f = get_relative_name(f);
|
|
}
|
|
console.log(f);
|
|
}
|
|
});
|
|
|
|
// Here's an example of just subscribing for notifications after the
|
|
// current point in time
|
|
client.command(['clock', root], function(error, resp) {
|
|
if (error) {
|
|
console.error('Failed to query clock:', error);
|
|
return;
|
|
}
|
|
|
|
client.command(['subscribe', root, 'sincesub', {
|
|
expression: ['allof',
|
|
["match", "*.js"],
|
|
// focus on the relative path from the project to the path
|
|
// of interest
|
|
['dirname', path_prefix]
|
|
],
|
|
// Note: since we only request a single field, the `sincesub` subscription
|
|
// response will just set files to an array of filenames, not an array of
|
|
// objects with name properties
|
|
// { root: '/private/tmp/foo',
|
|
// subscription: 'sincesub',
|
|
// files: [ 'node_modules/fb-watchman/index.js' ] }
|
|
fields: ["name"],
|
|
since: resp.clock // time constraint
|
|
}],
|
|
function(error, resp) {
|
|
if (error) {
|
|
console.error('failed to subscribe: ', error);
|
|
return;
|
|
}
|
|
console.log('subscription ' + resp.subscribe + ' established');
|
|
}
|
|
);
|
|
});
|
|
});
|