374 lines
12 KiB
Plaintext
374 lines
12 KiB
Plaintext
// --------------------------------------------------------------------------------------
|
|
// 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"
|