Skip to content

Commit

Permalink
Bug 1762642: Add libopus to mach vendor r=kinetik,jewilde
Browse files Browse the repository at this point in the history
This makes some ./mach vendor improvements needed:
 - Adds a replace-in-file-regex action
 - Allows you to skip copying the temporary extract directory
   so that a script can do it
 - Removes 'commit' from the look-in-moz.yaml-for-release match

Differential Revision: https://phabricator.services.mozilla.com/D142720
  • Loading branch information
tomrittervg committed Apr 15, 2022
1 parent fc564bd commit aae5d51
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 29 deletions.
2 changes: 1 addition & 1 deletion media/libopus/README_MOZILLA
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ files after the copy step.

The upstream repository is https://git.xiph.org/opus.git

The git tag/revision used was 2654707e86cc94413998976d179b2ab4a2aa3114.
Refer to moz.yaml for the current in-tree revision.
2 changes: 1 addition & 1 deletion media/libopus/gen-sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def generate_sources_mozbuild(path):

if __name__ == '__main__':
if len(sys.argv) != 2:
print "Usage: %s /path/to/opus" % (sys.argv[0])
print("Usage: %s /path/to/opus" % (sys.argv[0]))
sys.exit(1)

generate_sources_mozbuild(sys.argv[1])
67 changes: 67 additions & 0 deletions media/libopus/moz.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Version of this schema
schema: 1

bugzilla:
# Bugzilla product and component for this directory and subdirectories
product: Core
component: "Audio/Video: Playback"

# Document the source of externally hosted code
origin:

# Short name of the package/library
name: opus

description: opus, an open, royalty-free, highly versatile audio codec

# Full URL for the package's homepage/etc
# Usually different from repository url
url: https://opus-codec.org/

# Human-readable identifier for this version/release
# Generally "version NNN", "tag SSS", "bookmark SSS"
release: 2654707e86cc94413998976d179b2ab4a2aa3114 (2022-04-01T14:32:38.000-04:00).

# Revision to pull in
# Must be a long or short commit SHA (long preferred)
revision: 2654707e86cc94413998976d179b2ab4a2aa3114

# The package's license, where possible using the mnemonic from
# https://spdx.org/licenses/
# Multiple licenses can be specified (as a YAML list)
# A "LICENSE" file must exist containing the full license text
license: BSD-2-Clause

license-file: COPYING

updatebot:
maintainer-phab: kinetik
maintainer-bz: [email protected]
tasks:
- type: vendoring
enabled: true
frequency: every

vendoring:
url: https://gitlab.xiph.org/xiph/opus
source-hosting: gitlab
vendor-directory: media/libopus
skip-vendoring-steps: ['move-contents', 'update-moz-build']

keep:
- COPYING
- gen-sources.py
- "*.patch"
- README_MOZILLA
- sources.mozbuild
- update.sh

update-actions:
- action: run-script
script: 'update.sh'
cwd: '{yaml_dir}'
args: ['{tmpextractdir}']
- action: replace-in-file-regex
file: moz.build
pattern: 'DEFINES\["OPUS_VERSION"\] = "(.+)"'
with: 'DEFINES["OPUS_VERSION"] = "{revision}"'
15 changes: 3 additions & 12 deletions media/libopus/update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,9 @@ if test -d $1/.git; then
else
version="UNKNOWN"
fi
echo "copied from revision ${version}"
# update README revision
sed -e "s/^The git tag\/revision used was .*/The git tag\/revision used was ${version}./" \
${TARGET}/README_MOZILLA > ${TARGET}/README_MOZILLA+ && \
mv ${TARGET}/README_MOZILLA+ ${TARGET}/README_MOZILLA
# update compiled-in version string
sed -e "s/DEFINES\['OPUS_VERSION'\][ \t]*=[ \t]*'\".*\"'/DEFINES['OPUS_VERSION'] = '\"${version}-mozilla\"'/" \
${TARGET}/moz.build > ${TARGET}/moz.build+ && \
mv ${TARGET}/moz.build+ ${TARGET}/moz.build

python gen-sources.py $1
python3 gen-sources.py $1

# apply outstanding local patches
patch -p3 < nonunified.patch
patch -p3 < nonunified2.patch
patch -p3 --no-backup-if-mismatch < nonunified.patch
patch -p3 --no-backup-if-mismatch < nonunified2.patch
12 changes: 9 additions & 3 deletions python/mozbuild/mozbuild/vendor/moz_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,14 @@
# The valid steps that can be skipped are listed below
skip-vendoring-steps:
- fetch
- keep
- include
- exclude
- update-moz-yaml
- move-contents
- update-actions
- hg-add
- spurious-check
- update-moz-yaml
- update-moz-build
# List of patch files to apply after vendoring. Applied in the order
Expand Down Expand Up @@ -234,6 +238,7 @@
# - copy-file
# - move-dir
# - replace-in-file
# - replace-in-file-regex
# - delete-path
# - run-script
# Unless otherwise noted, all subfields of action are required.
Expand All @@ -242,7 +247,7 @@
# from is the source file
# to is the destination
#
# If the action is replace-in-file:
# If the action is replace-in-file or replace-in-file-regex:
# pattern is what in the file to search for. It is an exact strng match.
# with is the string to replace it with. Accepts the special keyword
# '{revision}' for the commit we are updating to.
Expand Down Expand Up @@ -441,6 +446,7 @@ def _schema_1():
"copy-file",
"move-dir",
"replace-in-file",
"replace-in-file-regex",
"run-script",
"delete-path",
],
Expand Down Expand Up @@ -563,7 +569,7 @@ def __call__(self, values):
"%s action must (only) specify 'from' and 'to' keys"
% v["action"]
)
elif v["action"] == "replace-in-file":
elif v["action"] in ["replace-in-file", "replace-in-file-regex"]:
if (
"pattern" not in v
or "with" not in v
Expand Down
52 changes: 40 additions & 12 deletions python/mozbuild/mozbuild/vendor/vendor_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
DEFAULT_INCLUDE_FILES = []


def throwe():
raise Exception


class VendorManifest(MozbuildObject):
def should_perform_step(self, step):
return step not in self.manifest["vendoring"].get("skip-vendoring-steps", [])
Expand All @@ -47,6 +51,7 @@ def vendor(
):
self.manifest = manifest
self.yaml_file = yaml_file
self._extract_directory = throwe
self.logInfo = functools.partial(self.log, logging.INFO, "vendor")
if "vendor-directory" not in self.manifest["vendoring"]:
self.manifest["vendoring"]["vendor-directory"] = os.path.dirname(
Expand Down Expand Up @@ -170,6 +175,9 @@ def get_source_host(self):
def get_full_path(self, path, support_cwd=False):
if support_cwd and path[0:5] == "{cwd}":
path = path.replace("{cwd}", ".")
elif "{tmpextractdir}" in path:
# _extract_directory() will throw an exception if it is invalid to use it
path = path.replace("{tmpextractdir}", self._extract_directory())
elif "{yaml_dir}" in path:
path = path.replace("{yaml_dir}", os.path.dirname(self.yaml_file))
elif "{vendor_dir}" in path:
Expand Down Expand Up @@ -207,7 +215,8 @@ def fetch_and_unpack(self, revision):
self.logInfo({"url": url}, "Fetching code archive from {url}")

with mozfile.NamedTemporaryFile() as tmptarfile:
with tempfile.TemporaryDirectory() as tmpextractdir:
tmpextractdir = tempfile.TemporaryDirectory()
try:
req = requests.get(url, stream=True)
for data in req.iter_content(4096):
tmptarfile.write(data)
Expand Down Expand Up @@ -244,7 +253,7 @@ def fetch_and_unpack(self, revision):
mozfile.remove(file)

self.logInfo({"vd": vendor_dir}, "Unpacking upstream files for {vd}.")
tar.extractall(tmpextractdir)
tar.extractall(tmpextractdir.name)

def get_first_dir(p):
halves = os.path.split(p)
Expand All @@ -258,14 +267,14 @@ def get_first_dir(p):

# GitLab puts everything down a directory; move it up.
if has_prefix:
tardir = mozpath.join(tmpextractdir, one_prefix)
mozfile.copy_contents(tardir, tmpextractdir)
tardir = mozpath.join(tmpextractdir.name, one_prefix)
mozfile.copy_contents(tardir, tmpextractdir.name)
mozfile.remove(tardir)

if self.should_perform_step("include"):
self.logInfo({}, "Retaining wanted files from upstream changes.")
to_include = self.convert_patterns_to_paths(
tmpextractdir,
tmpextractdir.name,
self.manifest["vendoring"].get("include", [])
+ DEFAULT_INCLUDE_FILES,
)
Expand All @@ -276,7 +285,7 @@ def get_first_dir(p):
if self.should_perform_step("exclude"):
self.logInfo({}, "Removing excluded files from upstream changes.")
to_exclude = self.convert_patterns_to_paths(
tmpextractdir,
tmpextractdir.name,
self.manifest["vendoring"].get("exclude", [])
+ DEFAULT_EXCLUDE_FILES,
)
Expand Down Expand Up @@ -305,19 +314,27 @@ def removeEmpty(tmpextractdir):
pass
return removed

while removeEmpty(tmpextractdir):
while removeEmpty(tmpextractdir.name):
pass

# Then copy over the directories
mozfile.copy_contents(tmpextractdir, vendor_dir)
if self.should_perform_step("move-contents"):
self.logInfo({"d": vendor_dir}, "Copying to {d}.")
mozfile.copy_contents(tmpextractdir.name, vendor_dir)
else:
self.logInfo({}, "Skipping copying contents into tree.")
self._extract_directory = lambda: tmpextractdir.name
except Exception as e:
tmpextractdir.cleanup()
raise e

def update_yaml(self, revision, timestamp):
with open(self.yaml_file) as f:
yaml = f.readlines()

replaced = 0
replacements = [
[" release: commit", " %s (%s)." % (revision, timestamp)],
[" release:", " %s (%s)." % (revision, timestamp)],
[" revision:", " %s" % (revision)],
]

Expand Down Expand Up @@ -417,7 +434,7 @@ def copy_tree(src, dst):
copy_tree(src, dst)
shutil.rmtree(src)

elif update["action"] == "replace-in-file":
elif update["action"] in ["replace-in-file", "replace-in-file-regex"]:
file = self.get_full_path(update["file"])

self.logInfo({"file": file}, "action: replace-in-file file: {file}")
Expand All @@ -426,7 +443,10 @@ def copy_tree(src, dst):
contents = f.read()

replacement = update["with"].replace("{revision}", revision)
contents = contents.replace(update["pattern"], replacement)
if update["action"] == "replace-in-file":
contents = contents.replace(update["pattern"], replacement)
else:
contents = re.sub(update["pattern"], replacement, contents)

with open(file, "w") as f:
f.write(contents)
Expand All @@ -442,7 +462,15 @@ def copy_tree(src, dst):
for a in update.get("args", []):
if a == "{revision}":
args.append(revision)
elif any(s in a for s in ["{cwd}", "{vendor_dir}", "{yaml_dir}"]):
elif any(
s in a
for s in [
"{cwd}",
"{vendor_dir}",
"{yaml_dir}",
"{tmpextractdir}",
]
):
args.append(self.get_full_path(a, support_cwd=True))
else:
args.append(a)
Expand Down

0 comments on commit aae5d51

Please sign in to comment.