Skip to content

Commit 61104f1

Browse files
committed
docs: add a bunch of docs to dynamic outputs
There's a bunch of boilerplate due to #1046. Documents the problem mentioned in #1041, but a more ideal fix would involve the tool itself handling the mixup for you. Fixes: #1038
1 parent febf909 commit 61104f1

File tree

7 files changed

+95
-2
lines changed

7 files changed

+95
-2
lines changed

app/buck2_action_impl/src/context/dynamic_output.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,35 @@ pub(crate) fn analysis_actions_methods_dynamic_output(methods: &mut MethodsBuild
202202
/// New version of `dynamic_output`.
203203
///
204204
/// This is work in progress, and will eventually replace the old `dynamic_output`.
205+
/// In contrast to the old `dynamic_output`, `dynamic_output_new()` allows calling dynamic
206+
/// actions similarly to normal rules as function calls.
207+
///
208+
/// This function allows defining deferred analysis actions that are executed in the action
209+
/// graph on demand rather than at normal analysis time. Using `dynamic_output_new`, one can
210+
/// write rules which can read the contents of artifacts built by other rules while determining
211+
/// which actions to register.
212+
///
213+
/// It takes as input a `DynamicActions` obtained from calling a dynamic action defined with
214+
/// [`dynamic_actions()`](../#dynamic_actions) or
215+
/// [`bxl.dynamic_actions()`](../../bxl/#dynamic_actions).
216+
///
217+
/// This function is typically used in two distinct ways:
218+
/// - Binding an artifact: passing in an unbound artifact to a
219+
/// [`dynattrs.output()`](../dynattrs#output) attr of a dynamic action. That dynamic action is
220+
/// then analyzed at build time when the artifact is required by another rule, then the
221+
/// actions bound to the artifact are executed. In this case, the return value of
222+
/// `dynamic_output_new()` is not used.
223+
/// - Using the returned opaque [`DynamicValue`](../DynamicValue) as input to other dynamic
224+
/// actions' [`dynattrs.dynamic_value()`](../dynattrs/#dynamic_value) attrs.
225+
///
226+
/// The invoked dynamic actions will be analyzed at build time when a dependency requires them
227+
/// through an artifact bound by [`dynattrs.output()`](../dynattrs#output) or if they are
228+
/// required by other dynamic actions that use the returned `DynamicValue`.
229+
///
230+
/// See [Dynamic Dependencies](../../../rule_authors/dynamic_dependencies) for an overall
231+
/// overview of dynamic dependencies in buck2.
232+
///
233+
/// For a guide on using this with BXL, see [How to run actions based on the content of artifacts](../../../bxl/how_tos/how_to_run_actions_based_on_the_content_of_artifact).
205234
fn dynamic_output_new<'v>(
206235
this: &'v AnalysisActions<'v>,
207236
#[starlark(require = pos)] dynamic_actions: ValueTyped<'v, StarlarkDynamicActions<'v>>,

app/buck2_action_impl/src/dynamic/attrs_starlark.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,41 @@ impl<'v> AllocValue<'v> for StarlarkDynamicAttrType {
4949
}
5050
}
5151

52+
/// Attributes declared for [`dynamic_actions()`](../#dynamic_actions) functions.
5253
#[starlark_module]
5354
fn struct_dynattrs(globals: &mut GlobalsBuilder) {
55+
/// Unbound output to be bound by this dynamic action.
56+
/// Accepts an [`OutputArtifact`](../OutputArtifact/).
57+
///
58+
/// The impl function receives an [`OutputArtifact`](../OutputArtifact/) value.
5459
fn output() -> starlark::Result<StarlarkDynamicAttrType> {
5560
Ok(StarlarkDynamicAttrType {
5661
ty: DynamicAttrType::Output,
5762
})
5863
}
5964

65+
/// Artifact to use the contents of in this dynamic action.
66+
/// Accepts an [`OutputArtifact`](../OutputArtifact/).
67+
///
68+
/// The impl function receives an [`ArtifactValue`](../ArtifactValue).
6069
fn artifact_value() -> starlark::Result<StarlarkDynamicAttrType> {
6170
Ok(StarlarkDynamicAttrType {
6271
ty: DynamicAttrType::ArtifactValue,
6372
})
6473
}
6574

75+
/// Dynamic value generated by another dynamic action, which is resolved before calling the
76+
/// dynamic action.
77+
/// Accepts a [`DynamicValue`](../DynamicValue/).
78+
///
79+
/// The impl function receives a [`ResolvedDynamicValue`](../ResolvedDynamicValue/).
6680
fn dynamic_value() -> starlark::Result<StarlarkDynamicAttrType> {
6781
Ok(StarlarkDynamicAttrType {
6882
ty: DynamicAttrType::DynamicValue,
6983
})
7084
}
7185

86+
/// Plain value of a given type.
7287
fn value<'v>(
7388
#[starlark(require = pos)] ty: ValueOf<'v, TypeType>,
7489
eval: &mut Evaluator<'v, '_, '_>,
@@ -82,6 +97,7 @@ fn struct_dynattrs(globals: &mut GlobalsBuilder) {
8297
})
8398
}
8499

100+
/// Takes a list of values and gives a list to the impl function.
85101
fn list<'v>(
86102
#[starlark(require = pos)] ty: &'v StarlarkDynamicAttrType,
87103
) -> starlark::Result<StarlarkDynamicAttrType> {
@@ -91,6 +107,7 @@ fn struct_dynattrs(globals: &mut GlobalsBuilder) {
91107
})
92108
}
93109

110+
/// Takes a dict of values and gives it to the impl function.
94111
fn dict<'v>(
95112
#[starlark(require = pos)] key: ValueOf<'v, TypeType>,
96113
#[starlark(require = pos)] value: &'v StarlarkDynamicAttrType,
@@ -105,6 +122,7 @@ fn struct_dynattrs(globals: &mut GlobalsBuilder) {
105122
})
106123
}
107124

125+
/// Takes a tuple and gives it to the impl function.
108126
fn tuple<'v>(
109127
#[starlark(args)] args: UnpackTuple<&'v StarlarkDynamicAttrType>,
110128
) -> starlark::Result<StarlarkDynamicAttrType> {
@@ -114,6 +132,7 @@ fn struct_dynattrs(globals: &mut GlobalsBuilder) {
114132
})
115133
}
116134

135+
/// Takes either a value or `None` and gives it to the impl function.
117136
fn option<'v>(
118137
#[starlark(require = pos)] ty: &'v StarlarkDynamicAttrType,
119138
) -> starlark::Result<StarlarkDynamicAttrType> {

app/buck2_action_impl/src/dynamic/dynamic_actions.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ use std::cell::RefCell;
1313
use allocative::Allocative;
1414
use buck2_artifact::artifact::artifact_type::OutputArtifact;
1515
use starlark::any::ProvidesStaticType;
16+
use starlark::environment::Methods;
17+
use starlark::environment::MethodsBuilder;
18+
use starlark::environment::MethodsStatic;
19+
use starlark::starlark_module;
1620
use starlark::values::AllocValue;
1721
use starlark::values::FrozenValueTyped;
1822
use starlark::values::Heap;
@@ -45,7 +49,13 @@ pub(crate) struct StarlarkDynamicActions<'v> {
4549
}
4650

4751
#[starlark_value(type = "DynamicAction")]
48-
impl<'v> StarlarkValue<'v> for StarlarkDynamicActions<'v> {}
52+
impl<'v> StarlarkValue<'v> for StarlarkDynamicActions<'v> {
53+
// Used to add type documentation to the generated documentation
54+
fn get_methods() -> Option<&'static Methods> {
55+
static RES: MethodsStatic = MethodsStatic::new();
56+
RES.methods(dynamic_actions_methods)
57+
}
58+
}
4959

5060
impl<'v> AllocValue<'v> for StarlarkDynamicActions<'v> {
5161
fn alloc_value(self, heap: &'v Heap) -> Value<'v> {
@@ -54,3 +64,11 @@ impl<'v> AllocValue<'v> for StarlarkDynamicActions<'v> {
5464
heap.alloc_complex_no_freeze(self)
5565
}
5666
}
67+
68+
/// Opaque thunk type returned from calling the returned value of a `dynamic_actions` or
69+
/// `bxl.dynamic_actions` invocation. Conceptually, a tuple of (function, args).
70+
///
71+
/// Must be passed to
72+
/// [`AnalysisActions.dynamic_output_new`](../AnalysisActions#analysisactionsdynamic_output_new).
73+
#[starlark_module]
74+
fn dynamic_actions_methods(builder: &mut MethodsBuilder) {}

app/buck2_action_impl/src/dynamic/dynamic_actions_callable.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ use buck2_build_api::interpreter::rule_defs::provider::ty::abstract_provider::Ab
1919
use buck2_error::BuckErrorContext;
2020
use dupe::Dupe;
2121
use starlark::any::ProvidesStaticType;
22+
use starlark::environment::Methods;
23+
use starlark::environment::MethodsBuilder;
24+
use starlark::environment::MethodsStatic;
2225
use starlark::eval::Arguments;
2326
use starlark::eval::Evaluator;
2427
use starlark::eval::ParametersSpec;
2528
use starlark::eval::ParametersSpecParam;
29+
use starlark::starlark_module;
2630
use starlark::typing::ParamIsRequired;
2731
use starlark::typing::ParamSpec;
2832
use starlark::typing::Ty;
@@ -92,7 +96,6 @@ enum DynamicActionCallableError {
9296
NotExported,
9397
}
9498

95-
/// Result of `dynamic_actions` rule invocation.
9699
#[derive(
97100
Debug,
98101
NoSerialize,
@@ -164,6 +167,12 @@ impl<'v> StarlarkValue<'v> for DynamicActionsCallable<'v> {
164167
impl<'v> StarlarkValue<'v> for FrozenStarlarkDynamicActionsCallable {
165168
type Canonical = Self;
166169

170+
// Used to add type documentation to the generated documentation
171+
fn get_methods() -> Option<&'static Methods> {
172+
static RES: MethodsStatic = MethodsStatic::new();
173+
RES.methods(dynamic_actions_callable_methods)
174+
}
175+
167176
fn invoke(
168177
&self,
169178
me: Value<'v>,
@@ -236,3 +245,10 @@ impl<'v> Freeze for DynamicActionsCallable<'v> {
236245
})
237246
}
238247
}
248+
249+
/// Result of `dynamic_actions` or `bxl.dynamic_actions` invocation.
250+
///
251+
/// When called, becomes a [`DynamicActions`](../DynamicActions) value which can then be passed to
252+
/// [`AnalysisActions.dynamic_output_new`](../AnalysisActions#analysisactionsdynamic_output_new)
253+
#[starlark_module]
254+
fn dynamic_actions_callable_methods(builder: &mut MethodsBuilder) {}

app/buck2_action_impl/src/dynamic/dynamic_actions_globals.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ pub fn new_dynamic_actions_callable<'v>(
9595
pub(crate) fn register_dynamic_actions(globals: &mut GlobalsBuilder) {
9696
/// Create new dynamic action callable. Returned object will be callable,
9797
/// and the result of calling it can be passed to `ctx.actions.dynamic_output_new`.
98+
///
99+
/// Be aware that the context argument of the called impl function differs between
100+
/// [`dynamic_actions`](../#dynamic_actions) where it is [`actions: AnalysisActions`](../AnalysisActions)
101+
/// and [`bxl.dynamic_actions`](../../bxl/#dynamic_actions)
102+
/// where it is [`bxl_ctx: bxl.Context`](../../bxl/Context).
98103
fn dynamic_actions<'v>(
99104
#[starlark(require = named)] r#impl: StarlarkCallableChecked<
100105
'v,

app/buck2_build_api/src/interpreter/rule_defs/artifact/starlark_output_artifact.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ impl<'v> CommandLineArgLike<'v> for FrozenStarlarkOutputArtifact {
197197
}
198198
}
199199

200+
/// The result of calling [`Artifact.as_output()`](../Artifact/#artifactas_output).
200201
#[starlark_module]
201202
pub(crate) fn register_output_artifact(globals: &mut GlobalsBuilder) {
202203
const OutputArtifact: StarlarkValueAsType<StarlarkOutputArtifact> = StarlarkValueAsType::new();

app/buck2_bxl/src/bxl/starlark_defs/context/dynamic.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ static P_BXLCTX: DynamicActionsCallbackParam = DynamicActionsCallbackParam {
281281
pub(crate) fn register_dynamic_actions(globals: &mut GlobalsBuilder) {
282282
/// Create new bxl dynamic action callable. Returned object will be callable,
283283
/// and the result of calling it can be passed to `ctx.actions.dynamic_output_new`.
284+
///
285+
/// Be aware that the context argument of the called impl function differs between
286+
/// [`dynamic_actions`](../#dynamic_actions) where it is [`actions: AnalysisActions`](../AnalysisActions)
287+
/// and [`bxl.dynamic_actions`](../../bxl/#dynamic_actions)
288+
/// where it is [`bxl_ctx: bxl.Context`](../../bxl/Context).
284289
fn dynamic_actions<'v>(
285290
#[starlark(require = named)] r#impl: StarlarkCallableChecked<
286291
'v,

0 commit comments

Comments
 (0)