< Summary - Jellyfin

Information
Class: Emby.Server.Implementations.Library.DotIgnoreIgnoreRule
Assembly: Emby.Server.Implementations
File(s): /srv/git/jellyfin/Emby.Server.Implementations/Library/DotIgnoreIgnoreRule.cs
Line coverage
38%
Covered lines: 12
Uncovered lines: 19
Coverable lines: 31
Total lines: 96
Line coverage: 38.7%
Branch coverage
30%
Covered branches: 8
Total branches: 26
Branch coverage: 30.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 8/15/2025 - 12:10:51 AM Line coverage: 56.6% (17/30) Branch coverage: 57.1% (8/14) Total lines: 949/13/2025 - 12:11:04 AM Line coverage: 51.5% (17/33) Branch coverage: 44.4% (8/18) Total lines: 10110/28/2025 - 12:11:27 AM Line coverage: 48.5% (17/35) Branch coverage: 36.3% (8/22) Total lines: 10611/18/2025 - 12:11:25 AM Line coverage: 38.7% (12/31) Branch coverage: 30.7% (8/26) Total lines: 96 8/15/2025 - 12:10:51 AM Line coverage: 56.6% (17/30) Branch coverage: 57.1% (8/14) Total lines: 949/13/2025 - 12:11:04 AM Line coverage: 51.5% (17/33) Branch coverage: 44.4% (8/18) Total lines: 10110/28/2025 - 12:11:27 AM Line coverage: 48.5% (17/35) Branch coverage: 36.3% (8/22) Total lines: 10611/18/2025 - 12:11:25 AM Line coverage: 38.7% (12/31) Branch coverage: 30.7% (8/26) Total lines: 96

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
FindIgnoreFile(...)75%4480%
ShouldIgnore(...)100%11100%
IsIgnored(...)35.71%331453.84%
CheckIgnoreRules(...)0%2040%
GetFileContent(...)0%2040%

File(s)

/srv/git/jellyfin/Emby.Server.Implementations/Library/DotIgnoreIgnoreRule.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using MediaBrowser.Controller.Entities;
 4using MediaBrowser.Controller.IO;
 5using MediaBrowser.Controller.Resolvers;
 6using MediaBrowser.Model.IO;
 7
 8namespace Emby.Server.Implementations.Library;
 9
 10/// <summary>
 11/// Resolver rule class for ignoring files via .ignore.
 12/// </summary>
 13public class DotIgnoreIgnoreRule : IResolverIgnoreRule
 14{
 015    private static readonly bool IsWindows = OperatingSystem.IsWindows();
 16
 17    private static FileInfo? FindIgnoreFile(DirectoryInfo directory)
 18    {
 180219        for (var current = directory; current is not null; current = current.Parent)
 20        {
 78521            var ignorePath = Path.Join(current.FullName, ".ignore");
 78522            if (File.Exists(ignorePath))
 23            {
 024                return new FileInfo(ignorePath);
 25            }
 26        }
 27
 11628        return null;
 29    }
 30
 31    /// <inheritdoc />
 8232    public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem? parent) => IsIgnored(fileInfo, parent);
 33
 34    /// <summary>
 35    /// Checks whether or not the file is ignored.
 36    /// </summary>
 37    /// <param name="fileInfo">The file information.</param>
 38    /// <param name="parent">The parent BaseItem.</param>
 39    /// <returns>True if the file should be ignored.</returns>
 40    public static bool IsIgnored(FileSystemMetadata fileInfo, BaseItem? parent)
 41    {
 11642        var searchDirectory = fileInfo.IsDirectory
 11643            ? new DirectoryInfo(fileInfo.FullName)
 11644            : new DirectoryInfo(Path.GetDirectoryName(fileInfo.FullName) ?? string.Empty);
 45
 11646        if (string.IsNullOrEmpty(searchDirectory.FullName))
 47        {
 048            return false;
 49        }
 50
 11651        var ignoreFile = FindIgnoreFile(searchDirectory);
 11652        if (ignoreFile is null)
 53        {
 11654            return false;
 55        }
 56
 57        // Fast path in case the ignore files isn't a symlink and is empty
 058        if (ignoreFile.LinkTarget is null && ignoreFile.Length == 0)
 59        {
 60            // Ignore directory if we just have the file
 061            return true;
 62        }
 63
 064        var content = GetFileContent(ignoreFile);
 065        return string.IsNullOrWhiteSpace(content)
 066            || CheckIgnoreRules(fileInfo.FullName, content, fileInfo.IsDirectory);
 67    }
 68
 69    private static bool CheckIgnoreRules(string path, string ignoreFileContent, bool isDirectory)
 70    {
 71        // If file has content, base ignoring off the content .gitignore-style rules
 072        var rules = ignoreFileContent.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
 073        var ignore = new Ignore.Ignore();
 074        ignore.Add(rules);
 75
 76         // Mitigate the problem of the Ignore library not handling Windows paths correctly.
 77         // See https://github.com/jellyfin/jellyfin/issues/15484
 078        var pathToCheck = IsWindows ? path.NormalizePath('/') : path;
 79
 80        // Add trailing slash for directories to match "folder/"
 081        if (isDirectory)
 82        {
 083            pathToCheck = string.Concat(pathToCheck.AsSpan().TrimEnd('/'), "/");
 84        }
 85
 086        return ignore.IsIgnored(pathToCheck);
 87    }
 88
 89    private static string GetFileContent(FileInfo ignoreFile)
 90    {
 091        ignoreFile = FileSystemHelper.ResolveLinkTarget(ignoreFile, returnFinalTarget: true) ?? ignoreFile;
 092        return ignoreFile.Exists
 093            ? File.ReadAllText(ignoreFile.FullName)
 094            : string.Empty;
 95    }
 96}