View Source Bonfire.Common.Extend (Bonfire v0.9.11-social-beta.6)

Helpers for using and managing the extensibility of Bonfire, such as checking if a module or extension is enabled or hot-swapped, or loading code or docs. See also Bonfire.Common.Extensions.

Summary

Functions

Retrieves the OTP application associated with a given module.

Retrieves the beam file path from the object code of a module.

Checks if a value indicates that a module or extension is disabled.

Extend a module by defining defdelegate and defoverridable for all functions from the source module in the current module.

Checks if an Elixir module or extension/OTP app is present and not disabled.

Whether an Elixir module or extension / OTP app is present

Fetches the @moduledoc of a module as a markdown string.

Fetches module.function's @doc as a markdown string

Retrieves the content of a code file.

Retrieves the AST of a specific function from a module.

Retrieves the code of a specific function from a module.

Returns the line number of the first line where a function is defined in a module.

Return the numbers (as a tuple) of the first and last lines of a function's definition in a module

Generates an updated reverse router based on enabled/disabled extensions.

Checks whether an Elixir module or extension / OTP app has any configuration available.

Conditionally imports a module if it's enabled, with an optional fallback.

Copies the code defining a function from its original module to a target module.

Returns a map of loaded applications with their versions and descriptions.

Returns a map of loaded applications names as keys.

Inspects a macro by expanding it and converting it to a string.

Returns the OTP app name for a module or extension.

Returns the OTP app name for a module or extension if available, and nil otherwise.

Given an Elixir module, returns the module if available and not disabled, or its replacement if configured.

Returns the module if it is present and not disabled; raises an error if the module is disabled and no replacement is configured.

Checks if a module exists and returns it, otherwise returns nil.

Returns the given schema module if it exists, otherwise returns Needle.Pointer.

Normalizes the AST of a module for use.

Checks if an Elixir module exists and is loaded and that it (or the extension/OTP app it belongs to) is not disabled.

Re-creates a module's code from compiled Beam artifacts.

Checks if a module implements a specific behaviour.

Returns a list of behaviours implemented by a module.

Retrieves the code of a module from the source.

Retrieves the code of a module from its AST (Abstract Syntax Tree).

Retrieves the code of a module from its object code.

Checks if an Elixir module or the extension/OTP app it belongs to is available and not disabled.

Checks if an Elixir module exists and can be loaded.

Retrieves the file path of the module's source file.

Retrieves the source code of a module.

Retrieves the file path of a module from its object code.

Checks if an Elixir module exists and that it (or the extension/OTP app it belongs to) is not disabled.

Retrieves the bytecode of a module's object code.

Retrieves the object code tuple for a module.

Conditionally requires a module if it's enabled, with an optional fallback.

Returns a string given raw code data.

Retrieves the content of a code file within the source code tar file (available in Bonfire prod releases).

Conditionally uses a module if it's enabled, with an optional fallback.

Functions

application_for_module(module)

Retrieves the OTP application associated with a given module.

Examples

iex> application_for_module(Bonfire.Common)
:bonfire_common

iex> application_for_module(SomeUnknownModule)
nil

beam_file_from_object_code(module)

Retrieves the beam file path from the object code of a module.

Examples

> beam_file_from_object_code(Bonfire.Common)
"/path/ebin/Elixir.Bonfire.Common.beam"

deps_tree()

deps_tree_flat(tree \\ deps_tree())

disabled_value?(value)

Checks if a value indicates that a module or extension is disabled.

Examples

iex> disabled_value?(:disabled)
true

iex> disabled_value?(false)
false

iex> disabled_value?(disabled: true)
true

extend_module(module)

(macro)

Extend a module by defining defdelegate and defoverridable for all functions from the source module in the current module.

Examples

> import Bonfire.Common.Extend
> extend_module Common.Text

extension_enabled?(module_or_otp_app, opts \\ [])

Checks if an Elixir module or extension/OTP app is present and not disabled.

For modules, checks also that the extension/OTP app it belongs is not disabled.

Examples

iex> extension_enabled?(Bonfire.Common)
true

iex> extension_enabled?(:bonfire_common)
true

iex> extension_enabled?(SomeOtherModule)
false

iex> extension_enabled?(:non_existent_extension)
false

extension_loaded?(module_or_otp_app)

Whether an Elixir module or extension / OTP app is present

fetch_docs_as_markdown(module)

@spec fetch_docs_as_markdown(module()) :: nil | binary()

Fetches the @moduledoc of a module as a markdown string.

Examples

> fetch_docs_as_markdown(SomeModule)
"This is the moduledoc for SomeModule"

fetch_docs_as_markdown(module, function)

@spec fetch_docs_as_markdown(module(), fun()) :: nil | binary()

Fetches module.function's @doc as a markdown string

file_code(code_file)

Retrieves the content of a code file.

Examples

> file_code("mix.ex")
"defmodule ... end"

function_ast(module, fun, opts \\ [])

Retrieves the AST of a specific function from a module.

Examples

> function_ast(Bonfire.Common, :some_function)
[{:def, [...], [...]}, ...]

function_code(module, fun, opts \\ [])

Retrieves the code of a specific function from a module.

Examples

> function_code(Bonfire.Common, :some_function)
"def some_function do ... end"

function_line_number(module, fun, opts \\ [])

Returns the line number of the first line where a function is defined in a module.

Examples

> function_line_number(Bonfire.Common, :some_function)
10

function_line_numbers(module, fun, opts \\ [])

Return the numbers (as a tuple) of the first and last lines of a function's definition in a module

Examples

> function_line_numbers(Bonfire.Common, :some_function)
{10, 20}

generate_reverse_router!()

Generates an updated reverse router based on enabled/disabled extensions.

Examples

> generate_reverse_router!()
:ok

has_extension_config?(module_or_otp_app)

Checks whether an Elixir module or extension / OTP app has any configuration available.

import_if_enabled(module, opts \\ [], fallback_module \\ nil)

(macro)

Conditionally imports a module if it's enabled, with an optional fallback.

Examples

defmodule MyModule do
  import_if_enabled SomeExtension
  # or
  import_if_enabled SomeExtension, [], FallbackModule
end

inject_function(module, fun, target_module \\ nil)

Copies the code defining a function from its original module to a target module.

The target module can be specified, otherwise, the function will be injected into a default extension module.

Examples

iex> inject_function(Common.TextExtended, :blank?)

loaded_applications_map(opts \\ [cache: false])

Returns a map of loaded applications with their versions and descriptions.

Examples

iex> %{bonfire_common: {_version, _description} } = loaded_applications_map()

loaded_applications_names(opts \\ [cache: false])

Returns a map of loaded applications names as keys.

Examples

iex> %{bonfire_common: _} = loaded_applications_names()

macro_inspect(fun)

Inspects a macro by expanding it and converting it to a string.

Examples

iex> macro_inspect(fn -> quote do: 1 + 1 end)
"1 + 1"

maybe_extension_loaded(module_or_otp_app)

Returns the OTP app name for a module or extension.

Examples

iex> maybe_extension_loaded(Bonfire.Common)
:bonfire_common

iex> maybe_extension_loaded(:bonfire_common)
:bonfire_common

iex> maybe_extension_loaded(:non_existent_app)
:non_existent_app

maybe_extension_loaded!(module_or_otp_app)

Returns the OTP app name for a module or extension if available, and nil otherwise.

Examples

iex> maybe_extension_loaded!(Bonfire.Common)
:bonfire_common

iex> maybe_extension_loaded!(:non_existent_app)
nil

maybe_module(module, opts \\ [])

Given an Elixir module, returns the module if available and not disabled, or its replacement if configured.

Checks both that module and the extension / OTP app it belongs to are available and not disabled (eg. by configuring something like config :bonfire_common, Bonfire.Common.Text, modularity: :disabled)

Important note: you should make sure to use the returned module after calling this function, as it can be different from the one you intended to call, as this allows for swapping out modules in config or user settings (eg. by configuring something like config :bonfire_common, Bonfire.Common.Text, modularity: MyCustomExtension.Text)

Examples

iex> maybe_module(Bonfire.Common)
Bonfire.Common

iex> Config.put(DisabledModule, modularity: :disabled)
iex> maybe_module(DisabledModule)
nil

iex> Config.put([Bonfire.Common.Text], modularity: Bonfire.Common.TextExtended)
iex> maybe_module(Bonfire.Common.Text)
Bonfire.Common.TextExtended
iex> Config.put([Bonfire.Common.Text], modularity: Bonfire.Common.Text)
iex> maybe_module(Bonfire.Common.Text)
Bonfire.Common.Text

maybe_module!(module, opts \\ [])

Returns the module if it is present and not disabled; raises an error if the module is disabled and no replacement is configured.

Examples

iex> maybe_module!(Bonfire.Common)
Bonfire.Common

iex> maybe_module!(SomeDisabledModule)
** (RuntimeError) Module Elixir.SomeDisabledModule is disabled and no replacement was configured

maybe_module_loaded(module)

Checks if a module exists and returns it, otherwise returns nil.

Examples

iex> maybe_module_loaded(Bonfire.Common)
Bonfire.Common

iex> maybe_module_loaded(NonExistentModule)
nil

maybe_schema_or_pointer(schema_module)

Returns the given schema module if it exists, otherwise returns Needle.Pointer.

Examples

> maybe_schema_or_pointer(SomeSchema)
SomeSchema

iex> maybe_schema_or_pointer(NonExistentSchema)
Needle.Pointer

module_ast_normalize(module, ast, target \\ :ast)

Normalizes the AST of a module for use.

Examples

> module_ast_normalize(Bonfire.Common, ast)

module_available?(module)

Checks if an Elixir module exists and is loaded and that it (or the extension/OTP app it belongs to) is not disabled.

Examples

iex> module_available?(Bonfire.Common)
true

iex> module_available?(SomeOtherModule)
false

module_beam_code(module, opts \\ [])

Re-creates a module's code from compiled Beam artifacts.

Examples

iex> {:ok, _} = module_beam_code(Bonfire.Common)

module_behaviour?(module, behaviour)

Checks if a module implements a specific behaviour.

Examples

> module_behaviour?(MyModule, SomeBehaviour)
true

module_behaviours(module)

Returns a list of behaviours implemented by a module.

Examples

> module_behaviours(MyModule)
[SomeBehaviour, AnotherBehaviour]

module_code(module, opts \\ [])

Retrieves the code of a module from the source.

Examples

> module_code(Bonfire.Common)
"defmodule Bonfire.Common do ... end"

module_code_from_ast(module, ast, target \\ :ast)

Retrieves the code of a module from its AST (Abstract Syntax Tree).

Examples

> module_code_from_ast(Bonfire.Common, ast)
"defmodule Bonfire.Common do ... end"

module_code_from_object_code(module)

Retrieves the code of a module from its object code.

Examples

> module_code_from_object_code(Bonfire.Common)
"defmodule Bonfire.Common do ... end"

module_enabled?(module, opts \\ [])

Checks if an Elixir module or the extension/OTP app it belongs to is available and not disabled.

Examples

iex> module_enabled?(Bonfire.Common)
true

iex> module_enabled?(SomeDisabledModule)
false

module_exists?(module)

Checks if an Elixir module exists and can be loaded.

Examples

iex> module_exists?(Bonfire.Common)
true

iex> module_exists?(SomeOtherModule)
false

module_file(module)

Retrieves the file path of the module's source file.

Examples

> module_file(Bonfire.Common)
"/path/lib/common.ex"

module_file_code(module, opts \\ [])

Retrieves the source code of a module.

Examples

> module_file_code(Bonfire.Common)
"defmodule Bonfire.Common do ... end"

module_file_from_object_code(module)

Retrieves the file path of a module from its object code.

Examples

> module_file_from_object_code(Bonfire.Common)

module_not_disabled?(module, opts \\ [])

Checks if an Elixir module exists and that it (or the extension/OTP app it belongs to) is not disabled.

Examples

iex> module_enabled?(Bonfire.Common)
true

iex> module_enabled?(SomeDisabledModule)
false

module_object_byte_code(module)

Retrieves the bytecode of a module's object code.

Examples

> module_object_byte_code(Bonfire.Common)
<<...>>

module_object_code_tuple(module)

Retrieves the object code tuple for a module.

Examples

iex> {Bonfire.Common, _bytecode, _path} = module_object_code_tuple(Bonfire.Common)

quoted_import_if_enabled(module, opts \\ [], fallback_module \\ nil, caller \\ nil)

quoted_require_if_enabled(module, opts \\ [], fallback_module \\ nil, caller \\ nil)

quoted_use_if_enabled(module, opts \\ [], fallback_module \\ nil, caller \\ nil)

quoted_use_many_if_enabled(module_configs)

require_if_enabled(module, opts \\ [], fallback_module \\ nil)

(macro)

Conditionally requires a module if it's enabled, with an optional fallback.

Examples

defmodule MyModule do
  require_if_enabled SomeExtension
  # or
  require_if_enabled SomeExtension, [], FallbackModule
end

return_file(raw)

Returns a string given raw code data.

tar_file_code(code_file)

Retrieves the content of a code file within the source code tar file (available in Bonfire prod releases).

Examples

> tar_file_code("/mix.exs")
"defmodule ... end"

use_if_enabled(module, opts \\ [], fallback_module \\ nil)

(macro)

Conditionally uses a module if it's enabled, with an optional fallback.

Examples

defmodule MyModule do
  use_if_enabled SomeExtension
  # or
  use_if_enabled SomeExtension, [], FallbackModule
end

use_many_if_enabled(module_configs)

(macro)