Files
opentelemetry-python-contrib/scripts/generate_instrumentation_bootstrap.py
2021-09-27 20:28:32 +00:00

121 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import ast
import filecmp
import logging
import os
import subprocess
import sys
import tempfile
import astor
import pkg_resources
import requests
from otel_packaging import get_instrumentation_packages, scripts_path
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("instrumentation_list_generator")
_auto_generation_msg = """
# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM templates/{source}.
# RUN `python scripts/generate_setup.py` TO REGENERATE.
"""
_template = """
{header}
# DO NOT EDIT. THIS FILE WAS AUTOGENERATED FROM INSTRUMENTATION PACKAGES.
# RUN `python scripts/generate_instrumentation_bootstrap.py` TO REGENERATE.
{source}
"""
_source_tmpl = """
libraries = {}
default_instrumentations = []
"""
tmpdir = tempfile.TemporaryDirectory() # pylint: disable=R1732
gen_path = os.path.join(tmpdir.name, "new.py",)
current_path = os.path.join(tmpdir.name, "current.py",)
core_repo = os.getenv("CORE_REPO_SHA", "main")
url = f"https://raw.githubusercontent.com/open-telemetry/opentelemetry-python/{core_repo}/opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py"
r = requests.get(url, allow_redirects=True)
with open(current_path, "wb") as output:
output.write(r.content)
def main():
# pylint: disable=no-member
default_instrumentations = ast.List(elts=[])
libraries = ast.Dict(keys=[], values=[])
for pkg in get_instrumentation_packages():
if not pkg["instruments"]:
default_instrumentations.elts.append(ast.Str(pkg["requirement"]))
for target_pkg in pkg["instruments"]:
parsed = pkg_resources.Requirement.parse(target_pkg)
libraries.keys.append(ast.Str(parsed.name))
libraries.values.append(
ast.Dict(
keys=[ast.Str("library"), ast.Str("instrumentation")],
values=[ast.Str(target_pkg), ast.Str(pkg["requirement"])],
)
)
tree = ast.parse(_source_tmpl)
tree.body[0].value = libraries
tree.body[1].value = default_instrumentations
source = astor.to_source(tree)
with open(
os.path.join(scripts_path, "license_header.txt"), "r", encoding="utf-8"
) as header_file:
header = header_file.read()
source = _template.format(header=header, source=source)
with open(gen_path, "w", encoding="utf-8") as gen_file:
gen_file.write(source)
subprocess.run(
[
sys.executable,
"scripts/eachdist.py",
"format",
"--path",
tmpdir.name,
],
check=True,
)
logger.info("generated %s", gen_path)
def compare():
if not filecmp.cmp(current_path, gen_path):
logger.info(
'Generated code is out of date, please run "tox -e generate" and commit bootstrap_gen.py to core repo.'
)
os.replace(gen_path, "bootstrap_gen.py")
sys.exit(1)
if __name__ == "__main__":
main()
compare()