Dependency Management and Build Automation
Russ Cam @forloop
~/libs directory
..designed to work well with NuGet packages and also enables referencing files directly from Git repositories or any HTTP resource. It enables precise and predictable control over what packages the projects within your application reference.
paket.exe
in ~/.paket directory in root
.paket\paket.exe --help
add <options> Adds a new package to your paket.dependencies file
find-refs <options> Finds all project files with package installed
init <options> Creates an empty paket.dependencies in working directory
install <options> Download the dependencies in paket.dependencies or paket.lock
outdated <options> Lists all dependencies that have newer versions available
remove <options> Removes package from paket.dependencies and paket.references
restore <options> Download the dependencies in paket.lock
update <options> Update one or all dependencies
In solution root
source https://www.nuget.org/api/v2
nuget Newtonsoft.Json
source https://api.nuget.org/v3/index.json
nuget AsciiDocNet
group build
source https://www.nuget.org/api/v2
nuget FAKE
nuget FSharp.Data
nuget GitLink prerelease
source https://www.myget.org/F/xunit/
nuget xunit.runner.console 2.2.0-beta3-build3330
Generated from paket install
NUGET
remote: https://www.nuget.org/api/v2
AsciiDocNet (1.0.0-alpha3)
Bogus (7.1.6)
NETStandard.Library (>= 1.6) - framework: >= netstandard13
Newtonsoft.Json (>= 9.0.1) - framework: >= net40, >= netstandard13
System.Linq (>= 4.1) - framework: >= netstandard13
System.Linq.Expressions (>= 4.1) - framework: >= netstandard13
System.Reflection (>= 4.1) - framework: >= netstandard13
System.Reflection.TypeExtensions (>= 4.1) - framework: >= netstandard13
CsQuery (1.3.4)
DiffPlex (1.2.1)
FluentAssertions (4.13)
NETStandard.Library (>= 1.6) - framework: >= netstandard13
System.Reflection.TypeExtensions (>= 4.1) - framework: >= netstandard13
In each project
FluentAssertions
Newtonsoft.Json
xunit
xunit.abstractions
System.Reactive
Bogus
DiffPlex
SemanticVersioning
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Elasticsearch.Net" version="1.9.0" targetFramework="net40" />
<package id="GeoAPI" version="1.7.4" targetFramework="net40" />
<package id="NEST" version="1.9.0" targetFramework="net40" />
<package id="NetTopologySuite" version="1.14" targetFramework="net40" />
<package id="NetTopologySuite.IO.GeoJSON" version="1.14" targetFramework="net40" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net40" />
</packages>
NEST
NetTopologySuite.IO.GeoJSON
source https://www.nuget.org/api/v2
nuget Newtonsoft.Json
group legacy
source https://www.nuget.org/api/v2
nuget Newtonsoft.Json 6.0.0
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v2.0' Or $(TargetFrameworkVersion) == 'v3.0')">
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\packages\Newtonsoft.Json\lib\net20\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v3.5'">
<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\packages\Newtonsoft.Json\lib\net35\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
let leftpad s n c =
let l = s |> String.length
let c' = match c with
| None -> "."
| Some v -> v
match l <= n with
| true -> String.replicate (n-l) c' + s
| false -> s
"The owner of LeftPad 1.0.0-alpha1 has unlisted the package. This could mean that the package version is deprecated or shouldn't be used anymore."
What is used where and by whom?
paket.exe why nuget [id]
.paket\paket.exe why nuget Newtonsoft.Json
Paket version 3.30.2
NuGet Newtonsoft.Json is a direct (paket.dependencies) dependency.
It's a part of following dependency chains:
-> Bogus
-> Newtonsoft.Json
"Select the latest version for each of the packages in the paket.dependencies file, plus all their transitive dependencies, such that all version constraints are satisfied."
1. Create .paket dir
mkdir .paket
cd .paket
2. Download paket.bootstrapper.exe
$output = "paket.bootstrapper.exe"
$latestRelease = iwr "https://github.com/fsprojects/Paket/releases/latest"
$baseUri = $latestRelease.BaseResponse.ResponseUri.AbsoluteUri
$uri = "$baseUri/$output"
iwr -Uri $uri -OutFile $output
3. Run the bootstrapper
.paket\paket.bootstrapper.exe
4. Convert nuget dependencies
.paket\paket.exe convert-from-nuget
5. Simplify dependencies
.paket\paket.exe simplify
6. Profit!
... is a build automation system with capabilities which are similar to make and rake. It is using an easy domain-specific language (DSL) so that you can start using it without learning F#.
1. Include in paket.dependencies
group build
source https://www.nuget.org/api/v2
nuget FAKE
2. install package
.paket\paket.exe install
3. set up F# project
4. Reference FAKE in F# script
#r "build/FAKE/tools/FakeLib.dll"
open Fake
#r "build/FAKE/tools/FakeLib.dll"
open Fake
Target "Test" <| fun _ ->
trace "Testing stuff..."
Target "Build" <| fun _ ->
trace "Building stuff..."
// define the dependencies
"Test"
==> "Build"
RunTargetOrDefault "Build"
@echo off
REM build <target>
.paket\paket.bootstrapper.exe
if errorlevel 1 (
exit /b %errorlevel%
)
.paket\paket.exe restore
if errorlevel 1 (
exit /b %errorlevel%
)
SET TARGET="build"
SET SCRIPT="build\\scripts\\Targets.fsx"
IF NOT [%1]==[] (set TARGET="%1")
ECHO starting build using target=%TARGET%
"packages\build\FAKE\tools\Fake.exe" "%SCRIPT%" "target=%TARGET%"
#r "tools/FAKE/FakeLib.dll"
open Fake
let buildDir = "./build/"
let appReferences =
!! "src/app/**/*.csproj"
++ "src/app/**/and-this.fsproj"
-- "src/app/**/but-not-this.csproj"
Target "BuildApp" (fun _ ->
MSBuildRelease buildDir "Build" appReferences
|> Log "AppBuild-Output: "
)