HEX
Server: Apache/2.4.65 (Ubuntu)
System: Linux ielts-store-v2 6.8.0-1036-gcp #38~22.04.1-Ubuntu SMP Thu Aug 14 01:19:18 UTC 2025 x86_64
User: root (0)
PHP: 7.2.34-54+ubuntu20.04.1+deb.sury.org+1
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
Upload Files
File: //snap/google-cloud-cli/current/lib/googlecloudsdk/api_lib/cloudbuild/transforms.py
# -*- coding: utf-8 -*- #
# Copyright 2016 Google LLC. All Rights Reserved.
#
# 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.


"""CloudBuild resource transforms and symbols dict.

A resource transform function converts a JSON-serializable resource to a string
value. This module contains built-in transform functions that may be used in
resource projection and filter expressions.

NOTICE: Each TransformFoo() method is the implementation of a foo() transform
function. Even though the implementation here is in Python the usage in resource
projection and filter expressions is language agnostic. This affects the
Pythonicness of the Transform*() methods:
  (1) The docstrings are used to generate external user documentation.
  (2) The method prototypes are included in the documentation. In particular the
      prototype formal parameter names are stylized for the documentation.
  (3) The 'r', 'kwargs', and 'projection' args are not included in the external
      documentation. Docstring descriptions, other than the Args: line for the
      arg itself, should not mention these args. Assume the reader knows the
      specific item the transform is being applied to. When in doubt refer to
      the output of $ gcloud topic projections.
  (4) The types of some args, like r, are not fixed until runtime. Other args
      may have either a base type value or string representation of that type.
      It is up to the transform implementation to silently do the string=>type
      conversions. That's why you may see e.g. int(arg) in some of the methods.
  (5) Unless it is documented to do so, a transform function must not raise any
      exceptions related to the resource r. The `undefined' arg is used to
      handle all unusual conditions, including ones that would raise exceptions.
      Exceptions for arguments explicitly under the caller's control are OK.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from apitools.base.py import encoding as apitools_encoding
from googlecloudsdk.api_lib.container.fleet import client as hub_client
from googlecloudsdk.api_lib.util import apis as core_apis
from googlecloudsdk.core import properties
from googlecloudsdk.core import resources
from googlecloudsdk.core.resource import resource_transform


def TransformBuildImages(r, undefined=''):
  """Returns the formatted build results images.

  Args:
    r: JSON-serializable object.
    undefined: Returns this value if the resource cannot be formatted.
  Returns:
    The formatted build results images.
  """
  messages = core_apis.GetMessagesModule('cloudbuild', 'v1')
  b = apitools_encoding.DictToMessage(r, messages.Build)
  if b.results is None:
    return undefined
  images = b.results.images
  if not images:
    return undefined
  names = []
  for i in images:
    if i.name is None:
      names.append(undefined)
    else:
      names.append(i.name)
  if len(names) > 1:
    return names[0] + ' (+{0} more)'.format(len(names)-1)
  return names[0]


def TransformBuildSource(r, undefined=''):
  """Returns the formatted build source.

  Args:
    r: JSON-serializable object.
    undefined: Returns this value if the resource cannot be formatted.
  Returns:
    The formatted build source.
  """
  messages = core_apis.GetMessagesModule('cloudbuild', 'v1')
  b = apitools_encoding.DictToMessage(r, messages.Build)
  if b.source is None:
    return undefined

  storage_source = b.source.storageSource
  if storage_source is not None:
    bucket = storage_source.bucket
    obj = storage_source.object
    if bucket is None or obj is None:
      return undefined
    return 'gs://{0}/{1}'.format(bucket, obj)

  repo_source = b.source.repoSource
  if repo_source is not None:
    repo_name = repo_source.repoName or 'default'
    branch_name = repo_source.branchName
    if branch_name is not None:
      return '{0}@{1}'.format(repo_name, branch_name)
    tag_name = repo_source.tagName
    if tag_name is not None:
      return '{0}@{1}'.format(repo_name, tag_name)
    commit_sha = repo_source.commitSha
    if commit_sha is not None:
      return '{0}@{1}'.format(repo_name, commit_sha)

  git_source = b.source.gitSource
  if git_source is not None:
    url = git_source.url
    revision = git_source.revision
    if url is not None:
      return '{0}@{1}'.format(url, revision)

  storage_source_manifest = b.source.storageSourceManifest
  if storage_source_manifest is not None:
    bucket = storage_source_manifest.bucket
    obj = storage_source_manifest.object
    if bucket is None or obj is None:
      return undefined
    return 'gs://{0}/{1}'.format(bucket, obj)

  connected_repository = b.source.connectedRepository
  if connected_repository is not None:
    repository = connected_repository.repository
    revision = connected_repository.revision
    if repository is not None:
      return '{0}@{1}'.format(repository, revision)

  developer_connect_config = b.source.developerConnectConfig
  if developer_connect_config is not None:
    git_repository_link = developer_connect_config.gitRepositoryLink
    revision = developer_connect_config.revision
    if git_repository_link is not None:
      return '{0}@{1}'.format(git_repository_link, revision)

  return undefined


def TransformResultDuration(resource, undefined=''):
  """Returns the formatted result duration.

  Args:
    resource: JSON-serializable object.
    undefined: Returns this value if the resource cannot be formatted.

  Returns:
    The formatted result duration.
  """
  messages = core_apis.GetMessagesModule('cloudbuild', 'v2')
  result = apitools_encoding.DictToMessage(resource, messages.Result)
  record_data = hub_client.HubClient.ToPyDict(
      result.recordSummaries[0].recordData)
  if 'completion_time' in record_data:
    return resource_transform.TransformDuration(record_data, 'start_time',
                                                'completion_time', 3, 0, False,
                                                1, '-')
  if 'finish_time' in record_data:
    return resource_transform.TransformDuration(record_data, 'start_time',
                                                'finish_time', 3, 0, False, 1,
                                                '-')
  return undefined


def TransformResultStatus(resource, undefined=''):
  """Returns the formatted result status.

  Args:
    resource: JSON-serializable object.
    undefined: Returns this value if the resource cannot be formatted.

  Returns:
    The formatted result status.
  """
  messages = core_apis.GetMessagesModule('cloudbuild', 'v2')
  result = apitools_encoding.DictToMessage(resource, messages.Result)
  record_summary = result.recordSummaries[0]
  record_data = hub_client.HubClient.ToPyDict(record_summary.recordData)
  if record_summary.status is not None:
    return record_summary.status
  if 'pipeline_run_status' in record_data or 'task_run_status' in record_data:
    return 'CANCELLED'
  # Get the status from conditions if record_summary.status is not set.
  succeeded_status = ''
  dequeued_status = ''
  # There are two types of conditions, 'Succeeded' and 'Dequeued'.
  for index in (0, 1):
    condition_type = record_data.get(f'conditions[{index}].type')
    if condition_type == 'Succeeded':
      succeeded_status = record_data.get(f'conditions[{index}].status')
    elif condition_type == 'Dequeued':
      dequeued_status = record_data.get(f'conditions[{index}].status')
  if succeeded_status == 'TRUE':
    return 'SUCCESS'
  if succeeded_status == 'FALSE':
    return 'FAILURE'
  if dequeued_status == 'TRUE':
    return 'IN_PROGRESS'
  if dequeued_status == 'FALSE':
    return 'QUEUED'
  return undefined


def _GetUri(resource, undefined=None):
  # pylint: disable=missing-docstring
  messages = core_apis.GetMessagesModule('cloudbuild', 'v1')
  if isinstance(resource, messages.Build):
    build_ref = resources.REGISTRY.Parse(
        None,
        params={
            'projectId': resource.projectId,
            'id': resource.id,
        },
        collection='cloudbuild.projects.builds')
    return build_ref.SelfLink() or undefined
  elif isinstance(resource, messages.BuildTrigger):
    project = properties.VALUES.core.project.Get(required=True)
    trigger_ref = resources.REGISTRY.Parse(
        None,
        params={
            'projectId': project,
            'triggerId': resource.id,
        },
        collection='cloudbuild.projects.triggers')
    return trigger_ref.SelfLink() or undefined
  else:
    return undefined

_TRANSFORMS = {
    'build_images': TransformBuildImages,
    'build_source': TransformBuildSource,
    'result_duration': TransformResultDuration,
    'result_status': TransformResultStatus,
    'uri': _GetUri,
}


def GetTransforms():
  """Returns the cloudbuild specific resource transform symbol table."""
  return _TRANSFORMS