diff --git a/packages/google-cloud-containeranalysis/.github/.OwlBot.lock.yaml b/packages/google-cloud-containeranalysis/.github/.OwlBot.lock.yaml new file mode 100644 index 000000000000..3e1b7787d41d --- /dev/null +++ b/packages/google-cloud-containeranalysis/.github/.OwlBot.lock.yaml @@ -0,0 +1,4 @@ +docker: + digest: sha256:c0deb0984dd1c56fa04aaf6974f23f4fe674d80f4329310c3f52cd46c40b7419 + image: gcr.io/repo-automation-bots/owlbot-python:latest + diff --git a/packages/google-cloud-containeranalysis/.github/.OwlBot.yaml b/packages/google-cloud-containeranalysis/.github/.OwlBot.yaml new file mode 100644 index 000000000000..b09a23976f51 --- /dev/null +++ b/packages/google-cloud-containeranalysis/.github/.OwlBot.yaml @@ -0,0 +1,29 @@ +# Copyright 2021 Google LLC +# +# 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. + +docker: + image: gcr.io/repo-automation-bots/owlbot-python:latest + +deep-remove-regex: + - /owl-bot-staging + +deep-preserve-regex: + - /owl-bot-staging/v1beta1 + +deep-copy-regex: + - source: /google/devtools/containeranalysis/(v.*)/.*-py/(.*) + dest: /owl-bot-staging/$1/$2 + +begin-after-commit-hash: 6a5da3f1274b088752f074da5bc9e30bd1beb27e + diff --git a/packages/google-cloud-containeranalysis/.pre-commit-config.yaml b/packages/google-cloud-containeranalysis/.pre-commit-config.yaml index 1bbd787833ec..8912e9b5d7d7 100644 --- a/packages/google-cloud-containeranalysis/.pre-commit-config.yaml +++ b/packages/google-cloud-containeranalysis/.pre-commit-config.yaml @@ -26,6 +26,6 @@ repos: hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 - rev: 3.9.1 + rev: 3.9.0 hooks: - id: flake8 diff --git a/packages/google-cloud-containeranalysis/CONTRIBUTING.rst b/packages/google-cloud-containeranalysis/CONTRIBUTING.rst index 89f7728f6663..dc32e75e02fc 100644 --- a/packages/google-cloud-containeranalysis/CONTRIBUTING.rst +++ b/packages/google-cloud-containeranalysis/CONTRIBUTING.rst @@ -160,7 +160,21 @@ Running System Tests auth settings and change some configuration in your project to run all the tests. -- System tests will be run against an actual project. You should use local credentials from gcloud when possible. See `Best practices for application authentication `__. Some tests require a service account. For those tests see `Authenticating as a service account `__. +- System tests will be run against an actual project and + so you'll need to provide some environment variables to facilitate + authentication to your project: + + - ``GOOGLE_APPLICATION_CREDENTIALS``: The path to a JSON key file; + Such a file can be downloaded directly from the developer's console by clicking + "Generate new JSON key". See private key + `docs `__ + for more details. + +- Once you have downloaded your json keys, set the environment variable + ``GOOGLE_APPLICATION_CREDENTIALS`` to the absolute path of the json file:: + + $ export GOOGLE_APPLICATION_CREDENTIALS="/Users//path/to/app_credentials.json" + ************* Test Coverage diff --git a/packages/google-cloud-containeranalysis/noxfile.py b/packages/google-cloud-containeranalysis/noxfile.py index 70417e8cac20..4d37cd3a7eb6 100644 --- a/packages/google-cloud-containeranalysis/noxfile.py +++ b/packages/google-cloud-containeranalysis/noxfile.py @@ -62,9 +62,16 @@ def lint(session): session.run("flake8", "google", "tests") -@nox.session(python=DEFAULT_PYTHON_VERSION) +@nox.session(python="3.6") def blacken(session): - """Run black. Format code to uniform standard.""" + """Run black. + + Format code to uniform standard. + + This currently uses Python 3.6 due to the automated Kokoro run of synthtool. + That run uses an image that doesn't have 3.6 installed. Before updating this + check the state of the `gcp_ubuntu_config` we use for that Kokoro run. + """ session.install(BLACK_VERSION) session.run( "black", *BLACK_PATHS, @@ -124,6 +131,9 @@ def system(session): # Check the value of `RUN_SYSTEM_TESTS` env var. It defaults to true. if os.environ.get("RUN_SYSTEM_TESTS", "true") == "false": session.skip("RUN_SYSTEM_TESTS is set to false, skipping") + # Sanity check: Only run tests if the environment variable is set. + if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS", ""): + session.skip("Credentials must be set via environment variable") # Install pyopenssl for mTLS testing. if os.environ.get("GOOGLE_API_USE_CLIENT_CERTIFICATE", "false") == "true": session.install("pyopenssl") diff --git a/packages/google-cloud-containeranalysis/owlbot.py b/packages/google-cloud-containeranalysis/owlbot.py new file mode 100644 index 000000000000..c7eb1bb3a82a --- /dev/null +++ b/packages/google-cloud-containeranalysis/owlbot.py @@ -0,0 +1,110 @@ +# Copyright 2018 Google LLC +# +# 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. + +"""This script is used to synthesize generated parts of this library.""" + +import synthtool as s +import synthtool.gcp as gcp +import logging +from synthtool.languages import python + +logging.basicConfig(level=logging.DEBUG) + +common = gcp.CommonTemplates() + +default_version = "v1" + +for library in s.get_staging_dirs(default_version): + s.replace( + library / "google/**/*client.py", + r"""google-cloud-devtools-containeranalysis""", + r"""google-cloud-containeranalysis""", + ) + + # Fix imported type from grafeas + s.replace( + library / "google/**/types/containeranalysis.py", + "from grafeas\.v1 import vulnerability_pb2 as vulnerability", + "from grafeas.grafeas_v1.types import vulnerability" + ) + + # Insert helper method to get grafeas client + s.replace( + library / "google/**/client.py", + "class ContainerAnalysisClientMeta\(type\):", + "from grafeas import grafeas_v1\n" + "from grafeas.grafeas_v1.services.grafeas import transports\n\n" + "class ContainerAnalysisClientMeta(type):", + ) + + s.replace( + library / "google/**/async_client.py", + "class ContainerAnalysisAsyncClient:", + "from grafeas import grafeas_v1\n" + "from grafeas.grafeas_v1.services.grafeas import transports\n\n" + "class ContainerAnalysisAsyncClient:", + ) + + s.replace( + library / "google/**/client.py", + r"""(\s+)def set_iam_policy\(""", + r'''\n\g<1>def get_grafeas_client( + self + ) -> grafeas_v1.GrafeasClient: + transport = type(self).get_transport_class("grpc")() + grafeas_transport = grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport( + host=transport._host, + scopes=transport.AUTH_SCOPES + ) + return grafeas_v1.GrafeasClient(transport=grafeas_transport) + + \g<1># Service calls + \g<1>def set_iam_policy(''', + ) + + s.replace( + library / "google/**/async_client.py", + r"""(\s+)async def set_iam_policy\(""", + r'''\n\g<1>def get_grafeas_client( + self + ) -> grafeas_v1.GrafeasClient: + transport = type(self).get_transport_class("grpc_asyncio")() + grafeas_transport = grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport( + host=transport._host, + scopes=transport.AUTH_SCOPES + ) + return grafeas_v1.GrafeasClient(transport=grafeas_transport) + + \g<1># Service calls + \g<1>async def set_iam_policy(''', + ) + + s.move(library, excludes=["setup.py", "README.rst", "docs/index.rst"]) + +s.remove_staging_dirs() + +# ---------------------------------------------------------------------------- +# Add templated files +# ---------------------------------------------------------------------------- +templated_files = common.py_library( + samples=False, # set to True only if there are samples + microgenerator=True, + cov_level=98, +) +s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good coveragerc + +python.py_samples(skip_readmes=True) + + +s.shell.run(["nox", "-s", "blacken"], hide_output=False) \ No newline at end of file diff --git a/packages/google-cloud-containeranalysis/synth.metadata b/packages/google-cloud-containeranalysis/synth.metadata deleted file mode 100644 index c255ca0f17b0..000000000000 --- a/packages/google-cloud-containeranalysis/synth.metadata +++ /dev/null @@ -1,128 +0,0 @@ -{ - "sources": [ - { - "git": { - "name": ".", - "remote": "https://github.com/googleapis/python-containeranalysis.git", - "sha": "13b00b95024b7692eccdd87ab40a99e549e09461" - } - }, - { - "git": { - "name": "googleapis", - "remote": "https://github.com/googleapis/googleapis.git", - "sha": "56fc6d43fed71188d7e18f3ca003544646c4ab35", - "internalRef": "366346972" - } - } - ], - "destinations": [ - { - "client": { - "source": "googleapis", - "apiName": "containeranalysis", - "apiVersion": "v1", - "language": "python", - "generator": "bazel" - } - } - ], - "generatedFiles": [ - ".coveragerc", - ".flake8", - ".github/CONTRIBUTING.md", - ".github/ISSUE_TEMPLATE/bug_report.md", - ".github/ISSUE_TEMPLATE/feature_request.md", - ".github/ISSUE_TEMPLATE/support_request.md", - ".github/PULL_REQUEST_TEMPLATE.md", - ".github/header-checker-lint.yml", - ".github/release-please.yml", - ".github/snippet-bot.yml", - ".gitignore", - ".kokoro/build.sh", - ".kokoro/continuous/common.cfg", - ".kokoro/continuous/continuous.cfg", - ".kokoro/docker/docs/Dockerfile", - ".kokoro/docker/docs/fetch_gpg_keys.sh", - ".kokoro/docs/common.cfg", - ".kokoro/docs/docs-presubmit.cfg", - ".kokoro/docs/docs.cfg", - ".kokoro/populate-secrets.sh", - ".kokoro/presubmit/common.cfg", - ".kokoro/presubmit/presubmit.cfg", - ".kokoro/publish-docs.sh", - ".kokoro/release.sh", - ".kokoro/release/common.cfg", - ".kokoro/release/release.cfg", - ".kokoro/samples/lint/common.cfg", - ".kokoro/samples/lint/continuous.cfg", - ".kokoro/samples/lint/periodic.cfg", - ".kokoro/samples/lint/presubmit.cfg", - ".kokoro/samples/python3.6/common.cfg", - ".kokoro/samples/python3.6/continuous.cfg", - ".kokoro/samples/python3.6/periodic-head.cfg", - ".kokoro/samples/python3.6/periodic.cfg", - ".kokoro/samples/python3.6/presubmit.cfg", - ".kokoro/samples/python3.7/common.cfg", - ".kokoro/samples/python3.7/continuous.cfg", - ".kokoro/samples/python3.7/periodic-head.cfg", - ".kokoro/samples/python3.7/periodic.cfg", - ".kokoro/samples/python3.7/presubmit.cfg", - ".kokoro/samples/python3.8/common.cfg", - ".kokoro/samples/python3.8/continuous.cfg", - ".kokoro/samples/python3.8/periodic-head.cfg", - ".kokoro/samples/python3.8/periodic.cfg", - ".kokoro/samples/python3.8/presubmit.cfg", - ".kokoro/test-samples-against-head.sh", - ".kokoro/test-samples-impl.sh", - ".kokoro/test-samples.sh", - ".kokoro/trampoline.sh", - ".kokoro/trampoline_v2.sh", - ".pre-commit-config.yaml", - ".trampolinerc", - "CODE_OF_CONDUCT.md", - "CONTRIBUTING.rst", - "LICENSE", - "MANIFEST.in", - "docs/_static/custom.css", - "docs/_templates/layout.html", - "docs/conf.py", - "docs/containeranalysis_v1/container_analysis.rst", - "docs/containeranalysis_v1/services.rst", - "docs/containeranalysis_v1/types.rst", - "docs/multiprocessing.rst", - "google/cloud/devtools/containeranalysis/__init__.py", - "google/cloud/devtools/containeranalysis/py.typed", - "google/cloud/devtools/containeranalysis_v1/__init__.py", - "google/cloud/devtools/containeranalysis_v1/proto/containeranalysis.proto", - "google/cloud/devtools/containeranalysis_v1/py.typed", - "google/cloud/devtools/containeranalysis_v1/services/__init__.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/__init__.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/async_client.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/client.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/transports/__init__.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/transports/base.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/transports/grpc.py", - "google/cloud/devtools/containeranalysis_v1/services/container_analysis/transports/grpc_asyncio.py", - "google/cloud/devtools/containeranalysis_v1/types/__init__.py", - "google/cloud/devtools/containeranalysis_v1/types/containeranalysis.py", - "mypy.ini", - "noxfile.py", - "renovate.json", - "samples/AUTHORING_GUIDE.md", - "samples/CONTRIBUTING.md", - "samples/snippets/noxfile.py", - "scripts/decrypt-secrets.sh", - "scripts/fixup_containeranalysis_v1_keywords.py", - "scripts/readme-gen/readme_gen.py", - "scripts/readme-gen/templates/README.tmpl.rst", - "scripts/readme-gen/templates/auth.tmpl.rst", - "scripts/readme-gen/templates/auth_api_key.tmpl.rst", - "scripts/readme-gen/templates/install_deps.tmpl.rst", - "scripts/readme-gen/templates/install_portaudio.tmpl.rst", - "setup.cfg", - "testing/.gitignore", - "tests/unit/gapic/containeranalysis_v1/__init__.py", - "tests/unit/gapic/containeranalysis_v1/test_container_analysis.py" - ] -} \ No newline at end of file diff --git a/packages/google-cloud-containeranalysis/synth.py b/packages/google-cloud-containeranalysis/synth.py deleted file mode 100644 index 3028b708e8db..000000000000 --- a/packages/google-cloud-containeranalysis/synth.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2018 Google LLC -# -# 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. - -"""This script is used to synthesize generated parts of this library.""" - -import synthtool as s -import synthtool.gcp as gcp -import logging -from synthtool.languages import python - -logging.basicConfig(level=logging.DEBUG) - -gapic = gcp.GAPICBazel() -common = gcp.CommonTemplates() - -# ---------------------------------------------------------------------------- -# Generate Container Analysis GAPIC layer -# ---------------------------------------------------------------------------- -library = gapic.py_library( - service="containeranalysis", - version="v1", - bazel_target="//google/devtools/containeranalysis/v1:devtools-containeranalysis-v1-py", - proto_output_path="google/cloud/devtools/containeranalysis_v1/proto", - include_protos=True, -) - -excludes = [ - "setup.py", - "README.rst", - "docs/index.rst", -] - -s.move(library, excludes=excludes) - - -s.replace( - "google/**/*client.py", - r"""google-cloud-devtools-containeranalysis""", - r"""google-cloud-containeranalysis""", -) - -# Fix imported type from grafeas - -s.replace( - "google/**/types/containeranalysis.py", - "from grafeas\.v1 import vulnerability_pb2 as vulnerability", - "from grafeas.grafeas_v1.types import vulnerability" -) - -# Insert helper method to get grafeas client - -s.replace( - "google/**/client.py", - "class ContainerAnalysisClientMeta\(type\):", - """from grafeas import grafeas_v1 -from grafeas.grafeas_v1.services.grafeas import transports - -class ContainerAnalysisClientMeta(type):""", -) - -s.replace( - "google/**/async_client.py", - "class ContainerAnalysisAsyncClient:", - """from grafeas import grafeas_v1 -from grafeas.grafeas_v1.services.grafeas import transports - -class ContainerAnalysisAsyncClient:""", -) - - -s.replace( - "google/**/client.py", - r"""(\s+)def set_iam_policy\(""", - r'''\n\g<1>def get_grafeas_client( - self - ) -> grafeas_v1.GrafeasClient: - transport = type(self).get_transport_class("grpc")() - grafeas_transport = grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport( - host=transport._host, - scopes=transport.AUTH_SCOPES - ) - return grafeas_v1.GrafeasClient(transport=grafeas_transport) - -\g<1># Service calls -\g<1>def set_iam_policy(''', -) - -s.replace( - "google/**/async_client.py", - r"""(\s+)async def set_iam_policy\(""", - r'''\n\g<1>def get_grafeas_client( - self - ) -> grafeas_v1.GrafeasClient: - transport = type(self).get_transport_class("grpc_asyncio")() - grafeas_transport = grafeas_v1.services.grafeas.transports.GrafeasGrpcTransport( - host=transport._host, - scopes=transport.AUTH_SCOPES - ) - return grafeas_v1.GrafeasClient(transport=grafeas_transport) - -\g<1># Service calls -\g<1>async def set_iam_policy(''', -) - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- -templated_files = common.py_library( - samples=False, # set to True only if there are samples - microgenerator=True, - cov_level=98, -) -s.move(templated_files, excludes=[".coveragerc"]) # microgenerator has a good coveragerc - -python.py_samples(skip_readmes=True) - - -s.shell.run(["nox", "-s", "blacken"], hide_output=False)