View Source MishkaInstaller.Installer.RunTimeSourcing (Mishka Installer v0.0.4)

Using this module, you can independently add a downloaded-library while your system is running, with minimal dependencies. The important thing to note is that you are actually adding a complete dependency and a complete Elixir project which is compiled to the system, and this is not Hot Coding. At the time of this section's development, we have been very aware that with the least dependence and only with the Erlang and Elixir functions do all the process. We covered the whole process, but without informing different sectors and being able to notify the installation, removing, and updating process, it would be incomplete. We couldn't leave the programmers. Hence, the Phoenix Pubsub library can be an excellent option to notice processes are subscribed to in the MishkaInstaller channel.

the-purpose-of-this-section-is-divided-into-two-categories-as-follows

The purpose of this section is divided into two categories as follows:

  1. View in the terminal
  2. Send Ported Output by Pubsub

This module requires the import_path as a variable system, which is your project's path.


below-you-can-see-the-graph-of-connecting-this-module-to-another-module

Below you can see the graph of connecting this module to another module.


+--------------------------------------------------+
|                                                  |
|                                                  |
|      MishkaInstaller.Installer.DepHandler        +--------------------+
|                                                  |                    |
|                                                  |                    |
+--------------------------------------------------+                    |
+---------------------------------------------+       +-----------------v-------------------------+
|                                             |       |                                           |
|    MishkaInstaller.Installer.Live.DepGetter +-------> MishkaInstaller.Installer.RunTimeSourcing |
|                                             |       |                                           |
+---------------------------------------------+       +------------------^------------------------+
                                                                         |
+--------------------------------------------------+                     |
|                                                  |                     |
|                                                  |                     |
|  MishkaInstaller.Installer.DepChangesProtector   |                     |
|                                                  +---------------------+
|                                                  |
+--------------------------------------------------+

  • Warning: This module is independent and surrounded by operational functions to create a custom system by developers themselves. Suppose you want to have an action function that makes an exemplary process by managing errors and the download queue. In that case, it is best to use two MishkaInstaller.Installer.DepHandler and MishkaInstaller.Installer.Live.DepGetter modules.
  • Warning: In this version, we use the project mix.exs so that this file does not change, and the new library is not added to it; it is impossible to use these functions. For your convenience, we added a module named mix creator as MishkaInstaller.Installer.MixCreator module. If you don't want to change mix.exs and download a dependency, you need to prepper the library file directly and compile it.
  • Warning: Being limited to mix.exs will be deleted in the future.

Link to this section Summary

Types

This type can be used when you want to send an app name

This type can be used when you want to prepend a compiled-project

This type can be used when you want to ensure or start a project

Functions

Returns a specification to start this module under a supervisor.

This function helps you compare the installed libraries and the ones you want to install and displays the ones not installed in a list. The first entry is the installed apps, which can be left blank. it is loaded from Application.loaded_applications/0.

This function converts loaded .app file as elixir type like list and tuple

This aggregator function is an action function to download and compile requested dependencies. You can decide what your default output is. It should be noted that this part of the project supports Terminal output with System.cmd/2 function and sending Pubsub with Port.open/2 module.

This function is made in three different situations that you can load according to your own needs. The overall purpose of this function with different patterns is to add - update and delete a library on your Elixir project without the need for Downtime.

It displays the build directory path based on MishkaInstaller.get_config/1. Hence you should bind :project_path on runtime or before running the CMS in your config. The first entry is the Environment status, which can be left blank. it is loaded from Mix.env/0.

Prepending path means that after getting and compiling a dependency, you can determine a made ebin folder as an item of dependencies. Hence, you need to move a compiled app with its sup-apps.

This function loads a .app file as binary.

This function helps the programmer to join the channel of this module(MishkaInstaller.Installer.RunTimeSourcing) and receive the output as a broadcast in the form of {:run_time_sourcing, answer}. It uses Phoenix.PubSub.subscribe/2.

Link to this section Types

@type app_name() :: String.t() | atom()

This type can be used when you want to send an app name

@type do_runtime() :: :application_ensure | :prepend_compiled_apps

This type can be used when you want to prepend a compiled-project

@type ensure() :: :bad_directory | :load | :no_directory | :sure_all_started

This type can be used when you want to ensure or start a project

Link to this section Functions

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

compare_dependencies(installed_apps \\ Application.loaded_applications(), files_list)

View Source
@spec compare_dependencies([tuple()], [String.t()]) :: [String.t()]

This function helps you compare the installed libraries and the ones you want to install and displays the ones not installed in a list. The first entry is the installed apps, which can be left blank. it is loaded from Application.loaded_applications/0.

examples

Examples

MishkaInstaller.Installer.RunTimeSourcing.compare_dependencies(["the_app_does_not_exist", "compiler"])
@spec consult_app_file(binary()) ::
  {:error,
   {non_neg_integer() | {non_neg_integer(), pos_integer()}, atom(), any()}}
  | {:ok, any()}
  | {:error,
     {non_neg_integer() | {non_neg_integer(), pos_integer()}, atom(), any()},
     non_neg_integer() | {non_neg_integer(), pos_integer()}}

This function converts loaded .app file as elixir type like list and tuple

references

References:

  1. https://elixirforum.com/t/how-to-get-vsn-from-app-file/48132/2
  2. https://github.com/elixir-lang/elixir/blob/main/lib/mix/lib/mix/tasks/compile.all.ex#L153-L154
Link to this function

do_deps_compile(app, type \\ :cmd)

View Source

This aggregator function is an action function to download and compile requested dependencies. You can decide what your default output is. It should be noted that this part of the project supports Terminal output with System.cmd/2 function and sending Pubsub with Port.open/2 module.

Warning: the routing of this function may change in future versions. Please check it in each version if you use this function directly. Please consider after each operation; the directory reference gets back to the project path.

examples

Examples

MishkaInstaller.Installer.RunTimeSourcing.do_deps_compile("test_app", :cmd)
MishkaInstaller.Installer.RunTimeSourcing.do_deps_compile("test_app", :port)
@spec do_runtime(atom(), atom()) ::
  {:ok, :application_ensure} | {:error, do_runtime(), ensure(), any()}

This function is made in three different situations that you can load according to your own needs. The overall purpose of this function with different patterns is to add - update and delete a library on your Elixir project without the need for Downtime.


The first pattern is :add.

This function adds a library that is neither already installed nor loaded on your project.

the-overall-activity-of-this-function-can-be-divided-into-several-parts

The overall activity of this function can be divided into several parts:

  1. Routing of compiled sub-libraries (requested library dependencies)
  2. Check compiled dependencies with installed-dependencies
  3. Introducing and addressing dependencies (in terms of files)
  4. Introducing and starting dependencies on the system

As we have mentioned in option 4 when a state dependency is started, it also starts working; now, these items can be called directly by the programmer or placed in the Application.ex of the plugin itself as a Genserver. The first entry is the dependency name. This name must be exactly the name mentioned in the mix.exs file of the requested dependency. For this purpose, the type of the library name must be an atom type and the second entry is :add.

examples

Examples

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_developer_tools, :add)

# Or

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_social, :add)

this-function-calls-6-other-functions-including

This function calls 6 other functions including:

  1. get_build_path/0
  2. File.ls!/1
  3. Enum.reject/2
  4. compare_dependencies/2
  5. prepend_compiled_apps/2
  6. application_ensure/2

The second pattern is :force_update.

This pattern is similar to :add, except that you no longer check the installed dependencies with the compiled ones. This pattern is mostly used for updates or when you are sure everything is already in place.

examples-1

Examples

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_developer_tools, :force_update)

# Or

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_social, :force_update)

this-function-calls-5-other-functions-including

This function calls 5 other functions including:

  1. get_build_path/0
  2. File.ls!/1
  3. Enum.reject/2
  4. prepend_compiled_apps/2
  5. application_ensure/2

The third pattern is :uninstall.

This function stops an already installed library and removes it from the list of installed libraries(unload an app). After deleting by the Application module functions, the compiled directory of the requested library is also deleted.

examples-2

Examples

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_developer_tools, :uninstall)

# Or

MishkaInstaller.Installer.RunTimeSourcing.do_runtime(:mishka_social, :uninstall)

this-function-calls-5-other-functions-including-1

This function calls 5 other functions including:

  1. File.ls!/1
  2. Application.stop/1
  3. Application.unload/1
  4. delete_app_dir/1
  5. get_build_path/1
Link to this function

get_build_path(mode \\ Mix.env())

View Source
@spec get_build_path(atom()) :: binary()

It displays the build directory path based on MishkaInstaller.get_config/1. Hence you should bind :project_path on runtime or before running the CMS in your config. The first entry is the Environment status, which can be left blank. it is loaded from Mix.env/0.

examples

Examples

MishkaInstaller.Installer.RunTimeSourcing.get_build_path(:dev) # Or :test, Mix.env()
MishkaInstaller.Installer.RunTimeSourcing.get_build_path()
Link to this function

prepend_compiled_apps(files_list)

View Source
@spec prepend_compiled_apps(any()) ::
  {:ok, :prepend_compiled_apps} | {:error, do_runtime(), ensure(), list()}

Prepending path means that after getting and compiling a dependency, you can determine a made ebin folder as an item of dependencies. Hence, you need to move a compiled app with its sup-apps.

This function calls Code.prepend_path/1.

examples

Examples

MishkaInstaller.Installer.RunTimeSourcing.prepend_compiled_apps(["test_app", "mishka_developer_tools"])
Link to this function

read_app(lib_path, sub_app)

View Source
@spec read_app(binary(), app_name()) :: {:error, atom()} | {:ok, binary()}

This function loads a .app file as binary.

references

References:

  1. https://elixirforum.com/t/how-to-get-vsn-from-app-file/48132/2
  2. https://github.com/elixir-lang/elixir/blob/main/lib/mix/lib/mix/tasks/compile.all.ex#L153-L154
@spec subscribe() :: :ok | {:error, {:already_registered, pid()}}

This function helps the programmer to join the channel of this module(MishkaInstaller.Installer.RunTimeSourcing) and receive the output as a broadcast in the form of {:run_time_sourcing, answer}. It uses Phoenix.PubSub.subscribe/2.

examples

Examples

# Subscribe to `MishkaInstaller.Installer.RunTimeSourcing` module
MishkaInstaller.Installer.RunTimeSourcing.subscribe()

# Getting the answer as Pubsub for examples in LiveView
@impl Phoenix.LiveView
def handle_info({:run_time_sourcing, answer}, socket) when is_binary(answer) do
  {:noreply, socket}
end