Basic import of FSharp.ProjectScaffold setup.

This commit is contained in:
Achim D. Brucker 2017-08-06 17:59:09 +01:00
parent c133d80700
commit c462ea554d
26 changed files with 1224 additions and 34 deletions

26
.gitattributes vendored Normal file
View File

@ -0,0 +1,26 @@
# Auto detect text files
* text=auto
# Custom for Visual Studio
*.cs diff=csharp text=auto eol=lf
*.vb diff=csharp text=auto eol=lf
*.fs diff=csharp text=auto eol=lf
*.fsi diff=csharp text=auto eol=lf
*.fsx diff=csharp text=auto eol=lf
*.sln text eol=crlf merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

102
.gitignore vendored
View File

@ -14,10 +14,23 @@ TestResults
*.user
*.sln.docstates
# Xamarin Studio / monodevelop user-specific
*.userprefs
*.dll.mdb
*.exe.mdb
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
@ -33,10 +46,14 @@ x64/
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
@ -44,24 +61,35 @@ ipch/
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Other Visual Studio data
.vs/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
@ -74,14 +102,15 @@ DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
publish/
# Publish Web Output
*.Publish.xml
# NuGet Packages Directory
packages
# Enable nuget.exe in the .nuget folder (though normally executables are not tracked)
!.nuget/NuGet.exe
# Packet lock file
paket.lock
.paket/paket.exe
@ -93,24 +122,83 @@ csx
# Windows Store app package directory
AppPackages/
# VSCode
.vscode/
# Others
[Bb]in
[Oo]bj
sql
sql/
TestResults
[Tt]est[Rr]esult*
*.Cache
ClientBin
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# Default archive directory
archive
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac desktop service store files
.DS_Store
# ===================================================
# Exclude F# project specific directories and files
# ===================================================
# NuGet Packages Directory
packages/
# Test results produced by build
TestResults.xml
# Nuget outputs
nuget/*.nupkg
release.cmd
release.sh
docs
localpackages/
paket-files
*.orig
.paket/paket.exe
docsrc/content/license.md
docsrc/content/release-notes.md
.fake
docsrc/tools/FSharp.Formatting.svclog

View File

@ -0,0 +1,60 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}"
ProjectSection(SolutionItems) = preProject
paket.dependencies = paket.dependencies
paket.lock = paket.lock
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LogicalHacking.ExtensionDsLab", "src\LogicalHacking.ExtensionDsLab\LogicalHacking.ExtensionDsLab.fsproj", "{8A2EBFC4-14CE-4D77-81DE-1FD7372C3382}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}"
ProjectSection(SolutionItems) = preProject
build.fsx = build.fsx
README.md = README.md
RELEASE_NOTES.md = RELEASE_NOTES.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{83F16175-43B1-4C90-A1EE-8E351C33435D}"
ProjectSection(SolutionItems) = preProject
docsrc\tools\generate.fsx = docsrc\tools\generate.fsx
docsrc\tools\templates\template.cshtml = docsrc\tools\templates\template.cshtml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{8E6D5255-776D-4B61-85F9-73C37AA1FB9A}"
ProjectSection(SolutionItems) = preProject
docsrc\content\index.fsx = docsrc\content\index.fsx
docsrc\content\tutorial.fsx = docsrc\content\tutorial.fsx
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "LogicalHacking.ExtensionDsLab.Tests", "tests\LogicalHacking.ExtensionDsLab.Tests\LogicalHacking.ExtensionDsLab.Tests.fsproj", "{661253B3-4C4D-4EBD-87E4-F1C6F010347F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8A2EBFC4-14CE-4D77-81DE-1FD7372C3382}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A2EBFC4-14CE-4D77-81DE-1FD7372C3382}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A2EBFC4-14CE-4D77-81DE-1FD7372C3382}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A2EBFC4-14CE-4D77-81DE-1FD7372C3382}.Release|Any CPU.Build.0 = Release|Any CPU
{661253B3-4C4D-4EBD-87E4-F1C6F010347F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{661253B3-4C4D-4EBD-87E4-F1C6F010347F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{661253B3-4C4D-4EBD-87E4-F1C6F010347F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{661253B3-4C4D-4EBD-87E4-F1C6F010347F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{83F16175-43B1-4C90-A1EE-8E351C33435D} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}
{8E6D5255-776D-4B61-85F9-73C37AA1FB9A} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}
{661253B3-4C4D-4EBD-87E4-F1C6F010347F} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4}
EndGlobalSection
EndGlobal

1
RELEASE_NOTES.md Normal file
View File

@ -0,0 +1 @@
#### 0.0.0

18
build.cmd Normal file
View File

@ -0,0 +1,18 @@
@echo off
cls
.paket\paket.bootstrapper.exe
if errorlevel 1 (
exit /b %errorlevel%
)
.paket\paket.exe restore
if errorlevel 1 (
exit /b %errorlevel%
)
IF NOT EXIST build.fsx (
.paket\paket.exe update
packages\build\FAKE\tools\FAKE.exe init.fsx
)
packages\build\FAKE\tools\FAKE.exe build.fsx %*

373
build.fsx Normal file
View File

@ -0,0 +1,373 @@
// --------------------------------------------------------------------------------------
// FAKE build script
// --------------------------------------------------------------------------------------
#r @"packages/build/FAKE/tools/FakeLib.dll"
open Fake
open Fake.Git
open Fake.AssemblyInfoFile
open Fake.ReleaseNotesHelper
open Fake.UserInputHelper
open System
open System.IO
open System.Diagnostics
// --------------------------------------------------------------------------------------
// START TODO: Provide project-specific details below
// --------------------------------------------------------------------------------------
// Information about the project are used
// - for version and project name in generated AssemblyInfo file
// - by the generated NuGet package
// - to run tests and to publish documentation on GitHub gh-pages
// - for documentation, you also need to edit info in "docsrc/tools/generate.fsx"
// The name of the project
// (used by attributes in AssemblyInfo, name of a NuGet package and directory in 'src')
let project = "LogicalHacking.ExtensionDsLab"
// Short summary of the project
// (used as description in AssemblyInfo and as a short summary for NuGet package)
let summary = "A data science framework for analyzing Chrome browser extensions."
// Longer description of the project
// (used as a description for NuGet package; line breaks are automatically cleaned up)
let description = "A data science framework for analyzing Chrome browser extensions."
// List of author names (for NuGet package)
let authors = [ "Achim D. Brucker" ]
// Tags for your project (for NuGet package)
let tags = "ChromeExtension DataScience BrowserSecurity"
// File system information
let solutionFile = "LogicalHacking.ExtensionDsLab.sln"
// Default target configuration
let configuration = "Release"
// Pattern specifying assemblies to be tested using NUnit
let testAssemblies = "tests/**/bin" </> configuration </> "*Tests*.dll"
// Git configuration (used for publishing documentation in gh-pages branch)
// The profile where the project is posted
let gitOwner = "BrowserSecurity"
let gitHome = sprintf "%s/%s" "https://git.logicalhacking.com" gitOwner
// The name of the project on GitHub
let gitName = "ExtensionDsLab"
// The url for the raw files hosted
let gitRaw = environVarOrDefault "gitRaw" "https://git.logicalhacking.com/BrowserSecurity"
// --------------------------------------------------------------------------------------
// END TODO: The rest of the file includes standard build steps
// --------------------------------------------------------------------------------------
// Read additional information from the release notes document
let release = LoadReleaseNotes "RELEASE_NOTES.md"
// Helper active pattern for project types
let (|Fsproj|Csproj|Vbproj|Shproj|) (projFileName:string) =
match projFileName with
| f when f.EndsWith("fsproj") -> Fsproj
| f when f.EndsWith("csproj") -> Csproj
| f when f.EndsWith("vbproj") -> Vbproj
| f when f.EndsWith("shproj") -> Shproj
| _ -> failwith (sprintf "Project file %s not supported. Unknown project type." projFileName)
// Generate assembly info files with the right version & up-to-date information
Target "AssemblyInfo" (fun _ ->
let getAssemblyInfoAttributes projectName =
[ Attribute.Title (projectName)
Attribute.Product project
Attribute.Description summary
Attribute.Version release.AssemblyVersion
Attribute.FileVersion release.AssemblyVersion
Attribute.Configuration configuration ]
let getProjectDetails projectPath =
let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath)
( projectPath,
projectName,
System.IO.Path.GetDirectoryName(projectPath),
(getAssemblyInfoAttributes projectName)
)
!! "src/**/*.??proj"
|> Seq.map getProjectDetails
|> Seq.iter (fun (projFileName, projectName, folderName, attributes) ->
match projFileName with
| Fsproj -> CreateFSharpAssemblyInfo (folderName </> "AssemblyInfo.fs") attributes
| Csproj -> CreateCSharpAssemblyInfo ((folderName </> "Properties") </> "AssemblyInfo.cs") attributes
| Vbproj -> CreateVisualBasicAssemblyInfo ((folderName </> "My Project") </> "AssemblyInfo.vb") attributes
| Shproj -> ()
)
)
// Copies binaries from default VS location to expected bin folder
// But keeps a subdirectory structure for each project in the
// src folder to support multiple project outputs
Target "CopyBinaries" (fun _ ->
!! "src/**/*.??proj"
-- "src/**/*.shproj"
|> Seq.map (fun f -> ((System.IO.Path.GetDirectoryName f) </> "bin" </> configuration, "bin" </> (System.IO.Path.GetFileNameWithoutExtension f)))
|> Seq.iter (fun (fromDir, toDir) -> CopyDir toDir fromDir (fun _ -> true))
)
// --------------------------------------------------------------------------------------
// Clean build results
let vsProjProps =
#if MONO
[ ("DefineConstants","MONO"); ("Configuration", configuration) ]
#else
[ ("Configuration", configuration); ("Platform", "Any CPU") ]
#endif
Target "Clean" (fun _ ->
!! solutionFile |> MSBuildReleaseExt "" vsProjProps "Clean" |> ignore
CleanDirs ["bin"; "temp"; "docs"]
)
// --------------------------------------------------------------------------------------
// Build library & test project
Target "Build" (fun _ ->
!! solutionFile
|> MSBuildReleaseExt "" vsProjProps "Rebuild"
|> ignore
)
// --------------------------------------------------------------------------------------
// Run the unit tests using test runner
Target "RunTests" (fun _ ->
!! testAssemblies
|> NUnit (fun p ->
{ p with
DisableShadowCopy = true
TimeOut = TimeSpan.FromMinutes 20.
OutputFile = "TestResults.xml" })
)
// --------------------------------------------------------------------------------------
// Build a NuGet package
Target "NuGet" (fun _ ->
Paket.Pack(fun p ->
{ p with
OutputPath = "bin"
Version = release.NugetVersion
ReleaseNotes = toLines release.Notes})
)
Target "PublishNuget" (fun _ ->
Paket.Push(fun p ->
{ p with
PublishUrl = "https://www.nuget.org"
WorkingDir = "bin" })
)
// --------------------------------------------------------------------------------------
// Generate the documentation
let fakePath = "packages" </> "build" </> "FAKE" </> "tools" </> "FAKE.exe"
let fakeStartInfo script workingDirectory args fsiargs environmentVars =
(fun (info: ProcessStartInfo) ->
info.FileName <- System.IO.Path.GetFullPath fakePath
info.Arguments <- sprintf "%s --fsiargs -d:FAKE %s \"%s\"" args fsiargs script
info.WorkingDirectory <- workingDirectory
let setVar k v =
info.EnvironmentVariables.[k] <- v
for (k, v) in environmentVars do
setVar k v
setVar "MSBuild" msBuildExe
setVar "GIT" Git.CommandHelper.gitPath
setVar "FSI" fsiPath)
/// Run the given buildscript with FAKE.exe
let executeFAKEWithOutput workingDirectory script fsiargs envArgs =
let exitCode =
ExecProcessWithLambdas
(fakeStartInfo script workingDirectory "" fsiargs envArgs)
TimeSpan.MaxValue false ignore ignore
System.Threading.Thread.Sleep 1000
exitCode
// Documentation
let buildDocumentationTarget fsiargs target =
trace (sprintf "Building documentation (%s), this could take some time, please wait..." target)
let exit = executeFAKEWithOutput "docsrc/tools" "generate.fsx" fsiargs ["target", target]
if exit <> 0 then
failwith "generating reference documentation failed"
()
Target "GenerateReferenceDocs" (fun _ ->
buildDocumentationTarget "-d:RELEASE -d:REFERENCE" "Default"
)
let generateHelp' fail debug =
let args =
if debug then "--define:HELP"
else "--define:RELEASE --define:HELP"
try
buildDocumentationTarget args "Default"
traceImportant "Help generated"
with
| e when not fail ->
traceImportant "generating help documentation failed"
let generateHelp fail =
generateHelp' fail false
Target "GenerateHelp" (fun _ ->
DeleteFile "docsrc/content/release-notes.md"
CopyFile "docsrc/content/" "RELEASE_NOTES.md"
Rename "docsrc/content/release-notes.md" "docsrc/content/RELEASE_NOTES.md"
DeleteFile "docsrc/content/license.md"
CopyFile "docsrc/content/" "LICENSE"
Rename "docsrc/content/license.md" "docsrc/content/LICENSE"
generateHelp true
)
Target "GenerateHelpDebug" (fun _ ->
DeleteFile "docsrc/content/release-notes.md"
CopyFile "docsrc/content/" "RELEASE_NOTES.md"
Rename "docsrc/content/release-notes.md" "docsrc/content/RELEASE_NOTES.md"
DeleteFile "docsrc/content/license.md"
CopyFile "docsrc/content/" "LICENSE"
Rename "docsrc/content/license.md" "docsrc/content/LICENSE"
generateHelp' true true
)
Target "KeepRunning" (fun _ ->
use watcher = !! "docsrc/content/**/*.*" |> WatchChanges (fun changes ->
generateHelp' true true
)
traceImportant "Waiting for help edits. Press any key to stop."
System.Console.ReadKey() |> ignore
watcher.Dispose()
)
Target "GenerateDocs" DoNothing
let createIndexFsx lang =
let content = """(*** hide ***)
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.
#I "../../../bin"
(**
F# Project Scaffold ({0})
=========================
*)
"""
let targetDir = "docsrc/content" </> lang
let targetFile = targetDir </> "index.fsx"
ensureDirectory targetDir
System.IO.File.WriteAllText(targetFile, System.String.Format(content, lang))
Target "AddLangDocs" (fun _ ->
let args = System.Environment.GetCommandLineArgs()
if args.Length < 4 then
failwith "Language not specified."
args.[3..]
|> Seq.iter (fun lang ->
if lang.Length <> 2 && lang.Length <> 3 then
failwithf "Language must be 2 or 3 characters (ex. 'de', 'fr', 'ja', 'gsw', etc.): %s" lang
let templateFileName = "template.cshtml"
let templateDir = "docsrc/tools/templates"
let langTemplateDir = templateDir </> lang
let langTemplateFileName = langTemplateDir </> templateFileName
if System.IO.File.Exists(langTemplateFileName) then
failwithf "Documents for specified language '%s' have already been added." lang
ensureDirectory langTemplateDir
Copy langTemplateDir [ templateDir </> templateFileName ]
createIndexFsx lang)
)
// --------------------------------------------------------------------------------------
// Release Scripts
#load "paket-files/build/fsharp/FAKE/modules/Octokit/Octokit.fsx"
open Octokit
Target "Release" (fun _ ->
let user =
match getBuildParam "github-user" with
| s when not (String.IsNullOrWhiteSpace s) -> s
| _ -> getUserInput "Username: "
let pw =
match getBuildParam "github-pw" with
| s when not (String.IsNullOrWhiteSpace s) -> s
| _ -> getUserPassword "Password: "
let remote =
Git.CommandHelper.getGitResult "" "remote -v"
|> Seq.filter (fun (s: string) -> s.EndsWith("(push)"))
|> Seq.tryFind (fun (s: string) -> s.Contains(gitOwner + "/" + gitName))
|> function None -> gitHome + "/" + gitName | Some (s: string) -> s.Split().[0]
StageAll ""
Git.Commit.Commit "" (sprintf "Bump version to %s" release.NugetVersion)
Branches.pushBranch "" remote (Information.getBranchName "")
Branches.tag "" release.NugetVersion
Branches.pushTag "" remote release.NugetVersion
// release on github
createClient user pw
|> createDraft gitOwner gitName release.NugetVersion (release.SemVer.PreRelease <> None) release.Notes
// TODO: |> uploadFile "PATH_TO_FILE"
|> releaseDraft
|> Async.RunSynchronously
)
Target "BuildPackage" DoNothing
// --------------------------------------------------------------------------------------
// Run all targets by default. Invoke 'build <Target>' to override
Target "All" DoNothing
"AssemblyInfo"
==> "Build"
==> "CopyBinaries"
==> "RunTests"
==> "GenerateReferenceDocs"
==> "GenerateDocs"
==> "NuGet"
==> "BuildPackage"
==> "All"
"GenerateHelp"
==> "GenerateReferenceDocs"
==> "GenerateDocs"
"GenerateHelpDebug"
==> "KeepRunning"
"Clean"
==> "Release"
"BuildPackage"
==> "PublishNuget"
==> "Release"
RunTargetOrDefault "All"

77
build.sh Executable file
View File

@ -0,0 +1,77 @@
#!/usr/bin/env bash
set -eu
cd "$(dirname "$0")"
PAKET_BOOTSTRAPPER_EXE=.paket/paket.bootstrapper.exe
PAKET_EXE=.paket/paket.exe
FAKE_EXE=packages/build/FAKE/tools/FAKE.exe
FSIARGS=""
FSIARGS2=""
OS=${OS:-"unknown"}
if [ "$OS" != "Windows_NT" ]
then
# Can't use FSIARGS="--fsiargs -d:MONO" in zsh, so split it up
# (Can't use arrays since dash can't handle them)
FSIARGS="--fsiargs"
FSIARGS2="-d:MONO"
fi
run() {
if [ "$OS" != "Windows_NT" ]
then
mono "$@"
else
"$@"
fi
}
yesno() {
# NOTE: Defaults to NO
read -p "$1 [y/N] " ynresult
case "$ynresult" in
[yY]*) true ;;
*) false ;;
esac
}
set +e
run $PAKET_BOOTSTRAPPER_EXE
bootstrapper_exitcode=$?
set -e
if [ "$OS" != "Windows_NT" ] &&
[ $bootstrapper_exitcode -ne 0 ] &&
[ $(certmgr -list -c Trust | grep X.509 | wc -l) -le 1 ] &&
[ $(certmgr -list -c -m Trust | grep X.509 | wc -l) -le 1 ]
then
echo "Your Mono installation has no trusted SSL root certificates set up."
echo "This may result in the Paket bootstrapper failing to download Paket"
echo "because Github's SSL certificate can't be verified. One way to fix"
echo "this issue would be to download the list of SSL root certificates"
echo "from the Mozilla project by running the following command:"
echo ""
echo " mozroots --import --sync"
echo ""
echo "This will import over 100 SSL root certificates into your Mono"
echo "certificate repository."
echo ""
if yesno "Run 'mozroots --import --sync' now?"
then
mozroots --import --sync
else
echo "Attempting to continue without running mozroots. This might fail."
fi
# Re-run bootstrapper whether or not the user ran mozroots, because maybe
# they fixed the problem in a separate terminal window.
run $PAKET_BOOTSTRAPPER_EXE
fi
run $PAKET_EXE restore
[ ! -e build.fsx ] && run $PAKET_EXE update
[ ! -e build.fsx ] && run $FAKE_EXE init.fsx
run $FAKE_EXE "$@" $FSIARGS $FSIARGS2 build.fsx

View File

@ -1,23 +0,0 @@
#!/bin/bash
if test "$OS" = "Windows_NT"
then
MONO=""
else
MONO="mono"
fi
$MONO .paket/paket.bootstrapper.exe
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
if [ -e "paket.lock" ]
then
$MONO .paket/paket.exe restore
else
$MONO .paket/paket.exe install
fi
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi

49
docsrc/content/index.fsx Normal file
View File

@ -0,0 +1,49 @@
(*** hide ***)
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.
#I "../../bin"
(**
LogicalHacking.ExtensionDsLab
======================
Documentation
<div class="row">
<div class="span1"></div>
<div class="span6">
<div class="well well-small" id="nuget">
The LogicalHacking.ExtensionDsLab library can be <a href="https://nuget.org/packages/LogicalHacking.ExtensionDsLab">installed from NuGet</a>:
<pre>PM> Install-Package LogicalHacking.ExtensionDsLab</pre>
</div>
</div>
<div class="span1"></div>
</div>
Example
-------
This example demonstrates using a function defined in this sample library.
*)
#r "LogicalHacking.ExtensionDsLab.dll"
open LogicalHacking.ExtensionDsLab
printfn "hello = %i" <| Library.hello 0
(**
Some more info
Samples & documentation
-----------------------
The library comes with comprehensible documentation.
It can include tutorials automatically generated from `*.fsx` files in [the content folder][content].
The API reference is automatically generated from Markdown comments in the library implementation.
* [Tutorial](tutorial.html) contains a further explanation of this sample library.
* [API Reference](reference/index.html) contains automatically generated documentation for all types, modules
and functions in the library. This includes additional brief samples on using most of the
functions.

View File

@ -0,0 +1,19 @@
(*** hide ***)
// This block of code is omitted in the generated HTML documentation. Use
// it to define helpers that you do not want to show in the documentation.
#I "../../bin"
(**
Introducing your project
========================
Say more
*)
#r "LogicalHacking.ExtensionDsLab.dll"
open LogicalHacking.ExtensionDsLab
Library.hello 0
(**
Some more info
*)

Binary file not shown.

BIN
docsrc/files/img/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

145
docsrc/tools/generate.fsx Normal file
View File

@ -0,0 +1,145 @@
// --------------------------------------------------------------------------------------
// Builds the documentation from `.fsx` and `.md` files in the 'docsrc/content' directory
// (the generated documentation is stored in the 'docsrc/output' directory)
// --------------------------------------------------------------------------------------
// Binaries that have XML documentation (in a corresponding generated XML file)
// Any binary output / copied to bin/projectName/projectName.dll will
// automatically be added as a binary to generate API docs for.
// for binaries output to root bin folder please add the filename only to the
// referenceBinaries list below in order to generate documentation for the binaries.
// (This is the original behaviour of ProjectScaffold prior to multi project support)
let referenceBinaries = []
// Web site location for the generated documentation
let website = "/LogicalHacking.ExtensionDsLab"
let githubLink = "https://git.logicalhacking.com/BrowserSecurity/ExtensionDsLab"
// Specify more information about your project
let info =
[ "project-name", "LogicalHacking.ExtensionDsLab"
"project-author", "Achim D. Brucker"
"project-summary", "A data science framework for analyzing Chrome browser extensions."
"project-github", githubLink
"project-nuget", "http://nuget.org/packages/LogicalHacking.ExtensionDsLab" ]
// --------------------------------------------------------------------------------------
// For typical project, no changes are needed below
// --------------------------------------------------------------------------------------
#load "../../packages/build/FSharp.Formatting/FSharp.Formatting.fsx"
#I "../../packages/build/FAKE/tools/"
#r "FakeLib.dll"
open Fake
open System.IO
open Fake.FileHelper
open FSharp.Literate
open FSharp.MetadataFormat
// When called from 'build.fsx', use the public project URL as <root>
// otherwise, use the current 'output' directory.
#if RELEASE
let root = website
#else
let root = "file://" + (__SOURCE_DIRECTORY__ @@ "../../docs")
#endif
// Paths with template/source/output locations
let bin = __SOURCE_DIRECTORY__ @@ "../../bin"
let content = __SOURCE_DIRECTORY__ @@ "../content"
let output = __SOURCE_DIRECTORY__ @@ "../../docs"
let files = __SOURCE_DIRECTORY__ @@ "../files"
let templates = __SOURCE_DIRECTORY__ @@ "templates"
let formatting = __SOURCE_DIRECTORY__ @@ "../../packages/build/FSharp.Formatting/"
let docTemplate = "docpage.cshtml"
// Where to look for *.csproj templates (in this order)
let layoutRootsAll = new System.Collections.Generic.Dictionary<string, string list>()
layoutRootsAll.Add("en",[ templates; formatting @@ "templates"
formatting @@ "templates/reference" ])
subDirectories (directoryInfo templates)
|> Seq.iter (fun d ->
let name = d.Name
if name.Length = 2 || name.Length = 3 then
layoutRootsAll.Add(
name, [templates @@ name
formatting @@ "templates"
formatting @@ "templates/reference" ]))
// Copy static files and CSS + JS from F# Formatting
let copyFiles () =
CopyRecursive files output true |> Log "Copying file: "
ensureDirectory (output @@ "content")
CopyRecursive (formatting @@ "styles") (output @@ "content") true
|> Log "Copying styles and scripts: "
let binaries =
let manuallyAdded =
referenceBinaries
|> List.map (fun b -> bin @@ b)
let conventionBased =
directoryInfo bin
|> subDirectories
|> Array.map (fun d -> d.FullName @@ (sprintf "%s.dll" d.Name))
|> List.ofArray
conventionBased @ manuallyAdded
let libDirs =
let conventionBasedbinDirs =
directoryInfo bin
|> subDirectories
|> Array.map (fun d -> d.FullName)
|> List.ofArray
conventionBasedbinDirs @ [bin]
// Build API reference from XML comments
let buildReference () =
CleanDir (output @@ "reference")
MetadataFormat.Generate
( binaries, output @@ "reference", layoutRootsAll.["en"],
parameters = ("root", root)::info,
sourceRepo = githubLink @@ "tree/master",
sourceFolder = __SOURCE_DIRECTORY__ @@ ".." @@ "..",
publicOnly = true,libDirs = libDirs )
// Build documentation from `fsx` and `md` files in `docs/content`
let buildDocumentation () =
// First, process files which are placed in the content root directory.
Literate.ProcessDirectory
( content, docTemplate, output, replacements = ("root", root)::info,
layoutRoots = layoutRootsAll.["en"],
generateAnchors = true,
processRecursive = false)
// And then process files which are placed in the sub directories
// (some sub directories might be for specific language).
let subdirs = Directory.EnumerateDirectories(content, "*", SearchOption.TopDirectoryOnly)
for dir in subdirs do
let dirname = (new DirectoryInfo(dir)).Name
let layoutRoots =
// Check whether this directory name is for specific language
let key = layoutRootsAll.Keys
|> Seq.tryFind (fun i -> i = dirname)
match key with
| Some lang -> layoutRootsAll.[lang]
| None -> layoutRootsAll.["en"] // "en" is the default language
Literate.ProcessDirectory
( dir, docTemplate, output @@ dirname, replacements = ("root", root)::info,
layoutRoots = layoutRoots,
generateAnchors = true )
// Generate
copyFiles()
#if HELP
buildDocumentation()
#endif
#if REFERENCE
buildReference()
#endif

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>@Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="@Description"/>
<meta name="author" content="@Properties["project-author"]"/>
<script src="https://code.jquery.com/jquery-1.8.0.js"></script>
<script src="https://code.jquery.com/ui/1.8.23/jquery-ui.js"></script>
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet"/>
<link type="text/css" rel="stylesheet" href="@Root/content/style.css" />
<script type="text/javascript" src="@Root/content/tips.js"></script>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<div class="masthead">
<ul class="nav nav-pills pull-right">
<li><a href="http://fsharp.org">fsharp.org</a></li>
<li><a href="@Properties["project-github"]">github page</a></li>
</ul>
<h3 class="muted"><a href="@Root/index.html">@Properties["project-name"]</a></h3>
</div>
<hr />
<div class="row">
<div class="span9" id="main">
@RenderBody()
</div>
<div class="span3">
<img src="@Root/img/logo.png" alt="F# Project" style="width:150px;margin:10px" />
<ul class="nav nav-list" id="menu" style="margin-top: 20px;">
<li class="nav-header">@Properties["project-name"]</li>
<li><a href="@Root/index.html">Home page</a></li>
<li class="divider"></li>
<li><a href="@Properties["project-nuget"]">Get Library via NuGet</a></li>
<li><a href="@Properties["project-github"]">Source Code on GitHub</a></li>
<li><a href="@Root/license.html">License</a></li>
<li><a href="@Root/release-notes.html">Release Notes</a></li>
<li class="nav-header">Getting started</li>
<li><a href="@Root/tutorial.html">Sample tutorial</a></li>
<li class="nav-header">Documentation</li>
<li><a href="@Root/reference/index.html">API Reference</a></li>
</ul>
</div>
</div>
</div>
<a href="@Properties["project-github"]"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png" alt="Fork me on GitHub"/></a>
</body>
</html>

View File

@ -1,6 +1,25 @@
framework: >= net40
framework: >= net45
source https://nuget.org/api/v2
nuget FsLab
nuget System.Data.Sqlite
nuget SQLProvider
# The setting below means your libraries will assume a minimum target of .NET 4.5 + F# 4.0.
#
# To increase the minimum assumed .NET Framework, change the TargetFrameworkVersion in the .fsproj project files.
#
# To increase the minimum assumed F# version to F# 4.1, change to
# nuget FSharp.Core ~> 4.1.0 redirects: force
nuget FSharp.Core ~> 4.0.0.1 redirects: force
group Build
source https://nuget.org/api/v2
nuget FAKE
nuget FSharp.Formatting
github fsharp/FAKE modules/Octokit/Octokit.fsx
group Test
source https://nuget.org/api/v2
nuget NUnit ~> 2
nuget NUnit.Runners ~> 2

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<Paket>True</Paket>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding></runtime></configuration>

View File

@ -0,0 +1,19 @@
// Auto-Generated by FAKE; do not edit
namespace System
open System.Reflection
[<assembly: AssemblyTitleAttribute("LogicalHacking.ExtensionDsLab")>]
[<assembly: AssemblyProductAttribute("LogicalHacking.ExtensionDsLab")>]
[<assembly: AssemblyDescriptionAttribute("A data science framework for analyzing Chrome browser extensions.")>]
[<assembly: AssemblyVersionAttribute("1.0.1")>]
[<assembly: AssemblyFileVersionAttribute("1.0.1")>]
[<assembly: AssemblyConfigurationAttribute("Release")>]
do ()
module internal AssemblyVersionInformation =
let [<Literal>] AssemblyTitle = "LogicalHacking.ExtensionDsLab"
let [<Literal>] AssemblyProduct = "LogicalHacking.ExtensionDsLab"
let [<Literal>] AssemblyDescription = "A data science framework for analyzing Chrome browser extensions."
let [<Literal>] AssemblyVersion = "1.0.1"
let [<Literal>] AssemblyFileVersion = "1.0.1"
let [<Literal>] AssemblyConfiguration = "Release"

View File

@ -0,0 +1,16 @@
namespace LogicalHacking.ExtensionDsLab
/// Documentation for my library
///
/// ## Example
///
/// let h = Library.hello 1
/// printfn "%d" h
///
module Library =
/// Returns 42
///
/// ## Parameters
/// - `num` - whatever
let hello num = 42

View File

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>8a2ebfc4-14ce-4d77-81de-1fd7372c3382</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>LogicalHacking.ExtensionDsLab</RootNamespace>
<AssemblyName>LogicalHacking.ExtensionDsLab</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<Name>LogicalHacking.ExtensionDsLab</Name>
<TargetFrameworkProfile />
<DocumentationFile>.\bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<OutputPath>.\bin\Debug</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<OtherFlags>--warnon:1182</OtherFlags>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>.\bin\Release</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<OtherFlags>--warnon:1182</OtherFlags>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
<Import Project="..\..\.paket\paket.targets" />
<ItemGroup>
<Compile Include="Library.fs" />
<None Include="Script.fsx" />
<None Include="paket.references" />
<None Include="paket.template" />
<Content Include="App.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
</ItemGroup>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3' Or $(TargetFrameworkVersion) == 'v4.7')">
<ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
</Project>

View File

@ -0,0 +1,8 @@
// Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project
// for more guidance on F# programming.
#load "Library.fs"
open LogicalHacking.ExtensionDsLab
let num = Library.hello 42
printfn "%i" num

View File

@ -0,0 +1 @@
FSharp.Core

View File

@ -0,0 +1,25 @@
type project
title
LogicalHacking.ExtensionDsLab
owners
Achim D. Brucker
authors
Achim D. Brucker
projectUrl
https://git.logicalhacking.com/BrowserSecurity/ExtensionDsLab
iconUrl
https://git.logicalhacking.com/BrowserSecurity/ExtensionDsLab/master/docs/files/img/logo.png
licenseUrl
https://git.logicalhacking.com/BrowserSecurity/ExtensionDsLab/raw/master/LICENSE
requireLicenseAcceptance
false
copyright
Copyright 2015
tags
ChromeExtension DataScience BrowserSecurity
summary
A data science framework for analyzing Chrome browser extensions.
description
A data science framework for analyzing Chrome browser extensions.

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<Paket>True</Paket>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.4.0.0" />
</dependentAssembly>
</assemblyBinding></runtime></configuration>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>661253b3-4c4d-4ebd-87e4-f1c6f010347f</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>LogicalHacking.ExtensionDsLab.Tests</RootNamespace>
<AssemblyName>LogicalHacking.ExtensionDsLab.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<Name>LogicalHacking.ExtensionDsLab.Tests</Name>
<TargetFrameworkProfile />
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<Tailcalls>false</Tailcalls>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
<StartAction>Project</StartAction>
<StartProgram>
</StartProgram>
<StartArguments>
</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<Tailcalls>true</Tailcalls>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<WarningLevel>3</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Import Project="..\..\.paket\paket.targets" />
<ItemGroup>
<Compile Include="Tests.fs" />
<None Include="paket.references" />
<Content Include="App.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<ProjectReference Include="..\..\src\LogicalHacking.ExtensionDsLab\LogicalHacking.ExtensionDsLab.fsproj">
<Name>LogicalHacking.ExtensionDsLab</Name>
<Project>{8a2ebfc4-14ce-4d77-81de-1fd7372c3382}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<Choose>
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1' Or $(TargetFrameworkVersion) == 'v4.6.2' Or $(TargetFrameworkVersion) == 'v4.6.3' Or $(TargetFrameworkVersion) == 'v4.7')">
<ItemGroup>
<Reference Include="FSharp.Core">
<HintPath>..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</When>
</Choose>
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\packages\test\NUnit\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
module LogicalHacking.ExtensionDsLab.Tests
open LogicalHacking.ExtensionDsLab
open NUnit.Framework
[<Test>]
let ``hello returns 42`` () =
let result = Library.hello 42
printfn "%i" result
Assert.AreEqual(42,result)

View File

@ -0,0 +1,4 @@
FSharp.Core
group Test
NUnit
NUnit.Runners