Packages
caffeine_lang
4.6.3
6.3.1
6.3.0
6.2.2
6.2.1
6.2.0
6.1.2
6.1.1
6.1.0
6.0.0
5.6.0
5.5.0
5.4.4
5.4.3
5.4.2
5.4.1
5.4.0
5.3.0
5.2.0
5.1.1
5.1.0
5.0.12
5.0.11
5.0.10
5.0.8
5.0.7
5.0.6
5.0.5
5.0.4
5.0.1
5.0.0
4.10.0
4.9.0
4.8.3
4.8.2
4.8.1
4.8.0
4.7.9
4.7.8
4.7.7
4.7.6
4.7.5
4.6.7
4.6.6
4.6.5
4.6.4
4.6.3
4.6.2
4.6.0
4.5.1
4.5.0
4.4.4
4.4.3
4.4.1
4.4.0
4.3.7
4.3.6
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
3.0.1
3.0.0
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.0.2
1.0.1
0.1.0
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.2
0.0.1
A compiler for generating reliability artifacts from service expectation definitions.
Current section
Files
Jump to
Current section
Files
src/caffeine_lang@analysis@dependency_validator.erl
-module(caffeine_lang@analysis@dependency_validator).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/caffeine_lang/analysis/dependency_validator.gleam").
-export([build_expectation_index/1, parse_dependency_path/1, validate_dependency_relations/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 66).
?DOC(false).
-spec build_expectation_index(
list(caffeine_lang@linker@ir:intermediate_representation(HEA))
) -> gleam@dict:dict(binary(), caffeine_lang@linker@ir:intermediate_representation(HEA)).
build_expectation_index(Irs) ->
_pipe = Irs,
_pipe@1 = gleam@list:map(
_pipe,
fun(Ir) ->
Path = caffeine_lang@linker@ir:ir_to_identifier(Ir),
{Path, Ir}
end
),
maps:from_list(_pipe@1).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 111).
-spec get_all_dependency_targets(
gleam@dict:dict(caffeine_lang@linker@artifacts:dependency_relation_type(), list(binary()))
) -> list(binary()).
get_all_dependency_targets(Relations) ->
_pipe = Relations,
_pipe@1 = maps:values(_pipe),
lists:append(_pipe@1).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 131).
-spec do_check_for_duplicates(list(binary()), gleam@set:set(binary()), binary()) -> {ok,
nil} |
{error, caffeine_lang@errors:compilation_error()}.
do_check_for_duplicates(Targets, Seen, Self_path) ->
case Targets of
[] ->
{ok, nil};
[Target | Rest] ->
gleam@bool:guard(
gleam@set:contains(Seen, Target),
{error,
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<<<<<<<"Duplicate dependency reference '"/utf8,
Target/binary>>/binary,
"' in '"/utf8>>/binary,
Self_path/binary>>/binary,
"'"/utf8>>
)},
fun() ->
do_check_for_duplicates(
Rest,
gleam@set:insert(Seen, Target),
Self_path
)
end
)
end.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 119).
-spec check_for_duplicates_per_relation(
gleam@dict:dict(caffeine_lang@linker@artifacts:dependency_relation_type(), list(binary())),
binary()
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
check_for_duplicates_per_relation(Relations, Self_path) ->
_pipe = Relations,
_pipe@1 = maps:to_list(_pipe),
gleam@list:try_each(
_pipe@1,
fun(Pair) ->
{_, Targets} = Pair,
do_check_for_duplicates(Targets, gleam@set:new(), Self_path)
end
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 190).
?DOC(false).
-spec parse_dependency_path(binary()) -> {ok,
{binary(), binary(), binary(), binary()}} |
{error, nil}.
parse_dependency_path(Path) ->
case gleam@string:split(Path, <<"."/utf8>>) of
[Org, Team, Service, Name] when (((Org =/= <<""/utf8>>) andalso (Team =/= <<""/utf8>>)) andalso (Service =/= <<""/utf8>>)) andalso (Name =/= <<""/utf8>>) ->
{ok, {Org, Team, Service, Name}};
_ ->
{error, nil}
end.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 202).
?DOC(" Build a dependency reference error with a consistent message format.\n").
-spec dependency_ref_error(binary(), binary(), binary()) -> caffeine_lang@errors:compilation_error().
dependency_ref_error(Target, Self_path, Reason) ->
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<<<<<<<<<"Invalid dependency reference '"/utf8, Target/binary>>/binary,
"' in '"/utf8>>/binary,
Self_path/binary>>/binary,
"': "/utf8>>/binary,
Reason/binary>>
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 154).
-spec validate_dependency_target(
binary(),
binary(),
gleam@dict:dict(binary(), caffeine_lang@linker@ir:intermediate_representation(any()))
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
validate_dependency_target(Target, Self_path, Expectation_index) ->
case parse_dependency_path(Target) of
{error, nil} ->
{error,
dependency_ref_error(
Target,
Self_path,
<<"expected format 'org.team.service.name'"/utf8>>
)};
{ok, _} ->
gleam@bool:guard(
Target =:= Self_path,
{error,
dependency_ref_error(
Target,
Self_path,
<<"self-reference not allowed"/utf8>>
)},
fun() -> case gleam_stdlib:map_get(Expectation_index, Target) of
{ok, _} ->
{ok, nil};
{error, nil} ->
{error,
dependency_ref_error(
Target,
Self_path,
<<"target does not exist"/utf8>>
)}
end end
)
end.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 77).
-spec validate_ir_dependencies(
caffeine_lang@linker@ir:intermediate_representation(HEG),
gleam@dict:dict(binary(), caffeine_lang@linker@ir:intermediate_representation(HEG))
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
validate_ir_dependencies(Ir, Expectation_index) ->
gleam@bool:guard(
not gleam@list:contains(erlang:element(4, Ir), dependency_relations),
{ok, nil},
fun() ->
Self_path = caffeine_lang@linker@ir:ir_to_identifier(Ir),
gleam@result:'try'(
begin
_pipe = caffeine_lang@linker@ir:get_dependency_fields(
erlang:element(6, Ir)
),
gleam@option:to_result(
_pipe,
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<Self_path/binary,
" - missing dependency artifact data"/utf8>>
)
)
end,
fun(Dep) ->
Relations = erlang:element(2, Dep),
gleam@result:'try'(
check_for_duplicates_per_relation(Relations, Self_path),
fun(_) ->
All_targets = get_all_dependency_targets(Relations),
_pipe@1 = All_targets,
gleam@list:try_each(
_pipe@1,
fun(Target) ->
validate_dependency_target(
Target,
Self_path,
Expectation_index
)
end
)
end
)
end
)
end
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 220).
?DOC(" Builds a directed adjacency list from all IRs with DependencyRelations.\n").
-spec build_adjacency_list(
list(caffeine_lang@linker@ir:intermediate_representation(any()))
) -> gleam@dict:dict(binary(), list(binary())).
build_adjacency_list(Irs) ->
_pipe = Irs,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Ir) ->
gleam@list:contains(erlang:element(4, Ir), dependency_relations)
end
),
_pipe@2 = gleam@list:filter_map(
_pipe@1,
fun(Ir@1) ->
case caffeine_lang@linker@ir:get_dependency_fields(
erlang:element(6, Ir@1)
) of
{some, Dep} ->
Path = caffeine_lang@linker@ir:ir_to_identifier(Ir@1),
Targets = get_all_dependency_targets(erlang:element(2, Dep)),
{ok, {Path, Targets}};
none ->
{error, nil}
end
end
),
maps:from_list(_pipe@2).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 403).
?DOC(
" Collects thresholds from hard dependency targets that have SLO artifacts.\n"
" Skips targets that don't exist in the index or don't have SLO artifacts.\n"
" Note: targets with SLO in artifact_refs but missing SLO data are skipped\n"
" because the linker guarantees consistency between artifact_refs and artifact_data.\n"
).
-spec collect_hard_dep_thresholds(
list(binary()),
gleam@dict:dict(binary(), caffeine_lang@linker@ir:intermediate_representation(any()))
) -> list({binary(), float()}).
collect_hard_dep_thresholds(Targets, Expectation_index) ->
_pipe = Targets,
gleam@list:filter_map(
_pipe,
fun(Target_path) ->
case gleam_stdlib:map_get(Expectation_index, Target_path) of
{error, nil} ->
{error, nil};
{ok, Target_ir} ->
gleam@bool:guard(
not gleam@list:contains(
erlang:element(4, Target_ir),
s_l_o
),
{error, nil},
fun() ->
case caffeine_lang@linker@ir:get_slo_fields(
erlang:element(6, Target_ir)
) of
none ->
{error, nil};
{some, Slo} ->
{ok, {Target_path, erlang:element(2, Slo)}}
end
end
)
end
end
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 428).
?DOC(
" Computes the composite availability ceiling from a list of thresholds.\n"
" Each threshold is a percentage (e.g. 99.99). The composite ceiling is\n"
" the product of individual availabilities.\n"
).
-spec compute_composite_ceiling(list(float())) -> float().
compute_composite_ceiling(Thresholds) ->
gleam@list:fold(Thresholds, 1.0, fun(Acc, T) -> Acc * (T / 100.0) end) * 100.0.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 433).
?DOC(" Rounds a float to 4 decimal places for cleaner display.\n").
-spec round_to_4(float()) -> float().
round_to_4(F) ->
erlang:float(erlang:round(F * 10000.0)) / 10000.0.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 344).
?DOC(
" Validates hard dependency thresholds for a single IR using composite ceiling.\n"
" The composite ceiling is the product of all hard dependency thresholds,\n"
" representing the maximum achievable availability given those dependencies.\n"
).
-spec validate_single_ir_hard_thresholds(
caffeine_lang@linker@ir:intermediate_representation(HGX),
gleam@dict:dict(binary(), caffeine_lang@linker@ir:intermediate_representation(HGX))
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
validate_single_ir_hard_thresholds(Ir, Expectation_index) ->
Self_path = caffeine_lang@linker@ir:ir_to_identifier(Ir),
gleam@result:'try'(
case {caffeine_lang@linker@ir:get_slo_fields(erlang:element(6, Ir)),
caffeine_lang@linker@ir:get_dependency_fields(erlang:element(6, Ir))} of
{{some, Slo}, {some, Dep}} ->
{ok, {Slo, Dep}};
{_, _} ->
{error,
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<Self_path/binary,
" - missing SLO or dependency artifact data"/utf8>>
)}
end,
fun(_use0) ->
{Slo@1, Dep@1} = _use0,
Source_threshold = erlang:element(2, Slo@1),
Hard_targets = begin
_pipe = gleam_stdlib:map_get(erlang:element(2, Dep@1), hard),
gleam@result:unwrap(_pipe, [])
end,
Dep_thresholds = collect_hard_dep_thresholds(
Hard_targets,
Expectation_index
),
gleam@bool:guard(
gleam@list:is_empty(Dep_thresholds),
{ok, nil},
fun() ->
Composite_ceiling = compute_composite_ceiling(
gleam@list:map(
Dep_thresholds,
fun(Pair) -> erlang:element(2, Pair) end
)
),
Display_ceiling = round_to_4(Composite_ceiling),
case gleam@float:compare(
Source_threshold,
Composite_ceiling
) of
gt ->
Deps_description = begin
_pipe@1 = Dep_thresholds,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Pair@1) ->
<<<<<<<<"'"/utf8,
(erlang:element(
1,
Pair@1
))/binary>>/binary,
"' ("/utf8>>/binary,
(gleam_stdlib:float_to_string(
erlang:element(2, Pair@1)
))/binary>>/binary,
")"/utf8>>
end
),
gleam@string:join(_pipe@2, <<", "/utf8>>)
end,
{error,
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<<<<<<<<<<<<<"Composite hard dependency threshold violation: '"/utf8,
Self_path/binary>>/binary,
"' (threshold: "/utf8>>/binary,
(gleam_stdlib:float_to_string(
Source_threshold
))/binary>>/binary,
") exceeds the composite availability ceiling of "/utf8>>/binary,
(gleam_stdlib:float_to_string(
Display_ceiling
))/binary>>/binary,
" from its hard dependencies: "/utf8>>/binary,
Deps_description/binary>>
)};
_ ->
{ok, nil}
end
end
)
end
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 301).
-spec explore_neighbors(
list(binary()),
gleam@dict:dict(binary(), list(binary())),
gleam@set:set(binary()),
gleam@set:set(binary()),
list(binary())
) -> {ok, {gleam@set:set(binary()), gleam@set:set(binary())}} |
{error, caffeine_lang@errors:compilation_error()}.
explore_neighbors(Neighbors, Adjacency, Visited, In_progress, Path) ->
case Neighbors of
[] ->
{ok, {Visited, In_progress}};
[Neighbor | Rest] ->
gleam@bool:guard(
gleam@set:contains(In_progress, Neighbor),
{error,
caffeine_lang@errors:semantic_analysis_dependency_validation_error(
<<<<<<"Circular dependency detected: "/utf8,
(gleam@string:join(
lists:reverse(Path),
<<" -> "/utf8>>
))/binary>>/binary,
" -> "/utf8>>/binary,
Neighbor/binary>>
)},
fun() ->
gleam@bool:guard(
gleam@set:contains(Visited, Neighbor),
explore_neighbors(
Rest,
Adjacency,
Visited,
In_progress,
Path
),
fun() ->
gleam@result:'try'(
explore_node(
Neighbor,
Adjacency,
Visited,
In_progress,
[Neighbor | Path]
),
fun(_use0) ->
{Visited@1, In_progress@1} = _use0,
explore_neighbors(
Rest,
Adjacency,
Visited@1,
In_progress@1,
Path
)
end
)
end
)
end
)
end.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 277).
-spec explore_node(
binary(),
gleam@dict:dict(binary(), list(binary())),
gleam@set:set(binary()),
gleam@set:set(binary()),
list(binary())
) -> {ok, {gleam@set:set(binary()), gleam@set:set(binary())}} |
{error, caffeine_lang@errors:compilation_error()}.
explore_node(Node, Adjacency, Visited, In_progress, Path) ->
In_progress@1 = gleam@set:insert(In_progress, Node),
Neighbors = begin
_pipe = gleam_stdlib:map_get(Adjacency, Node),
gleam@result:unwrap(_pipe, [])
end,
gleam@result:'try'(
explore_neighbors(Neighbors, Adjacency, Visited, In_progress@1, Path),
fun(_use0) ->
{Visited@1, In_progress@2} = _use0,
Visited@2 = gleam@set:insert(Visited@1, Node),
In_progress@3 = gleam@set:delete(In_progress@2, Node),
{ok, {Visited@2, In_progress@3}}
end
).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 252).
-spec detect_cycles_loop(
list(binary()),
gleam@dict:dict(binary(), list(binary())),
gleam@set:set(binary()),
gleam@set:set(binary())
) -> {ok, gleam@set:set(binary())} |
{error, caffeine_lang@errors:compilation_error()}.
detect_cycles_loop(Nodes, Adjacency, Visited, In_progress) ->
case Nodes of
[] ->
{ok, Visited};
[Node | Rest] ->
gleam@bool:guard(
gleam@set:contains(Visited, Node),
detect_cycles_loop(Rest, Adjacency, Visited, In_progress),
fun() ->
gleam@result:'try'(
explore_node(
Node,
Adjacency,
Visited,
In_progress,
[Node]
),
fun(_use0) ->
{Visited@1, In_progress@1} = _use0,
detect_cycles_loop(
Rest,
Adjacency,
Visited@1,
In_progress@1
)
end
)
end
)
end.
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 239).
?DOC(" Detects circular dependencies in the dependency graph.\n").
-spec detect_cycles(
list(caffeine_lang@linker@ir:intermediate_representation(any()))
) -> {ok, nil} | {error, caffeine_lang@errors:compilation_error()}.
detect_cycles(Irs) ->
Adjacency = build_adjacency_list(Irs),
Nodes = begin
_pipe = Adjacency,
_pipe@1 = maps:keys(_pipe),
gleam@list:sort(_pipe@1, fun gleam@string:compare/2)
end,
_pipe@2 = detect_cycles_loop(
Nodes,
Adjacency,
gleam@set:new(),
gleam@set:new()
),
gleam@result:map(_pipe@2, fun(_) -> nil end).
-file("src/caffeine_lang/analysis/dependency_validator.gleam", 25).
?DOC(false).
-spec validate_dependency_relations(
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:linked()))
) -> {ok,
list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:deps_validated()))} |
{error, caffeine_lang@errors:compilation_error()}.
validate_dependency_relations(Irs) ->
Expectation_index = build_expectation_index(Irs),
gleam@result:'try'(
begin
_pipe = Irs,
_pipe@1 = gleam@list:map(
_pipe,
fun(Ir) -> validate_ir_dependencies(Ir, Expectation_index) end
),
_pipe@2 = caffeine_lang@errors:from_results(_pipe@1),
gleam@result:map(_pipe@2, fun(_) -> nil end)
end,
fun(_) ->
gleam@result:'try'(
detect_cycles(Irs),
fun(_) ->
gleam@result:'try'(
begin
_pipe@3 = Irs,
_pipe@4 = gleam@list:filter(
_pipe@3,
fun(Ir@1) ->
gleam@list:contains(
erlang:element(4, Ir@1),
dependency_relations
)
andalso gleam@list:contains(
erlang:element(4, Ir@1),
s_l_o
)
end
),
_pipe@5 = gleam@list:map(
_pipe@4,
fun(Ir@2) ->
validate_single_ir_hard_thresholds(
Ir@2,
Expectation_index
)
end
),
_pipe@6 = caffeine_lang@errors:from_results(_pipe@5),
gleam@result:map(_pipe@6, fun(_) -> nil end)
end,
fun(_) ->
{ok,
gleam@list:map(
Irs,
fun caffeine_lang@linker@ir:promote/1
)}
end
)
end
)
end
).