aboutsummaryrefslogtreecommitdiffstats
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/servo/bootstrap_commands.py175
-rw-r--r--python/servo/build_commands.py20
2 files changed, 175 insertions, 20 deletions
diff --git a/python/servo/bootstrap_commands.py b/python/servo/bootstrap_commands.py
index a3016014792..da182198ac4 100644
--- a/python/servo/bootstrap_commands.py
+++ b/python/servo/bootstrap_commands.py
@@ -18,6 +18,7 @@ import shutil
import subprocess
import sys
import urllib2
+import glob
from mach.decorators import (
CommandArgument,
@@ -26,7 +27,7 @@ from mach.decorators import (
)
import servo.bootstrap as bootstrap
-from servo.command_base import CommandBase, BIN_SUFFIX
+from servo.command_base import CommandBase, BIN_SUFFIX, cd
from servo.util import delete, download_bytes, download_file, extract, host_triple
@@ -346,3 +347,175 @@ class MachCommands(CommandBase):
elif not force:
print("Nothing done. "
"Run `./mach clean-nightlies -f` to actually remove.")
+
+ @Command('clean-cargo-cache',
+ description='Clean unused Cargo packages',
+ category='bootstrap')
+ @CommandArgument('--force', '-f',
+ action='store_true',
+ help='Actually remove stuff')
+ @CommandArgument('--show-size', '-s',
+ action='store_true',
+ help='Show packages size')
+ @CommandArgument('--keep',
+ default='1',
+ help='Keep up to this many most recent dependencies')
+ @CommandArgument('--custom-path', '-c',
+ action='store_true',
+ help='Get Cargo path from CARGO_HOME environment variable')
+ def clean_cargo_cache(self, force=False, show_size=False, keep=None, custom_path=False):
+ def get_size(path):
+ if os.path.isfile(path):
+ return os.path.getsize(path) / (1024 * 1024.0)
+ total_size = 0
+ for dirpath, dirnames, filenames in os.walk(path):
+ for f in filenames:
+ fp = os.path.join(dirpath, f)
+ total_size += os.path.getsize(fp)
+ return total_size / (1024 * 1024.0)
+
+ removing_anything = False
+ packages = {
+ 'crates': {},
+ 'git': {},
+ }
+ import toml
+ if os.environ.get("CARGO_HOME", "") and custom_path:
+ cargo_dir = os.environ.get("CARGO_HOME")
+ else:
+ cargo_dir = path.join(self.context.topdir, ".cargo")
+ cargo_file = open(path.join(self.context.topdir, "Cargo.lock"))
+ content = toml.load(cargo_file)
+
+ for package in content.get("package", []):
+ source = package.get("source", "")
+ version = package["version"]
+ if source == u"registry+https://github.com/rust-lang/crates.io-index":
+ crate_name = "{}-{}".format(package["name"], version)
+ if not packages["crates"].get(crate_name, False):
+ packages["crates"][package["name"]] = {
+ "current": [],
+ "exist": [],
+ }
+ packages["crates"][package["name"]]["current"].append(crate_name)
+ elif source.startswith("git+"):
+ name = source.split("#")[0].split("/")[-1].replace(".git", "")
+ branch = ""
+ crate_name = "{}-{}".format(package["name"], source.split("#")[1])
+ crate_branch = name.split("?")
+ if len(crate_branch) > 1:
+ branch = crate_branch[1].replace("branch=", "")
+ name = crate_branch[0]
+
+ if not packages["git"].get(name, False):
+ packages["git"][name] = {
+ "current": [],
+ "exist": [],
+ }
+ packages["git"][name]["current"].append(source.split("#")[1][:7])
+ if branch:
+ packages["git"][name]["current"].append(branch)
+
+ crates_dir = path.join(cargo_dir, "registry")
+ crates_cache_dir = ""
+ crates_src_dir = ""
+ if os.path.isdir(path.join(crates_dir, "cache")):
+ for p in os.listdir(path.join(crates_dir, "cache")):
+ crates_cache_dir = path.join(crates_dir, "cache", p)
+ crates_src_dir = path.join(crates_dir, "src", p)
+
+ git_dir = path.join(cargo_dir, "git")
+ git_db_dir = path.join(git_dir, "db")
+ git_checkout_dir = path.join(git_dir, "checkouts")
+ git_db_list = filter(lambda f: not f.startswith('.'), os.listdir(git_db_dir))
+ git_checkout_list = os.listdir(git_checkout_dir)
+
+ for d in list(set(git_db_list + git_checkout_list)):
+ crate_name = d.replace("-{}".format(d.split("-")[-1]), "")
+ if not packages["git"].get(crate_name, False):
+ packages["git"][crate_name] = {
+ "current": [],
+ "exist": [],
+ }
+ if os.path.isdir(path.join(git_checkout_dir, d)):
+ for d2 in os.listdir(path.join(git_checkout_dir, d)):
+ dep_path = path.join(git_checkout_dir, d, d2)
+ if os.path.isdir(dep_path):
+ packages["git"][crate_name]["exist"].append((path.getmtime(dep_path), d, d2))
+ elif os.path.isdir(path.join(git_db_dir, d)):
+ packages["git"][crate_name]["exist"].append(("db", d, ""))
+
+ for d in os.listdir(crates_src_dir):
+ crate_name = re.sub(r"\-\d+(\.\d+){1,3}.+", "", d)
+ if not packages["crates"].get(crate_name, False):
+ packages["crates"][crate_name] = {
+ "current": [],
+ "exist": [],
+ }
+ packages["crates"][crate_name]["exist"].append(d)
+
+ total_size = 0
+ for packages_type in ["git", "crates"]:
+ sorted_packages = sorted(packages[packages_type])
+ for crate_name in sorted_packages:
+ crate_count = 0
+ existed_crates = packages[packages_type][crate_name]["exist"]
+ for exist in sorted(existed_crates, reverse=True):
+ current_crate = packages[packages_type][crate_name]["current"]
+ size = 0
+ exist_name = exist
+ exist_item = exist[2] if packages_type == "git" else exist
+ if exist_item not in current_crate:
+ crate_count += 1
+ removing_anything = True
+ if int(crate_count) >= int(keep) or not current_crate:
+ crate_paths = []
+ if packages_type == "git":
+ exist_checkout_path = path.join(git_checkout_dir, exist[1])
+ exist_db_path = path.join(git_db_dir, exist[1])
+ exist_name = path.join(exist[1], exist[2])
+ exist_path = path.join(git_checkout_dir, exist_name)
+
+ if exist[0] == "db":
+ crate_paths.append(exist_db_path)
+ crate_count += -1
+ else:
+ crate_paths.append(exist_path)
+
+ # remove crate from checkout if doesn't exist in db directory
+ if not os.path.isdir(exist_db_path):
+ crate_count += -1
+
+ with cd(path.join(exist_path, ".git", "objects", "pack")):
+ for pack in glob.glob("*"):
+ pack_path = path.join(exist_db_path, "objects", "pack", pack)
+ if os.path.exists(pack_path):
+ crate_paths.append(pack_path)
+
+ if len(os.listdir(exist_checkout_path)) <= 1:
+ crate_paths.append(exist_checkout_path)
+ if os.path.isdir(exist_db_path):
+ crate_paths.append(exist_db_path)
+ else:
+ crate_paths.append(path.join(crates_cache_dir, "{}.crate".format(exist)))
+ crate_paths.append(path.join(crates_src_dir, exist))
+
+ size = sum(get_size(p) for p in crate_paths) if show_size else 0
+ total_size += size
+ print_msg = (exist_name, " ({}MB)".format(round(size, 2)) if show_size else "", cargo_dir)
+ if force:
+ print("Removing `{}`{} package from {}".format(*print_msg))
+ for crate_path in crate_paths:
+ if os.path.exists(crate_path):
+ delete(crate_path)
+ else:
+ print("Would remove `{}`{} package from {}".format(*print_msg))
+
+ if removing_anything and show_size:
+ print("\nTotal size of {} MB".format(round(total_size, 2)))
+
+ if not removing_anything:
+ print("Nothing to remove.")
+ elif not force:
+ print("\nNothing done. "
+ "Run `./mach clean-cargo-cache -f` to actually remove.")
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py
index 792b6071145..3a33f5f3b0d 100644
--- a/python/servo/build_commands.py
+++ b/python/servo/build_commands.py
@@ -24,7 +24,7 @@ from mach.decorators import (
Command,
)
-from servo.command_base import CommandBase, cd, call, BIN_SUFFIX, find_dep_path_newest
+from servo.command_base import CommandBase, cd, call, BIN_SUFFIX
from servo.util import host_triple
@@ -413,7 +413,6 @@ class MachCommands(CommandBase):
self.ensure_bootstrapped()
env = self.build_env(is_build=True, geckolib=True)
- geckolib_build_path = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
ret = None
opts = []
@@ -433,14 +432,6 @@ class MachCommands(CommandBase):
if features:
opts += ["--features", ' '.join(features)]
- if with_gecko is not None:
- print("Generating atoms data...")
- run_file = path.join(self.context.topdir, "components",
- "style", "binding_tools", "regen_atoms.py")
- run_globals = {"__file__": run_file}
- execfile(run_file, run_globals)
- run_globals["generate_atoms"](env["MOZ_DIST"])
-
build_start = time()
with cd(path.join("ports", "geckolib")):
ret = call(["cargo", "build"] + opts, env=env, verbose=verbose)
@@ -451,15 +442,6 @@ class MachCommands(CommandBase):
print("GeckoLib build completed in %s" % format_duration(elapsed))
- if with_gecko is not None:
- print("Copying binding files to style/gecko_bindings...")
- build_path = path.join(geckolib_build_path, "release" if release else "debug", "")
- target_style_path = find_dep_path_newest("style", build_path)
- out_gecko_path = path.join(target_style_path, "out", "gecko")
- bindings_path = path.join(self.context.topdir, "components", "style", "gecko_bindings")
- for f in ["bindings.rs", "structs_debug.rs", "structs_release.rs"]:
- shutil.copy(path.join(out_gecko_path, f), bindings_path)
-
return ret
@Command('clean',