  @contextmanager
  def make_tempdir():
      d = Path(tempfile.mkdtemp())
      yield d
      shutil.rmtree(str(d))
  
  
  def get_hash(data) -> str:
 
</s> remove 

def get_hash(data) -> str:
    data_str = srsly.json_dumps(data, sort_keys=True).encode("utf8")
    return hashlib.md5(data_str).hexdigest()


def get_checksum(path: Path) -> str:
    return hashlib.md5(path.read_bytes()).hexdigest()
 </s> add  </s> remove def check_asset(url: str) -> None:
 </s> add def convert_asset_url(url: str) -> str:
    """Check and convert the asset URL if needed.

    url (str): The asset URL.
    RETURNS (str): The converted URL.
    """ </s> remove @project_cli.command("assets")
def project_assets_cli(
    # fmt: off
    path: Path = Arg(..., help="Path to cloned project", exists=True, file_okay=False),
    # fmt: on
):
    """Use Data Version Control to get the assets for the project."""
    project_assets(path)
 </s> add def project_assets(project_dir: Path) -> None:
    """Fetch assets for a project using DVC if possible. </s> remove         updated = update_dvc_config(project_path, config, silent=True)
 </s> add         updated = update_dvc_config(project_dir, config, silent=True) </s> remove @project_cli.command("update-dvc")
def project_update_dvc_cli(
    # fmt: off
    project_dir: Path = Arg(..., help="Location of project directory", exists=True, file_okay=False),
    verbose: bool = Opt(False, "--verbose", "-V", help="Print more info"),
    force: bool = Opt(False, "--force", "-F", help="Force update DVC config"),
    # fmt: on
):
    config = load_project_config(project_dir)
    updated = update_dvc_config(project_dir, config, verbose=verbose, force=force)
    if updated:
        msg.good(f"Updated DVC config from {CONFIG_FILE}")
    else:
        msg.info(f"No changes found in {CONFIG_FILE}, no update needed")


app.add_typer(project_cli, name="project")
 </s> add ###########
# HELPERS #
###########
    """Execute a block in a temporary directory and remove the directory and
    its contents at the end of the with block.

    YIELDS (Path): The path of the temp directory.
    """
  @contextmanager
  def make_tempdir():
    """Execute a block in a temporary directory and remove the directory and
    its contents at the end of the with block.

    YIELDS (Path): The path of the temp directory.
    """
      d = Path(tempfile.mkdtemp())
      yield d
      shutil.rmtree(str(d))
  
  
  def get_hash(data) -> str:
keep add keep keep keep keep keep keep
 Tidy up, document and add custom clone logic 
spacy/util.py