Skip to content

Commit

Permalink
[surface-ui#481] Disable build timestamp, replace header
Browse files Browse the repository at this point in the history
This change removes the build timestamp from headers of the generated
files, and replaces it with a helpful message pointing to the original
source files that should be modified instead of the current file.

This change also improves the tests by generating the hook files in the
tests themselves, making sure their content changes and not just rely on
the timestamps / build times.
  • Loading branch information
hubertlepicki committed Sep 17, 2021
1 parent 3a6a3a4 commit 8168ce1
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 35 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Expand Up @@ -23,4 +23,8 @@ erl_crash.dump
surface-*.tar

# Ignore temp files.
/tmp/
/tmp/

# Ignore fake hooks files that are created in tests
/test/support/mix/tasks/compile/surface_test/fake_button.hooks.js
/test/support/mix/tasks/compile/surface_test/fake_link.hooks.js
35 changes: 21 additions & 14 deletions lib/mix/tasks/compile/surface.ex
Expand Up @@ -10,17 +10,15 @@ defmodule Mix.Tasks.Compile.Surface do
@hooks_extension ".hooks.js"

@doc false
def run(args) do
build_time = Keyword.get(args, :build_time)

case get_colocated_assets() |> generate_files(build_time) do
def run(_args) do
case get_colocated_assets() |> generate_files() do
"" -> {:noop, []}
_ -> {:ok, []}
end
end

@doc false
def generate_files({js_files, _css_files}, build_time \\ nil) do
def generate_files({js_files, _css_files}) do
opts = Application.get_env(:surface, :compiler, [])

hooks_output_dir = Keyword.get(opts, :hooks_output_dir, @default_hooks_output_dir)
Expand All @@ -44,13 +42,13 @@ defmodule Mix.Tasks.Compile.Surface do
!File.exists?(dest_file) or time > index_file_time,
reduce: false do
_ ->
content = [header(build_time), "\n\n", File.read!(src_file)]
content = [header(src_file), "\n\n", File.read!(src_file)]
File.write!(dest_file, content)
true
end

if !index_file_time or update_index? or unused_hooks_files != [] do
File.write!(index_file, index_content(js_files, build_time))
File.write!(index_file, index_content(js_files))
end
end

Expand All @@ -76,15 +74,15 @@ defmodule Mix.Tasks.Compile.Surface do
end
end

defp index_content([], build_time) do
defp index_content([]) do
"""
#{header(build_time)}
#{header()}
export default {}
"""
end

defp index_content(js_files, build_time) do
defp index_content(js_files) do
files = js_files |> Enum.sort() |> Enum.with_index(1)

{hooks, imports} =
Expand All @@ -101,7 +99,7 @@ defmodule Mix.Tasks.Compile.Surface do
imports = Enum.reverse(imports)

"""
#{header(build_time)}
#{header()}
function ns(hooks, nameSpace) {
const updatedHooks = {}
Expand Down Expand Up @@ -166,14 +164,23 @@ defmodule Mix.Tasks.Compile.Surface do
match?({:module, _mod}, Code.ensure_compiled(module))
end

defp header(build_time) do
build_time = build_time || DateTime.utc_now()
defp header() do
"""
/*
This file was generated by the Surface compiler.
Please do not modify this file directly.
*/\
"""
end

defp header(src_file) do
"""
/*
This file was generated by the Surface compiler.
Build time: #{build_time}
Please do not modify this file directly, instead edit the source file:
#{src_file |> Path.relative_to_cwd()}
*/\
"""
end
Expand Down
46 changes: 30 additions & 16 deletions test/mix/tasks/compile/surface_test.exs
Expand Up @@ -8,19 +8,24 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
@test_components_dir Path.join(File.cwd!(), "test/support/mix/tasks/compile/surface_test")

@button_src_hooks_file Path.join(@test_components_dir, "fake_button.hooks.js")
@button_rel_src_hooks_file Path.join("test/support/mix/tasks/compile/surface_test", "fake_button.hooks.js")
@button_dest_hooks_file Path.join(
@hooks_output_dir,
"Mix.Tasks.Compile.SurfaceTest.FakeButton.hooks.js"
)
@button_src_hooks_file_content "let FakeButton = {}\nexport { FakeButton }"
@button_src_hooks_file_content_modified "let FakeButton = { mounted() {} }\nexport { FakeButton }"

@link_src_hooks_file Path.join(@test_components_dir, "fake_link.hooks.js")
@link_rel_src_hooks_file Path.join("test/support/mix/tasks/compile/surface_test", "fake_link.hooks.js")
@link_dest_hooks_file Path.join(
@hooks_output_dir,
"Mix.Tasks.Compile.SurfaceTest.FakeLink.hooks.js"
)
@link_src_hooks_file_content "let FakeLink = {}\nexport { FakeLink }"

@hooks_index_file Path.join(@hooks_output_dir, "index.js")

@build_time DateTime.new!(~D[2021-01-01], ~T[20:01:02.000003])

setup_all do
conf_before = Application.get_env(:surface, :compiler, [])
Application.put_env(:surface, :compiler, hooks_output_dir: @hooks_rel_output_dir)
Expand All @@ -33,12 +38,17 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
end

setup do
File.write!(@button_src_hooks_file, @button_src_hooks_file_content)
File.write!(@link_src_hooks_file, @link_src_hooks_file_content)

if File.exists?(@hooks_output_dir) do
File.rm_rf!(@hooks_output_dir)
end

on_exit(fn ->
File.rm_rf!(@hooks_output_dir)
File.rm_rf!(@button_src_hooks_file)
File.rm_rf!(@link_src_hooks_file)
end)

:ok
Expand All @@ -48,13 +58,14 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
refute File.exists?(@button_dest_hooks_file)
refute File.exists?(@link_dest_hooks_file)

run(build_time: @build_time)
run([])

assert File.read!(@button_dest_hooks_file) == """
/*
This file was generated by the Surface compiler.
Build time: 2021-01-01 20:01:02.000003Z
Please do not modify this file directly, instead edit the source file:
#{@button_rel_src_hooks_file}
*/
let FakeButton = {}
Expand All @@ -65,7 +76,8 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
/*
This file was generated by the Surface compiler.
Build time: 2021-01-01 20:01:02.000003Z
Please do not modify this file directly, instead edit the source file:
#{@link_rel_src_hooks_file}
*/
let FakeLink = {}
Expand All @@ -76,13 +88,13 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
test "generate index.js file for hooks" do
refute File.exists?(@hooks_output_dir)

run(build_time: @build_time)
run([])

assert File.read!(@hooks_index_file) =~ """
/*
This file was generated by the Surface compiler.
Build time: 2021-01-01 20:01:02.000003Z
Please do not modify this file directly.
*/
function ns(hooks, nameSpace) {
Expand All @@ -105,7 +117,7 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
"""
end

test "update dest hook file and index.js if src hook file is newer then index.js" do
test "update dest hook file and index.js if src hook file is newer than index.js" do
refute File.exists?(@hooks_output_dir)

run([])
Expand All @@ -115,40 +127,42 @@ defmodule Mix.Tasks.Compile.SurfaceTest do
assert files_changed?(files, fn -> run([]) end) == [false, false, false]

mtime = @hooks_index_file |> get_mtime() |> inc_mtime()
File.write!(@button_src_hooks_file, @button_src_hooks_file_content_modified)
File.touch!(@button_src_hooks_file, mtime)

assert files_changed?(files, fn -> run([]) end) == [true, false, true]
assert files_changed?(files, fn -> run([]) end) == [true, false, false]

assert File.read!(@button_dest_hooks_file) =~ "let FakeButton = { mounted() {} }"
end

test "generate index.js with empty object if there's no hooks available" do
refute File.exists?(@hooks_output_dir)

generate_files({[], []}, @build_time)
generate_files({[], []})

assert File.read!(@hooks_index_file) == """
/*
This file was generated by the Surface compiler.
Build time: 2021-01-01 20:01:02.000003Z
Please do not modify this file directly.
*/
export default {}
"""
end

test "delete unused hooks files from output dir and update index.js" do
test "removes unused hooks files from output dir and update index.js" do
refute File.exists?(@hooks_output_dir)

run([])

unused_file = Path.join(@hooks_output_dir, "Unused.hooks.js")
File.touch!(unused_file)
assert File.exists?(@link_dest_hooks_file)

assert File.exists?(unused_file)
File.rm!(@link_src_hooks_file)

assert files_changed?([@hooks_index_file], fn -> run([]) end) == [true]

refute File.exists?(unused_file)
refute File.exists?(@link_dest_hooks_file)
end

defp inc_mtime(time) do
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 8168ce1

Please sign in to comment.