mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-12-06 10:06:11 +01:00
Backport pull request #15501 from jellyfin/release-10.11.z
Fix .ignore handling for directories
Original-merge: e8150428b6
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Bond_009 <bond.009@outlook.com>
This commit is contained in:
parent
c869b5b884
commit
5b3f29946b
1 changed files with 42 additions and 61 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.IO;
|
using MediaBrowser.Controller.IO;
|
||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
|
|
@ -13,28 +12,24 @@ namespace Emby.Server.Implementations.Library;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DotIgnoreIgnoreRule : IResolverIgnoreRule
|
public class DotIgnoreIgnoreRule : IResolverIgnoreRule
|
||||||
{
|
{
|
||||||
|
private static readonly bool IsWindows = OperatingSystem.IsWindows();
|
||||||
|
|
||||||
private static FileInfo? FindIgnoreFile(DirectoryInfo directory)
|
private static FileInfo? FindIgnoreFile(DirectoryInfo directory)
|
||||||
{
|
{
|
||||||
var ignoreFile = new FileInfo(Path.Join(directory.FullName, ".ignore"));
|
for (var current = directory; current is not null; current = current.Parent)
|
||||||
if (ignoreFile.Exists)
|
|
||||||
{
|
{
|
||||||
return ignoreFile;
|
var ignorePath = Path.Join(current.FullName, ".ignore");
|
||||||
|
if (File.Exists(ignorePath))
|
||||||
|
{
|
||||||
|
return new FileInfo(ignorePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentDir = directory.Parent;
|
return null;
|
||||||
if (parentDir is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FindIgnoreFile(parentDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem? parent)
|
public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem? parent) => IsIgnored(fileInfo, parent);
|
||||||
{
|
|
||||||
return IsIgnored(fileInfo, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks whether or not the file is ignored.
|
/// Checks whether or not the file is ignored.
|
||||||
|
|
@ -44,72 +39,58 @@ public class DotIgnoreIgnoreRule : IResolverIgnoreRule
|
||||||
/// <returns>True if the file should be ignored.</returns>
|
/// <returns>True if the file should be ignored.</returns>
|
||||||
public static bool IsIgnored(FileSystemMetadata fileInfo, BaseItem? parent)
|
public static bool IsIgnored(FileSystemMetadata fileInfo, BaseItem? parent)
|
||||||
{
|
{
|
||||||
if (fileInfo.IsDirectory)
|
var searchDirectory = fileInfo.IsDirectory
|
||||||
{
|
? new DirectoryInfo(fileInfo.FullName)
|
||||||
var dirIgnoreFile = FindIgnoreFile(new DirectoryInfo(fileInfo.FullName));
|
: new DirectoryInfo(Path.GetDirectoryName(fileInfo.FullName) ?? string.Empty);
|
||||||
if (dirIgnoreFile is null)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fast path in case the ignore files isn't a symlink and is empty
|
if (string.IsNullOrEmpty(searchDirectory.FullName))
|
||||||
if (dirIgnoreFile.LinkTarget is null && dirIgnoreFile.Length == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore the directory only if the .ignore file is empty
|
|
||||||
// evaluate individual files otherwise
|
|
||||||
return string.IsNullOrWhiteSpace(GetFileContent(dirIgnoreFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
var parentDirPath = Path.GetDirectoryName(fileInfo.FullName);
|
|
||||||
if (string.IsNullOrEmpty(parentDirPath))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var folder = new DirectoryInfo(parentDirPath);
|
var ignoreFile = FindIgnoreFile(searchDirectory);
|
||||||
var ignoreFile = FindIgnoreFile(folder);
|
|
||||||
if (ignoreFile is null)
|
if (ignoreFile is null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ignoreFileString = GetFileContent(ignoreFile);
|
// Fast path in case the ignore files isn't a symlink and is empty
|
||||||
|
if (ignoreFile.LinkTarget is null && ignoreFile.Length == 0)
|
||||||
if (string.IsNullOrWhiteSpace(ignoreFileString))
|
|
||||||
{
|
{
|
||||||
// Ignore directory if we just have the file
|
// Ignore directory if we just have the file
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If file has content, base ignoring off the content .gitignore-style rules
|
var content = GetFileContent(ignoreFile);
|
||||||
var ignoreRules = ignoreFileString.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
return string.IsNullOrWhiteSpace(content)
|
||||||
var ignore = new Ignore.Ignore();
|
|| CheckIgnoreRules(fileInfo.FullName, content, fileInfo.IsDirectory);
|
||||||
ignore.Add(ignoreRules);
|
|
||||||
|
|
||||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
||||||
{
|
|
||||||
// Mitigate the problem of the Ignore library not handling Windows paths correctly.
|
|
||||||
// See https://github.com/jellyfin/jellyfin/issues/15484
|
|
||||||
return ignore.IsIgnored(fileInfo.FullName.NormalizePath('/'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ignore.IsIgnored(fileInfo.FullName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetFileContent(FileInfo dirIgnoreFile)
|
private static bool CheckIgnoreRules(string path, string ignoreFileContent, bool isDirectory)
|
||||||
{
|
{
|
||||||
dirIgnoreFile = FileSystemHelper.ResolveLinkTarget(dirIgnoreFile, returnFinalTarget: true) ?? dirIgnoreFile;
|
// If file has content, base ignoring off the content .gitignore-style rules
|
||||||
if (!dirIgnoreFile.Exists)
|
var rules = ignoreFileContent.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||||
|
var ignore = new Ignore.Ignore();
|
||||||
|
ignore.Add(rules);
|
||||||
|
|
||||||
|
// Mitigate the problem of the Ignore library not handling Windows paths correctly.
|
||||||
|
// See https://github.com/jellyfin/jellyfin/issues/15484
|
||||||
|
var pathToCheck = IsWindows ? path.NormalizePath('/') : path;
|
||||||
|
|
||||||
|
// Add trailing slash for directories to match "folder/"
|
||||||
|
if (isDirectory)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
pathToCheck = string.Concat(pathToCheck.AsSpan().TrimEnd('/'), "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var reader = dirIgnoreFile.OpenText())
|
return ignore.IsIgnored(pathToCheck);
|
||||||
{
|
}
|
||||||
return reader.ReadToEnd();
|
|
||||||
}
|
private static string GetFileContent(FileInfo ignoreFile)
|
||||||
|
{
|
||||||
|
ignoreFile = FileSystemHelper.ResolveLinkTarget(ignoreFile, returnFinalTarget: true) ?? ignoreFile;
|
||||||
|
return ignoreFile.Exists
|
||||||
|
? File.ReadAllText(ignoreFile.FullName)
|
||||||
|
: string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue