Pratyush Mallick
/
nano_dac
this is testing
noos_mbed/.git/hooks/fsmonitor-watchman.sample@0:e8a1ba50c46b, 2021-01-14 (annotated)
- Committer:
- pmallick
- Date:
- Thu Jan 14 19:12:57 2021 +0530
- Revision:
- 0:e8a1ba50c46b
this is testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pmallick | 0:e8a1ba50c46b | 1 | #!/usr/bin/perl |
pmallick | 0:e8a1ba50c46b | 2 | |
pmallick | 0:e8a1ba50c46b | 3 | use strict; |
pmallick | 0:e8a1ba50c46b | 4 | use warnings; |
pmallick | 0:e8a1ba50c46b | 5 | use IPC::Open2; |
pmallick | 0:e8a1ba50c46b | 6 | |
pmallick | 0:e8a1ba50c46b | 7 | # An example hook script to integrate Watchman |
pmallick | 0:e8a1ba50c46b | 8 | # (https://facebook.github.io/watchman/) with git to speed up detecting |
pmallick | 0:e8a1ba50c46b | 9 | # new and modified files. |
pmallick | 0:e8a1ba50c46b | 10 | # |
pmallick | 0:e8a1ba50c46b | 11 | # The hook is passed a version (currently 2) and last update token |
pmallick | 0:e8a1ba50c46b | 12 | # formatted as a string and outputs to stdout a new update token and |
pmallick | 0:e8a1ba50c46b | 13 | # all files that have been modified since the update token. Paths must |
pmallick | 0:e8a1ba50c46b | 14 | # be relative to the root of the working tree and separated by a single NUL. |
pmallick | 0:e8a1ba50c46b | 15 | # |
pmallick | 0:e8a1ba50c46b | 16 | # To enable this hook, rename this file to "query-watchman" and set |
pmallick | 0:e8a1ba50c46b | 17 | # 'git config core.fsmonitor .git/hooks/query-watchman' |
pmallick | 0:e8a1ba50c46b | 18 | # |
pmallick | 0:e8a1ba50c46b | 19 | my ($version, $last_update_token) = @ARGV; |
pmallick | 0:e8a1ba50c46b | 20 | |
pmallick | 0:e8a1ba50c46b | 21 | # Uncomment for debugging |
pmallick | 0:e8a1ba50c46b | 22 | # print STDERR "$0 $version $last_update_token\n"; |
pmallick | 0:e8a1ba50c46b | 23 | |
pmallick | 0:e8a1ba50c46b | 24 | # Check the hook interface version |
pmallick | 0:e8a1ba50c46b | 25 | if ($version ne 2) { |
pmallick | 0:e8a1ba50c46b | 26 | die "Unsupported query-fsmonitor hook version '$version'.\n" . |
pmallick | 0:e8a1ba50c46b | 27 | "Falling back to scanning...\n"; |
pmallick | 0:e8a1ba50c46b | 28 | } |
pmallick | 0:e8a1ba50c46b | 29 | |
pmallick | 0:e8a1ba50c46b | 30 | my $git_work_tree = get_working_dir(); |
pmallick | 0:e8a1ba50c46b | 31 | |
pmallick | 0:e8a1ba50c46b | 32 | my $retry = 1; |
pmallick | 0:e8a1ba50c46b | 33 | |
pmallick | 0:e8a1ba50c46b | 34 | my $json_pkg; |
pmallick | 0:e8a1ba50c46b | 35 | eval { |
pmallick | 0:e8a1ba50c46b | 36 | require JSON::XS; |
pmallick | 0:e8a1ba50c46b | 37 | $json_pkg = "JSON::XS"; |
pmallick | 0:e8a1ba50c46b | 38 | 1; |
pmallick | 0:e8a1ba50c46b | 39 | } or do { |
pmallick | 0:e8a1ba50c46b | 40 | require JSON::PP; |
pmallick | 0:e8a1ba50c46b | 41 | $json_pkg = "JSON::PP"; |
pmallick | 0:e8a1ba50c46b | 42 | }; |
pmallick | 0:e8a1ba50c46b | 43 | |
pmallick | 0:e8a1ba50c46b | 44 | launch_watchman(); |
pmallick | 0:e8a1ba50c46b | 45 | |
pmallick | 0:e8a1ba50c46b | 46 | sub launch_watchman { |
pmallick | 0:e8a1ba50c46b | 47 | my $o = watchman_query(); |
pmallick | 0:e8a1ba50c46b | 48 | if (is_work_tree_watched($o)) { |
pmallick | 0:e8a1ba50c46b | 49 | output_result($o->{clock}, @{$o->{files}}); |
pmallick | 0:e8a1ba50c46b | 50 | } |
pmallick | 0:e8a1ba50c46b | 51 | } |
pmallick | 0:e8a1ba50c46b | 52 | |
pmallick | 0:e8a1ba50c46b | 53 | sub output_result { |
pmallick | 0:e8a1ba50c46b | 54 | my ($clockid, @files) = @_; |
pmallick | 0:e8a1ba50c46b | 55 | |
pmallick | 0:e8a1ba50c46b | 56 | # Uncomment for debugging watchman output |
pmallick | 0:e8a1ba50c46b | 57 | # open (my $fh, ">", ".git/watchman-output.out"); |
pmallick | 0:e8a1ba50c46b | 58 | # binmode $fh, ":utf8"; |
pmallick | 0:e8a1ba50c46b | 59 | # print $fh "$clockid\n@files\n"; |
pmallick | 0:e8a1ba50c46b | 60 | # close $fh; |
pmallick | 0:e8a1ba50c46b | 61 | |
pmallick | 0:e8a1ba50c46b | 62 | binmode STDOUT, ":utf8"; |
pmallick | 0:e8a1ba50c46b | 63 | print $clockid; |
pmallick | 0:e8a1ba50c46b | 64 | print "\0"; |
pmallick | 0:e8a1ba50c46b | 65 | local $, = "\0"; |
pmallick | 0:e8a1ba50c46b | 66 | print @files; |
pmallick | 0:e8a1ba50c46b | 67 | } |
pmallick | 0:e8a1ba50c46b | 68 | |
pmallick | 0:e8a1ba50c46b | 69 | sub watchman_clock { |
pmallick | 0:e8a1ba50c46b | 70 | my $response = qx/watchman clock "$git_work_tree"/; |
pmallick | 0:e8a1ba50c46b | 71 | die "Failed to get clock id on '$git_work_tree'.\n" . |
pmallick | 0:e8a1ba50c46b | 72 | "Falling back to scanning...\n" if $? != 0; |
pmallick | 0:e8a1ba50c46b | 73 | |
pmallick | 0:e8a1ba50c46b | 74 | return $json_pkg->new->utf8->decode($response); |
pmallick | 0:e8a1ba50c46b | 75 | } |
pmallick | 0:e8a1ba50c46b | 76 | |
pmallick | 0:e8a1ba50c46b | 77 | sub watchman_query { |
pmallick | 0:e8a1ba50c46b | 78 | my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') |
pmallick | 0:e8a1ba50c46b | 79 | or die "open2() failed: $!\n" . |
pmallick | 0:e8a1ba50c46b | 80 | "Falling back to scanning...\n"; |
pmallick | 0:e8a1ba50c46b | 81 | |
pmallick | 0:e8a1ba50c46b | 82 | # In the query expression below we're asking for names of files that |
pmallick | 0:e8a1ba50c46b | 83 | # changed since $last_update_token but not from the .git folder. |
pmallick | 0:e8a1ba50c46b | 84 | # |
pmallick | 0:e8a1ba50c46b | 85 | # To accomplish this, we're using the "since" generator to use the |
pmallick | 0:e8a1ba50c46b | 86 | # recency index to select candidate nodes and "fields" to limit the |
pmallick | 0:e8a1ba50c46b | 87 | # output to file names only. Then we're using the "expression" term to |
pmallick | 0:e8a1ba50c46b | 88 | # further constrain the results. |
pmallick | 0:e8a1ba50c46b | 89 | if (substr($last_update_token, 0, 1) eq "c") { |
pmallick | 0:e8a1ba50c46b | 90 | $last_update_token = "\"$last_update_token\""; |
pmallick | 0:e8a1ba50c46b | 91 | } |
pmallick | 0:e8a1ba50c46b | 92 | my $query = <<" END"; |
pmallick | 0:e8a1ba50c46b | 93 | ["query", "$git_work_tree", { |
pmallick | 0:e8a1ba50c46b | 94 | "since": $last_update_token, |
pmallick | 0:e8a1ba50c46b | 95 | "fields": ["name"], |
pmallick | 0:e8a1ba50c46b | 96 | "expression": ["not", ["dirname", ".git"]] |
pmallick | 0:e8a1ba50c46b | 97 | }] |
pmallick | 0:e8a1ba50c46b | 98 | END |
pmallick | 0:e8a1ba50c46b | 99 | |
pmallick | 0:e8a1ba50c46b | 100 | # Uncomment for debugging the watchman query |
pmallick | 0:e8a1ba50c46b | 101 | # open (my $fh, ">", ".git/watchman-query.json"); |
pmallick | 0:e8a1ba50c46b | 102 | # print $fh $query; |
pmallick | 0:e8a1ba50c46b | 103 | # close $fh; |
pmallick | 0:e8a1ba50c46b | 104 | |
pmallick | 0:e8a1ba50c46b | 105 | print CHLD_IN $query; |
pmallick | 0:e8a1ba50c46b | 106 | close CHLD_IN; |
pmallick | 0:e8a1ba50c46b | 107 | my $response = do {local $/; <CHLD_OUT>}; |
pmallick | 0:e8a1ba50c46b | 108 | |
pmallick | 0:e8a1ba50c46b | 109 | # Uncomment for debugging the watch response |
pmallick | 0:e8a1ba50c46b | 110 | # open ($fh, ">", ".git/watchman-response.json"); |
pmallick | 0:e8a1ba50c46b | 111 | # print $fh $response; |
pmallick | 0:e8a1ba50c46b | 112 | # close $fh; |
pmallick | 0:e8a1ba50c46b | 113 | |
pmallick | 0:e8a1ba50c46b | 114 | die "Watchman: command returned no output.\n" . |
pmallick | 0:e8a1ba50c46b | 115 | "Falling back to scanning...\n" if $response eq ""; |
pmallick | 0:e8a1ba50c46b | 116 | die "Watchman: command returned invalid output: $response\n" . |
pmallick | 0:e8a1ba50c46b | 117 | "Falling back to scanning...\n" unless $response =~ /^\{/; |
pmallick | 0:e8a1ba50c46b | 118 | |
pmallick | 0:e8a1ba50c46b | 119 | return $json_pkg->new->utf8->decode($response); |
pmallick | 0:e8a1ba50c46b | 120 | } |
pmallick | 0:e8a1ba50c46b | 121 | |
pmallick | 0:e8a1ba50c46b | 122 | sub is_work_tree_watched { |
pmallick | 0:e8a1ba50c46b | 123 | my ($output) = @_; |
pmallick | 0:e8a1ba50c46b | 124 | my $error = $output->{error}; |
pmallick | 0:e8a1ba50c46b | 125 | if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { |
pmallick | 0:e8a1ba50c46b | 126 | $retry--; |
pmallick | 0:e8a1ba50c46b | 127 | my $response = qx/watchman watch "$git_work_tree"/; |
pmallick | 0:e8a1ba50c46b | 128 | die "Failed to make watchman watch '$git_work_tree'.\n" . |
pmallick | 0:e8a1ba50c46b | 129 | "Falling back to scanning...\n" if $? != 0; |
pmallick | 0:e8a1ba50c46b | 130 | $output = $json_pkg->new->utf8->decode($response); |
pmallick | 0:e8a1ba50c46b | 131 | $error = $output->{error}; |
pmallick | 0:e8a1ba50c46b | 132 | die "Watchman: $error.\n" . |
pmallick | 0:e8a1ba50c46b | 133 | "Falling back to scanning...\n" if $error; |
pmallick | 0:e8a1ba50c46b | 134 | |
pmallick | 0:e8a1ba50c46b | 135 | # Uncomment for debugging watchman output |
pmallick | 0:e8a1ba50c46b | 136 | # open (my $fh, ">", ".git/watchman-output.out"); |
pmallick | 0:e8a1ba50c46b | 137 | # close $fh; |
pmallick | 0:e8a1ba50c46b | 138 | |
pmallick | 0:e8a1ba50c46b | 139 | # Watchman will always return all files on the first query so |
pmallick | 0:e8a1ba50c46b | 140 | # return the fast "everything is dirty" flag to git and do the |
pmallick | 0:e8a1ba50c46b | 141 | # Watchman query just to get it over with now so we won't pay |
pmallick | 0:e8a1ba50c46b | 142 | # the cost in git to look up each individual file. |
pmallick | 0:e8a1ba50c46b | 143 | my $o = watchman_clock(); |
pmallick | 0:e8a1ba50c46b | 144 | $error = $output->{error}; |
pmallick | 0:e8a1ba50c46b | 145 | |
pmallick | 0:e8a1ba50c46b | 146 | die "Watchman: $error.\n" . |
pmallick | 0:e8a1ba50c46b | 147 | "Falling back to scanning...\n" if $error; |
pmallick | 0:e8a1ba50c46b | 148 | |
pmallick | 0:e8a1ba50c46b | 149 | output_result($o->{clock}, ("/")); |
pmallick | 0:e8a1ba50c46b | 150 | $last_update_token = $o->{clock}; |
pmallick | 0:e8a1ba50c46b | 151 | |
pmallick | 0:e8a1ba50c46b | 152 | eval { launch_watchman() }; |
pmallick | 0:e8a1ba50c46b | 153 | return 0; |
pmallick | 0:e8a1ba50c46b | 154 | } |
pmallick | 0:e8a1ba50c46b | 155 | |
pmallick | 0:e8a1ba50c46b | 156 | die "Watchman: $error.\n" . |
pmallick | 0:e8a1ba50c46b | 157 | "Falling back to scanning...\n" if $error; |
pmallick | 0:e8a1ba50c46b | 158 | |
pmallick | 0:e8a1ba50c46b | 159 | return 1; |
pmallick | 0:e8a1ba50c46b | 160 | } |
pmallick | 0:e8a1ba50c46b | 161 | |
pmallick | 0:e8a1ba50c46b | 162 | sub get_working_dir { |
pmallick | 0:e8a1ba50c46b | 163 | my $working_dir; |
pmallick | 0:e8a1ba50c46b | 164 | if ($^O =~ 'msys' || $^O =~ 'cygwin') { |
pmallick | 0:e8a1ba50c46b | 165 | $working_dir = Win32::GetCwd(); |
pmallick | 0:e8a1ba50c46b | 166 | $working_dir =~ tr/\\/\//; |
pmallick | 0:e8a1ba50c46b | 167 | } else { |
pmallick | 0:e8a1ba50c46b | 168 | require Cwd; |
pmallick | 0:e8a1ba50c46b | 169 | $working_dir = Cwd::cwd(); |
pmallick | 0:e8a1ba50c46b | 170 | } |
pmallick | 0:e8a1ba50c46b | 171 | |
pmallick | 0:e8a1ba50c46b | 172 | return $working_dir; |
pmallick | 0:e8a1ba50c46b | 173 | } |