Commit 9691120a authored by Zeyi (Rice) Fan's avatar Zeyi (Rice) Fan Committed by Facebook Github Bot

getdeps: include subdirectories when searching manifest

Summary: Make getdeps to look for subdirectories for manifest files.

Reviewed By: simpkins

Differential Revision: D17222388

fbshipit-source-id: e13503beccd9edf6d80f78fbc3238b2a8d2053dd
parent 0bfa67ca
...@@ -120,6 +120,10 @@ class BuildOptions(object): ...@@ -120,6 +120,10 @@ class BuildOptions(object):
self.vcvars_path = vcvars_path self.vcvars_path = vcvars_path
@property
def manifests_dir(self):
return os.path.join(self.fbcode_builder_dir, "manifests")
def is_darwin(self): def is_darwin(self):
return self.host_type.is_darwin() return self.host_type.is_darwin()
......
...@@ -14,3 +14,8 @@ class TransientFailure(Exception): ...@@ -14,3 +14,8 @@ class TransientFailure(Exception):
infrastructure error """ infrastructure error """
pass pass
class ManifestNotFound(Exception):
def __init__(self, manifest_name):
super(Exception, self).__init__("Unable to find manifest '%s'" % manifest_name)
...@@ -8,30 +8,44 @@ ...@@ -8,30 +8,44 @@
from __future__ import absolute_import, division, print_function, unicode_literals from __future__ import absolute_import, division, print_function, unicode_literals
import base64 import base64
import glob
import hashlib import hashlib
import os import os
from . import fetcher from . import fetcher
from .envfuncs import path_search from .envfuncs import path_search
from .errors import ManifestNotFound
from .manifest import ManifestParser from .manifest import ManifestParser
class Loader(object): class Loader(object):
""" The loader allows our tests to patch the load operation """ """ The loader allows our tests to patch the load operation """
def _list_manifests(self, manifests_dir):
""" Returns a generator that iterates all the available manifests """
for (path, _, files) in os.walk(manifests_dir):
for name in files:
# skip hidden files
if name.startswith("."):
continue
yield os.path.join(path, name)
def load_project(self, build_opts, project_name): def load_project(self, build_opts, project_name):
manifest_path = resolve_manifest_path(build_opts, project_name) if "/" in project_name or "\\" in project_name:
return ManifestParser(manifest_path) # Assume this is a path already
return ManifestParser(project_name)
for manifest in self._list_manifests(build_opts.manifests_dir):
if os.path.basename(manifest) == project_name:
return ManifestParser(manifest)
raise ManifestNotFound(project_name)
def load_all(self, build_opts): def load_all(self, build_opts):
manifests_by_name = {} 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 for manifest in self._list_manifests(build_opts.manifests_dir):
# eg: vim swap files that a maintainer might happen to have m = ManifestParser(manifest)
# for manifests that they are editing
for name in glob.glob("%s/*" % manifests_dir):
m = ManifestParser(name)
manifests_by_name[m.name] = m manifests_by_name[m.name] = m
return manifests_by_name return manifests_by_name
...@@ -41,23 +55,45 @@ class ResourceLoader(Loader): ...@@ -41,23 +55,45 @@ class ResourceLoader(Loader):
def __init__(self, namespace): def __init__(self, namespace):
self.namespace = namespace self.namespace = namespace
def load_project(self, build_opts, project_name): def _list_manifests(self):
import pkg_resources import pkg_resources
contents = pkg_resources.resource_string( dirs = ["manifests"]
self.namespace, "manifests/%s" % project_name
).decode("utf8")
m = ManifestParser(file_name=project_name, fp=contents)
return m
def load_all(self, build_opts): while dirs:
current = dirs.pop(0)
for name in pkg_resources.resource_listdir(self.namespace, current):
path = "%s/%s" % (current, name)
if pkg_resources.resource_isdir(self.namespace, path):
dirs.append(path)
else:
yield "%s/%s" % (current, name)
def _find_manifest(self, project_name):
for name in self._list_manifests():
if name.endswith("/%s" % project_name):
return name
raise ManifestNotFound(project_name)
def _load_resource_manifest(self, path):
import pkg_resources import pkg_resources
manifest_by_name = {} contents = pkg_resources.resource_string(self.namespace, path).decode("utf8")
for name in pkg_resources.resource_listdir(self.namespace, "manifests"): return ManifestParser(file_name=path, fp=contents)
m = self.load_project(build_opts, name)
manifest_by_name[m.name] = m def load_project(self, build_opts, project_name):
return manifest_by_name project_name = self._find_manifest(project_name)
return self._load_resource_manifest(project_name)
def load_all(self, build_opts):
manifests_by_name = {}
for path in self._list_manifests():
m = self._load_resource_manifest(path)
manifests_by_name[m.name] = m
return manifests_by_name
LOADER = Loader() LOADER = Loader()
...@@ -68,15 +104,6 @@ def patch_loader(namespace): ...@@ -68,15 +104,6 @@ def patch_loader(namespace):
LOADER = ResourceLoader(namespace) 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
return project_name
# Otherwise, resolve it relative to the manifests dir
return os.path.join(build_opts.fbcode_builder_dir, "manifests", project_name)
def load_project(build_opts, project_name): def load_project(build_opts, project_name):
""" given the name of a project or a path to a manifest file, """ given the name of a project or a path to a manifest file,
load up the ManifestParser instance for it and return it """ load up the ManifestParser instance for it and return it """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment