├── .dockerignore ├── .gitignore ├── .paket ├── Paket.Restore.targets ├── paket.bootstrapper.exe.config ├── paket.bootstrapper.proj └── paket.bootstrapper.props ├── Dockerfile ├── README.md ├── global.json ├── paket.dependencies ├── paket.lock └── src ├── c1 ├── Program.fs ├── c1.fsproj └── paket.references └── l1 ├── Library.fs ├── l1.fsproj └── paket.references /.dockerignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | out/ 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /packages/ 2 | /paket-files/ 3 | /.paket/* 4 | !/.paket/*.proj 5 | !/.paket/*.exe.config 6 | !/.paket/*.props 7 | !/.paket/*.targets 8 | !/.paket/Paket.Restore.targets 9 | bin 10 | obj 11 | -------------------------------------------------------------------------------- /.paket/Paket.Restore.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 8 | 9 | true 10 | $(MSBuildThisFileDirectory) 11 | $(MSBuildThisFileDirectory)..\ 12 | $(PaketRootPath)paket-files\paket.restore.cached 13 | $(PaketRootPath)paket.lock 14 | classic 15 | proj 16 | assembly 17 | native 18 | /Library/Frameworks/Mono.framework/Commands/mono 19 | mono 20 | 21 | $(PaketToolsPath)paket 22 | $(PaketRootPath)paket.exe 23 | 24 | $(PaketToolsPath)paket.exe 25 | $(PaketToolsPath)paket.exe 26 | $(PaketToolsPath)paket 27 | 28 | 29 | <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) 30 | dotnet "$(PaketExePath)" 31 | "$(PaketExePath)" 32 | $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" 33 | "$(PaketExePath)" 34 | 35 | $(PaketRootPath)paket.bootstrapper.exe 36 | $(PaketToolsPath)paket.bootstrapper.exe 37 | "$(PaketBootStrapperExePath)" 38 | $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" 39 | 40 | 41 | 42 | 43 | true 44 | true 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | true 56 | $(NoWarn);NU1603;NU1604;NU1605;NU1608 57 | 58 | 59 | 60 | 61 | /usr/bin/shasum "$(PaketRestoreCacheFile)" | /usr/bin/awk '{ print $1 }' 62 | /usr/bin/shasum "$(PaketLockFilePath)" | /usr/bin/awk '{ print $1 }' 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) 79 | $([System.IO.File]::ReadAllText('$(PaketLockFilePath)')) 80 | true 81 | false 82 | true 83 | 84 | 85 | 86 | true 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).paket.references.cached 103 | 104 | $(MSBuildProjectFullPath).paket.references 105 | 106 | $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references 107 | 108 | $(MSBuildProjectDirectory)\paket.references 109 | 110 | false 111 | true 112 | true 113 | references-file-or-cache-not-found 114 | 115 | 116 | 117 | 118 | $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) 119 | $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) 120 | references-file 121 | false 122 | 123 | 124 | 125 | 126 | false 127 | 128 | 129 | 130 | 131 | true 132 | target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | false 143 | true 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) 155 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) 156 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) 157 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) 158 | 159 | 160 | %(PaketReferencesFileLinesInfo.PackageVersion) 161 | All 162 | runtime 163 | true 164 | 165 | 166 | 167 | 168 | $(MSBuildProjectDirectory)/obj/$(MSBuildProjectFile).paket.clitools 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) 178 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) 179 | 180 | 181 | %(PaketCliToolFileLinesInfo.PackageVersion) 182 | 183 | 184 | 185 | 189 | 190 | 191 | 192 | 193 | 194 | false 195 | 196 | 197 | 198 | 199 | 200 | <_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/> 201 | 202 | 203 | 204 | $(MSBuildProjectDirectory)/$(MSBuildProjectFile) 205 | true 206 | false 207 | true 208 | $(BaseIntermediateOutputPath)$(Configuration) 209 | $(BaseIntermediateOutputPath) 210 | 211 | 212 | 213 | <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.nuspec"/> 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 266 | 267 | 308 | 309 | 310 | 311 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.proj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(MSBuildThisFileDirectory.TrimEnd('\\').TrimEnd('/')) 7 | 8 | $(RepoRoot)\paket.bootstrapper.exe 9 | $(RepoRoot)/paket.bootstrapper 10 | $(RepoRoot)\paket.exe 11 | $(RepoRoot)/paket 12 | 13 | 14 | 15 | 16 | 17 | dotnet tool install paket.bootstrapper --tool-path "$(RepoRoot)" 18 | $(InstallBootstrapperCommand) --version "[$(PaketBootstrapperVersion)]" 19 | $(InstallBootstrapperCommand) --add-source "$(PaketBootstrapperFeed)" 20 | $(InstallBootstrapperCommand) $(InstallBootstrapperOtherArgs)" 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | $(PaketBootstrapperExe) --as-tool --output-dir=$(RepoRoot) 29 | $(RunBootstrapperCommand) --config-file=$(RepoRoot)/paket.bootstrapper.exe.config 30 | $(RunBootstrapperCommand) $(RunBootstrapperOtherArgs) 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5.180.414 5 | https://www.myget.org/F/paket-netcore-as-tool/api/v2 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.1.402-sdk AS build-env 2 | WORKDIR /app 3 | 4 | # bootstrap as separate layer 5 | COPY .paket/paket.bootstrapper.proj .paket/ 6 | COPY .paket/paket.bootstrapper.props .paket/ 7 | COPY .paket/paket.bootstrapper.exe.config .paket/ 8 | RUN dotnet restore .paket 9 | 10 | # paket restore as separate layer 11 | COPY paket.dependencies . 12 | COPY paket.lock . 13 | 14 | RUN .paket/paket restore 15 | 16 | # now copy everything and build 17 | COPY src src/ 18 | RUN dotnet publish src/c1 -c Release -o /app/out 19 | 20 | # build runtime image 21 | FROM microsoft/dotnet:2.1.4-runtime-alpine 22 | WORKDIR /app 23 | COPY --from=build-env /app/out ./ 24 | ENTRYPOINT ["dotnet", "c1.dll"] 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Paket .NET Core 2 | 3 | Both `paket` and `paket.bootstrapper` as .NET tool, trying to maintain a dev flow similar to current paket v5 (and hopefully minimal maintenance) 4 | 5 | # Requirements 6 | 7 | - [.NET Core Sdk 2.1.402] 8 | 9 | `NOTE` install from zip/binaries (safe way), but you need to set `DOTNET_ROOT` env var to the dir of unzipped sdk (bug in `dotnet/cli` for preview https://github.com/dotnet/cli/issues/9114 ) 10 | 11 | # Try it 12 | 13 | See the scenarios below. 14 | 15 | The scenario 1 (`dotnet restore .paket`) maintain current flow with `paket.bootstrapper` 16 | 17 | As .net tools so each one can be installed separately to specific dir, so can be run as normal native binaries. as 18 | 19 | - `dotnet tool install paket.bootstrapper --version "[5.179.403]" --tool-path "mydir" --add-source https://www.myget.org/F/paket-netcore-as-tool/api/v3/index.json` 20 | - `dotnet tool install paket --version "[5.179.403]" --tool-path "mydir2" --add-source https://www.myget.org/F/paket-netcore-as-tool/api/v3/index.json` 21 | 22 | `NOTE` to both command you need to add the `--add-source` because is in myget: 23 | 24 | PRO: 25 | 26 | - maintan the `paket.bootstrapper` (download from github, etc) but is not mandatory 27 | - the `paket.bootstrapper` download the nupkg (from github or nuget feed) and .net core sdk install it from a local dir (so not using nuget client) 28 | - you can install just `paket` as .net tool, no need for `paket.bootstrapper` 29 | - native exe in `.paket`, as usual 30 | 31 | CONS: 32 | 33 | - some dirty in `.paket` dir (the `.store`). 34 | - we can restore in `paket-files\paket-bin` and symlink/shellscript the exe? 35 | - no atm `dotnet paket`. this will be another PR for an helper global tool (`dotnet tool install -g`) 36 | - need .net core sdk. But we can use paket repotool when ready for `paket` .net full too 37 | 38 | Behaviour: 39 | 40 | - install the bootstrapper as .NET Tool 41 | - run `paket.bootstrapper` but download the nupkg and install `paket` as .NET tool 42 | 43 | # Scenarios 44 | 45 | Before each scenario do a `git clean -xdf` 46 | 47 | # scenario 1, download bootstrapper and paket 48 | 49 | Install the boostrapper and restore `paket` with 50 | 51 | `dotnet restore .paket` 52 | 53 | after that, as usual 54 | 55 | `.paket\paket --help` 56 | 57 | or 58 | 59 | `.paket\paket restore` 60 | 61 | # scenario 2, integration with sdk 62 | 63 | normal command like the following should work, without explicit bootstrapping 64 | 65 | ``` 66 | dotnet run -p src/c1 67 | ``` 68 | 69 | or for a suave app 70 | 71 | ``` 72 | dotnet run -p src/c1 -- --port 8083 73 | ``` 74 | 75 | # scenario 3, docker 76 | 77 | In `Dockerfile`, with multi steps to reuse layers to build a smaller `alpine`+`.net core runtime` 78 | 79 | build the image with 80 | 81 | ``` 82 | docker build . -t paket-netcore-app 83 | ``` 84 | 85 | Run just the console app 86 | 87 | ``` 88 | docker run paket-netcore-app 89 | ``` 90 | 91 | Run suave webapp (after that is avaiable at http://localhost:8083/ ) 92 | 93 | ``` 94 | docker run -p 8083:8083 paket-netcore-app --port 8083 95 | ``` 96 | 97 | # scenario 4, just paket 98 | 99 | To just download the `paket` in `.paket` dir, use 100 | 101 | `dotnet tool install paket --version "[5.179.403]" --tool-path ".paket" --add-source https://www.myget.org/F/paket-netcore-as-tool/api/v3/index.json` 102 | 103 | after that, as usual 104 | 105 | `.paket\paket --help` 106 | 107 | # EXPECTED TO WORK 108 | 109 | - the `dotnet restore .paket` should work docker/win/osx/unix 110 | - integration with sdk wihout explicit bootstrap first (just `dotnet build`) on win. fails on unix (just do `dotnet restore .paket` first) 111 | - `.paket/paket` commands 112 | - docker scenario 113 | 114 | # KNOWN BUGS 115 | 116 | - if there is a system proxy, there is an access error. the code for proxy management is temporary disabled on .net core version (thx @vaskir). 117 | 118 | # EXPECTED TO NOT WORK (WIP) 119 | 120 | - `dotnet paket`. It's not installed as global command. will do a workaround later. For now, use as before `.paket/paket --version` 121 | - download from github, need a real version of paket deployed. atm just myget feed are usable (forcenuget or prefernuget) 122 | - the cache is disabled. 123 | 124 | # HOW TO MIGRATE FROM PAKET .NET 125 | 126 | - require .net sdk >= 2.1.401 (best practice is to add a [global.json](https://raw.githubusercontent.com/enricosada/paket-netcore-testing-as-tool/master/global.json) in root) 127 | - delete `.paket/paket.exe` 128 | - delete `.paket/paket.bootstrapper.exe` 129 | - append to .gitignore some rules 130 | 131 | ```` 132 | /.paket/* 133 | !/.paket/*.proj 134 | !/.paket/*.exe.config 135 | !/.paket/*.props 136 | !/.paket/*.targets 137 | ```` 138 | - add `.paket/paket.bootstrapper.proj` from [this repo .paket/paket.bootstrapper.proj](https://raw.githubusercontent.com/enricosada/paket-netcore-testing-as-tool/master/.paket/paket.bootstrapper.proj) 139 | - because currently it's a prerelease, we need to add these to config the version and feeds 140 | - add `.paket/paket.bootstrapper.props` from [this repo .paket/paket.bootstrapper.props](https://raw.githubusercontent.com/enricosada/paket-netcore-testing-as-tool/master/.paket/paket.bootstrapper.props) 141 | - add `.paket/paket.bootstrapper.exe.config` from [this repo .paket/paket.bootstrapper.exe.config](https://raw.githubusercontent.com/enricosada/paket-netcore-testing-as-tool/master/.paket/paket.bootstrapper.exe.config) 142 | - run `dotnet restore .paket` to bootstrap paket 143 | - run `.paket/paket restore`. this will update `.paket/Paket.Restore.targets` to latest version 144 | 145 | from now **on a clean repo**, like previous scenarios: 146 | 147 | - `dotnet build` of project should work 148 | - you can do `dotnet run .paket` to explicit bootstrap paket 149 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "2.1.401" 4 | } 5 | } -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://www.nuget.org/api/v2 2 | framework netcoreapp2.1, netstandard2.0 3 | 4 | nuget FSharp.Core 5 | nuget Argu 6 | nuget Suave 7 | 8 | group Build 9 | 10 | github forki/FsUnit FsUnit.fs 11 | -------------------------------------------------------------------------------- /paket.lock: -------------------------------------------------------------------------------- 1 | RESTRICTION: || (== netcoreapp2.1) (== netstandard2.0) 2 | NUGET 3 | remote: https://www.nuget.org/api/v2 4 | Argu (5.1) 5 | FSharp.Core (>= 4.3.2) 6 | System.Configuration.ConfigurationManager (>= 4.4) 7 | FSharp.Core (4.3.4) 8 | Suave (2.4) 9 | FSharp.Core (>= 4.0 < 5.0) 10 | System.Configuration.ConfigurationManager (4.4.1) 11 | System.Security.Cryptography.ProtectedData (>= 4.4) 12 | System.Security.Cryptography.ProtectedData (4.4) 13 | 14 | GROUP Build 15 | 16 | GITHUB 17 | remote: forki/FsUnit 18 | FsUnit.fs (fa4eb37288d355eb855261be6c0b3945fba68432) -------------------------------------------------------------------------------- /src/c1/Program.fs: -------------------------------------------------------------------------------- 1 | // Learn more about F# at http://fsharp.org 2 | 3 | open System 4 | 5 | open Argu 6 | 7 | type CLIArguments = 8 | | Port of tcp_port:int 9 | with 10 | interface IArgParserTemplate with 11 | member s.Usage = 12 | match s with 13 | | Port _ -> "specify a primary port." 14 | 15 | [] 16 | let main argv = 17 | printfn "Hello World from F#!" 18 | l1.Say.hello "built paket .net core" 19 | 20 | let parser = ArgumentParser.Create(programName = "c1") 21 | 22 | try 23 | let args = parser.Parse argv 24 | 25 | let port = 26 | match args.GetAllResults() with 27 | | [Port p] -> Some (uint16 p) 28 | | _ -> None 29 | 30 | port 31 | |> Option.iter (l1.Say.start) 32 | 33 | 0 34 | with 35 | | :? ArguParseException as ex -> 36 | printfn "%s" ex.Message 37 | 1 38 | | ex -> 39 | printfn "Internal Error:" 40 | printfn "%s" ex.Message 41 | 2 42 | -------------------------------------------------------------------------------- /src/c1/c1.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/c1/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Core 2 | Argu 3 | Suave 4 | -------------------------------------------------------------------------------- /src/l1/Library.fs: -------------------------------------------------------------------------------- 1 | namespace l1 2 | 3 | open Suave 4 | 5 | module Say = 6 | let hello name = 7 | printfn "Hello %s" name 8 | 9 | let start port = 10 | startWebServer 11 | { defaultConfig with 12 | bindings = [ HttpBinding.create HTTP System.Net.IPAddress.Any port ] } 13 | (Successful.OK "Hello World!") 14 | -------------------------------------------------------------------------------- /src/l1/l1.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/l1/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Core 2 | Suave 3 | --------------------------------------------------------------------------------