diff --git a/CHANGELOG.md b/CHANGELOG.md index da9e5fb8b2..8bdf7d823b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## [5.1.5] - 2022-12-22 + +### Fixed +* Call ignoreFile.IsIgnored with absolute path. [#2656](https://github.com/fsprojects/fantomas/pull/2656) + ## [5.1.4] - 2022-11-30 ### Fixed diff --git a/src/Fantomas.Tests/Integration/DaemonTests.fs b/src/Fantomas.Tests/Integration/DaemonTests.fs index 84eb3885e2..74730dd6ca 100644 --- a/src/Fantomas.Tests/Integration/DaemonTests.fs +++ b/src/Fantomas.Tests/Integration/DaemonTests.fs @@ -320,3 +320,32 @@ let add (a : int) (b : int) = // " | otherResponse -> Assert.Fail $"Unexpected response %A{otherResponse}" }) + +[] +let ``format nested ignored file`` () = + runWithDaemon (fun client -> + async { + let sourceCode = "let foo = 4" + + use codeFile = + new TemporaryFileCodeSample( + sourceCode, + fileName = "NicePrint", + subFolders = [| "src"; "Compiler"; "Checking" |] + ) + + use _ignoreFixture = new FantomasIgnoreFile("src/Compiler/Checking/NicePrint.fs") + + let request = + { SourceCode = sourceCode + FilePath = codeFile.Filename + Config = None } + + let! response = + client.InvokeAsync(Methods.FormatDocument, request) + |> Async.AwaitTask + + match response with + | FormatDocumentResponse.IgnoredFile _ -> Assert.Pass() + | otherResponse -> Assert.Fail $"Unexpected response %A{otherResponse}" + }) diff --git a/src/Fantomas/IgnoreFile.fs b/src/Fantomas/IgnoreFile.fs index 09d0fdff5b..87032b6520 100644 --- a/src/Fantomas/IgnoreFile.fs +++ b/src/Fantomas/IgnoreFile.fs @@ -3,9 +3,20 @@ namespace Fantomas open System.IO.Abstractions open Ignore +type AbsoluteFilePath = + private + | AbsoluteFilePath of string + + member x.Path = + let (AbsoluteFilePath(path)) = x + path + + static member Create (fs: IFileSystem) (filePath: string) = + fs.Path.GetFullPath filePath |> AbsoluteFilePath + /// The string argument is taken relative to the location /// of the ignore-file. -type IsPathIgnored = string -> bool +type IsPathIgnored = AbsoluteFilePath -> bool type IgnoreFile = { Location: IFileInfo @@ -46,7 +57,7 @@ module IgnoreFile = (Ignore(), lines) ||> Array.fold (fun (ig: Ignore) (line: string) -> ig.Add(line)) - fun path -> + fun (absoluteFilePath: AbsoluteFilePath) -> // See https://git-scm.com/docs/gitignore // We transform the incoming path relative to the .ignoreFilePath folder. // In a cli scenario that is the current directory, for the daemon it is the first found ignore file. @@ -54,7 +65,7 @@ module IgnoreFile = let relativePath = fs .Path - .GetRelativePath(fs.Directory.GetParent(ignoreFilePath).FullName, path) + .GetRelativePath(fs.Directory.GetParent(ignoreFilePath).FullName, absoluteFilePath.Path) .Replace("\\", "/") fantomasIgnore.IsIgnored(relativePath) @@ -74,19 +85,10 @@ module IgnoreFile = | None -> false | Some ignoreFile -> let fs = ignoreFile.Location.FileSystem - let fullPath = fs.Path.GetFullPath(file) + let fullPath = AbsoluteFilePath.Create fs file try - let path = - if fullPath.StartsWith ignoreFile.Location.Directory.FullName then - fullPath.[ignoreFile.Location.Directory.FullName.Length + 1 ..] - else - // This scenario is a bit unexpected - it suggests that we are - // trying to ask an ignorefile whether a file that is outside - // its dependency tree is ignored. - fullPath - - ignoreFile.IsIgnored path + ignoreFile.IsIgnored fullPath with ex -> printfn "%A" ex false diff --git a/src/Fantomas/IgnoreFile.fsi b/src/Fantomas/IgnoreFile.fsi index b735d51450..4f1440a342 100644 --- a/src/Fantomas/IgnoreFile.fsi +++ b/src/Fantomas/IgnoreFile.fsi @@ -2,9 +2,16 @@ namespace Fantomas open System.IO.Abstractions +type AbsoluteFilePath = + private + | AbsoluteFilePath of string + + member Path: string + static member Create: fs: IFileSystem -> filePath: string -> AbsoluteFilePath + /// The string argument is taken relative to the location /// of the ignore-file. -type IsPathIgnored = string -> bool +type IsPathIgnored = AbsoluteFilePath -> bool type IgnoreFile = { Location: IFileInfo @@ -19,14 +26,14 @@ module IgnoreFile = /// Note that this is intended for use only in the daemon; the command-line tool /// does not support `.fantomasignore` files anywhere other than the current /// working directory. - val find: fs: IFileSystem -> loadIgnoreList: (string -> string -> bool) -> filePath: string -> IgnoreFile option + val find: fs: IFileSystem -> loadIgnoreList: (string -> IsPathIgnored) -> filePath: string -> IgnoreFile option val loadIgnoreList: fs: IFileSystem -> ignoreFilePath: string -> IsPathIgnored val internal current': fs: IFileSystem -> currentDirectory: string -> - loadIgnoreList: (string -> string -> bool) -> + loadIgnoreList: (string -> IsPathIgnored) -> Lazy /// When executed from the command line, Fantomas will not dynamically locate