Skip to content

Commit 520415b

Browse files
committed
Dont run any tasks recursively from another task
The only time a task may run recursively is after a new project has been pushed to the stack.
1 parent 98ade3b commit 520415b

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

lib/mix/lib/mix/server.ex

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ defmodule Mix.Server do
55
use GenServer.Behaviour
66

77
defrecord Config, tasks: Ordset.new, projects: [], mixfile: [],
8-
shell: Mix.Shell.IO, scm: Ordset.new, env: nil, post_config: [],
9-
io_done: false
8+
shell: Mix.Shell.IO, scm: Ordset.new, env: nil, post_config: []
109

11-
defrecord Project, name: nil, config: nil
10+
defrecord Project, name: nil, config: nil, rec_enabled?: true, io_done: false
1211

1312
def start_link(env) do
1413
:gen_server.start_link({ :local, __MODULE__ }, __MODULE__, env, [])
@@ -59,7 +58,7 @@ defmodule Mix.Server do
5958
def handle_call(:pop_project, _from, config) do
6059
case config.projects do
6160
[ Project[name: project] | tail ] ->
62-
{ :reply, project, config.projects(tail).io_done(false) }
61+
{ :reply, project, config.projects(tail) }
6362
_ ->
6463
{ :reply, nil, config }
6564
end
@@ -69,15 +68,25 @@ defmodule Mix.Server do
6968
{ :reply, config.mixfile[app], config }
7069
end
7170

72-
def handle_call(:io_done, _from, config) do
73-
{ :reply, config.io_done, config.io_done(true) }
74-
end
75-
7671
def handle_call(:output_app?, _from, config) do
7772
# Check that we haven't already outputted app and that we are part of an
7873
# umbrella project
79-
output = not config.io_done and not umbrella?(config) and in_umbrella?(config)
80-
{ :reply, output, config.io_done(true) }
74+
case config.projects do
75+
[ project | tail ] ->
76+
output = not project.io_done and not umbrella?(config) and in_umbrella?(config)
77+
{ :reply, output, config.projects([project.io_done(true)|tail]) }
78+
_ ->
79+
{ :reply, false, config }
80+
end
81+
end
82+
83+
def handle_call(:recursive_enabled?, _from, config) do
84+
case config.projects do
85+
[ Project[rec_enabled?: bool] | _ ] ->
86+
{ :reply, bool, config }
87+
_ ->
88+
{ :reply, true, config }
89+
end
8190
end
8291

8392
def handle_call(request, from, config) do
@@ -113,7 +122,6 @@ defmodule Mix.Server do
113122
project = Project[name: name, config: conf]
114123
config = config.post_config([])
115124
.update_projects([project|&1])
116-
.io_done(false)
117125
{ :noreply, config }
118126
end
119127

@@ -133,18 +141,27 @@ defmodule Mix.Server do
133141
{ :noreply, config.mixfile([]) }
134142
end
135143

144+
def handle_cast({:recursive_enabled?, bool}, config) do
145+
case config.projects do
146+
[ project | tail ] ->
147+
{ :noreply, config.projects([project.rec_enabled?(bool)|tail]) }
148+
_ ->
149+
{ :noreply, config }
150+
end
151+
end
152+
136153
def handle_cast(request, config) do
137154
super(request, config)
138155
end
139156

140-
# Returns if project is part of an umbrella project
157+
# Returns true if project is part of an umbrella project
141158
defp in_umbrella?(config) do
142159
Enum.any?(config.projects, fn(Project[config: conf]) ->
143160
conf[:apps_path] != nil
144161
end)
145162
end
146163

147-
# Returns if project is an umbrella project
164+
# Returns true if project is an umbrella project
148165
defp umbrella?(config) do
149166
case config.projects do
150167
[ Project[name: name, config: config] | _ ] when name != nil ->

lib/mix/lib/mix/task.ex

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,16 @@ defmodule Mix.Task do
141141

142142
recursive = recursive(module)
143143

144-
if recursive do
144+
if recursive && Mix.Server.call(:recursive_enabled?) do
145+
Mix.Server.cast({ :recursive_enabled?, false })
145146
res = if Mix.Project.umbrella? and recursive == :both do
146147
[module.run(args)]
147148
else
148149
[]
149150
end
150-
res ++ Mix.Project.recur(fn _ -> module.run(args) end)
151+
res = res ++ Mix.Project.recur(fn _ -> module.run(args) end)
152+
Mix.Server.cast({ :recursive_enabled?, true })
153+
res
151154
else
152155
module.run(args)
153156
end

0 commit comments

Comments
 (0)