Skip to content

Commit

Permalink
Add Jinja whitespace control
Browse files Browse the repository at this point in the history
  • Loading branch information
joaopgrassi committed Jun 27, 2024
1 parent 77d0d9b commit 1ef0d07
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 9 deletions.
14 changes: 8 additions & 6 deletions crates/weaver_forge/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ templates/
html/ <-- Templates to generate the semantic conventions in HTML
...
markdown/ <-- Templates to generate the semantic conventions in markdown
...
...
rust/ <-- Templates to generate the semantic conventions in Rust
...
...
go/ <-- Templates to generate the semantic conventions in Go
...
schema/
Expand Down Expand Up @@ -78,6 +78,7 @@ documentation for more details.
## Global Variables

All templates have access to the following global variables:

- `ctx`: The context object that contains the resolved registry or the output of
the JQ filter if defined in the `weaver.yaml` configuration file.
- `params`: The parameters defined in the `weaver.yaml` configuration file or overridden
Expand Down Expand Up @@ -130,12 +131,13 @@ Jinja templates can also access the parameters:
## Jinja Filters

All the filters available in the MiniJinja template engine are available (see
this online [documentation](https://docs.rs/minijinja/latest/minijinja/filters/index.html)).
this online [documentation](https://docs.rs/minijinja/latest/minijinja/filters/index.html)).

In addition, OTel Weaver provides a set of custom filters to facilitate the
generation of documentation and code.

The following filters are available:

- `lower_case`: Converts a string to lowercase.
- `upper_case`: Converts a string to UPPERCASE.
- `title_case`: Converts a string to TitleCase.
Expand All @@ -146,7 +148,7 @@ The following filters are available:
- `kebab_case`: Converts a string to kebab-case.
- `screaming_kebab_case`: Converts a string to SCREAMING-KEBAB-CASE.
- `capitalize_first`: Capitalizes the first letter of a string.
- `kebab_case_const`: Generates kebab-case constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful).
- `kebab_case_const`: Generates kebab-case constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful).
- `pascal_case_const`: Generates PascalCase constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful).
- `camel_case_const`: Generates camelCase constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful).
- `snake_case_const`: Generates snake_case constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful).
Expand All @@ -165,7 +167,7 @@ e.g. \[\[a,b\],\[c\]\] => \[a,b,c\]
- `attribute_namespace`: Converts {namespace}.{attribute_id} to {namespace}.
- `required`: Filters a list of `Attribute`s to include only the required attributes. The "conditionally_required" attributes are not returned by this filter.
- `not_required`: Filters a list of `Attribute`s to only include non-required attributes. The "conditionally_required" attributes are returned by this filter.
- `instantiated_type`: Filters a type to return the instantiated type.
- `instantiated_type`: Filters a type to return the instantiated type.
- `enum_type`: Filters a type to return the enum type or an error if the type is not an enum.
- `markdown_to_html`: Converts a markdown string to an HTML string.
- `map_text`: Converts an input into a string based on the `text_maps` section of the `weaver.yaml` configuration file
Expand Down Expand Up @@ -212,7 +214,7 @@ value if the name of the text map or the input are not found in the `text_maps`
## Jinja Functions

All the functions available in the MiniJinja template engine are available (see
All the functions available in the MiniJinja template engine are available (see
this online [documentation](https://docs.rs/minijinja/latest/minijinja/functions/index.html)).

Right now, OTel Weaver does not provide any custom functions but feel free to
Expand Down
21 changes: 21 additions & 0 deletions crates/weaver_forge/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,15 @@ pub struct TemplateSyntax {
/// The end of a comment.
#[serde(default = "default_comment_end")]
pub comment_end: String,
/// Configures the behavior of the first newline after a block.
/// See https://docs.rs/minijinja/latest/minijinja/struct.Environment.html#method.set_trim_blocks
#[serde(default = "default_trim_blocks")]
pub trim_blocks: bool,
/// Configures the behavior of the first newline after a block.
/// Configures the behavior of leading spaces and tabs from the start of a line to a block.
/// See https://docs.rs/minijinja/latest/minijinja/struct.Environment.html#method.set_lstrip_blocks
#[serde(default = "default_lstrip_blocks")]
pub lstrip_blocks: bool,
}

/// Default block start delimiter.
Expand Down Expand Up @@ -285,6 +294,16 @@ fn default_comment_end() -> String {
"#}".to_owned()
}

/// Default trim_blocks behavior.
fn default_trim_blocks() -> bool {
false
}

/// Default lstrip_blocks behavior.
fn default_lstrip_blocks() -> bool {
false
}

impl Default for TemplateSyntax {
fn default() -> Self {
TemplateSyntax {
Expand All @@ -294,6 +313,8 @@ impl Default for TemplateSyntax {
variable_end: default_variable_end(),
comment_start: default_comment_start(),
comment_end: default_comment_end(),
trim_blocks: default_trim_blocks(),
lstrip_blocks: default_lstrip_blocks()
}
}
}
Expand Down
45 changes: 45 additions & 0 deletions crates/weaver_forge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,11 @@ impl TemplateEngine {
});
env.set_syntax(syntax);

// Jinja whitespace control
// https://docs.rs/minijinja/latest/minijinja/syntax/index.html#whitespace-control
env.set_trim_blocks(template_syntax.trim_blocks);
env.set_lstrip_blocks(template_syntax.lstrip_blocks);

code::add_filters(&mut env, &self.target_config);
ansi::add_filters(&mut env);
case::add_filters(&mut env, &self.target_config);
Expand Down Expand Up @@ -682,4 +687,44 @@ mod tests {

assert!(diff_dir("expected_output", "observed_output").unwrap());
}

#[test]
fn test_whitespace_control() {
let logger = TestLogger::default();
let loader = FileSystemFileLoader::try_new("templates/test".into(), "whitespace_control")
.expect("Failed to create file system loader");
let engine = super::TemplateEngine::try_new(loader, Params::default())
.expect("Failed to create template engine");

let registry_id = "default";
let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml")
.expect("Failed to load registry");
let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry)
.expect("Failed to resolve registry");

let template_registry = ResolvedRegistry::try_from_resolved_registry(
schema.registry(registry_id).expect("registry not found"),
schema.catalog(),
)
.unwrap_or_else(|e| {
panic!(
"Failed to create the context for the template evaluation: {:?}",
e
)
});

engine
.generate(
logger.clone(),
&template_registry,
Path::new("templates/test/whitespace_control/observed_output"),
&OutputDirective::File,
)
.inspect_err(|e| {
print_dedup_errors(logger.clone(), e.clone());
})
.expect("Failed to generate registry assets");

assert!(diff_dir("templates/test/whitespace_control/expected_output", "templates/test/whitespace_control/observed_output").unwrap());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Semantic Convention Registry

Url:

## Attribute Groups

- [attributes.jvm.memory](attribute_group/attributes_jvm_memory.md)
- [registry.db](attribute_group/registry_db.md)
- [registry.http](attribute_group/registry_http.md)
- [registry.network](attribute_group/registry_network.md)
- [server](attribute_group/server.md)
- [registry.url](attribute_group/registry_url.md)
- [registry.user_agent](attribute_group/registry_user_agent.md)

## Events

- [ios.lifecycle.events](event/ios_lifecycle_events.md)
- [android.lifecycle.events](event/android_lifecycle_events.md)

## Metrics

- [metric.jvm.memory.used](metric/metric_jvm_memory_used.md)
- [metric.jvm.memory.committed](metric/metric_jvm_memory_committed.md)
- [metric.jvm.memory.limit](metric/metric_jvm_memory_limit.md)
- [metric.jvm.memory.used_after_last_gc](metric/metric_jvm_memory_used_after_last_gc.md)
- [metric.jvm.gc.duration](metric/metric_jvm_gc_duration.md)
- [metric.jvm.thread.count](metric/metric_jvm_thread_count.md)
- [metric.jvm.class.loaded](metric/metric_jvm_class_loaded.md)
- [metric.jvm.class.unloaded](metric/metric_jvm_class_unloaded.md)
- [metric.jvm.class.count](metric/metric_jvm_class_count.md)
- [metric.jvm.cpu.count](metric/metric_jvm_cpu_count.md)
- [metric.jvm.cpu.time](metric/metric_jvm_cpu_time.md)
- [metric.jvm.cpu.recent_utilization](metric/metric_jvm_cpu_recent_utilization.md)

## Metric Groups

## Resource

- [otel.scope](resource/otel_scope.md)
- [otel.library](resource/otel_library.md)

## Scope

## Span

- [db](span/db.md)
- [db.mssql](span/db_mssql.md)
- [db.cassandra](span/db_cassandra.md)
- [db.hbase](span/db_hbase.md)
- [db.couchdb](span/db_couchdb.md)
- [db.redis](span/db_redis.md)
- [db.mongodb](span/db_mongodb.md)
- [db.elasticsearch](span/db_elasticsearch.md)
- [db.sql](span/db_sql.md)
- [db.cosmosdb](span/db_cosmosdb.md)
- [db.tech](span/db_tech.md)
57 changes: 57 additions & 0 deletions crates/weaver_forge/templates/test/whitespace_control/registry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Semantic Convention Registry

Url:{{ registry_url }}

## Attribute Groups

{% for group in ctx.groups %}
{% if group.type == "attribute_group" %}
- [{{ group.id }}](attribute_group/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Events

{% for group in ctx.groups %}
{% if group.type == "event" %}
- [{{ group.id }}](event/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Metrics

{% for group in ctx.groups %}
{% if group.type == "metric" %}
- [{{ group.id }}](metric/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Metric Groups
{% for group in ctx.groups %}
{% if group.type == "metric_group" %}
- [{{ group.id }}](metric_group/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Resource

{% for group in ctx.groups %}
{% if group.type == "resource" %}
- [{{ group.id }}](resource/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Scope
{% for group in ctx.groups %}
{% if group.type == "scope" %}
- [{{ group.id }}](scope/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}

## Span

{% for group in ctx.groups %}
{% if group.type == "span" %}
- [{{ group.id }}](span/{{ group.id | file_name }}.md)
{% endif %}
{% endfor %}
21 changes: 21 additions & 0 deletions crates/weaver_forge/templates/test/whitespace_control/weaver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
file_name: snake_case
function_name: PascalCase
arg_name: camelCase
struct_name: PascalCase
field_name: PascalCase

type_mapping:
int: int64
double: double
boolean: bool
string: string
"int[]": "[]int64"
"double[]": "[]double"
"boolean[]": "[]bool"
"string[]": "[]string"

acronyms: ["iOS", "API", "URL"]

template_syntax:
trim_blocks: true
lstrip_blocks: true
9 changes: 6 additions & 3 deletions docs/weaver-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ following options:
# double: doubleKey
# boolean: booleanKey
# string: stringKey

# Deprecated, please use text_maps instead
# Configuration of the type mapping. This is useful to generate code in a
# specific language. This is optional.
Expand All @@ -33,7 +33,8 @@ following options:
# "string[]": "[]string"
# ...

# Uncomment this section to specify the configuration of the Jinja template syntax.
# Uncomment this section to specify the configuration of the Jinja template syntax
# and control whitespace behavior.
# Note: The default syntax is strongly recommended.
#template_syntax:
# block_start: "{%"
Expand All @@ -42,6 +43,8 @@ following options:
# variable_end: "}}"
# comment_start: "{#"
# comment_end: "#}"
# trim_blocks: false
# lstrip_blocks: false

# Uncomment the following section to specify a list of acronyms that
# will be interpreted by the acronym filter. This is optional.
Expand All @@ -52,7 +55,7 @@ following options:
# params:
# param1: val1
# param2: val2

# Uncomment the following templates to override the default template
# mapping. Each template mapping specifies a jaq filter (compatible with jq)
# to apply to every file matching the pattern. The application_mode specifies
Expand Down

0 comments on commit 1ef0d07

Please sign in to comment.