Skip to content

Commit 7887eb7

Browse files
committed
Update readme with build instructions, see #29
Update readme with `build` instructions, see #29 Update readme with `build`, see #29 for details Add help-option to build.cmd
1 parent 9f3c0d9 commit 7887eb7

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

README.md

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,76 @@
1-
[![build](https://github.com/abelbraaksma/TaskSeq/actions/workflows/main.yaml/badge.svg)](https://github.com/abelbraaksma/TaskSeq/actions/workflows/main.yaml)
2-
[![test](https://github.com/abelbraaksma/TaskSeq/actions/workflows/test.yaml/badge.svg)](https://github.com/abelbraaksma/TaskSeq/actions/workflows/test.yaml)
1+
[![build][buildstatus_img]][buildstatus]
2+
[![test][teststatus_img]][teststatus]
33

44
# TaskSeq
5-
An implementation [`IAsyncEnumerable<'T>`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1?view=net-7.0) as a `taskSeq` CE for F# with accompanying `TaskSeq` module.
5+
An implementation [`IAsyncEnumerable<'T>`][3] as a `taskSeq` CE for F# with accompanying `TaskSeq` module.
66

7-
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, where each page is a [`MoveNextAsync`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1.movenextasync?view=net-7.0) call on the [`IAsyncEnumerator<'T>`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1?view=net-7.0) given by a call to [`GetAsyncEnumerator()`](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1.getasyncenumerator?view=net-7.0). It has been relatively challenging to work properly with this type and dealing with each step being asynchronous, and the enumerator implementing [`IAsyncDisposable`](https://learn.microsoft.com/en-us/dotnet/api/system.iasyncdisposable?view=net-7.0) as well, which requires careful handling.
7+
The `IAsyncEnumerable` interface was added to .NET in `.NET Core 3.0` and is part of `.NET Standard 2.1`. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, where each page is a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator<'T>`][5] given by a call to [`GetAsyncEnumerator()`][6]. It has been relatively challenging to work properly with this type and dealing with each step being asynchronous, and the enumerator implementing [`IAsyncDisposable`][7] as well, which requires careful handling.
8+
9+
A good C#-based introduction on `IAsyncEnumerable` [can be found in this blog][8]. Another resource is [this MSDN article shortly after its introductiono][9].
10+
11+
## Building & testing
12+
13+
TLDR: just run `build`. Or load the `sln` file in Visual Studio or VS Code and compile.
14+
15+
### Prerequisites
16+
17+
* .NET 6 or .NET 7 Preview
18+
* F# 6.0 compiler
19+
* To use `build.cmd`, the `dotnet` command must be accessible from your path.
20+
21+
Just checkout this repo locally. Then, from the root of the repo, you can do:
22+
23+
### Build the solution
24+
25+
```
26+
build [release|debug]
27+
```
28+
29+
### Run the tests
30+
31+
```
32+
build test [release|debug]
33+
```
34+
35+
By default, all tests are output to the console. If you don't want that, you can use `--logger console;verbosity=summary`.
36+
Furthermore, no TRX file is generated and the `--blame-xxx` flags aren't set.
37+
38+
### Run the CI command
39+
40+
```
41+
build ci [release|debug]
42+
```
43+
44+
This will run `dotnet test` with the `--blame-xxx` settings enabled to [prevent hanging tests][1] caused by
45+
an [xUnit runner bug][2].
46+
47+
### Advanced
48+
49+
You can pass any additional options that are valid for `dotnet test` and `dotnet build` respectively. However,
50+
these cannot be the very first argument, so you should either use `build build --myadditionalOptions fizz buzz`, or
51+
just specify the build-kind, i.e. this is fine:
52+
53+
```
54+
build debug --verbosity detailed
55+
build test --logger console;verbosity=summary
56+
```
57+
58+
At this moment, additional options cannot have quotes in them.
59+
60+
Command modifiers, like `release` and `debug`, can be specified with `-` or `/` if you so prefer: `dotnet build /release`.
61+
62+
### Get help (duh!)
63+
64+
```
65+
build help
66+
```
67+
68+
For more info, see this PR: https://github.com/abelbraaksma/TaskSeq/pull/29.
869

9-
A good C#-based introduction on `IAsyncEnumerable` [can be found in this blog](https://stu.dev/iasyncenumerable-introduction/). Another resource is [this MSDN article shortly after its introductiono](https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8).
1070

1171
## In progress!!!
1272

13-
It's based on [Don Symes `taskSeq.fs`](https://github.com/dotnet/fsharp/blob/d5312aae8aad650f0043f055bb14c3aa8117e12e/tests/benchmarks/CompiledCodeBenchmarks/TaskPerf/TaskPerf/taskSeq.fs)
73+
It's based on [Don Symes `taskSeq.fs`][10]
1474
but expanded with useful utility functions and a few extra binding overloads.
1575

1676
## Short-term feature planning
@@ -307,3 +367,19 @@ module TaskSeq =
307367
val foldAsync: folder: ('State -> 'T -> #Task<'State>) -> state: 'State -> taskSeq: taskSeq<'T> -> Task<'State>
308368
309369
```
370+
371+
[buildstatus]: https://github.com/abelbraaksma/TaskSeq/actions/workflows/main.yaml
372+
[buildstatus_img]: https://github.com/abelbraaksma/TaskSeq/actions/workflows/main.yaml/badge.svg
373+
[teststatus]: https://github.com/abelbraaksma/TaskSeq/actions/workflows/test.yaml
374+
[teststatus_img]: https://github.com/abelbraaksma/TaskSeq/actions/workflows/test.yaml/badge.svg
375+
376+
[1]: https://github.com/abelbraaksma/TaskSeq/issues/25
377+
[2]: https://github.com/xunit/xunit/issues/2587
378+
[3]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1?view=net-7.0
379+
[4]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1.movenextasync?view=net-7.0
380+
[5]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1?view=net-7.0
381+
[6]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1.getasyncenumerator?view=net-7.0
382+
[7]: https://learn.microsoft.com/en-us/dotnet/api/system.iasyncdisposable?view=net-7.0
383+
[8]: https://stu.dev/iasyncenumerable-introduction/
384+
[9]: https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8
385+
[10]: https://github.com/dotnet/fsharp/blob/d5312aae8aad650f0043f055bb14c3aa8117e12e/tests/benchmarks/CompiledCodeBenchmarks/TaskPerf/TaskPerf/taskSeq.fs

build.cmd

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ IF "%~1"=="build" (
3434
REM Drop 'ci' from the remaining args
3535
CALL :shiftArg %REST_ARGS%
3636

37+
) ELSE IF "%~1"=="help" (
38+
GOTO :showHelp
39+
40+
) ELSE IF "%~1"=="/help" (
41+
GOTO :showHelp
42+
43+
) ELSE IF "%~1"=="-help" (
44+
GOTO :showHelp
45+
3746
) ELSE IF "%~1"=="" (
3847
REM No args, default: build
3948
SET BUILD_MODE=build
@@ -53,6 +62,8 @@ REM Something wrong, we don't recognize the given arguments
5362
REM Display help:
5463

5564
ECHO Argument not recognized
65+
66+
:showHelp
5667
ECHO.
5768
ECHO Available options are:
5869
ECHO.

0 commit comments

Comments
 (0)