# Path: pre_commit_hooks/destroyed_symlinks.py
# def find_destroyed_symlinks(files: Sequence[str]) -> list[str]:
#     destroyed_links: list[str] = []
#     if not files:
#         return destroyed_links
#     for line in zsplit(
#         cmd_output('git', 'status', '--porcelain=v2', '-z', '--', *files),
#     ):
#         splitted = line.split(' ')
#         if splitted and splitted[0] == ORDINARY_CHANGED_ENTRIES_MARKER:
#             # https://git-scm.com/docs/git-status#_changed_tracked_entries
#             (
#                 _, _, _,
#                 mode_HEAD,
#                 mode_index,
#                 _,
#                 hash_HEAD,
#                 hash_index,
#                 *path_splitted,
#             ) = splitted
#             path = ' '.join(path_splitted)
#             if (
#                     mode_HEAD == PERMS_LINK and
#                     mode_index != PERMS_LINK and
#                     mode_index != PERMS_NONEXIST
#             ):
#                 if hash_HEAD == hash_index:
#                     # if old and new hashes are equal, it's not needed to check
#                     # anything more, we've found a destroyed symlink for sure
#                     destroyed_links.append(path)
#                 else:
#                     # if old and new hashes are *not* equal, it doesn't mean
#                     # that everything is OK - new file may be altered
#                     # by something like trailing-whitespace and/or
#                     # mixed-line-ending hooks so we need to go deeper
#                     SIZE_CMD = ('git', 'cat-file', '-s')
#                     size_index = int(cmd_output(*SIZE_CMD, hash_index).strip())
#                     size_HEAD = int(cmd_output(*SIZE_CMD, hash_HEAD).strip())
# 
#                     # in the worst case new file may have CRLF added
#                     # so check content only if new file is bigger
#                     # not more than 2 bytes compared to the old one
#                     if size_index <= size_HEAD + 2:
#                         head_content = subprocess.check_output(
#                             ('git', 'cat-file', '-p', hash_HEAD),
#                         ).rstrip()
#                         index_content = subprocess.check_output(
#                             ('git', 'cat-file', '-p', hash_index),
#                         ).rstrip()
#                         if head_content == index_content:
#                             destroyed_links.append(path)
#     return destroyed_links
# 
# Path: pre_commit_hooks/destroyed_symlinks.py
# def main(argv: Sequence[str] | None = None) -> int:
#     parser = argparse.ArgumentParser()
#     parser.add_argument('filenames', nargs='*', help='Filenames to check.')
#     args = parser.parse_args(argv)
#     destroyed_links = find_destroyed_symlinks(files=args.filenames)
#     if destroyed_links:
#         print('Destroyed symlinks:')
#         for destroyed_link in destroyed_links:
#             print(f'- {destroyed_link}')
#         print('You should unstage affected files:')
#         print(
#             '\tgit reset HEAD -- {}'.format(
#                 ' '.join(shlex.quote(link) for link in destroyed_links),
#             ),
#         )
#         print(
#             'And retry commit. As a long term solution '
#             'you may try to explicitly tell git that your '
#             'environment does not support symlinks:',
#         )
#         print('\tgit config core.symlinks false')
#         return 1
#     else:
#         return 0
# 
# Path: testing/util.py
# def git_commit(*args, **kwargs):
#     cmd = ('git', 'commit', '--no-gpg-sign', '--no-verify', '--no-edit', *args)
#     subprocess.check_call(cmd, **kwargs)


import os
import subprocess
import pytest
from pre_commit_hooks.destroyed_symlinks import find_destroyed_symlinks
from pre_commit_hooks.destroyed_symlinks import main
from testing.util import git_commit
from __future__ import annotations




TEST_SYMLINK = 'test_symlink'
TEST_SYMLINK_TARGET = '/doesnt/really/matters'
TEST_FILE = 'test_file'
TEST_FILE_RENAMED = f'{TEST_FILE}_renamed'


@pytest.fixture
def repo_with_destroyed_symlink(tmpdir):
    source_repo = tmpdir.join('src')
    os.makedirs(source_repo, exist_ok=True)
    test_repo = tmpdir.join('test')
    with source_repo.as_cwd():
        subprocess.check_call(('git', 'init'))
        os.symlink(TEST_SYMLINK_TARGET, TEST_SYMLINK)
        with open(TEST_FILE, 'w') as f:
            print('some random content', file=f)
        subprocess.check_call(('git', 'add', '.'))

# Path: pre_commit_hooks/destroyed_symlinks.py
# def find_destroyed_symlinks(files: Sequence[str]) -> list[str]:
#     destroyed_links: list[str] = []
#     if not files:
#         return destroyed_links
#     for line in zsplit(
#         cmd_output('git', 'status', '--porcelain=v2', '-z', '--', *files),
#     ):
#         splitted = line.split(' ')
#         if splitted and splitted[0] == ORDINARY_CHANGED_ENTRIES_MARKER:
#             # https://git-scm.com/docs/git-status#_changed_tracked_entries
#             (
#                 _, _, _,
#                 mode_HEAD,
#                 mode_index,
#                 _,
#                 hash_HEAD,
#                 hash_index,
#                 *path_splitted,
#             ) = splitted
#             path = ' '.join(path_splitted)
#             if (
#                     mode_HEAD == PERMS_LINK and
#                     mode_index != PERMS_LINK and
#                     mode_index != PERMS_NONEXIST
#             ):
#                 if hash_HEAD == hash_index:
#                     # if old and new hashes are equal, it's not needed to check
#                     # anything more, we've found a destroyed symlink for sure
#                     destroyed_links.append(path)
#                 else:
#                     # if old and new hashes are *not* equal, it doesn't mean
#                     # that everything is OK - new file may be altered
#                     # by something like trailing-whitespace and/or
#                     # mixed-line-ending hooks so we need to go deeper
#                     SIZE_CMD = ('git', 'cat-file', '-s')
#                     size_index = int(cmd_output(*SIZE_CMD, hash_index).strip())
#                     size_HEAD = int(cmd_output(*SIZE_CMD, hash_HEAD).strip())
# 
#                     # in the worst case new file may have CRLF added
#                     # so check content only if new file is bigger
#                     # not more than 2 bytes compared to the old one
#                     if size_index <= size_HEAD + 2:
#                         head_content = subprocess.check_output(
#                             ('git', 'cat-file', '-p', hash_HEAD),
#                         ).rstrip()
#                         index_content = subprocess.check_output(
#                             ('git', 'cat-file', '-p', hash_index),
#                         ).rstrip()
#                         if head_content == index_content:
#                             destroyed_links.append(path)
#     return destroyed_links
# 
# Path: pre_commit_hooks/destroyed_symlinks.py
# def main(argv: Sequence[str] | None = None) -> int:
#     parser = argparse.ArgumentParser()
#     parser.add_argument('filenames', nargs='*', help='Filenames to check.')
#     args = parser.parse_args(argv)
#     destroyed_links = find_destroyed_symlinks(files=args.filenames)
#     if destroyed_links:
#         print('Destroyed symlinks:')
#         for destroyed_link in destroyed_links:
#             print(f'- {destroyed_link}')
#         print('You should unstage affected files:')
#         print(
#             '\tgit reset HEAD -- {}'.format(
#                 ' '.join(shlex.quote(link) for link in destroyed_links),
#             ),
#         )
#         print(
#             'And retry commit. As a long term solution '
#             'you may try to explicitly tell git that your '
#             'environment does not support symlinks:',
#         )
#         print('\tgit config core.symlinks false')
#         return 1
#     else:
#         return 0
# 
# Path: testing/util.py
# def git_commit(*args, **kwargs):
#     cmd = ('git', 'commit', '--no-gpg-sign', '--no-verify', '--no-edit', *args)
#     subprocess.check_call(cmd, **kwargs)


# Path: tests/destroyed_symlinks_test.py
import os
import subprocess
import pytest
from pre_commit_hooks.destroyed_symlinks import find_destroyed_symlinks
from pre_commit_hooks.destroyed_symlinks import main
from testing.util import git_commit

from __future__ import annotations




TEST_SYMLINK = 'test_symlink'
TEST_SYMLINK_TARGET = '/doesnt/really/matters'
TEST_FILE = 'test_file'
TEST_FILE_RENAMED = f'{TEST_FILE}_renamed'


@pytest.fixture
def repo_with_destroyed_symlink(tmpdir):
    source_repo = tmpdir.join('src')
    os.makedirs(source_repo, exist_ok=True)
    test_repo = tmpdir.join('test')
    with source_repo.as_cwd():
        subprocess.check_call(('git', 'init'))
        os.symlink(TEST_SYMLINK_TARGET, TEST_SYMLINK)
        with open(TEST_FILE, 'w') as f:
            print('some random content', file=f)
        subprocess.check_call(('git', 'add', '.'))

        git_commit('-m', 'initial')