Repository: phoenixframework/phoenix
Pull request #4463 (2021-09-06 14:36:10)

Remove comma on generated form.html.heex
After converting the template from .eex to .heex on https://github.com/phoenixframework/phoenix/commit/12f4116e299b43bec9c74a379d8de55b0a13262c, a comma was left behind.

```diff
-<.form let={f} for={@changeset}, action={@action}>
+<.form let={f} for={@changeset} action={@action}>
```

Thanks for making it so easy to contribute in this project. Just doing `mix deps.get` and `mix test` was enough to start.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 920b27910..bbf6e6d4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@ Phoenix v1.6 requires Elixir v1.9+.
 ### Enhancements
   * [mix phx.gen.auth] Validate bcrypt passwords are no longer than 72 bytes
   * re-enable `phx.routes` task to support back to back invocations, such as for aliased mix route tasks
+  * [mix phx.gen.html] Remove comma after `for={@changeset}` on `form.html.heex`
 
 ## 1.6.0-rc.0 (2021-08-26)
 
diff --git a/guides/contexts.md b/guides/contexts.md
index 27d5639dd..2b01b5935 100644
--- a/guides/contexts.md
+++ b/guides/contexts.md
@@ -277,7 +277,7 @@ Let's think of a function describes what we want to accomplish. Here's how we wo
 
 That looks great. Our callers will have no confusion over what this function does, and we can wrap up the increment in an atomic operation to prevent race conditions.
 
-Open up your CMS context (`lib/hello/catalog.ex`), and add this new function:
+Open up your catalog context (`lib/hello/catalog.ex`), and add this new function:
 
 ```elixir
   def inc_page_views(%Product{} = product) do
@@ -401,7 +401,7 @@ $ mix ecto.migrate
 Now that we have a `Catalog.Product` schema and a join table to associate products and categories, we're nearly ready to start wiring up our new features. Before we dive in, we first need real categories to select in our web UI. Let's quickly seed some new categories in the application. Add the following code to your seeds file in `priv/repo/seeds.exs`:
 
 ```elixir
-for title <- ["Fashion", "Power Tools", "Gardening", "Books", "Education"] do
+for title <- ["Home Improvement", "Power Tools", "Gardening", "Books"] do
   {:ok, _} = Hello.Catalog.create_category(%{title: title})
 end
 ```
diff --git a/lib/phoenix/digester.ex b/lib/phoenix/digester.ex
index 27727c197..b06c08e9d 100644
--- a/lib/phoenix/digester.ex
+++ b/lib/phoenix/digester.ex
@@ -83,15 +83,21 @@ defmodule Phoenix.Digester do
     write_manifest(latest, digests, output_path)
   end
 
+  @comment "This is file was auto-generated by `mix phx.digest`. Remove it and all generated artefacts with `mix phx.digest.clean --all`"
+
   defp write_manifest(latest, digests, output_path) do
-    json = %{
-      "latest" => latest,
-      "version" => @manifest_version,
-      "digests" => digests
+    encoder = Phoenix.json_library()
+
+    json = """
+    {
+      "!comment!":#{encoder.encode!(@comment)},
+      "version":#{encoder.encode!(@manifest_version)},
+      "latest":#{encoder.encode!(latest)},
+      "digests":#{encoder.encode!(digests)}
     }
+    """
 
-    manifest_content = Phoenix.json_library().encode!(json)
-    File.write!(Path.join(output_path, "cache_manifest.json"), manifest_content)
+    File.write!(Path.join(output_path, "cache_manifest.json"), json)
   end
 
   defp remove_manifest(output_path) do
@@ -123,7 +129,7 @@ defmodule Phoenix.Digester do
 
   defp compiled_file?(file_path) do
     compressors = Application.fetch_env!(:phoenix, :static_compressors)
-    compressed_extensions = Enum.flat_map(compressors, &(&1.file_extensions))
+    compressed_extensions = Enum.flat_map(compressors, & &1.file_extensions)
 
     Regex.match?(@digested_file_regex, Path.basename(file_path)) ||
       Path.extname(file_path) in compressed_extensions ||
@@ -157,10 +163,11 @@ defmodule Phoenix.Digester do
 
     compressors = Application.fetch_env!(:phoenix, :static_compressors)
 
-    Enum.each(compressors, fn(compressor) ->
+    Enum.each(compressors, fn compressor ->
       [file_extension | _] = compressor.file_extensions
 
-      with {:ok, compressed_digested} <- compressor.compress_file(file.digested_filename, file.digested_content) do
+      with {:ok, compressed_digested} <-
+             compressor.compress_file(file.digested_filename, file.digested_content) do
         File.write!(
           Path.join(path, file.digested_filename <> file_extension),
           compressed_digested
@@ -203,7 +210,8 @@ defmodule Phoenix.Digester do
     Regex.replace(@stylesheet_url_regex, file.content, fn _, open, url, close ->
       case Regex.run(@quoted_text_regex, url) do
         [_, quote_symbol, url] ->
-          open <> quote_symbol <> digested_url(url, file, latest, with_vsn?) <> quote_symbol <> close
+          open <>
+            quote_symbol <> digested_url(url, file, latest, with_vsn?) <> quote_symbol <> close
 
         nil ->
           open <> digested_url(url, file, latest, with_vsn?) <> close
diff --git a/priv/templates/phx.gen.html/form.html.heex b/priv/templates/phx.gen.html/form.html.heex
index c4cbb9a15..f0dfb8627 100644
--- a/priv/templates/phx.gen.html/form.html.heex
+++ b/priv/templates/phx.gen.html/form.html.heex
@@ -1,4 +1,4 @@
-<.form let={f} for={@changeset}, action={@action}>
+<.form let={f} for={@changeset} action={@action}>
   <%%= if @changeset.action do %>
     <div class="alert alert-danger">
       <p>Oops, something went wrong! Please check the errors below.</p>


Test patch:
diff --git a/test/mix/tasks/phx.gen.html_test.exs b/test/mix/tasks/phx.gen.html_test.exs
index 4b0a9cb8a..71b3511f1 100644
--- a/test/mix/tasks/phx.gen.html_test.exs
+++ b/test/mix/tasks/phx.gen.html_test.exs
@@ -132,6 +132,7 @@ defmodule Mix.Tasks.Phx.Gen.HtmlTest do
       end
 
       assert_file "lib/phoenix_web/templates/post/form.html.heex", fn file ->
+        assert file =~ ~s(<.form let={f} for={@changeset} action={@action}>)
         assert file =~ ~s(<%= text_input f, :title %>)
         assert file =~ ~s(<%= number_input f, :votes %>)
         assert file =~ ~s(<%= number_input f, :cost, step: "any" %>)