feat: Relax single file limit of run_in rule (#71)

This change makes `run_in` rule accept multi-file executable target by
using `ctx.executable.tool`. With this change, it will be possible to
wrap e.g. a `py_console_script_binary` target where there is an
executable file together with a bunch of other files.

As a concrete example:

```starlark
load("@pip_deps//:requirements.bzl", "requirement")
load("@rules_multitool//multitool:cwd.bzl", "cwd")
load("@rules_python//python/entry_points:py_console_script_binary.bzl", "py_console_script_binary")

py_console_script_binary(
    name = "pre-commit",
    pkg = requirement("pre-commit"),
    script = "pre-commit",
)

cwd(
    name = "cwd",
    tool = ":pre-commit",
)
```

Then we can do `bazel run //tools/pre-commit:cwd -- autoupdate`,
otherwise we will need to have workaround like `bazel run
--run_under="cd $PWD && " //tools/pre-commit -- autoupdate`
diff --git a/examples/module/.bazelrc b/examples/module/.bazelrc
index fe93ecc..c7becee 100644
--- a/examples/module/.bazelrc
+++ b/examples/module/.bazelrc
@@ -10,3 +10,7 @@
 
 # off by default on windows, required for this module
 common --enable_runfiles
+
+# Don't rely on test logs being easily accessible from the test runner,
+# though it makes the log noisier.
+test --test_output=errors
diff --git a/examples/module/BUILD.bazel b/examples/module/BUILD.bazel
index e143f37..d738393 100644
--- a/examples/module/BUILD.bazel
+++ b/examples/module/BUILD.bazel
@@ -1,3 +1,6 @@
+load("@rules_multitool//multitool:cwd.bzl", "cwd")
+load("//:add_dummy_file.bzl", "add_dummy_file")
+
 sh_test(
     name = "integration_test",
     srcs = ["integration_test.sh"],
@@ -24,3 +27,22 @@
     ],
     data = ["@multitool//tools/target-determinator:workspace_root"],
 )
+
+add_dummy_file(
+    name = "add_dummy_file",
+    tool = "@multitool//tools/target-determinator",
+)
+
+cwd(
+    name = "add_dummy_file_cwd",
+    tool = ":add_dummy_file",
+)
+
+sh_test(
+    name = "integration_test_add_dummy_file_cwd",
+    srcs = ["integration_test.sh"],
+    args = [
+        "$(location :add_dummy_file_cwd)",
+    ],
+    data = [":add_dummy_file_cwd"],
+)
diff --git a/examples/module/add_dummy_file.bzl b/examples/module/add_dummy_file.bzl
new file mode 100644
index 0000000..7a90bc3
--- /dev/null
+++ b/examples/module/add_dummy_file.bzl
@@ -0,0 +1,27 @@
+"rule adding a dummy file to output, for test purpose"
+
+def _add_dummy_file(ctx):
+    if ctx.executable.tool.extension == "exe":
+        content = "@%s %%*" % ctx.executable.tool.short_path.replace("/", "\\")
+        script = ctx.actions.declare_file(ctx.label.name + ".bat")
+    else:
+        content = '#!/usr/bin/env bash\nexec "%s" "$@"' % ctx.executable.tool.short_path
+        script = ctx.actions.declare_file(ctx.label.name)
+    ctx.actions.write(script, content, is_executable = True)
+
+    dummy_output_file = ctx.actions.declare_file(ctx.label.name + ".dummy")
+    ctx.actions.write(dummy_output_file, "")
+
+    return [DefaultInfo(
+        executable = script,
+        files = depset([script, dummy_output_file]),
+        runfiles = ctx.attr.tool[DefaultInfo].default_runfiles,
+    )]
+
+add_dummy_file = rule(
+    implementation = _add_dummy_file,
+    executable = True,
+    attrs = {
+        "tool": attr.label(mandatory = True, executable = True, cfg = "exec"),
+    },
+)
diff --git a/multitool/private/run_in.bzl b/multitool/private/run_in.bzl
index 619c523..c8bbd73 100644
--- a/multitool/private/run_in.bzl
+++ b/multitool/private/run_in.bzl
@@ -1,7 +1,7 @@
 "run_in provides a shared implementation for cwd and workspace_root execution"
 
 run_in_attrs = {
-    "tool": attr.label(mandatory = True, allow_single_file = True, executable = True, cfg = "exec"),
+    "tool": attr.label(mandatory = True, executable = True, cfg = "exec"),
     "_template_sh": attr.label(default = "//multitool/private:run_in.template.sh", allow_single_file = True),
     "_template_bat": attr.label(default = "//multitool/private:run_in.template.bat", allow_single_file = True),
 }
@@ -22,8 +22,8 @@
     # This algorithm requires --enable_runfiles (enabled by default on non-windows)
     template = ctx.file._template_sh
     wrapper_name = ctx.label.name
-    tool_short_path = ctx.file.tool.short_path
-    if ctx.file.tool.extension == "exe":
+    tool_short_path = ctx.executable.tool.short_path
+    if ctx.executable.tool.extension == "exe":
         template = ctx.file._template_bat
         wrapper_name = wrapper_name + ".bat"
         tool_short_path = tool_short_path.replace("/", "\\")
@@ -36,4 +36,4 @@
             "{{env_var}}": env_var,
         },
     )
-    return [DefaultInfo(executable = output, runfiles = ctx.runfiles(files = [ctx.file.tool]))]
+    return [DefaultInfo(executable = output, runfiles = ctx.attr.tool[DefaultInfo].default_runfiles)]