def add()

in tools/registry.py [0:0]


  def add(self, module, override=False):
    """
    Add a new module version, the module must be already initialized

    Parameters
    ----------
    module : Module
        A Module instance containing information of the module version to
        be added
    override : Whether to override existing module
    """
    # Check if the module version already exists
    if self.contains(module.name, module.version):
      if override:
        log("Overridding module '%s' at version '%s'..." %
            (module.name, module.version))
        self.delete(module.name, module.version)
      else:
        raise RegistryException(
            f"Version {module.version} for module {module.name} already exists.")

    p = self.root.joinpath("modules", module.name, module.version)
    p.mkdir()

    # Create MODULE.bazel
    module_dot_bazel = p.joinpath("MODULE.bazel")
    if module.module_dot_bazel:
      # TODO(pcloudy): Sanity check the given MODULE.bazel
      #   - module name and version should match the specified values
      #   - no override is used
      shutil.copy(module.module_dot_bazel, module_dot_bazel)
    else:
      deps = "\n".join(
          f"bazel_dep(name = \"{name}\", version = \"{version}\")"
          for name, version in module.deps)
      with module_dot_bazel.open("w") as f:
        f.write(self._MODULE_BAZEL.format(
            module.name, module.version,
            module.compatibility_level))
        if deps:
          f.write("\n")
          f.write(deps)
        f.write("\n")

    # Create source.json & copy patch files to the registry
    source = {
        "url": module.url,
        "integrity": integrity(download(module.url)),
    }
    if module.strip_prefix:
      source["strip_prefix"] = module.strip_prefix

    patch_dir = p.joinpath("patches")
    if module.patches or module.build_file:
      patch_dir.mkdir()
      source["patches"] = {}
      source["patch_strip"] = module.patch_strip

    if module.patches:
      for s in module.patches:
        patch = pathlib.Path(s)
        source["patches"][patch.name] = integrity(read(patch))
        shutil.copy(patch, patch_dir)

    # Turn additional BUILD file into a patch
    if module.build_file:
      build_file_content = pathlib.Path(module.build_file).open().readlines()
      build_file = "a/" * module.patch_strip + "BUILD.bazel"
      patch_content = difflib.unified_diff(
          [], build_file_content, "/dev/null", build_file)
      patch_name = "add_build_file.patch"
      patch = patch_dir.joinpath(patch_name)
      with patch.open("w") as f:
        f.writelines(patch_content)
      source["patches"][patch_name] = integrity(read(patch))

    json_dump(p.joinpath("source.json"), source)

    # Create presubmit.yml file
    presubmit_yml = p.joinpath("presubmit.yml")
    if module.presubmit_yml:
      shutil.copy(module.presubmit_yml, presubmit_yml)
    else:
      PLATFORMS = ["centos7", "debian10", "ubuntu2004", "macos", "windows"]
      presubmit = {
        "matrix": {
          "platform": PLATFORMS.copy(),
        },
        "tasks": {
          "verify_targets": {
            "name": "Verify build targets",
            "platform": "${{ platform }}",
            "build_targets": module.build_targets.copy()
          }
        }
      }

      if module.test_module_path:
        task = {
          "name": "Run test module",
          "platform": "${{ platform }}",
        }
        if module.test_module_build_targets:
          task["build_targets"] = module.test_module_build_targets.copy()
        if module.test_module_test_targets:
          task["test_targets"] = module.test_module_test_targets.copy()
        presubmit["bcr_test_module"] = {
          "module_path": module.test_module_path,
          "matrix": {
            "platform": PLATFORMS.copy(),
          },
          "tasks": {
            "run_test_module": task
          }
        }

      with presubmit_yml.open("w") as f:
        yaml.dump(presubmit, f, sort_keys=False)

    # Add new version to metadata.json
    metadata_path = self.root.joinpath("modules", module.name,
                                       "metadata.json")
    metadata = json.load(metadata_path.open())
    metadata["versions"].append(module.version)
    metadata["versions"] = list(set(metadata["versions"]))
    # TODO(pcloudy): versions should be sorted with the same logic in Bzlmod.
    metadata["versions"].sort()
    json_dump(metadata_path, metadata)