Class: ElasticGraph::CLI

Inherits:
Thor
  • Object
show all
Includes:
Thor::Actions
Defined in:
lib/elastic_graph/cli.rb

Constant Summary collapse

VALID_DATASTORES =
%w[elasticsearch opensearch]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/elastic_graph/cli.rb', line 22

def self.exit_on_failure?
  true
end

.source_rootObject

Tell Thor where our template files live



18
19
20
# File 'lib/elastic_graph/cli.rb', line 18

def self.source_root
  ::File.expand_path("project_template", __dir__)
end

Instance Method Details

#new(app_path) ⇒ Object



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
# File 'lib/elastic_graph/cli.rb', line 30

def new(app_path)
  new_app_path = ::File.absolute_path?(app_path) ? app_path : ::File.join(::Dir.pwd, app_path)
  app_name = ::File.basename(new_app_path)

  unless app_name.match?(/\A[a-z][a-z0-9_]+\z/)
    raise ::Thor::Error, "App name must start with a letter and be in `snake_case` form but was not: `#{app_name}`."
  end

  unless VALID_DATASTORES.include?(options[:datastore])
    raise ::Thor::Error, "Invalid datastore option: #{options[:datastore]}. Must be #{VALID_DATASTORES.join(" or ")}."
  end

  # This determines where the ElasticGraph gems are sourced from. By default, we source them from the
  # released gems (using the current `VERSION`). However, we also need to be able to use the local
  # unreleased gems in some specific situations:
  #
  # - From our cli acceptance spec -- we want to test against our local gems, not the released gems.
  # - From our Dockerfile -- we want it to build the docker image from our local gems.
  gemfile_elasticgraph_details_code_snippet = %(["#{VERSION}"])
  if (eg_gems_path = ENV["ELASTICGRAPH_GEMS_PATH"])
    gemfile_elasticgraph_details_code_snippet = %([path: "#{eg_gems_path}"])
    # :nocov: -- our tests always override `gemfile_elasticgraph_details_code_snippet` using the ENV var.
  else
    # :nocov:
  end

  setup_env = SetupEnv.new(
    app_name: app_name,
    app_module: app_name.split("_").map(&:capitalize).join,
    datastore: options.fetch(:datastore),
    gemfile_elasticgraph_details_code_snippet: gemfile_elasticgraph_details_code_snippet
  )

  say "Creating a new #{setup_env.datastore_name} ElasticGraph project called '#{app_name}' at: #{new_app_path}", :green

  ElasticGraph.with_setup_env(setup_env) do
    # Recursively copy all files from project_template into the new_app_path
    directory ".", new_app_path, exclude_pattern: %r{/lib/app_name/}
    directory "lib/app_name", ::File.join(new_app_path, "lib", app_name)
  end

  inside new_app_path do
    ::Bundler.with_unbundled_env do
      run "bundle install"
      run "bundle exec rake schema_artifacts:dump query_registry:dump_variables:all build"
    end

    run "git init"
    run "git add ."
    run "git commit -m 'Bootstrapped ElasticGraph with `elasticgraph new`.'"
  end

  say "Successfully bootstrapped '#{app_name}' as a new #{setup_env.datastore_name} ElasticGraph project.", :green

  say <<~INSTRUCTIONS, :yellow
    Next steps:
      1. cd #{app_path}
      2. Run `bundle exec rake boot_locally` to try it out in your browser.
      3. Run `bundle exec rake -T` to view other available tasks.
      4. Customize your new project as needed. (Search for `TODO` to find things that need updating.)
  INSTRUCTIONS
end