elasticgraph 0.19.0.0 → 0.19.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8eca32e62a4248d2e0af28f5fc55387b041730fab33f333393681f2ce4c8b7d4
4
- data.tar.gz: 885c292bd452fd17ccd495478097c3e3fbbe60214f56f4c75a9371e40cf0392a
3
+ metadata.gz: 2bc0f43e12d65d88384972b991179c77c5ec7856c86c85f151138e0af2d99f2f
4
+ data.tar.gz: f12ed7e628eba142a6299f5878a97d8d80de3068fbff13606fe6ffbc7e181acd
5
5
  SHA512:
6
- metadata.gz: 753d971644015e750ff3a23f639059a14b70794c8cff317609d405861c5e602230be5e0ed911baf9860a627c304aaaba77a80f4acb552f9a38fe9acc58887439
7
- data.tar.gz: 712cd194f44ecb3cc412811214a761150936ea166611a2bc901f862108cc830d7db531e4fd9ab683e8039b5c845a07b933610a8d98f22d4dc8eb50692b718418
6
+ metadata.gz: 276bb3d1e4e9aa8180c01031468d60115ec05567bfbc02d39fbd65e8777dec65f874a19f6e46a5bbeb20aca56d0855c66ba0dd1a989462804ba01cddf6ba81e5
7
+ data.tar.gz: c191d95111cf81157ef2777bea143d12a0f71aa095b9df0da9bccf27ede6b3f53f250e01bc1bf0d20ab911840dbe33534c9c5fb7557cc521f08496eb8bc2a49f
data/README.md CHANGED
@@ -2,3 +2,11 @@
2
2
 
3
3
  ElasticGraph meta-gem that pulls in all the core ElasticGraph gems. Intended for use when all
4
4
  parts of ElasticGraph are used from the same deployed app.
5
+
6
+ ## Getting Started
7
+
8
+ Run this command to bootstrap a new local project:
9
+
10
+ ```bash
11
+ elasticgraph new my_app
12
+ ```
data/exe/elasticgraph ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2024 Block, Inc.
3
+ #
4
+ # Use of this source code is governed by an MIT-style
5
+ # license that can be found in the LICENSE file or at
6
+ # https://opensource.org/licenses/MIT.
7
+ #
8
+ # frozen_string_literal: true
9
+
10
+ require "elastic_graph/cli"
11
+ ElasticGraph::CLI.start(ARGV)
@@ -0,0 +1,106 @@
1
+ # Copyright 2024 Block, Inc.
2
+ #
3
+ # Use of this source code is governed by an MIT-style
4
+ # license that can be found in the LICENSE file or at
5
+ # https://opensource.org/licenses/MIT.
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ require "bundler"
10
+ require "elastic_graph/version"
11
+ require "thor"
12
+
13
+ module ElasticGraph
14
+ class CLI < ::Thor
15
+ include ::Thor::Actions
16
+
17
+ # Tell Thor where our template files live
18
+ def self.source_root
19
+ ::File.expand_path("project_template", __dir__)
20
+ end
21
+
22
+ def self.exit_on_failure?
23
+ true
24
+ end
25
+
26
+ VALID_DATASTORES = %w[elasticsearch opensearch]
27
+
28
+ option :datastore, desc: "elasticsearch or opensearch", type: :string, default: "opensearch"
29
+ desc "new APP_NAME", "Generate a new ElasticGraph project in APP_NAME."
30
+ def new(app_path)
31
+ new_app_path = ::File.join(::Dir.pwd, app_path)
32
+ app_name = ::File.basename(new_app_path)
33
+
34
+ unless app_name.match?(/\A[a-z_]+\z/)
35
+ raise ::Thor::Error, "App name must be in `snake_case` form but was not: `#{app_name}`."
36
+ end
37
+
38
+ unless VALID_DATASTORES.include?(options[:datastore])
39
+ raise ::Thor::Error, "Invalid datastore option: #{options[:datastore]}. Must be #{VALID_DATASTORES.join(" or ")}."
40
+ end
41
+
42
+ setup_env = SetupEnv.new(
43
+ app_name: app_name,
44
+ app_module: app_name.split("_").map(&:capitalize).join,
45
+ datastore: options.fetch(:datastore),
46
+ gemfile_elasticgraph_details_code_snippet: %(["#{VERSION}"])
47
+ )
48
+
49
+ say "Creating a new #{setup_env.datastore_name} ElasticGraph project called '#{app_name}' at: #{new_app_path}", :green
50
+
51
+ ElasticGraph.with_setup_env(setup_env) do
52
+ # Recursively copy all files from project_template into the new_app_path
53
+ directory ".", new_app_path, exclude_pattern: %r{/lib/app_name/}
54
+ directory "lib/app_name", ::File.join(new_app_path, "lib", app_name)
55
+ end
56
+
57
+ inside new_app_path do
58
+ ::Bundler.with_unbundled_env do
59
+ run "bundle install"
60
+ run "bundle exec rake schema_artifacts:dump query_registry:dump_variables:all build"
61
+ end
62
+
63
+ run "git init"
64
+ run "git add ."
65
+ run "git commit -m 'Bootstrapped ElasticGraph with `elasticgraph new`.'"
66
+ end
67
+
68
+ say "Successfully bootstrapped '#{app_name}' as a new #{setup_env.datastore_name} ElasticGraph project.", :green
69
+
70
+ say <<~INSTRUCTIONS, :yellow
71
+ Next steps:
72
+ 1. cd #{app_path}
73
+ 2. Run `bundle exec rake boot_locally` to try it out in your browser.
74
+ 3. Run `bundle exec rake -T` to view other available tasks.
75
+ 4. Customize your new project as needed. (Search for `TODO` to find things that need updating.)
76
+ INSTRUCTIONS
77
+ end
78
+ end
79
+
80
+ class SetupEnv < ::Data.define(:app_name, :app_module, :datastore, :gemfile_elasticgraph_details_code_snippet)
81
+ DATASTORE_NAMES = {"elasticsearch" => "Elasticsearch", "opensearch" => "OpenSearch"}
82
+ DATASTORE_UI_NAMES = {"elasticsearch" => "Kibana", "opensearch" => "OpenSearch Dashboards"}
83
+
84
+ def datastore_name
85
+ DATASTORE_NAMES.fetch(datastore)
86
+ end
87
+
88
+ def datastore_ui_name
89
+ DATASTORE_UI_NAMES.fetch(datastore)
90
+ end
91
+
92
+ def ruby_major_minor
93
+ "3.4"
94
+ end
95
+ end
96
+
97
+ singleton_class.attr_reader :setup_env
98
+
99
+ def self.with_setup_env(setup_env)
100
+ original_setup_env = self.setup_env
101
+ @setup_env = setup_env
102
+ yield
103
+ ensure
104
+ @setup_env = original_setup_env
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ bin/*
2
+ bundle/*
3
+ .bundle/*
4
+ tmp/*
5
+ log/*
@@ -0,0 +1,8 @@
1
+ ruby_version: <%= ElasticGraph.setup_env.ruby_major_minor %>
2
+ format: progress
3
+ ignore:
4
+ - bin/**/*
5
+ - bundle/**/*
6
+ - .bundle/**/*
7
+ - log/**/*
8
+ - tmp/**/*
@@ -0,0 +1,17 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Gem details for the elasticgraph gems.
4
+ elasticgraph_details = <%= ElasticGraph.setup_env.gemfile_elasticgraph_details_code_snippet %>
5
+
6
+ gem "elasticgraph-local", *elasticgraph_details
7
+ gem "elasticgraph-<%= ElasticGraph.setup_env.datastore %>", *elasticgraph_details
8
+ gem "elasticgraph-query_registry", *elasticgraph_details
9
+
10
+ gem "httpx", "~> 1.3"
11
+
12
+ group :development do
13
+ gem "factory_bot"
14
+ gem "faker"
15
+ gem "rspec"
16
+ gem "standard"
17
+ end
@@ -0,0 +1,176 @@
1
+ # <%= ElasticGraph.setup_env.app_module %> ElasticGraph Project
2
+
3
+ This repository contains the files for creating and maintaining the <%= ElasticGraph.setup_env.app_module %> ElasticGraph Project.
4
+
5
+ ## Development Environment
6
+
7
+ Here's what you need:
8
+
9
+ | Requirement | Version | Installation Instructions |
10
+ |----------------|---------|---------------------------------------------------------------------------|
11
+ | Ruby | <%= ElasticGraph.setup_env.ruby_major_minor %>.x | [ruby-lang.org](https://www.ruby-lang.org/en/documentation/installation/) |
12
+ | Docker Engine | 27.x | [docker.com](https://docs.docker.com/engine/install/) |
13
+ | Docker Compose | 2.29.x | [docker.com](https://docs.docker.com/compose/install/) |
14
+
15
+ ### Ruby
16
+
17
+ This project is written in Ruby, a dynamic, open source programming language with a focus on simplicity and productivity.
18
+
19
+ You may verify your `ruby` installation via the terminal:
20
+
21
+ ```bash
22
+ $ ruby -v
23
+ ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [arm64-darwin24]
24
+ ```
25
+
26
+ If you do not have Ruby, we recommend installing it using one of the following:
27
+
28
+ * [RVM](https://rvm.io/)
29
+ * [asdf](https://asdf-vm.com/)
30
+ * [rbenv](https://rbenv.org/)
31
+ * [ruby-install](https://github.com/postmodern/ruby-install)
32
+
33
+ ### Ruby Dependencies
34
+
35
+ Ruby dependencies are managed using [bundler](https://bundler.io/), which comes installed with Ruby.
36
+ To install Ruby dependencies, run:
37
+
38
+ ```bash
39
+ $ bundle install
40
+ ```
41
+
42
+ Once that is done, prefix Ruby commands with `bundle exec` in order to run them in the context of the project bundle.
43
+
44
+ ### Docker and Docker Compose
45
+
46
+ This project uses Docker Engine and Docker Compose to run <%= ElasticGraph.setup_env.datastore_name %> locally. We recommend installing
47
+ [Docker Desktop](https://docs.docker.com/desktop/) to get both Docker dependencies.
48
+
49
+ ## Local Development
50
+
51
+ Some useful commands to try:
52
+
53
+ ```bash
54
+ # The build rake task can be used after making changes to rebuild everything
55
+ bundle exec rake build
56
+
57
+ # See all tasks available for managing your project and schemas
58
+ bundle exec rake -T
59
+
60
+ # Boot a local instance prepopulated with fake data, useful for experimenting
61
+ bundle exec rake boot_locally
62
+
63
+ # The GraphiQL UI should open automatically
64
+ open http://localhost:9393/
65
+
66
+ # You can also visit <%= ElasticGraph.setup_env.datastore_ui_name %> via:
67
+ open http://localhost:19293/
68
+ ```
69
+
70
+ ### Run Build Tasks
71
+
72
+ Run a complete suite of build tasks with the build `rake` task:
73
+
74
+ ```bash
75
+ bundle exec rake build
76
+ ```
77
+
78
+ This will:
79
+ 1. (Re)generate your schema artifacts
80
+ 2. Validate all registered queries against the latest schema
81
+ 3. Lint everything (use `bundle exec standardrb --fix` to fix most issues)
82
+ 4. Run tests (including the common shared ElasticGraph tests)
83
+
84
+ Note: on CI, you'll want to use `bundle exec rake check` instead of `bundle exec rake build`,
85
+ so that it verifies that schema artifacts are up-to-date (rather than dumping them).
86
+
87
+ ### Upgrading ElasticGraph
88
+
89
+ Upgrades to the ElasticGraph gems will come with [release notes](https://github.com/block/elasticgraph/releases/tag/v0.19.0.0) that include upgrade instructions, if necessary.
90
+
91
+ Here's the bare minimum upgrade process:
92
+
93
+ 1. Modify `elasticgraph_details` in the root `Gemfile` and run `bundle install`.
94
+ 2. Run `bundle exec rake`.
95
+ 3. Commit the results.
96
+
97
+ ### Managing <%= ElasticGraph.setup_env.datastore_name %>
98
+
99
+ The `<%= ElasticGraph.setup_env.datastore %>:` tasks will boot the desired <%= ElasticGraph.setup_env.datastore_name %> version using docker. You can
100
+ use either the `:boot` or `:daemon` tasks:
101
+
102
+ * The `:boot` task will keep <%= ElasticGraph.setup_env.datastore_name %> in the foreground, allowing you to see the logs.
103
+ * The `:daemon` task runs <%= ElasticGraph.setup_env.datastore_name %> as a background daemon task. Notably, it waits to return
104
+ until <%= ElasticGraph.setup_env.datastore_name %> is ready to receive traffic.
105
+
106
+ If you use a `:daemon` task, you can later use the corresponding `:halt` task to stop the daemon.
107
+
108
+ ### Using the GraphiQL interactive GraphQL query editor
109
+
110
+ When running `bundle exec rake boot_locally` the GraphiQL editor should open automatically
111
+ (`open http://localhost:9393/`). Using it you can query your ElasticGraph cluster using GraphQL.
112
+
113
+ ### Seeding Fake Data
114
+
115
+ The `bundle exec rake index_fake_data:<type_name>` tasks generate and index a batch of fake data.
116
+ You can pass an arg (note quotes) to seed more batches of data:
117
+ `bundle exec rake "index_fake_data:<type_name>[10]"`.
118
+
119
+ ### Using <%= ElasticGraph.setup_env.datastore_ui_name %>
120
+
121
+ After running `bundle exec rake boot_locally` and opening <%= ElasticGraph.setup_env.datastore_ui_name %>
122
+ `open http://localhost:19293/` click "Dev Tools" to open the <%= ElasticGraph.setup_env.datastore_name %> console.
123
+
124
+ Here are some queries to get you started:
125
+
126
+ ```
127
+ # Cluster info
128
+ GET /_cat/indices?v
129
+ GET /_cat/shards?v
130
+ GET /_cat/templates?v
131
+ GET /_cat/nodes?v
132
+ GET /_cat/allocation?v
133
+
134
+ # Or with a pattern
135
+ GET /_cat/shards/*_rollover__202*?v
136
+
137
+ # More cluster info
138
+ GET /_cluster/health
139
+ GET /_cluster/settings
140
+
141
+ # Test queries (change from `artists` to your index name)
142
+ GET /artists/_search
143
+ {
144
+ "from": 0,
145
+ "size": 1
146
+ }
147
+
148
+ GET /artists/_search
149
+ {
150
+ "from": 0,
151
+ "size": 1,
152
+ "query": {
153
+ "bool": {
154
+ "must": [
155
+ {
156
+ "match": {
157
+ "bio": "accordion"
158
+ }
159
+ }
160
+ ]
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+ ### Query Registry
167
+
168
+ This project uses the ElasticGraph query registry extension. This is an optional piece you can choose to remove,
169
+ but provides many benefits--see the [elasticgraph-query_registry
170
+ README](https://github.com/block/elasticgraph/tree/main/elasticgraph-query_registry#elasticgraphqueryregistry)
171
+ for details.
172
+
173
+ With the registry in place, clients must register their queries in a directory under
174
+ [config/queries](config/queries) that matches their resolved application name.
175
+ The CI build will validate that all schema changes are compatible with all registered queries, and
176
+ your deployed GraphQL endpoints will reject any unregistered queries.
@@ -0,0 +1,64 @@
1
+ project_root = File.expand_path(__dir__)
2
+
3
+ require "elastic_graph/local/rake_tasks"
4
+ require "elastic_graph/query_registry/rake_tasks"
5
+ require "rspec/core/rake_task"
6
+ require "standard/rake"
7
+ require_relative "lib/<%= ElasticGraph.setup_env.app_name %>/fake_data_batch_generator"
8
+
9
+ settings_file = "#{project_root}/config/settings/local.yaml"
10
+
11
+ ElasticGraph::Local::RakeTasks.new(
12
+ local_config_yaml: settings_file,
13
+ path_to_schema: "#{project_root}/config/schema.rb"
14
+ ) do |tasks|
15
+ # Set this to true once you're beyond the prototyping stage.
16
+ tasks.enforce_json_schema_version = false
17
+
18
+ # Determines casing of field names. Can be either `:camelCase` or `:snake_case`.
19
+ tasks.schema_element_name_form = :camelCase
20
+
21
+ # Customizes the names of fields generated by ElasticGraph.
22
+ tasks.schema_element_name_overrides = {
23
+ # Example: force inequality operators to be spelled out.
24
+ # gt: "greaterThan",
25
+ # gte: "greaterThanOrEqualTo",
26
+ # lt: "lessThan",
27
+ # lte: "lessThanOrEqualTo"
28
+ }
29
+
30
+ # Customizes the naming format used by derived types.
31
+ tasks.derived_type_name_formats = {
32
+ # Example: change suffix used for filter inputs from `FilterInput` to just `Filter`.
33
+ # FilterInput: "%{base}Filter",
34
+ }
35
+
36
+ # Use this to override type names generated by ElasticGraph. We generally recommend sticking
37
+ # with the defaults, but to align with conventions in your organization you may need to override
38
+ # some type names.
39
+ tasks.type_name_overrides = {
40
+ # Example: this would make your ElasticGraph schema use `IDFilter` in place of the standard `IDFilterInput`.
41
+ # IDFilterInput: "IDFilter"
42
+ }
43
+
44
+ # TODO: replace this with a fake data generator for your own dataset.
45
+ tasks.define_fake_data_batch_for :artists do
46
+ <%= ElasticGraph.setup_env.app_module %>::FakeDataBatchGenerator.generate(artists: 100, venues: 10)
47
+ end
48
+ end
49
+
50
+ ElasticGraph::QueryRegistry::RakeTasks.from_yaml_file(
51
+ settings_file,
52
+ "config/queries",
53
+ require_eg_latency_slo_directive: false
54
+ )
55
+
56
+ ::RSpec::Core::RakeTask.new
57
+
58
+ standard_checks = ["standard", "query_registry:validate_queries", "spec"]
59
+
60
+ desc "Rebuild everything. Intended to be run locally as you iterate on the schema"
61
+ task build: ["schema_artifacts:dump", *standard_checks]
62
+
63
+ desc "Check everything. Intended to be run on CI to check your project."
64
+ task check: ["schema_artifacts:check", *standard_checks]
@@ -0,0 +1,24 @@
1
+ # TODO: remove or replace this query when you replace the artist schema.
2
+ query FindArtist {
3
+ byName: artists(filter: {
4
+ name: {equalToAnyOf: ["U2"]}
5
+ }) {
6
+ nodes {
7
+ name
8
+ bio {
9
+ yearFormed
10
+ }
11
+ }
12
+ }
13
+
14
+ byBioYearFounded: artists(filter: {
15
+ bio: {yearFormed: {gt: 2000}}
16
+ }) {
17
+ nodes {
18
+ name
19
+ bio {
20
+ yearFormed
21
+ }
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,16 @@
1
+ # TODO: remove or replace this query when you replace the artist schema.
2
+ query ListArtistAlbums {
3
+ artists {
4
+ nodes {
5
+ name
6
+ albums {
7
+ name
8
+ releasedOn
9
+
10
+ tracks {
11
+ name
12
+ }
13
+ }
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,65 @@
1
+ # TODO: replace this file with one that defines the schema for your own dataset.
2
+ ElasticGraph.define_schema do |schema|
3
+ schema.object_type "Artist" do |t|
4
+ t.field "id", "ID"
5
+ t.field "name", "String"
6
+ t.field "lifetimeSales", "JsonSafeLong"
7
+ t.field "bio", "ArtistBio"
8
+
9
+ t.field "albums", "[Album!]!" do |f|
10
+ f.mapping type: "nested"
11
+ end
12
+
13
+ t.field "tours", "[Tour!]!" do |f|
14
+ f.mapping type: "nested"
15
+ end
16
+
17
+ t.index "artists"
18
+ end
19
+
20
+ schema.object_type "ArtistBio" do |t|
21
+ t.field "yearFormed", "Int"
22
+ t.field "homeCountry", "String"
23
+ t.field "description", "String" do |f|
24
+ f.mapping type: "text"
25
+ end
26
+ end
27
+
28
+ schema.object_type "Album" do |t|
29
+ t.field "name", "String"
30
+ t.field "releasedOn", "Date"
31
+ t.field "soldUnits", "Int"
32
+ t.field "tracks", "[AlbumTrack!]!" do |f|
33
+ f.mapping type: "nested"
34
+ end
35
+ end
36
+
37
+ schema.object_type "AlbumTrack" do |t|
38
+ t.field "name", "String"
39
+ t.field "trackNumber", "Int"
40
+ t.field "lengthInSeconds", "Int"
41
+ end
42
+
43
+ schema.object_type "Tour" do |t|
44
+ t.field "name", "String"
45
+ t.field "shows", "[Show!]!" do |f|
46
+ f.mapping type: "nested"
47
+ end
48
+ end
49
+
50
+ schema.object_type "Show" do |t|
51
+ t.relates_to_one "venue", "Venue", via: "venueId", dir: :out
52
+ t.field "attendance", "Int"
53
+ t.field "startedAt", "DateTime"
54
+ end
55
+
56
+ schema.object_type "Venue" do |t|
57
+ t.field "id", "ID"
58
+ t.field "name", "String"
59
+ t.field "location", "GeoLocation"
60
+ t.field "capacity", "Int"
61
+ t.relates_to_many "featuredArtists", "Artist", via: "tours.shows.venueId", dir: :in, singular: "featuredArtist"
62
+
63
+ t.index "venues"
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ require "pathname"
2
+
3
+ ElasticGraph.define_schema do |schema|
4
+ # ElasticGraph will tell you when you need to bump this.
5
+ schema.json_schema_version 1
6
+
7
+ # This registers the elasticgraph-query_registry extension, which can be used to reject queries that
8
+ # clients have not registered (and to reject queries that differ from what a client has registered).
9
+ # In addition, every registered query is validated against the schema in the CI build, giving you
10
+ # confidence as you evolve your schema that you're not breaking client queries.
11
+ #
12
+ # If you don't want to use this extension, you can remove these lines.
13
+ require(query_registry_path = "elastic_graph/query_registry/graphql_extension")
14
+ schema.register_graphql_extension ElasticGraph::QueryRegistry::GraphQLExtension, defined_at: query_registry_path
15
+ end
16
+
17
+ # Load the rest of the schema from files at config/schema/**/*.rb.
18
+ Dir["#{__dir__}/schema/**/*.rb"].each do |schema_def_file|
19
+ # Must use `load`, not `require` so that if the schema is evaluated multiple times it works.
20
+ load Pathname(schema_def_file).expand_path
21
+ end
@@ -0,0 +1,36 @@
1
+ datastore:
2
+ client_faraday_adapter:
3
+ name: httpx
4
+ require: httpx/adapters/faraday
5
+ clusters:
6
+ main:
7
+ backend: <%= ElasticGraph.setup_env.datastore %>
8
+ url: http://localhost:9293
9
+ settings: {}
10
+ index_definitions:
11
+ # TODO: replace the `artists:` and `venues:` keys with the indices from your dataset
12
+ artists: &main_index_settings
13
+ # elasticgraph-local relies on the cluster being named "main".
14
+ query_cluster: "main"
15
+ index_into_clusters: ["main"]
16
+ ignore_routing_values: []
17
+ custom_timestamp_ranges: []
18
+ setting_overrides:
19
+ number_of_shards: 10
20
+ setting_overrides_by_timestamp: {}
21
+ venues: *main_index_settings
22
+ max_client_retries: 3
23
+ graphql:
24
+ default_page_size: 50
25
+ max_page_size: 500
26
+ logger:
27
+ device: stderr
28
+ indexer:
29
+ latency_slo_thresholds_by_timestamp_in_ms: {}
30
+ schema_artifacts:
31
+ directory: config/schema/artifacts
32
+ query_registry:
33
+ # Allow any query by any client since this is for local use.
34
+ allow_unregistered_clients: true
35
+ allow_any_query_for_clients: []
36
+ path_to_registry: config/queries
@@ -0,0 +1,107 @@
1
+ require "factory_bot"
2
+ require "faker"
3
+ require_relative "shared_factories"
4
+
5
+ # TODO: replace the artist/album/tour/venue factories with your own.
6
+ FactoryBot.define do
7
+ factory :artist, parent: :indexed_type_base do
8
+ __typename { "Artist" }
9
+ name { Faker::Music.band }
10
+
11
+ lifetimeSales do
12
+ albums.map { |a| a.fetch(:soldUnits) }.sum
13
+ end
14
+
15
+ bio { build(:artist_bio) }
16
+
17
+ albums do
18
+ Faker::Number.between(from: 1, to: 10).times.map { build(:album) }
19
+ end
20
+
21
+ tours do
22
+ Faker::Number.between(from: 0, to: 8).times.map { build(:tour, venueIds: venueIds) }
23
+ end
24
+
25
+ transient do
26
+ venueIds { [] }
27
+ end
28
+ end
29
+
30
+ factory :artist_bio, parent: :hash_base do
31
+ __typename { "ArtistBio" }
32
+ yearFormed { Faker::Number.between(from: 1900, to: 2025) }
33
+ homeCountry { Faker::Address.country }
34
+ description { Faker::Lorem.paragraphs(number: 3).join("\n\n") }
35
+ end
36
+
37
+ factory :album, parent: :hash_base do
38
+ __typename { "Album" }
39
+ name { Faker::Music.album }
40
+ releasedOn { Faker::Date.between(from: "1900-01-01", to: "2025-12-31").iso8601 }
41
+ soldUnits { Faker::Number.between(from: 10000, to: 100_000_000) }
42
+ tracks do
43
+ Faker::Number.between(from: 1, to: 20).times.map do |index|
44
+ build(:album_track, trackNumber: index + 1)
45
+ end
46
+ end
47
+ end
48
+
49
+ factory :album_track, parent: :hash_base do
50
+ __typename { "AlbumTrack" }
51
+ name { Faker::Music::RockBand.song }
52
+ trackNumber { Faker::Number.between(from: 1, to: 20) }
53
+ lengthInSeconds { Faker::Number.between(from: 30, to: 1200) }
54
+ end
55
+
56
+ factory :tour, parent: :hash_base do
57
+ __typename { "Tour" }
58
+ name { "#{Faker::Music::RockBand.song} Tour" }
59
+ shows do
60
+ start_date = Faker::Date.between(from: "1900-01-01", to: "2025-12-31")
61
+
62
+ Faker::Number.between(from: 3, to: 200).times.map do |index|
63
+ venue_id = Faker::Base.sample(venueIds)
64
+ build(:show, date: start_date + index, venueId: venue_id)
65
+ end
66
+ end
67
+
68
+ transient do
69
+ venueIds { [] }
70
+ end
71
+ end
72
+
73
+ factory :show, parent: :hash_base do
74
+ __typename { "Show" }
75
+ attendance { Faker::Number.between(from: 200, to: 100_000) }
76
+ startedAt { "#{date.iso8601}T#{startTime}" }
77
+ venueId { nil }
78
+
79
+ transient do
80
+ date { Faker::Date.between(from: "1900-01-01", to: "2025-12-31") }
81
+ startTime { Faker::Base.sample(%w[19:00:00Z 19:30:00Z 20:00:00Z 20:30:00Z]) }
82
+ end
83
+ end
84
+
85
+ factory :venue, parent: :indexed_type_base do
86
+ __typename { "Venue" }
87
+
88
+ name do
89
+ # Some common music venue types
90
+ venue_types = ["Theater", "Arena", "Music Hall", "Stadium", "Opera House", "Amphitheater"]
91
+
92
+ city_name = Faker::Address.city
93
+ venue_type = Faker::Base.sample(venue_types)
94
+
95
+ "#{city_name} #{venue_type}"
96
+ end
97
+
98
+ location { build(:geo_location) }
99
+ capacity { Faker::Number.between(from: 200, to: 100_000) }
100
+ end
101
+
102
+ factory :geo_location, parent: :hash_base do
103
+ __typename { "GeoLocation" }
104
+ latitude { Faker::Number.between(from: -90.0, to: 90.0) }
105
+ longitude { Faker::Number.between(from: -180.0, to: 180.0) }
106
+ end
107
+ end
@@ -0,0 +1,14 @@
1
+ require_relative "factories"
2
+
3
+ module <%= ElasticGraph.setup_env.app_module %>
4
+ module FakeDataBatchGenerator
5
+ def self.generate(artists:, venues:)
6
+ venue_list = FactoryBot.build_list(:venue, venues)
7
+ venue_ids = venue_list.map { |v| v.fetch(:id) }
8
+
9
+ artist_list = FactoryBot.build_list(:artist, artists, venueIds: venue_ids)
10
+
11
+ venue_list + artist_list
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require "date"
2
+ require "factory_bot"
3
+ require "faker"
4
+
5
+ FactoryBot.define do
6
+ factory :hash_base, class: Hash do
7
+ initialize_with { attributes }
8
+ end
9
+
10
+ trait :uuid_id do
11
+ id { Faker::Internet.uuid }
12
+ end
13
+
14
+ trait :versioned do
15
+ __version { Faker::Number.between(from: 1, to: 10) }
16
+ end
17
+
18
+ current_json_schema_version = nil
19
+
20
+ factory :indexed_type_base, parent: :hash_base, traits: [:uuid_id, :versioned] do
21
+ __typename { raise NotImplementedError, "You must supply __typename" }
22
+ __json_schema_version do
23
+ current_json_schema_version ||= begin
24
+ json_schema_file = File.expand_path("../../config/schema/artifacts/json_schemas.yaml", __dir__)
25
+ YAML.safe_load_file(json_schema_file).fetch("json_schema_version")
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ require "elastic_graph/local/spec_support/common_project_specs"
2
+ require "<%= ElasticGraph.setup_env.app_name %>/factories"
3
+ require "<%= ElasticGraph.setup_env.app_name %>/fake_data_batch_generator"
4
+
5
+ RSpec.describe "ElasticGraph project" do
6
+ ignored_factories = [
7
+ # List any factories to ignore
8
+ ]
9
+
10
+ include_examples "an ElasticGraph project",
11
+ use_settings_yaml: "local.yaml",
12
+ ignored_factories: ignored_factories
13
+
14
+ # TODO: update this spec as needed to generate example fake data for your dataset.
15
+ it "generates a batch of valid records from `FakeDataBatchGenerator`" do
16
+ batch = <%= ElasticGraph.setup_env.app_module %>::FakeDataBatchGenerator.generate(artists: 20, venues: 5)
17
+ expect(batch.size).to eq(25)
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticgraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0.0
4
+ version: 0.19.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
@@ -10,139 +10,71 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2024-12-10 00:00:00.000000000 Z
13
+ date: 2025-02-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: rubocop-factory_bot
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - "~>"
20
- - !ruby/object:Gem::Version
21
- version: '2.26'
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - "~>"
27
- - !ruby/object:Gem::Version
28
- version: '2.26'
29
- - !ruby/object:Gem::Dependency
30
- name: rubocop-rake
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - "~>"
34
- - !ruby/object:Gem::Version
35
- version: '0.6'
36
- type: :development
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: '0.6'
43
- - !ruby/object:Gem::Dependency
44
- name: rubocop-rspec
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '3.1'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - "~>"
55
- - !ruby/object:Gem::Version
56
- version: '3.1'
57
- - !ruby/object:Gem::Dependency
58
- name: standard
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - "~>"
62
- - !ruby/object:Gem::Version
63
- version: 1.41.0
64
- type: :development
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - "~>"
69
- - !ruby/object:Gem::Version
70
- version: 1.41.0
71
- - !ruby/object:Gem::Dependency
72
- name: elasticgraph-admin
73
- requirement: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - '='
76
- - !ruby/object:Gem::Version
77
- version: 0.19.0.0
78
- type: :runtime
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - '='
83
- - !ruby/object:Gem::Version
84
- version: 0.19.0.0
85
- - !ruby/object:Gem::Dependency
86
- name: elasticgraph-graphql
16
+ name: elasticgraph-support
87
17
  requirement: !ruby/object:Gem::Requirement
88
18
  requirements:
89
19
  - - '='
90
20
  - !ruby/object:Gem::Version
91
- version: 0.19.0.0
21
+ version: 0.19.1.0
92
22
  type: :runtime
93
23
  prerelease: false
94
24
  version_requirements: !ruby/object:Gem::Requirement
95
25
  requirements:
96
26
  - - '='
97
27
  - !ruby/object:Gem::Version
98
- version: 0.19.0.0
28
+ version: 0.19.1.0
99
29
  - !ruby/object:Gem::Dependency
100
- name: elasticgraph-indexer
30
+ name: thor
101
31
  requirement: !ruby/object:Gem::Requirement
102
32
  requirements:
103
- - - '='
104
- - !ruby/object:Gem::Version
105
- version: 0.19.0.0
106
- type: :runtime
107
- prerelease: false
108
- version_requirements: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - '='
111
- - !ruby/object:Gem::Version
112
- version: 0.19.0.0
113
- - !ruby/object:Gem::Dependency
114
- name: elasticgraph-local
115
- requirement: !ruby/object:Gem::Requirement
116
- requirements:
117
- - - '='
33
+ - - "~>"
118
34
  - !ruby/object:Gem::Version
119
- version: 0.19.0.0
35
+ version: '1.3'
120
36
  type: :runtime
121
37
  prerelease: false
122
38
  version_requirements: !ruby/object:Gem::Requirement
123
39
  requirements:
124
- - - '='
40
+ - - "~>"
125
41
  - !ruby/object:Gem::Version
126
- version: 0.19.0.0
42
+ version: '1.3'
127
43
  description:
128
44
  email:
129
45
  - myron@squareup.com
130
- executables: []
46
+ executables:
47
+ - elasticgraph
131
48
  extensions: []
132
49
  extra_rdoc_files: []
133
50
  files:
134
51
  - LICENSE.txt
135
52
  - README.md
136
- - elasticgraph.gemspec
53
+ - exe/elasticgraph
54
+ - lib/elastic_graph/cli.rb
55
+ - lib/elastic_graph/project_template/.gitignore
56
+ - lib/elastic_graph/project_template/.standard.yml.tt
57
+ - lib/elastic_graph/project_template/Gemfile.tt
58
+ - lib/elastic_graph/project_template/README.md.tt
59
+ - lib/elastic_graph/project_template/Rakefile.tt
60
+ - lib/elastic_graph/project_template/config/queries/example_client/FindArtist.graphql
61
+ - lib/elastic_graph/project_template/config/queries/example_client/ListArtistAlbums.graphql
62
+ - lib/elastic_graph/project_template/config/schema.rb.tt
63
+ - lib/elastic_graph/project_template/config/schema/artists.rb.tt
64
+ - lib/elastic_graph/project_template/config/settings/local.yaml.tt
65
+ - lib/elastic_graph/project_template/lib/app_name/factories.rb
66
+ - lib/elastic_graph/project_template/lib/app_name/fake_data_batch_generator.rb.tt
67
+ - lib/elastic_graph/project_template/lib/app_name/shared_factories.rb
68
+ - lib/elastic_graph/project_template/spec/project_spec.rb.tt
137
69
  homepage: https://block.github.io/elasticgraph/
138
70
  licenses:
139
71
  - MIT
140
72
  metadata:
141
73
  bug_tracker_uri: https://github.com/block/elasticgraph/issues
142
- changelog_uri: https://github.com/block/elasticgraph/releases/tag/v0.19.0.0
74
+ changelog_uri: https://github.com/block/elasticgraph/releases/tag/v0.19.1.0
143
75
  documentation_uri: https://block.github.io/elasticgraph/docs/main/
144
76
  homepage_uri: https://block.github.io/elasticgraph/
145
- source_code_uri: https://github.com/block/elasticgraph/tree/v0.19.0.0/elasticgraph
77
+ source_code_uri: https://github.com/block/elasticgraph/tree/v0.19.1.0/elasticgraph
146
78
  gem_category: core
147
79
  post_install_message:
148
80
  rdoc_options: []
@@ -150,9 +82,12 @@ require_paths:
150
82
  - lib
151
83
  required_ruby_version: !ruby/object:Gem::Requirement
152
84
  requirements:
153
- - - "~>"
85
+ - - ">="
154
86
  - !ruby/object:Gem::Version
155
87
  version: '3.2'
88
+ - - "<"
89
+ - !ruby/object:Gem::Version
90
+ version: '3.5'
156
91
  required_rubygems_version: !ruby/object:Gem::Requirement
157
92
  requirements:
158
93
  - - ">="
@@ -162,5 +97,5 @@ requirements: []
162
97
  rubygems_version: 3.5.22
163
98
  signing_key:
164
99
  specification_version: 4
165
- summary: ElasticGraph meta-gem that pulls in all the core ElasticGraph gems.
100
+ summary: Bootstraps ElasticGraph projects.
166
101
  test_files: []
data/elasticgraph.gemspec DELETED
@@ -1,18 +0,0 @@
1
- # Copyright 2024 Block, Inc.
2
- #
3
- # Use of this source code is governed by an MIT-style
4
- # license that can be found in the LICENSE file or at
5
- # https://opensource.org/licenses/MIT.
6
- #
7
- # frozen_string_literal: true
8
-
9
- require_relative "../gemspec_helper"
10
-
11
- ElasticGraphGemspecHelper.define_elasticgraph_gem(gemspec_file: __FILE__, category: :core) do |spec, eg_version|
12
- spec.summary = "ElasticGraph meta-gem that pulls in all the core ElasticGraph gems."
13
-
14
- spec.add_dependency "elasticgraph-admin", eg_version
15
- spec.add_dependency "elasticgraph-graphql", eg_version
16
- spec.add_dependency "elasticgraph-indexer", eg_version
17
- spec.add_dependency "elasticgraph-local", eg_version
18
- end