-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathrake_tasks.rb
More file actions
195 lines (182 loc) · 9.13 KB
/
rake_tasks.rb
File metadata and controls
195 lines (182 loc) · 9.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# Copyright 2024 - 2026 Block, Inc.
#
# Use of this source code is governed by an MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT.
#
# frozen_string_literal: true
require "rake/tasklib"
require "elastic_graph/schema_artifacts/runtime_metadata/schema_element_names"
module ElasticGraph
module SchemaDefinition
# Defines rake tasks for managing artifacts generated from a schema definition.
#
# @note {ElasticGraph::Local::RakeTasks} wraps this and provides additional functionality. Most users will not need to interact with
# this class directly.
class RakeTasks < ::Rake::TaskLib
# @private
attr_reader :output
# @param index_document_sizes [Boolean] When enabled, ElasticGraph will configure the index mappings so that the datastore indexes a
# `_size` field in each document. ElasticGraph itself does not do anything with this field, but it will be available for your use
# in any direct queries (e.g. via Kibana). Important note: this requires the [mapper-size
# plugin](https://www.elastic.co/guide/en/elasticsearch/plugins/8.15/mapper-size.html) to be installed on your datastore cluster.
# You are responsible for ensuring that is installed if you enable this feature. If you enable this and the plugin is not
# installed, you will get errors!
# @param path_to_schema [String, Pathname] path to the main (or only) schema definition file
# @param schema_artifacts_directory [String, Pathname] Directory to dump the schema artifacts in
# @param schema_element_name_form [:camelCase, :snake_case] the form of names for schema elements (fields, arguments, directives)
# generated by ElasticGraph.
# @param schema_element_name_overrides [Hash<Symbol, String>] overrides for specific names of schema elements (fields, arguments,
# directives) generated by ElasticGraph. For example, to rename the `gt` filter field to `greaterThan`, pass `{gt: "greaterThan"}`.
# @param derived_type_name_formats [Hash<Symbol, String>] overrides for the naming formats used by ElasticGraph for derived GraphQL
# type names. For example, to use `Metrics` instead of `AggregatedValues` as the suffix for the generated types supporting
# getting aggregated metrid values, pass `{AggregatedValues: "%{base}Metrics"}`. See {SchemaElements::TypeNamer::DEFAULT_FORMATS}
# for the available formats.
# @param type_name_overrides [Hash<Symbol, String>] overrides for the names of specific GraphQL types. For example, to rename the
# `DateTime` scalar to `Timestamp`, pass `{DateTime: "Timestamp}`.
# @param enum_value_overrides_by_type [Hash<Symbol, Hash<Symbol, String>>] overrides for the names of specific enum values for
# specific enum types. For example, to rename the `DayOfWeek.MONDAY` enum to `DayOfWeek.MON`, pass `{DayOfWeek: {MONDAY: "MON"}}`.
# @param extension_modules [Array<Module>] List of Ruby modules to extend onto the `SchemaDefinition::API` instance. Designed to
# support ElasticGraph extension gems (such as `elasticgraph-apollo`).
# @param enforce_json_schema_version [Boolean] Whether or not to enforce the requirement that the JSON schema version is incremented
# every time dumping the JSON schemas results in a changed artifact. Generally speaking, you will want this to be `true` for any
# ElasticGraph application that is in production as the versioning of JSON schemas is what supports safe schema evolution as it
# allows ElasticGraph to identify which version of the JSON schema the publishing system was operating on when it published an
# event. It can be useful to set it to `false` before your application is in production, as you do not want to be forced to bump
# the version after every single schema change while you are building an initial prototype.
# @param output [IO] used for printing task output
#
# @example Minimal setup with defaults
# ElasticGraph::SchemaDefinition::RakeTasks.new(
# index_document_sizes: false,
# path_to_schema: "config/schema.rb",
# schema_artifacts_directory: "config/schema/artifacts",
# schema_element_name_form: :camelCase
# )
#
# @example Spell out the full names of the `gt`/`gte`/`lt`/`lte` filter operators
# ElasticGraph::SchemaDefinition::RakeTasks.new(
# index_document_sizes: false,
# path_to_schema: "config/schema.rb",
# schema_artifacts_directory: "config/schema/artifacts",
# schema_element_name_form: :camelCase,
# schema_element_name_overrides: {
# gt: "greaterThan",
# gte: "greaterThanOrEqualTo",
# lt: "lessThan",
# lte: "lessThanOrEqualTo"
# }
# )
#
# @example Change the `AggregatedValues` type suffix to `Metrics`
# ElasticGraph::SchemaDefinition::RakeTasks.new(
# index_document_sizes: false,
# path_to_schema: "config/schema.rb",
# schema_artifacts_directory: "config/schema/artifacts",
# schema_element_name_form: :camelCase,
# derived_type_name_formats: {AggregatedValues: "Metrics"}
# )
#
# @example Rename `JsonSafeLong` to `BigInt`
# ElasticGraph::SchemaDefinition::RakeTasks.new(
# index_document_sizes: false,
# path_to_schema: "config/schema.rb",
# schema_artifacts_directory: "config/schema/artifacts",
# schema_element_name_form: :camelCase,
# type_name_overrides: {JsonSafeLong: "BigInt"}
# )
#
# @example Shorten the names of the `DayOfWeek` enum values
# ElasticGraph::SchemaDefinition::RakeTasks.new(
# index_document_sizes: false,
# path_to_schema: "config/schema.rb",
# schema_artifacts_directory: "config/schema/artifacts",
# schema_element_name_form: :camelCase,
# enum_value_overrides_by_type: {
# DayOfWeek: {
# MONDAY: "MON",
# TUESDAY: "TUE",
# WEDNESDAY: "WED",
# THURSDAY: "THU",
# FRIDAY: "FRI",
# SATURDAY: "SAT",
# SUNDAY: "SUN"
# }
# }
# )
def initialize(
index_document_sizes:,
path_to_schema:,
schema_artifacts_directory:,
schema_element_name_form:,
schema_element_name_overrides: {},
derived_type_name_formats: {},
type_name_overrides: {},
enum_value_overrides_by_type: {},
enums_in_transition: [],
extension_modules: [],
enforce_json_schema_version: true,
output: $stdout
)
@schema_element_names = SchemaArtifacts::RuntimeMetadata::SchemaElementNames.new(
form: schema_element_name_form,
overrides: schema_element_name_overrides
)
@derived_type_name_formats = derived_type_name_formats
@type_name_overrides = type_name_overrides
@enum_value_overrides_by_type = enum_value_overrides_by_type
@enums_in_transition = enums_in_transition
@index_document_sizes = index_document_sizes
@path_to_schema = path_to_schema
@schema_artifacts_directory = schema_artifacts_directory
@enforce_json_schema_version = enforce_json_schema_version
@extension_modules = extension_modules
@output = output
define_tasks
end
private
def define_tasks
namespace :schema_artifacts do
desc "Dumps all schema artifacts based on the current ElasticGraph schema definition"
task :dump do
schema_artifact_manager.dump_artifacts
end
desc "Checks the artifacts to make sure they are up-to-date, raising an exception if not"
task :check do
schema_artifact_manager.check_artifacts
end
end
end
def schema_artifact_manager
require "elastic_graph/schema_definition/api"
# :nocov: -- tests don't cover the `VERBOSE` side
max_diff_lines = ENV["VERBOSE"] ? 999999999 : 50
# :nocov:
schema_def_api.factory.new_schema_artifact_manager(
schema_definition_results: schema_def_api.results,
schema_artifacts_directory: @schema_artifacts_directory.to_s,
enforce_json_schema_version: @enforce_json_schema_version,
output: @output,
max_diff_lines: max_diff_lines
)
end
def schema_def_api
@schema_def_api ||= begin
require "elastic_graph/schema_definition/api"
API.new(
@schema_element_names,
@index_document_sizes,
extension_modules: @extension_modules,
derived_type_name_formats: @derived_type_name_formats,
type_name_overrides: @type_name_overrides,
enum_value_overrides_by_type: @enum_value_overrides_by_type,
enums_in_transition: @enums_in_transition,
output: @output
).tap do |api|
api.as_active_instance { load @path_to_schema.to_s }
end
end
end
end
end
end