Skip to content

Commit 656eec3

Browse files
committed
remove phoenix mix task deps
1 parent 637a1ee commit 656eec3

File tree

26 files changed

+1146
-133
lines changed

26 files changed

+1146
-133
lines changed

e2e/assets/corex/components/toast.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@
7171
min-height: var(--spacing-mini-sm);
7272
right: var(--spacing-mini-gap);
7373
top: var(--spacing-ui-gap-sm);
74+
color: var(--color-layer--text);
75+
background-color: transparent;
76+
border-color: transparent;
77+
}
78+
79+
.toast [data-scope="toast"][data-part="close-trigger"]:hover {
80+
background-color: --alpha(var(--color-layer--text) / 0.12);
81+
}
82+
83+
.toast [data-scope="toast"][data-part="close-trigger"]:active {
84+
background-color: --alpha(var(--color-layer--text) / 0.2);
85+
}
86+
87+
.toast [data-scope="toast"][data-part="close-trigger"]:focus-visible {
88+
box-shadow: inset 0 0 0 2px var(--color-layer--text);
7489
}
7590

7691
.toast [data-scope="toast"][data-part="root"][data-type="error"] [data-scope="toast"][data-part="title"] {

e2e/lib/e2e_web/controllers/page_html/home.html.heex

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,21 @@
1717
</h1>
1818

1919
<p class="md:text-ui-lg my-0">
20-
From design tokens to accessible, interactive components, <br />
21-
Corex provides a complete foundation for creating <br />
20+
From design tokens to interactive components, <br />
21+
Corex provides unstyled components for creating <br />
2222
beautiful, scalable, and performant websites.
2323
</p>
2424
<div class="gap-ui-gap p-ui-padding flex flex-wrap justify-start">
25+
<.navigate
26+
to={~p"/#{@locale}/accordion"}
27+
class="button button--brand button--sm md:button--md w-full md:w-auto hidden lg:flex"
28+
>
29+
Examples <.heroicon name="hero-arrow-right" />
30+
</.navigate>
2531
<.navigate
2632
to="https://hexdocs.pm/corex"
2733
external
28-
class="button button--brand button--sm md:button--md w-full md:w-auto"
34+
class="button button--sm md:button--md w-full md:w-auto"
2935
>
3036
Hex Documentation <.heroicon name="hero-arrow-top-right-on-square" />
3137
</.navigate>
@@ -42,12 +48,6 @@
4248
>
4349
Captures <.heroicon name="hero-arrow-top-right-on-square" />
4450
</.navigate>
45-
<.navigate
46-
to={~p"/#{@locale}/accordion"}
47-
class="button button--sm md:button--md w-full md:w-auto hidden lg:flex"
48-
>
49-
Examples <.heroicon name="hero-arrow-right" />
50-
</.navigate>
5151
</div>
5252
</section>
5353
</Layouts.app>

installer/templates/corex_web/router.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ defmodule <%= @web_namespace %>.Router do
3434
on_mount: [<%= Enum.join(@on_mount_hooks, ", ") %>] do
3535
live "/live", ExampleLive
3636
end
37-
<% else %> live "/live", ExampleLive
37+
<% else %> live "/live", ExampleLive
3838
<% end %> end
3939
<% else %>
4040
scope "/", <%= @web_namespace %> do
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
defmodule Corex.Integration.CodeGeneration.FullStackWithOptionsTest do
2+
use Corex.Integration.CodeGeneratorCase, async: true
3+
4+
@rich_attrs ~w(name:string age:integer score:float balance:decimal active:boolean bio:text birth_date:date start_time:time published_at:utc_datetime drafted_at:naive_datetime tags:array:string status:enum:draft:published:archived)
5+
6+
describe "full stack with heavy options and locale" do
7+
@tag database: :postgresql
8+
test "corex.new with --lang en:fr --mode --theme neo:uno:duo:leo --dev --live, then corex.gen.live and corex.gen.html with rich attrs, compiles formats and tests pass" do
9+
with_installer_tmp("full_stack_locale", fn tmp_dir ->
10+
{app_root_path, _} =
11+
generate_corex_app(tmp_dir, "full_app", [
12+
"--lang", "en:fr",
13+
"--mode",
14+
"--theme", "neo:uno:duo:leo",
15+
"--dev",
16+
"--live"
17+
])
18+
19+
router_path = Path.join(app_root_path, "lib/full_app_web/router.ex")
20+
21+
mix_run!(
22+
["corex.gen.live", "Admin", "admins" | @rich_attrs],
23+
app_root_path
24+
)
25+
26+
mix_run!(
27+
["corex.gen.html", "User", "users" | @rich_attrs],
28+
app_root_path
29+
)
30+
31+
live_routes =
32+
"""
33+
live "/admins", AdminLive.Index, :index
34+
live "/admins/new", AdminLive.Form, :new
35+
live "/admins/:id", AdminLive.Show, :show
36+
live "/admins/:id/edit", AdminLive.Form, :edit
37+
"""
38+
|> String.replace(~r/^ /m, " ")
39+
40+
inject_live_routes(router_path, live_routes, locale_scope: true)
41+
42+
resources_routes = " resources \"/users\", UserController\n"
43+
inject_resources(router_path, resources_routes, locale_scope: true)
44+
45+
assert_no_compilation_warnings(app_root_path)
46+
assert_passes_formatter_check(app_root_path)
47+
drop_test_database(app_root_path)
48+
assert_tests_pass(app_root_path)
49+
end)
50+
end
51+
end
52+
53+
describe "full stack with rich attrs without locale" do
54+
@tag database: :postgresql
55+
test "corex.new with --live, then corex.gen.live and corex.gen.html with rich attrs, compiles formats and tests pass" do
56+
with_installer_tmp("full_stack_no_locale", fn tmp_dir ->
57+
{app_root_path, _} = generate_corex_app(tmp_dir, "phx_blog", ["--live"])
58+
router_path = Path.join(app_root_path, "lib/phx_blog_web/router.ex")
59+
60+
mix_run!(
61+
["corex.gen.live", "Admin", "admins" | @rich_attrs],
62+
app_root_path
63+
)
64+
65+
mix_run!(
66+
["corex.gen.html", "User", "users" | @rich_attrs],
67+
app_root_path
68+
)
69+
70+
modify_file(router_path, fn file ->
71+
inject_before_final_end(file, """
72+
73+
scope "/", PhxBlogWeb do
74+
pipe_through [:browser]
75+
76+
resources "/users", UserController
77+
end
78+
79+
scope "/", PhxBlogWeb do
80+
pipe_through [:browser]
81+
82+
live "/admins", AdminLive.Index, :index
83+
live "/admins/new", AdminLive.Form, :new
84+
live "/admins/:id", AdminLive.Show, :show
85+
live "/admins/:id/edit", AdminLive.Form, :edit
86+
end
87+
""")
88+
end)
89+
90+
assert_no_compilation_warnings(app_root_path)
91+
assert_passes_formatter_check(app_root_path)
92+
drop_test_database(app_root_path)
93+
assert_tests_pass(app_root_path)
94+
end)
95+
end
96+
end
97+
end

integration_test/test/support/code_generator_case.ex

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,49 @@ defmodule Corex.Integration.CodeGeneratorCase do
137137
|> Kernel.<>("end\n")
138138
end
139139

140+
def inject_live_routes(router_path, live_routes, opts \\ []) do
141+
content = File.read!(router_path)
142+
143+
if Keyword.get(opts, :locale_scope) do
144+
pattern = "live \"/live\", ExampleLive\n"
145+
new_content = String.replace(content, pattern, pattern <> live_routes, global: false)
146+
File.write!(router_path, new_content)
147+
else
148+
new_content = inject_before_final_end(content, live_routes)
149+
File.write!(router_path, new_content)
150+
end
151+
end
152+
153+
def inject_resources(router_path, resources_routes, opts \\ []) do
154+
content = File.read!(router_path)
155+
156+
if Keyword.get(opts, :locale_scope) do
157+
parts = String.split(content, ~r/scope "\/:locale"/, parts: 2)
158+
159+
if length(parts) == 2 do
160+
[head, locale_block] = parts
161+
get_pattern = "get \"/\", PageController, :home\n"
162+
locale_parts = String.split(locale_block, get_pattern, parts: 2)
163+
164+
if length(locale_parts) == 2 do
165+
[before_get, after_get] = locale_parts
166+
new_locale_block = before_get <> get_pattern <> resources_routes <> after_get
167+
new_content = head <> "scope \"/:locale\"" <> new_locale_block
168+
File.write!(router_path, new_content)
169+
else
170+
new_content = inject_before_final_end(content, resources_routes)
171+
File.write!(router_path, new_content)
172+
end
173+
else
174+
new_content = inject_before_final_end(content, resources_routes)
175+
File.write!(router_path, new_content)
176+
end
177+
else
178+
new_content = inject_before_final_end(content, resources_routes)
179+
File.write!(router_path, new_content)
180+
end
181+
end
182+
140183
def modify_file(path, function) when is_binary(path) and is_function(function, 1) do
141184
path
142185
|> File.read!()

lib/mix/corex.ex

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,37 @@ defmodule Mix.Corex do
1919
EEx.eval_string(content, binding)
2020
end
2121

22+
def eval_from_roots(roots, relative_path, binding) when is_list(roots) do
23+
path =
24+
Enum.find_value(roots, fn root ->
25+
full = Path.join(root, relative_path)
26+
if File.exists?(full), do: full
27+
end) || raise "could not find #{relative_path} in any of the template roots"
28+
29+
content = File.read!(path)
30+
EEx.eval_string(content, binding)
31+
end
32+
33+
def inject_eex_before_final_end(content_to_inject, file_path, binding) do
34+
file = File.read!(file_path)
35+
36+
if String.contains?(file, content_to_inject) do
37+
:ok
38+
else
39+
Mix.shell().info([:green, "* injecting ", :reset, Path.relative_to_cwd(file_path)])
40+
41+
new_content =
42+
file
43+
|> String.trim_trailing()
44+
|> String.trim_trailing("end")
45+
|> EEx.eval_string(binding)
46+
|> Kernel.<>(content_to_inject)
47+
|> Kernel.<>("end\n")
48+
49+
File.write!(file_path, new_content)
50+
end
51+
end
52+
2253
@doc """
2354
Copies files from source dir to target dir
2455
according to the given map.
@@ -27,7 +58,12 @@ defmodule Mix.Corex do
2758
the given binding.
2859
"""
2960
def copy_from(apps, source_dir, binding, mapping) when is_list(mapping) do
30-
roots = Enum.map(apps, &to_app_source(&1, source_dir))
61+
roots =
62+
if source_dir == "" do
63+
apps
64+
else
65+
Enum.map(apps, &to_app_source(&1, source_dir))
66+
end
3167

3268
binding =
3369
Keyword.merge(binding,
@@ -199,6 +235,30 @@ defmodule Mix.Corex do
199235
[".", :corex]
200236
end
201237

238+
@doc """
239+
Returns the list of template directory paths for a Corex generator, in lookup order.
240+
241+
Used when copying generator files so that the project can override templates
242+
without editing Corex's priv. Order:
243+
244+
1. `priv/corex_templates/<generator_name>` in the current project
245+
2. `priv/templates/<generator_name>` in the current project
246+
3. Corex's `priv/templates/<generator_name>`
247+
248+
Pass the result to `copy_from/4` with `source_dir` set to `""` so files
249+
are resolved under each directory.
250+
"""
251+
def generator_template_dirs(generator_name) do
252+
cwd = File.cwd!()
253+
corex_priv = Application.app_dir(:corex, "priv/templates")
254+
255+
[
256+
Path.join([cwd, "priv", "corex_templates", generator_name]),
257+
Path.join([cwd, "priv", "templates", generator_name]),
258+
Path.join(corex_priv, generator_name)
259+
]
260+
end
261+
202262
@doc """
203263
Checks if the given `app_path` is inside an umbrella.
204264
"""

0 commit comments

Comments
 (0)