Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow lib_prefix to be specified through an environment variable #32

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 49 additions & 12 deletions htmltools/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
_html_escape, # type: ignore
_flatten, # type: ignore
hash_deterministic,
MISSING,
MISSING_TYPE,
)

__all__ = (
Expand Down Expand Up @@ -194,7 +196,11 @@ def tagify(self) -> "TagList":
return cp

def save_html(
self, file: str, *, libdir: Optional[str] = "lib", include_version: bool = True
self,
file: str,
*,
libdir: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> str:
"""
Save to a HTML file.
Expand Down Expand Up @@ -583,7 +589,11 @@ def render(self) -> RenderedHTML:
return {"dependencies": deps, "html": cp.get_html_string()}

def save_html(
self, file: str, *, libdir: Optional[str] = "lib", include_version: bool = True
self,
file: str,
*,
libdir: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> str:
"""
Save to a HTML file.
Expand Down Expand Up @@ -707,7 +717,10 @@ def append(self, *args: TagChildArg) -> None:
self._content.append(*args)

def render(
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
self,
*,
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> RenderedHTML:
"""
Render the document.
Expand All @@ -726,7 +739,10 @@ def render(
return rendered

def save_html(
self, file: str, libdir: Optional[str] = "lib", include_version: bool = True
self,
file: str,
libdir: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> str:
"""
Save the document to a HTML file.
Expand All @@ -743,9 +759,10 @@ def save_html(

# Directory where dependencies are copied to.
destdir = str(Path(file).resolve().parent)
if libdir:
destdir = os.path.join(destdir, libdir)
libdir = resolve_missing_lib_path(libdir)
destdir = os.path.join(destdir, libdir)

# TODO: fix all libdir occurrences
rendered = self.render(lib_prefix=libdir, include_version=include_version)
for dep in rendered["dependencies"]:
dep.copy_to(destdir, include_version=include_version)
Expand All @@ -760,12 +777,14 @@ def save_html(
# - lib_prefix: A directoy prefix to add to <script src="[lib_prefix]/script.js">
# and <link rel="[lib_prefix]/style.css"> tags.
def _gen_html_tag_tree(
self, lib_prefix: Optional[str], include_version: bool
self, lib_prefix: Union[str, MISSING_TYPE], include_version: bool
) -> Tag:
content: TagList = self._content
html: Tag
body: Tag

lib_prefix = resolve_missing_lib_path(lib_prefix)

if (
len(content) == 1
and isinstance(content[0], Tag)
Expand Down Expand Up @@ -797,7 +816,7 @@ def _gen_html_tag_tree(
# <link> and <script> tags.
@staticmethod
def _hoist_head_content(
x: Tag, lib_prefix: Optional[str], include_version: bool
x: Tag, lib_prefix: Union[str, MISSING_TYPE], include_version: bool
) -> Tag:
if x.name != "html":
raise ValueError(f"Expected <html> tag, got <{x.name}>.")
Expand Down Expand Up @@ -973,13 +992,18 @@ def __init__(
self.head = TagList(head)

def source_path_map(
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
self,
*,
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> SourcePathMapping:
"""
Returns a dict of the absolute 'source' filepath and the 'href' path it will
point to in the HTML (given the lib_prefix).
"""

lib_prefix = resolve_missing_lib_path(lib_prefix)

src = self.source
if src is None:
return {"source": "", "href": ""}
Expand All @@ -997,7 +1021,10 @@ def source_path_map(
return {"source": source, "href": href}

def as_html_tags(
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
self,
*,
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> TagList:
"""
Render the dependency as a ``TagList()``.
Expand All @@ -1009,7 +1036,10 @@ def as_html_tags(
return TagList(*metas, *links, *scripts, self.head)

def as_dict(
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
self,
*,
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
include_version: bool = True,
) -> Dict[str, Any]:
"""
Returns a dict of the dependency's attributes.
Expand Down Expand Up @@ -1054,7 +1084,7 @@ def copy_to(self, path: str, include_version: bool = True) -> None:
Copy the dependency's files to the given path.
"""

paths = self.source_path_map(lib_prefix=None, include_version=include_version)
paths = self.source_path_map(lib_prefix="", include_version=include_version)
if paths["source"] == "":
return None

Expand Down Expand Up @@ -1245,3 +1275,10 @@ def _equals_impl(x: Any, y: Any) -> bool:
if getattr(x, key, None) != getattr(y, key, None):
return False
return True


def resolve_missing_lib_path(lib: Union[str, MISSING_TYPE] = MISSING) -> str:
if isinstance(lib, MISSING_TYPE):
return os.getenv("HTMLTOOLS_LIB_PREFIX", "lib")
else:
return lib
10 changes: 9 additions & 1 deletion htmltools/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def hash_deterministic(s: str) -> str:
"""
Returns a deterministic hash of the given string.
"""
return hashlib.sha1(s.encode('utf-8')).hexdigest()
return hashlib.sha1(s.encode("utf-8")).hexdigest()


class _HttpServerInfo(NamedTuple):
Expand Down Expand Up @@ -175,3 +175,11 @@ def get_open_port() -> int:
with closing(socket()) as sock:
sock.bind(("", 0))
return sock.getsockname()[1]


# Sentinel value - indicates a missing value in a function call.
class MISSING_TYPE:
pass


MISSING = MISSING_TYPE()
14 changes: 6 additions & 8 deletions tests/test_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_dep_resolution():
)
c1_0 = HTMLDependency("c", "1.0", source={"subdir": "foo"}, script={"src": "c1.js"})
test = TagList(a1_1, b1_9, b1_10, a1_2, a1_2_1, b1_9, b1_10, c1_0)
assert HTMLDocument(test).render(lib_prefix=None)["html"] == textwrap.dedent(
assert HTMLDocument(test).render(lib_prefix="")["html"] == textwrap.dedent(
"""\
<!DOCTYPE html>
<html>
Expand Down Expand Up @@ -57,9 +57,7 @@ def test_inline_deps(snapshot):
TagList([a1_1, div("foo")], "bar"),
div([a1_1, div("foo")], "bar"),
]
html_ = "\n\n".join(
[HTMLDocument(t).render(lib_prefix=None)["html"] for t in tests]
)
html_ = "\n\n".join([HTMLDocument(t).render(lib_prefix="")["html"] for t in tests])
snapshot.assert_match(html_, "inline_deps")


Expand All @@ -86,16 +84,16 @@ def test_append_deps():

x = div(a1_1, b1_0)
x.append(a1_2)
assert HTMLDocument(x).render(lib_prefix=None)["html"] == expected_result
assert HTMLDocument(x).render(lib_prefix="")["html"] == expected_result

y = div(a1_1)
y.append([a1_2, b1_0])
assert HTMLDocument(y).render(lib_prefix=None)["html"] == expected_result
assert HTMLDocument(y).render(lib_prefix="")["html"] == expected_result

z = div()
z.append([a1_1, b1_0])
z.append(a1_2)
assert HTMLDocument(z).render(lib_prefix=None)["html"] == expected_result
assert HTMLDocument(z).render(lib_prefix="")["html"] == expected_result


def test_script_input():
Expand Down Expand Up @@ -213,7 +211,7 @@ def test_as_dict():
stylesheet=[{"href": "b1.css"}, {"href": "b2.css"}],
head=tags.script("1 && 1"),
)
assert b.as_dict(lib_prefix=None) == {
assert b.as_dict(lib_prefix="") == {
"name": "b",
"version": "2.0",
"script": [],
Expand Down
2 changes: 1 addition & 1 deletion tests/test_html_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ def tagify(self):
result = x.tagify().render()
assert result["dependencies"] == [DelayedDep.dep]

result = HTMLDocument(x).render(lib_prefix=None)
result = HTMLDocument(x).render(lib_prefix="")
assert result["dependencies"] == [DelayedDep.dep]
assert result["html"].find('<script src="testdep-1.0/testdep.js">') != -1
assert (
Expand Down
2 changes: 1 addition & 1 deletion tests/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def test_html_save():
stylesheet={"href": "testdep/testdep.css"},
script={"src": "testdep/testdep.js"},
)
assert saved_html(div("foo", dep), libdir=None) == textwrap.dedent(
assert saved_html(div("foo", dep), libdir="") == textwrap.dedent(
"""\
<!DOCTYPE html>
<html>
Expand Down