Class: Tapioca::Compilers::Dsl::Config

Inherits:
Base
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/tapioca/compilers/dsl/config.rb

Overview

Tapioca::Compilers::Dsl::Config generates RBI files for classes generated by the config gem.

The gem creates a Config::Options instance based on the settings files and/or env variables. It then assigns this instance to a constant with a configurable name, by default Settings. Application code uses methods on this constant to read off config values.

For a setting file like the following:

---
github:
  token: 12345
  client_id: 54321
  client_secret: super_secret

and a Config setup like:

Config.setup do |config|
  config.const_name = "AppSettings"
end

this generator will produce the following RBI file:

AppSettings = T.let(T.unsafe(nil), AppSettingsConfigOptions)

class AppSettingsConfigOptions < ::Config::Options
  sig { returns(T.untyped) }
  def github; end

  sig { params(value: T.untyped).returns(T.untyped) }
  def github=(value); end
end

Constant Summary collapse

CONFIG_OPTIONS_SUFFIX =
"ConfigOptions"

Constants included from Reflection

Reflection::ANCESTORS_METHOD, Reflection::CLASS_METHOD, Reflection::CONSTANTS_METHOD, Reflection::EQUAL_METHOD, Reflection::METHOD_METHOD, Reflection::NAME_METHOD, Reflection::OBJECT_ID_METHOD, Reflection::PRIVATE_INSTANCE_METHODS_METHOD, Reflection::PROTECTED_INSTANCE_METHODS_METHOD, Reflection::PUBLIC_INSTANCE_METHODS_METHOD, Reflection::SINGLETON_CLASS_METHOD, Reflection::SUPERCLASS_METHOD

Instance Attribute Summary

Attributes inherited from Base

#errors, #processable_constants

Instance Method Summary collapse

Methods inherited from Base

#add_error, #handles?, #initialize

Methods included from Reflection

#ancestors_of, #are_equal?, #class_of, #constants_of, #descendants_of, #inherited_ancestors_of, #method_of, #name_of, #name_of_type, #object_id_of, #private_instance_methods_of, #protected_instance_methods_of, #public_instance_methods_of, #qualified_name_of, #signature_of, #singleton_class_of, #superclass_of

Constructor Details

This class inherits a constructor from Tapioca::Compilers::Dsl::Base

Instance Method Details

#decorate(root, constant) ⇒ Object



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
# File 'lib/tapioca/compilers/dsl/config.rb', line 53

def decorate(root, constant)
  # The constant we are given is the specialized config options type
  option_class_name = constant.name
  return unless option_class_name

  # Grab the config constant name and the actual config constant
  config_constant_name = option_class_name
    .gsub(/#{CONFIG_OPTIONS_SUFFIX}$/, "")
  config_constant = Object.const_get(config_constant_name)

  # Look up method names from the keys of the config constant
  method_names = config_constant.keys

  return if method_names.empty?

  root.create_constant(config_constant_name, value: "T.let(T.unsafe(nil), #{option_class_name})")

  root.create_class(option_class_name, superclass_name: "::Config::Options") do |mod|
    # We need this to be generic only becuase `Config::Options` is an
    # enumerable and, thus, needs to redeclare the `Elem` type member.
    #
    # We declare it as a fixed member of `T.untyped` so that if anyone
    # enumerates the entries, we don't make any assumptions about their
    # types.
    mod.create_extend("T::Generic")
    mod.create_type_member("Elem", value: "type_member(fixed: T.untyped)")

    method_names.each do |method_name|
      # Create getter method
      mod.create_method(
        method_name.to_s,
        return_type: "T.untyped"
      )

      # Create setter method
      mod.create_method(
        "#{method_name}=",
        parameters: [create_param("value", type: "T.untyped")],
        return_type: "T.untyped"
      )
    end
  end
end

#gather_constants ⇒ Object



98
99
100
101
102
103
104
105
106
107
# File 'lib/tapioca/compilers/dsl/config.rb', line 98

def gather_constants
  name = ::Config.const_name
  return [] unless Object.const_defined?(name)

  config_object = Object.const_get(name)
  options_class_name = "#{name}#{CONFIG_OPTIONS_SUFFIX}"
  Object.const_set(options_class_name, config_object.singleton_class)

  Array(config_object.singleton_class)
end