Skip to content

Commit bff812f

Browse files
committed
Allow lib_prefix to be specified through an environment variable
1 parent 5c84033 commit bff812f

File tree

5 files changed

+66
-23
lines changed

5 files changed

+66
-23
lines changed

htmltools/_core.py

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
_html_escape, # type: ignore
4747
_flatten, # type: ignore
4848
hash_deterministic,
49+
MISSING,
50+
MISSING_TYPE,
4951
)
5052

5153
__all__ = (
@@ -194,7 +196,11 @@ def tagify(self) -> "TagList":
194196
return cp
195197

196198
def save_html(
197-
self, file: str, *, libdir: Optional[str] = "lib", include_version: bool = True
199+
self,
200+
file: str,
201+
*,
202+
libdir: Union[str, MISSING_TYPE] = MISSING,
203+
include_version: bool = True,
198204
) -> str:
199205
"""
200206
Save to a HTML file.
@@ -583,7 +589,11 @@ def render(self) -> RenderedHTML:
583589
return {"dependencies": deps, "html": cp.get_html_string()}
584590

585591
def save_html(
586-
self, file: str, *, libdir: Optional[str] = "lib", include_version: bool = True
592+
self,
593+
file: str,
594+
*,
595+
libdir: Union[str, MISSING_TYPE] = MISSING,
596+
include_version: bool = True,
587597
) -> str:
588598
"""
589599
Save to a HTML file.
@@ -707,7 +717,10 @@ def append(self, *args: TagChildArg) -> None:
707717
self._content.append(*args)
708718

709719
def render(
710-
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
720+
self,
721+
*,
722+
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
723+
include_version: bool = True,
711724
) -> RenderedHTML:
712725
"""
713726
Render the document.
@@ -726,7 +739,10 @@ def render(
726739
return rendered
727740

728741
def save_html(
729-
self, file: str, libdir: Optional[str] = "lib", include_version: bool = True
742+
self,
743+
file: str,
744+
libdir: Union[str, MISSING_TYPE] = MISSING,
745+
include_version: bool = True,
730746
) -> str:
731747
"""
732748
Save the document to a HTML file.
@@ -743,9 +759,10 @@ def save_html(
743759

744760
# Directory where dependencies are copied to.
745761
destdir = str(Path(file).resolve().parent)
746-
if libdir:
747-
destdir = os.path.join(destdir, libdir)
762+
libdir = resolve_missing_lib_path(libdir)
763+
destdir = os.path.join(destdir, libdir)
748764

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

786+
lib_prefix = resolve_missing_lib_path(lib_prefix)
787+
769788
if (
770789
len(content) == 1
771790
and isinstance(content[0], Tag)
@@ -797,7 +816,7 @@ def _gen_html_tag_tree(
797816
# <link> and <script> tags.
798817
@staticmethod
799818
def _hoist_head_content(
800-
x: Tag, lib_prefix: Optional[str], include_version: bool
819+
x: Tag, lib_prefix: Union[str, MISSING_TYPE], include_version: bool
801820
) -> Tag:
802821
if x.name != "html":
803822
raise ValueError(f"Expected <html> tag, got <{x.name}>.")
@@ -973,13 +992,18 @@ def __init__(
973992
self.head = TagList(head)
974993

975994
def source_path_map(
976-
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
995+
self,
996+
*,
997+
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
998+
include_version: bool = True,
977999
) -> SourcePathMapping:
9781000
"""
9791001
Returns a dict of the absolute 'source' filepath and the 'href' path it will
9801002
point to in the HTML (given the lib_prefix).
9811003
"""
9821004

1005+
lib_prefix = resolve_missing_lib_path(lib_prefix)
1006+
9831007
src = self.source
9841008
if src is None:
9851009
return {"source": "", "href": ""}
@@ -997,7 +1021,10 @@ def source_path_map(
9971021
return {"source": source, "href": href}
9981022

9991023
def as_html_tags(
1000-
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
1024+
self,
1025+
*,
1026+
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
1027+
include_version: bool = True,
10011028
) -> TagList:
10021029
"""
10031030
Render the dependency as a ``TagList()``.
@@ -1009,7 +1036,10 @@ def as_html_tags(
10091036
return TagList(*metas, *links, *scripts, self.head)
10101037

10111038
def as_dict(
1012-
self, *, lib_prefix: Optional[str] = "lib", include_version: bool = True
1039+
self,
1040+
*,
1041+
lib_prefix: Union[str, MISSING_TYPE] = MISSING,
1042+
include_version: bool = True,
10131043
) -> Dict[str, Any]:
10141044
"""
10151045
Returns a dict of the dependency's attributes.
@@ -1054,7 +1084,7 @@ def copy_to(self, path: str, include_version: bool = True) -> None:
10541084
Copy the dependency's files to the given path.
10551085
"""
10561086

1057-
paths = self.source_path_map(lib_prefix=None, include_version=include_version)
1087+
paths = self.source_path_map(lib_prefix="", include_version=include_version)
10581088
if paths["source"] == "":
10591089
return None
10601090

@@ -1245,3 +1275,10 @@ def _equals_impl(x: Any, y: Any) -> bool:
12451275
if getattr(x, key, None) != getattr(y, key, None):
12461276
return False
12471277
return True
1278+
1279+
1280+
def resolve_missing_lib_path(lib: Union[str, MISSING_TYPE] = MISSING) -> str:
1281+
if isinstance(lib, MISSING_TYPE):
1282+
return os.getenv("HTMLTOOLS_LIB_PREFIX", "lib")
1283+
else:
1284+
return lib

htmltools/_util.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def hash_deterministic(s: str) -> str:
132132
"""
133133
Returns a deterministic hash of the given string.
134134
"""
135-
return hashlib.sha1(s.encode('utf-8')).hexdigest()
135+
return hashlib.sha1(s.encode("utf-8")).hexdigest()
136136

137137

138138
class _HttpServerInfo(NamedTuple):
@@ -175,3 +175,11 @@ def get_open_port() -> int:
175175
with closing(socket()) as sock:
176176
sock.bind(("", 0))
177177
return sock.getsockname()[1]
178+
179+
180+
# Sentinel value - indicates a missing value in a function call.
181+
class MISSING_TYPE:
182+
pass
183+
184+
185+
MISSING = MISSING_TYPE()

tests/test_deps.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_dep_resolution():
1515
)
1616
c1_0 = HTMLDependency("c", "1.0", source={"subdir": "foo"}, script={"src": "c1.js"})
1717
test = TagList(a1_1, b1_9, b1_10, a1_2, a1_2_1, b1_9, b1_10, c1_0)
18-
assert HTMLDocument(test).render(lib_prefix=None)["html"] == textwrap.dedent(
18+
assert HTMLDocument(test).render(lib_prefix="")["html"] == textwrap.dedent(
1919
"""\
2020
<!DOCTYPE html>
2121
<html>
@@ -57,9 +57,7 @@ def test_inline_deps(snapshot):
5757
TagList([a1_1, div("foo")], "bar"),
5858
div([a1_1, div("foo")], "bar"),
5959
]
60-
html_ = "\n\n".join(
61-
[HTMLDocument(t).render(lib_prefix=None)["html"] for t in tests]
62-
)
60+
html_ = "\n\n".join([HTMLDocument(t).render(lib_prefix="")["html"] for t in tests])
6361
snapshot.assert_match(html_, "inline_deps")
6462

6563

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

8785
x = div(a1_1, b1_0)
8886
x.append(a1_2)
89-
assert HTMLDocument(x).render(lib_prefix=None)["html"] == expected_result
87+
assert HTMLDocument(x).render(lib_prefix="")["html"] == expected_result
9088

9189
y = div(a1_1)
9290
y.append([a1_2, b1_0])
93-
assert HTMLDocument(y).render(lib_prefix=None)["html"] == expected_result
91+
assert HTMLDocument(y).render(lib_prefix="")["html"] == expected_result
9492

9593
z = div()
9694
z.append([a1_1, b1_0])
9795
z.append(a1_2)
98-
assert HTMLDocument(z).render(lib_prefix=None)["html"] == expected_result
96+
assert HTMLDocument(z).render(lib_prefix="")["html"] == expected_result
9997

10098

10199
def test_script_input():
@@ -213,7 +211,7 @@ def test_as_dict():
213211
stylesheet=[{"href": "b1.css"}, {"href": "b2.css"}],
214212
head=tags.script("1 && 1"),
215213
)
216-
assert b.as_dict(lib_prefix=None) == {
214+
assert b.as_dict(lib_prefix="") == {
217215
"name": "b",
218216
"version": "2.0",
219217
"script": [],

tests/test_html_document.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def tagify(self):
140140
result = x.tagify().render()
141141
assert result["dependencies"] == [DelayedDep.dep]
142142

143-
result = HTMLDocument(x).render(lib_prefix=None)
143+
result = HTMLDocument(x).render(lib_prefix="")
144144
assert result["dependencies"] == [DelayedDep.dep]
145145
assert result["html"].find('<script src="testdep-1.0/testdep.js">') != -1
146146
assert (

tests/test_tags.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ def test_html_save():
229229
stylesheet={"href": "testdep/testdep.css"},
230230
script={"src": "testdep/testdep.js"},
231231
)
232-
assert saved_html(div("foo", dep), libdir=None) == textwrap.dedent(
232+
assert saved_html(div("foo", dep), libdir="") == textwrap.dedent(
233233
"""\
234234
<!DOCTYPE html>
235235
<html>

0 commit comments

Comments
 (0)