View Source Mix.Project (Mix v1.17.2)
Defines and manipulates Mix projects.
A Mix project is defined by calling use Mix.Project
in a module, usually
placed in mix.exs
:
defmodule MyApp.MixProject do
use Mix.Project
def project do
[
app: :my_app,
version: "1.0.0"
]
end
end
use Mix.Project
When you
use Mix.Project
, it notifies Mix that a new project has been defined, so all Mix tasks use your module as a starting point.
Configuration
In order to configure Mix, the module that calls use Mix.Project
should export
a project/0
function that returns a keyword list representing configuration
for the project.
This configuration can be read using Mix.Project.config/0
. Note that
config/0
won't fail if a project is not defined; this allows many Mix tasks
to work without a project.
If a task requires a project to be defined or needs to access a
special function within the project, the task can call Mix.Project.get!/0
which fails with Mix.NoProjectError
in the case a project is not
defined.
There isn't a comprehensive list of all the options that can be returned by
project/0
since many Mix tasks define their own options that they read from
this configuration. For example, look at the "Configuration" section in the
documentation for the Mix.Tasks.Compile
task.
These are a few options that are not used by just one Mix task (and will thus be documented here):
:build_per_environment
- iftrue
, builds will be per-environment. Iffalse
, builds will go in_build/shared
regardless of the Mix environment. Defaults totrue
.:aliases
- a list of task aliases. For more information, check out the "Aliases" section in the documentation for theMix
module. Defaults to[]
.:config_path
- a string representing the path of the main config file. Seeconfig_files/0
for more information. Defaults to"config/config.exs"
.:deps
- a list of dependencies of this project. Refer to the documentation for theMix.Tasks.Deps
task for more information. Defaults to[]
.:deps_path
- directory where dependencies are stored. Also seedeps_path/1
. Defaults to"deps"
.:lockfile
- the name of the lockfile used by themix deps.*
family of tasks. Defaults to"mix.lock"
.
Mix tasks may require their own configuration inside def project
. For example,
check the Mix.Tasks.Compile
task and all the specific compiler tasks
(such as Mix.Tasks.Compile.Elixir
or Mix.Tasks.Compile.Erlang
).
Note that different tasks may share the same configuration option. For example,
the :erlc_paths
configuration is used by mix compile.erlang
, mix compile.yecc
,
and other tasks.
CLI configuration
Mix is most often invoked from the command line. For this purpose, you may define
a specific cli/0
function which customizes default values when executed from
the CLI. For example:
def cli do
[
default_task: "phx.server",
preferred_envs: [docs: :docs]
]
end
The example above sets the default task (used by iex -S mix
and mix
) to
phx.server
. It also sets the default environment for the "mix docs" task to
be "docs".
The following CLI configuration are available:
:default_env
- the default environment to use when none is given andMIX_ENV
is not set:default_target
- the default target to use when none is given andMIX_TARGET
is not set:default_task
- the default task to invoke when none is given:preferred_envs
- a keyword list of{task, env}
tuples wheretask
is the task name as an atom (for example,:"deps.get"
) andenv
is the preferred environment (for example,:test
):preferred_targets
- a keyword list of{task, target}
tuples wheretask
is the task name as an atom (for example,:test
) andtarget
is the preferred target (for example,:host
)
Erlang projects
Mix can be used to manage Erlang projects that don't have any Elixir code. To
ensure Mix tasks work correctly for an Erlang project, language: :erlang
has
to be part of the configuration returned by project/0
. This setting also
makes sure Elixir is not added as a dependency to the generated .app
file or
to the escript generated with mix escript.build
, and so on.
Invoking this module
This module contains many functions that return project information and metadata. However, since Mix is not included nor configured during releases, we recommend using the functions in this module only inside Mix tasks. If you need to configure your own app, consider using the application environment instead. For example, don't do this:
def some_config do
Mix.Project.config()[:some_config]
end
Nor this:
@some_config Mix.Project.config()[:some_config]
Instead, do this:
def some_config do
Application.get_env(:my_app, :some_config)
end
Or this:
@some_config Application.compile_env(:my_app, :some_config)
Summary
Functions
Returns the application path inside the build.
Returns a map with the umbrella child applications paths.
Returns the build path for the given project.
Builds the project structure for the given application.
Clears the dependency for the current environment.
Returns the paths the given project compiles to.
Returns the project configuration.
Returns a list of project configuration files for this project.
Returns the latest modification time from config files.
Returns the path where protocol consolidations are stored.
Returns all dependencies app names.
Returns the path where dependencies are stored for the given project.
Returns the full path of all dependencies as a map.
Returns the SCMs of all dependencies as a map.
Returns the dependencies of all dependencies as a map.
Ensures the project structure for the given project exists.
Retrieves the current project if there is one.
Runs the given fun
inside the given project.
Returns the path where manifests are stored.
Returns the path to the file that defines the parent umbrella project, if one.
Returns the path to the file that defines the current project.
Returns true
if config
is the configuration for an umbrella project.
Functions
Returns the application path inside the build.
The returned path will be expanded.
Examples
If your project defines the app my_app
:
Mix.Project.app_path()
#=> "/path/to/project/_build/shared/lib/my_app"
Returns a map with the umbrella child applications paths.
These paths are based on the :apps_path
and :apps
configurations.
If the given project configuration identifies an umbrella project, the return
value is a map of app => path
where app
is a child app of the umbrella and
path
is its path relative to the root of the umbrella project.
If the given project configuration does not identify an umbrella project,
nil
is returned.
Examples
Mix.Project.apps_paths()
#=> %{my_app1: "apps/my_app1", my_app2: "apps/my_app2"}
Returns the build path for the given project.
The build path is built based on the :build_path
configuration
(which defaults to "_build"
) and a subdirectory. The subdirectory
is built based on two factors:
If
:build_per_environment
is set, the subdirectory is the value ofMix.env/0
(which can be set viaMIX_ENV
). Otherwise it is set to "shared".If
Mix.target/0
is set (often via theMIX_TARGET
environment variable), it will be used as a prefix to the subdirectory.
Finally, the environment variables MIX_BUILD_ROOT
and MIX_BUILD_PATH
can be used to change the result of this function. MIX_BUILD_ROOT
overwrites only the root "_build"
directory while keeping the
subdirectory as is. It may be useful to change it for caching reasons,
typically during Continuous Integration (CI). MIX_BUILD_PATH
overrides
the build path altogether and it typically used by other build tools
that invoke the mix
CLI.
Naming differences
Ideally the configuration option
:build_path
would be called:build_root
, as it would fully mirror the environment variable. However, its name is preserved for backwards compatibility.
Examples
Mix.Project.build_path()
#=> "/path/to/project/_build/shared"
If :build_per_environment
is set to true
, it will create a new build per
environment:
Mix.env()
#=> :dev
Mix.Project.build_path()
#=> "/path/to/project/_build/dev"
Builds the project structure for the given application.
Options
:symlink_ebin
- symlink ebin instead of copying it
@spec clear_deps_cache() :: :ok
Clears the dependency for the current environment.
Useful when dependencies need to be reloaded due to change of global state.
For example, Nerves uses this function to force all dependencies to be reloaded after it updates the system environment. It goes roughly like this:
- Nerves fetches all dependencies and looks for the system specific deps
- Once the system specific dep is found, it loads it alongside env vars
- Nerves then clears the cache, forcing dependencies to be loaded again
- Dependencies are loaded again, now with an updated env environment
Returns the paths the given project compiles to.
If no configuration is given, the one for the current project will be used.
The returned path will be expanded.
Examples
If your project defines the app my_app
:
Mix.Project.compile_path()
#=> "/path/to/project/_build/dev/lib/my_app/ebin"
@spec config() :: keyword()
Returns the project configuration.
If there is no project defined, it still returns a keyword list with default values. This allows many Mix tasks to work without the need for an underlying project.
Note this configuration is cached once the project is pushed onto the stack. Calling it multiple times won't cause it to be recomputed.
Do not use Mix.Project.config/0
to find the runtime configuration.
Use it only to configure aspects of your project (like
compilation directories) and not your application runtime.
@spec config_files() :: [Path.t()]
Returns a list of project configuration files for this project.
This function is usually used in compilation tasks to trigger a full recompilation whenever such configuration files change.
It returns the lock manifest, and all config files in the config
directory that do not start with a leading period (for example,
.my_config.exs
).
Note: before Elixir v1.13.0, the mix.exs
file was also included
as a config file, but since then it has been moved to its own
function called project_file/0
.
@spec config_mtime() :: posix_mtime when posix_mtime: integer()
Returns the latest modification time from config files.
This function is usually used in compilation tasks to trigger a full recompilation whenever such configuration files change. For this reason, the mtime is cached to avoid file system lookups.
However, for effective used of this function, you must avoid
comparing source files with the config_mtime
itself. Instead,
store the previous config_mtime
and compare it with the new
config_mtime
in order to detect if something is stale.
Note: before Elixir v1.13.0, the mix.exs
file was also included
in the mtimes, but not anymore. You can compute its modification
date by calling project_file/0
.
Returns the path where protocol consolidations are stored.
The returned path will be expanded.
Examples
If your project defines the app my_app
:
Mix.Project.consolidation_path()
#=> "/path/to/project/_build/dev/lib/my_app/consolidated"
Inside umbrellas:
Mix.Project.consolidation_path()
#=> "/path/to/project/_build/dev/consolidated"
@spec deps_apps() :: [atom()]
Returns all dependencies app names.
The order they are returned is guaranteed to be sorted for proper dependency resolution. For example, if A depends on B, then B will listed before A.
Returns the path where dependencies are stored for the given project.
If no configuration is given, the one for the current project is used.
The returned path will be expanded.
Examples
Mix.Project.deps_path()
#=> "/path/to/project/deps"
Returns the full path of all dependencies as a map.
Options
:depth
- only returns dependencies to the depth level, a depth of1
will only return top-level dependencies:parents
- starts the dependency traversal from the given parents instead of the application root
Examples
Mix.Project.deps_paths()
#=> %{foo: "deps/foo", bar: "custom/path/dep"}
Returns the SCMs of all dependencies as a map.
See Mix.SCM
module documentation to learn more about SCMs.
Options
:depth
- only returns dependencies to the depth level, a depth of1
will only return top-level dependencies:parents
- starts the dependency traversal from the given parents instead of the application root
Examples
Mix.Project.deps_scms()
#=> %{foo: Mix.SCM.Path, bar: Mix.SCM.Git}
Returns the dependencies of all dependencies as a map.
Options
:depth
- only returns dependencies to the depth level, a depth of1
will only return top-level dependencies:parents
- starts the dependency traversal from the given parents instead of the application root
Examples
Mix.Project.deps_tree()
#=> %{foo: [:bar, :baz], bar: [], baz: []}
Ensures the project structure for the given project exists.
In case it does exist, it is a no-op. Otherwise, it is built.
opts
are the same options that can be passed to build_structure/2
.
@spec get() :: module() | nil
Retrieves the current project if there is one.
If there is no current project, nil
is returned. This
may happen in cases there is no mix.exs
in the current
directory.
If you expect a project to be defined, i.e., it is a
requirement of the current task, you should call
get!/0
instead.
@spec get!() :: module()
Same as get/0
, but raises an exception if there is no current project.
This is usually called by tasks that need additional
functions on the project to be defined. Since such
tasks usually depend on a project being defined, this
function raises a Mix.NoProjectError
exception in
case no project is available.
Runs the given fun
inside the given project.
This function changes the current working directory and loads the project at the given directory onto the project stack.
A post_config
can be passed that will be merged into
the project configuration.
fun
is called with the module name of the given Mix.Project
.
The return value of this function is the return value of fun
.
Examples
Mix.Project.in_project(:my_app, "/path/to/my_app", fn module ->
"Mix project is: #{inspect(module)}"
end)
#=> "Mix project is: MyApp.MixProject"
Returns the path where manifests are stored.
By default they are stored in the app path inside the build directory. Umbrella applications have the manifest path set to the root of the build directory. Directories may be changed in future releases.
The returned path will be expanded.
Examples
If your project defines the app my_app
:
Mix.Project.manifest_path()
#=> "/path/to/project/_build/shared/lib/my_app/.mix"
@spec parent_umbrella_project_file() :: binary() | nil
Returns the path to the file that defines the parent umbrella project, if one.
The majority of the time, it will point to a mix.exs
file.
Returns nil
if not inside a project or not inside an umbrella.
@spec project_file() :: binary() | nil
Returns the path to the file that defines the current project.
The majority of the time, it will point to a mix.exs
file.
Returns nil
if not inside a project.
Returns true
if config
is the configuration for an umbrella project.
When called with no arguments, tells whether the current project is an umbrella project.