fbcode_builder: add getdeps main entrypoint

Summary:
This is the new getdeps entrypoint.  It lives in `opensource/fbcode_builder` so that
it is synced into the various opensource projects at FB.

In the incarnation in this diff is has a single subcommand that can be used to validate
a manifest file.

Reviewed By: sinancepel

Differential Revision: D14690995

fbshipit-source-id: 53f8ec9bafb7b1930970079e3ce20f496ac1c188
This commit is contained in:
Wez Furlong 2019-05-03 15:52:39 -07:00 committed by Facebook Github Bot
parent 4b50455edb
commit 0bc46905d0
3 changed files with 127 additions and 0 deletions

69
build/fbcode_builder/getdeps.py Executable file
View File

@ -0,0 +1,69 @@
#!/usr/bin/env python
# Copyright (c) 2019-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
from __future__ import absolute_import, division, print_function, unicode_literals
import argparse
import os
import subprocess
import sys
from getdeps.manifest import ManifestParser
from getdeps.subcmd import SubCmd, add_subcommands, cmd
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "getdeps"))
@cmd("validate-manifest", "parse a manifest and validate that it is correct")
class ValidateManifest(SubCmd):
def run(self, args):
try:
ManifestParser(file_name=args.file_name)
print("OK", file=sys.stderr)
return 0
except Exception as exc:
print("ERROR: %s" % str(exc), file=sys.stderr)
return 1
def setup_parser(self, parser):
parser.add_argument("file_name", help="path to the manifest file")
def build_argparser():
ap = argparse.ArgumentParser(description="Get and build dependencies and projects")
sub = ap.add_subparsers(
# metavar suppresses the long and ugly default list of subcommands on a
# single line. We still render the nicer list below where we would
# have shown the nasty one.
metavar="",
title="Available commands",
help="",
)
add_subcommands(sub)
return ap
def main():
ap = build_argparser()
args = ap.parse_args()
if getattr(args, "func", None) is None:
ap.print_help()
return 0
try:
return args.func(args)
except subprocess.CalledProcessError:
print("!! Failed", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())

View File

View File

@ -0,0 +1,58 @@
# Copyright (c) 2019-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.
from __future__ import absolute_import, division, print_function, unicode_literals
class SubCmd(object):
NAME = None
HELP = None
def run(self, args):
""" perform the command """
return 0
def setup_parser(self, parser):
# Subclasses should override setup_parser() if they have any
# command line options or arguments.
pass
CmdTable = []
def add_subcommands(parser, cmd_table=CmdTable):
""" Register parsers for the defined commands with the provided parser """
for cls in cmd_table:
command = cls()
command_parser = parser.add_parser(command.NAME, help=command.HELP)
command.setup_parser(command_parser)
command_parser.set_defaults(func=command.run)
def cmd(name, help=None, cmd_table=CmdTable):
"""
@cmd() is a decorator that can be used to help define Subcmd instances
Example usage:
@subcmd('list', 'Show the result list')
class ListCmd(Subcmd):
def run(self, args):
# Perform the command actions here...
pass
"""
def wrapper(cls):
class SubclassedCmd(cls):
NAME = name
HELP = help
cmd_table.append(SubclassedCmd)
return SubclassedCmd
return wrapper