# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Recipe to validate test ownership.
#
# Validates tests defined in `.ci.yaml` have corresponding ownership in `TESTOWNERS`.
# This supports only flutter/flutter repo for now, but can be easily extended to
# other repos in the future.
#
# The pre-submit `sha` and `repo` are needed for validation. Violated builders will
# be returned in stdout when ownership is missing.

DEPS = [
    'flutter/repo_util',
    'recipe_engine/context',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
]


def RunSteps(api):
  """Steps to checkout cocoon, dependencies and execute tests."""
  start_path = api.path['start_dir']
  cocoon_path = start_path.join('cocoon')
  flutter_path = start_path.join('flutter')

  repo = api.properties.get("git_repo")
  with api.step.nest('checkout source code'):
    # Checkout flutter/flutter at head.
    commit_sha = api.repo_util.checkout(
        repo,
        checkout_path=flutter_path,
        url=api.properties.get('git_url'),
        ref=api.properties.get('git_ref')
    )
    # Checkout latest version of flutter/cocoon.
    api.repo_util.checkout('cocoon', cocoon_path, ref='refs/heads/main')

  # The context adds dart-sdk tools to PATH and sets PUB_CACHE.
  env, env_prefixes = api.repo_util.flutter_environment(flutter_path)

  with api.context(env=env, env_prefixes=env_prefixes,
                   cwd=cocoon_path.join('app_dart')):
    api.step('flutter doctor', cmd=['flutter', 'doctor'])
    api.step('dart pub get', cmd=['dart', 'pub', 'get'])
    validate_task_owernship_path = cocoon_path.join(
        'app_dart', 'bin', 'validate_task_ownership.dart'
    )
    api.step(
        'validate test ownership',
        cmd=[
            'dart',
            validate_task_owernship_path,
            repo,
            commit_sha,
        ],
    )


def GenTests(api):
  yield api.test(
      'basic',
      api.repo_util.flutter_environment_data(
          api.path['start_dir'].join('flutter')
      ),
      api.properties(
          git_ref='refs/pull/123/head',
          git_url='https://abc.com/flutter',
          git_repo='flutter',
      )
  )
