From 36adbebc9056a27f79e15ca1ca65883cfae0277c Mon Sep 17 00:00:00 2001 From: Yuki Sekiguchi Date: Thu, 21 Nov 2024 18:00:22 +0900 Subject: [PATCH] Copy symbolic links in the assets as actual files (#1967) --- lib/ex_doc/formatter/html.ex | 2 +- lib/ex_doc/formatter/html/templates.ex | 3 +-- lib/ex_doc/retriever.ex | 12 ++++-------- test/ex_doc/formatter/html_test.exs | 20 ++++++++++++++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/ex_doc/formatter/html.ex b/lib/ex_doc/formatter/html.ex index c4fcb818d..e377d10fd 100644 --- a/lib/ex_doc/formatter/html.ex +++ b/lib/ex_doc/formatter/html.ex @@ -306,7 +306,7 @@ defmodule ExDoc.Formatter.HTML do is_binary(dir_or_files) and File.dir?(dir_or_files) -> dir_or_files - |> File.cp_r!(target_dir) + |> File.cp_r!(target_dir, dereference_symlinks: true) |> Enum.map(&Path.relative_to(&1, output)) is_binary(dir_or_files) -> diff --git a/lib/ex_doc/formatter/html/templates.ex b/lib/ex_doc/formatter/html/templates.ex index 7ce0f4248..d8b118385 100644 --- a/lib/ex_doc/formatter/html/templates.ex +++ b/lib/ex_doc/formatter/html/templates.ex @@ -203,8 +203,7 @@ defmodule ExDoc.Formatter.HTML.Templates do end def module_summary(module_node) do - entries = - docs_groups(module_node.docs_groups, module_node.docs ++ module_node.typespecs) + entries = docs_groups(module_node.docs_groups, module_node.docs ++ module_node.typespecs) Enum.reject(entries, fn {_type, nodes} -> nodes == [] end) end diff --git a/lib/ex_doc/retriever.ex b/lib/ex_doc/retriever.ex index e0f2c9c40..76225a7b2 100644 --- a/lib/ex_doc/retriever.ex +++ b/lib/ex_doc/retriever.ex @@ -247,8 +247,7 @@ defmodule ExDoc.Retriever do metadata ) - source_url = - source_link(function_data[:source_file], source, function_data.source_line) + source_url = source_link(function_data[:source_file], source, function_data.source_line) annotations = annotations_for_docs.(metadata) ++ @@ -260,8 +259,7 @@ defmodule ExDoc.Retriever do (source_doc && doc_ast(content_type, source_doc, file: doc_file, line: doc_line + 1)) || function_data.doc_fallback.() - group = - GroupMatcher.match_function(groups_for_docs, metadata) + group = GroupMatcher.match_function(groups_for_docs, metadata) %ExDoc.FunctionNode{ id: nil_or_name(name, arity), @@ -325,8 +323,7 @@ defmodule ExDoc.Retriever do doc_file = anno_file(anno, source) doc_line = anno_line(anno) - source_url = - source_link(callback_data[:source_file], source, callback_data.source_line) + source_url = source_link(callback_data[:source_file], source, callback_data.source_line) metadata = Map.merge( @@ -393,8 +390,7 @@ defmodule ExDoc.Retriever do metadata ) - source_url = - source_link(type_data[:source_file], source, type_data.source_line) + source_url = source_link(type_data[:source_file], source, type_data.source_line) signature = signature(type_data.signature) diff --git a/test/ex_doc/formatter/html_test.exs b/test/ex_doc/formatter/html_test.exs index 1fd67aaa1..213112cd9 100644 --- a/test/ex_doc/formatter/html_test.exs +++ b/test/ex_doc/formatter/html_test.exs @@ -816,4 +816,24 @@ defmodule ExDoc.Formatter.HTMLTest do after File.rm_rf!("test/tmp/html_assets") end + + test "symbolic links in the assets should be resolved and copied as actual files", + %{tmp_dir: tmp_dir} = context do + File.mkdir_p!("test/tmp/html_assets/hello") + File.touch!("test/tmp/html_assets/hello/world") + + File.ln_s("world", "test/tmp/html_assets/hello/symlink_world") + + generate_docs( + doc_config(context, + assets: %{"test/tmp/html_assets" => "assets"} + ) + ) + + assert File.regular?(tmp_dir <> "/html/assets/hello/world") + assert File.exists?(tmp_dir <> "/html/assets/hello/symlink_world") + assert File.read_link(tmp_dir <> "/html/assets/hello/symlink_world") == {:error, :einval} + after + File.rm_rf!("test/tmp/html_assets") + end end