summaryrefslogtreecommitdiffstats
path: root/python/mozbuild/mozbuild/action/process_install_manifest.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/mozbuild/mozbuild/action/process_install_manifest.py')
-rw-r--r--python/mozbuild/mozbuild/action/process_install_manifest.py125
1 files changed, 125 insertions, 0 deletions
diff --git a/python/mozbuild/mozbuild/action/process_install_manifest.py b/python/mozbuild/mozbuild/action/process_install_manifest.py
new file mode 100644
index 0000000000..faf1376dba
--- /dev/null
+++ b/python/mozbuild/mozbuild/action/process_install_manifest.py
@@ -0,0 +1,125 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import argparse
+import os
+import sys
+import time
+
+from mozpack.copier import FileCopier, FileRegistry
+from mozpack.errors import errors
+from mozpack.files import BaseFile, FileFinder
+from mozpack.manifests import InstallManifest
+
+from mozbuild.action.util import log_build_task
+from mozbuild.util import DefinesAction
+
+COMPLETE = (
+ "Elapsed: {elapsed:.2f}s; From {dest}: Kept {existing} existing; "
+ "Added/updated {updated}; "
+ "Removed {rm_files} files and {rm_dirs} directories."
+)
+
+
+def process_manifest(destdir, paths, track, no_symlinks=False, defines={}):
+
+ if os.path.exists(track):
+ # We use the same format as install manifests for the tracking
+ # data.
+ manifest = InstallManifest(path=track)
+ remove_unaccounted = FileRegistry()
+ dummy_file = BaseFile()
+
+ finder = FileFinder(destdir, find_dotfiles=True)
+ for dest in manifest._dests:
+ for p, f in finder.find(dest):
+ remove_unaccounted.add(p, dummy_file)
+
+ remove_empty_directories = True
+ remove_all_directory_symlinks = True
+
+ else:
+ # If tracking is enabled and there is no file, we don't want to
+ # be removing anything.
+ remove_unaccounted = False
+ remove_empty_directories = False
+ remove_all_directory_symlinks = False
+
+ manifest = InstallManifest()
+ for path in paths:
+ manifest |= InstallManifest(path=path)
+
+ copier = FileCopier()
+ link_policy = "copy" if no_symlinks else "symlink"
+ manifest.populate_registry(
+ copier, defines_override=defines, link_policy=link_policy
+ )
+ with errors.accumulate():
+ result = copier.copy(
+ destdir,
+ remove_unaccounted=remove_unaccounted,
+ remove_all_directory_symlinks=remove_all_directory_symlinks,
+ remove_empty_directories=remove_empty_directories,
+ )
+
+ if track:
+ # We should record files that we actually copied.
+ # It is too late to expand wildcards when the track file is read.
+ manifest.write(path=track, expand_pattern=True)
+
+ return result
+
+
+def main(argv):
+ parser = argparse.ArgumentParser(description="Process install manifest files.")
+
+ parser.add_argument("destdir", help="Destination directory.")
+ parser.add_argument("manifests", nargs="+", help="Path to manifest file(s).")
+ parser.add_argument(
+ "--no-symlinks",
+ action="store_true",
+ help="Do not install symbolic links. Always copy files",
+ )
+ parser.add_argument(
+ "--track",
+ metavar="PATH",
+ required=True,
+ help="Use installed files tracking information from the given path.",
+ )
+ parser.add_argument(
+ "-D",
+ action=DefinesAction,
+ dest="defines",
+ metavar="VAR[=VAL]",
+ help="Define a variable to override what is specified in the manifest",
+ )
+
+ args = parser.parse_args(argv)
+
+ start = time.monotonic()
+
+ result = process_manifest(
+ args.destdir,
+ args.manifests,
+ track=args.track,
+ no_symlinks=args.no_symlinks,
+ defines=args.defines,
+ )
+
+ elapsed = time.monotonic() - start
+
+ print(
+ COMPLETE.format(
+ elapsed=elapsed,
+ dest=args.destdir,
+ existing=result.existing_files_count,
+ updated=result.updated_files_count,
+ rm_files=result.removed_files_count,
+ rm_dirs=result.removed_directories_count,
+ )
+ )
+
+
+if __name__ == "__main__":
+ log_build_task(main, sys.argv[1:])