From cddc502b923b6fb70247e7a25f1eb54fbb801d56 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Fri, 3 May 2019 15:52:39 -0700 Subject: [PATCH] fbcode_builder: getdeps: introduce loader class Summary: The loader makes it possible to monkey patch the functions that are responsible for loading manifests. It is intended to be use in tests that are run in bucks sandboxed environment and that don't have direct access to the manifest files on disk. Reviewed By: simpkins Differential Revision: D14781326 fbshipit-source-id: 18f69f8ce5768dc605b1a9388a80b7b7b9ffe0f4 --- build/fbcode_builder/getdeps/load.py | 59 ++++++++++++++++++- .../getdeps/test/manifest_test.py | 12 ++-- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/build/fbcode_builder/getdeps/load.py b/build/fbcode_builder/getdeps/load.py index 116f64492..26cb5139a 100644 --- a/build/fbcode_builder/getdeps/load.py +++ b/build/fbcode_builder/getdeps/load.py @@ -7,11 +7,63 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import glob import os from .manifest import ManifestParser +class Loader(object): + """ The loader allows our tests to patch the load operation """ + + def load_project(self, build_opts, project_name): + manifest_path = resolve_manifest_path(build_opts, project_name) + return ManifestParser(manifest_path) + + def load_all(self, build_opts): + manifests_by_name = {} + manifests_dir = os.path.join(build_opts.fbcode_builder_dir, "manifests") + # We use glob rather than os.listdir because glob won't include + # eg: vim swap files that a maintainer might happen to have + # for manifests that they are editing + for name in glob.glob("%s/*" % manifests_dir): + m = ManifestParser(name) + manifests_by_name[m.name] = m + + return manifests_by_name + + +class ResourceLoader(Loader): + def __init__(self, namespace): + self.namespace = namespace + + def load_project(self, build_opts, project_name): + import pkg_resources + + contents = pkg_resources.resource_string( + self.namespace, "manifests/%s" % project_name + ).decode("utf8") + m = ManifestParser(file_name=project_name, fp=contents) + return m + + def load_all(self, build_opts): + import pkg_resources + + manifest_by_name = {} + for name in pkg_resources.resource_listdir(self.namespace, "manifests"): + m = self.load_project(build_opts, name) + manifest_by_name[m.name] = m + return manifest_by_name + + +LOADER = Loader() + + +def patch_loader(namespace): + global LOADER + LOADER = ResourceLoader(namespace) + + def resolve_manifest_path(build_opts, project_name): if "/" in project_name or "\\" in project_name: # Assume this is a path already @@ -24,8 +76,11 @@ def resolve_manifest_path(build_opts, project_name): def load_project(build_opts, project_name): """ given the name of a project or a path to a manifest file, load up the ManifestParser instance for it and return it """ - manifest_path = resolve_manifest_path(build_opts, project_name) - return ManifestParser(manifest_path) + return LOADER.load_project(build_opts, project_name) + + +def load_all_manifests(build_opts): + return LOADER.load_all(build_opts) def manifests_in_dependency_order(build_opts, manifest, ctx): diff --git a/build/fbcode_builder/getdeps/test/manifest_test.py b/build/fbcode_builder/getdeps/test/manifest_test.py index 8c018f866..f0c249808 100644 --- a/build/fbcode_builder/getdeps/test/manifest_test.py +++ b/build/fbcode_builder/getdeps/test/manifest_test.py @@ -12,6 +12,7 @@ import unittest import pkg_resources +from ..load import load_all_manifests, patch_loader from ..manifest import ManifestParser @@ -207,11 +208,6 @@ foo = bar ) def test_parse_common_manifests(self): - n = 0 - for name in pkg_resources.resource_listdir(__name__, "manifests"): - contents = pkg_resources.resource_string( - __name__, "manifests/%s" % name - ).decode("utf8") - ManifestParser(file_name=name, fp=contents) - n += 1 - self.assertTrue(n > 0, msg="parsed some number of manifests") + patch_loader(__name__) + manifests = load_all_manifests(None) + self.assertNotEqual(0, len(manifests), msg="parsed some number of manifests")