123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #!/usr/bin/env python3
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- import re
- import time
- from materialize.buildkite_insights.annotation_search.annotation_search_presentation import (
- print_annotation_match,
- print_before_search_results,
- )
- from materialize.buildkite_insights.data.build_annotation import BuildAnnotation
- from materialize.buildkite_insights.data.build_info import Build
- from materialize.test_analytics.search.test_analytics_search_source import (
- ANY_BRANCH_VALUE,
- ANY_PIPELINE_VALUE,
- TestAnalyticsDataSource,
- )
- def start_search(
- search_source: TestAnalyticsDataSource,
- pipeline_slug: str,
- branch: str | None,
- build_step_keys: list[str],
- only_failed_builds: bool,
- not_newer_than_build_number: int | None,
- like_pattern: str,
- max_results: int,
- short_result_presentation: bool,
- one_line_match_presentation: bool,
- ) -> None:
- assert len(like_pattern) > 0, "pattern must not be empty"
- if branch == ANY_BRANCH_VALUE:
- branch = None
- if not like_pattern.startswith("%"):
- like_pattern = f"%{like_pattern}"
- if not like_pattern.endswith("%"):
- like_pattern = f"{like_pattern}%"
- start_time = time.time()
- matches: list[tuple[Build, BuildAnnotation]] = search_source.search_annotations(
- pipeline=pipeline_slug,
- branch=branch,
- build_step_keys=build_step_keys,
- not_newer_than_build_number=not_newer_than_build_number,
- like_pattern=like_pattern,
- max_entries=max_results + 1,
- only_failed_builds=only_failed_builds,
- )
- end_time = time.time()
- duration_in_sec = round(end_time - start_time, 2)
- more_results_exist = len(matches) > max_results
- if more_results_exist:
- matches = matches[:max_results]
- search_value = _like_pattern_to_regex(like_pattern)
- print("Searching test-analytics database...")
- print_before_search_results()
- if len(matches) == 0:
- print("No matches found.")
- return
- for build, build_annotation in matches:
- print_annotation_match(
- build=build,
- annotation=build_annotation,
- search_value=search_value,
- use_regex=True,
- short_result_presentation=short_result_presentation,
- one_line_match_presentation=one_line_match_presentation,
- )
- _print_summary(pipeline_slug, matches, duration_in_sec, more_results_exist)
- def _print_summary(
- pipeline: str,
- matches: list[tuple[Build, BuildAnnotation]],
- duration_in_sec: float,
- more_results_exist: bool,
- ) -> None:
- newest_build_number_with_match = matches[0][0].number
- oldest_build_number_with_match = matches[-1][0].number
- search_scope = (
- f"builds #{oldest_build_number_with_match} to #{newest_build_number_with_match} of pipeline {pipeline }"
- if pipeline != ANY_PIPELINE_VALUE
- else "all pipelines"
- )
- print(
- f"Found {len(matches)} matches in {search_scope}. Search took {duration_in_sec}s.\n"
- "More matches exist in earlier builds."
- if more_results_exist
- else ""
- )
- def _like_pattern_to_regex(like_pattern: str) -> str:
- like_pattern = like_pattern.strip("%")
- like_pattern = re.escape(like_pattern)
- return like_pattern.replace("%", ".*")
|