Skip to content

Commit

Permalink
scripts/styleChecker.fsx: add
Browse files Browse the repository at this point in the history
Add styleChecker.fsx script to check style of our F#, TS
and YML codes.

The `git respore package.json` command in the
styleChecker.fsx script was failing with the following
error, even when I was running the
`git config --global --add safe.directory '*'` command in
both the styleChecker.fsx script and in the CI. In the
issue [1], it's suggested by someone to use --system
instead of --global in the mentioned command, when the
git command is running in a container, which solved the
problem.

```
fatal: detected dubious ownership in repository at '/__w/conventions/conventions'
To add an exception for this directory, call:

	git config --global --add safe.directory /__w/conventions/conventions

Error when running 'git restore package.json'
Fsdk.Process+ProcessFailed: Exception of type 'Fsdk.Process+ProcessFailed' was thrown.
   at Fsdk.Process.ProcessResult.Unwrap(String errMsg)
   at Fsdk.Process.ProcessResult.UnwrapDefault()
   at FSI_0002.RunPrettier(String arguments)
   at <StartupCode$FSI_0002>.$FSI_0002.main@()
Stopped due to error
Error: Process completed with exit code 1.
```

[1] actions/checkout#1048
  • Loading branch information
tehraninasab committed Apr 5, 2023
1 parent 282d3f1 commit 4c213d1
Show file tree
Hide file tree
Showing 2 changed files with 270 additions and 24 deletions.
28 changes: 4 additions & 24 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
fetch-depth: 0
# workaround for https://github.com/actions/runner/issues/2033
- name: ownership workaround
run: git config --global --add safe.directory '*'
run: git config --system --add safe.directory '*'
- name: Print versions
run: |
git --version
Expand Down Expand Up @@ -144,26 +144,6 @@ jobs:
- name: Check if gitPush1by1 was used
if: github.event_name == 'pull_request'
run: dotnet fsi scripts/detectNotUsingGitPush1by1.fsx
- name: Install prettier
run: npm install [email protected]
- name: Change file permissions
# We need this step so we can change the files using `npx prettier --write` in the next step.
# Otherwise we get permission denied error in the CI.
run: sudo chmod 777 -R .
- name: Run "prettier" to check the style of our TypeScript and YML code
run: |
sudo npx prettier --quote-props=consistent --write './**/*.ts'
sudo npx prettier --quote-props=consistent --write './**/*.yml'
# Since we changed file modes in the previous step we need the following command to
# make git ignore mode changes in files and doesn't include them in the git diff command.
git config core.fileMode false
# Since after installing commitlint dependencies package.json file changes, we need to
# run the following command to ignore package.json file
git restore package.json
git diff --exit-code
- name: fantomless
run: |
dotnet new tool-manifest
dotnet tool install fantomless-tool --version 4.7.997-prerelease
dotnet fantomless --recurse .
git diff --exit-code
- name: Check style of our F#, TypeScript and YML code
run: sudo dotnet fsi scripts/styleChecker.fsx

266 changes: 266 additions & 0 deletions scripts/styleChecker.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
#!/usr/bin/env -S dotnet fsi

#r "nuget: Fsdk, Version=0.6.0--date20230326-0544.git-5c4f55b"
#load "../src/FileConventions/Helpers.fs"

open System
open System.IO

open Fsdk
open Fsdk.Process

open Helpers

let prettierVersion = "2.8.3"

let StyleFSharpFiles() =
Process
.Execute(
{
Command = "dotnet"
Arguments = "new tool-manifest --force"
},
Echo.Off
)
.UnwrapDefault()
|> ignore

Process
.Execute(
{
Command = "dotnet"
Arguments =
"tool install fantomless-tool --version 4.7.997-prerelease"
},
Echo.Off
)
.UnwrapDefault()
|> ignore

Process
.Execute(
{
Command = "dotnet"
Arguments = "fantomless --recurse ."
},
Echo.Off
)
.UnwrapDefault()
|> ignore

let RunPrettier(arguments: string) =

// We need this step so we can change the files using `npx prettier --write` in the next step.
// Otherwise we get permission denied error in the CI.
Process.Execute(
{
Command = "chmod"
Arguments = "777 -R ."
},
Echo.Off
)
|> ignore

let processResult =
Process.Execute(
{
Command = "npx"
Arguments = $"prettier {arguments}"
},
Echo.Off
)

let errMsg =
sprintf
"Error when running '%s %s'"
processResult.Details.Command
processResult.Details.Args

match processResult.Result with
| Success output -> output
| Error(_, output) ->
if processResult.Details.Echo = Echo.Off then
output.PrintToConsole()
Console.WriteLine()
Console.Out.Flush()

Console.Error.WriteLine errMsg
raise <| ProcessFailed errMsg
| WarningsOrAmbiguous output ->
if processResult.Details.Echo = Echo.Off then
output.PrintToConsole()
Console.WriteLine()
Console.Out.Flush()

let fullErrMsg = sprintf "%s (with warnings?)" errMsg
fullErrMsg
|> printfn "%A"


// Since after installing commitlint dependencies package.json file changes, we need to
// run the following command to ignore package.json file
Process
.Execute(
{
Command = "git"
Arguments = "restore package.json"
},
Echo.Off
)
.UnwrapDefault()
|> ignore

let StyleTypeScriptFiles() =
RunPrettier "--quote-props=consistent --write ./**/*.ts"

let StyleYmlFiles() =
RunPrettier "--quote-props=consistent --write ./**/*.yml"

let ContainsFiles (rootDir: DirectoryInfo) (searchPattern: string) =
Helpers.GetFiles rootDir searchPattern |> Seq.length > 0

let GitDiff() : ProcessResult =

// Since we changed file modes in the prettier step we need the following command to
// make git ignore mode changes in files and doesn't include them in the git diff command.
Process.Execute(
{
Command = "git"
Arguments = "config core.fileMode false"
},
Echo.Off
)
|> ignore

let processResult =
Process.Execute(
{
Command = "git"
Arguments = "diff --exit-code"
},
Echo.Off
)

processResult

let GitRestore() =
Process.Execute(
{
Command = "git"
Arguments = "restore ."
},
Echo.Off
)
|> ignore

let InstallPrettier(version: string) =
Process.Execute(
{
Command = "npm"
Arguments = $"install prettier@{version}"
},
Echo.Off
)
|> ignore

let PrintProcessResult (processResult: ProcessResult) (suggestion: string) =
let errMsg =
sprintf
"Error when running '%s %s'"
processResult.Details.Command
processResult.Details.Args

match processResult.Result with
| Success output -> output
| Error(_, output) ->
if processResult.Details.Echo = Echo.Off then
output.PrintToConsole()
Console.WriteLine()
Console.Out.Flush()

let fullErrMsg = errMsg + Environment.NewLine + suggestion
fullErrMsg

| WarningsOrAmbiguous output ->
if processResult.Details.Echo = Echo.Off then
output.PrintToConsole()
Console.WriteLine()
Console.Out.Flush()

let fullErrMsg = sprintf "%s (with warnings?)" errMsg
fullErrMsg

|> printfn "%A"

let GetProcessExitCode(processResult: ProcessResult) : int =
match processResult.Result with
| Success output -> 0
| _ -> 1

let CheckStyleOfFSharpFiles(rootDir: DirectoryInfo) : int =
let suggestion =
"Please style your F# code using: `dotnet fantomless --recurse .`"

GitRestore()

let exitCode =
if ContainsFiles rootDir "*.fs" || ContainsFiles rootDir ".fsx" then
StyleFSharpFiles()
let processResult = GitDiff()
PrintProcessResult processResult suggestion
GetProcessExitCode processResult

else
0

exitCode

let CheckStyleOfTypeScriptFiles(rootDir: DirectoryInfo) : int =
let suggestion =
"Please style your TypeScript code using: `npx prettier --quote-props=consistent --write ./**/*.ts`"

GitRestore()

let exitCode =
if ContainsFiles rootDir "*.ts" then
InstallPrettier(prettierVersion)
StyleTypeScriptFiles()
let processResult = GitDiff()
PrintProcessResult processResult suggestion
GetProcessExitCode processResult

else
0

exitCode

let CheckStyleOfYmlFiles(rootDir: DirectoryInfo) : int =
let suggestion =
"Please style your YML code using: `npx prettier --quote-props=consistent --write ./**/*.yml`"

GitRestore()

let exitCode =
if ContainsFiles rootDir "*.yml" then
InstallPrettier(prettierVersion)
StyleYmlFiles()
let processResult = GitDiff()
PrintProcessResult processResult suggestion
GetProcessExitCode processResult
else
0

exitCode


let rootDir = Path.Combine(__SOURCE_DIRECTORY__, "..") |> DirectoryInfo

let exitCodes =
[|
CheckStyleOfFSharpFiles rootDir
CheckStyleOfTypeScriptFiles rootDir
CheckStyleOfYmlFiles rootDir
|]

if exitCodes |> Seq.contains 1 then
Environment.Exit 1

0 comments on commit 4c213d1

Please sign in to comment.