# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Use pywatchman to watch source directories and perform partial
``mach build faster`` builds. """
# Get the initial clock value so that we only get updates. # Wait 30s to allow for slow Windows IO. See # https://facebook.github.io/watchman/docs/cmd/clock.html.
query["since"] = self.client.query("clock", root, {"sync_timeout": 30000})[ "clock"
]
def changed_files(self): # In theory we can parse just the result variable here, but # the client object will accumulate all subscription results # over time, so we ask it to remove and return those values.
files = set()
data = self.client.getSubscription("topsrcdir") if data: for dat in data:
files |= set(
[
mozpath.normpath(
mozpath.join(self.config_environment.topsrcdir, f)
) for f in dat.get("files", [])
]
)
return files
def incremental_copy(self, copier, force=False, verbose=True): # Just like the 'repackage' target in browser/app/Makefile.in. if"cocoa" == self.config_environment.substs["MOZ_WIDGET_TOOLKIT"]:
bundledir = mozpath.join(
self.config_environment.topobjdir, "dist",
self.config_environment.substs["MOZ_MACBUNDLE_NAME"], "Contents", "Resources",
)
start = time.monotonic()
result = copier.copy(
bundledir,
skip_if_older=not force,
remove_unaccounted=False,
remove_all_directory_symlinks=False,
remove_empty_directories=False,
)
print_copy_result(
time.monotonic() - start, bundledir, result, verbose=verbose
)
def input_changes(self, verbose=True): """ Return an iterator of `FasterBuildChange` instances as inputs
to the faster build system change. """
# TODO: provide the debug diagnostics we want: this print is # not immediately before the watch. if verbose:
print_line("watch", "Connecting to watchman") # TODO: figure out why a large timeout is required for the # client, and a robust strategy for retrying timed out # requests.
self.client = pywatchman.client(timeout=5.0)
try: if verbose:
print_line("watch", "Checking watchman capabilities") # TODO: restrict these capabilities to the minimal set.
self.client.capabilityCheck(
required=[ "clock-sync-timeout", "cmd-watch-project", "term-dirname", "wildmatch",
]
)
if verbose:
print_line( "watch", "Subscribing to {}".format(self.config_environment.topsrcdir),
)
self.subscribe_to_topsrcdir() if verbose:
print_line( "watch", "Watching {}".format(self.config_environment.topsrcdir)
)
input_to_outputs = self.file_copier.input_to_outputs_tree() for input, outputs in input_to_outputs.items(): ifnot outputs: raise Exception( "Refusing to watch input ({}) with no outputs".format(input)
)
for change in changed: if change in input_to_outputs:
result.input_to_outputs[change] = set(
input_to_outputs[change]
) else:
result.unrecognized.add(change)
for input, outputs in result.input_to_outputs.items(): for output in outputs: if output notin result.output_to_inputs:
result.output_to_inputs[output] = set()
result.output_to_inputs[output].add(input)
yield result
except pywatchman.SocketTimeout: # Let's check to see if we're still functional.
self.client.query("version")
except pywatchman.CommandError as e: # Abstract away pywatchman errors. raise FasterBuildException(
e, "Command error using pywatchman to watch {}".format(
self.config_environment.topsrcdir
),
)
except pywatchman.SocketTimeout as e: # Abstract away pywatchman errors. raise FasterBuildException(
e, "Socket timeout using pywatchman to watch {}".format(
self.config_environment.topsrcdir
),
)
finally:
self.client.close()
def output_changes(self, verbose=True): """ Return an iterator of `FasterBuildChange` instances as outputs from the faster build system are updated. """ for change in self.input_changes(verbose=verbose):
now = datetime.datetime.utcnow()
for unrecognized in sorted(change.unrecognized):
print_line("watch", "! {}".format(unrecognized), now=now)
all_outputs = set() for input in sorted(change.input_to_outputs):
outputs = change.input_to_outputs[input]
print_line("watch", "< {}".format(input), now=now) for output in sorted(outputs):
print_line("watch", "> {}".format(output), now=now)
all_outputs |= outputs
if all_outputs:
partial_copier = FileCopier() for output in all_outputs:
partial_copier.add(output, self.file_copier[output])
for change in self.output_changes(verbose=verbose): # Try to run the active build backend's post-build step, if possible. if backend_cls:
backend_cls.post_build(self.config_environment, None, 1, False, 0)
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.