[hooks] Add documentation on running the debugger (#2706)
Closes: https://github.com/dart-lang/native/issues/2702
diff --git a/pkgs/hooks/CHANGELOG.md b/pkgs/hooks/CHANGELOG.md
index 064d4c4..8b2fc4c 100644
--- a/pkgs/hooks/CHANGELOG.md
+++ b/pkgs/hooks/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.20.4
+
+- Improved documentation on debugging and added a documentation index.
+
## 0.20.3
- Polished README.md, Dartdocs, and examples.
diff --git a/pkgs/hooks/README.md b/pkgs/hooks/README.md
index f1b4e25..a311ae3 100644
--- a/pkgs/hooks/README.md
+++ b/pkgs/hooks/README.md
@@ -52,6 +52,11 @@
For more information see [dart.dev/tools/hooks](https://dart.dev/tools/hooks).
+## Documentation
+
+For detailed documentation on debugging and the configuration schema, see the
+[documentation](./doc/README.md).
+
## Status: In Preview
**NOTE**: This package is currently in preview and published under the
diff --git a/pkgs/hooks/doc/README.md b/pkgs/hooks/doc/README.md
new file mode 100644
index 0000000..0853dd3
--- /dev/null
+++ b/pkgs/hooks/doc/README.md
@@ -0,0 +1,9 @@
+# `package:hooks` Documentation
+
+This directory contains detailed documentation for the `package:hooks` API.
+
+## Available Documentation
+
+* **[Debugging](./debugging.md)**: Learn how to debug your build hooks by inspecting intermediate files and running hooks with a debugger.
+
+* **[Schema](./schema/README.md)**: Explore the JSON schema for the configuration files used by build hooks.
diff --git a/pkgs/hooks/doc/debugging.md b/pkgs/hooks/doc/debugging.md
new file mode 100644
index 0000000..e21090e
--- /dev/null
+++ b/pkgs/hooks/doc/debugging.md
@@ -0,0 +1,89 @@
+# Debugging Dart Hooks
+
+When a build[^1] hook isn't working as expected, you can investigate the
+intermediate files generated by the Dart and Flutter SDK build process. These
+files provide insight into the inputs, outputs, and any errors that occurred
+during the hook's execution.
+
+## Key Debugging Directory
+
+All debugging artifacts are stored within the `.dart_tool` directory of your
+project. The hook runner generates a unique folder for each hook execution,
+containing temporary and output files.
+
+You can find the most important debugging files in a subdirectory specific to
+your hook's execution. The path is of the form
+`.dart_tool/hooks_runner/<package_name>/<some_hash>/`, where `<package_name>`
+is the name of the package containing the hook. For example, for a hook in a
+package named `sqlite`, it would be
+`.dart_tool/hooks_runner/sqlite/221e109fbc/`.
+
+When you run a build, hooks for all dependencies are executed, so you might see
+multiple package directories.
+
+The `<some_hash>` is a checksum of the hook's configuration. If you are unsure
+which hash directory to inspect within your package's hook directory, you can
+delete the `.dart_tool/hooks_runner/<package_name>/` directory and re-run the
+command that failed. The newly created directory will be for the latest
+invocation.
+
+Inside this directory, you will find:
+
+* `input.json`: Contains the exact configuration and data passed *into* your
+ build hook. Reviewing this helps confirm if the hook is receiving the expected
+ build configuration.
+* `output.json`: This file stores the JSON data that your build hook *produced*
+ as its result.
+* `stdout.txt`: Captures any standard output from your build hook. This is where
+ messages from a logger or `print` statements will appear.
+* `stderr.txt`: Captures any error messages or exceptions thrown during the
+ hook's execution.
+
+## Using a Debugger
+
+To step through your code with a debugger, run the build hook from its source
+file and provide the `input.json` via the `--config` flag. This allows you to
+set breakpoints in your IDE and inspect the hook's execution.
+
+For example:
+
+```sh
+dart run hook/build.dart --config .dart_tool/hooks_runner/your_package_name/some_hash/input.json
+```
+
+Make sure to replace `hook/build.dart`, `your_package_name`, and
+`some_hash` with the actual paths from your project.
+
+## VS Code Launch Configuration
+
+To debug in VS Code, you can create a `launch.json` file in a `.vscode`
+directory in your project root. This allows you to run your hook with a
+debugger attached.
+
+Here is an example configuration:
+
+```json
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Debug Hook",
+ "type": "dart",
+ "request": "launch",
+ "program": "path/to/your/hook/build.dart",
+ "args": [
+ "--config",
+ ".dart_tool/hooks_runner/your_package_name/some_hash/input.json"
+ ]
+ }
+ ]
+}
+```
+
+Again, make sure to replace `path/to/your/hook/build.dart`,
+`your_package_name`, and `some_hash` with the actual paths from your project.
+After setting this up, you can run the "Debug Hook" configuration from the
+"Run and Debug" view in VS Code.
+
+[^1]: This debugging strategy also works for other hooks than build hooks, but
+ this documentation focuses specifically on build hooks.
diff --git a/pkgs/hooks/lib/src/api/build_and_link.dart b/pkgs/hooks/lib/src/api/build_and_link.dart
index 3f83e51..0c6a04e 100644
--- a/pkgs/hooks/lib/src/api/build_and_link.dart
+++ b/pkgs/hooks/lib/src/api/build_and_link.dart
@@ -82,6 +82,66 @@
/// guaranteed to be invoked with a process invocation and should return a
/// non-zero exit code on failure. Throwing will lead to an uncaught exception,
/// causing a non-zero exit code.
+///
+/// ## Debugging
+///
+/// When a build hook doesn't work as expected, you can investigate the
+/// intermediate files generated by the Dart and Flutter SDK build process.
+///
+/// The most important files for debugging are located in a subdirectory
+/// specific to your hook's execution. The path is of the form
+/// `.dart_tool/hooks_runner/<package_name>/<some_hash>/`, where
+/// `<package_name>` is the name of the package containing the hook. Inside, you
+/// will find:
+///
+/// * `input.json`: The configuration and data passed into your build hook.
+/// * `output.json`: The JSON data that your build hook produced.
+/// * `stdout.txt`: Any standard output from your build hook.
+/// * `stderr.txt`: Any error messages or exceptions.
+///
+/// When you run a build, hooks for all dependencies are executed, so you might
+/// see multiple package directories.
+///
+/// The `<some_hash>` is a checksum of the [BuildConfig] in the `input.json`. If
+/// you are unsure which hash directory to inspect within your package's hook
+/// directory, you can delete the `.dart_tool/hooks_runner/<package_name>/`
+/// directory and re-run the command that failed. The newly created directory
+/// will be for the latest invocation.
+///
+/// You can step through your code with a debugger by running the build hook
+/// from its source file and providing the `input.json` via the `--config` flag:
+///
+/// ```sh
+/// dart run hook/build.dart --config .dart_tool/hooks_runner/<package_name>/<some_hash>/input.json
+/// ```
+///
+/// To debug in VS Code, you can create a `launch.json` file in a `.vscode`
+/// directory in your project root. This allows you to run your hook with a
+/// debugger attached.
+///
+/// Here is an example configuration:
+///
+/// ```json
+/// {
+/// "version": "0.2.0",
+/// "configurations": [
+/// {
+/// "name": "Debug Build Hook",
+/// "type": "dart",
+/// "request": "launch",
+/// "program": "hook/build.dart",
+/// "args": [
+/// "--config",
+/// ".dart_tool/hooks_runner/your_package_name/some_hash/input.json"
+/// ]
+/// }
+/// ]
+/// }
+/// ```
+///
+/// Again, make sure to replace `your_package_name`, and `some_hash` with the
+/// actual paths from your project. After setting this up, you can run the
+/// "Debug Build Hook" configuration from the "Run and Debug" view in VS Code.
Future<void> build(
List<String> arguments,
Future<void> Function(BuildInput input, BuildOutputBuilder output) builder,
@@ -122,8 +182,8 @@
/// Links assets in a `hook/link.dart`.
///
-/// If a link hook is defined (`hook/link.dart`) then `link` must be called
-/// by that hook, to write the [BuildInput.outputFile], even if the [linker]
+/// If a link hook is defined (`hook/link.dart`) then `link` must be called by
+/// that hook, to write the [BuildInput.outputFile], even if the [linker]
/// function has no work to do.
///
/// Can link native assets which are not already available, or expose existing
@@ -152,6 +212,66 @@
/// guaranteed to be invoked with a process invocation and should return a
/// non-zero exit code on failure. Throwing will lead to an uncaught exception,
/// causing a non-zero exit code.
+///
+/// ## Debugging
+///
+/// When a link hook doesn't work as expected, you can investigate the
+/// intermediate files generated by the Dart and Flutter SDK build process.
+///
+/// The most important files for debugging are located in a subdirectory
+/// specific to your hook's execution. The path is of the form
+/// `.dart_tool/hooks_runner/<package_name>/<some_hash>/`, where
+/// `<package_name>` is the name of the package containing the hook. Inside, you
+/// will find:
+///
+/// * `input.json`: The configuration and data passed into your link hook.
+/// * `output.json`: The JSON data that your link hook produced.
+/// * `stdout.txt`: Any standard output from your link hook.
+/// * `stderr.txt`: Any error messages or exceptions.
+///
+/// When you run a build, hooks for all dependencies are executed, so you might
+/// see multiple package directories.
+///
+/// The `<some_hash>` is a checksum of the [LinkConfig] in the `input.json`. If
+/// you are unsure which hash directory to inspect within your package's hook
+/// directory, you can delete the `.dart_tool/hooks_runner/<package_name>/`
+/// directory and re-run the command that failed. The newly created directory
+/// will be for the latest invocation.
+///
+/// You can step through your code with a debugger by running the link hook from
+/// its source file and providing the `input.json` via the `--config` flag:
+///
+/// ```sh
+/// dart run hook/link.dart --config .dart_tool/hooks_runner/<package_name>/<some_hash>/input.json
+/// ```
+///
+/// To debug in VS Code, you can create a `launch.json` file in a `.vscode`
+/// directory in your project root. This allows you to run your hook with a
+/// debugger attached.
+///
+/// Here is an example configuration:
+///
+/// ```json
+/// {
+/// "version": "0.2.0",
+/// "configurations": [
+/// {
+/// "name": "Debug Link Hook",
+/// "type": "dart",
+/// "request": "launch",
+/// "program": "hook/link.dart",
+/// "args": [
+/// "--config",
+/// ".dart_tool/hooks_runner/your_package_name/some_hash/input.json"
+/// ]
+/// }
+/// ]
+/// }
+/// ```
+///
+/// Again, make sure to replace `your_package_name`, and `some_hash` with the
+/// actual paths from your project. After setting this up, you can run the
+/// "Debug Link Hook" configuration from the "Run and Debug" view in VS Code.
Future<void> link(
List<String> arguments,
Future<void> Function(LinkInput input, LinkOutputBuilder output) linker,
diff --git a/pkgs/hooks/pubspec.yaml b/pkgs/hooks/pubspec.yaml
index 958f298..35f8cc8 100644
--- a/pkgs/hooks/pubspec.yaml
+++ b/pkgs/hooks/pubspec.yaml
@@ -3,7 +3,7 @@
A library that contains a Dart API for the JSON-based protocol for
`hook/build.dart` and `hook/link.dart`.
-version: 0.20.3
+version: 0.20.4
repository: https://github.com/dart-lang/native/tree/main/pkgs/hooks