├── .gitattributes ├── .gitignore ├── .paket ├── paket.bootstrapper.exe └── paket.targets ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── appveyor.yml ├── build.cmd ├── build.fsx ├── build.sh ├── buildConfig.fsx ├── doc ├── Caching.fsx ├── DevelopReadme.md ├── IntroExamples.fsx ├── ReleaseNotes.md ├── content │ ├── img │ │ ├── back_to_top.png │ │ ├── github-blue.png │ │ ├── github.png │ │ ├── logo-template.pdn │ │ └── logo.png │ ├── prism.css │ ├── prism.js │ ├── style.css │ └── tips.js └── templates │ ├── docpage-index.cshtml │ ├── docpage.cshtml │ ├── reference │ ├── module.cshtml │ ├── namespaces.cshtml │ ├── part-members.cshtml │ ├── part-nested.cshtml │ └── type.cshtml │ ├── template-color.tex │ ├── template-math.tex │ └── template.cshtml ├── generateDocs.fsx ├── lib └── README.md ├── nuget └── Yaaf.FSharp.Scripting.nuspec ├── packages └── Yaaf.AdvancedBuilding │ └── content │ ├── build.cmd │ ├── build.sh │ ├── build.targets │ ├── buildConfigDef.fsx │ ├── buildInclude.fsx │ ├── downloadNugetInclude.fsx │ └── generateDocsInclude.fsx ├── paket.dependencies ├── paket.lock └── src ├── .gitignore ├── SharedAssemblyInfo.fs ├── Yaaf.FSharp.Scripting.sln ├── nuget.config ├── source └── Yaaf.FSharp.Scripting │ ├── AssemblyInfo.fs │ ├── Script.fsx │ ├── Yaaf.FSharp.Scripting.fsproj │ ├── YaafFSharpScripting.fs │ ├── app.config │ └── paket.references └── test └── Test.Yaaf.FSharp.Scripting ├── App.config ├── ExtensionMethodTests.fs ├── FsiArgsTest.fs ├── FsiSessionTests.fs ├── Test.Yaaf.FSharp.Scripting.fsproj ├── UnquoteFix.fs └── paket.references /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp text=auto eol=lf 6 | *.fs diff=csharp text=auto eol=lf 7 | *.fsi diff=csharp text=auto eol=lf 8 | *.fsx diff=csharp text=auto eol=lf 9 | *.sln text eol=crlf merge=union 10 | *.csproj merge=union 11 | *.vbproj merge=union 12 | *.fsproj merge=union 13 | *.dbproj merge=union 14 | 15 | # Standard to msysgit 16 | *.doc diff=astextplain 17 | *.DOC diff=astextplain 18 | *.docx diff=astextplain 19 | *.DOCX diff=astextplain 20 | *.dot diff=astextplain 21 | *.DOT diff=astextplain 22 | *.pdf diff=astextplain 23 | *.PDF diff=astextplain 24 | *.rtf diff=astextplain 25 | *.RTF diff=astextplain 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Xamarin Studio / monodevelop user-specific 10 | *.userprefs 11 | 12 | # Build results 13 | 14 | [Dd]ebug/ 15 | [Rr]elease/ 16 | x64/ 17 | build/ 18 | [Bb]in/ 19 | [Oo]bj/ 20 | 21 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 22 | !packages/*/build/ 23 | 24 | # MSTest test Results 25 | [Tt]est[Rr]esult*/ 26 | [Bb]uild[Ll]og.* 27 | 28 | *_i.c 29 | *_p.c 30 | *.ilk 31 | *.meta 32 | *.obj 33 | *.pch 34 | *.pdb 35 | *.mdb 36 | *.pgc 37 | *.pgd 38 | *.rsp 39 | *.sbr 40 | *.tlb 41 | *.tli 42 | *.tlh 43 | *.tmp 44 | *.tmp_proj 45 | *.log 46 | *.svclog 47 | *.vspscc 48 | *.vssscc 49 | .builds 50 | *.pidb 51 | *.log 52 | *.scc 53 | XmlWriter 54 | 55 | # Visual C++ cache files 56 | ipch/ 57 | *.aps 58 | *.ncb 59 | *.opensdf 60 | *.sdf 61 | *.cachefile 62 | 63 | # Visual Studio profiler 64 | *.psess 65 | *.vsp 66 | *.vspx 67 | 68 | # Guidance Automation Toolkit 69 | *.gpState 70 | 71 | # ReSharper is a .NET coding add-in 72 | _ReSharper*/ 73 | *.[Rr]e[Ss]harper 74 | 75 | # TeamCity is a build add-in 76 | _TeamCity* 77 | 78 | # DotCover is a Code Coverage Tool 79 | *.dotCover 80 | 81 | # NCrunch 82 | *.ncrunch* 83 | .*crunch*.local.xml 84 | 85 | # Installshield output folder 86 | [Ee]xpress/ 87 | 88 | # DocProject is a documentation generator add-in 89 | DocProject/buildhelp/ 90 | DocProject/Help/*.HxT 91 | DocProject/Help/*.HxC 92 | DocProject/Help/*.hhc 93 | DocProject/Help/*.hhk 94 | DocProject/Help/*.hhp 95 | DocProject/Help/Html2 96 | DocProject/Help/html 97 | 98 | # Click-Once directory 99 | publish/ 100 | 101 | # Publish Web Output 102 | *.Publish.xml 103 | 104 | # Enable nuget.exe in the .nuget folder (though normally executables are not tracked) 105 | !.nuget/NuGet.exe 106 | 107 | # Windows Azure Build Output 108 | csx 109 | *.build.csdef 110 | 111 | # Windows Store app package directory 112 | AppPackages/ 113 | 114 | # Others 115 | sql/ 116 | *.Cache 117 | ClientBin/ 118 | [Ss]tyle[Cc]op.* 119 | ~$* 120 | *~ 121 | *.dbmdl 122 | *.[Pp]ublish.xml 123 | *.pfx 124 | *.publishsettings 125 | 126 | # RIA/Silverlight projects 127 | Generated_Code/ 128 | 129 | # Backup & report files from converting an old project file to a newer 130 | # Visual Studio version. Backup files are not needed, because we have git ;-) 131 | _UpgradeReport_Files/ 132 | Backup*/ 133 | UpgradeLog*.XML 134 | UpgradeLog*.htm 135 | 136 | # SQL Server files 137 | App_Data/*.mdf 138 | App_Data/*.ldf 139 | 140 | 141 | #LightSwitch generated files 142 | GeneratedArtifacts/ 143 | _Pvt_Extensions/ 144 | ModelManifest.xml 145 | 146 | # ========================= 147 | # Windows detritus 148 | # ========================= 149 | 150 | # Windows image file caches 151 | Thumbs.db 152 | ehthumbs.db 153 | 154 | # Folder config file 155 | Desktop.ini 156 | 157 | # Recycle Bin used on file shares 158 | $RECYCLE.BIN/ 159 | 160 | # Mac desktop service store files 161 | .DS_Store 162 | 163 | # =================================================== 164 | # Exclude F# project specific directories and files 165 | # =================================================== 166 | 167 | .fake/* 168 | 169 | # NuGet Packages Directory 170 | packages/* 171 | !packages/Yaaf.AdvancedBuilding 172 | packages/Yaaf.AdvancedBuilding/* 173 | !packages/Yaaf.AdvancedBuilding/content 174 | 175 | gh-pages/ 176 | 177 | # Generated documentation folder 178 | docs/output/ 179 | 180 | # Temp folder used for publishing docs 181 | temp/ 182 | # Where binaries get build into 183 | build/ 184 | # Where test binaries get build into 185 | /test/ 186 | 187 | # Test results produced by build 188 | TestResults.xml 189 | 190 | # Nuget outputs 191 | *.nuspec 192 | !nuget/*.nuspec 193 | nuget/*.nupkg 194 | 195 | 196 | release.cmd 197 | release.sh 198 | localpackages/ 199 | paket-files 200 | *.orig 201 | .paket/paket.exe 202 | docs/content/license.md 203 | docs/content/release-notes.md 204 | 205 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/.paket/paket.bootstrapper.exe -------------------------------------------------------------------------------- /.paket/paket.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | true 8 | $(MSBuildThisFileDirectory) 9 | $(MSBuildThisFileDirectory)..\ 10 | 11 | 12 | 13 | $(PaketToolsPath)paket.exe 14 | $(PaketToolsPath)paket.bootstrapper.exe 15 | "$(PaketExePath)" 16 | mono --runtime=v4.0.30319 $(PaketExePath) 17 | "$(PaketBootStrapperExePath)" 18 | mono --runtime=v4.0.30319 $(PaketBootStrapperExePath) 19 | 20 | $(PaketCommand) restore 21 | $(PaketBootStrapperCommand) 22 | 23 | RestorePackages; $(BuildDependsOn); 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | 3 | sudo: false # use the new container-based Travis infrastructure 4 | 5 | script: 6 | - ./build.sh All 7 | 8 | notifications: 9 | webhooks: 10 | urls: 11 | - https://webhooks.gitter.im/e/a43d3bdbdee36cd658ea 12 | on_success: change # options: [always|never|change] default: always 13 | on_failure: always # options: [always|never|change] default: always 14 | on_start: false # default: false -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Yaaf.FSharp.Scripting 2 | 3 | ## Contributing (Code) 4 | 5 | Just fork the project an send a pull request to discuss and merge the changes. 6 | Please send the pull request against the `develop` branch as the master branch is used for merging releases. 7 | See http://nvie.com/posts/a-successful-git-branching-model/ for details. 8 | 9 | ## Contributing (Documentation) 10 | 11 | The documentation is generated from the repository so you can help improving the documentation by editing the files in the `/doc` folder. 12 | You can even edit a page directly on github by clicking the edit button ([for example this page](https://github.com/matthid/Yaaf.FSharp.Scripting/blob/develop/CONTRIBUTING.md)). 13 | See also https://help.github.com/articles/editing-files-in-your-repository/ 14 | (don't forget to send a pull request back after forking and changing something). 15 | 16 | ## Licensing 17 | 18 | This project is subject to the terms and conditions defined in file ['LICENSE.md'](https://github.com/matthid/Yaaf.FSharp.Scripting/blob/develop/LICENSE.md), which is part of this source code package. 19 | 20 | You can find licenses of the programs this project depends on in either the "lib/$Project" folder or on their nuget page. -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | ============== 3 | 4 | _Version 2.0, January 2004_ 5 | _<>_ 6 | 7 | ### Terms and Conditions for use, reproduction, and distribution 8 | 9 | #### 1. Definitions 10 | 11 | “License” shall mean the terms and conditions for use, reproduction, and 12 | distribution as defined by Sections 1 through 9 of this document. 13 | 14 | “Licensor” shall mean the copyright owner or entity authorized by the copyright 15 | owner that is granting the License. 16 | 17 | “Legal Entity” shall mean the union of the acting entity and all other entities 18 | that control, are controlled by, or are under common control with that entity. 19 | For the purposes of this definition, “control” means **(i)** the power, direct or 20 | indirect, to cause the direction or management of such entity, whether by 21 | contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the 22 | outstanding shares, or **(iii)** beneficial ownership of such entity. 23 | 24 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 25 | permissions granted by this License. 26 | 27 | “Source” form shall mean the preferred form for making modifications, including 28 | but not limited to software source code, documentation source, and configuration 29 | files. 30 | 31 | “Object” form shall mean any form resulting from mechanical transformation or 32 | translation of a Source form, including but not limited to compiled object code, 33 | generated documentation, and conversions to other media types. 34 | 35 | “Work” shall mean the work of authorship, whether in Source or Object form, made 36 | available under the License, as indicated by a copyright notice that is included 37 | in or attached to the work (an example is provided in the Appendix below). 38 | 39 | “Derivative Works” shall mean any work, whether in Source or Object form, that 40 | is based on (or derived from) the Work and for which the editorial revisions, 41 | annotations, elaborations, or other modifications represent, as a whole, an 42 | original work of authorship. For the purposes of this License, Derivative Works 43 | shall not include works that remain separable from, or merely link (or bind by 44 | name) to the interfaces of, the Work and Derivative Works thereof. 45 | 46 | “Contribution” shall mean any work of authorship, including the original version 47 | of the Work and any modifications or additions to that Work or Derivative Works 48 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 49 | by the copyright owner or by an individual or Legal Entity authorized to submit 50 | on behalf of the copyright owner. For the purposes of this definition, 51 | “submitted” means any form of electronic, verbal, or written communication sent 52 | to the Licensor or its representatives, including but not limited to 53 | communication on electronic mailing lists, source code control systems, and 54 | issue tracking systems that are managed by, or on behalf of, the Licensor for 55 | the purpose of discussing and improving the Work, but excluding communication 56 | that is conspicuously marked or otherwise designated in writing by the copyright 57 | owner as “Not a Contribution.” 58 | 59 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 60 | of whom a Contribution has been received by Licensor and subsequently 61 | incorporated within the Work. 62 | 63 | #### 2. Grant of Copyright License 64 | 65 | Subject to the terms and conditions of this License, each Contributor hereby 66 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 67 | irrevocable copyright license to reproduce, prepare Derivative Works of, 68 | publicly display, publicly perform, sublicense, and distribute the Work and such 69 | Derivative Works in Source or Object form. 70 | 71 | #### 3. Grant of Patent License 72 | 73 | Subject to the terms and conditions of this License, each Contributor hereby 74 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 75 | irrevocable (except as stated in this section) patent license to make, have 76 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 77 | such license applies only to those patent claims licensable by such Contributor 78 | that are necessarily infringed by their Contribution(s) alone or by combination 79 | of their Contribution(s) with the Work to which such Contribution(s) was 80 | submitted. If You institute patent litigation against any entity (including a 81 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 82 | Contribution incorporated within the Work constitutes direct or contributory 83 | patent infringement, then any patent licenses granted to You under this License 84 | for that Work shall terminate as of the date such litigation is filed. 85 | 86 | #### 4. Redistribution 87 | 88 | You may reproduce and distribute copies of the Work or Derivative Works thereof 89 | in any medium, with or without modifications, and in Source or Object form, 90 | provided that You meet the following conditions: 91 | 92 | * **(a)** You must give any other recipients of the Work or Derivative Works a copy of 93 | this License; and 94 | * **(b)** You must cause any modified files to carry prominent notices stating that You 95 | changed the files; and 96 | * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, 97 | all copyright, patent, trademark, and attribution notices from the Source form 98 | of the Work, excluding those notices that do not pertain to any part of the 99 | Derivative Works; and 100 | * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any 101 | Derivative Works that You distribute must include a readable copy of the 102 | attribution notices contained within such NOTICE file, excluding those notices 103 | that do not pertain to any part of the Derivative Works, in at least one of the 104 | following places: within a NOTICE text file distributed as part of the 105 | Derivative Works; within the Source form or documentation, if provided along 106 | with the Derivative Works; or, within a display generated by the Derivative 107 | Works, if and wherever such third-party notices normally appear. The contents of 108 | the NOTICE file are for informational purposes only and do not modify the 109 | License. You may add Your own attribution notices within Derivative Works that 110 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 111 | provided that such additional attribution notices cannot be construed as 112 | modifying the License. 113 | 114 | You may add Your own copyright statement to Your modifications and may provide 115 | additional or different license terms and conditions for use, reproduction, or 116 | distribution of Your modifications, or for any such Derivative Works as a whole, 117 | provided Your use, reproduction, and distribution of the Work otherwise complies 118 | with the conditions stated in this License. 119 | 120 | #### 5. Submission of Contributions 121 | 122 | Unless You explicitly state otherwise, any Contribution intentionally submitted 123 | for inclusion in the Work by You to the Licensor shall be under the terms and 124 | conditions of this License, without any additional terms or conditions. 125 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 126 | any separate license agreement you may have executed with Licensor regarding 127 | such Contributions. 128 | 129 | #### 6. Trademarks 130 | 131 | This License does not grant permission to use the trade names, trademarks, 132 | service marks, or product names of the Licensor, except as required for 133 | reasonable and customary use in describing the origin of the Work and 134 | reproducing the content of the NOTICE file. 135 | 136 | #### 7. Disclaimer of Warranty 137 | 138 | Unless required by applicable law or agreed to in writing, Licensor provides the 139 | Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, 140 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 141 | including, without limitation, any warranties or conditions of TITLE, 142 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 143 | solely responsible for determining the appropriateness of using or 144 | redistributing the Work and assume any risks associated with Your exercise of 145 | permissions under this License. 146 | 147 | #### 8. Limitation of Liability 148 | 149 | In no event and under no legal theory, whether in tort (including negligence), 150 | contract, or otherwise, unless required by applicable law (such as deliberate 151 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 152 | liable to You for damages, including any direct, indirect, special, incidental, 153 | or consequential damages of any character arising as a result of this License or 154 | out of the use or inability to use the Work (including but not limited to 155 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 156 | any and all other commercial damages or losses), even if such Contributor has 157 | been advised of the possibility of such damages. 158 | 159 | #### 9. Accepting Warranty or Additional Liability 160 | 161 | While redistributing the Work or Derivative Works thereof, You may choose to 162 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 163 | other liability obligations and/or rights consistent with this License. However, 164 | in accepting such obligations, You may act only on Your own behalf and on Your 165 | sole responsibility, not on behalf of any other Contributor, and only if You 166 | agree to indemnify, defend, and hold each Contributor harmless for any liability 167 | incurred by, or claims asserted against, such Contributor by reason of your 168 | accepting any such warranty or additional liability. 169 | 170 | _END OF TERMS AND CONDITIONS_ 171 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yaaf.FSharp.Scripting 2 | 3 | ## [Documentation](https://matthid.github.io/Yaaf.FSharp.Scripting/) 4 | 5 | [![Join the chat at https://gitter.im/matthid/Yaaf](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/matthid/Yaaf?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | 7 | ## Build status 8 | 9 | **Development Branch** 10 | 11 | [![Build Status](https://travis-ci.org/matthid/Yaaf.FSharp.Scripting.svg?branch=develop)](https://travis-ci.org/matthid/Yaaf.FSharp.Scripting) 12 | [![Build status](https://ci.appveyor.com/api/projects/status/od970xa4gvkh4tea/branch/develop?svg=true)](https://ci.appveyor.com/project/matthid/yaaf-fsharp/branch/develop) 13 | 14 | **Master Branch** 15 | 16 | [![Build Status](https://travis-ci.org/matthid/Yaaf.FSharp.Scripting.svg?branch=master)](https://travis-ci.org/matthid/Yaaf.FSharp.Scripting) 17 | [![Build status](https://ci.appveyor.com/api/projects/status/od970xa4gvkh4tea/branch/master?svg=true)](https://ci.appveyor.com/project/matthid/yaaf-fsharp/branch/master) 18 | 19 | ## NuGet 20 | 21 |
22 |
23 |
24 |
25 | The Yaaf.FSharp.Scripting library can be installed from NuGet: 26 |
PM> Install-Package Yaaf.FSharp.Scripting
27 |
28 |
29 |
30 |
31 | 32 | ## Include as source file 33 | 34 | ### Paket 35 | 36 | You can include the functionality directly into your application by using paket source files: 37 | 38 | `paket.dependencies`: 39 | 40 | ``` 41 | github matthid/Yaaf.FSharp.Scripting src/source/Yaaf.FSharp.Scripting/YaafFSharpScripting.fs 42 | ``` 43 | 44 | `paket.references`: 45 | 46 | ``` 47 | File: YaafFSharpScripting.fs 48 | ``` 49 | 50 | See http://fsprojects.github.io/Paket/github-dependencies.html for details. 51 | 52 | 53 | ### NuGet 54 | 55 | The `YaafFSharpScripting.fs` source code file is included in the nuget package as well. 56 | You can find it in `content/YaafFSharpScripting.fs`. 57 | By adding the source code file (as reference) to your project you don't need 58 | to add a nuget dependency (`Yaaf.FSharp.Scripting`) to your final package. 59 | 60 | ## Quick intro 61 | 62 | This library tries to improve the scripting capabilities of FSharp. 63 | 64 | It builds on top of FSharp.Compiler.Service but provides a nice an clean API: 65 | 66 | ```fsharp 67 | open Yaaf.FSharp.Scripting 68 | use fsiSession = ScriptHost.CreateNew() 69 | fsiSession.Reference (@"C:\MyAssembly.dll") 70 | fsiSession.Open ("MyAssembly") 71 | 72 | // hook 25 into the session with name test (ie "let test = 25") 73 | // this works with any object 74 | fsiSession.Let "test" 25 75 | 76 | // Get a value out of the evaluator 77 | let v = fsiSession.EvalExpression "test" 78 | assert (v = 25) 79 | 80 | // Try to get a value (with handling error cases) 81 | match fsiSession.Handle fsiSession.EvalExpression "test" with 82 | | InvalidExpressionType e -> 83 | // not of type int 84 | // e.Value contains the result object, e.ExpectedType the expected type (int in this case) 85 | () 86 | | InvalidCode e -> 87 | // couldn't get app value (compiler error, not defined or exception in the running code) 88 | // e.Input is the given text, e.Result is the compiler or the script output 89 | // Note: script exceptions are written as strings within e.Result 90 | () 91 | | Result r -> 92 | // r is the value. 93 | () 94 | 95 | // Get the output of the snippet 96 | let v = fsiSession.EvalInteractionWithOutput """printf "test" """ 97 | assert (v.Output.ScriptOutput = "test") 98 | 99 | // Get the error message of the compilation 100 | try fsiSession.EvalInteraction """ Some_Invalid_F# """ 101 | with :? FsiEvaluationException ev -> 102 | printfn "FSI said: %s" ev.Result.Error.FsiOutput 103 | printfn "Complete Error: %O" ev 104 | 105 | // Load scripts 106 | fsiSession.EvalScript "Script.fsx" 107 | 108 | ``` 109 | 110 | The library also provides some nice members which are missing in FSharp.Compiler.Service: 111 | 112 | ```fsharp 113 | open Yaaf.FSharp.Scripting 114 | open FSharp.Compiler.SourceCodeServices 115 | 116 | // A Assembly -> FSharpEntity mapping (extension) function 117 | let fsAssembly = FSharpAssembly.FromAssembly typeof.Assembly 118 | 119 | // A extension method to find the entity type 120 | let fsType = fsAssembly.Value.FindType typeof 121 | ``` 122 | 123 | And some extensions for System.Type to get the FSharp type name 124 | 125 | ```fsharp 126 | // with concrete types. 127 | let def = typeof> 128 | test <@ def.Name = "FSharpOption`1" @> 129 | test <@ def.Namespace = "Microsoft.FSharp.Core" @> 130 | 131 | test <@ def.FSharpParamList = "" @> 132 | test <@ def.FSharpFullName = "Microsoft.FSharp.Core.Option" @> 133 | test <@ def.FSharpFullNameWithTypeArgs = "Microsoft.FSharp.Core.Option" @> 134 | test <@ def.FSharpName = "Option" @> 135 | 136 | // With typedefs. 137 | let def = typedefof> 138 | test <@ def.Name = "FSharpOption`1" @> 139 | test <@ def.FullName = "Microsoft.FSharp.Core.FSharpOption`1" @> 140 | 141 | test <@ def.FSharpParamList = "<_>" @> 142 | test <@ def.FSharpFullName = "Microsoft.FSharp.Core.Option" @> 143 | test <@ def.FSharpFullNameWithTypeArgs = "Microsoft.FSharp.Core.Option<_>" @> 144 | test <@ def.FSharpName = "Option" @> 145 | 146 | ``` 147 | 148 | [Examples and configuration overview](https://matthid.github.io/Yaaf.FSharp.Scripting/IntroExamples.html) 149 | 150 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | init: 2 | - git config --global core.autocrlf input 3 | build_script: 4 | - cmd: build.cmd 5 | test: off 6 | version: 0.0.1.{build} 7 | artifacts: 8 | - path: bin 9 | name: bin 10 | 11 | notifications: 12 | - provider: Webhook 13 | url: https://webhooks.gitter.im/e/1a414a5a94b6c2750022 14 | on_build_success: false 15 | on_build_failure: true -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | set buildFile=build.fsx 3 | "packages/Yaaf.AdvancedBuilding/content/build.cmd" %* 4 | -------------------------------------------------------------------------------- /build.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | #load "packages/Yaaf.AdvancedBuilding/content/buildConfigDef.fsx" 6 | #load @"buildConfig.fsx" 7 | #load "packages/Yaaf.AdvancedBuilding/content/buildInclude.fsx" 8 | 9 | open Fake 10 | let config = BuildInclude.config 11 | // Define your FAKE targets here 12 | 13 | // start build 14 | RunTargetOrDefault "All" -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | build="packages/Yaaf.AdvancedBuilding/content/build.sh" 3 | chmod +x $build 4 | $build $@ 5 | -------------------------------------------------------------------------------- /buildConfig.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | 6 | (* 7 | This file handles the configuration of the Yaaf.AdvancedBuilding build script. 8 | 9 | The first step is handled in build.sh and build.cmd by restoring either paket dependencies or bootstrapping a NuGet.exe and 10 | executing NuGet to resolve all build dependencies (dependencies required for the build to work, for example FAKE). 11 | 12 | The secound step is executing build.fsx which loads this file (for configuration), builds the solution and executes all unit tests. 13 | *) 14 | 15 | #if FAKE 16 | #else 17 | // Support when file is opened in Visual Studio 18 | #load "packages/Yaaf.AdvancedBuilding/content/buildConfigDef.fsx" 19 | #endif 20 | 21 | open BuildConfigDef 22 | open System.Collections.Generic 23 | open System.IO 24 | 25 | open Fake 26 | open Fake.Git 27 | open Fake.FSharpFormatting 28 | open AssemblyInfoFile 29 | 30 | if isMono then 31 | monoArguments <- "--runtime=v4.0 --debug" 32 | 33 | let buildConfig = 34 | // Read release notes document 35 | let release = ReleaseNotesHelper.parseReleaseNotes (File.ReadLines "doc/ReleaseNotes.md") 36 | { BuildConfiguration.Defaults with 37 | ProjectName = "Yaaf.FSharp.Scripting" 38 | CopyrightNotice = "Yaaf.FSharp.Scripting Copyright © Matthias Dittrich 2015" 39 | ProjectSummary = "A helper library to easily add F# scripts to your application." 40 | ProjectDescription = "This library builds on top of the FSharp.Compiler.Service library and provides a nice API for F# script integration. It provides APIs to push values into and to get values from scripts. Additionally it adds some extension methods missing from the FSharp.Compiler.Service API." 41 | ProjectAuthors = ["Matthias Dittrich"] 42 | NugetTags = "fsharp scripting compiler host" 43 | PageAuthor = "Matthias Dittrich" 44 | GithubUser = "matthid" 45 | Version = release.NugetVersion 46 | NugetPackages = 47 | [ "Yaaf.FSharp.Scripting.nuspec", (fun config p -> 48 | { p with 49 | Version = config.Version 50 | ReleaseNotes = toLines release.Notes 51 | Dependencies = 52 | [ "FSharp.Compiler.Service" 53 | "FSharp.Core" ] 54 | |> List.map (fun name -> name, (GetPackageVersion "packages" name)) }) ] 55 | UseNuget = false 56 | SetAssemblyFileVersions = (fun config -> 57 | let info = 58 | [ Attribute.Company config.ProjectName 59 | Attribute.Product config.ProjectName 60 | Attribute.Copyright config.CopyrightNotice 61 | Attribute.Version config.Version 62 | Attribute.FileVersion config.Version 63 | Attribute.InformationalVersion config.Version] 64 | CreateFSharpAssemblyInfo "./src/SharedAssemblyInfo.fs" info) 65 | EnableDebugSymbolConversion = false 66 | RestrictReleaseToWindows = false 67 | BuildTargets = 68 | [ { BuildParams.WithSolution with 69 | // The default build 70 | PlatformName = "Net40" 71 | SimpleBuildName = "net40" } 72 | // Test if it actually compiles without YAAF_FSHARP_SCRIPTING_PUBLIC defined. 73 | { BuildParams.WithSolution with 74 | // The generated templates 75 | PlatformName = "IncludeTest" 76 | SimpleBuildName = "include_test" } 77 | { BuildParams.WithSolution with 78 | // The generated templates 79 | PlatformName = "Net45" 80 | SimpleBuildName = "net45" } ] 81 | } -------------------------------------------------------------------------------- /doc/Caching.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | #nowarn "211" 3 | #I "../build/net45" 4 | #r "Yaaf.FSharp.Scripting.dll" 5 | (** 6 | # Caching 7 | 8 | Use the `DynamicAssemblyBuilder` or `DynamicAssembly` property and save the assembly. 9 | 10 | TODO: Show how to load assembly 11 | TODO: Maybe create an easy to use library. 12 | 13 | *) -------------------------------------------------------------------------------- /doc/DevelopReadme.md: -------------------------------------------------------------------------------- 1 | # Yaaf.FSharp.Scripting implementation documentation 2 | 3 | ## Building 4 | 5 | This project uses Yaaf.AdvancedBuilding, see https://matthid.github.io/Yaaf.AdvancedBuilding/DevelopReadme.html for details 6 | 7 | ## General overview: 8 | 9 | This library tries to improve the scripting capabilities of FSharp. 10 | 11 | ### Issues / Features / TODOs 12 | 13 | New features are accepted via github pull requests (so just fork away right now!): https://github.com/matthid/Yaaf.FSharp.Scripting 14 | 15 | Issues and TODOs are tracked on github, see: https://github.com/matthid/Yaaf.FSharp.Scripting/issues 16 | 17 | ### Versioning: 18 | 19 | http://semver.org/ 20 | 21 | ### High level documentation ordered by project. 22 | 23 | - `Yaaf.FSharp.Scripting`: Project to improve FSharp scripting. 24 | -------------------------------------------------------------------------------- /doc/IntroExamples.fsx: -------------------------------------------------------------------------------- 1 | (*** hide ***) 2 | #nowarn "211" 3 | #I "../build/net45" 4 | #r "Yaaf.FSharp.Scripting.dll" 5 | (** 6 | # Working with IFsiSessions 7 | 8 | ## Creating sessions 9 | 10 | `ScriptHost.CreateNew()` and `ScriptHost.Create()` provide several optional parameters 11 | to configure the scripting environment: 12 | 13 | * `fsiObj: obj`: 14 | The optional "fsi" object to use (defaults to using the one defined in `FSharp.Compiler.Service.dll`) 15 | You should have the same members as https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/fsiaux.fsi#L19 . 16 | All your members are called via reflection. 17 | * `reportGlobal: bool`: 18 | When true all error messages and outputs contain the complete output (instead of only the output of the last command). 19 | This only affects error messages. 20 | Defaults to `false` 21 | * `outWriter: TextWriter`: 22 | A custom TextWriter object where we additionally write the stdout of the executing code (for long running scripts). 23 | * `fsiOutWriter: TextWriter`: 24 | A custom TextWriter object where we additionally write the fsi stdout (for long running scripts). 25 | * `errWriter: TextWriter`: 26 | A custom TextWriter object where we additionally write the stderr of the executing code (for long running scripts). 27 | * `fsiErrWriter: TextWriter`: 28 | A custom TextWriter object where we additionally write the fsi stderr (for long running scripts). 29 | * `preventStdOut: bool`: 30 | A value indicating whether we should completly block the executing script from writing to the current stdout and stderr. 31 | Defaults to `false`. 32 | 33 | You should use `preventStdOut = true` if you want to control the script output yourself. 34 | You can work with either the live output or with the return values. 35 | Return values will be constant no matter the configuration options! 36 | 37 | ### Example usage ("Live Output"): 38 | 39 | *) 40 | (*** define-output: liveRedirect ***) 41 | open Yaaf.FSharp.Scripting 42 | 43 | // Setup for all future interactions 44 | use liveSession = 45 | try ScriptHost.CreateNew 46 | (preventStdOut = true, 47 | outWriter = ScriptHost.CreateForwardWriter (printfn "Script stdout: %s"), 48 | errWriter = ScriptHost.CreateForwardWriter (printfn "Script stderr: %s")) 49 | with :? FsiEvaluationException as e -> 50 | printf "FsiEvaluationSession could not be created." 51 | printf "%s" e.Result.Error.Merged 52 | reraise () 53 | liveSession.EvalInteraction """printf "Some test" """ 54 | (** The standard output is: *) 55 | (*** include-output:liveRedirect ***) 56 | (** 57 | 58 | ### Example usage ("Return values"): 59 | 60 | *) 61 | 62 | (*** define-output: direct ***) 63 | // Use the "WithOutput" members and work with the return type 64 | use directSession = 65 | try ScriptHost.CreateNew(preventStdOut = true) 66 | with :? FsiEvaluationException as e -> 67 | printf "FsiEvaluationSession could not be created." 68 | printf "%s" e.Result.Error.Merged 69 | reraise () 70 | let v = directSession.EvalInteractionWithOutput """printfn "direct result" """ 71 | printfn "And We have: %s" v.Output.ScriptOutput 72 | (** The standard output is: *) 73 | (*** include-output:direct ***) 74 | (** The value v is: *) 75 | (*** include-value: v ***) 76 | (** 77 | 78 | ### Example usage ("Use both"): 79 | 80 | Note that you can use both systems at the same time as well (the return values are always available). 81 | *) 82 | 83 | (*** define-output: both ***) 84 | let b = liveSession.EvalInteractionWithOutput """printfn "both is possible" """ 85 | printfn "The returned result: %s" b.Output.ScriptOutput 86 | (** The standard output is: *) 87 | (*** include-output:both ***) 88 | (** The value b is: *) 89 | (*** include-value: b ***) -------------------------------------------------------------------------------- /doc/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | ### 1.7.2 2 | 3 | * Fix breaking change in FCS 4 | 5 | ### 1.7.1 6 | 7 | * Fix FAKE Chinese text bug, see https://github.com/matthid/Yaaf.FSharp.Scripting/pull/8 8 | 9 | ### 1.7.0 10 | 11 | * Add EvalScriptAsInteractionWithOutput and EvalScriptAsInteraction, see https://github.com/Microsoft/visualfsharp/issues/1392 12 | 13 | ### 1.6.1 14 | 15 | * On CoreCLR we can use the current directory and AppContext.BaseDirectory to resolve assemblies. 16 | 17 | ### 1.6.0 18 | 19 | * Compatible with dotnet core (netstandard 1.5) 20 | * Bugfix: 'reportGlobal' wasn't working as intended. 21 | * Add arguments to `FsiEvaluationException` error message. 22 | 23 | ### 1.5.2 24 | 25 | * Workaround -g[+|-|:full|:pdbonly] not working as documented. 26 | 27 | ### 1.5.1 28 | 29 | * Fix forward function not being called with string.Empty if the last line ends with a new-line-character and removeEmptyLines = true (CreateForwardWriter). 30 | 31 | ### 1.5.0 32 | 33 | * Add a DynamicAssembly and a DynamicAssemblyBuilder property to IFSIEvaluationSession to be able to save the result. 34 | 35 | ### 1.4.1 36 | 37 | * Use ProgramFilesX86 instead on hard coded value. 38 | * Minor code improvements. 39 | 40 | ### 1.4.0 41 | 42 | * ScriptHost is now disposable to be able to dispose the underlying FsiEvaluationSession, fixes https://github.com/matthid/Yaaf.FSharp.Scripting/issues/5 43 | 44 | ### 1.3.0 45 | 46 | * Use 4.5 reference assemblies in the net45 build. 47 | You can define NET40 if you include the source and want to continue to use the NET40 reference assemblies. 48 | * Default to the latest FSharp.Core if possible (but prefer the currently loaded FSharp.Core version) 49 | 50 | ### 1.2.1 51 | 52 | * Blacklist System.EnterpriseServices.Wrapper as well to fix another warning, see https://github.com/matthid/Yaaf.FSharp.Scripting/issues/4 53 | 54 | ### 1.2.0 55 | 56 | * Update to latest FSharp.Compiler.Service & FSharp.Core 57 | * ScriptHost: Change default args to find a FSharp.Core.dll with optdata and sigdata alongside. 58 | * ScriptHost: Throw early when no FSharp.Core (with sigdata and optdata) can be found when using the default config. 59 | 60 | ### 1.1.12 61 | 62 | * Ignore System.EnterpriseServices.Thunk.dll, see https://github.com/matthid/Yaaf.FSharp.Scripting/issues/4 63 | 64 | ### 1.1.11 65 | 66 | * Improve logging output. 67 | 68 | ### 1.1.10 69 | 70 | * Improve logging output. 71 | 72 | ### 1.1.9 73 | 74 | * Bugfix: Correctly log large argument lists. 75 | 76 | ### 1.1.8 77 | 78 | * Add logging with System.Diagnostics.TraceSource (configure in app.config with the name "Yaaf.FSharp.Scripting") 79 | 80 | ### 1.1.7 81 | 82 | * Fix https://github.com/fsharp/FAKE/issues/790 and https://github.com/fsharp/FAKE/issues/794 83 | 84 | ### 1.1.6 85 | 86 | * Fix https://github.com/fsharp/FAKE/issues/777 87 | 88 | ### 1.1.5 89 | 90 | * Use case insensitive comparison and compare file-names when manually resolving references 91 | 92 | ### 1.1.4 93 | 94 | * Fixed a build failure when YAAF_FSHARP_SCRIPTING_PUBLIC is not defined 95 | * Ignore FSharp.Core.dll in lib-path, when there is no .optdata and .sigdata alongside 96 | * Don't use a loaded FSharp.Core when it has no .optdata and .sigdata alongside 97 | 98 | ### 1.1.3 99 | 100 | * Added "Load" to load script files (see https://github.com/matthid/Yaaf.FSharp.Scripting/issues/1) 101 | * Added "Handle" function to make the usage a bit easier. (see https://github.com/matthid/Yaaf.FSharp.Scripting/issues/2) 102 | 103 | ### 1.1.2 104 | 105 | * Revert the redirect when using CreateForwardWriter (otherwise users run into unexpected StackOverflowExceptions when printing to stdout or stderr) 106 | See https://github.com/fsharp/FAKE/pull/771 107 | * Add an option to remove NewLines when using a forward function (the function will be called whenever a line as been finished) 108 | Note: You must Dispose the TextWrapper to get the last output (if it wasn't finished with a NewLine character) 109 | * Add the AppDomain.BaseDirectory to the base path when searching for a FSharp.Core.dll 110 | 111 | ### 1.1.1 112 | 113 | * Add ScriptHost.CreateForwardWriter which creates a new TextWriter that forwards everything to a simple (string -> unit) function 114 | * Add session.ChangeCurrentDirectory and session.WithCurrentDirectory, to take care of relative paths within executed snippets 115 | * Some more docs 116 | 117 | ### 1.1.0 118 | 119 | * Redirect of stdout and stderr, see https://github.com/fsharp/FSharp.Compiler.Service/issues/201 120 | * added an option prevent writing to stdout and stderr 121 | 122 | ### 1.0.13 123 | 124 | * Introduce FsiEvaluationException when something goes wrong 125 | 126 | ### 1.0.12 127 | 128 | * Add overloaded methods which return the FSI output and error text 129 | * Support for running from within FSI.exe 130 | 131 | ### 1.0.11 132 | 133 | * Add FsiOptions record 134 | 135 | ### 1.0.10 136 | 137 | * Improve FSharp.Core resolution 138 | 139 | ### 1.0.9 140 | 141 | * added FSharpAssembly.LoadFiles API 142 | 143 | ### 1.0.8 144 | 145 | * Support for custom fsi settings object ("fsi") 146 | 147 | ### 1.0.7 148 | 149 | * Add TryEvalExpression to get the type of the expression (not the runtime type) 150 | 151 | ### 1.0.6 152 | 153 | * Add support for using the source code files directly (via paket and nuget) 154 | 155 | ### 1.0.5 156 | 157 | * Add workaround to make scripting work on a clean gentoo install 158 | * Improve error messages when session creation fails 159 | 160 | ### 1.0.4 161 | 162 | * Add FSharp.Core nuget package 163 | 164 | ### 1.0.3 165 | 166 | * Includes a net45 build 167 | 168 | ### 1.0.2 169 | 170 | * You can now set custom defined symbols 171 | 172 | ### 1.0.1 173 | 174 | * NuGet dependency FSharp.Compiler.Service added 175 | 176 | ### 1.0.0 177 | 178 | * Initial release 179 | -------------------------------------------------------------------------------- /doc/content/img/back_to_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/doc/content/img/back_to_top.png -------------------------------------------------------------------------------- /doc/content/img/github-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/doc/content/img/github-blue.png -------------------------------------------------------------------------------- /doc/content/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/doc/content/img/github.png -------------------------------------------------------------------------------- /doc/content/img/logo-template.pdn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/doc/content/img/logo-template.pdn -------------------------------------------------------------------------------- /doc/content/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/f99c04bde0d3cd071475b023acf61fef6b8e8da1/doc/content/img/logo.png -------------------------------------------------------------------------------- /doc/content/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+java+php+bash+c+python+sql+ruby+csharp+scala+haskell+ini+latex+git&plugins=file-highlight */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | text-shadow: 0 1px white; 12 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 13 | direction: ltr; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | line-height: 1.5; 19 | 20 | -moz-tab-size: 4; 21 | -o-tab-size: 4; 22 | tab-size: 4; 23 | 24 | -webkit-hyphens: none; 25 | -moz-hyphens: none; 26 | -ms-hyphens: none; 27 | hyphens: none; 28 | } 29 | 30 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 31 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 32 | text-shadow: none; 33 | background: #b3d4fc; 34 | } 35 | 36 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 37 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 38 | text-shadow: none; 39 | background: #b3d4fc; 40 | } 41 | 42 | @media print { 43 | code[class*="language-"], 44 | pre[class*="language-"] { 45 | text-shadow: none; 46 | } 47 | } 48 | 49 | /* Code blocks */ 50 | pre[class*="language-"] { 51 | padding: 1em; 52 | margin: .5em 0; 53 | overflow: auto; 54 | } 55 | 56 | :not(pre) > code[class*="language-"], 57 | pre[class*="language-"] { 58 | background: #f5f2f0; 59 | } 60 | 61 | /* Inline code */ 62 | :not(pre) > code[class*="language-"] { 63 | padding: .1em; 64 | border-radius: .3em; 65 | } 66 | 67 | .token.comment, 68 | .token.prolog, 69 | .token.doctype, 70 | .token.cdata { 71 | color: slategray; 72 | } 73 | 74 | .token.punctuation { 75 | color: #999; 76 | } 77 | 78 | .namespace { 79 | opacity: .7; 80 | } 81 | 82 | .token.property, 83 | .token.tag, 84 | .token.boolean, 85 | .token.number, 86 | .token.constant, 87 | .token.symbol, 88 | .token.deleted { 89 | color: #905; 90 | } 91 | 92 | .token.selector, 93 | .token.attr-name, 94 | .token.string, 95 | .token.char, 96 | .token.builtin, 97 | .token.inserted { 98 | color: #690; 99 | } 100 | 101 | .token.operator, 102 | .token.entity, 103 | .token.url, 104 | .language-css .token.string, 105 | .style .token.string { 106 | color: #a67f59; 107 | background: hsla(0, 0%, 100%, .5); 108 | } 109 | 110 | .token.atrule, 111 | .token.attr-value, 112 | .token.keyword { 113 | color: #07a; 114 | } 115 | 116 | .token.function { 117 | color: #DD4A68; 118 | } 119 | 120 | .token.regex, 121 | .token.important, 122 | .token.variable { 123 | color: #e90; 124 | } 125 | 126 | .token.important { 127 | font-weight: bold; 128 | } 129 | 130 | .token.entity { 131 | cursor: help; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /doc/content/prism.js: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+java+php+bash+c+python+sql+ruby+csharp+scala+haskell+ini+latex+git&plugins=file-highlight */ 2 | self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{};var Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content),e.alias):"Array"===t.util.type(e)?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(d instanceof a)){c.lastIndex=0;var m=c.exec(d);if(m){u&&(f=m[1].length);var y=m.index-1+f,m=m[0].slice(f),v=m.length,k=y+v,b=d.slice(0,y+1),w=d.slice(k+1),N=[p,1];b&&N.push(b);var O=new a(l,g?t.tokenize(m,g):m,h);N.push(O),w&&N.push(w),Array.prototype.splice.apply(r,N)}}}}}return r},hooks:{all:{},add:function(e,n){var a=t.hooks.all;a[e]=a[e]||[],a[e].push(n)},run:function(e,n){var a=t.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(n)}}},n=t.Token=function(e,t,n){this.type=e,this.content=t,this.alias=n};if(n.stringify=function(e,a,r){if("string"==typeof e)return e;if("[object Array]"==Object.prototype.toString.call(e))return e.map(function(t){return n.stringify(t,a,e)}).join("");var i={type:e.type,content:n.stringify(e.content,a,r),tag:"span",classes:["token",e.type],attributes:{},language:a,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===t.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}t.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'" '+o+">"+i.content+""},!self.document)return self.addEventListener?(self.addEventListener("message",function(e){var n=JSON.parse(e.data),a=n.language,r=n.code;self.postMessage(JSON.stringify(t.util.encode(t.tokenize(r,t.languages[a])))),self.close()},!1),self.Prism):self.Prism;var a=document.getElementsByTagName("script");return a=a[a.length-1],a&&(t.filename=a.src,document.addEventListener&&!a.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)),self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism);; 3 | Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\&#?[\da-z]{1,8};/gi},Prism.hooks.add("wrap",function(t){"entity"===t.type&&(t.attributes.title=t.content.replace(/&/,"&"))});; 4 | Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/gi,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,punctuation:/[\{\};:]/g,"function":/[-a-z0-9]+(?=\()/gi},Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/gi,inside:{tag:{pattern:/|<\/style>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});; 5 | Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//g,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*?(\r?\n|$)/g,lookbehind:!0}],string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/gi,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/gi,inside:{punctuation:/\(/}},number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|&{1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; 6 | Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|function|get|if|implements|import|in|instanceof|interface|let|new|null|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/gi,inside:{tag:{pattern:/|<\/script>/gi,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; 7 | Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/g,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+[e]?[\d]*[df]\b|\W\d*\.?\d+\b/gi,operator:{pattern:/(^|[^\.])(?:\+=|\+\+?|-=|--?|!=?|<{1,2}=?|>{1,3}=?|==?|&=|&&?|\|=|\|\|?|\?|\*=?|\/=?|%=?|\^=?|:|~)/gm,lookbehind:!0}});; 8 | Prism.languages.php=Prism.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/gi,constant:/\b[A-Z0-9_]{2,}\b/g,comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])(\/\/|#).*?(\r?\n|$))/g,lookbehind:!0}}),Prism.languages.insertBefore("php","keyword",{delimiter:/(\?>|<\?php|<\?)/gi,variable:/(\$\w+)\b/gi,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/g,lookbehind:!0,inside:{punctuation:/\\/}}}),Prism.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/g,lookbehind:!0}}),Prism.languages.markup&&(Prism.hooks.add("before-highlight",function(e){"php"===e.language&&(e.tokenStack=[],e.backupCode=e.code,e.code=e.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(n){return e.tokenStack.push(n),"{{{PHP"+e.tokenStack.length+"}}}"}))}),Prism.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),Prism.hooks.add("after-highlight",function(e){if("php"===e.language){for(var n,a=0;n=e.tokenStack[a];a++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(a+1)+"}}}",Prism.highlight(n,e.grammar,"php"));e.element.innerHTML=e.highlightedCode}}),Prism.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'$1'))}),Prism.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/g,inside:Prism.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/g}));; 9 | Prism.languages.bash=Prism.languages.extend("clike",{comment:{pattern:/(^|[^"{\\])(#.*?(\r?\n|$))/g,lookbehind:!0},string:{pattern:/("|')(\\?[\s\S])*?\1/g,inside:{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^\}]+\})/g}},keyword:/\b(if|then|else|elif|fi|for|break|continue|while|in|case|function|select|do|done|until|echo|exit|return|set|declare)\b/g}),Prism.languages.insertBefore("bash","keyword",{property:/\$([a-zA-Z0-9_#\?\-\*!@]+|\{[^}]+\})/g}),Prism.languages.insertBefore("bash","comment",{important:/(^#!\s*\/bin\/bash)|(^#!\s*\/bin\/sh)/g});; 10 | Prism.languages.c=Prism.languages.extend("clike",{string:/("|')([^\n\\\1]|\\.|\\\r*\n)*?\1/g,keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/g,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\//g}),Prism.languages.insertBefore("c","string",{property:{pattern:/((^|\n)\s*)#\s*[a-z]+([^\n\\]|\\.|\\\r*\n)*/gi,lookbehind:!0,inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/g,lookbehind:!0}}}}),delete Prism.languages.c["class-name"],delete Prism.languages.c["boolean"];; 11 | Prism.languages.python={comment:{pattern:/(^|[^\\])#.*?(\r?\n|$)/g,lookbehind:!0},string:/"""[\s\S]+?"""|("|')(\\?.)*?\1/g,keyword:/\b(as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/g,"boolean":/\b(True|False)\b/g,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/[-+]{1,2}|=?<|=?>|!|={1,2}|(&){1,2}|(&){1,2}|\|?\||\?|\*|\/|~|\^|%|\b(or|and|not)\b/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; 12 | Prism.languages.sql={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|((--)|(\/\/)|#).*?(\r?\n|$))/g,lookbehind:!0},string:{pattern:/(^|[^@])("|')(\\?[\s\S])*?\2/g,lookbehind:!0},variable:/@[\w.$]+|@("|'|`)(\\?[\s\S])+?\1/g,"function":/\b(?:COUNT|SUM|AVG|MIN|MAX|FIRST|LAST|UCASE|LCASE|MID|LEN|ROUND|NOW|FORMAT)(?=\s*\()/ig,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALTER|ANALYZE|APPLY|AS|ASC|AUTHORIZATION|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADE|CASCADED|CASE|CHAIN|CHAR VARYING|CHARACTER VARYING|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLUMN|COLUMNS|COMMENT|COMMIT|COMMITTED|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATA|DATABASE|DATABASES|DATETIME|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DOUBLE PRECISION|DROP|DUMMY|DUMP|DUMPFILE|DUPLICATE KEY|ELSE|ENABLE|ENCLOSED BY|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPE|ESCAPED BY|EXCEPT|EXEC|EXECUTE|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR|FOR EACH ROW|FORCE|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GEOMETRY|GEOMETRYCOLLECTION|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|IDENTITY|IDENTITY_INSERT|IDENTITYCOL|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTO|INVOKER|ISOLATION LEVEL|JOIN|KEY|KEYS|KILL|LANGUAGE SQL|LAST|LEFT|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONGBLOB|LONGTEXT|MATCH|MATCHED|MEDIUMBLOB|MEDIUMINT|MEDIUMTEXT|MERGE|MIDDLEINT|MODIFIES SQL DATA|MODIFY|MULTILINESTRING|MULTIPOINT|MULTIPOLYGON|NATIONAL|NATIONAL CHAR VARYING|NATIONAL CHARACTER|NATIONAL CHARACTER VARYING|NATIONAL VARCHAR|NATURAL|NCHAR|NCHAR VARCHAR|NEXT|NO|NO SQL|NOCHECK|NOCYCLE|NONCLUSTERED|NULLIF|NUMERIC|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPTIMIZE|OPTION|OPTIONALLY|ORDER|OUT|OUTER|OUTFILE|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREV|PRIMARY|PRINT|PRIVILEGES|PROC|PROCEDURE|PUBLIC|PURGE|QUICK|RAISERROR|READ|READS SQL DATA|READTEXT|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEATABLE|REPLICATION|REQUIRE|RESTORE|RESTRICT|RETURN|RETURNS|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROWCOUNT|ROWGUIDCOL|ROWS?|RTREE|RULE|SAVE|SAVEPOINT|SCHEMA|SELECT|SERIAL|SERIALIZABLE|SESSION|SESSION_USER|SET|SETUSER|SHARE MODE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|START|STARTING BY|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLE|TABLES|TABLESPACE|TEMP(?:ORARY)?|TEMPTABLE|TERMINATED BY|TEXT|TEXTSIZE|THEN|TIMESTAMP|TINYBLOB|TINYINT|TINYTEXT|TO|TOP|TRAN|TRANSACTION|TRANSACTIONS|TRIGGER|TRUNCATE|TSEQUAL|TYPE|TYPES|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNPIVOT|UPDATE|UPDATETEXT|USAGE|USE|USER|USING|VALUE|VALUES|VARBINARY|VARCHAR|VARCHARACTER|VARYING|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH|WITH ROLLUP|WITHIN|WORK|WRITE|WRITETEXT)\b/gi,"boolean":/\b(?:TRUE|FALSE|NULL)\b/gi,number:/\b-?(0x)?\d*\.?[\da-f]+\b/g,operator:/\b(?:ALL|AND|ANY|BETWEEN|EXISTS|IN|LIKE|NOT|OR|IS|UNIQUE|CHARACTER SET|COLLATE|DIV|OFFSET|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b|[-+]{1}|!|[=<>]{1,2}|(&){1,2}|\|?\||\?|\*|\//gi,punctuation:/[;[\]()`,.]/g};; 13 | Prism.languages.ruby=Prism.languages.extend("clike",{comment:/#[^\r\n]*(\r?\n|$)/g,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/g,builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*[?!]?\b/g}),Prism.languages.insertBefore("ruby","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0},variable:/[@$]+\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g,symbol:/:\b[a-zA-Z_][a-zA-Z_0-9]*[?!]?\b/g});; 14 | Prism.languages.csharp=Prism.languages.extend("clike",{keyword:/\b(abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/g,string:/@?("|')(\\?.)*?\1/g,preprocessor:/^\s*#.*/gm,number:/\b-?(0x)?\d*\.?\d+\b/g});; 15 | Prism.languages.scala=Prism.languages.extend("java",{keyword:/(<-|=>)|\b(abstract|case|catch|class|def|do|else|extends|final|finally|for|forSome|if|implicit|import|lazy|match|new|null|object|override|package|private|protected|return|sealed|self|super|this|throw|trait|try|type|val|var|while|with|yield)\b/g,builtin:/\b(String|Int|Long|Short|Byte|Boolean|Double|Float|Char|Any|AnyRef|AnyVal|Unit|Nothing)\b/g,number:/\b0x[\da-f]*\.?[\da-f\-]+\b|\b\d*\.?\d+[e]?[\d]*[dfl]?\b/gi,symbol:/'([^\d\s]\w*)/g,string:/(""")[\W\w]*?\1|("|\/)[\W\w]*?\2|('.')/g}),delete Prism.languages.scala["function"];; 16 | Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=\?&@|~.:<>^\\])(--[^-!#$%*+=\?&@|~.:<>^\\].*(\r?\n|$)|{-[\w\W]*?-})/gm,lookbehind:!0},"char":/'([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+))'/g,string:/"([^\\"]|\\([abfnrtv\\"'&]|\^[A-Z@[\]\^_]|NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|\d+|o[0-7]+|x[0-9a-fA-F]+)|\\\s+\\)*"/g,keyword:/\b(case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/g,import_statement:{pattern:/(\n|^)\s*(import)\s+(qualified\s+)?(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*)(\s+(as)\s+(([A-Z][_a-zA-Z0-9']*)(\.[A-Z][_a-zA-Z0-9']*)*))?(\s+hiding\b)?/gm,inside:{keyword:/\b(import|qualified|as|hiding)\b/g}},builtin:/\b(abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/g,number:/\b(\d+(\.\d+)?([eE][+-]?\d+)?|0[Oo][0-7]+|0[Xx][0-9a-fA-F]+)\b/g,operator:/\s\.\s|([-!#$%*+=\?&@|~:<>^\\]*\.[-!#$%*+=\?&@|~:<>^\\]+)|([-!#$%*+=\?&@|~:<>^\\]+\.[-!#$%*+=\?&@|~:<>^\\]*)|[-!#$%*+=\?&@|~:<>^\\]+|(`([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*`)/g,hvariable:/\b([A-Z][_a-zA-Z0-9']*\.)*[_a-z][_a-zA-Z0-9']*\b/g,constant:/\b([A-Z][_a-zA-Z0-9']*\.)*[A-Z][_a-zA-Z0-9']*\b/g,punctuation:/[{}[\];(),.:]/g};; 17 | Prism.languages.ini={comment:/^\s*;.*$/gm,important:/\[.*?\]/gm,constant:/^\s*[^\s\=]+?(?=[ \t]*\=)/gm,"attr-value":{pattern:/\=.*/gm,inside:{punctuation:/^[\=]/g}}};; 18 | Prism.languages.latex={comment:/%.*?(\r?\n|$)$/m,string:/(\$)(\\?.)*?\1/g,punctuation:/[{}]/g,selector:/\\[a-z;,:\.]*/i};; 19 | Prism.languages.git={comment:/^#.*$/m,string:/("|')(\\?.)*?\1/gm,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s(--|-)\w+/m}},coord:/^@@.*@@$/m,deleted:/^-(?!-).+$/m,inserted:/^\+(?!\+).+$/m,commit_sha1:/^commit \w{40}$/m} 20 | ; 21 | !function(){if(self.Prism&&self.document&&document.querySelector){var t={js:"javascript",html:"markup",svg:"markup",xml:"markup",py:"python",rb:"ruby"};Array.prototype.slice.call(document.querySelectorAll("pre[data-src]")).forEach(function(e){var n=e.getAttribute("data-src"),r=(n.match(/\.(\w+)$/)||[,""])[1],a=t[r]||r,s=document.createElement("code");s.className="language-"+a,e.textContent="",s.textContent="Loading…",e.appendChild(s);var o=new XMLHttpRequest;o.open("GET",n,!0),o.onreadystatechange=function(){4==o.readyState&&(o.status<400&&o.responseText?(s.textContent=o.responseText,Prism.highlightElement(s)):s.textContent=o.status>=400?"✖ Error "+o.status+" while fetching file: "+o.statusText:"✖ Error: File does not exist or is empty")},o.send(null)})}}(); 22 | ; 23 | -------------------------------------------------------------------------------- /doc/content/style.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono|Open+Sans:400,600,700); 2 | 3 | /*-------------------------------------------------------------------------- 4 | Formatting for F# code snippets 5 | /*--------------------------------------------------------------------------*/ 6 | 7 | /* identifier */ 8 | span.i { color:#d1d1d1; } 9 | /* string */ 10 | span.s { color:#d4b43c; } 11 | /* keywords */ 12 | span.k { color:#4e98dc; } 13 | /* comment */ 14 | span.c { color:#96C71D; } 15 | /* operators */ 16 | span.o { color:#af75c1; } 17 | /* numbers */ 18 | span.n { color:#96C71D; } 19 | /* line number */ 20 | span.l { color:#80b0b0; } 21 | 22 | /* inactive code */ 23 | span.inactive { color:#808080; } 24 | /* preprocessor */ 25 | span.prep { color:#af75c1; } 26 | /* fsi output */ 27 | span.fsi { color:#808080; } 28 | 29 | /* omitted */ 30 | span.omitted { 31 | background:#3c4e52; 32 | border-radius:5px; 33 | color:#808080; 34 | padding:0px 0px 1px 0px; 35 | } 36 | /* tool tip */ 37 | div.tip { 38 | background:#475b5f; 39 | border-radius:4px; 40 | font:11pt 'Droid Sans', arial, sans-serif; 41 | padding:6px 8px 6px 8px; 42 | display:none; 43 | color:#d1d1d1; 44 | } 45 | table.pre pre { 46 | padding:0px; 47 | margin:0px; 48 | border:none; 49 | } 50 | table.pre, pre.fssnip, pre { 51 | line-height:13pt; 52 | border:1px solid #d8d8d8; 53 | border-collapse:separate; 54 | white-space:pre; 55 | font: 9pt 'Droid Sans Mono',consolas,monospace; 56 | width:90%; 57 | margin:10px 20px 20px 20px; 58 | background-color:#212d30; 59 | padding:10px; 60 | border-radius:5px; 61 | color:#d1d1d1; 62 | } 63 | table.pre pre { 64 | padding:0px; 65 | margin:0px; 66 | border-radius:0px; 67 | width: 100%; 68 | } 69 | table.pre td { 70 | padding:0px; 71 | white-space:normal; 72 | margin:0px; 73 | } 74 | table.pre td.lines { 75 | width:30px; 76 | } 77 | 78 | /*-------------------------------------------------------------------------- 79 | Formatting for page & standard document content 80 | /*--------------------------------------------------------------------------*/ 81 | 82 | body { 83 | font-family: 'Open Sans', serif; 84 | padding-top: 0px; 85 | padding-bottom: 40px; 86 | } 87 | 88 | pre { 89 | word-wrap: inherit; 90 | } 91 | 92 | /* Format the heading - nicer spacing etc. */ 93 | .masthead { 94 | overflow: hidden; 95 | } 96 | .masthead .muted a { 97 | text-decoration:none; 98 | color:#999999; 99 | } 100 | .masthead ul, .masthead li { 101 | margin-bottom:0px; 102 | } 103 | .masthead .nav li { 104 | margin-top: 15px; 105 | font-size:110%; 106 | } 107 | .masthead h3 { 108 | margin-bottom:5px; 109 | font-size:170%; 110 | } 111 | hr { 112 | margin:0px 0px 20px 0px; 113 | } 114 | 115 | /* Make table headings and td.title bold */ 116 | td.title, thead { 117 | font-weight:bold; 118 | } 119 | 120 | /* Format the right-side menu */ 121 | #menu { 122 | margin-top:50px; 123 | font-size:11pt; 124 | padding-left:20px; 125 | } 126 | 127 | #menu .nav-header { 128 | font-size:12pt; 129 | color:#606060; 130 | margin-top:20px; 131 | } 132 | 133 | #menu li { 134 | line-height:25px; 135 | } 136 | 137 | /* Change font sizes for headings etc. */ 138 | #main h1 { font-size: 26pt; margin:10px 0px 15px 0px; font-weight:400; } 139 | #main h2 { font-size: 20pt; margin:20px 0px 0px 0px; font-weight:400; } 140 | #main h3 { font-size: 14pt; margin:15px 0px 0px 0px; font-weight:600; } 141 | #main p { font-size: 11pt; margin:5px 0px 15px 0px; } 142 | #main ul { font-size: 11pt; margin-top:10px; } 143 | #main li { font-size: 11pt; margin: 5px 0px 5px 0px; } 144 | #main strong { font-weight:700; } 145 | 146 | /*-------------------------------------------------------------------------- 147 | Formatting for API reference 148 | /*--------------------------------------------------------------------------*/ 149 | 150 | .type-list .type-name, .module-list .module-name { 151 | width:25%; 152 | font-weight:bold; 153 | } 154 | .member-list .member-name { 155 | width:35%; 156 | } 157 | #main .xmldoc h2 { 158 | font-size:14pt; 159 | margin:10px 0px 0px 0px; 160 | } 161 | #main .xmldoc h3 { 162 | font-size:12pt; 163 | margin:10px 0px 0px 0px; 164 | } 165 | .github-link { 166 | float:right; 167 | text-decoration:none; 168 | } 169 | .github-link img { 170 | border-style:none; 171 | margin-left:10px; 172 | } 173 | .github-link .hover { display:none; } 174 | .github-link:hover .hover { display:block; } 175 | .github-link .normal { display: block; } 176 | .github-link:hover .normal { display: none; } 177 | 178 | /*-------------------------------------------------------------------------- 179 | Links 180 | /*--------------------------------------------------------------------------*/ 181 | 182 | h1 a, h1 a:hover, h1 a:focus, 183 | h2 a, h2 a:hover, h2 a:focus, 184 | h3 a, h3 a:hover, h3 a:focus, 185 | h4 a, h4 a:hover, h4 a:focus, 186 | h5 a, h5 a:hover, h5 a:focus, 187 | h6 a, h6 a:hover, h6 a:focus { color : inherit; text-decoration : inherit; outline:none } 188 | 189 | /*-------------------------------------------------------------------------- 190 | Additional formatting for the homepage 191 | /*--------------------------------------------------------------------------*/ 192 | 193 | #nuget { 194 | margin-top:20px; 195 | font-size: 11pt; 196 | padding:20px; 197 | } 198 | 199 | #nuget pre { 200 | font-size:11pt; 201 | -moz-border-radius: 0px; 202 | -webkit-border-radius: 0px; 203 | border-radius: 0px; 204 | background: #404040; 205 | border-style:none; 206 | color: #e0e0e0; 207 | margin-top:15px; 208 | } -------------------------------------------------------------------------------- /doc/content/tips.js: -------------------------------------------------------------------------------- 1 | var currentTip = null; 2 | var currentTipElement = null; 3 | 4 | function hideTip(evt, name, unique) { 5 | var el = document.getElementById(name); 6 | el.style.display = "none"; 7 | currentTip = null; 8 | } 9 | 10 | function findPos(obj) { 11 | // no idea why, but it behaves differently in webbrowser component 12 | if (window.location.search == "?inapp") 13 | return [obj.offsetLeft + 10, obj.offsetTop + 30]; 14 | 15 | var curleft = 0; 16 | var curtop = obj.offsetHeight; 17 | while (obj) { 18 | curleft += obj.offsetLeft; 19 | curtop += obj.offsetTop; 20 | obj = obj.offsetParent; 21 | }; 22 | return [curleft, curtop]; 23 | } 24 | 25 | function hideUsingEsc(e) { 26 | if (!e) { e = event; } 27 | hideTip(e, currentTipElement, currentTip); 28 | } 29 | 30 | function showTip(evt, name, unique, owner) { 31 | document.onkeydown = hideUsingEsc; 32 | if (currentTip == unique) return; 33 | currentTip = unique; 34 | currentTipElement = name; 35 | 36 | var pos = findPos(owner ? owner : (evt.srcElement ? evt.srcElement : evt.target)); 37 | var posx = pos[0]; 38 | var posy = pos[1]; 39 | 40 | var el = document.getElementById(name); 41 | var parent = (document.documentElement == null) ? document.body : document.documentElement; 42 | el.style.position = "absolute"; 43 | el.style.left = posx + "px"; 44 | el.style.top = posy + "px"; 45 | el.style.display = "block"; 46 | } -------------------------------------------------------------------------------- /doc/templates/docpage-index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "template"; 3 | Title = Properties["page-title"]; 4 | Description = Properties["project-summary"]; 5 | } 6 | 7 | @Properties["document"] 8 | @Properties["tooltips"] -------------------------------------------------------------------------------- /doc/templates/docpage.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "template"; 3 | Title = Properties["page-title"]; 4 | Description = Properties["project-summary"]; 5 | } 6 | @Properties["document"] 7 | @Properties["tooltips"] -------------------------------------------------------------------------------- /doc/templates/reference/module.cshtml: -------------------------------------------------------------------------------- 1 | @using FSharp.MetadataFormat 2 | @{ 3 | Layout = "template"; 4 | Title = Model.Module.Name + " - " + Properties["project-name"]; 5 | } 6 | 7 | @{ 8 | // Get all the members & comment for the type 9 | var members = (IEnumerable)Model.Module.AllMembers; 10 | var comment = (Comment)Model.Module.Comment; 11 | 12 | // Group all members by their category which is an inline annotation 13 | // that can be added to members using special XML comment: 14 | // 15 | // /// [category:Something] 16 | // 17 | // ...and can be used to categorize members in large modules or types 18 | // (but if this is not used, then all members end up in just one category) 19 | var byCategory = members 20 | .GroupBy(m => m.Category) 21 | .OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key) 22 | .Select((g, n) => new { 23 | Index = n, 24 | GroupKey = g.Key, 25 | Members = g.OrderBy(m => m.Name), 26 | Name = String.IsNullOrEmpty(g.Key) ? "Other module members" : g.Key 27 | }); 28 | 29 | // Get nested modules and nested types as statically typed collections 30 | var nestModules = (IEnumerable)Model.Module.NestedModules; 31 | var nestTypes = (IEnumerable)Model.Module.NestedTypes; 32 | } 33 | 34 |

@Model.Module.Name

35 |
36 | Defined in @(Model.Module.Assembly.Name).dll. 37 |
38 |
39 | @foreach (var sec in comment.Sections) { 40 | // XML comment for the type has multiple sections that can be labelled 41 | // with categories (to give comment for an individual category). Here, 42 | // we print only those that belong to the section. 43 | if (!byCategory.Any(g => g.GroupKey == sec.Key)) 44 | { 45 | if (sec.Key != "") { 46 |

@sec.Key

47 | } 48 | @sec.Value 49 | } 50 | } 51 |
52 | @if (byCategory.Count() > 1) 53 | { 54 | 55 |

Table of contents

56 |
    57 | @foreach (var g in byCategory) 58 | { 59 |
  • @g.Name
  • 60 | } 61 |
62 | } 63 | 64 | 65 | @if (nestTypes.Count() + nestModules.Count() > 0) 66 | { 67 |

Nested types and modules

68 |
69 | @RenderPart("part-nested", new { 70 | Types = nestTypes, 71 | Modules = nestModules 72 | }) 73 |
74 | } 75 | 76 | @foreach (var g in byCategory) 77 | { 78 | // Iterate over all the categories and print members. If there are more than one 79 | // categories, print the category heading (as

) and add XML comment from the type 80 | // that is related to this specific category. 81 | if (byCategory.Count() > 1) 82 | { 83 |

@g.Name 

84 | var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey); 85 | if (info.Key != null) 86 | { 87 |
88 | @info.Value 89 |
90 | } 91 | } 92 | 93 | @RenderPart("part-members", new { 94 | Header = "Functions and values", 95 | TableHeader = "Function or value", 96 | Members = g.Members.Where(m => m.Kind == MemberKind.ValueOrFunction) 97 | }) 98 | 99 | @RenderPart("part-members", new { 100 | Header = "Type extensions", 101 | TableHeader = "Type extension", 102 | Members = g.Members.Where(m => m.Kind == MemberKind.TypeExtension) 103 | }) 104 | 105 | @RenderPart("part-members", new { 106 | Header = "Active patterns", 107 | TableHeader = "Active pattern", 108 | Members = g.Members.Where(m => m.Kind == MemberKind.ActivePattern) 109 | }) 110 | } -------------------------------------------------------------------------------- /doc/templates/reference/namespaces.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "template"; 3 | Title = "Namespaces - " + Properties["project-name"]; 4 | } 5 | 6 |

@Model.Name

7 | 8 |

Overview

9 | @foreach (var ns in Model.Namespaces) 10 | { 11 | if (ns.Types.Length + ns.Modules.Length > 0) 12 | { 13 | @ns.Name
14 | } 15 | } 16 | 17 | @foreach (var ns in Model.Namespaces) 18 | { 19 | if (ns.Types.Length + ns.Modules.Length > 0) 20 | { 21 |

Back to top @ns.Name Namespace

22 |
23 | @RenderPart("part-nested", new { 24 | Types = ns.Types, 25 | Modules = ns.Modules 26 | }) 27 |
28 | } 29 | } 30 | -------------------------------------------------------------------------------- /doc/templates/reference/part-members.cshtml: -------------------------------------------------------------------------------- 1 | @if (Enumerable.Count(Model.Members) > 0) { 2 |

@Model.Header

3 | 4 | 5 | 6 | 7 | 8 | @foreach (var it in Model.Members) 9 | { 10 | 11 | 26 | 36 | 37 | } 38 | 39 |
@Model.TableHeaderDescription
12 | @{ var id = Html.UniqueID().ToString(); } 13 | 14 | @Html.Encode(it.Details.FormatUsage(40)) 15 | 16 |
17 | Signature: @Html.Encode(it.Details.Signature)
18 | @if (!it.Details.Modifiers.IsEmpty) { 19 | Modifiers: @it.Details.FormatModifiers
20 | } 21 | @if (!it.Details.TypeArguments.IsEmpty) { 22 | Type parameters: @it.Details.FormatTypeArguments 23 | } 24 |
25 |
27 | @if (!String.IsNullOrEmpty(it.Details.FormatSourceLocation)) 28 | { 29 | 30 | 31 | 32 | 33 | } 34 | @it.Comment.FullText 35 |
40 | } -------------------------------------------------------------------------------- /doc/templates/reference/part-nested.cshtml: -------------------------------------------------------------------------------- 1 | @if (Enumerable.Count(Model.Types) > 0) { 2 | 3 | 4 | 5 | 6 | 7 | @foreach (var it in Model.Types) 8 | { 9 | 10 | 13 | 14 | 15 | } 16 | 17 |
TypeDescription
11 | @it.Name 12 | @it.Comment.Blurb
18 | } 19 | @if (Enumerable.Count(Model.Modules) > 0) { 20 | 21 | 22 | 23 | 24 | 25 | @foreach (var it in Model.Modules) 26 | { 27 | 28 | 31 | 32 | 33 | } 34 | 35 |
ModuleDescription
29 | @it.Name 30 | @it.Comment.Blurb
36 | } -------------------------------------------------------------------------------- /doc/templates/reference/type.cshtml: -------------------------------------------------------------------------------- 1 | @using FSharp.MetadataFormat 2 | @{ 3 | Layout = "template"; 4 | Title = Model.Type.Name + " - " + Properties["project-name"]; 5 | } 6 | 7 | @{ 8 | // Get all the members & comment for the type 9 | var members = (IEnumerable)Model.Type.AllMembers; 10 | var comment = (Comment)Model.Type.Comment; 11 | 12 | // Group all members by their category which is an inline annotation 13 | // that can be added to members using special XML comment: 14 | // 15 | // /// [category:Something] 16 | // 17 | // ...and can be used to categorize members in large modules or types 18 | // (but if this is not used, then all members end up in just one category) 19 | var byCategory = members 20 | .GroupBy(m => m.Category) 21 | .OrderBy(g => String.IsNullOrEmpty(g.Key) ? "ZZZ" : g.Key) 22 | .Select((g, n) => new { 23 | Index = n, 24 | GroupKey = g.Key, 25 | Members = g.OrderBy(m => m.Kind == MemberKind.StaticParameter ? "" : m.Name), 26 | Name = String.IsNullOrEmpty(g.Key) ? "Other type members" : g.Key 27 | }); 28 | } 29 | 30 |

@Model.Type.Name

31 |
32 | Defined in @(Model.Type.Assembly.Name).dll. 33 |
34 |
35 | @foreach (var sec in comment.Sections) { 36 | // XML comment for the type has multiple sections that can be labelled 37 | // with categories (to give comment for an individual category). Here, 38 | // we print only those that belong to the section. 39 | if (!byCategory.Any(g => g.GroupKey == sec.Key)) { 40 | if (sec.Key != "") { 41 |

@sec.Key

42 | } 43 | @sec.Value 44 | } 45 | } 46 |
47 | @if (byCategory.Count() > 1) 48 | { 49 | 50 |

Table of contents

51 |
    52 | @foreach (var g in byCategory) 53 | { 54 |
  • @g.Name
  • 55 | } 56 |
57 | } 58 | @foreach (var g in byCategory) { 59 | // Iterate over all the categories and print members. If there are more than one 60 | // categories, print the category heading (as

) and add XML comment from the type 61 | // that is related to this specific category. 62 | if (byCategory.Count() > 1) { 63 |

@g.Name 

64 | var info = comment.Sections.FirstOrDefault(kvp => kvp.Key == g.GroupKey); 65 | if (info.Key != null) { 66 |
67 | @info.Value 68 |
69 | } 70 | } 71 | 72 | @RenderPart("part-members", new { 73 | Header = "Union Cases", 74 | TableHeader = "Union Case", 75 | Members = g.Members.Where(m => m.Kind == MemberKind.UnionCase) 76 | }) 77 | 78 | @RenderPart("part-members", new { 79 | Header = "Record Fields", 80 | TableHeader = "Record Field", 81 | Members = g.Members.Where(m => m.Kind == MemberKind.RecordField) 82 | }) 83 | 84 | @RenderPart("part-members", new { 85 | Header = "Static parameters", 86 | TableHeader = "Static parameters", 87 | Members = g.Members.Where(m => m.Kind == MemberKind.StaticParameter) 88 | }) 89 | 90 | @RenderPart("part-members", new { 91 | Header = "Constructors", 92 | TableHeader = "Constructor", 93 | Members = g.Members.Where(m => m.Kind == MemberKind.Constructor) 94 | }) 95 | 96 | @RenderPart("part-members", new { 97 | Header = "Instance members", 98 | TableHeader = "Instance member", 99 | Members = g.Members.Where(m => m.Kind == MemberKind.InstanceMember) 100 | }) 101 | 102 | @RenderPart("part-members", new { 103 | Header = "Static members", 104 | TableHeader = "Static member", 105 | Members = g.Members.Where(m => m.Kind == MemberKind.StaticMember) 106 | }) 107 | } 108 | -------------------------------------------------------------------------------- /doc/templates/template-color.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | % Defining colors by names 4 | \usepackage{xcolor} 5 | % Verbatim enviroment 6 | \usepackage{fancyvrb} 7 | % Verbatim enviroment for unformatted source code 8 | \usepackage{listings} 9 | % Better font for backslash 10 | \usepackage[T1]{fontenc} 11 | \usepackage{hyperref} 12 | % Providing more features than usual tabular 13 | \usepackage{longtable} 14 | 15 | % Identifiers in color code #000000 16 | \newcommand{\id}[1]{\textcolor{black}{#1}} 17 | 18 | % Comments in green 19 | \definecolor{officegreen}{rgb}{0, 0.5, 0} 20 | \newcommand{\com}[1]{\textcolor{officegreen}{#1}} 21 | 22 | % Inactive elements in color code #808080 23 | \newcommand{\inact}[1]{\textcolor{gray}{#1}} 24 | 25 | % Keywords in color code #000080 26 | \definecolor{navy}{rgb}{0, 0, 0.5} 27 | \newcommand{\kwd}[1]{\textcolor{navy}{#1}} 28 | 29 | % Numbers in color code #008000 30 | \newcommand{\num}[1]{\textcolor{officegreen}{#1}} 31 | 32 | % Operators in color code #800080 33 | \newcommand{\ops}[1]{\textcolor{purple}{#1}} 34 | 35 | % Preprocessors in color code #800080 36 | \newcommand{\prep}[1]{\textcolor{purple}{#1}} 37 | 38 | % Strings in color code #808000 39 | \newcommand{\str}[1]{\textcolor{olive}{#1}} 40 | 41 | % Lines in color code #80b0b0 42 | % Define relative color to work correctly with \newcommand 43 | \definecolor{linecolor}{rgb}{0.5, 0.6875, 0.6875} 44 | \newcommand{\lines}[1]{\textcolor{linecolor}{#1}} 45 | 46 | % fsi output in color code #606060 47 | \definecolor{outputcolor}{rgb}{0.375, 0.375, 0.375} 48 | \newcommand{\fsi}[1]{\textcolor{outputcolor}{#1}} 49 | 50 | % Omitted parts in color code #808080 51 | \newcommand{\omi}[1]{\textcolor{gray}{#1}} 52 | 53 | % Overriding color and style of line numbers 54 | \renewcommand{\theFancyVerbLine}{ 55 | \lines{\small \arabic{FancyVerbLine}:}} 56 | 57 | \lstset{% 58 | backgroundcolor=\color{gray!15}, 59 | basicstyle=\ttfamily, 60 | breaklines=true, 61 | columns=fullflexible 62 | } 63 | 64 | \title{{page-title}} 65 | \date{} 66 | 67 | \begin{document} 68 | 69 | \maketitle 70 | 71 | {contents} 72 | 73 | {tooltips} 74 | 75 | \end{document} 76 | -------------------------------------------------------------------------------- /doc/templates/template-math.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | 3 | % Defining colors by names 4 | \usepackage{xcolor} 5 | % Verbatim enviroment 6 | \usepackage{fancyvrb} 7 | % Verbatim enviroment for unformatted source code 8 | \usepackage{listings} 9 | % Better font for backslash 10 | \usepackage[T1]{fontenc} 11 | \usepackage{hyperref} 12 | % Providing more features than usual tabular 13 | \usepackage{longtable} 14 | % Augment with more font faces 15 | \usepackage{bera} 16 | % More math symbols 17 | \usepackage{amssymb} 18 | 19 | % Simple key value store 20 | % (source at http://tex.stackexchange.com/questions/48907/global-key-value-dictionary) 21 | \def\addvalue#1#2{\expandafter\gdef\csname my@data@\detokenize{#1}\endcsname{#2}} 22 | \def\usevalue#1{% 23 | \ifcsname my@data@\detokenize{#1}\endcsname 24 | \csname my@data@\detokenize{#1}\expandafter\endcsname 25 | \else 26 | % if not found, return key as value 27 | {#1}\expandafter 28 | \fi 29 | } 30 | 31 | \addvalue{>=}{$\geq$} 32 | \addvalue{<=}{$\leq$} 33 | \addvalue{<>}{$\neq$} 34 | \addvalue{not}{$\neg$} 35 | \addvalue{&&}{$\land$} 36 | \addvalue{||}{$\lor$} 37 | \addvalue{->}{$\rightarrow$} 38 | \addvalue{<-}{$\leftarrow$} 39 | \addvalue{=>}{$\Rightarrow$} 40 | \addvalue{*}{$\times$} 41 | \addvalue{|>}{$\blacktriangleright$} 42 | \addvalue{<|}{$\blacktriangleleft$} 43 | 44 | % Identifiers 45 | \newcommand{\id}[1]{\texttt{#1}} 46 | 47 | % Comments 48 | \newcommand{\com}[1]{\textit{#1}} 49 | 50 | % Inactive elements 51 | \newcommand{\inact}[1]{\textmd{#1}} 52 | 53 | % Keywords 54 | \newcommand{\kwd}[1]{\textbf{#1}} 55 | 56 | % Numbers 57 | \newcommand{\num}[1]{\textrm{#1}} 58 | 59 | % Operators 60 | \newcommand{\ops}[1]{\usevalue{#1}} 61 | 62 | % Preprocessors 63 | \newcommand{\prep}[1]{\textsf{#1}} 64 | 65 | % Strings 66 | \newcommand{\str}[1]{\textrm{#1}} 67 | 68 | % Line numbers 69 | \newcommand{\lines}[1]{\textrm{#1}} 70 | 71 | % fsi output 72 | \newcommand{\fsi}[1]{\textsf{#1}} 73 | 74 | % Omitted parts 75 | \newcommand{\omi}[1]{\textsc{#1}} 76 | 77 | % Overriding color and style of line numbers 78 | \renewcommand{\theFancyVerbLine}{ 79 | \lines{\small \arabic{FancyVerbLine}:}} 80 | 81 | \lstset{% 82 | backgroundcolor=\color{gray!15}, 83 | basicstyle=\ttfamily, 84 | breaklines=true, 85 | columns=fullflexible 86 | } 87 | 88 | \title{{page-title}} 89 | \date{} 90 | 91 | \begin{document} 92 | 93 | \maketitle 94 | 95 | {contents} 96 | 97 | {tooltips} 98 | 99 | \end{document} 100 | -------------------------------------------------------------------------------- /doc/templates/template.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 |
27 | 35 |
36 |
37 |
38 | @RenderBody() 39 |
40 |
41 | 42 | 43 | 44 | 45 | 70 |
71 |
72 |
73 | Fork me on GitHub 74 | 75 | 76 | -------------------------------------------------------------------------------- /generateDocs.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | #load "packages/Yaaf.AdvancedBuilding/content/buildConfigDef.fsx" 6 | #load @"buildConfig.fsx" 7 | #load "packages/Yaaf.AdvancedBuilding/content/generateDocsInclude.fsx" 8 | open Fake 9 | RunTargetOrDefault "LocalDoc" -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | This file is in the `lib` directory. 2 | 3 | Any **libraries** on which your project depends and which are **NOT managed via NuGet** should be kept **in this directory**. 4 | This typically includes custom builds of third-party software, private (i.e. to a company) codebases, and native libraries. 5 | 6 | --- 7 | NOTE: 8 | 9 | This file is a placeholder, used to preserve directory structure in Git. 10 | 11 | This file does not need to be edited. 12 | -------------------------------------------------------------------------------- /nuget/Yaaf.FSharp.Scripting.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @project@ 5 | @build.number@ 6 | @authors@ 7 | @authors@ 8 | http://github.com/matthid/Yaaf.FSharp.Scripting/blob/develop/LICENSE.md 9 | http://matthid.github.com/Yaaf.FSharp.Scripting 10 | https://raw.githubusercontent.com/matthid/Yaaf.FSharp.Scripting/develop/doc/content/img/logo.png 11 | false 12 | @summary@ 13 | @description@ 14 | @releaseNotes@ 15 | Copyright 2015 16 | @tags@ 17 | @dependencies@ 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM cls 3 | set nuget_packages=packages 4 | set paket_packages=packages 5 | 6 | set nuget_path=NuGet.CommandLine/tools/NuGet.exe 7 | set fake_path=FAKE/tools/FAKE.exe 8 | 9 | REM resore paket build dependencies 10 | if exist ".paket/paket.bootstrapper.exe" ( 11 | echo Bootstrap paket 12 | .paket\paket.bootstrapper.exe %PAKET_VERSION% 13 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 14 | 15 | REM Batch is just a useless shit 16 | if "%PAKET_UPDATE%" == "y" ( 17 | echo Running paket update - as requested by PAKET_UPDATE=y 18 | .paket\paket.exe update 19 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 20 | ) 21 | 22 | if "%PAKET_UPDATE%" == "true" ( 23 | echo Running paket update - as requested by PAKET_UPDATE=y 24 | .paket\paket.exe update 25 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 26 | ) 27 | 28 | 29 | 30 | echo restore paket packages 31 | .paket\paket.exe restore 32 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 33 | 34 | set fake=%paket_packages%/%fake_path% 35 | set nuget=%paket_packages%/%nuget_path% 36 | ) 37 | REM Download NuGet (if not already available because of paket) 38 | if not exist %nuget% ( 39 | if exist downloadNuget.fsx ( 40 | if not exist %nuget_packages%/%nuget_path% ( 41 | echo Bootstrap Nuget 42 | "C:\Program Files (x86)\Microsoft SDKs\F#\3.1\Framework\v4.0\fsi.exe" downloadNuget.fsx 43 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 44 | ) 45 | set nuget=%nuget_packages%/%nuget_path% 46 | ) 47 | ) 48 | REM Restore Nuget build dependencies 49 | if exist packages.config ( 50 | if exist %nuget% ( 51 | echo Resolve build dependencies 52 | "%nuget%" "install" "packages.config" "-OutputDirectory" %nuget_packages% "-ExcludeVersion" 53 | if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% 54 | ) else ( 55 | echo NuGet build dependencies file found but no NuGet.exe could be found, either add downloadNuget.fsx or add Nuget.Commandline as paket dependency!. 56 | ) 57 | ) 58 | 59 | REM FAKE could be available as nuget dependency 60 | if not exist %fake% ( 61 | set fake=%nuget_packages%/%fake_path% 62 | if not exist %fake% ( 63 | echo Could not find FAKE in nuget or paket dependencies! 64 | exit /b 1 65 | ) 66 | ) 67 | 68 | echo start FAKE for the rest of the build procedure... 69 | "%fake%" %* --fsiargs -d:WIN64 -d:FAKE build.fsx 70 | 71 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if test "$OS" = "Windows_NT" 3 | then 4 | # use .Net 5 | MONO="" 6 | DEFINE="WIN64" 7 | FSI="C:\Program Files (x86)\Microsoft SDKs\F#\3.1\Framework\v4.0\fsi.exe" 8 | else 9 | # use mono 10 | command -v mono >/dev/null 2>&1 || { echo >&2 "Please install mono dependency."; exit 1; } 11 | myMono="mono --debug --runtime=v4.0" 12 | FSI="fsharpi" 13 | 14 | MONO="$myMono" 15 | DEFINE="MONO" 16 | fi 17 | 18 | function do_build { 19 | nuget_packages="packages" 20 | paket_packages="packages" 21 | 22 | nuget_path="NuGet.CommandLine/tools/NuGet.exe" 23 | fake_path="FAKE/tools/FAKE.exe" 24 | 25 | # Restore paket build dependencies 26 | if [ -f ".paket/paket.bootstrapper.exe" ]; 27 | then 28 | echo "Bootstrap paket" 29 | $MONO .paket/paket.bootstrapper.exe $PAKET_VERSION 30 | exit_code=$? 31 | if [ $exit_code -ne 0 ]; then 32 | exit $exit_code 33 | fi 34 | 35 | if [ "$PAKET_UPDATE" == "y" ] || [ "$PAKET_UPDATE" == "true" ]; then 36 | echo "run paket update (as requested by PAKET_UPDATE=y)" 37 | $MONO .paket/paket.exe update 38 | exit_code=$? 39 | if [ $exit_code -ne 0 ]; then 40 | exit $exit_code 41 | fi 42 | fi 43 | 44 | echo "restore paket packages" 45 | $MONO .paket/paket.exe restore 46 | exit_code=$? 47 | if [ $exit_code -ne 0 ]; then 48 | exit $exit_code 49 | fi 50 | 51 | fake=$paket_packages/$fake_path 52 | nuget=$paket_packages/$nuget_path 53 | fi 54 | # Download NuGet (if not already available because of paket) 55 | if [ ! -f "$nuget" ]; 56 | then 57 | if [ -f downloadNuget.fsx ]; 58 | then 59 | if [ ! -f "$nuget_packages/$nuget_path" ]; then 60 | echo "Bootstrap Nuget" 61 | command -v "$FSI" >/dev/null 2>&1 || { echo >&2 "Please install fsharpi or download a NuGet.exe to $nuget_packages/$nuget_path"; exit 1; } 62 | "$FSI" downloadNuget.fsx 63 | fi 64 | nuget="$nuget_packages/$nuget_path" 65 | fi 66 | fi 67 | 68 | # Restore Nuget build dependencies 69 | if [ -f "packages.config" ]; 70 | then 71 | if [ -f "$nuget" ]; 72 | then 73 | echo "restore NuGet build dependencies." 74 | $MONO $nuget "install" "packages.config" "-OutputDirectory" "$nuget_packages" "-ExcludeVersion" 75 | else 76 | echo "NuGet build dependencies file found but no NuGet.exe could be found, either add downloadNuget.fsx or add Nuget.Commandline as paket dependency!." 77 | fi 78 | fi 79 | 80 | # FAKE could be available as nuget dependency 81 | if [ ! -f "$fake" ]; 82 | then 83 | fake="$nuget_packages/$fake_path" 84 | if [ ! -f "$fake" ]; 85 | then 86 | echo "Could not find FAKE in nuget or paket dependencies!" 87 | exit 1 88 | fi 89 | fi 90 | 91 | echo "start FAKE for the rest of the build procedure..." 92 | $MONO $fake $@ --fsiargs -d:$DEFINE -d:FAKE build.fsx 93 | return $? 94 | } 95 | 96 | if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then 97 | # we are sourced 98 | : 99 | else 100 | do_build $@ 101 | fi 102 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(MSBuildToolsPath)\Microsoft.CSharp.targets 7 | 8 | 9 | 10 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.5\Microsoft.FSharp.Targets 11 | 12 | 13 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.5\Microsoft.FSharp.Targets 14 | 15 | 16 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets 17 | 18 | 19 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.FSharp.Targets 20 | 21 | 22 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.0\Microsoft.FSharp.Targets 23 | 24 | 25 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.5\Microsoft.FSharp.Targets 26 | 27 | 28 | 29 | 30 | $(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets 31 | 32 | 33 | 34 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.5\Microsoft.Portable.FSharp.Targets 35 | 36 | 37 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.5\Microsoft.Portable.FSharp.Targets 38 | 39 | 40 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.Portable.FSharp.Targets 41 | 42 | 43 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.1\Framework\v4.0\Microsoft.Portable.FSharp.Targets 44 | 45 | 46 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.0\Microsoft.Portable.FSharp.Targets 47 | 48 | 49 | $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\4.0\Framework\v4.5\Microsoft.Portable.FSharp.Targets 50 | 51 | 52 | 53 | 54 | $(OutputPath)\$(AssemblyName).xml 55 | 56 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/buildConfigDef.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | #I @"../../FAKE/tools/" 6 | #r @"FakeLib.dll" 7 | // NOTE: We cannot add those here because FSharp.Formatting requires Razor2 8 | //#I @"../../FSharp.Compiler.Service/lib/net40/" 9 | //#I @"../../Yaaf.FSharp.Scripting/lib/net40/" 10 | //#I "../tools/" 11 | //#r "Yaaf.AdvancedBuilding.dll" 12 | 13 | 14 | open System.IO 15 | open System 16 | 17 | open Fake 18 | open Fake.Testing.NUnit3 19 | open Fake.MSTest 20 | open AssemblyInfoFile 21 | 22 | (** 23 | ## The `BuildParams` Type 24 | 25 | You can define your own type for building, the only limitation is that this type needs the `SimpleBuildName` and `CustomBuildName` properties. 26 | The `SimpleBuildName` property is used for the generated FAKE target for this build `(sprintf "Build_%s" build.SimpleBuildName)`. 27 | The `CustomBuildName` is used as a parameter for msbuild/xbuild and can be used within the fsproj and csproj files to define custom builds. 28 | (IE. custom defines / targets and so on). 29 | The `CustomBuildName` property is also used as the name of the sub-directory within the `buildDir` (see below). 30 | *) 31 | 32 | type BuildParams = 33 | { /// The name of the output folder and the build target 34 | SimpleBuildName : string 35 | /// The name of the platform to build 36 | PlatformName : string 37 | BuildMode : string 38 | DisableProjectFileCreation : bool 39 | UseProjectOutDir : bool 40 | BeforeBuild : unit -> unit 41 | AfterBuild : unit -> unit 42 | AfterTest : unit -> unit 43 | FindSolutionFiles : BuildParams -> string seq 44 | FindProjectFiles : BuildParams -> string seq 45 | FindTestFiles : BuildParams -> string seq 46 | FindUnitTestDlls : (string * BuildParams) -> string seq } 47 | static member Empty = 48 | { SimpleBuildName = "" 49 | BuildMode = "Release" 50 | BeforeBuild = fun _ -> () 51 | AfterBuild = fun _ -> () 52 | AfterTest = fun _ -> () 53 | PlatformName = "AnyCPU" 54 | DisableProjectFileCreation = false 55 | UseProjectOutDir = false 56 | FindSolutionFiles = fun _ -> Seq.empty 57 | FindProjectFiles = fun (_:BuildParams) -> 58 | !! (sprintf "src/**/*.fsproj") 59 | ++ (sprintf "src/**/*.csproj") 60 | -- (sprintf "src/**/*.Tests.fsproj") 61 | -- (sprintf "src/**/*.Tests.csproj") 62 | -- (sprintf "src/**/Test.*.fsproj") 63 | -- (sprintf "src/**/Test.*.csproj") 64 | :> _ 65 | FindTestFiles = fun (_:BuildParams) -> 66 | !! (sprintf "src/**/*.Tests.fsproj") 67 | ++ (sprintf "src/**/*.Tests.csproj") 68 | ++ (sprintf "src/**/Test.*.fsproj") 69 | ++ (sprintf "src/**/Test.*.csproj") 70 | :> _ 71 | FindUnitTestDlls = fun (testDir, (_:BuildParams)) -> 72 | !! (testDir + "/Test.*.dll") 73 | ++ (testDir + "/*.Tests.dll") 74 | :> _ } 75 | static member WithSolution = 76 | { BuildParams.Empty with 77 | BuildMode = "Release" 78 | PlatformName = "Any CPU" 79 | UseProjectOutDir = true 80 | FindSolutionFiles = fun _ -> !! "**/*.sln" :> _ 81 | FindProjectFiles = fun _ -> Seq.empty 82 | FindTestFiles = fun _ -> Seq.empty } 83 | 84 | /// see http://tpetricek.github.io/FSharp.Formatting/diagnostics.html 85 | type FSharpFormattingLogging = 86 | /// Disable all logging. F# Formatting will not print anything to the console and it will also not produce a log file (this is not recomended, but you might need this if you want to suppress all output). 87 | | DisableFSFLogging 88 | /// Enables detailed logging to a file FSharp.Formatting.svclog and keeps printing of basic information to console too. 89 | | AllFSFLogging 90 | /// Enables detailed logging to a file FSharp.Formatting.svclog but disables printing of basic information to console. 91 | | FileOnlyFSFLogging 92 | /// Any other value (default) - Print basic information to console and do not produce a detailed log file. 93 | | ConsoleOnlyFSFLogging 94 | 95 | type NuGetPackage = 96 | { /// The version of the package (null = use global version) 97 | Version : string 98 | /// The filename of the nuspec (template) file, in the config.NugetDir folder 99 | FileName : string 100 | /// The prefix for the created tag (null = no tag will be created) 101 | TagPrefix : string 102 | /// identifier for this package 103 | SimpleName : string 104 | 105 | ConfigFun : (NuGetParams -> NuGetParams) } 106 | static member Empty = 107 | { Version = null 108 | FileName = null 109 | TagPrefix = null 110 | SimpleName = null 111 | ConfigFun = id } 112 | member x.Name = 113 | if isNull x.SimpleName then x.TagPrefix else x.SimpleName 114 | member x.TagName = 115 | if isNull x.TagPrefix then failwith "no TagPrefix is specified!" 116 | sprintf "%s%s" x.TagPrefix x.Version 117 | member x.VersionLine = 118 | sprintf "%s_%s" x.SimpleName (if isNull x.TagPrefix then x.Version else x.TagName) 119 | 120 | type BuildConfiguration = 121 | { // Metadata 122 | ProjectName : string 123 | ProjectSummary : string 124 | Company : string 125 | CopyrightNotice : string 126 | ProjectDescription : string 127 | ProjectAuthors : string list 128 | /// Enable all github integrations (pushing documentation) 129 | EnableGithub : bool 130 | GithubUser : string 131 | /// Defaults to ProjectName 132 | GithubProject : string 133 | PageAuthor : string 134 | /// Defaults to github issues 135 | IssuesUrl : string 136 | /// Defaults to github new issue page 137 | FileNewIssueUrl : string 138 | /// Defaults to github master branch "/blob/master/" 139 | SourceReproUrl : string 140 | 141 | // Nuget configuration 142 | /// Defaults to sprintf "https://www.nuget.org/packages/%s/" x.ProjectName 143 | NugetUrl : string 144 | NugetTags : string 145 | /// The directory for the nuspec (template) files. 146 | NugetDir : string 147 | /// Like NugetPackages but allows to define different versions (which will create tags) 148 | NugetVersionPackages : BuildConfiguration -> NuGetPackage list 149 | // [] 150 | // see https://fslang.uservoice.com/forums/245727-f-language/suggestions/12826233-hide-obsolete-warnings-on-record-initializer-not-u 151 | NugetPackages : (string * (BuildConfiguration -> NuGetParams -> NuGetParams)) list 152 | // Defaults to "./release/nuget/" 153 | OutNugetDir : string 154 | 155 | // Pre build 156 | Version : string 157 | /// Defaults to setting up a "./src/SharedAssemblyInfo.fs" and "./src/SharedAssemblyInfo.cs" 158 | SetAssemblyFileVersions : BuildConfiguration -> unit 159 | /// Enables to convert pdb to mdb or mdb to pdb after paket restore. 160 | /// This improves cross platform development and creates pdb files 161 | /// on unix (to create nuget packages on linux with integrated pdb files) 162 | EnableDebugSymbolConversion : bool 163 | 164 | /// Makes "./build.sh Release" fail when not executed on a windows machine 165 | /// Use this if you want to include .pdb in your nuget packge 166 | /// (to ensure your release contains debug symbols) 167 | RestrictReleaseToWindows : bool 168 | 169 | // Build configuration 170 | /// Defaults to [ x.ProjectName + ".dll"; x.ProjectName + ".xml" ] 171 | GeneratedFileList : string list 172 | /// Defaults to false (support for nuget msbuild integration) 173 | UseNuget : bool 174 | BuildTargets : BuildParams list 175 | /// Defaults to "./build/" 176 | BuildDir : string 177 | /// Defaults to "./release/lib/" 178 | OutLibDir : string 179 | NugetPackageDir : string 180 | GlobalPackagesDir : string 181 | 182 | // Test 183 | /// Defaults to "./test/" 184 | TestDir : string 185 | 186 | DisableNUnit : bool 187 | SetupNUnit : (NUnitParams -> NUnitParams) 188 | 189 | DisableNUnit3 : bool 190 | SetupNUnit3 : (NUnit3Params -> NUnit3Params) 191 | 192 | DisableMSTest : bool 193 | SetupMSTest : (MSTestParams -> MSTestParams) 194 | 195 | // Documentation generation 196 | /// Defaults to "./release/documentation/" 197 | OutDocDir : string 198 | /// Defaults to "./doc/templates/" 199 | DocTemplatesDir : string 200 | DocLogging : FSharpFormattingLogging 201 | LayoutRoots : string list 202 | /// Specify the list of references used for (razor) documentation generation. 203 | DocRazorReferences : string list option } 204 | static member Defaults = 205 | { ProjectName = "" 206 | ProjectSummary = "" 207 | Company = "" 208 | CopyrightNotice = "" 209 | ProjectDescription = "" 210 | UseNuget = false 211 | EnableGithub = true 212 | EnableDebugSymbolConversion = false 213 | RestrictReleaseToWindows = true 214 | ProjectAuthors = [] 215 | BuildTargets = [ BuildParams.Empty ] 216 | NugetUrl = "" 217 | NugetTags = "" 218 | PageAuthor = "" 219 | GithubUser = "" 220 | GithubProject = "" 221 | DocLogging = AllFSFLogging 222 | SetAssemblyFileVersions = (fun config -> 223 | let info = 224 | [ Attribute.Company config.Company 225 | Attribute.Product config.ProjectName 226 | Attribute.Copyright config.CopyrightNotice 227 | Attribute.Version config.Version 228 | Attribute.FileVersion config.Version 229 | Attribute.InformationalVersion config.Version ] 230 | CreateFSharpAssemblyInfo "./src/SharedAssemblyInfo.fs" info 231 | CreateCSharpAssemblyInfo "./src/SharedAssemblyInfo.cs" info) 232 | Version = "" 233 | IssuesUrl = "" 234 | FileNewIssueUrl = "" 235 | SourceReproUrl = "" 236 | NugetDir = "nuget" 237 | NugetVersionPackages = fun _ -> [] 238 | NugetPackages = [] 239 | DisableNUnit = false 240 | SetupNUnit = id 241 | DisableNUnit3 = false 242 | SetupNUnit3 = id 243 | DisableMSTest = isLinux 244 | SetupMSTest = id 245 | GeneratedFileList = [] 246 | BuildDir = "./build/" 247 | OutLibDir = "./release/lib/" 248 | OutDocDir = "./release/documentation/" 249 | OutNugetDir = "./release/nuget/" 250 | DocTemplatesDir = "./doc/templates/" 251 | LayoutRoots = [ ] 252 | TestDir = "./build/test/" 253 | GlobalPackagesDir = "./packages" 254 | NugetPackageDir = "./packages/.nuget" 255 | DocRazorReferences = 256 | if isMono then 257 | let loadedList = 258 | System.AppDomain.CurrentDomain.GetAssemblies() 259 | |> Seq.choose (fun a -> try Some (a.Location) with _ -> None) 260 | |> Seq.cache 261 | let getItem name = loadedList |> Seq.find (fun l -> l.Contains name) 262 | [ (getItem "FSharp.Core").Replace("4.3.0.0", "4.3.1.0") // (if isMono then "/usr/lib64/mono/gac/FSharp.Core/4.3.1.0__b03f5f7f11d50a3a/FSharp.Core.dll" else "FSharp.Core") 263 | Path.GetFullPath "./packages/FSharp.Compiler.Service/lib/net40/FSharp.Compiler.Service.dll" 264 | Path.GetFullPath "./packages/FSharp.Formatting/lib/net40/System.Web.Razor.dll" 265 | Path.GetFullPath "./packages/FSharp.Formatting/lib/net40/RazorEngine.dll" 266 | Path.GetFullPath "./packages/FSharp.Formatting/lib/net40/FSharp.Literate.dll" 267 | Path.GetFullPath "./packages/FSharp.Formatting/lib/net40/FSharp.CodeFormat.dll" 268 | Path.GetFullPath "./packages/FSharp.Formatting/lib/net40/FSharp.MetadataFormat.dll" ] 269 | |> Some 270 | else None} 271 | member x.GithubUrl = sprintf "https://github.com/%s/%s" x.GithubUser x.GithubProject 272 | member x.AllNugetPackages = 273 | let versionPackages = x.NugetVersionPackages x 274 | let otherPackages = x.NugetPackages |> List.map (fun (s, func) -> { NuGetPackage.Empty with FileName = s; ConfigFun = func x }) 275 | versionPackages @ otherPackages 276 | member x.GetPackageByName name = 277 | x.AllNugetPackages |> Seq.find (fun p -> p.Name = name) 278 | member x.SpecialVersionPackages = 279 | x.AllNugetPackages |> List.filter (fun p -> not (isNull p.Version)) 280 | member x.VersionInfoLine = 281 | let packages = x.SpecialVersionPackages 282 | if packages.Length = 0 then 283 | x.Version 284 | else 285 | sprintf "%s (%s)" x.Version (String.Join(", ", packages |> Seq.map (fun p -> p.VersionLine))) 286 | member x.CheckValid() = 287 | match x.AllNugetPackages |> Seq.tryFind (fun p -> isNull p.FileName) with 288 | | Some p -> 289 | failwithf "found a package with a FileName of null: %A" p 290 | | None -> () 291 | let packages = x.SpecialVersionPackages 292 | match packages |> Seq.tryFind (fun p -> isNull p.Name) with 293 | | Some p -> 294 | failwithf "package '%s' has a version '%s' but SimpleName and TagPrefix are both null!" p.FileName p.Version 295 | | None -> () 296 | match x.AllNugetPackages |> Seq.tryFind (fun p -> isNull p.Version && not (isNull p.TagPrefix)) with 297 | | Some p -> 298 | failwithf "package '%s' has a TagPrefix set but it's version is not set (eg it is null)" p.FileName 299 | | None -> () 300 | 301 | member x.FillDefaults () = 302 | let x = 303 | { x with 304 | Company = 305 | if String.IsNullOrEmpty x.Company then x.ProjectName else x.Company 306 | NugetUrl = 307 | if String.IsNullOrEmpty x.NugetUrl then sprintf "https://www.nuget.org/packages/%s/" x.ProjectName else x.NugetUrl 308 | GithubProject = if String.IsNullOrEmpty x.GithubProject then x.ProjectName else x.GithubProject 309 | GeneratedFileList = 310 | if x.GeneratedFileList |> List.isEmpty |> not then x.GeneratedFileList 311 | else [ x.ProjectName + ".dll"; x.ProjectName + ".xml" ] 312 | LayoutRoots = 313 | if not x.LayoutRoots.IsEmpty then x.LayoutRoots 314 | else [ x.DocTemplatesDir; x.DocTemplatesDir @@ "reference" ] } 315 | // GithubUrl is now available 316 | let final = 317 | { x with 318 | SourceReproUrl = 319 | if String.IsNullOrEmpty x.SourceReproUrl then x.GithubUrl + "/blob/master/" else x.SourceReproUrl 320 | IssuesUrl = if String.IsNullOrEmpty x.IssuesUrl then sprintf "%s/issues" x.GithubUrl else x.IssuesUrl 321 | FileNewIssueUrl = 322 | if String.IsNullOrEmpty x.FileNewIssueUrl then sprintf "%s/issues/new" x.GithubUrl else x.FileNewIssueUrl } 323 | final.CheckValid() 324 | final -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/buildInclude.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | 6 | (* 7 | This file handles the complete build process of RazorEngine 8 | 9 | The first step is handled in build.sh and build.cmd by bootstrapping a NuGet.exe and 10 | executing NuGet to resolve all build dependencies (dependencies required for the build to work, for example FAKE) 11 | 12 | The secound step is executing this file which resolves all dependencies, builds the solution and executes all unit tests 13 | *) 14 | 15 | #if FAKE 16 | #else 17 | // Support when file is opened in Visual Studio 18 | #load "buildConfigDef.fsx" 19 | #load "../../../buildConfig.fsx" 20 | #endif 21 | 22 | open BuildConfigDef 23 | let config = BuildConfig.buildConfig.FillDefaults () 24 | 25 | // NOTE: We want to add that to buildConfigDef.fsx sometimes in the future 26 | // #I @"../../FSharp.Compiler.Service/lib/net40/" // included in FAKE, but to be able to use the latest 27 | // Bundled 28 | //#I @"../../Yaaf.FSharp.Scripting/lib/net40/" 29 | #I "../tools/" 30 | #r "Yaaf.AdvancedBuilding.dll" 31 | 32 | 33 | open Yaaf.AdvancedBuilding 34 | open System.IO 35 | open System 36 | 37 | open Fake 38 | open Fake.Testing.NUnit3 39 | open Fake.Git 40 | open Fake.MSTest 41 | open Fake.FSharpFormatting 42 | open AssemblyInfoFile 43 | 44 | let readLine msg def = 45 | if isLocalBuild then 46 | printf "%s" msg 47 | System.Console.ReadLine() 48 | else 49 | printf "%s%s" msg def 50 | def 51 | 52 | if config.UseNuget then 53 | // Ensure the ./src/.nuget/NuGet.exe file exists (required by xbuild) 54 | let nuget = findToolInSubPath "NuGet.exe" (config.GlobalPackagesDir @@ "NuGet.CommandLine/tools/NuGet.exe") 55 | if Directory.Exists "./src/.nuget" then 56 | File.Copy(nuget, "./src/.nuget/NuGet.exe", true) 57 | else 58 | failwith "you set UseNuget to true but there is no \"./src/.nuget/NuGet.targets\" or \"./src/.nuget/NuGet.Config\"! Please copy them from ./packages/Yaaf.AdvancedBuilding/scaffold/nuget" 59 | 60 | let createMissingSymbolFiles assembly = 61 | try 62 | match File.Exists (Path.ChangeExtension(assembly, "pdb")), File.Exists (assembly + ".mdb") with 63 | | true, false when not isLinux -> 64 | // create mdb 65 | trace (sprintf "Creating mdb for %s" assembly) 66 | DebugSymbolHelper.writeMdbFromPdb assembly 67 | | true, false -> 68 | trace (sprintf "Cannot create mdb for %s because we are not on windows :(" assembly) 69 | | false, true when not isLinux -> 70 | // create pdb 71 | trace (sprintf "Creating pdb for %s" assembly) 72 | DebugSymbolHelper.writePdbFromMdb assembly 73 | | false, true -> 74 | trace (sprintf "Cannot create pdb for %s because we are not on windows :(" assembly) 75 | | _, _ -> 76 | // either no debug symbols available or already both. 77 | () 78 | with exn -> traceError (sprintf "Error creating symbols: %s" exn.Message) 79 | 80 | 81 | let buildWithFiles msg dir projectFileFinder (buildParams:BuildParams) = 82 | let files = projectFileFinder buildParams |> Seq.toList 83 | let buildDir = 84 | if not buildParams.UseProjectOutDir then 85 | let buildDir = dir @@ buildParams.SimpleBuildName 86 | CleanDirs [ buildDir ] 87 | buildDir 88 | else 89 | files 90 | |> MSBuild null "clean" 91 | [ "Configuration", buildParams.BuildMode 92 | "Platform", buildParams.PlatformName ] 93 | |> Log "Cleaning: " 94 | null 95 | // build app 96 | files 97 | |> MSBuild buildDir "Build" 98 | [ "Configuration", buildParams.BuildMode 99 | "Platform", buildParams.PlatformName ] 100 | |> Log msg 101 | 102 | let buildSolution = buildWithFiles "BuildSolution-Output: " config.BuildDir (fun buildParams -> buildParams.FindSolutionFiles buildParams) 103 | let buildApp = buildWithFiles "AppBuild-Output: " config.BuildDir (fun buildParams -> buildParams.FindProjectFiles buildParams) 104 | let buildTests = buildWithFiles "TestBuild-Output: " config.TestDir (fun buildParams -> buildParams.FindTestFiles buildParams) 105 | 106 | exception NUnitNotFoundException of string 107 | 108 | let runTests (buildParams:BuildParams) = 109 | let testDir = config.TestDir @@ buildParams.SimpleBuildName 110 | let logs = System.IO.Path.Combine(testDir, "logs") 111 | System.IO.Directory.CreateDirectory(logs) |> ignore 112 | let files = buildParams.FindUnitTestDlls (testDir, buildParams) |> Seq.cache 113 | if files |> Seq.isEmpty then 114 | traceError (sprintf "NO test found in %s" testDir) 115 | else 116 | let legacyNunitRun = 117 | if not config.DisableNUnit then 118 | try 119 | files 120 | |> NUnit (fun p -> 121 | let setupValue = 122 | {p with 123 | ProcessModel = 124 | // Because the default nunit-console.exe.config doesn't use .net 4... 125 | if isMono then NUnitProcessModel.SingleProcessModel else NUnitProcessModel.DefaultProcessModel 126 | WorkingDir = testDir 127 | StopOnError = true 128 | TimeOut = System.TimeSpan.FromMinutes 30.0 129 | Framework = "4.0" 130 | DisableShadowCopy = true 131 | OutputFile = "logs/TestResults.xml" } |> config.SetupNUnit 132 | let tool = setupValue.ToolPath @@ setupValue.ToolName 133 | if File.Exists tool |> not then 134 | raise <| NUnitNotFoundException (sprintf "The path to the nunit runner (%s) was not found!\nIt might be because you updated NUnit and they changed the path to the executable.\nEither downgrade NUnit again or use the new API (if already available)." tool) 135 | setupValue) 136 | true 137 | with 138 | | NUnitNotFoundException s -> 139 | traceEndTask "NUnit" (files |> separated ", ") // Workaround for https://github.com/fsharp/FAKE/issues/1079 140 | let msg = sprintf "NUNIT COULD NOT BE RUN, because it was not found. Please disable NUnit in your buildConfigDef.fsx with 'DisableNUnit = true'.\n\nDetails: %s" s 141 | if not config.DisableNUnit3 && File.Exists Fake.Testing.NUnit3.NUnit3Defaults.ToolPath then 142 | traceFAKE "%s\n\nThis is a warning only because we will be running NUnit3 as well" msg 143 | else failwith msg 144 | false 145 | else false 146 | if not legacyNunitRun && not config.DisableNUnit3 then 147 | files 148 | |> NUnit3 (fun p -> 149 | let setupValue = 150 | {p with 151 | ProcessModel = 152 | // Because the default nunit-console.exe.config doesn't use .net 4... 153 | if isMono then NUnit3ProcessModel.SingleProcessModel else NUnit3ProcessModel.DefaultProcessModel 154 | WorkingDir = testDir 155 | StopOnError = true 156 | TimeOut = System.TimeSpan.FromMinutes 30.0 157 | Framework = if isMono then NUnit3Runtime.Mono40 else NUnit3Runtime.Net45 158 | ShadowCopy = false 159 | OutputDir = "logs" } |> config.SetupNUnit3 160 | let tool = setupValue.ToolPath 161 | if File.Exists tool |> not then 162 | failwithf "The path to the nunit runner (%s) was not found!\nIt might be because you updated NUnit and they changed the path to the executable.\nEither downgrade NUnit again or use the new API (if already available)." tool 163 | setupValue) 164 | 165 | if not config.DisableMSTest then 166 | files 167 | |> MSTest (fun p -> 168 | {p with 169 | WorkingDir = testDir 170 | ResultsDir = "logs" } |> config.SetupMSTest) 171 | 172 | let buildAll (buildParams:BuildParams) = 173 | buildParams.BeforeBuild () 174 | buildSolution buildParams 175 | buildApp buildParams 176 | buildTests buildParams 177 | buildParams.AfterBuild () 178 | runTests buildParams 179 | buildParams.AfterTest () 180 | 181 | let fakePath = "packages" @@ "FAKE" @@ "tools" @@ "FAKE.exe" 182 | let fakeStartInfo script workingDirectory args environmentVars = 183 | (fun (info: System.Diagnostics.ProcessStartInfo) -> 184 | info.FileName <- fakePath 185 | info.Arguments <- sprintf "%s --fsiargs -d:FAKE \"%s\"" args script 186 | info.WorkingDirectory <- workingDirectory 187 | let setVar k v = 188 | info.EnvironmentVariables.[k] <- v 189 | for (k, v) in environmentVars do 190 | setVar k v 191 | setVar "MSBuild" msBuildExe 192 | setVar "GIT" Git.CommandHelper.gitPath 193 | setVar "FSI" fsiPath) 194 | 195 | 196 | /// Run the given startinfo by printing the output (live) 197 | let executeWithOutput configStartInfo = 198 | let exitCode = 199 | ExecProcessWithLambdas 200 | configStartInfo 201 | TimeSpan.MaxValue false ignore ignore 202 | System.Threading.Thread.Sleep 1000 203 | exitCode 204 | 205 | /// Run the given startinfo by redirecting the output (live) 206 | let executeWithRedirect errorF messageF configStartInfo = 207 | let exitCode = 208 | ExecProcessWithLambdas 209 | configStartInfo 210 | TimeSpan.MaxValue true errorF messageF 211 | System.Threading.Thread.Sleep 1000 212 | exitCode 213 | 214 | /// Helper to fail when the exitcode is <> 0 215 | let executeHelper executer traceMsg failMessage configStartInfo = 216 | trace traceMsg 217 | let exit = executer configStartInfo 218 | if exit <> 0 then 219 | failwith failMessage 220 | () 221 | 222 | let execute = executeHelper executeWithOutput 223 | 224 | /// Undocumentated way to disable cache (-nc) for documentation generation 225 | let mutable documentationFAKEArgs = "" 226 | 227 | // Documentation 228 | let buildDocumentationTarget target = 229 | let loggingValue = 230 | match config.DocLogging with 231 | | DisableFSFLogging -> "NONE" 232 | | AllFSFLogging -> "ALL" 233 | | FileOnlyFSFLogging -> "FILE_ONLY" 234 | | ConsoleOnlyFSFLogging -> "CONSOLE_ONLY" 235 | execute 236 | (sprintf "Building documentation (%s), this could take some time, please wait..." target) 237 | "generating reference documentation failed" 238 | (fakeStartInfo "generateDocs.fsx" "." documentationFAKEArgs ["target", target; "FSHARP_FORMATTING_LOG", loggingValue]) 239 | 240 | let tryDelete dir = 241 | try 242 | CleanDirs [ dir ] 243 | with 244 | | :? System.IO.IOException as e -> 245 | traceImportant (sprintf "Cannot access: %s\nTry closing Visual Studio!" e.Message) 246 | | :? System.UnauthorizedAccessException as e -> 247 | traceImportant (sprintf "Cannot access: %s\nTry closing Visual Studio!" e.Message) 248 | 249 | let MyTarget name body = 250 | Target name (fun _ -> body false) 251 | let single = (sprintf "%s_single" name) 252 | Target single (fun _ -> body true) 253 | 254 | // Targets 255 | MyTarget "Clean" (fun _ -> 256 | tryDelete config.BuildDir 257 | tryDelete config.TestDir 258 | 259 | CleanDirs [ config.BuildDir; config.TestDir; config.OutLibDir; config.OutDocDir; config.OutNugetDir ] 260 | ) 261 | 262 | MyTarget "CleanAll" (fun _ -> 263 | // Only done when we want to redownload all. 264 | Directory.EnumerateDirectories config.GlobalPackagesDir 265 | |> Seq.filter (fun buildDepDir -> 266 | let buildDepName = Path.GetFileName buildDepDir 267 | // We can't delete the FAKE directory (as it is used currently) 268 | buildDepName <> "FAKE") 269 | |> Seq.iter (fun dir -> 270 | try 271 | DeleteDir dir 272 | with exn -> 273 | traceError (sprintf "Unable to delete %s: %O" dir exn)) 274 | ) 275 | 276 | MyTarget "RestorePackages" (fun _ -> 277 | // will catch src/targetsDependencies 278 | !! "./src/**/packages.config" 279 | |> Seq.iter 280 | (RestorePackage (fun param -> 281 | { param with 282 | // ToolPath = "" 283 | OutputPath = config.NugetPackageDir })) 284 | ) 285 | 286 | MyTarget "CreateDebugFiles" (fun _ -> 287 | // creates .mdb from .pdb files and the other way around 288 | !! (config.GlobalPackagesDir + "/**/*.exe") 289 | ++ (config.GlobalPackagesDir + "/**/*.dll") 290 | |> Seq.iter createMissingSymbolFiles 291 | ) 292 | 293 | MyTarget "SetVersions" (fun _ -> 294 | config.SetAssemblyFileVersions config 295 | ) 296 | 297 | config.BuildTargets 298 | |> Seq.iter (fun buildParam -> 299 | MyTarget (sprintf "Build_%s" buildParam.SimpleBuildName) (fun _ -> buildAll buildParam)) 300 | 301 | MyTarget "CopyToRelease" (fun _ -> 302 | trace "Copying to release because test was OK." 303 | let outLibDir = config.OutLibDir 304 | CleanDirs [ outLibDir ] 305 | Directory.CreateDirectory(outLibDir) |> ignore 306 | 307 | // Copy files to release directory 308 | config.BuildTargets 309 | |> Seq.map (fun buildParam -> buildParam.SimpleBuildName) 310 | |> Seq.map (fun t -> config.BuildDir @@ t, t) 311 | |> Seq.filter (fun (p, _) -> Directory.Exists p) 312 | |> Seq.iter (fun (source, buildName) -> 313 | let outDir = outLibDir @@ buildName 314 | ensureDirectory outDir 315 | config.GeneratedFileList 316 | |> Seq.collect (fun file -> 317 | let extension = (Path.GetExtension file).TrimStart('.') 318 | match extension with 319 | | "dll" | "exe" -> 320 | [ file 321 | Path.ChangeExtension(file, "pdb") 322 | Path.ChangeExtension(file, extension + ".mdb" ) ] 323 | | _ -> [ file ] 324 | ) 325 | |> Seq.filter (fun (file) -> File.Exists (source @@ file)) 326 | |> Seq.iter (fun (file) -> 327 | let sourceFile = source @@ file 328 | let newfile = outDir @@ Path.GetFileName file 329 | trace (sprintf "Copying %s to %s" sourceFile newfile) 330 | File.Copy(sourceFile, newfile)) 331 | ) 332 | ) 333 | 334 | MyTarget "CreateReleaseSymbolFiles" (fun _ -> 335 | // creates .mdb from .pdb files and the other way around 336 | !! (config.OutLibDir + "/**/*.exe") 337 | ++ (config.OutLibDir + "/**/*.dll") 338 | |> Seq.iter createMissingSymbolFiles 339 | ) 340 | 341 | /// push package (and try again if something fails), FAKE Version doesn't work on mono 342 | /// From https://raw.githubusercontent.com/fsharp/FAKE/master/src/app/FakeLib/NuGet/NugetHelper.fs 343 | let rec private publish parameters = 344 | let replaceAccessKey key (text : string) = 345 | if isNullOrEmpty key then text 346 | else text.Replace(key, "PRIVATEKEY") 347 | let nuspec = sprintf "%s.%s.nupkg" parameters.Project parameters.Version 348 | traceStartTask "MyNuGetPublish" nuspec 349 | let tracing = enableProcessTracing 350 | enableProcessTracing <- false 351 | let source = 352 | let uri = if isNullOrEmpty parameters.PublishUrl then "https://www.nuget.org/api/v2/package" else parameters.PublishUrl 353 | sprintf "-s %s" uri 354 | 355 | let args = sprintf "push \"%s\" %s %s" (parameters.OutputPath @@ nuspec) parameters.AccessKey source 356 | tracefn "%s %s in WorkingDir: %s Trials left: %d" parameters.ToolPath (replaceAccessKey parameters.AccessKey args) 357 | (FullName parameters.WorkingDir) parameters.PublishTrials 358 | try 359 | try 360 | let result = 361 | ExecProcess (fun info -> 362 | info.FileName <- parameters.ToolPath 363 | info.WorkingDirectory <- FullName parameters.WorkingDir 364 | info.Arguments <- args) parameters.TimeOut 365 | enableProcessTracing <- tracing 366 | if result <> 0 then failwithf "Error during NuGet push. %s %s" parameters.ToolPath args 367 | true 368 | with exn -> 369 | let existsError = exn.Message.Contains("already exists and cannot be modified") 370 | if existsError then 371 | trace exn.Message 372 | false 373 | else 374 | if parameters.PublishTrials > 0 then publish { parameters with PublishTrials = parameters.PublishTrials - 1 } 375 | else 376 | (if not (isNull exn.InnerException) then exn.Message + "\r\n" + exn.InnerException.Message 377 | else exn.Message) 378 | |> replaceAccessKey parameters.AccessKey 379 | |> failwith 380 | finally 381 | traceEndTask "MyNuGetPublish" nuspec 382 | 383 | let packSetup version config p = 384 | { p with 385 | Authors = config.ProjectAuthors 386 | Project = config.ProjectName 387 | Summary = config.ProjectSummary 388 | Version = if isNull version then config.Version else version 389 | Description = config.ProjectDescription 390 | Tags = config.NugetTags 391 | WorkingDir = "." 392 | OutputPath = config.OutNugetDir 393 | AccessKey = getBuildParamOrDefault "nugetkey" "" 394 | Publish = false 395 | Dependencies = [ ] } 396 | 397 | MyTarget "NuGetPack" (fun _ -> 398 | ensureDirectory config.OutNugetDir 399 | for package in config.AllNugetPackages do 400 | let packSetup = packSetup package.Version config 401 | NuGet (fun p -> { (packSetup >> package.ConfigFun) p with Publish = false }) (Path.Combine(config.NugetDir, package.FileName)) 402 | ) 403 | 404 | MyTarget "NuGetPush" (fun _ -> 405 | let packagePushed = 406 | config.AllNugetPackages 407 | |> List.map (fun package -> 408 | try 409 | let packSetup = packSetup package.Version config 410 | let parameters = NuGetDefaults() |> (fun p -> { packSetup p with Publish = true }) |> package.ConfigFun 411 | // This allows us to specify packages which we do not want to push... 412 | if hasBuildParam "nugetkey" && parameters.Publish then publish parameters 413 | else true 414 | with e -> 415 | trace (sprintf "Could not push package '%s': %O" (if isNull package.Name then "{null}" else package.Name) e) 416 | false) 417 | |> List.exists id 418 | 419 | if not packagePushed then 420 | failwithf "No package could be pushed!" 421 | ) 422 | 423 | // Documentation 424 | MyTarget "GithubDoc" (fun _ -> buildDocumentationTarget "GithubDoc") 425 | 426 | MyTarget "LocalDoc" (fun _ -> buildDocumentationTarget "LocalDoc") 427 | 428 | MyTarget "WatchDocs" (fun _ -> buildDocumentationTarget "WatchDocs") 429 | 430 | // its just faster to generate all at the same time... 431 | MyTarget "AllDocs" (fun _ -> buildDocumentationTarget "AllDocs") 432 | 433 | MyTarget "ReleaseGithubDoc" (fun isSingle -> 434 | let repro = (sprintf "git@github.com:%s/%s.git" config.GithubUser config.GithubProject) 435 | let doAction = 436 | if isSingle then true 437 | else 438 | let msg = sprintf "update github docs to %s? (y,n): " repro 439 | let line = readLine msg "y" 440 | line = "y" 441 | if doAction then 442 | CleanDir "gh-pages" 443 | cloneSingleBranch "" repro "gh-pages" "gh-pages" 444 | fullclean "gh-pages" 445 | CopyRecursive ("release"@@"documentation"@@(sprintf "%s.github.io" config.GithubUser)@@"html") "gh-pages" true |> printfn "%A" 446 | StageAll "gh-pages" 447 | Commit "gh-pages" (sprintf "Update generated documentation %s" config.VersionInfoLine) 448 | let msg = sprintf "gh-pages branch updated in the gh-pages directory, push that branch to %s now? (y,n): " repro 449 | let line = readLine msg "y" 450 | if line = "y" then 451 | Branches.pushBranch "gh-pages" "origin" "gh-pages" 452 | ) 453 | 454 | Target "All" (fun _ -> 455 | trace "All finished!" 456 | ) 457 | 458 | Target "CheckWindows" (fun _ -> 459 | if isLinux then failwith "can only do releases on windows." 460 | ) 461 | 462 | MyTarget "VersionBump" (fun _ -> 463 | let repositoryHelperDir = "__repository" 464 | let workingDir = 465 | if not isLocalBuild && buildServer = BuildServer.TeamFoundation then 466 | let workingDir = repositoryHelperDir 467 | // We are not in a git repository, because the .git folder is missing. 468 | let repro = (sprintf "git@github.com:%s/%s.git" config.GithubUser config.GithubProject) 469 | CleanDir workingDir 470 | clone "" repro workingDir 471 | checkoutBranch workingDir (Information.getCurrentSHA1(".")) 472 | fullclean (workingDir @@ "src") 473 | CopyRecursive "src" (workingDir @@ "src") true |> printfn "%A" 474 | workingDir 475 | else "" 476 | 477 | let doBranchUpdates = not isLocalBuild && (getBuildParamOrDefault "yaaf_merge_master" "false") = "true" 478 | if doBranchUpdates then 479 | // Make sure we are on develop (commit will fail otherwise) 480 | Stash.push workingDir "" 481 | try Branches.deleteBranch workingDir true "develop" 482 | with e -> trace (sprintf "deletion of develop branch failed %O" e) 483 | Branches.checkout workingDir true "develop" 484 | try Stash.pop workingDir 485 | with e -> trace (sprintf "stash pop failed %O" e) 486 | 487 | // Commit updates the SharedAssemblyInfo.cs files. 488 | let changedFiles = Fake.Git.FileStatus.getChangedFilesInWorkingCopy workingDir "HEAD" |> Seq.toList 489 | if changedFiles |> Seq.isEmpty |> not then 490 | for (status, file) in changedFiles do 491 | printfn "File %s changed (%A)" file status 492 | 493 | let line = readLine "version bump commit? (y,n): " "y" 494 | if line = "y" then 495 | StageAll workingDir 496 | Commit workingDir (sprintf "Bump version to %s" config.VersionInfoLine) 497 | 498 | if doBranchUpdates then 499 | try Branches.deleteBranch workingDir true "master" 500 | with e -> trace (sprintf "deletion of master branch failed %O" e) 501 | Branches.checkout workingDir false "origin/master" 502 | Branches.checkout workingDir true "master" 503 | try Merge.merge workingDir NoFastForwardFlag "develop" 504 | with e -> 505 | trace (sprintf "merging of develop into master failed: %O" e) 506 | trace (sprintf "Try 'git checkout develop && git pull origin master && git checkout master && git pull origin master && git merge develop && git push origin master' locally and repeat the release process!") 507 | reraise() 508 | 509 | //try Branches.deleteTag "" config.Version 510 | //with e -> trace (sprintf "deletion of tag %s failed %O" config.Version e) 511 | 512 | let specialVersionedPackages = 513 | config.SpecialVersionPackages 514 | |> List.filter (fun p -> not (isNull p.TagPrefix)) 515 | let createdPackageTags = 516 | specialVersionedPackages 517 | |> List.map (fun p -> 518 | try Branches.tag workingDir p.TagName; true 519 | with e -> trace (sprintf "creation of tag '%s' failed: %O" p.TagName e); false) 520 | |> List.exists id 521 | 522 | try Branches.tag workingDir config.Version 523 | with e -> 524 | if createdPackageTags then 525 | trace (sprintf "creation of tag '%s' failed: %O" config.Version e) 526 | else 527 | raise <| new Exception("No tag was created for this release, please increase a (package) version!", e) 528 | 529 | try Branches.deleteBranch workingDir true "develop" 530 | with e -> trace (sprintf "deletion of develop branch failed %O" e) 531 | Branches.checkout workingDir false "origin/develop" 532 | Branches.checkout workingDir true "develop" 533 | try Merge.merge workingDir NoFastForwardFlag "master" 534 | with e -> 535 | trace (sprintf "merging of master into develop failed: %O" e) 536 | trace (sprintf "Try 'git checkout master && git pull origin master && git checkout develop && git pull origin master && git merge master && git push origin develop' locally and repeat the release process!") 537 | reraise() 538 | 539 | for p in specialVersionedPackages do 540 | Branches.pushTag workingDir "origin" p.TagName 541 | Branches.pushTag workingDir "origin" config.Version 542 | Branches.pushBranch workingDir "origin" "develop" 543 | Branches.pushBranch workingDir "origin" "master" 544 | CleanDir repositoryHelperDir 545 | DeleteDir repositoryHelperDir 546 | ) 547 | 548 | Target "Release" (fun _ -> 549 | trace "All released!" 550 | ) 551 | 552 | Target "ReadyForBuild" ignore 553 | Target "AfterBuild" ignore 554 | 555 | // Clean all 556 | "Clean" 557 | ==> "CleanAll" 558 | "Clean_single" 559 | ==> "CleanAll_single" 560 | 561 | "Clean" 562 | =?> ("RestorePackages", config.UseNuget) 563 | =?> ("CreateDebugFiles", config.EnableDebugSymbolConversion) 564 | ==> "SetVersions" 565 | ==> "ReadyForBuild" 566 | 567 | config.BuildTargets 568 | |> Seq.iter (fun buildParam -> 569 | let buildName = sprintf "Build_%s" buildParam.SimpleBuildName 570 | "ReadyForBuild" 571 | ==> buildName 572 | |> ignore 573 | buildName 574 | ==> "AfterBuild" 575 | |> ignore 576 | ) 577 | 578 | // Dependencies 579 | "AfterBuild" 580 | ==> "CopyToRelease" 581 | =?> ("CreateReleaseSymbolFiles", config.EnableDebugSymbolConversion) 582 | ==> "NuGetPack" 583 | ==> "AllDocs" 584 | ==> "All" 585 | 586 | "All" 587 | =?> ("CheckWindows", config.RestrictReleaseToWindows) 588 | ==> "VersionBump" 589 | =?> ("ReleaseGithubDoc", config.EnableGithub) 590 | ==> "NuGetPush" 591 | ==> "Release" 592 | 593 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/downloadNugetInclude.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | // Get any working NuGet.exe 6 | // It's sad that this does'nt work on mono as they don't have a working "System.IO.Compression.FileSystem.dll" 7 | 8 | open System.Net 9 | open System.IO 10 | 11 | //let nugetCommandLinePackage = "https://www.nuget.org/api/v2/package/NuGet.Commandline" 12 | //let nugetPkg = "lib/NuGet.CommandLine/NuGet.CommandLine.nupkg" 13 | let nugetLink = "https://www.nuget.org/nuget.exe" 14 | let nugetExe = "packages/NuGet.CommandLine/tools/NuGet.exe" 15 | 16 | let nugetToolsPath = Path.GetDirectoryName(nugetExe) 17 | //let nugetPath = Path.GetDirectoryName(nugetToolsPath) 18 | 19 | let downloadFile (link:string) (filePath:string) = 20 | let wc = new WebClient() 21 | wc.DownloadFile(link, filePath) 22 | 23 | Directory.CreateDirectory(nugetToolsPath) |> ignore 24 | 25 | downloadFile nugetLink nugetExe 26 | //ZipFile.ExtractToDirectory(nugetPkg, nugetPath) 27 | -------------------------------------------------------------------------------- /packages/Yaaf.AdvancedBuilding/content/generateDocsInclude.fsx: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // This file is subject to the terms and conditions defined in 3 | // file 'LICENSE.txt', which is part of this source code package. 4 | // ---------------------------------------------------------------------------- 5 | 6 | (* 7 | This file handles the generation of the docs (it is called by the build automatically). 8 | *) 9 | #if FAKE 10 | #else 11 | // Support when file is opened in Visual Studio 12 | #load "buildConfigDef.fsx" 13 | #load "../../../buildConfig.fsx" 14 | #endif 15 | 16 | open BuildConfigDef 17 | let config = BuildConfig.buildConfig.FillDefaults() 18 | 19 | #load @"../../FSharp.Formatting/FSharp.Formatting.fsx" 20 | #r "System.Web" 21 | 22 | open System.Collections.Generic 23 | open System.IO 24 | open System.Web 25 | 26 | open Fake 27 | open Fake.Git 28 | open Fake.FSharpFormatting 29 | open AssemblyInfoFile 30 | 31 | open FSharp.Markdown 32 | open FSharp.Literate 33 | open FSharp.MetadataFormat 34 | 35 | open RazorEngine.Compilation 36 | 37 | let commitHash = lazy Information.getCurrentSHA1(".") 38 | 39 | // Documentation 40 | 41 | /// Processes an entire directory containing multiple script files 42 | /// (*.fsx) and Markdown documents (*.md) and it specifies additional 43 | /// replacements for the template file 44 | 45 | //let website_root = "file://" + Path.GetFullPath (config.OutDocDir @@ "html") 46 | 47 | let formattingContext templateFile format generateAnchors replacements layoutRoots = 48 | { TemplateFile = templateFile 49 | Replacements = defaultArg replacements [] 50 | GenerateLineNumbers = true 51 | IncludeSource = false 52 | Prefix = "fs" 53 | OutputKind = defaultArg format OutputKind.Html 54 | GenerateHeaderAnchors = defaultArg generateAnchors false 55 | LayoutRoots = defaultArg layoutRoots [] } 56 | 57 | let rec replaceCodeBlocks ctx = function 58 | | Matching.LiterateParagraph(special) -> 59 | match special with 60 | | LanguageTaggedCode(lang, code) -> 61 | let inlined = 62 | match ctx.OutputKind with 63 | | OutputKind.Html -> 64 | let code = HttpUtility.HtmlEncode code 65 | let codeHtmlKey = sprintf "language-%s" lang 66 | sprintf "
%s
" codeHtmlKey codeHtmlKey code 67 | | OutputKind.Latex -> 68 | sprintf "\\begin{lstlisting}\n%s\n\\end{lstlisting}" code 69 | Some(InlineBlock(inlined)) 70 | | _ -> Some (EmbedParagraphs special) 71 | | Matching.ParagraphNested(pn, nested) -> 72 | let nested = List.map (List.choose (replaceCodeBlocks ctx)) nested 73 | Some(Matching.ParagraphNested(pn, nested)) 74 | | par -> Some par 75 | 76 | let editLiterateDocument ctx (doc:LiterateDocument) = 77 | doc.With(paragraphs = List.choose (replaceCodeBlocks ctx) doc.Paragraphs) 78 | 79 | let printAssemblies msg = 80 | printfn "%s. Loaded Assemblies:" msg 81 | System.AppDomain.CurrentDomain.GetAssemblies() 82 | |> Seq.choose (fun a -> try Some (a.GetName().FullName, a.Location) with _ -> None) 83 | //|> Seq.filter (fun l -> l.Contains ("Razor")) 84 | |> Seq.iter (fun (n, l) -> printfn "\t- %s: %s" n l) 85 | 86 | // ITS VERY IMPORTANT TO CREATE THE EVALUATOR LAZY (see https://github.com/matthid/Yaaf.AdvancedBuilding/issues/5) 87 | let evalutator = lazy (Some <| (FsiEvaluator() :> IFsiEvaluator)) 88 | //let evalutator = lazy None 89 | 90 | let buildAllDocumentation outDocDir website_root = 91 | let references = config.DocRazorReferences 92 | 93 | let projInfo = 94 | [ "root", website_root 95 | "page-description", config.ProjectDescription 96 | "page-author", config.PageAuthor 97 | "github-link", config.GithubUrl 98 | "project-name", config.ProjectName 99 | "project-summary", config.ProjectSummary 100 | "project-commit", commitHash.Value 101 | "project-author", config.ProjectAuthors |> Seq.head 102 | "project-github", config.GithubUrl 103 | "project-issues", config.IssuesUrl 104 | "project-new-issue", config.FileNewIssueUrl 105 | "project-nuget", config.NugetUrl] 106 | 107 | 108 | // Copy static files and CSS + JS from F# Formatting 109 | let copyDocContentFiles () = 110 | ensureDirectory (outDocDir @@ "html" @@ "content") 111 | CopyRecursive "./doc/content" (outDocDir @@ "html" @@ "content") true |> Log "Copying file: " 112 | //CopyRecursive (formatting @@ "styles") (output @@ "content") true 113 | // |> Log "Copying styles and scripts: " 114 | 115 | 116 | 117 | let processDocumentationFiles(outputKind) = 118 | let indexTemplate, template, outDirName, indexName, extension = 119 | match outputKind with 120 | | OutputKind.Html -> "docpage-index.cshtml", "docpage.cshtml", "html", "index.html", ".html" 121 | | OutputKind.Latex -> 122 | config.DocTemplatesDir @@ "template-color.tex", config.DocTemplatesDir @@ "template-color.tex", 123 | "latex", "Readme.tex", ".tex" 124 | let outDir = outDocDir @@ outDirName 125 | let handleDoc template (doc:LiterateDocument) outfile = 126 | // prismjs support 127 | let ctx = formattingContext (Some template) (Some outputKind) (Some true) (Some projInfo) (Some config.LayoutRoots) 128 | Templating.processFile references (editLiterateDocument ctx doc) outfile ctx 129 | 130 | let processMarkdown template infile outfile = 131 | let doc = Literate.ParseMarkdownFile( infile, ?fsiEvaluator = evalutator.Value ) 132 | handleDoc template doc outfile 133 | let processScriptFile template infile outfile = 134 | let doc = Literate.ParseScriptFile( infile, ?fsiEvaluator = evalutator.Value ) 135 | handleDoc template doc outfile 136 | 137 | let rec processDirectory template indir outdir = 138 | Literate.ProcessDirectory( 139 | indir, template, outdir, outputKind, generateAnchors = true, replacements = projInfo, 140 | layoutRoots = config.LayoutRoots, customizeDocument = editLiterateDocument, 141 | processRecursive = true, includeSource = true, ?fsiEvaluator = evalutator.Value, 142 | ?assemblyReferences = references) 143 | 144 | processDirectory template (Path.GetFullPath "./doc") outDir 145 | let processFile template inFile outFile = 146 | if File.Exists inFile then 147 | processMarkdown template inFile outFile 148 | else 149 | trace (sprintf "File %s was not found so %s was not created!" inFile outFile) 150 | 151 | // Handle some special files. 152 | processFile indexTemplate "./README.md" (outDir @@ indexName) 153 | processFile template "./CONTRIBUTING.md" (outDir @@ "Contributing" + extension) 154 | processFile template "./LICENSE.md" (outDir @@ "License" + extension) 155 | 156 | // Build API reference from XML comments 157 | let referenceBinaries = 158 | let xmlFiles = config.GeneratedFileList |> List.filter (fun f -> f.EndsWith(".xml")) 159 | config.GeneratedFileList 160 | |> List.filter (fun f -> f.EndsWith(".dll") || f.EndsWith(".exe")) 161 | |> List.filter (fun f -> 162 | let exists = 163 | xmlFiles |> List.exists (fun xml -> 164 | Path.GetFileNameWithoutExtension xml = Path.GetFileNameWithoutExtension f) 165 | if not exists then 166 | trace (sprintf "No .xml file is given in GeneratedFileList for %s" f) 167 | exists) 168 | 169 | let buildReference () = 170 | let referenceDir = outDocDir @@ "html" 171 | let outDir = referenceDir @@ "references" 172 | ensureDirectory referenceDir 173 | ensureDirectory outDir 174 | let libDir = config.BuildDir @@ (config.BuildTargets |> Seq.last).SimpleBuildName 175 | let binaries = 176 | referenceBinaries 177 | |> List.map (fun lib -> libDir @@ lib) 178 | 179 | MetadataFormat.Generate 180 | (binaries, Path.GetFullPath outDir, config.LayoutRoots, 181 | parameters = projInfo, 182 | libDirs = [ libDir ], 183 | otherFlags = [], 184 | sourceRepo = config.SourceReproUrl, 185 | sourceFolder = "./", 186 | publicOnly = true, 187 | markDownComments = false, // support 188 | ?assemblyReferences = references ) 189 | 190 | CleanDirs [ outDocDir ] 191 | copyDocContentFiles() 192 | 193 | try 194 | // FIRST build the reference documentation, see https://github.com/matthid/Yaaf.AdvancedBuilding/issues/5 195 | buildReference() 196 | processDocumentationFiles OutputKind.Html 197 | processDocumentationFiles OutputKind.Latex 198 | with e -> 199 | printAssemblies "(DIAGNOSTICS) Documentation failed" 200 | reraise() 201 | 202 | let MyTarget name body = 203 | Target name (fun _ -> body false) 204 | let single = (sprintf "%s_single" name) 205 | Target single (fun _ -> body true) 206 | 207 | let doGithub () = 208 | buildAllDocumentation (config.OutDocDir @@ sprintf "%s.github.io" config.GithubUser) (sprintf "https://%s.github.io/%s" config.GithubUser config.GithubProject) 209 | 210 | let doLocal () = 211 | buildAllDocumentation (config.OutDocDir @@ "local") ("file://" + Path.GetFullPath (config.OutDocDir @@ "local" @@ "html")) 212 | trace (sprintf "Local documentation has been finished, you can view it by opening %s in your browser!" (Path.GetFullPath (config.OutDocDir @@ "local" @@ "html" @@ "index.html"))) 213 | 214 | let watch () = 215 | printfn "Starting watching by initial building..." 216 | let rebuildDocs () = 217 | CleanDir (config.OutDocDir @@ "local") // Just in case the template changed (buildDocumentation is caching internally, maybe we should remove that) 218 | doLocal() 219 | rebuildDocs() 220 | printfn "Watching for changes..." 221 | 222 | let full s = Path.GetFullPath s 223 | let queue = new System.Collections.Concurrent.ConcurrentQueue<_>() 224 | let processTask () = 225 | async { 226 | let! tok = Async.CancellationToken 227 | while not tok.IsCancellationRequested do 228 | try 229 | if queue.IsEmpty then 230 | do! Async.Sleep 1000 231 | else 232 | let data = ref [] 233 | let hasData = ref true 234 | while !hasData do 235 | match queue.TryDequeue() with 236 | | true, d -> 237 | data := d :: !data 238 | | _ -> 239 | hasData := false 240 | 241 | printfn "Detected changes (%A). Invalidate cache and rebuild." !data 242 | //global.FSharp.MetadataFormat.RazorEngineCache.InvalidateCache (!data |> Seq.map (fun change -> change.FullPath)) 243 | //global.FSharp.Literate.RazorEngineCache.InvalidateCache (!data |> Seq.map (fun change -> change.FullPath)) 244 | rebuildDocs() 245 | printfn "Documentation generation finished." 246 | with e -> 247 | printfn "Documentation generation failed: %O" e 248 | } 249 | use watcher = 250 | !! (full "." + "/**/*.*") 251 | |> WatchChanges (fun changes -> 252 | changes 253 | |> Seq.filter (fun change -> 254 | change.Name.StartsWith("doc" @@ "") || 255 | change.Name = "README.md" || 256 | change.Name = "CONTRIBUTING.md" || 257 | change.Name = "LICENSE.md") 258 | |> Seq.iter queue.Enqueue 259 | ) 260 | use source = new System.Threading.CancellationTokenSource() 261 | Async.Start(processTask (), source.Token) 262 | printfn "Press enter to exit watching..." 263 | System.Console.ReadLine() |> ignore 264 | watcher.Dispose() 265 | source.Cancel() 266 | 267 | MyTarget "GithubDoc" (fun _ -> doGithub()) 268 | 269 | MyTarget "LocalDoc" (fun _ -> doLocal()) 270 | 271 | MyTarget "WatchDocs" (fun _ -> watch()) 272 | 273 | MyTarget "AllDocs" (fun _ -> 274 | if config.EnableGithub then doGithub() 275 | doLocal() 276 | ) 277 | -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | redirects on 2 | source https://nuget.org/api/v2 3 | 4 | nuget FSharp.Compiler.Service 5 | nuget NUnit 6 | nuget NUnit.Runners 7 | nuget NuGet.CommandLine 8 | nuget Unquote 9 | nuget FSharp.Core 10 | nuget Yaaf.AdvancedBuilding == 0.14.1 11 | -------------------------------------------------------------------------------- /paket.lock: -------------------------------------------------------------------------------- 1 | REDIRECTS: ON 2 | NUGET 3 | remote: https://www.nuget.org/api/v2 4 | FAKE (4.29) 5 | FSharp.Compiler.Service (2.0.0.6) 6 | FSharp.Core (4.0.0.1) 7 | FSharp.Formatting (2.14.4) 8 | FSharp.Compiler.Service (2.0.0.6) 9 | FSharpVSPowerTools.Core (>= 2.3 < 2.4) 10 | FSharpVSPowerTools.Core (2.3) 11 | FSharp.Compiler.Service (>= 2.0.0.3) 12 | NuGet.CommandLine (3.4.3) 13 | NUnit (3.4) 14 | NUnit.ConsoleRunner (3.4) 15 | NUnit.Extension.NUnitProjectLoader (3.4) 16 | NUnit.Extension.NUnitV2Driver (3.4) 17 | NUnit.Extension.NUnitV2ResultWriter (3.4) 18 | NUnit.Extension.TeamCityEventListener (1.0) 19 | NUnit.Extension.VSProjectLoader (3.4) 20 | NUnit.Runners (3.4) 21 | NUnit.ConsoleRunner (3.4) 22 | NUnit.Extension.NUnitProjectLoader (3.4) 23 | NUnit.Extension.NUnitV2Driver (3.4) 24 | NUnit.Extension.NUnitV2ResultWriter (3.4) 25 | NUnit.Extension.TeamCityEventListener (1.0) 26 | NUnit.Extension.VSProjectLoader (3.4) 27 | Unquote (3.1.1) 28 | Yaaf.AdvancedBuilding (0.14.1) 29 | FAKE (4.29) 30 | FSharp.Formatting (2.14.4) 31 | FSharpVSPowerTools.Core (2.3) 32 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | *.obj 3 | *.exe 4 | *.pdb 5 | *.user 6 | *.aps 7 | *.pch 8 | *.vspscc 9 | *_i.c 10 | *_p.c 11 | *.ncb 12 | *.suo 13 | *.sln.docstates 14 | *.tlb 15 | *.tlh 16 | *.bak 17 | *.cache 18 | *.ilk 19 | *.log 20 | [Bb]in/ 21 | [Dd]ebug*/ 22 | *.lib 23 | *.sbr 24 | obj/ 25 | [Rr]elease*/ 26 | _ReSharper*/ 27 | [Tt]est[Rr]esult* 28 | 29 | # Monodevelop 30 | test-results/ 31 | *.userprefs -------------------------------------------------------------------------------- /src/SharedAssemblyInfo.fs: -------------------------------------------------------------------------------- 1 | namespace System 2 | open System.Reflection 3 | 4 | [] 5 | [] 6 | [] 7 | [] 8 | [] 9 | [] 10 | do () 11 | 12 | module internal AssemblyVersionInformation = 13 | let [] Version = "1.7.1" 14 | let [] InformationalVersion = "1.7.1" 15 | -------------------------------------------------------------------------------- /src/Yaaf.FSharp.Scripting.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.25123.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}" 6 | ProjectSection(SolutionItems) = preProject 7 | ..\paket.dependencies = ..\paket.dependencies 8 | ..\paket.lock = ..\paket.lock 9 | EndProjectSection 10 | EndProject 11 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "doc", "doc", "{A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1}" 12 | ProjectSection(SolutionItems) = preProject 13 | ..\doc\Caching.fsx = ..\doc\Caching.fsx 14 | ..\CONTRIBUTING.md = ..\CONTRIBUTING.md 15 | ..\doc\DevelopReadme.md = ..\doc\DevelopReadme.md 16 | ..\doc\IntroExamples.fsx = ..\doc\IntroExamples.fsx 17 | ..\README.md = ..\README.md 18 | ..\doc\ReleaseNotes.md = ..\doc\ReleaseNotes.md 19 | EndProjectSection 20 | EndProject 21 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "project", "project", "{BF60BC93-E09B-4E5F-9D85-95A519479D54}" 22 | ProjectSection(SolutionItems) = preProject 23 | ..\buildConfig.fsx = ..\buildConfig.fsx 24 | ..\paket.dependencies = ..\paket.dependencies 25 | ..\nuget\Yaaf.FSharp.Scripting.nuspec = ..\nuget\Yaaf.FSharp.Scripting.nuspec 26 | EndProjectSection 27 | EndProject 28 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Yaaf.FSharp.Scripting", "source\Yaaf.FSharp.Scripting\Yaaf.FSharp.Scripting.fsproj", "{2D4E0476-7D33-449B-B895-FF1CAF9DD712}" 29 | EndProject 30 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Test.Yaaf.FSharp.Scripting", "test\Test.Yaaf.FSharp.Scripting\Test.Yaaf.FSharp.Scripting.fsproj", "{ED6905ED-539D-43FA-A48D-15BF4D6A1F80}" 31 | EndProject 32 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "templates", "templates", "{1532E90C-4D3F-4AB2-9636-22726F68F4E8}" 33 | ProjectSection(SolutionItems) = preProject 34 | ..\doc\templates\docpage-index.cshtml = ..\doc\templates\docpage-index.cshtml 35 | ..\doc\templates\docpage.cshtml = ..\doc\templates\docpage.cshtml 36 | ..\doc\templates\template-color.tex = ..\doc\templates\template-color.tex 37 | ..\doc\templates\template-math.tex = ..\doc\templates\template-math.tex 38 | ..\doc\templates\template.cshtml = ..\doc\templates\template.cshtml 39 | EndProjectSection 40 | EndProject 41 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "reference", "reference", "{65D8785D-F9BA-4E17-9667-99ADBEAA411C}" 42 | ProjectSection(SolutionItems) = preProject 43 | ..\doc\templates\reference\module.cshtml = ..\doc\templates\reference\module.cshtml 44 | ..\doc\templates\reference\namespaces.cshtml = ..\doc\templates\reference\namespaces.cshtml 45 | ..\doc\templates\reference\part-members.cshtml = ..\doc\templates\reference\part-members.cshtml 46 | ..\doc\templates\reference\part-nested.cshtml = ..\doc\templates\reference\part-nested.cshtml 47 | ..\doc\templates\reference\type.cshtml = ..\doc\templates\reference\type.cshtml 48 | EndProjectSection 49 | EndProject 50 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{B925F738-D2CD-469E-A596-CBE4BFD67C72}" 51 | ProjectSection(SolutionItems) = preProject 52 | ..\doc\content\prism.css = ..\doc\content\prism.css 53 | ..\doc\content\prism.js = ..\doc\content\prism.js 54 | ..\doc\content\style.css = ..\doc\content\style.css 55 | ..\doc\content\tips.js = ..\doc\content\tips.js 56 | EndProjectSection 57 | EndProject 58 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "img", "img", "{0248EE74-229A-485A-8886-CC83C099FA76}" 59 | ProjectSection(SolutionItems) = preProject 60 | ..\doc\content\img\back_to_top.png = ..\doc\content\img\back_to_top.png 61 | ..\doc\content\img\github-blue.png = ..\doc\content\img\github-blue.png 62 | ..\doc\content\img\github.png = ..\doc\content\img\github.png 63 | ..\doc\content\img\logo-template.pdn = ..\doc\content\img\logo-template.pdn 64 | ..\doc\content\img\logo.png = ..\doc\content\img\logo.png 65 | EndProjectSection 66 | EndProject 67 | Global 68 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 69 | Debug|IncludeTest = Debug|IncludeTest 70 | Debug|Net40 = Debug|Net40 71 | Debug|Net45 = Debug|Net45 72 | Release|IncludeTest = Release|IncludeTest 73 | Release|Net40 = Release|Net40 74 | Release|Net45 = Release|Net45 75 | EndGlobalSection 76 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 77 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|IncludeTest.ActiveCfg = Debug|IncludeTest 78 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|IncludeTest.Build.0 = Debug|IncludeTest 79 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|Net40.ActiveCfg = Debug|Net40 80 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|Net40.Build.0 = Debug|Net40 81 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|Net45.ActiveCfg = Debug|Net45 82 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Debug|Net45.Build.0 = Debug|Net45 83 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|IncludeTest.ActiveCfg = Release|IncludeTest 84 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|IncludeTest.Build.0 = Release|IncludeTest 85 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|Net40.ActiveCfg = Release|Net40 86 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|Net40.Build.0 = Release|Net40 87 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|Net45.ActiveCfg = Release|Net45 88 | {2D4E0476-7D33-449B-B895-FF1CAF9DD712}.Release|Net45.Build.0 = Release|Net45 89 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Debug|IncludeTest.ActiveCfg = Debug|Net45 90 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Debug|Net40.ActiveCfg = Debug|Net40 91 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Debug|Net40.Build.0 = Debug|Net40 92 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Debug|Net45.ActiveCfg = Debug|Net45 93 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Debug|Net45.Build.0 = Debug|Net45 94 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Release|IncludeTest.ActiveCfg = Release|Net45 95 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Release|Net40.ActiveCfg = Release|Net40 96 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Release|Net40.Build.0 = Release|Net40 97 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Release|Net45.ActiveCfg = Release|Net45 98 | {ED6905ED-539D-43FA-A48D-15BF4D6A1F80}.Release|Net45.Build.0 = Release|Net45 99 | EndGlobalSection 100 | GlobalSection(SolutionProperties) = preSolution 101 | HideSolutionNode = FALSE 102 | EndGlobalSection 103 | GlobalSection(NestedProjects) = preSolution 104 | {1532E90C-4D3F-4AB2-9636-22726F68F4E8} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} 105 | {65D8785D-F9BA-4E17-9667-99ADBEAA411C} = {1532E90C-4D3F-4AB2-9636-22726F68F4E8} 106 | {B925F738-D2CD-469E-A596-CBE4BFD67C72} = {A6A6AF7D-D6E3-442D-9B1E-58CC91879BE1} 107 | {0248EE74-229A-485A-8886-CC83C099FA76} = {B925F738-D2CD-469E-A596-CBE4BFD67C72} 108 | EndGlobalSection 109 | EndGlobal 110 | -------------------------------------------------------------------------------- /src/nuget.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/source/Yaaf.FSharp.Scripting/AssemblyInfo.fs: -------------------------------------------------------------------------------- 1 | namespace System 2 | open System.Runtime.CompilerServices 3 | 4 | [] 5 | do () -------------------------------------------------------------------------------- /src/source/Yaaf.FSharp.Scripting/Script.fsx: -------------------------------------------------------------------------------- 1 | // Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project 2 | // for more guidance on F# programming. 3 | 4 | #load "Library.fs" 5 | open Yaaf.FSharp.Scripting 6 | 7 | let num = Library.hello 42 8 | printfn "%i" num 9 | -------------------------------------------------------------------------------- /src/source/Yaaf.FSharp.Scripting/Yaaf.FSharp.Scripting.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Net40 7 | 2.0 8 | 2d4e0476-7d33-449b-b895-ff1caf9dd712 9 | Library 10 | Yaaf.FSharp.Scripting 11 | Yaaf.FSharp.Scripting 12 | v4.0 13 | 4.3.0.0 14 | Yaaf.FSharp.Scripting 15 | 16 | ..\..\ 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | bin 24 | DEBUG;TRACE;NET40;YAAF_FSHARP_SCRIPTING_PUBLIC 25 | 3 26 | 27 | 28 | pdbonly 29 | true 30 | true 31 | $(SolutionDir)/../build/net40 32 | TRACE;NET40;YAAF_FSHARP_SCRIPTING_PUBLIC 33 | 3 34 | 35 | 36 | true 37 | full 38 | false 39 | false 40 | v4.5 41 | bin 42 | DEBUG;TRACE;YAAF_FSHARP_SCRIPTING_PUBLIC 43 | 3 44 | 45 | 46 | pdbonly 47 | true 48 | true 49 | v4.5 50 | $(SolutionDir)/../build/net45 51 | TRACE;YAAF_FSHARP_SCRIPTING_PUBLIC 52 | 3 53 | 54 | 55 | true 56 | full 57 | false 58 | false 59 | v4.5 60 | bin 61 | DEBUG;TRACE 62 | 3 63 | 64 | 65 | pdbonly 66 | true 67 | true 68 | v4.5 69 | $(SolutionDir)/../build/include_test 70 | TRACE 71 | 3 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | SharedAssemblyInfo.fs 84 | 85 | 86 | 87 | 88 | 89 | 90 | 11 91 | 92 | 93 | 100 | 101 | 102 | 103 | 104 | ..\..\..\packages\FSharp.Compiler.Service\lib\net40\FSharp.Compiler.Service.dll 105 | True 106 | True 107 | 108 | 109 | 110 | 111 | 112 | 113 | ..\..\..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.dll 114 | True 115 | True 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | ..\..\..\packages\FSharp.Core\lib\net20\FSharp.Core.dll 125 | True 126 | True 127 | 128 | 129 | 130 | 131 | 132 | 133 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll 134 | True 135 | True 136 | 137 | 138 | 139 | 140 | 141 | 142 | ..\..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll 143 | True 144 | True 145 | 146 | 147 | 148 | 149 | 150 | 151 | ..\..\..\packages\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll 152 | True 153 | True 154 | 155 | 156 | 157 | 158 | 159 | 160 | ..\..\..\packages\FSharp.Core\lib\portable-net45+sl5+netcore45\FSharp.Core.dll 161 | True 162 | True 163 | 164 | 165 | 166 | 167 | 168 | 169 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wp8\FSharp.Core.dll 170 | True 171 | True 172 | 173 | 174 | 175 | 176 | 177 | 178 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll 179 | True 180 | True 181 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /src/source/Yaaf.FSharp.Scripting/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | True 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/source/Yaaf.FSharp.Scripting/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Compiler.Service 2 | FSharp.Core -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | True 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/ExtensionMethodTests.fs: -------------------------------------------------------------------------------- 1 | module Test.Yaaf.FSharp.Scripting.ExtensionMethodTests 2 | type T () = 3 | let _ = () 4 | type TGen<'a> () = 5 | let _ = () 6 | open System.IO 7 | open NUnit.Framework 8 | open Test.Yaaf.FSharp.Scripting.FsiUnquote 9 | open Yaaf.FSharp.Scripting 10 | open FSharp.Compiler.SourceCodeServices 11 | 12 | let withNoWarnings f = 13 | let builder = new System.Text.StringBuilder() 14 | use writer = new StringWriter(builder) 15 | Log.source.Switch.Level <- System.Diagnostics.SourceLevels.Warning 16 | use listener = 17 | new System.Diagnostics.TextWriterTraceListener( 18 | writer, 19 | Filter = new System.Diagnostics.EventTypeFilter(System.Diagnostics.SourceLevels.Warning)) 20 | let listenerIndex = Log.source.Listeners.Add(listener) 21 | f () 22 | Log.source.Listeners.RemoveAt(listenerIndex) 23 | writer.Flush() 24 | let logText = builder.ToString() 25 | test <@ System.String.IsNullOrWhiteSpace logText @> 26 | 27 | let testType<'a> () = 28 | withNoWarnings (fun () -> 29 | // A Assembly -> FSharpEntity mapping (extension) function 30 | let fsAssembly = FSharpAssembly.FromAssembly typeof<'a>.Assembly 31 | test <@ fsAssembly.IsSome @> 32 | test <@ fsAssembly.Value.FileName.IsSome @> 33 | // we don't require the exact same path (could be loaded from somewhere else) 34 | test <@ Path.GetFileName fsAssembly.Value.FileName.Value = Path.GetFileName typeof<'a>.Assembly.Location @> 35 | test <@ fsAssembly.Value.SimpleName = typeof<'a>.Assembly.GetName().Name @> 36 | // A extension method to find the type 37 | let fsType = fsAssembly.Value.FindType typeof<'a> 38 | test <@ fsType.IsSome @> 39 | test <@ fsType.Value.FullName = typeof<'a>.NamespaceName.Replace("+", ".") @> 40 | ()) 41 | 42 | [] 43 | let ``check that default assemblies generate no warnings`` () = 44 | let frameworkVersion = FSharpAssemblyHelper.defaultFrameworkVersion 45 | let sysLibs = FSharpAssemblyHelper.getDefaultSystemReferences frameworkVersion 46 | let fsCore = FSharpAssemblyHelper.findFSCore [] [] 47 | //for sysLib in sysLibs do 48 | let projFileName, args = FSharpAssemblyHelper.getCheckerArguments frameworkVersion sysLibs (Some fsCore) [] [] [] 49 | let options = FSharpAssemblyHelper.checker.GetProjectOptionsFromCommandLineArgs(projFileName, args) 50 | let results = FSharpAssemblyHelper.checker.ParseAndCheckProject(options) |> Async.RunSynchronously 51 | test <@ results.Errors.Length = 0 @> 52 | 53 | [] 54 | let ``check that we can get the fsassembly and fstype of a custom nested type`` () = 55 | testType() 56 | 57 | [] 58 | let ``check that we can get the fsassembly and fstype of a custom generic type`` () = 59 | testType() 60 | 61 | [] 62 | let ``check that we can get the fsassembly and fstype of a interface type`` () = 63 | testType() 64 | 65 | 66 | [] 67 | let ``check that we can get the fsassembly and fstype of int`` () = 68 | testType () 69 | 70 | [] 71 | let ``check that we can get the fsassembly and fstype of option`` () = 72 | testType> () 73 | 74 | [] 75 | let ``check that the type extensions works for typedefof`` () = 76 | 77 | let def = typedefof> 78 | test <@ def.Name = "FSharpOption`1" @> 79 | test <@ def.FullName = "Microsoft.FSharp.Core.FSharpOption`1" @> 80 | 81 | test <@ def.FSharpParamList = "<_>" @> 82 | test <@ def.FSharpFullName = "Microsoft.FSharp.Core.Option" @> 83 | test <@ def.FSharpFullNameWithTypeArgs = "Microsoft.FSharp.Core.Option<_>" @> 84 | test <@ def.FSharpName = "Option" @> 85 | 86 | [] 87 | let ``check that the type extensions works for typeof`` () = 88 | 89 | let def = typeof> 90 | test <@ def.Name = "FSharpOption`1" @> 91 | test <@ def.Namespace = "Microsoft.FSharp.Core" @> 92 | 93 | test <@ def.FSharpParamList = "" @> 94 | test <@ def.FSharpFullName = "Microsoft.FSharp.Core.Option" @> 95 | test <@ def.FSharpFullNameWithTypeArgs = "Microsoft.FSharp.Core.Option" @> 96 | test <@ def.FSharpName = "Option" @> -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/FsiArgsTest.fs: -------------------------------------------------------------------------------- 1 | module Test.Yaaf.FSharp.Scripting.FsiArgsTest 2 | 3 | open System.IO 4 | open NUnit.Framework 5 | open Test.Yaaf.FSharp.Scripting.FsiUnquote 6 | open Yaaf.FSharp.Scripting 7 | 8 | let argTest args = 9 | let parsed = FsiOptions.ofArgs args 10 | let toArgs = parsed.AsArgs 11 | let parsed2 = FsiOptions.ofArgs toArgs 12 | test <@ parsed = parsed2 @> 13 | parsed 14 | 15 | [] 16 | let ``Check that fsi arg-parser works`` () = 17 | argTest [| "--noninteractive"; "-g+"; "--warnaserror+:34,42" ; "--"; "test" ; "more" |] |> ignore 18 | 19 | argTest [| "-I:first"; "-I:second" |]|> ignore 20 | argTest [| "-r:first"; "-r:second" |]|> ignore 21 | argTest [| "--load:first"; "--load:second" |]|> ignore 22 | argTest [| "--use:first"; "--use:second" |]|> ignore 23 | -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/FsiSessionTests.fs: -------------------------------------------------------------------------------- 1 | module Test.Yaaf.FSharp.Scripting.FsiSessionTests 2 | 3 | open NUnit.Framework 4 | open Test.Yaaf.FSharp.Scripting.FsiUnquote 5 | open Yaaf.FSharp.Scripting 6 | open System.Text 7 | open System.IO 8 | let fsiSession = ScriptHost.CreateNew(["MYDEFINE"]) 9 | let liveOut = new StringBuilder() 10 | let liveErr = new StringBuilder() 11 | let liveOutStream = new StringWriter(liveOut) 12 | let liveErrStream = new StringWriter(liveErr) 13 | let fixNewLines (l:string) = l.Replace("\r\n", "\n") 14 | 15 | [] 16 | let ``Check if we don't call the forwarder`` () = 17 | let called = ref false 18 | ( use __ = ScriptHost.CreateForwardWriter ((fun _ -> called := true), removeNewLines = true) 19 | ()) 20 | test <@ (not !called) @> 21 | 22 | [] 23 | let ``Check if we can detect a newline charater at the end with removeNewLines`` () = 24 | let called = ref 0 25 | ( use forwarder = ScriptHost.CreateForwardWriter ((fun _ -> called := !called + 1), removeNewLines = true) 26 | forwarder.WriteLine "test") 27 | test <@ !called = 2 @> 28 | 29 | called := 0 30 | ( use forwarder = ScriptHost.CreateForwardWriter ((fun _ -> called := !called + 1), removeNewLines = true) 31 | forwarder.Write "test") 32 | test <@ !called = 1 @> 33 | 34 | [] 35 | let ``Check if get the last input`` () = 36 | let sb = new StringBuilder() 37 | ( use forwarder = ScriptHost.CreateForwardWriter (sb.AppendLine >> ignore, removeNewLines = true) 38 | forwarder.Write "test" 39 | ()) 40 | test <@ fixNewLines (sb.ToString()) = "test\n" @> 41 | 42 | [] 43 | let ``Check if get the multiple inputs`` () = 44 | let sb = new StringBuilder() 45 | ( use forwarder = ScriptHost.CreateForwardWriter (sb.AppendLine >> ignore, removeNewLines = true) 46 | forwarder.Write "test" 47 | forwarder.Write "test1" 48 | forwarder.WriteLine () 49 | forwarder.Write "test2" 50 | ()) 51 | test <@ fixNewLines (sb.ToString()) = "testtest1\ntest2\n" @> 52 | 53 | let preventFsiSession = 54 | ScriptHost.CreateNew( 55 | ["MYDEFINE"], 56 | preventStdOut = true, 57 | outWriter = liveOutStream, 58 | errWriter = liveErrStream) 59 | let forwardFsiSession = 60 | ScriptHost.CreateNew( 61 | ["MYDEFINE"], 62 | preventStdOut = true, 63 | outWriter = ScriptHost.CreateForwardWriter (liveOut.Append >> ignore), 64 | errWriter = ScriptHost.CreateForwardWriter (liveErr.Append >> ignore)) 65 | let withOutput f = 66 | liveOut.Clear() |> ignore 67 | liveErr.Clear() |> ignore 68 | f (), 69 | liveOut.ToString(), liveErr.ToString() 70 | [] 71 | let ``let with a given integer type works`` () = 72 | fsiSession.Let "test" 25 73 | test <@ fsiSession.EvalExpression "test" = 25 @> 74 | 75 | [] 76 | let ``test that we get the correct output`` () = 77 | let inter = fsiSession.EvalInteractionWithOutput "3 + 4" 78 | test <@ fixNewLines inter.Output.FsiOutput = "val it : int = 7\n" @> 79 | 80 | [] 81 | let ``let with a given integer option type works`` () = 82 | fsiSession.Let "test" (Some 25) 83 | test <@ fsiSession.EvalExpression "test" = Some 25 @> 84 | 85 | [] 86 | let ``check that default config produces no error output`` () = 87 | let _, _, err = 88 | withOutput (fun () -> 89 | ScriptHost.CreateNew( 90 | ["MYDEFINE"], 91 | preventStdOut = true, 92 | outWriter = ScriptHost.CreateForwardWriter (liveOut.Append >> ignore), 93 | errWriter = ScriptHost.CreateForwardWriter (liveErr.Append >> ignore))) 94 | test <@ System.String.IsNullOrWhiteSpace(err) @> 95 | 96 | [] 97 | let ``check that defines work works`` () = 98 | fsiSession.EvalInteraction(""" 99 | #if MYDEFINE 100 | let test = 125 101 | #else 102 | let test = 0 103 | #endif""") 104 | test <@ fsiSession.EvalExpression "test" = 125 @> 105 | 106 | [] 107 | let ``check that fsi object works`` () = 108 | fsiSession.EvalInteraction (""" 109 | fsi.AddPrinter(fun (n:int) -> n.ToString()) 110 | printfn "%d" 4 111 | """) 112 | 113 | [] 114 | let ``check that compile time exceptions are wrapped`` () = 115 | Assert.Throws(fun () -> 116 | fsiSession.EvalInteraction (""" 117 | asdfasd 118 | """)) 119 | |> ignore 120 | 121 | [] 122 | let ``check that runtime exceptions are wrapped`` () = 123 | Assert.Throws(fun () -> 124 | fsiSession.EvalInteraction (""" 125 | ((failwith "game over") : unit) 126 | """)) 127 | |> ignore 128 | 129 | [] 130 | let ``check that we get print output`` () = 131 | let res = fsiSession.EvalInteractionWithOutput (""" 132 | printf "%s" "test" """) 133 | test <@ res.Output.ScriptOutput = "test" @> 134 | 135 | [] 136 | let ``check that we can work with live output`` () = 137 | let _, out, err = withOutput (fun () -> 138 | let res = preventFsiSession.EvalInteractionWithOutput (""" 139 | printfn "%s" "test" 140 | eprintfn "%s" "test" """) 141 | test <@ fixNewLines res.Error.ScriptOutput = "test\n" @>) 142 | test <@ fixNewLines out = "test\n" @> 143 | test <@ fixNewLines err = "test\n" @> 144 | 145 | [] 146 | let ``check that we can work with a forwarder`` () = 147 | let _, out, err = withOutput (fun () -> 148 | let res = forwardFsiSession.EvalInteractionWithOutput (""" 149 | printfn "%s" "test" 150 | eprintfn "%s" "test" """) 151 | test <@ fixNewLines res.Error.ScriptOutput = "test\n" @>) 152 | test <@ fixNewLines out = "test\n" @> 153 | test <@ fixNewLines err = "test\n" @> 154 | 155 | [] 156 | let ``test Handle method`` () = 157 | match fsiSession.Handle fsiSession.EvalExpression "5 + 4" with 158 | | InvalidExpressionType _ 159 | | InvalidCode _ -> Assert.Fail "expected 9" 160 | | Result r -> test <@ r = 9 @> 161 | 162 | match fsiSession.Handle fsiSession.EvalExpression "5 + 4" with 163 | | InvalidExpressionType e -> test <@ e.Value.IsSome @> 164 | | InvalidCode _ 165 | | Result _ -> Assert.Fail "expected InvalidExpressionType failure" 166 | 167 | match fsiSession.Handle fsiSession.EvalExpression """failwith "test" : int """ with 168 | | InvalidCode _ -> () 169 | | InvalidExpressionType _ 170 | | Result _ -> Assert.Fail "expected InvalidCode failure" 171 | 172 | [] 173 | let ``check that we can access System.IO`` () = 174 | File.WriteAllText("Test.txt", "content") 175 | try 176 | let res = fsiSession.EvalInteractionWithOutput (""" 177 | printf "%s" <| System.IO.File.ReadAllText("Test.txt") """) 178 | test <@ res.Output.ScriptOutput = "content" @> 179 | finally 180 | File.Delete("Test.txt") 181 | 182 | [] 183 | let ``check that we can access System.Linq`` () = 184 | let res = fsiSession.EvalInteractionWithOutput (""" 185 | System.Linq.Enumerable.Average([1; 3]) |> int |> printf "%d" """) 186 | test <@ res.Output.ScriptOutput = "2" @> 187 | 188 | [] 189 | let ``check that we can access System.Numerics`` () = 190 | let res = fsiSession.EvalInteractionWithOutput (""" 191 | typeof.Name |> printf "%s" """) 192 | test <@ res.Output.ScriptOutput = "BigInteger" @> 193 | 194 | [] 195 | let ``Test that we can use objects after dispose`` () = 196 | let incFunc, getFunc = 197 | ( use fsiSession = ScriptHost.CreateNew(["MYDEFINE"]) 198 | fsiSession.EvalInteraction("""let mutable t = 0""") 199 | fsiSession.EvalExpression unit>("fun () -> t <- t + 1"), 200 | fsiSession.EvalExpression int>("fun () -> t")) 201 | 202 | test <@ getFunc() = 0 @> 203 | test <@ getFunc() = 0 @> 204 | incFunc() 205 | test <@ getFunc() = 1 @> 206 | incFunc() 207 | incFunc() 208 | test <@ getFunc() = 3 @> 209 | test <@ getFunc() = 3 @> 210 | 211 | [] 212 | let ``Test that we can call with full debug`` () = 213 | ( use fsiSession = ScriptHost.Create({ FsiOptions.Default with Debug = Some DebugMode.Full }) 214 | let res = fsiSession.EvalInteractionWithOutput (""" 215 | System.Linq.Enumerable.Average([1; 3]) |> int |> printf "%d" """) 216 | test <@ res.Output.ScriptOutput = "2" @>) 217 | 218 | [] 219 | let ``Test that we can call with no debug`` () = 220 | ( use fsiSession = ScriptHost.Create({ FsiOptions.Default with Debug = Some DebugMode.NoDebug }) 221 | let res = fsiSession.EvalInteractionWithOutput (""" 222 | System.Linq.Enumerable.Average([1; 3]) |> int |> printf "%d" """) 223 | test <@ res.Output.ScriptOutput = "2" @>) 224 | 225 | [] 226 | let ``Test that we can call with pdbonly debug`` () = 227 | ( use fsiSession = ScriptHost.Create({ FsiOptions.Default with Debug = Some DebugMode.PdbOnly }) 228 | let res = fsiSession.EvalInteractionWithOutput (""" 229 | System.Linq.Enumerable.Average([1; 3]) |> int |> printf "%d" """) 230 | test <@ res.Output.ScriptOutput = "2" @>) 231 | 232 | 233 | [] 234 | let ``Test that report local works`` () = 235 | ( use fsiSession = ScriptHost.CreateNew() 236 | match fsiSession.Handle fsiSession.EvalExpression "asdasdfasdffas" with 237 | | InvalidCode e -> test <@ e.Result.Error.FsiOutput.Contains "asdasdfasdffas" @> 238 | | InvalidExpressionType _ 239 | | Result _ -> Assert.Fail "expected InvalidCode failure") 240 | 241 | [] 242 | let ``Test that report global works`` () = 243 | ( use fsiSession = ScriptHost.CreateNew(reportGlobal = true) 244 | match fsiSession.Handle fsiSession.EvalExpression "asdasdfasdffas" with 245 | | InvalidCode e -> test <@ e.Result.Error.FsiOutput.Contains "asdasdfasdffas" @> 246 | | InvalidExpressionType _ 247 | | Result _ -> Assert.Fail "expected InvalidCode failure") -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/Test.Yaaf.FSharp.Scripting.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Net40 7 | 2.0 8 | ed6905ed-539d-43fa-a48d-15bf4d6a1f80 9 | Library 10 | Test.Yaaf.FSharp.Scripting 11 | Test.Yaaf.FSharp.Scripting 12 | v4.0 13 | 4.3.1.0 14 | Yaaf.FSharp.Scripting.Tests 15 | 16 | ..\..\ 17 | 18 | 19 | true 20 | full 21 | false 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | 3 26 | Project 27 | 28 | 29 | 30 | 31 | 32 | 33 | pdbonly 34 | true 35 | true 36 | $(SolutionDir)/../build/test/net40 37 | TRACE 38 | 3 39 | 40 | 41 | true 42 | full 43 | false 44 | false 45 | v4.5 46 | bin\Debug\ 47 | DEBUG;TRACE 48 | 3 49 | Project 50 | 51 | 52 | 53 | 54 | 55 | 56 | pdbonly 57 | true 58 | true 59 | v4.5 60 | $(SolutionDir)/../build/test/net45 61 | TRACE 62 | 3 63 | 64 | 65 | 66 | 11 67 | 68 | 69 | 70 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Yaaf.FSharp.Scripting 92 | {2d4e0476-7d33-449b-b895-ff1caf9dd712} 93 | True 94 | 95 | 96 | 97 | 98 | 99 | 100 | ..\..\..\packages\FSharp.Compiler.Service\lib\net40\FSharp.Compiler.Service.dll 101 | True 102 | True 103 | 104 | 105 | 106 | 107 | 108 | 109 | ..\..\..\packages\FSharp.Compiler.Service\lib\net45\FSharp.Compiler.Service.dll 110 | True 111 | True 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | ..\..\..\packages\FSharp.Core\lib\net20\FSharp.Core.dll 121 | True 122 | True 123 | 124 | 125 | 126 | 127 | 128 | 129 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45\FSharp.Core.dll 130 | True 131 | True 132 | 133 | 134 | 135 | 136 | 137 | 138 | ..\..\..\packages\FSharp.Core\lib\net40\FSharp.Core.dll 139 | True 140 | True 141 | 142 | 143 | 144 | 145 | 146 | 147 | ..\..\..\packages\FSharp.Core\lib\portable-net45+monoandroid10+monotouch10+xamarinios10\FSharp.Core.dll 148 | True 149 | True 150 | 151 | 152 | 153 | 154 | 155 | 156 | ..\..\..\packages\FSharp.Core\lib\portable-net45+sl5+netcore45\FSharp.Core.dll 157 | True 158 | True 159 | 160 | 161 | 162 | 163 | 164 | 165 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wp8\FSharp.Core.dll 166 | True 167 | True 168 | 169 | 170 | 171 | 172 | 173 | 174 | ..\..\..\packages\FSharp.Core\lib\portable-net45+netcore45+wpa81+wp8\FSharp.Core.dll 175 | True 176 | True 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | ..\..\..\packages\NUnit\lib\net35\nunit.framework.dll 186 | True 187 | True 188 | 189 | 190 | 191 | 192 | 193 | 194 | ..\..\..\packages\NUnit\lib\net20\NUnit.System.Linq.dll 195 | True 196 | True 197 | 198 | 199 | ..\..\..\packages\NUnit\lib\net20\nunit.framework.dll 200 | True 201 | True 202 | 203 | 204 | 205 | 206 | 207 | 208 | ..\..\..\packages\NUnit\lib\net40\nunit.framework.dll 209 | True 210 | True 211 | 212 | 213 | 214 | 215 | 216 | 217 | ..\..\..\packages\NUnit\lib\net45\nunit.framework.dll 218 | True 219 | True 220 | 221 | 222 | 223 | 224 | 225 | 226 | ..\..\..\packages\NUnit\lib\portable-net45+win8+wp8+wpa81+Xamarin.Mac+MonoAndroid10+MonoTouch10+Xamarin.iOS10\nunit.framework.dll 227 | True 228 | True 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | ..\..\..\packages\Unquote\lib\net40\Unquote.dll 238 | True 239 | True 240 | 241 | 242 | 243 | 244 | 245 | 246 | ..\..\..\packages\Unquote\lib\net45\Unquote.dll 247 | True 248 | True 249 | 250 | 251 | 252 | 253 | 254 | 255 | ..\..\..\packages\Unquote\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\Unquote.dll 256 | True 257 | True 258 | 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/UnquoteFix.fs: -------------------------------------------------------------------------------- 1 | /// We have the FSI-ASSEMBLY loaded, thats why we need to ensure that our Unquote 'test' method throws properly! 2 | [] 3 | module Test.Yaaf.FSharp.Scripting.FsiUnquote 4 | 5 | open Swensen.Unquote 6 | 7 | open System 8 | open Microsoft.FSharp.Quotations 9 | 10 | let testFailed = 11 | let outputReducedExprsMsg = 12 | fun outputTestFailedMsg (reducedExprs:Expr list) additionalInfo -> 13 | let msg = 14 | sprintf "\n%s\n%s\n" 15 | (if additionalInfo |> String.IsNullOrWhiteSpace then "" else sprintf "\n%s\n" additionalInfo) 16 | (reducedExprs |> List.map decompile |> String.concat "\n") 17 | outputTestFailedMsg msg 18 | let outputNonFsiTestFailedMsg = (fun msg -> 19 | printfn "%s" msg 20 | NUnit.Framework.Assert.Fail(msg)) 21 | outputReducedExprsMsg outputNonFsiTestFailedMsg 22 | 23 | let reduceFullyAndGetLast expr = 24 | let reducedExprs = expr |> reduceFully 25 | let lastExpr = reducedExprs |> List.rev |> List.head 26 | reducedExprs, lastExpr 27 | 28 | let inline test (expr:Expr) = 29 | let reducedExprs, lastExpr = reduceFullyAndGetLast expr 30 | match lastExpr with 31 | | DerivedPatterns.Bool(true) -> () 32 | | _ -> 33 | //try 34 | testFailed reducedExprs "" 35 | //with 36 | //| e -> raise e //we catch and raise e here to hide stack traces for clean test framework output 37 | 38 | let inline expectedExnButWrongExnRaisedMsg ty1 ty2 = sprintf "Expected exception of type '%s', but '%s' was raised instead" ty1 ty2 39 | let inline expectedExnButNoExnRaisedMsg ty1 = sprintf "Expected exception of type '%s', but no exception was raised" ty1 40 | ///Test wether the given expr fails with the given expected exception (or a subclass thereof). 41 | let inline raises<'a when 'a :> exn> (expr:Expr) = 42 | let reducedExprs, lastExpr = reduceFullyAndGetLast expr 43 | match lastExpr with 44 | | Patterns.Value(lastValue,lastValueTy) when isNull lastValue |> not && typeof.IsAssignableFrom(lastValueTy) -> //it's an exception 45 | if typeof<'a>.IsAssignableFrom(lastValueTy) then () //it's the correct exception 46 | else //it's not the correct exception 47 | //try 48 | testFailed reducedExprs (expectedExnButWrongExnRaisedMsg typeof<'a>.Name (lastValueTy.Name)) 49 | //with 50 | //| e -> raise e 51 | | _ -> //it's not an exception 52 | //try 53 | testFailed reducedExprs (expectedExnButNoExnRaisedMsg typeof<'a>.Name) 54 | //with 55 | //| e -> raise e 56 | 57 | ///Test wether the given expr fails with the given expected exception (or a subclass thereof) when the additional assertion on the exception object holds. 58 | let inline raisesWith<'a when 'a :> exn> (expr:Expr) (exnWhen: 'a -> Expr) = 59 | let reducedExprs, lastExpr = reduceFullyAndGetLast expr 60 | match lastExpr with 61 | | Patterns.Value(lastValue,lastValueTy) when isNull lastValue |> not && typeof.IsAssignableFrom(lastValueTy) -> //it's an exception 62 | if typeof<'a>.IsAssignableFrom(lastValueTy) then //it's the correct exception 63 | //but we also need to check the exnWhen condition is true 64 | let lastValue = lastValue :?> 'a 65 | let exnWhenExpr = exnWhen lastValue 66 | let exnWhenReducedExprs, exnWhenLastExpr = reduceFullyAndGetLast exnWhenExpr 67 | match exnWhenLastExpr with 68 | | DerivedPatterns.Bool(true) -> () //the exnWhen condition is true 69 | | _ -> 70 | //try 71 | testFailed reducedExprs (sprintf "The expected exception was raised, but the exception assertion failed:\n\nException Assertion:\n\n%s\n\nTest Expression:" (exnWhenReducedExprs |> List.map decompile |> String.concat "\n")) 72 | //with 73 | //| e -> raise e //we catch and raise e here to hide stack traces for clean test framework output 74 | 75 | else //it's not the correct exception 76 | //try 77 | testFailed reducedExprs (expectedExnButWrongExnRaisedMsg typeof<'a>.Name (lastValueTy.Name)) 78 | //with 79 | //| e -> raise e 80 | | _ -> //it's not an exception 81 | //try 82 | testFailed reducedExprs (expectedExnButNoExnRaisedMsg typeof<'a>.Name) 83 | //with 84 | //| e -> raise e 85 | 86 | let inline (=?) x y = test <@ x = y @> 87 | let inline ( 88 | let inline (>?) x y = test <@ x > y @> 89 | let inline (<=?) x y = test <@ x <= y @> 90 | let inline (>=?) x y = test <@ x >= y @> 91 | let inline (<>?) x y = test <@ x <> y @> -------------------------------------------------------------------------------- /src/test/Test.Yaaf.FSharp.Scripting/paket.references: -------------------------------------------------------------------------------- 1 | NUnit 2 | NUnit.Runners 3 | Unquote 4 | FSharp.Compiler.Service 5 | FSharp.Core --------------------------------------------------------------------------------