@@ -79,24 +79,60 @@ defmodule Igniter.Project.Application do
79
79
end
80
80
end
81
81
82
- @ doc "Adds a new child to the `children` list in the application file"
83
- @ spec add_new_child ( Igniter . t ( ) , module ( ) | { module , term ( ) } ) :: Igniter . t ( )
84
- def add_new_child ( igniter , to_supervise ) do
82
+ @ doc """
83
+ Adds a new child to the `children` list in the application file
84
+
85
+ To pass quoted code as the options, use the following format:
86
+
87
+ {module, {:code, quoted_code}}
88
+
89
+ i.e
90
+
91
+ {MyApp.Supervisor, {:code, quote do
92
+ Application.fetch_env!(:app, :config)
93
+ end}}
94
+
95
+ ## Options
96
+
97
+ - `after` - A list of other modules that this supervisor should appear after,
98
+ or a function that takes a module and returns `true` if this module should be placed after it.
99
+
100
+ ## Ordering
101
+
102
+ We will put the new child as the earliest item in the list that we can, skipping any modules
103
+ in `after`.
104
+ """
105
+ @ spec add_new_child (
106
+ Igniter . t ( ) ,
107
+ module ( ) | { module , { :code , term ( ) } } | { module , term ( ) } ,
108
+ opts :: Keyword . t ( )
109
+ ) ::
110
+ Igniter . t ( )
111
+ def add_new_child ( igniter , to_supervise , opts \\ [ ] ) do
85
112
to_perform =
86
113
case app_module ( igniter ) do
87
114
nil -> { :create_an_app , Igniter.Code.Module . module_name ( igniter , "Application" ) }
88
115
{ mod , _ } -> { :modify , mod }
89
116
mod -> { :modify , mod }
90
117
end
91
118
119
+ opts =
120
+ Keyword . update ( opts , :after , fn _ -> false end , fn list ->
121
+ if is_list ( list ) do
122
+ fn item -> item in list end
123
+ else
124
+ list
125
+ end
126
+ end )
127
+
92
128
case to_perform do
93
129
{ :create_an_app , mod } ->
94
130
igniter
95
131
|> create_app ( mod )
96
- |> do_add_child ( mod , to_supervise )
132
+ |> do_add_child ( mod , to_supervise , opts )
97
133
98
134
{ :modify , mod } ->
99
- do_add_child ( igniter , mod , to_supervise )
135
+ do_add_child ( igniter , mod , to_supervise , opts )
100
136
end
101
137
end
102
138
@@ -106,25 +142,20 @@ defmodule Igniter.Project.Application do
106
142
|> create_application_file ( application )
107
143
end
108
144
109
- def do_add_child ( igniter , application , to_supervise ) do
145
+ def do_add_child ( igniter , application , to_supervise , opts ) do
110
146
path = Igniter.Code.Module . proper_location ( application )
111
147
112
- diff_checker =
148
+ to_supervise =
113
149
case to_supervise do
114
- v when is_atom ( v ) ->
115
- & Common . nodes_equal? / 2
116
-
117
- { v , _opts } when is_atom ( v ) ->
118
- fn
119
- { item , _ } , { right , _ } ->
120
- Common . nodes_equal? ( item , right )
121
-
122
- item , { right , _ } ->
123
- Common . nodes_equal? ( item , right )
150
+ module when is_atom ( module ) -> module
151
+ { module , { :code , contents } } when is_atom ( module ) -> { module , contents }
152
+ { module , contents } -> { module , Macro . escape ( contents ) }
153
+ end
124
154
125
- _ , _ ->
126
- false
127
- end
155
+ to_supervise_module =
156
+ case to_supervise do
157
+ { module , _ } -> module
158
+ module -> module
128
159
end
129
160
130
161
Igniter . update_elixir_file ( igniter , path , fn zipper ->
@@ -143,11 +174,35 @@ defmodule Igniter.Project.Application do
143
174
) &&
144
175
Igniter.Code.Function . argument_matches_pattern? ( call , 1 , v when is_list ( v ) )
145
176
end
146
- ) do
147
- zipper
148
- |> Zipper . down ( )
149
- |> Zipper . rightmost ( )
150
- |> Igniter.Code.List . append_new_to_list ( Macro . escape ( to_supervise ) , diff_checker )
177
+ ) ,
178
+ { :ok , zipper } <- Igniter.Code.Function . move_to_nth_argument ( zipper , 1 ) do
179
+ if Igniter.Code.List . find_list_item_index ( zipper , fn item ->
180
+ if Igniter.Code.Tuple . tuple? ( item ) do
181
+ with { :ok , zipper } <- Igniter.Code.Tuple . tuple_elem ( zipper , 0 ) ,
182
+ zipper <- Igniter.Code.Common . expand_alias ( zipper ) ,
183
+ module when is_atom ( module ) <- zipper . node do
184
+ module == to_supervise_module
185
+ else
186
+ _ -> false
187
+ end
188
+ else
189
+ with zipper <- Igniter.Code.Common . expand_alias ( zipper ) ,
190
+ module when is_atom ( module ) <- zipper . node do
191
+ module == to_supervise_module
192
+ else
193
+ _ -> false
194
+ end
195
+ end
196
+ end ) do
197
+ { :ok , zipper }
198
+ else
199
+ zipper
200
+ |> Zipper . down ( )
201
+ |> skip_after ( opts )
202
+ |> Zipper . insert_child ( to_supervise )
203
+
204
+ # |> Igniter.Code.Common.insert_child(to_supervise)
205
+ end
151
206
else
152
207
_ ->
153
208
{ :warning ,
@@ -159,6 +214,28 @@ defmodule Igniter.Project.Application do
159
214
end )
160
215
end
161
216
217
+ def skip_after ( zipper , opts ) do
218
+ Igniter.Code.Common . move_right ( zipper , fn item ->
219
+ with true <- Igniter.Code.Tuple . tuple? ( item ) ,
220
+ { :ok , zipper } <- Igniter.Code.Tuple . tuple_elem ( zipper , 0 ) ,
221
+ zipper <- Igniter.Code.Common . expand_alias ( zipper ) ,
222
+ module when is_atom ( module ) <- zipper . node ,
223
+ true <- opts [ :after ] . ( module ) do
224
+ true
225
+ else
226
+ _ ->
227
+ false
228
+ end
229
+ end )
230
+ |> case do
231
+ { :ok , zipper } ->
232
+ skip_after ( zipper , opts )
233
+
234
+ :error ->
235
+ zipper
236
+ end
237
+ end
238
+
162
239
def create_application_file ( igniter , application ) do
163
240
path = Igniter.Code.Module . proper_location ( application )
164
241
supervisor = Igniter.Code.Module . module_name ( igniter , "Supervisor" )
@@ -189,9 +266,14 @@ defmodule Igniter.Project.Application do
189
266
case Igniter.Code.Function . move_to_def ( zipper , :application , 0 ) do
190
267
{ :ok , zipper } ->
191
268
zipper
192
- |> Zipper . rightmost ( )
269
+ |> Igniter.Code.Common . rightmost ( )
193
270
|> Igniter.Code.Keyword . set_keyword_key ( :mod , { application , [ ] } , fn z ->
194
- { :ok , Common . replace_code ( z , { application , [ ] } ) }
271
+ code =
272
+ { application , [ ] }
273
+ |> Sourceror . to_string ( )
274
+ |> Sourceror . parse_string! ( )
275
+
276
+ { :ok , Common . replace_code ( z , code ) }
195
277
end )
196
278
197
279
_ ->
0 commit comments