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
This commit is contained in:
Wez Furlong 2019-05-03 15:52:39 -07:00 committed by Facebook Github Bot
parent 27776a83b1
commit 23ad8b952a
2 changed files with 61 additions and 10 deletions

View File

@ -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):

View File

@ -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")