github fsprojects/Paket 12.0.0

one hour ago

Paket 12 only ships as the paket .NET tool, which needs the .NET 10 runtime: paket.exe, paket.bootstrapper.exe and Mono are no longer supported. To upgrade, install Paket as a local tool (https://fsprojects.github.io/Paket/installation.html#Moving-from-paket-exe-and-the-bootstrapper). To keep paket.exe for now, remove the version line from paket.dependencies and run .paket/paket.bootstrapper.exe --self: you get the bootstrapper of Paket 11, which stays on the latest 11.x.

When the tool manifest declares paket, the restore during the builds and #r "paket:" in F# scripts run the local tool, before a Paket installed with --tool-path. Paket.Core targets net10.0 and drops its obsolete members, the command line no longer takes the syntax that Paket 5.5 replaced nor the generate-include-scripts and fix-nuspec commands, Paket no longer looks for projects in the folders whose name starts with a dot or that are links, and paket pack --release-notes-file reads the file with Fake.Core.ReleaseNotes 6.

This release also recognizes .NET 11, supports .slnx solutions, moves to the NuGet client libraries 7.9, writes paket.lock faster, and fixes many issues of git dependencies and of the restore. The next paket install or paket update may rewrite some framework restrictions of paket.lock, for the OS-specific frameworks of .NET 9 to 11 and in a shorter form.

  • feat(BREAKING): Paket only ships as a .NET tool: dotnet tool install paket. paket.exe and paket.bootstrapper.exe are no longer built, and Paket no longer runs on Mono or the .NET Framework. See https://fsprojects.github.io/Paket/installation.html#Moving-from-paket-exe-and-the-bootstrapper
  • feat(BREAKING): The release and tools/paket.exe of the Paket package carry a paket.exe stub instead, so that bootstrappers older than 11.0 explain how to move on: it prints the steps and exits with code 1. To stay on paket.exe, move to the bootstrapper of Paket 11, which stays on the latest 11.x: remove the version line from paket.dependencies, then run paket.bootstrapper.exe --self.
  • feat(BREAKING): Paket.Restore.targets and paket.targets no longer run the bootstrapper or run paket.exe through mono. They find Paket installed with --tool-path (in .paket or the root), as a local tool, or on the PATH like a global tool. The MonoPath and PaketBootStrapper* properties are gone; the PaketBootstrapping target is kept, empty, for the projects that depend on it.
  • fix(BREAKING): When the tool manifest declares paket, Paket.Restore.targets and paket.targets run the local tool instead of a Paket installed with --tool-path in .paket or the root, which can be an older Paket left by the move to the .NET tool, such as the paket.exe or bootstrapper of Paket 11. They skip it with the warning PAKET0001, on every OS, which NoWarn can turn off. To keep running it, set PaketExePath to its full path
  • fix(BREAKING): When a .config/dotnet-tools.json or dotnet-tools.json up from the script declares paket, #r "paket:" in F# scripts runs that local tool instead of a Paket installed with --tool-path up from the script, which can be an older Paket such as the paket.exe or bootstrapper of Paket 11, and shows a warning. When the local tool isn't restored, it asks to run dotnet tool restore instead of running that Paket. As dotnet, it no longer looks for a manifest above an isRoot one
  • feat(BREAKING): Paket.Core targets net10.0 instead of netstandard2.0 and net461: the projects and scripts that reference it must target net10.0 or later, as the paket .NET tool already needs the .NET 10 runtime. FSharp.DependencyManager.Paket stays on netstandard2.0 - #4317
  • refactor(BREAKING): In Paket.Core, Dependencies.DownloadLatestBootstrapper and the downloadBootstrapper parameter of Dependencies.Init are removed, along with the Releases module, Utils.isMonoRuntime, Utils.isMono, Utils.monoPath, Utils.fixArchive, ProcessHelper.monoArguments, ProcessHelper.appSettings, FrameworkDetection.resolveEnvironmentFramework (replaced by defaultScriptFramework), Queries.resolveEnvironmentFrameworkForScriptGeneration and the BootstrapperFileName, PaketFileName and GithubReleaseDownloadUrl constants. ProcessHelper.tryFindPath and findPath take the ;-separated paths instead of an app setting name. The PAKET_PUSH_HTTPCLIENT variable is gone: paket push always uses HttpClient.
  • refactor(BREAKING): The obsolete InstallModel.CreateFromLibs and InstallModel.createFromLibs, InstallModel.GetLibReferences and PlatformMatching.getFrameworkPathPenalty of Paket.Core are removed: use InstallModel.CreateFromContent and createFromContent, GetLegacyReferences or GetCompileReferences, and PlatformMatching.getPathPenalty. So is the Fake.Globbing module that Paket.Core carried from FAKE 4: use Fake.IO.Globbing.Glob of the Fake.IO.FileSystem package. So are NuGetCache.NuGetConfig.writeNuGetConfig and Constants.NuGetConfigFile, unused since the end of the project.json support
  • refactor(BREAKING): The obsolete Dependencies.ShowOutdated and Dependencies.FindOutdated overloads without the force parameter, NuGet.GetLibFiles, NuGet.GetTargetsFiles, NuGet.GetAnalyzerFiles, InstallModel.GetReferenceFolders and FrameworkDetection.Extract of Paket.Core are removed: use the overloads with force set to true, NuGet.GetContent with NuGet.tryFindFolder, InstallModel.CompileLibFolders and PlatformMatching.extractPlatforms, whose Platforms hold the framework. So is the Dependencies.FixNuspecs overload that takes the path of the obj/*.references file of a project: use the one that takes the ProjectFile and its ReferencesFile
  • refactor(BREAKING): The obsolete paket generate-include-scripts and paket fix-nuspec commands, and the references-file option of paket fix-nuspecs, are removed: use paket generate-load-scripts, and paket fix-nuspecs files <nuspec files> project-file <project file> as Paket.Restore.targets does since Paket 5.92. The .paket/Paket.Restore.targets of an older Paket is replaced at the next paket install or full paket restore
  • refactor(BREAKING): The paket command line no longer accepts the syntax that Paket 5.5 replaced, which it still took with a warning: the options without dashes, as in paket add nuget Foo version 1.0, paket pack output bin buildconfig Debug templatefile paket.template or paket push file Foo.nupkg url https://example.org apikey KEY, and the old names --createnewbindingfiles, --creds-migrations and --references-files. Write paket add Foo --version 1.0, paket pack bin --build-config Debug --template paket.template, paket push Foo.nupkg --url https://example.org --api-key KEY, --create-new-binding-files, --migrate-credentials and --references-file (once per file). The .paket/paket.targets of Paket 5.97.0 and earlier passes --references-files: the next paket install or full paket restore replaces it. The Ionide-Paket extension of Visual Studio Code, last updated in 2020, still passes this syntax to add, remove or update a package and to update a group
  • fix(BREAKING): Paket no longer looks for projects and paket.template files in the folders whose name starts with a dot, like .devenv, nor in the folders that are links, as paket convert-from-nuget already did for the solutions and NuGet files: the projects there are left out of install, restore, update, remove and pack. Until now only .git and .fable were skipped. A cyclic link, as in a Nix .devenv profile, no longer makes the search run forever - #4421
  • deps(BREAKING): paket pack --release-notes-file reads the file with Fake.Core.ReleaseNotes 6, in the formats described in https://fake.build/reference/fake-core-releasenotes.html: the package version is the first word of the latest header that is a whole SemVer version, so ## [1.2.3] - 2020-01-01 and ## v1.2.3 - 2020-01-01 give 2020-01-01; pass --version for such headers. Prerelease versions like 1.2.3-beta.11.2 are no longer cut, and build metadata (+sha.abc) is kept - fsprojects/FAKE#2686
  • feat: The release carries the paket.targets and paket.bootstrapper.exe of the latest Paket 11 release, for Paket 11.0.0 and earlier, which download them from the latest release on auto-restore on, convert-from-nuget and init, and for the --self of the bootstrappers older than 11.0
  • feat: paket auto-restore on writes paket.targets from Paket itself instead of downloading it from the latest GitHub release, so it works offline and matches the running Paket
  • feat: paket install, paket restore, and update, add and remove when they install rewrite an existing .paket/paket.targets with the one of the running Paket, unless PAKET_SKIP_RESTORE_TARGETS is true, so that a repository that turned auto-restore on with Paket 11 no longer keeps the one that runs paket.exe through mono outside Windows and falls back to the bootstrapper. A restore with --project, --references-file or --only-referenced, like the one paket.targets runs during a build, leaves it as it is.
  • feat: #r "paket:" in F# scripts finds the Paket .NET tool: installed with --tool-path, as a local tool of the manifest, as a global tool, or restored in the NuGet packages folder
  • feat: Recognize the .NET 11 monikers: net11.0, net11.0-windows..., net11.0-android and the other OS-specific ones, and netcoreapp11.0 - #4439
  • feat: Add support for .slnx solution files - #4443
  • feat: paket convert-from-nuget now updates .slnx solution files, as it does .sln ones - #4443
  • perf: Faster framework restrictions: writing the lock files of large repositories takes a quarter of the time and allocates less than 40% of the memory it did - #4317
  • deps: Update the NuGet client libraries from 5.11 to 7.9, along with System.Net.Http.WinHttpHandler and System.Security.Cryptography.ProtectedData
  • deps: Update Argu from 6.1.1 to 6.2.5, and System.Configuration.ConfigurationManager from 4.7 to 10.0, so the paket tool no longer ships System.Drawing.Common 4.7 and its critical vulnerability (GHSA-rxg9-xrhp-64gj). The help of paket update, paket find-packages and paket generate-nuspec no longer shows their optional package ID, search text and output directory as required
  • fix: The conditions written in project files now list the OS-specific frameworks of .NET 9 to 11 (net9.0-android, net10.0-ios, net11.0-macos...), which were left out in favour of their .NET 8 counterparts
  • fix: The OS-specific frameworks of .NET 9 to 11 fall back to the previous .NET version for the same OS, as the Windows ones do: a net11.0-android project can use the net10.0-android assets and dependencies of a package
  • fix: paket install no longer rewrites the framework restrictions of unchanged packages in paket.lock when it saves it for another reason, such as a removed github file, in groups with a framework: line: these restrictions are written in a single, shorter form, without empty clauses like (&& (== net10.0) (== net461)). The restrictions of the dependencies are rewritten once at the next paket install, and those of the packages when their group is resolved again; they hold the same frameworks
  • fix: With MSBuild 15.8 or later, paket.targets skips the restore when paket-files/paket.restore.cached says that the last full restore, as by paket install or paket restore of all the groups and projects, was of the current paket.lock, instead of restoring on every build of a project without the SDK. It still restores while paket.local exists, when the packages folder is missing unless paket.lock has storage: none for all its groups, the main one included, and packages, and after it restored a project for another paket.lock, for a missing packages folder or with paket.local, until the next full restore
  • fix: paket restore no longer skips as up to date when the packages folder is missing, or when a restore since the last full one may have changed it: a restore of some projects or groups for another paket.lock, one with paket.local or --force, or a full one for another paket.lock that failed. A full paket restore --force now writes paket-files/paket.restore.cached
  • fix: Paket.Restore.targets and paket.targets read the closest .config/dotnet-tools.json and the closest dotnet-tools.json from the root up, instead of only the .config/dotnet-tools.json of the root, to know whether paket is a local tool, and only the paket tool counts, not another tool with a paket command
  • fix: Paket.Restore.targets and paket.targets no longer take a folder named paket in the root or in .paket, such as a project folder named Paket on a case-insensitive file system, for a Paket installed with --tool-path
  • fix: The restore no longer rewrites .paket/Paket.Restore.targets when only its line endings differ from the ones of Paket, as after a checkout with other line endings, which showed it as changed in git after each restore. The same goes for .paket/paket.targets and the other files that the restore writes
  • fix: When the restore updates .paket/Paket.Restore.targets, as for a new version of Paket, the file keeps its line endings instead of taking the ones of the machine that built Paket. The same goes for .paket/paket.targets and the other files that the restore writes
  • fix: When #r "paket:" in F# scripts runs the newest Paket .NET tool restored in the NuGet packages folder, as it does when it finds Paket neither installed with --tool-path nor as a local or global tool, it takes a release before its prereleases: with 12.0.0 and 12.0.0-alpha001 restored, it runs 12.0.0 instead of 12.0.0-alpha001
  • fix: Git dependencies restore again when the git cache doesn't have their repository yet, as on a fresh CI agent: since 11.0.0, Paket ran git remote set-url in the empty cache folder that its lock had created - #4461
  • fix: The paket-files of a git dependency are checked out when the HEAD of its git cache names a branch that is gone, as after the repository renamed its default branch, instead of failing with "bad revision 'HEAD'"
  • fix: A git dependency whose checkout failed, as for a file name too long for the file system, is cloned again at the next restore, instead of being taken for one with local changes or for an up-to-date one
  • fix: A local git dependency without a branch, whose repository has no master, gets an error that suggests giving its branch, as in git file:///path/to/repository main
  • fix: A process that Paket starts and that exits right away, such as a git command, the build: command of a git dependency or a credential provider, no longer fails with "Start of process ... failed". For a local git repository, the error showed as "Could not find hash for ..."
  • fix: Local git dependencies with a Windows path, like git file:///C:/code/repo, resolve again: since 11.0.0 and #4377, their path kept the / before the drive letter
  • fix: A broken git cache in ~/.paket/git/db is set up again instead of making git change the repository of a parent folder, such as a dotfiles repository in the home folder, and the git cache works with safe.bareRepository=explicit
  • fix: The path of a local git repository can escape characters, like git file:///home/me/my%20repo, and its folder name is read from a Windows path that ends with \ or doesn't exist yet, and from a path to the .git folder of the repository, like git file:///home/me/repo/.git. Such a path used to give an empty or a whole path as the name of the git cache and paket-files folders. A repository at the root of a file system, which has no folder name, or whose path ends with . or .., fails with an error. A folder name that holds a %, like git file:///home/me/100%25, is checked out too
  • fix: A paket-files folder of a git dependency that isn't a clone, as one committed with the project, is cloned again. Paket used to run its git commands on the repository of the project instead, and could check the dependency out over the project
  • fix: A git dependency on an annotated tag is locked at the commit of the tag, not at the tag object, which made each restore download it again. A lock file that holds the tag object still restores, and gets the commit at the next update
  • fix: Only the .git that ends the name of a git repository, in any case as in Repo.GIT, is left out of its folder name, so git https://github.com/me/me.github.io.git goes to paket-files/github.com/me/me.github.io instead of mehub.io. The paket-files folder of a repository with .git inside its name, or another case of .git at its end, moves. A remote URL to the .git folder of a repository, like git ssh://host/home/me/repo/.git, is named after the folder of the repository, as a local one is, instead of taking the paket-files folder of its owner
  • fix: The git cache of a repository is ~/.paket/git/db/<owner>/<project>, so that remote repositories of the same name from two owners no longer share one, and swap its branches on each fetch. Local repositories of the same folder name still share one. Each repository is cloned again once, and paket clear-cache removes the old caches
  • fix: paket convert-from-nuget removes the NuGet.Config, NuGet.targets and NuGet.exe files of the root .nuget folder again, as well as the folder once it is empty: Paket 11.0 had stopped finding them. It reads and removes the NuGet.Config of the root and of the .nuget folder under the names NuGet looks for, nuget.config, NuGet.config or NuGet.Config, and the NuGet.targets and NuGet.exe of the .nuget folder whatever the case of their name, where Linux only found lowercase names
  • fix: paket convert-from-nuget converts and removes nothing through a link: it skips the projects, NuGet files and solutions of the folders that are links, with a warning for each such folder, so these projects are not converted. It leaves in place a .nuget folder that is a link and the solutions that are links, and skips with a warning the solutions it cannot read or update, instead of failing
  • fix: paket convert-from-nuget only removes the solution items of a .sln that are files it deletes, found by their path in any solution folder. It removed the first line naming a NuGet file of .nuget, even a project or a packages.config it kept
  • fix: paket convert-from-nuget keeps the non-ASCII characters of a .sln without a BOM, which it saved in ASCII
  • fix: paket generate-load-scripts keeps in the group scripts the assemblies that reference themselves, like System.Reactive 7.0, which it dropped. It also keeps, with a warning, the assemblies and packages that depend on each other, which it dropped too - #4458
  • fix: paket update --no-install no longer fails when a group has generate_load_scripts: true and the packages of the new paket.lock aren't all restored, as on a fresh checkout or for a package that the update adds: it leaves the load scripts to the next restore, which downloads the packages that they load - #2785
  • fix: paket pack --symbols no longer fails on a project with Compile entries without an Include or Update attribute, such as <Compile Remove="..." /> or a Compile item definition in an ItemDefinitionGroup, and leaves out of the symbols package the files that a Remove names without wildcards - #4222
  • fix: Looking for projects no longer runs forever on a cyclic directory link, as in a Nix .devenv profile. paket pack still follows the links when it looks for template files - #4421 @michaelglass
  • fix: Do not warn about missing "redirects: force" for FSharp.Core in projects targeting net5.0 and later - #4455
  • fix: paket install no longer warns about missing "redirects: force" for FSharp.Core in SDK projects that take their target framework from Directory.Build.props, by inheriting it or through a property such as $(DefaultTargetFramework). Paket, which doesn't read Directory.Build.props, also stops taking such a property for net10 (.NET Framework 1.0): where it needs the framework of the project, as for framework: auto-detect or paket pack, it falls back to net40, like for a project without framework - #4485
  • fix: The warning about the FSharp.Core binding redirects of F# projects links to an existing section of the documentation

Don't miss a new Paket release

NewReleases is sending notifications on new releases.