From 383b0fb7d1e50ad98e1107b1196dad2e38ab26a5 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 11:35:24 +0200 Subject: [PATCH 1/7] Remove Fsi, Stdin and Stdout. --- .../Integration/MultiplePathsTests.fs | 36 ------ src/Fantomas/Program.fs | 121 ++++-------------- 2 files changed, 26 insertions(+), 131 deletions(-) diff --git a/src/Fantomas.Tests/Integration/MultiplePathsTests.fs b/src/Fantomas.Tests/Integration/MultiplePathsTests.fs index ade0d97945..92035b6538 100644 --- a/src/Fantomas.Tests/Integration/MultiplePathsTests.fs +++ b/src/Fantomas.Tests/Integration/MultiplePathsTests.fs @@ -36,42 +36,6 @@ let ``format multiple paths`` () = fileContentMatches FormattedCode fileFixtureOne.Filename fileContentMatches FormattedCode fileFixtureTwo.Filename -[] -let ``format multiple paths cannot be combined with --out`` () = - use config = new ConfigurationFile("[*]\nend_of_line = lf") - - use fileFixtureOne = new TemporaryFileCodeSample(UserCode) - - use fileFixtureTwo = new TemporaryFileCodeSample(UserCode) - - let arguments = - sprintf "\"%s\" \"%s\" --out \"some Folder\"" fileFixtureOne.Filename fileFixtureTwo.Filename - - let { ExitCode = exitCode; Error = error } = runFantomasTool arguments - - exitCode |> should equal 1 - - error - |> should contain "--stdout and --out cannot be combined with multiple files." - -[] -let ``format multiple paths cannot be combined with --stdout`` () = - use config = new ConfigurationFile("[*]\nend_of_line = lf") - - use fileFixtureOne = new TemporaryFileCodeSample(UserCode) - - use fileFixtureTwo = new TemporaryFileCodeSample(UserCode) - - let arguments = - sprintf "\"%s\" \"%s\" --stdout" fileFixtureOne.Filename fileFixtureTwo.Filename - - let { ExitCode = exitCode; Error = error } = runFantomasTool arguments - - exitCode |> should equal 1 - - error - |> should contain "--stdout and --out cannot be combined with multiple files." - [] let ``format multiple paths with recursive flag`` () = use config = new ConfigurationFile("[*]\nend_of_line = lf") diff --git a/src/Fantomas/Program.fs b/src/Fantomas/Program.fs index eea85f2e5d..d619075eea 100644 --- a/src/Fantomas/Program.fs +++ b/src/Fantomas/Program.fs @@ -3,7 +3,6 @@ open System.IO open Fantomas.Core open Fantomas open Fantomas.Daemon -open Fantomas.Core.FormatConfig open Argu open System.Text @@ -19,9 +18,6 @@ type Arguments = | [] Recurse | [] Force | [] Profile - | [] Fsi of string - | [] Stdin - | [] Stdout | [] Out of string | [] Check | [] Daemon @@ -33,11 +29,8 @@ type Arguments = | Recurse -> "Process the input folder recursively." | Force -> "Print the source unchanged if it cannot be parsed correctly." | Out _ -> - "Give a valid path for files/folders. Files should have .fs, .fsx, .fsi, .ml or .mli extension only." + "Give a valid path for files/folders. Files should have .fs, .fsx, .fsi, .ml or .mli extension only. Multiple files/folders are not supported." | Profile -> "Print performance profiling information." - | Fsi _ -> "Read F# source from stdin as F# signatures." - | Stdin -> "Read F# source from standard input." - | Stdout -> "Write the formatted source code to standard output." | Check -> "Don't format files, just check if they have changed. Exits with 0 if it's formatted correctly, with 1 if some files need formatting and 99 if there was an internal error" | Daemon -> "Daemon mode, launches an LSP-like server to can be used by editor tooling." @@ -59,14 +52,12 @@ let time f = type InputPath = | File of string | Folder of string - | StdIn of string | Multiple of files: string list * folder: string list | Unspecified [] type OutputPath = | IO of string - | StdOut | NotKnown let isInExcludedDir (fullPath: string) = @@ -110,32 +101,22 @@ let private hasByteOrderMark file = false /// Format a source string using given config and write to a text writer -let processSourceString isFsiFile s (tw: Choice) config = - let fileName = - match tw, isFsiFile with - | Choice1Of2 _, isFsi -> - let extension = if isFsi then "fsi" else "fs" - sprintf "/tmp.%s" extension - | Choice2Of2 f, _ -> f - +let processSourceString s (fileName: string) config = let writeResult (formatted: string) = - match tw with - | Choice1Of2 tw -> tw.Write(formatted) - | Choice2Of2 path -> - if hasByteOrderMark path then - File.WriteAllText(path, formatted, Encoding.UTF8) - else - File.WriteAllText(path, formatted) + if hasByteOrderMark fileName then + File.WriteAllText(fileName, formatted, Encoding.UTF8) + else + File.WriteAllText(fileName, formatted) - printfn "%s has been written." path + printfn $"%s{fileName} has been written." async { let! formatted = s |> Format.formatContentAsync config fileName match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> formattedContent |> writeResult - | Format.FormatResult.Unchanged file -> printfn "'%s' was unchanged" file - | Format.IgnoredFile file -> printfn "'%s' was ignored" file + | Format.FormatResult.Unchanged file -> printfn $"'%s{file}' was unchanged" + | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" | Format.FormatResult.Error (_, ex) -> raise <| ex } |> Async.RunSynchronously @@ -148,7 +129,7 @@ let processSourceFile inFile (tw: TextWriter) = match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> tw.Write(formattedContent) | Format.FormatResult.Unchanged _ -> inFile |> File.ReadAllText |> tw.Write - | Format.IgnoredFile file -> printfn "'%s' was ignored" file + | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" | Format.FormatResult.Error (_, ex) -> raise <| ex } |> Async.RunSynchronously @@ -206,8 +187,7 @@ let runCheckCommand (recurse: bool) (inputPath: InputPath) : int = if checkResult.HasErrors then 1 else 99 match inputPath with - | InputPath.Unspecified - | InputPath.StdIn _ -> + | InputPath.Unspecified _ -> eprintfn "No input path provided. Nothing to do." 0 | InputPath.File f when (IgnoreFile.isIgnoredFile (IgnoreFile.current.Force()) f) -> @@ -248,14 +228,9 @@ let main argv = let results = parser.ParseCommandLine argv let outputPath = - let hasStdout = results.Contains <@ Arguments.Stdout @> - - if hasStdout then - OutputPath.StdOut - else - match results.TryGetResult <@ Arguments.Out @> with - | Some output -> OutputPath.IO output - | None -> OutputPath.NotKnown + match results.TryGetResult <@ Arguments.Out @> with + | Some output -> OutputPath.IO output + | None -> OutputPath.NotKnown let inputPath = let maybeInput = results.TryGetResult <@ Arguments.Input @> @@ -287,28 +262,17 @@ let main argv = let filesAndFolders = loop inputs id InputPath.Multiple filesAndFolders - | None -> - let hasStdin = results.Contains <@ Arguments.Stdin @> - - if hasStdin then - let stdInInput = readFromStdin StdInLineLimit - - match stdInInput with - | Some input -> InputPath.StdIn input - | None -> InputPath.Unspecified - else - InputPath.Unspecified + | None -> InputPath.Unspecified let force = results.Contains <@ Arguments.Force @> let profile = results.Contains <@ Arguments.Profile @> - let fsi = results.Contains <@ Arguments.Fsi @> let recurse = results.Contains <@ Arguments.Recurse @> let version = results.TryGetResult <@ Arguments.Version @> let fileToFile (inFile: string) (outFile: string) = try - printfn "Processing %s" inFile + printfn $"Processing %s{inFile}" let hasByteOrderMark = hasByteOrderMark inFile use buffer = @@ -332,46 +296,34 @@ let main argv = buffer.Flush() printfn "%s has been written." outFile with exn -> - eprintfn "The following exception occurred while formatting %s: %O" inFile exn + eprintfn $"The following exception occurred while formatting %s{inFile}: {exn}" if force then File.WriteAllText(outFile, File.ReadAllText inFile) - printfn "Force writing original contents to %s" outFile + printfn $"Force writing original contents to %s{outFile}" reraise () let stringToFile (s: string) (outFile: string) config = try - let fsi = Path.GetExtension(outFile) = ".fsi" - if profile then printfn "Line count: %i" (s.Length - s.Replace(Environment.NewLine, "").Length) - time (fun () -> processSourceString fsi s (Choice2Of2 outFile) config) + time (fun () -> processSourceString s outFile config) else - processSourceString fsi s (Choice2Of2 outFile) config + processSourceString s outFile config with exn -> - eprintfn "The following exception occurs while formatting stdin: %O" exn + eprintfn $"The following exception occurs while formatting stdin: {exn}" if force then File.WriteAllText(outFile, s) - printfn "Force writing original contents to %s." outFile + printfn $"Force writing original contents to %s{outFile}." reraise () - let stringToStdOut s config = - try - use buffer = new StringWriter() :> TextWriter - processSourceString fsi s (Choice1Of2 buffer) config - stdout.Write(buffer.ToString()) - with exn -> - eprintfn "The following exception occurs while formatting stdin: %O" exn - if force then stdout.Write(s) - reraise () - let processFile inputFile outputFile = if inputFile <> outputFile then fileToFile inputFile outputFile @@ -398,20 +350,6 @@ let main argv = processFile i o) - let fileToStdOut inFile = - try - use buffer = new StringWriter() - // Don't record running time when output formatted content to console - processSourceFile inFile buffer - stdout.Write(buffer.ToString()) - with exn -> - eprintfn "The following exception occurred while formatting %s: %O" inFile exn - - if force then - stdout.Write(File.ReadAllText inFile) - - reraise () - let filesAndFolders (files: string list) (folders: string list) : unit = files |> List.iter (fun file -> @@ -428,7 +366,7 @@ let main argv = if Option.isSome version then let version = CodeFormatter.GetVersion() - printfn "Fantomas v%s" version + printfn $"Fantomas v%s{version}" elif isDaemon then let daemon = new FantomasDaemon(Console.OpenStandardOutput(), Console.OpenStandardInput()) @@ -451,17 +389,10 @@ let main argv = | InputPath.File p1, OutputPath.NotKnown -> processFile p1 p1 | InputPath.File p1, OutputPath.IO p2 -> processFile p1 p2 | InputPath.Folder p1, OutputPath.IO p2 -> processFolder p1 p2 - | InputPath.StdIn s, OutputPath.IO p -> stringToFile s p FormatConfig.Default - | InputPath.StdIn s, OutputPath.NotKnown - | InputPath.StdIn s, OutputPath.StdOut -> stringToStdOut s FormatConfig.Default - | InputPath.File p, OutputPath.StdOut -> fileToStdOut p - | InputPath.Folder p, OutputPath.StdOut -> allFiles recurse p |> Seq.iter fileToStdOut - | InputPath.Multiple _, - (OutputPath.StdOut - | OutputPath.IO _) -> - eprintfn "--stdout and --out cannot be combined with multiple files." - exit 1 | InputPath.Multiple (files, folders), OutputPath.NotKnown -> filesAndFolders files folders + | InputPath.Multiple _, OutputPath.IO _ -> + eprintfn "Multiple input files are not supported with the --out flag." + exit 1 with exn -> printfn "%s" exn.Message exit 1 From de449198a41f3f60dc01975b581367ebfc12ff87 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 11:50:41 +0200 Subject: [PATCH 2/7] Update the meaning of --force. --- src/Fantomas/Format.fs | 42 +++---------------- src/Fantomas/Program.fs | 90 ++++++++++++++++++++--------------------- 2 files changed, 51 insertions(+), 81 deletions(-) diff --git a/src/Fantomas/Format.fs b/src/Fantomas/Format.fs index 65222f5032..bd6c75bf29 100644 --- a/src/Fantomas/Format.fs +++ b/src/Fantomas/Format.fs @@ -32,6 +32,7 @@ exception CodeFormatException of (string * Option) array with type FormatResult = | Formatted of filename: string * formattedContent: string | Unchanged of filename: string + | InvalidCode of filename: string * formattedContent: string | Error of filename: string * formattingError: Exception | IgnoredFile of filename: string @@ -64,10 +65,9 @@ let private formatContentInternalAsync let! isValid = CodeFormatter.IsValidFSharpCodeAsync(isSignatureFile, formattedContent) if not isValid then - raise - <| FormatException "Formatted content is not valid F# code" - - return Formatted(filename = file, formattedContent = formattedContent) + return InvalidCode(filename = file, formattedContent = formattedContent) + else + return Formatted(filename = file, formattedContent = formattedContent) else return Unchanged(filename = file) with ex -> @@ -94,37 +94,6 @@ let private formatFileInternalAsync (compareWithoutLineEndings: bool) (file: str let formatFileAsync = formatFileInternalAsync false -let formatFilesAsync files = - files |> Seq.map formatFileAsync |> Async.Parallel - -let formatCode files = - async { - let! results = formatFilesAsync files - - // Check for formatting errors: - let errors = - results - |> Array.choose (fun x -> - match x with - | Error (file, ex) -> Some(file, Some(ex)) - | _ -> None) - - if not <| Array.isEmpty errors then - raise <| CodeFormatException errors - - // Overwrite source files with formatted content - let result = - results - |> Array.choose (fun x -> - match x with - | Formatted (source, formatted) -> - File.WriteAllText(source, formatted) - Some source - | _ -> None) - - return result - } - type CheckResult = { Errors: (string * exn) list Formatted: string list } @@ -159,7 +128,8 @@ let checkCode (filenames: seq) = | FormatResult.Unchanged _ | FormatResult.IgnoredFile _ -> None | FormatResult.Formatted (f, _) - | FormatResult.Error (f, _) -> Some f + | FormatResult.Error (f, _) + | FormatResult.InvalidCode (f, _) -> Some f let changes = formatted diff --git a/src/Fantomas/Program.fs b/src/Fantomas/Program.fs index d619075eea..fa711ea441 100644 --- a/src/Fantomas/Program.fs +++ b/src/Fantomas/Program.fs @@ -5,6 +5,7 @@ open Fantomas open Fantomas.Daemon open Argu open System.Text +open Fantomas.Format let extensions = set @@ -27,7 +28,7 @@ type Arguments = member s.Usage = match s with | Recurse -> "Process the input folder recursively." - | Force -> "Print the source unchanged if it cannot be parsed correctly." + | Force -> "Print the output even if it is not valid F# code. For debugging purposes only." | Out _ -> "Give a valid path for files/folders. Files should have .fs, .fsx, .fsi, .ml or .mli extension only. Multiple files/folders are not supported." | Profile -> "Print performance profiling information." @@ -101,7 +102,7 @@ let private hasByteOrderMark file = false /// Format a source string using given config and write to a text writer -let processSourceString s (fileName: string) config = +let processSourceString (force: bool) s (fileName: string) config = let writeResult (formatted: string) = if hasByteOrderMark fileName then File.WriteAllText(fileName, formatted, Encoding.UTF8) @@ -115,22 +116,26 @@ let processSourceString s (fileName: string) config = match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> formattedContent |> writeResult + | Format.InvalidCode (_, formattedContent) when force -> formattedContent |> writeResult | Format.FormatResult.Unchanged file -> printfn $"'%s{file}' was unchanged" | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" - | Format.FormatResult.Error (_, ex) -> raise <| ex + | Format.FormatResult.Error (_, ex) -> raise ex + | Format.InvalidCode (file, _) -> raise (exn $"Formatting {file} lead to invalid F# code") } |> Async.RunSynchronously /// Format inFile and write to text writer -let processSourceFile inFile (tw: TextWriter) = +let processSourceFile (force: bool) inFile (tw: TextWriter) = async { let! formatted = Format.formatFileAsync inFile match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> tw.Write(formattedContent) + | Format.InvalidCode (_, formattedContent) when force -> tw.Write(formattedContent) | Format.FormatResult.Unchanged _ -> inFile |> File.ReadAllText |> tw.Write | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" - | Format.FormatResult.Error (_, ex) -> raise <| ex + | Format.FormatResult.Error (_, ex) -> raise ex + | Format.InvalidCode (file, _) -> raise (exn $"Formatting {file} lead to invalid F# code") } |> Async.RunSynchronously @@ -270,7 +275,7 @@ let main argv = let version = results.TryGetResult <@ Arguments.Version @> - let fileToFile (inFile: string) (outFile: string) = + let fileToFile (force: bool) (inFile: string) (outFile: string) = try printfn $"Processing %s{inFile}" let hasByteOrderMark = hasByteOrderMark inFile @@ -289,22 +294,17 @@ let main argv = |> Seq.length |> printfn "Line count: %i" - time (fun () -> processSourceFile inFile buffer) + time (fun () -> processSourceFile force inFile buffer) else - processSourceFile inFile buffer + processSourceFile force inFile buffer buffer.Flush() printfn "%s has been written." outFile with exn -> eprintfn $"The following exception occurred while formatting %s{inFile}: {exn}" - - if force then - File.WriteAllText(outFile, File.ReadAllText inFile) - printfn $"Force writing original contents to %s{outFile}" - reraise () - let stringToFile (s: string) (outFile: string) config = + let stringToFile (force: bool) (s: string) (outFile: string) config = try if profile then printfn @@ -312,54 +312,54 @@ let main argv = (s.Length - s.Replace(Environment.NewLine, "").Length) - time (fun () -> processSourceString s outFile config) + time (fun () -> processSourceString force s outFile config) else - processSourceString s outFile config + processSourceString force s outFile config with exn -> eprintfn $"The following exception occurs while formatting stdin: {exn}" - - if force then - File.WriteAllText(outFile, s) - printfn $"Force writing original contents to %s{outFile}." - reraise () - let processFile inputFile outputFile = + let processFile force inputFile outputFile = if inputFile <> outputFile then - fileToFile inputFile outputFile + fileToFile force inputFile outputFile else printfn "Processing %s" inputFile let content = File.ReadAllText inputFile let config = EditorConfig.readConfiguration inputFile - stringToFile content inputFile config + stringToFile force content inputFile config - let processFolder inputFolder outputFolder = + let processFolder force inputFolder outputFolder = if not <| Directory.Exists(outputFolder) then Directory.CreateDirectory(outputFolder) |> ignore allFiles recurse inputFolder - |> Seq.iter (fun i -> - // s supposes to have form s1/suffix - let suffix = i.Substring(inputFolder.Length + 1) - - let o = - if inputFolder <> outputFolder then - Path.Combine(outputFolder, suffix) - else - i - - processFile i o) - - let filesAndFolders (files: string list) (folders: string list) : unit = + |> Seq.map (fun i -> + async { + // s supposes to have form s1/suffix + let suffix = i.Substring(inputFolder.Length + 1) + + let o = + if inputFolder <> outputFolder then + Path.Combine(outputFolder, suffix) + else + i + + processFile force i o + }) + |> Async.Parallel + |> Async.Ignore + |> Async.RunSynchronously + + let filesAndFolders force (files: string list) (folders: string list) : unit = files |> List.iter (fun file -> if (IgnoreFile.isIgnoredFile (IgnoreFile.current.Force()) file) then printfn "'%s' was ignored" file else - processFile file file) + processFile force file file) folders - |> List.iter (fun folder -> processFolder folder folder) + |> List.iter (fun folder -> processFolder force folder folder) let check = results.Contains <@ Arguments.Check @> let isDaemon = results.Contains <@ Arguments.Daemon @> @@ -385,11 +385,11 @@ let main argv = exit 1 | InputPath.File f, _ when (IgnoreFile.isIgnoredFile (IgnoreFile.current.Force()) f) -> printfn "'%s' was ignored" f - | InputPath.Folder p1, OutputPath.NotKnown -> processFolder p1 p1 - | InputPath.File p1, OutputPath.NotKnown -> processFile p1 p1 - | InputPath.File p1, OutputPath.IO p2 -> processFile p1 p2 - | InputPath.Folder p1, OutputPath.IO p2 -> processFolder p1 p2 - | InputPath.Multiple (files, folders), OutputPath.NotKnown -> filesAndFolders files folders + | InputPath.Folder p1, OutputPath.NotKnown -> processFolder force p1 p1 + | InputPath.File p1, OutputPath.NotKnown -> processFile force p1 p1 + | InputPath.File p1, OutputPath.IO p2 -> processFile force p1 p2 + | InputPath.Folder p1, OutputPath.IO p2 -> processFolder force p1 p2 + | InputPath.Multiple (files, folders), OutputPath.NotKnown -> filesAndFolders force files folders | InputPath.Multiple _, OutputPath.IO _ -> eprintfn "Multiple input files are not supported with the --out flag." exit 1 From 1e8375996a76cb75f541b1f0ab94647eba140abb Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 11:53:12 +0200 Subject: [PATCH 3/7] Don't processFolder asynchronously. --- src/Fantomas/Program.fs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/Fantomas/Program.fs b/src/Fantomas/Program.fs index fa711ea441..8cfea7633e 100644 --- a/src/Fantomas/Program.fs +++ b/src/Fantomas/Program.fs @@ -333,22 +333,17 @@ let main argv = Directory.CreateDirectory(outputFolder) |> ignore allFiles recurse inputFolder - |> Seq.map (fun i -> - async { - // s supposes to have form s1/suffix - let suffix = i.Substring(inputFolder.Length + 1) - - let o = - if inputFolder <> outputFolder then - Path.Combine(outputFolder, suffix) - else - i - - processFile force i o - }) - |> Async.Parallel - |> Async.Ignore - |> Async.RunSynchronously + |> Seq.iter (fun i -> + // s supposes to have form s1/suffix + let suffix = i.Substring(inputFolder.Length + 1) + + let o = + if inputFolder <> outputFolder then + Path.Combine(outputFolder, suffix) + else + i + + processFile force i o) let filesAndFolders force (files: string list) (folders: string list) : unit = files From bf398cf7040b9f93ddb38cf6f5592992efc53819 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 12:12:41 +0200 Subject: [PATCH 4/7] Mention invalid result when force is active. Don't print exception stacktrace. --- src/Fantomas/Program.fs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Fantomas/Program.fs b/src/Fantomas/Program.fs index 8cfea7633e..cd810a3250 100644 --- a/src/Fantomas/Program.fs +++ b/src/Fantomas/Program.fs @@ -116,7 +116,9 @@ let processSourceString (force: bool) s (fileName: string) config = match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> formattedContent |> writeResult - | Format.InvalidCode (_, formattedContent) when force -> formattedContent |> writeResult + | Format.InvalidCode (file, formattedContent) when force -> + printfn $"%s{file} was not valid after formatting." + formattedContent |> writeResult | Format.FormatResult.Unchanged file -> printfn $"'%s{file}' was unchanged" | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" | Format.FormatResult.Error (_, ex) -> raise ex @@ -131,7 +133,9 @@ let processSourceFile (force: bool) inFile (tw: TextWriter) = match formatted with | Format.FormatResult.Formatted (_, formattedContent) -> tw.Write(formattedContent) - | Format.InvalidCode (_, formattedContent) when force -> tw.Write(formattedContent) + | Format.InvalidCode (file, formattedContent) when force -> + printfn $"%s{file} was not valid after formatting." + tw.Write(formattedContent) | Format.FormatResult.Unchanged _ -> inFile |> File.ReadAllText |> tw.Write | Format.IgnoredFile file -> printfn $"'%s{file}' was ignored" | Format.FormatResult.Error (_, ex) -> raise ex @@ -301,7 +305,6 @@ let main argv = buffer.Flush() printfn "%s has been written." outFile with exn -> - eprintfn $"The following exception occurred while formatting %s{inFile}: {exn}" reraise () let stringToFile (force: bool) (s: string) (outFile: string) config = @@ -316,7 +319,6 @@ let main argv = else processSourceString force s outFile config with exn -> - eprintfn $"The following exception occurs while formatting stdin: {exn}" reraise () let processFile force inputFile outputFile = From 6be8ee3c4079f78338c6d7d4c3f603378e8e36f8 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 14:09:01 +0200 Subject: [PATCH 5/7] Add test to cover --force functionality. --- paket.dependencies | 1 + paket.lock | 1 + src/Fantomas.Tests/Fantomas.Tests.fsproj | 1 + src/Fantomas.Tests/Integration/ForceTests.fs | 44 ++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 src/Fantomas.Tests/Integration/ForceTests.fs diff --git a/paket.dependencies b/paket.dependencies index 84ec6ab676..691b753690 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -16,6 +16,7 @@ nuget Ionide.KeepAChangelog.Tasks copy_local: true nuget Dotnet.ReproducibleBuilds copy_local: true github: fsprojects/fantomas:829faa6ba834f99afed9b4434b3a1680536474b2 src/Fantomas/CodePrinter.fs +github: dotnet/fsharp:267d0a57f217df756d9ac33c6aa4ffbfe3b53097 src/Compiler/Checking/CheckDeclarations.fs # F# compiler source github: dotnet/fsharp:267d0a57f217df756d9ac33c6aa4ffbfe3b53097 src/Compiler/FSComp.txt diff --git a/paket.lock b/paket.lock index 452eefe69f..55743c8437 100644 --- a/paket.lock +++ b/paket.lock @@ -182,6 +182,7 @@ GITHUB src/Compiler/AbstractIL/ilpars.fsy (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) src/Compiler/AbstractIL/ilx.fs (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) src/Compiler/AbstractIL/ilx.fsi (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) + src/Compiler/Checking/CheckDeclarations.fs (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) src/Compiler/Facilities/DiagnosticOptions.fs (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) src/Compiler/Facilities/DiagnosticOptions.fsi (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) src/Compiler/Facilities/DiagnosticsLogger.fs (267d0a57f217df756d9ac33c6aa4ffbfe3b53097) diff --git a/src/Fantomas.Tests/Fantomas.Tests.fsproj b/src/Fantomas.Tests/Fantomas.Tests.fsproj index 3da16645e6..66669f8097 100644 --- a/src/Fantomas.Tests/Fantomas.Tests.fsproj +++ b/src/Fantomas.Tests/Fantomas.Tests.fsproj @@ -27,6 +27,7 @@ + \ No newline at end of file diff --git a/src/Fantomas.Tests/Integration/ForceTests.fs b/src/Fantomas.Tests/Integration/ForceTests.fs new file mode 100644 index 0000000000..6a5734cb9c --- /dev/null +++ b/src/Fantomas.Tests/Integration/ForceTests.fs @@ -0,0 +1,44 @@ +module Fantomas.Tests.Integration.ForceTests + +open System.IO +open NUnit.Framework +open FsUnit +open Fantomas.Tests.TestHelpers + +// The day this test fails because Fantomas can format the file, is the day you can remove this file. + +[] +let ``code that was invalid should be still be written`` () = + let pwd = Path.GetDirectoryName(typeof.Assembly.Location) + + let sourceFile = + Path.Combine( + pwd, + "..", + "..", + "..", + "..", + "..", + "paket-files", + "dotnet", + "fsharp", + "src", + "Compiler", + "Checking", + "CheckDeclarations.fs" + ) + + use outputFixture = new OutputFile() + + let { ExitCode = exitCode; Output = output } = + runFantomasTool $"--force --out {outputFixture.Filename} {sourceFile}" + + exitCode |> should equal 0 + + output + |> should contain "was not valid after formatting" + + output |> should contain "has been written" + + File.Exists outputFixture.Filename + |> should equal true From 01f188d2eead899f262f8dcf8893133326fb8700 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 14:13:47 +0200 Subject: [PATCH 6/7] Update documentation. --- docs-old/Documentation.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs-old/Documentation.md b/docs-old/Documentation.md index 1f19df1035..57b2821dbd 100644 --- a/docs-old/Documentation.md +++ b/docs-old/Documentation.md @@ -18,7 +18,7 @@ For the overview how to use the tool, you can type the command dotnet fantomas --help ``` -USAGE: dotnet fantomas [--help] [--recurse] [--force] [--profile] [--fsi ] [--stdin] [--stdout] [--out ] [--check] [--daemon] [--version] [...] +USAGE: dotnet fantomas [--help] [--recurse] [--force] [--profile] [--out ] [--check] [--daemon] [--version] [...] INPUT: @@ -27,12 +27,9 @@ INPUT: OPTIONS: --recurse, -r Process the input folder recursively. - --force Print the source unchanged if it cannot be parsed correctly. + --force Print the output even if it is not valid F# code. For debugging purposes only. --profile Print performance profiling information. - --fsi Read F# source from stdin as F# signatures. - --stdin Read F# source from standard input. - --stdout Write the formatted source code to standard output. - --out Give a valid path for files/folders. Files should have .fs, .fsx, .fsi, .ml or .mli extension only. + --out Give a valid path for files/folders. Files should have .fs, .fsx, .fsi, .ml or .mli extension only. Multiple files/folders are not supported. --check Don't format files, just check if they have changed. Exits with 0 if it's formatted correctly, with 1 if some files need formatting and 99 if there was an internal error --daemon Daemon mode, launches an LSP-like server to can be used by editor tooling. --version, -v Displays the version of Fantomas From 58d476da5f9d81687414a50d248ed630e57d3fef Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 8 Jul 2022 14:17:20 +0200 Subject: [PATCH 7/7] Add changelog entry. --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9534221d0..5b0254017b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,13 @@ # Changelog -## [Unreleased] +## [5.0.0-alpha-011] - 2022-07-08 ### Changed * Restore the CodeFormatter.MakeRange public API. [#2306](https://github.com/fsprojects/fantomas/pull/2306) * Update FCS to 'Add arrow to SynType.Fun trivia.', commit 5a5a5f6cd07aa4a8326baa07d4f7af1305ced6f4 * Update FCS to 'Fix setter first', commit 267d0a57f217df756d9ac33c6aa4ffbfe3b53097 * Update style of long if/match expressions (See [fslang-design#646](https://github.com/fsharp/fslang-design/issues/646)). [#2334](https://github.com/fsprojects/fantomas/pull/2334) +* `--force` will now write a file even when the result is invalid. [#2346](https://github.com/fsprojects/fantomas/issues/2346) ### Added * Add setting `fsharp_max_if_then_short_width`. [#2299](https://github.com/fsprojects/fantomas/issues/2299) @@ -14,6 +15,9 @@ ### Fixed * KeepIndentInBranch not respected inside a let and match. [1825](https://github.com/fsprojects/fantomas/issues/1825) +### Removed +* `--stdin`, `--stdout` and `--fsi` flags. [#2346](https://github.com/fsprojects/fantomas/issues/2346) + ## [5.0.0-alpha-010] - 2022-06-27 ### Changed