Skip to content

Instantly share code, notes, and snippets.

View baronfel's full-sized avatar

Chet Husk baronfel

View GitHub Profile
@baronfel
baronfel / between.fsx
Last active January 23, 2023 02:33
Between Active Pattern
open System
[<return:Struct>]
let inline (|Between|_|) left right value =
if value > left && value < right then ValueSome () else ValueNone
let today = DateTime.Now
let yesterday = DateTime.Now.AddDays(-1.0)
let tomorrow = DateTime.Now.AddDays(1.0)
let twoDaysAgo = DateTime.Now.AddDays(-2.0)
@baronfel
baronfel / Blackjack.fsx
Created December 1, 2022 23:11
Blackjack kata
type Suit =
| Spades
| Clubs
| Diamonds
| Hearts
type Face =
| Two
| Three
| Four
@baronfel
baronfel / checking.fsx
Created October 13, 2022 18:33
Minimal FCS source checking
#r "FSharp.Compiler.Service"
open FSharp.Compiler.EditorServices
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.Text
open System.IO
let fcsVersion =
System
.Reflection
.Assembly
@baronfel
baronfel / license-attribute.targets
Created October 9, 2022 23:31
MSBuild target to write license expressions to an assembly attribute
<Project>
<!-- Create a target that will assign the license information for a project to an attribute -->
<Target Name="AssignLicenseAttribute">
<!-- Only do this if the user is allowing assemblyinfo generation -->
<ItemGroup Condition="'$(GenerateAssemblyInfo)' == 'true'">
<!-- Only generate if the license is present and the user has requested this attribute -->
<AssemblyAttribute
Include="System.Reflection.AssemblyMetadataAttribute"
Condition="'$(GenerateLicenseExpressionAttribute)' == 'true' and '$(PackageLicenseExpression)' != ''">
<_Parameter1>LicenseExpression</_Parameter1>
@baronfel
baronfel / pack-help.sh
Last active August 5, 2022 16:30
Potential `dotnet pack` help output for nuspecs
➜ dotnet pack --help
Description:
Create NuGet packages out of .NET projects or Nuspec files.
Usage:
dotnet pack [<PROJECT | SOLUTION>...] [Project Packing Options]
dotnet pack <NUSPEC> [Nuspec Packing Options]
Arguments:
<PROJECT | SOLUTION> A project or solution file to operate on. If a file is not specified, the command will search the current directory for one.
@baronfel
baronfel / multitargeting-msbuild-targets.md
Last active August 3, 2022 19:23
changes made to seamlessly move to multitargeting

Multitargeting your MSBuild tasks and targets

Why would you multitarget?

For all practical purposes, you must multitarget. There is a huge chunk of the MSBuild ecosystem that's stuck on the .NET Framework build of MSBuild - everyone using tooling inside Visual Studio meets this criteria. If you don't support both Full and Core MSBuild distributions you're artificially cutting out your user base.

What does multitargeting mean?

For 'normal' .NET SDK projects, multitargeting means setting multiple TargetFrameworks in your project file. When you do this, builds will be triggered for both TFM, and the overall results can be packaged as a single artifact.

@baronfel
baronfel / wrap.fsx
Created July 5, 2022 17:55
attempted .Add wrapper
[<Struct>]
type AddWrapper< 't, 'x >(item: 't, adder: 'x -> unit) =
member inline _.Delay(f) = f()
// incorrect, but just doing it for now
member inline _.Combine(left, right) = left
member _.Yield(o) =
adder o
item
@baronfel
baronfel / Test.cs
Created June 10, 2022 21:11
SCL multiple array arguments problem
using System.CommandLine;
using System.CommandLine.Completions;
using System.CommandLine.Parsing;
using System.CommandLine.Builder;
new CommandLineBuilder(new TestCommand())
.UseParseDirective()
.UseSuggestDirective()
.Build()
.InvokeAsync(args);
// here's the machinery
/// an SRTP function call that can call any type with a Count member, regardless of the return type of the Count
let inline count (t: ^t): ^u =
(^t : (member Count : ^u) (t))
/// an SRTP function call that can call any Indexer on a type, regardless of the input and output of that indexer
let inline item (t: ^t) (x: ^u) : ^v =
(^t : (member get_Item: ^u -> ^v) (t, x))
@baronfel
baronfel / groupwith.fsx
Created April 18, 2022 01:40
Seq.groupWith
module Seq =
let groupWith grouper items =
seq {
let mutable currentKey = Unchecked.defaultof<'key>
let mutable currentSet = null
for item in items do
let thisKey = grouper item
if currentKey = Unchecked.defaultof<'key>
then
// new grouping