diff --git a/swh/model/git.py b/swh/model/git.py --- a/swh/model/git.py +++ b/swh/model/git.py @@ -1,10 +1,11 @@ -# Copyright (C) 2015 The Software Heritage developers +# Copyright (C) 2015-2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information import os +import stat from enum import Enum @@ -160,17 +161,24 @@ Args: filepath: absolute pathname of the file. + Special file (fifo, character or + block device) are considered empty and None is returned. Returns: Dictionary of values: - name: basename of the file + - length: data length - perms: git permission for file - type: git type for file - path: absolute filepath on filesystem """ - blob_metadata = hashutil.hash_path(filepath) + mode = os.lstat(filepath).st_mode + if not stat.S_ISREG(mode): # block or character device, fifo, etc... + return None + perms = GitPerm.EXEC if os.access(filepath, os.X_OK) else GitPerm.BLOB + blob_metadata = hashutil.hash_path(filepath) blob_metadata.update({ 'name': os.path.basename(filepath), 'perms': perms, @@ -394,7 +402,8 @@ for filepath in (file for file in filenames if file not in all_links): m_hashes = compute_blob_metadata(filepath) - hashes.append(m_hashes) + if m_hashes: + hashes.append(m_hashes) ls_hashes[dirpath] = hashes @@ -494,10 +503,11 @@ for filepath in (file for file in filenames if file not in all_links): m_hashes = compute_blob_metadata(filepath) - d = _get_dict_from_filepath(ls_hashes, filepath) - d['checksums'] = m_hashes - ls_hashes[filepath] = d - children.add(filepath) + if m_hashes: + d = _get_dict_from_filepath(ls_hashes, filepath) + d['checksums'] = m_hashes + ls_hashes[filepath] = d + children.add(filepath) for fulldirname in (dir for dir in dirnames if dir not in all_links): d_hashes = _get_dict_from_dirpath(ls_hashes, fulldirname) diff --git a/swh/model/tests/test_git.py b/swh/model/tests/test_git.py --- a/swh/model/tests/test_git.py +++ b/swh/model/tests/test_git.py @@ -1,4 +1,4 @@ -# Copyright (C) 2015 The Software Heritage developers +# Copyright (C) 2015-2017 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information @@ -138,6 +138,27 @@ self.assertEqual(checksum, self.checksums['tag_sha1_git']) +@attr('fs') +class ComputeBlobMetadata(unittest.TestCase): + @istest + def compute_blob_metadata__special_file_returns_nothing(self): + # prepare + tmp_root_path = tempfile.mkdtemp().encode('utf-8') + path = os.path.join(tmp_root_path, b'fifo-file') + + # given + os.mkfifo(path) + + # when + actual_metadata = git.compute_blob_metadata(path) + + # then + self.assertIsNone(actual_metadata) + + # cleanup + shutil.rmtree(tmp_root_path) + + @attr('fs') class GitHashWalkArborescenceTree: """Root class to ease walk and git hash testing without side-effecty