Skip to content

Commit c3d877e

Browse files
r-barnesmeta-codesync[bot]
authored andcommitted
Strip fb-only comments when using opensource manifest shipit builder
Summary: Lines marked as comments for open source distribution should not be included in internal open source-esque testing. Reviewed By: bigfootjon, itamaro Differential Revision: D93801016 fbshipit-source-id: 344a5b0ca29b89d81a5d0ba9d961c884e28f03dc
1 parent 5368361 commit c3d877e

3 files changed

Lines changed: 192 additions & 0 deletions

File tree

build/fbcode_builder/getdeps/fetcher.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,31 @@ def copy_if_different(src_name, dest_name) -> bool:
380380
return True
381381

382382

383+
def filter_strip_marker(dest_name, marker) -> None:
384+
"""Strip lines/blocks tagged with the given marker from a file."""
385+
try:
386+
with open(dest_name, "r") as f:
387+
content = f.read()
388+
except (UnicodeDecodeError, PermissionError):
389+
return
390+
391+
if marker not in content:
392+
return
393+
394+
escaped = re.escape(marker)
395+
block_re = re.compile(
396+
r"[^\n]*" + escaped + r"-start[^\n]*\n.*?[^\n]*" + escaped + r"-end[^\n]*\n?",
397+
re.DOTALL,
398+
)
399+
line_re = re.compile(r".*" + escaped + r".*\n?")
400+
401+
filtered = block_re.sub("", content)
402+
filtered = line_re.sub("", filtered)
403+
if filtered != content:
404+
with open(dest_name, "w") as f:
405+
f.write(filtered)
406+
407+
383408
def list_files_under_dir_newer_than_timestamp(dir_to_scan, ts):
384409
for root, _dirs, files in os.walk(dir_to_scan):
385410
for src_file in files:
@@ -394,6 +419,7 @@ def __init__(self) -> None:
394419
self.roots = []
395420
self.mapping = []
396421
self.exclusion = []
422+
self.strip_marker = "@fb-only"
397423

398424
def add_mapping(self, fbsource_dir, target_dir) -> None:
399425
"""Add a posix path or pattern. We cannot normpath the input
@@ -492,6 +518,7 @@ def st_dev(path):
492518
if target_name:
493519
full_file_list.add(target_name)
494520
if copy_if_different(full_name, target_name):
521+
filter_strip_marker(target_name, self.strip_marker)
495522
change_status.record_change(target_name)
496523
if update_count < 10:
497524
print("Updated %s -> %s" % (full_name, target_name))
@@ -680,6 +707,8 @@ def update(self) -> ChangeStatus:
680707
for pattern in self.manifest.get_section_as_args("shipit.strip", self.ctx):
681708
mapping.add_exclusion(pattern)
682709

710+
mapping.strip_marker = self.manifest.shipit_strip_marker
711+
683712
return mapping.mirror(self.build_options.fbsource_dir, self.repo_dir)
684713

685714
# pyre-fixme[15]: `hash` overrides method defined in `Fetcher` inconsistently.

build/fbcode_builder/getdeps/manifest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"shipit_fbcode_builder": OPTIONAL,
5252
"use_shipit": OPTIONAL,
5353
"shipit_external_branch": OPTIONAL,
54+
"shipit_strip_marker": OPTIONAL,
5455
},
5556
},
5657
"dependencies": {"optional_section": True, "allow_values": False},
@@ -258,6 +259,9 @@ def __init__(self, file_name, fp=None):
258259
self.shipit_project = self.get("manifest", "shipit_project")
259260
self.shipit_fbcode_builder = self.get("manifest", "shipit_fbcode_builder")
260261
self.resolved_system_packages = {}
262+
self.shipit_strip_marker = self.get(
263+
"manifest", "shipit_strip_marker", defval="@fb-only"
264+
)
261265

262266
if self.name != os.path.basename(file_name):
263267
raise Exception(
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
#
3+
# This source code is licensed under the MIT license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
# pyre-strict
7+
8+
9+
import os
10+
import tempfile
11+
import unittest
12+
13+
from ..fetcher import filter_strip_marker
14+
from ..manifest import ManifestParser
15+
16+
17+
class ManifestStripMarkerTest(unittest.TestCase):
18+
def test_default_strip_marker(self) -> None:
19+
p = ManifestParser(
20+
"test",
21+
"""
22+
[manifest]
23+
name = test
24+
""",
25+
)
26+
self.assertEqual(p.shipit_strip_marker, "@fb-only")
27+
28+
def test_custom_strip_marker(self) -> None:
29+
p = ManifestParser(
30+
"test",
31+
"""
32+
[manifest]
33+
name = test
34+
shipit_strip_marker = @oss-disable
35+
""",
36+
)
37+
self.assertEqual(p.shipit_strip_marker, "@oss-disable")
38+
39+
40+
class FilterStripMarkerTest(unittest.TestCase):
41+
def _write_temp(self, content: str) -> str:
42+
fd, path = tempfile.mkstemp(suffix=".txt")
43+
os.close(fd)
44+
with open(path, "w") as f:
45+
f.write(content)
46+
return path
47+
48+
def _read(self, path: str) -> str:
49+
with open(path, "r") as f:
50+
return f.read()
51+
52+
def test_single_line_removal(self) -> None:
53+
path = self._write_temp("keep this\nremove this @fb-only\nkeep this too\n")
54+
try:
55+
filter_strip_marker(path, "@fb-only")
56+
self.assertEqual(self._read(path), "keep this\nkeep this too\n")
57+
finally:
58+
os.unlink(path)
59+
60+
def test_block_removal(self) -> None:
61+
content = (
62+
"before\n"
63+
"// @fb-only-start\n"
64+
"secret stuff\n"
65+
"more secret\n"
66+
"// @fb-only-end\n"
67+
"after\n"
68+
)
69+
path = self._write_temp(content)
70+
try:
71+
filter_strip_marker(path, "@fb-only")
72+
self.assertEqual(self._read(path), "before\nafter\n")
73+
finally:
74+
os.unlink(path)
75+
76+
def test_no_marker_present_no_change(self) -> None:
77+
original = "nothing special here\njust plain code\n"
78+
path = self._write_temp(original)
79+
try:
80+
filter_strip_marker(path, "@fb-only")
81+
self.assertEqual(self._read(path), original)
82+
finally:
83+
os.unlink(path)
84+
85+
def test_custom_marker_single_line(self) -> None:
86+
content = "keep\nremove @oss-disable\nkeep too\n"
87+
path = self._write_temp(content)
88+
try:
89+
filter_strip_marker(path, "@oss-disable")
90+
self.assertEqual(self._read(path), "keep\nkeep too\n")
91+
finally:
92+
os.unlink(path)
93+
94+
def test_custom_marker_block(self) -> None:
95+
content = (
96+
"before\n"
97+
"# @oss-disable-start\n"
98+
"internal only\n"
99+
"# @oss-disable-end\n"
100+
"after\n"
101+
)
102+
path = self._write_temp(content)
103+
try:
104+
filter_strip_marker(path, "@oss-disable")
105+
self.assertEqual(self._read(path), "before\nafter\n")
106+
finally:
107+
os.unlink(path)
108+
109+
def test_custom_marker_ignores_default(self) -> None:
110+
"""When using a custom marker, @fb-only lines should be kept."""
111+
content = "keep @fb-only\nremove @oss-disable\nplain\n"
112+
path = self._write_temp(content)
113+
try:
114+
filter_strip_marker(path, "@oss-disable")
115+
self.assertEqual(self._read(path), "keep @fb-only\nplain\n")
116+
finally:
117+
os.unlink(path)
118+
119+
def test_mixed_single_and_block(self) -> None:
120+
content = (
121+
"line1\n"
122+
"line2 @fb-only\n"
123+
"line3\n"
124+
"// @fb-only-start\n"
125+
"block content\n"
126+
"// @fb-only-end\n"
127+
"line4\n"
128+
)
129+
path = self._write_temp(content)
130+
try:
131+
filter_strip_marker(path, "@fb-only")
132+
self.assertEqual(self._read(path), "line1\nline3\nline4\n")
133+
finally:
134+
os.unlink(path)
135+
136+
def test_marker_with_regex_metacharacters(self) -> None:
137+
"""Markers containing regex metacharacters should be escaped properly."""
138+
content = "keep\nremove @fb.only\nkeep too\n"
139+
path = self._write_temp(content)
140+
try:
141+
# With proper escaping, the dot is literal, not a wildcard
142+
filter_strip_marker(path, "@fb.only")
143+
self.assertEqual(self._read(path), "keep\nkeep too\n")
144+
finally:
145+
os.unlink(path)
146+
147+
def test_binary_file_skipped(self) -> None:
148+
"""Binary files that can't be decoded as UTF-8 should be skipped."""
149+
fd, path = tempfile.mkstemp(suffix=".bin")
150+
os.close(fd)
151+
binary_content = b"\x80\x81\x82\xff\xfe"
152+
with open(path, "wb") as f:
153+
f.write(binary_content)
154+
try:
155+
filter_strip_marker(path, "@fb-only")
156+
with open(path, "rb") as f:
157+
self.assertEqual(f.read(), binary_content)
158+
finally:
159+
os.unlink(path)

0 commit comments

Comments
 (0)