From 67fa0be17061484fcc21389e2d1fd26d2bdee214 Mon Sep 17 00:00:00 2001 From: Rodolfo Carvalho Date: Sun, 2 Aug 2026 21:15:57 +0200 Subject: [PATCH] Ensure single trailing newline in source files Reduce future code churn by gating source files with a test that ensures tracked text files in the repository end with a single trailing newline (UNIX convention). Alternatives to enforce this without a test: An .editorconfig file at the root of the repository makes most editors automatically insert a final newline and trim trailing whitespace on save, preventing the problem at the source: root = true [*] insert_final_newline = true trim_trailing_whitespace = true end_of_line = lf charset = utf-8 A .gitattributes file makes Git itself flag whitespace issues in diffs, on apply, and on merge: * text=auto eol=lf whitespace=blank-at-eol,blank-at-eof Both files support per-path exceptions. In .editorconfig, a section like [*.png] can override any setting. In .gitattributes, paths can opt out with -whitespace or be marked as binary (e.g. "*.png binary"). --- .github/ISSUE_TEMPLATE/bug_report.md | 3 +++ test/phoenix/source_files_test.exs | 36 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 test/phoenix/source_files_test.exs diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6c01ae8ea9..8008265178 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,3 +24,6 @@ https://github.com/wojtekmach/mix_install_examples/blob/main/phoenix.exs ### Expected behavior + diff --git a/test/phoenix/source_files_test.exs b/test/phoenix/source_files_test.exs new file mode 100644 index 0000000000..bf71b64ade --- /dev/null +++ b/test/phoenix/source_files_test.exs @@ -0,0 +1,36 @@ +defmodule Phoenix.SourceFilesTest do + use ExUnit.Case, async: true + + @repo_root Path.expand("../..", __DIR__) + @git_repo? File.dir?(Path.join(@repo_root, ".git")) and System.find_executable("git") != nil + @excluded_exts ~w(.br .foo .gz .ico .lock .map .pem .png) + @excluded_files ~w(test/fixtures/hello.txt) + + @tag skip: if(not @git_repo?, do: "git or .git repository not available") + test "all tracked text files in the repository end with a single newline" do + {output, 0} = System.cmd("git", ["ls-files", "-z"], cd: @repo_root) + + target_files = + output + |> String.split("\0", trim: true) + |> Enum.reject(fn file -> + file in @excluded_files or Enum.any?(@excluded_exts, &String.ends_with?(file, &1)) + end) + |> Enum.map(&Path.expand(&1, @repo_root)) + |> Enum.filter(&File.regular?/1) + + assert target_files != [], "No tracked files found in the repository" + + offending = + target_files + |> Enum.reject(fn file -> + content = File.read!(file) + content == "" or content =~ ~r/\S\n\z/ + end) + |> Enum.map(&Path.relative_to(&1, @repo_root)) + + assert offending == [], + "Expected the following files to end with a single trailing newline:\n\n" <> + Enum.map_join(offending, "\n", &" - #{&1}") + end +end