Skip to content

Commit 46fd43b

Browse files
author
Scott Arbeit
committed
Merge branch 'main' of https://github.com/ScottArbeit/Grace
2 parents 6d25e1d + 894d36b commit 46fd43b

File tree

158 files changed

+9521
-6080
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+9521
-6080
lines changed

src/AGENTS.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,68 @@ Optional: `pwsh ./scripts/install-githooks.ps1` to add a pre-commit
6161
- Format code with `dotnet tool run fantomas --recurse .` (from `./src`) and
6262
include comprehensive, copy/paste-ready snippets when sharing examples.
6363

64+
### Avoid FS3511 in resumable computation expressions
65+
66+
These rules apply to `task { }` and `backgroundTask { }`.
67+
68+
1. **Do not define `let rec` inside `task { }`.**
69+
70+
Bad:
71+
72+
```fsharp
73+
task {
74+
let rec poll () = task { return! poll () }
75+
return! poll ()
76+
}
77+
```
78+
79+
Good:
80+
81+
```fsharp
82+
task {
83+
let mutable done_ = false
84+
while not done_ do
85+
done_ <- true
86+
}
87+
```
88+
89+
2. **Avoid `for ... in ... do` loops inside `task { }`.**
90+
91+
Bad:
92+
93+
```fsharp
94+
task {
95+
for item in items do
96+
useItem item
97+
}
98+
```
99+
100+
Good:
101+
102+
```fsharp
103+
task {
104+
items |> Seq.iter useItem
105+
}
106+
```
107+
108+
3. **Policy: treat FS3511 warnings as regressions (do not suppress).**
109+
110+
Bad:
111+
112+
```xml
113+
<PropertyGroup>
114+
<NoWarn>FS3511</NoWarn>
115+
</PropertyGroup>
116+
```
117+
118+
Good:
119+
120+
```xml
121+
<PropertyGroup>
122+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
123+
</PropertyGroup>
124+
```
125+
64126
## Agent-Friendly Context Practices
65127

66128
- Start with the relevant `AGENTS.md` file(s) to load key patterns,

src/Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
66
<EnableNETAnalyzers>true</EnableNETAnalyzers>
77
<AnalysisLevel>latest</AnalysisLevel>
8+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
89
<NoWarn>$(NoWarn);NETSDK1057</NoWarn>
910
<PublishProfile>DefaultContainer</PublishProfile>
1011
<OtherFlags>$(OtherFlags) --test:GraphBasedChecking</OtherFlags>

src/Grace.Actors/AccessControl.Actor.fs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,11 @@ module AccessControl =
2727
match scope with
2828
| Scope.System -> "system"
2929
| Scope.Owner ownerId -> $"owner:{ownerId}"
30-
| Scope.Organization(ownerId, organizationId) -> $"org:{ownerId}:{organizationId}"
31-
| Scope.Repository(ownerId, organizationId, repositoryId) -> $"repo:{ownerId}:{organizationId}:{repositoryId}"
32-
| Scope.Branch(ownerId, organizationId, repositoryId, branchId) -> $"branch:{ownerId}:{organizationId}:{repositoryId}:{branchId}"
30+
| Scope.Organization (ownerId, organizationId) -> $"org:{ownerId}:{organizationId}"
31+
| Scope.Repository (ownerId, organizationId, repositoryId) -> $"repo:{ownerId}:{organizationId}:{repositoryId}"
32+
| Scope.Branch (ownerId, organizationId, repositoryId, branchId) -> $"branch:{ownerId}:{organizationId}:{repositoryId}:{branchId}"
3333

34-
type AccessControlActor([<PersistentState(StateName.AccessControl, Grace.Shared.Constants.GraceActorStorage)>] state: IPersistentState<AccessControlState>)
35-
=
34+
type AccessControlActor([<PersistentState(StateName.AccessControl, Grace.Shared.Constants.GraceActorStorage)>] state: IPersistentState<AccessControlState>) =
3635
inherit Grain()
3736

3837
let log = loggerFactory.CreateLogger("AccessControl.Actor")
@@ -124,7 +123,7 @@ module AccessControl =
124123
member this.Handle command metadata =
125124
match command with
126125
| AccessControlCommand.GrantRole assignment -> this.GrantRole assignment metadata
127-
| AccessControlCommand.RevokeRole(principal, roleId) -> this.RevokeRole principal roleId metadata
126+
| AccessControlCommand.RevokeRole (principal, roleId) -> this.RevokeRole principal roleId metadata
128127
| AccessControlCommand.ListAssignments principal -> this.ListAssignments principal metadata
129128

130129
member this.GetAssignments principal correlationId =

src/Grace.Actors/Branch.Actor.fs

Lines changed: 69 additions & 55 deletions
Large diffs are not rendered by default.

src/Grace.Actors/ConflictReceipt.Actor.fs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ module ConflictReceipt =
5656
state.State.Add(receiptEvent)
5757
do! state.WriteStateAsync()
5858

59-
receipt <- receipt |> ConflictReceiptDto.UpdateDto receiptEvent
59+
receipt <-
60+
receipt
61+
|> ConflictReceiptDto.UpdateDto receiptEvent
6062

6163
let graceEvent = GraceEvent.ConflictReceiptEvent receiptEvent
6264
do! publishGraceEvent graceEvent receiptEvent.Metadata
@@ -68,7 +70,8 @@ module ConflictReceipt =
6870
.enhance (nameof ConflictReceiptEventType, getDiscriminatedUnionFullName receiptEvent.Event)
6971

7072
return Ok returnValue
71-
with ex ->
73+
with
74+
| ex ->
7275
log.LogError(
7376
ex,
7477
"{CurrentInstant}: Node: {hostName}; CorrelationId: {correlationId}; Failed to apply event {eventType} for conflict receipt {receiptId}.",
@@ -92,7 +95,10 @@ module ConflictReceipt =
9295
interface IConflictReceiptActor with
9396
member this.Exists correlationId =
9497
this.correlationId <- correlationId
95-
(receipt.ConflictReceiptId <> ConflictReceiptId.Empty) |> returnTask
98+
99+
(receipt.ConflictReceiptId
100+
<> ConflictReceiptId.Empty)
101+
|> returnTask
96102

97103
member this.Get correlationId =
98104
this.correlationId <- correlationId
@@ -104,7 +110,9 @@ module ConflictReceipt =
104110

105111
member this.GetEvents correlationId =
106112
this.correlationId <- correlationId
107-
state.State :> IReadOnlyList<ConflictReceiptEvent> |> returnTask
113+
114+
state.State :> IReadOnlyList<ConflictReceiptEvent>
115+
|> returnTask
108116

109117
member this.Handle command metadata =
110118
let isValid (command: ConflictReceiptCommand) (metadata: EventMetadata) =
@@ -117,7 +125,8 @@ module ConflictReceipt =
117125
else
118126
match command with
119127
| ConflictReceiptCommand.Create _ ->
120-
if receipt.ConflictReceiptId <> ConflictReceiptId.Empty then
128+
if receipt.ConflictReceiptId
129+
<> ConflictReceiptId.Empty then
121130
return
122131
Error(
123132
GraceError.Create

src/Grace.Actors/Diff.Actor.fs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,26 @@ module Diff =
7676
// Find the entries that changed
7777
if
7878
newerLookupCache.ContainsKey((fileSystemEntryType, relativePath))
79-
&& sha256Hash <> newerLookupCache.Item((fileSystemEntryType, relativePath))
79+
&& sha256Hash
80+
<> newerLookupCache.Item((fileSystemEntryType, relativePath))
8081
then
8182
differences.Add(FileSystemDifference.Create Change fileSystemEntryType relativePath)
8283

8384
// Find the entries that were deleted
84-
elif not <| newerLookupCache.ContainsKey((fileSystemEntryType, relativePath)) then
85+
elif
86+
not
87+
<| newerLookupCache.ContainsKey((fileSystemEntryType, relativePath))
88+
then
8589
differences.Add(FileSystemDifference.Create Delete fileSystemEntryType relativePath)
8690

8791
// Find the entries that were added
8892
for kvp in newerLookupCache do
8993
let ((fileSystemEntryType, relativePath), sha256Hash) = kvp.Deconstruct()
9094

91-
if not <| olderLookupCache.ContainsKey((fileSystemEntryType, relativePath)) then
95+
if
96+
not
97+
<| olderLookupCache.ContainsKey((fileSystemEntryType, relativePath))
98+
then
9299
differences.Add(FileSystemDifference.Create Add fileSystemEntryType relativePath)
93100

94101
return differences
@@ -114,7 +121,9 @@ module Diff =
114121

115122
for directoryVersionDto in directoryVersionDtos do
116123
let directoryVersion = directoryVersionDto.DirectoryVersion
117-
graceIndex.TryAdd(directoryVersion.RelativePath, directoryVersion) |> ignore
124+
125+
graceIndex.TryAdd(directoryVersion.RelativePath, directoryVersion)
126+
|> ignore
118127

119128
return (graceIndex, directoryCreatedAt)
120129
}
@@ -211,7 +220,8 @@ module Diff =
211220
try
212221

213222
// If it's already populated, skip this.
214-
if diffDto.DirectoryVersionId1 <> DiffDto.Default.DirectoryVersionId1 then
223+
if diffDto.DirectoryVersionId1
224+
<> DiffDto.Default.DirectoryVersionId1 then
215225
return
216226
Ok(
217227
(GraceReturnValue.Create<string> "DiffActor.Compute: already populated." correlationId)
@@ -289,7 +299,7 @@ module Diff =
289299
let! result2 = getFileStream graceIndex2 difference.RelativePath repositoryDto
290300

291301
match (result1, result2) with
292-
| (Ok(fileStream1, fileVersion1), Ok(fileStream2, fileVersion2)) ->
302+
| (Ok (fileStream1, fileVersion1), Ok (fileStream2, fileVersion2)) ->
293303
try
294304
// Compare the streams using DiffPlex, and get the Inline and Side-by-Side diffs.
295305
let! diffResults =
@@ -347,7 +357,8 @@ module Diff =
347357
Directory1CreatedAt = createdAt1
348358
DirectoryVersionId2 = directoryVersionId2
349359
Directory2CreatedAt = createdAt2
350-
Differences = differences }
360+
Differences = differences
361+
}
351362

352363
state.State <- diffDto
353364
do! state.WriteStateAsync()
@@ -372,17 +383,22 @@ module Diff =
372383
.enhance("RepositoryId", $"{diffDto.RepositoryId}")
373384
.enhance ("HasDifferences", $"{diffDto.HasDifferences}")
374385
)
375-
with ex ->
386+
with
387+
| ex ->
376388
logToConsole $"Exception in DiffActor.Compute(): {ExceptionResponse.Create ex}"
377389
logToConsole $"directoryVersionId1: {diffDto.DirectoryVersionId1}; directoryVersionId2: {diffDto.DirectoryVersionId2}"
378390

379391
if not <| isNull Activity.Current then
380-
Activity.Current
392+
Activity
393+
.Current
381394
.SetStatus(ActivityStatusCode.Error, "Exception while creating diff.")
382395
.AddTag("ex.Message", ex.Message)
383396
.AddTag("ex.StackTrace", ex.StackTrace)
384397

385-
.AddTag("directoryVersionId1", $"{diffDto.DirectoryVersionId1}")
398+
.AddTag(
399+
"directoryVersionId1",
400+
$"{diffDto.DirectoryVersionId1}"
401+
)
386402
.AddTag("directoryVersionId2", $"{diffDto.DirectoryVersionId2}")
387403
|> ignore
388404

src/Grace.Actors/DirectoryAppearance.Actor.fs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ module DirectoryAppearance =
2424
member val public RepositoryId: RepositoryId = RepositoryId.Empty with get, set
2525

2626
type DirectoryAppearanceActor
27-
([<PersistentState(StateName.DirectoryAppearance, Constants.GraceActorStorage)>] state: IPersistentState<SortedSet<Appearance>>) =
27+
(
28+
[<PersistentState(StateName.DirectoryAppearance, Constants.GraceActorStorage)>] state: IPersistentState<SortedSet<Appearance>>
29+
) =
2830
inherit Grain()
2931

3032
let actorName = ActorName.DirectoryAppearance
@@ -74,6 +76,8 @@ module DirectoryAppearance =
7476
}
7577
:> Task
7678

77-
member this.Contains appearance correlationId = directoryAppearanceDto.Appearances.Contains(appearance) |> returnTask
79+
member this.Contains appearance correlationId =
80+
directoryAppearanceDto.Appearances.Contains(appearance)
81+
|> returnTask
7882

7983
member this.Appearances correlationId = directoryAppearanceDto.Appearances |> returnTask

0 commit comments

Comments
 (0)