def METHOD_NAME(ctx):
    old_default_info = ctx.attr.target[DefaultInfo]
    old_executable = old_default_info.files_to_run.executable
    new_default_info = None
    if old_executable:
        # Bazel requires executable rules to created the executable themselves,
        # so we create a symlink in this rule so that it appears this rule created its executable.
        new_executable = ctx.actions.declare_file(ctx.attr.name)
        ctx.actions.symlink(output = new_executable, target_file = old_executable)
        new_default_info = DefaultInfo(
            files = depset([new_executable]),
            runfiles = old_default_info.default_runfiles,
            executable = new_executable,
        )
    else:
        # There's no way to determine if the underlying `go_binary` target is executable at loading time
        # so we must set the `go_cross` rule to be always executable. If the `go_binary` target is not
        # executable, we set the `go_cross` executable to a simple script that prints an error message
        # when executed. This way users can still run a `go_cross` target using `bazel run` as long as
        # the underlying `go_binary` target is executable.
        error_script = _error_script(ctx)
        # See the implementation of `go_binary` for an explanation of the need for default vs data runfiles here.
        new_default_info = DefaultInfo(
            files = depset([error_script] + old_default_info.files.to_list()),
            default_runfiles = old_default_info.default_runfiles,
            data_runfiles = old_default_info.data_runfiles.merge(ctx.runfiles([error_script])),
            executable = error_script,
        )
    providers = [
        ctx.attr.target[provider]
        for provider in [
            GoLibrary,
            GoSource,
            GoArchive,
            OutputGroupInfo,
            CcInfo,
        ]
        if provider in ctx.attr.target
    ]
    return [new_default_info] + providers