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

# Creates a group() that lists Python sources as |data|.
# Having such targets serves two purposes:
# 1) Causes files to be included in runtime_deps, so that they are uploaded to
#    swarming when running tests remotely.
# 2) Causes "gn analyze" to know about all Python inputs so that tests will be
#    re-run when relevant Python files change.
#
# All non-trivial Python scripts should use a "pydeps" file to track their
# sources. To create a .pydep file for a target in //example:
#
#   build/print_python_deps.py \
#       --root example \
#       --output example/$target_name.pydeps \
#       path/to/your/script.py
#
# Keep the .pydep file up-to-date by adding to //PRESUBMIT.py under one of:
#     _ANDROID_SPECIFIC_PYDEPS_FILES, _GENERIC_PYDEPS_FILES
#
# Variables
#   pydeps_file: Path to .pydeps file to read sources from (optional).
#   data: Additional files to include in data. E.g. non-.py files needed by the
#         library, or .py files that are conditionally / lazily imported.
#
# Example
#   python_library("my_library_py") {
#      pydeps_file = "my_library.pydeps"
#      data = [ "foo.dat" ]
#   }
template("python_library") {
  group(target_name) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "deps",
                             "testonly",
                             "visibility",
                           ])

    if (defined(invoker.pydeps_file)) {
      # Read and filter out comments.
      _pydeps_lines = read_file(invoker.pydeps_file, "list lines")
      _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])

      # Dependencies are listed relative to the pydeps file directory, but data
      # parameter expects paths that are relative to the current BUILD.gn
      _script_dir = get_path_info(invoker.pydeps_file, "dir")
      _rebased_pydeps_entries = rebase_path(_pydeps_entries, ".", _script_dir)

      # Even though the .pydep file is not used at runtime, it must be added
      # so that "gn analyze" will mark the target as changed when .py files
      # are removed but none are added or modified.
      data = _rebased_pydeps_entries + [ invoker.pydeps_file ]
    } else {
      data = []
    }
    if (defined(invoker.data)) {
      data += invoker.data
    }
  }
}

# A template used for actions that execute a Python script, which has an
# associated .pydeps file. In other words:
#
# - This is very similar to just an action(), except that |script| must point
#   to a Python script (e.g. "//build/.../foo.py") that has a corresponding
#   .pydeps file in the source tree (e.g. "//build/.../foo.pydeps").
#
# - The .pydeps file contains a list of python dependencies (imports really)
#   and is generated _manually_ by using a command like:
#
#     build/print_python_deps.py --inplace build/android/gyp/foo.py
#
# Example
#   action_with_pydeps("create_foo") {
#     script = "myscript.py"
#     args = [...]
#   }
template("action_with_pydeps") {
  action(target_name) {
    # Ensure that testonly and visibility are forwarded
    # explicitly, since this performs recursive scope lookups, which is
    # required to ensure their definition from scopes above the caller are
    # properly handled. All other variables are forwarded with "*", which
    # doesn't perform recursive lookups at all. See https://crbug.com/862232
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
    forward_variables_from(invoker,
                           "*",
                           [
                             "testonly",
                             "visibility",
                           ])

    # Read and filter out comments.
    # Happens every time the template is instantiated, but benchmarking shows no
    # perceivable impact on overall 'gn gen' speed.
    _pydeps_file = invoker.script + "deps"

    _pydeps_lines =
        read_file(_pydeps_file, "list lines")  # https://crbug.com/1102058
    _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])

    if (!defined(inputs)) {
      inputs = []
    }

    # Dependencies are listed relative to the script directory, but inputs
    # expects paths that are relative to the current BUILD.gn
    _script_dir = get_path_info(_pydeps_file, "dir")
    inputs += rebase_path(_pydeps_entries, ".", _script_dir)
  }
}

template("action_foreach_with_pydeps") {
  action_foreach(target_name) {
    # Ensure that testonly and visibility are forwarded
    # explicitly, since this performs recursive scope lookups, which is
    # required to ensure their definition from scopes above the caller are
    # properly handled. All other variables are forwarded with "*", which
    # doesn't perform recursive lookups at all. See https://crbug.com/862232
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
    forward_variables_from(invoker,
                           "*",
                           [
                             "testonly",
                             "visibility",
                           ])

    # Read and filter out comments.
    # Happens every time the template is instantiated, but benchmarking shows no
    # perceivable impact on overall 'gn gen' speed.
    if (defined(invoker.deps_file)) {
      _pydeps_file = invoker.deps_file
    } else {
      _pydeps_file = invoker.script + "deps"
    }
    _pydeps_lines = read_file(_pydeps_file, "list lines")
    _pydeps_entries = filter_exclude(_pydeps_lines, [ "#*" ])

    if (!defined(inputs)) {
      inputs = []
    }

    # Dependencies are listed relative to the script directory, but inputs
    # expects paths that are relative to the current BUILD.gn
    _script_dir = get_path_info(script, "dir")
    inputs += rebase_path(_pydeps_entries, ".", _script_dir)
  }
}
