Changeset View
Changeset View
Standalone View
Standalone View
swh/model/cli.py
# Copyright (C) 2018-2020 The Software Heritage developers | # Copyright (C) 2018-2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import os | import os | ||||
import sys | import sys | ||||
from typing import Dict, List, Optional | from typing import Dict, Iterable, Optional | ||||
# WARNING: do not import unnecessary things here to keep cli startup time under | # WARNING: do not import unnecessary things here to keep cli startup time under | ||||
# control | # control | ||||
try: | try: | ||||
import click | import click | ||||
except ImportError: | except ImportError: | ||||
print( | print( | ||||
"Cannot run swh-identify; the Click package is not installed." | "Cannot run swh-identify; the Click package is not installed." | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | def swhid_of_file_content(data) -> CoreSWHID: | ||||
from swh.model.hashutil import hash_to_bytes | from swh.model.hashutil import hash_to_bytes | ||||
object = Content.from_bytes(mode=644, data=data).get_data() | object = Content.from_bytes(mode=644, data=data).get_data() | ||||
return CoreSWHID( | return CoreSWHID( | ||||
object_type=ObjectType.CONTENT, object_id=hash_to_bytes(object["sha1_git"]) | object_type=ObjectType.CONTENT, object_id=hash_to_bytes(object["sha1_git"]) | ||||
) | ) | ||||
def model_of_dir(path: bytes, exclude_patterns: List[bytes] = None) -> Directory: | def model_of_dir(path: bytes, exclude_patterns: Iterable[bytes] = None) -> Directory: | ||||
from swh.model.from_disk import accept_all_directories, ignore_directories_patterns | from swh.model.from_disk import accept_all_directories, ignore_directories_patterns | ||||
dir_filter = ( | dir_filter = ( | ||||
ignore_directories_patterns(path, exclude_patterns) | ignore_directories_patterns(path, exclude_patterns) | ||||
if exclude_patterns | if exclude_patterns | ||||
else accept_all_directories | else accept_all_directories | ||||
) | ) | ||||
return Directory.from_disk(path=path, dir_filter=dir_filter) | return Directory.from_disk(path=path, dir_filter=dir_filter) | ||||
def swhid_of_dir(path: bytes, exclude_patterns: List[bytes] = None) -> CoreSWHID: | def swhid_of_dir(path: bytes, exclude_patterns: Iterable[bytes] = None) -> CoreSWHID: | ||||
from swh.model.hashutil import hash_to_bytes | from swh.model.hashutil import hash_to_bytes | ||||
obj = model_of_dir(path, exclude_patterns) | obj = model_of_dir(path, exclude_patterns) | ||||
return CoreSWHID( | return CoreSWHID( | ||||
object_type=ObjectType.DIRECTORY, object_id=hash_to_bytes(obj.get_data()["id"]) | object_type=ObjectType.DIRECTORY, object_id=hash_to_bytes(obj.get_data()["id"]) | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | def swhid_of_git_repo(path) -> CoreSWHID: | ||||
snapshot = {"branches": branches} | snapshot = {"branches": branches} | ||||
return CoreSWHID( | return CoreSWHID( | ||||
object_type=ObjectType.SNAPSHOT, | object_type=ObjectType.SNAPSHOT, | ||||
object_id=hashutil.hash_to_bytes(snapshot_identifier(snapshot)), | object_id=hashutil.hash_to_bytes(snapshot_identifier(snapshot)), | ||||
) | ) | ||||
def identify_object(obj_type, follow_symlinks, exclude_patterns, obj) -> str: | def identify_object( | ||||
obj_type: str, follow_symlinks: bool, exclude_patterns: Iterable[bytes], obj | |||||
) -> str: | |||||
from urllib.parse import urlparse | from urllib.parse import urlparse | ||||
if obj_type == "auto": | if obj_type == "auto": | ||||
if obj == "-" or os.path.isfile(obj): | if obj == "-" or os.path.isfile(obj): | ||||
obj_type = "content" | obj_type = "content" | ||||
elif os.path.isdir(obj): | elif os.path.isdir(obj): | ||||
obj_type = "directory" | obj_type = "directory" | ||||
else: | else: | ||||
Show All 10 Lines | if obj == "-": | ||||
swhid = str(swhid_of_file_content(content)) | swhid = str(swhid_of_file_content(content)) | ||||
elif obj_type in ["content", "directory"]: | elif obj_type in ["content", "directory"]: | ||||
path = obj.encode(sys.getfilesystemencoding()) | path = obj.encode(sys.getfilesystemencoding()) | ||||
if follow_symlinks and os.path.islink(obj): | if follow_symlinks and os.path.islink(obj): | ||||
path = os.path.realpath(obj) | path = os.path.realpath(obj) | ||||
if obj_type == "content": | if obj_type == "content": | ||||
swhid = str(swhid_of_file(path)) | swhid = str(swhid_of_file(path)) | ||||
elif obj_type == "directory": | elif obj_type == "directory": | ||||
swhid = str( | swhid = str(swhid_of_dir(path, exclude_patterns)) | ||||
swhid_of_dir(path, [pattern.encode() for pattern in exclude_patterns]) | |||||
) | |||||
elif obj_type == "origin": | elif obj_type == "origin": | ||||
swhid = str(swhid_of_origin(obj)) | swhid = str(swhid_of_origin(obj)) | ||||
elif obj_type == "snapshot": | elif obj_type == "snapshot": | ||||
swhid = str(swhid_of_git_repo(obj)) | swhid = str(swhid_of_git_repo(obj)) | ||||
else: # shouldn't happen, due to option validation | else: # shouldn't happen, due to option validation | ||||
raise click.BadParameter("invalid object type: " + obj_type) | raise click.BadParameter("invalid object type: " + obj_type) | ||||
# note: we return original obj instead of path here, to preserve user-given | # note: we return original obj instead of path here, to preserve user-given | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | \b | ||||
$ git clone --mirror https://forge.softwareheritage.org/source/helloworld.git | $ git clone --mirror https://forge.softwareheritage.org/source/helloworld.git | ||||
$ swh identify --type snapshot helloworld.git/ | $ swh identify --type snapshot helloworld.git/ | ||||
swh:1:snp:510aa88bdc517345d258c1fc2babcd0e1f905e93 helloworld.git | swh:1:snp:510aa88bdc517345d258c1fc2babcd0e1f905e93 helloworld.git | ||||
""" # NoQA # overlong lines in shell examples are fine | """ # NoQA # overlong lines in shell examples are fine | ||||
from functools import partial | from functools import partial | ||||
import logging | import logging | ||||
if exclude_patterns: | |||||
exclude_patterns = set(pattern.encode() for pattern in exclude_patterns) | |||||
if verify and len(objects) != 1: | if verify and len(objects) != 1: | ||||
raise click.BadParameter("verification requires a single object") | raise click.BadParameter("verification requires a single object") | ||||
if recursive and not os.path.isdir(objects[0]): | if recursive and not os.path.isdir(objects[0]): | ||||
recursive = False | recursive = False | ||||
logging.warn("recursive option disabled, input is not a directory object") | logging.warn("recursive option disabled, input is not a directory object") | ||||
if recursive: | if recursive: | ||||
▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines |