@@ -36,6 +36,8 @@ defmodule Mix.Project do
3636 end
3737 end
3838
39+ @ private_config [ :build_path , :app_path ]
40+
3941 # Invoked after each Mix.Project is compiled.
4042 @ doc false
4143 def __after_compile__ ( env , _binary ) do
@@ -46,7 +48,10 @@ defmodule Mix.Project do
4648 # the top of the stack can be accessed.
4749 @ doc false
4850 def push ( atom , file // "nofile" ) when is_atom ( atom ) do
49- config = Keyword . merge default_config , get_project_config ( atom )
51+ config = default_config
52+ |> Keyword . merge ( get_project_config ( atom ) )
53+ |> Keyword . drop ( @ private_config )
54+
5055 case Mix.ProjectStack . push ( atom , config , file ) do
5156 :ok ->
5257 :ok
@@ -62,6 +67,14 @@ defmodule Mix.Project do
6267 Mix.ProjectStack . pop
6368 end
6469
70+ # The configuration that is pushed down to dependencies.
71+ @ doc false
72+ def deps_config ( config // config ( ) ) do
73+ [ build_path: build_path ( config ) ,
74+ deps_path: deps_path ( config ) ,
75+ lockfile: Path . expand ( config [ :lockfile ] ) ]
76+ end
77+
6578 @ doc """
6679 Retrieves the current project, `nil` if there is no
6780 current project (i.e. there is no mixfile in the current
@@ -93,6 +106,7 @@ defmodule Mix.Project do
93106
94107 @ doc """
95108 Returns the project configuration for the current environment.
109+ This configuration is cached once the project is pushed into the stack.
96110 """
97111 def config do
98112 case Mix.ProjectStack . peek do
@@ -102,14 +116,16 @@ defmodule Mix.Project do
102116 end
103117
104118 @ doc """
105- Returns a list of project configuration files, for example,
106- `mix.exs` and `mix.lock`. This function is usually used
107- in compilation tasks to trigger a full recompilation
108- whenever such configuration files change.
119+ Returns a list of project configuration files as known by
120+ this project. This function is usually used in compilation
121+ tasks to trigger a full recompilation whenever such
122+ configuration files change.
123+
124+ By default it includes the mix.exs file and the lock manifest.
109125 """
110126 def config_files do
111- project = get
112- opts = [ Mix.Deps.Lock . manifest ]
127+ project = get
128+ opts = [ Mix.Deps.Lock . manifest ]
113129
114130 if project && ( source = project . __info__ ( :compile ) [ :source ] ) do
115131 opts = [ String . from_char_list! ( source ) | opts ]
@@ -149,16 +165,82 @@ defmodule Mix.Project do
149165 end
150166
151167 @ doc """
152- Returns the paths this project compiles to,
153- collecting all `:compile_path` in case of umbrella apps.
168+ Returns the path to store dependencies for this project.
169+ The returned path will be expanded.
170+
171+ ## Examples
172+
173+ Mix.Project.deps_path
174+ #=> "/path/to/project/deps"
175+
176+ """
177+ def deps_path ( config // config ( ) ) do
178+ Path . expand config [ :deps_path ]
179+ end
180+
181+ @ doc """
182+ Returns the build path for this project.
183+ The returned path will be expanded.
184+
185+ ## Examples
186+
187+ Mix.Project.build_path
188+ #=> "/path/to/project/_build"
189+
190+ """
191+ def build_path ( config // config ( ) ) do
192+ config [ :build_path ] || Path . expand ( "_build" )
193+ end
194+
195+ @ doc """
196+ Returns the library path inside the build.
197+ The returned path will be expanded.
198+
199+ ## Examples
200+
201+ Mix.Project.app_path
202+ #=> "/path/to/project/_build/lib/app"
203+
204+ """
205+ def app_path ( config // config ( ) ) do
206+ config [ :app_path ] || if app = config [ :app ] do
207+ Path . join ( [ build_path ( config ) , "lib" , app ] )
208+ else
209+ raise Mix.Error , message: "Cannot access build without an application name, " <>
210+ "please ensure you are in a directory with a mix.exs file and it defines " <>
211+ "an :app name under the project configuration"
212+ end
213+ end
214+
215+ @ doc """
216+ Returns the paths this project compiles to.
217+ The returned path will be expanded.
218+
219+ ## Examples
220+
221+ Mix.Project.compile_path
222+ #=> "/path/to/project/_build/lib/app/priv"
223+
154224 """
155225 def compile_path ( config // config ( ) ) do
156- unless config [ :app ] do
157- raise Mix.Error , message: "Cannot access compilation path without an application name, " <>
158- "please ensure you are in a directory with a mix.exs file and it defines an :app " <>
159- "name under the project configuration"
226+ Path . join ( app_path ( config ) , "ebin" )
227+ end
228+
229+ @ doc """
230+ Builds the project structure for the current application.
231+ """
232+ def build_structure ( config // config ( ) ) do
233+ ebin = compile_path ( config )
234+ File . mkdir_p! ( ebin )
235+
236+ lib = Path . dirname ( ebin )
237+ old = Path . expand ( "priv" )
238+
239+ case :file . make_symlink ( old , Path . join ( lib , "priv" ) ) do
240+ :ok -> :ok
241+ { :error , :eexist } -> :ok
242+ { :error , _ } -> File . cp_r! ( old , lib ) |> IO . inspect
160243 end
161- Path . expand "ebin"
162244 end
163245
164246 @ doc """
0 commit comments