Packages
nerves
1.10.4
1.15.0
1.14.3
1.14.2
1.14.1
1.14.0
1.13.2
1.13.1
1.13.0
1.12.0
1.11.3
1.11.2
1.11.1
1.11.0
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.3
1.9.2
retired
1.9.1
1.9.0
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
retired
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
retired
1.7.1
retired
1.7.0
retired
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.11.0
0.10.1
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.4.0-rc.0
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
Craft and deploy bulletproof embedded software
Current section
Files
Jump to
Current section
Files
lib/nerves/package.ex
defmodule Nerves.Package do
@moduledoc """
Defines a Nerves package struct and helper functions.
A Nerves package is a Mix application that defines the configuration for a
Nerves system or Nerves toolchain. For more details, see the Nerves
[system documentation](https://hexdocs.pm/nerves/systems.html#package-configuration)
"""
alias Nerves.Artifact
defstruct app: nil,
path: nil,
dep: nil,
env: [],
type: nil,
version: nil,
platform: nil,
build_runner: nil,
compilers: [],
dep_opts: [],
config: []
@type t :: %__MODULE__{
app: atom,
path: binary,
env: %{String.t() => String.t()},
type:
:system
| :package
| :toolchain
| :system_platform
| :toolchain_platform,
dep:
:project
| :path
| :hex
| :git,
platform: atom,
build_runner: {module(), Keyword.t()},
compilers: [atom],
dep_opts: Keyword.t(),
version: Version.t(),
config: Keyword.t()
}
@package_config "nerves.exs"
@required [:type, :version, :platform]
@doc """
Loads the package config and parses it into a `%Package{}`
"""
@spec load_config({app :: atom, path :: String.t()}) :: Nerves.Package.t()
def load_config({app, path}) do
config = config(app, path)
version = config[:version]
type = config[:nerves_package][:type]
compilers = config[:compilers] || Mix.compilers()
env = Map.new(config[:nerves_package][:env] || %{})
unless type do
Mix.shell().error(
"The Nerves package #{app} does not define a type.\n\n" <>
"Verify that the key exists in '#{config_path(path)}'.\n"
)
exit({:shutdown, 1})
end
platform = config[:nerves_package][:platform]
build_runner = Artifact.build_runner(config)
config = Enum.reject(config[:nerves_package], fn {k, _v} -> k in @required end)
dep_opts =
Mix.Dep.load_on_environment(env: Mix.env())
|> Enum.find(%{}, &(&1.app == app))
|> Map.get(:opts, [])
|> Keyword.get(:nerves, [])
%__MODULE__{
app: app,
type: type,
env: env,
platform: platform,
build_runner: build_runner,
compilers: compilers,
dep_opts: dep_opts,
dep: dep_type(app),
path: path,
version: version,
config: config
}
end
@doc """
Starts an interactive shell with the working directory set
to the package path
"""
@spec shell(Nerves.Package.t() | nil) :: :ok
def shell(nil) do
Mix.raise("Package is not loaded in your Nerves Environment.")
end
def shell(%{platform: nil, app: app}) do
Mix.raise("Cannot start shell for #{app}")
end
def shell(pkg) do
pkg.build_runner.shell(pkg)
end
@doc """
Takes the path to the package and returns the path to its package config.
"""
@spec config_path(String.t()) :: String.t()
def config_path(path) do
Path.join(path, @package_config)
end
@doc """
Get Mix.Project config for an application
"""
@spec config(Application.app(), Path.t()) :: Keyword.t()
def config(app, path) do
project_config =
if app == Mix.Project.config()[:app] do
Mix.Project.config()
else
Mix.Project.in_project(app, path, fn _mod ->
Mix.Project.config()
end)
end
nerves_package =
case project_config[:nerves_package] do
nil ->
# TODO: Deprecated. Clean up after 1.0
Mix.shell().raise("""
Nerves configuration has moved from nerves.exs to mix.exs.
Use `mix nerves.new` to regenerate your project's mix.exs and merge
your code into the new project.
""")
nerves_package ->
nerves_package
end
Keyword.put(project_config, :nerves_package, nerves_package)
end
defp dep_type(pkg) do
deps_paths = Mix.Project.deps_paths()
case Map.get(deps_paths, pkg) do
nil ->
:project
path ->
deps_path =
File.cwd!()
|> Path.join(Mix.Project.config()[:deps_path])
|> Path.expand()
if String.starts_with?(path, deps_path) do
:hex
else
:path
end
end
end
end