Cabal-install installs old package versions by default - haskell

I just upgraded to the latest version of cabal-install which is 1.20. I am not sure if it is related but cabal started fetching old versions of packages for some reason.
In my cabal file, all dependencies are specified without version numbers. So I believe, cabal should fetch the latest versions available unless there is a conflict, correct?
If I run cabal install --only-dependencies within a sandbox environment, cabal pulls all kind of rubbish and old package versions like mongoDB-1.2.2 instead of 1.4.4 and scotty-0.5 instead of 0.7.2. If I run a specific package installation like cabal install scotty then it fetches the latest version and all is well. So I have to install all dependencies manually to get the latest versions - one by one. Annoying. What is going on?
Google gives me no hits.
If there are some kind of changes in cabal, what is it? And how do I pull all the latest dependencies within a sandbox.
Thanks.

Some of your dependencies have upper bounds that are forcing the usage of older versions of a given package. One thing that might help is to start over. Delete your package repository (~/.ghc on linux machines), and keep a discipline to work entirely within sandboxes. Use your package manager to install stuff you need globally, sandboxes for your development projects, and you can avoid a lot of the reasons this problem crops up. That said, if you're truly depending on a project that hasn't updated its upper bounds, then you're stuck using the older packages, short of submitting a patch to the library author or switching to a different dependency.

Related

Cache NPM library of different versions

For my use case, I want to install the NPM package Playwright(https://www.npmjs.com/package/playwright) of different versions in the same node project in zero time.
e.g. for executing one script, I will specify the package version as 1.21.0, for other, I will specify it as 1.26.0, etc. I want his installation to be in zero time. Playwright also installs the browser binaries in the system according to the version installed(https://playwright.dev/docs/browsers).
I tried using yarn zero installs(https://yarnpkg.com/features/zero-installs) feature for this, but it was removing the previous version of Playwright in the .yarn/cache/ folder. Thus, as the cache wasn't found, it was downloading the other version again.
Is there any way to resolve this? Please experiment with the Playwright package as it has the browser files with it. Experimenting with any other npm package might not help in this specific case.

Link cabal to local library

Lets MyLib be my local Haskell library. I can build it with cabal build and install it with cabal install, but can I use it in other projects without the installation step?
I'm developing several libraries and installing them after every change is not a good solution.
Let's say you have two entirely separate projects, one called my-library and another called my-project. And my-project depends on my-library.
The way to build my-library and make it available to other projects is cabal install my-library. Once that's done, any other project can use the library.
Now you're ready to build my-project using the command cabal install my-project. It will not rebuild or reinstall my-library, but it will link your project with the library.
Now, if you make modifications to my-library, be sure to update the version number before running cabal install my-library. If you forget to bump the version number, you will be warned that my-project will be made obsolete. Now the old version and the new version of your library are available to other projects.
You can continue to run your projects. They will happily continue to use the previous version of my-library until you do another cabal install my-project. So there is no need to re-install everything after every change.
If you do want to rebuild your projects, but continue to work with an older version of your library, you can specify that in the build-depends section of your cabal file. For example, if you have versions 1.0 and 2.0 of my-library installed, you can build your project against the older version like this:
build-depends: my-library==1.0, ...
There isn't a great solution to your problem, but you can use sandboxes to keep your development environment a bit cleaner.
With cabal-1.18 or newer, you can create a sandbox with cabal sandbox init and then you can either install to that sandbox or add-source (cabal sandbox add-source <path to library>).
This helps to keep unstable libraries (and their potentially unstable dependencies) out of your user package database, and that can help prevent 'cabal hell' (unsolvable conflicts between dependencies). However, that doesn't directly help reduce the number of commands you need to issue each time you want to do a top-level build.
What you can do though, is set up a simple script that performs the add-source commands and builds your top-level package. eg:
#!/bin/bash
cabal sandbox init # a no-op if the sandbox exists.
cabal sandbox add-source ../MyLib
cabal install --dependencies-only
cabal build
Granted, you could do that before, but this time you can also easily clean up (removing all the installed artifacts) by cleaning the sandbox:
cabal sandbox delete

Installing packages (via cabal) from "local hackage"

Is it possible to get cabal to
Download a particular package source, including all dependency packages sources.
At a later stage (when internet connectivity can no longer be relied upon) install these packages via cabal, from the locally downloaded files, automatically in the right order so that the desired package is build?
I know that you can use cabal unpack to view the source of a particular package, but I am not sure how to achieve above. Also note that in this post Can't get cabal update to work inside corporate network it was mentioned that this could be done, but the instructions were not specific enough for me.
cabal help | grep fetch:
fetch Downloads packages for later installation.
Example:
$ cabal fetch unbound
Resolving dependencies...
Downloading RepLib-0.5.3.1...
Downloading type-equality-0.1.1...
Downloading unbound-0.4.1.1...
Running cabal install unbound at a later stage won't require Internet access.

Optimal way to install and keep Node.js & packages up-to-date on OS X?

What is the cleanest or most optimal way to keep an up-to-date installation of Node along with its accompanying packages on OS X? Homebrew always seems a touch behind (except for head).
Additionally, an interesting observation from the Node.js wiki says:
Warning: brew installs are known to be buggy
Further, is there a preferred method to update the installed packages as well (across node updates and just generally updating them)?
I use a tool called NVM to manage Node.js installation; you can install and switch to various versions of Node.js with a single command. You can find NVM at https://github.com/creationix/nvm.
You may be interested in the first half of this screencast that covers installing and using NVM (full disclosure: I made the screencast).
I personally switched back to homebrew because installing the official package would foul up my path and which version of node I use.
And node packages shall not be installed globally so every new npm install will fetch the newest version if asked to do so.

How do I disable dependency checking with a local cabal install?

So I'm trying to install a package with a big messy dependency set (gitit, in this case). A direct cabal install from hackage forces rebuilds of plenty of libraries I don't want to rebuild (having to do with constraints on text, constraints on network, constraints on parsec, etc.) I did the right thing, ran cabal unpack gitit, manually edited the .cabal file, and successfully put it through a cabal configure, cabal build cycle. So far, so good.
Now, I want to run a cabal install. In the good old days (last year), this would just install the already built binaries and files where they belong. However, now, running cabal install runs the dependency checker, which decides that all the packages that I'm building with don't use the same parsec, etc., and tries to reinstall them anyway! Even though I just ran a perfectly fine cabal build. What's the magic flag to turn this off and get the old, not-clever, and perfectly acceptable behavior?
Looking at the flags, there doesn't seem to be any indication of cabal install doing this. In times of yore, before cabal install and when you had to manually get your own packages, the incantation at the install stage was runghc Setup install --user after you had run runghc Setup configure --prefix=$FOO --user - perhaps this will work? Setup.hs will not automatically invoke 'build' when you tell it to 'install', if my memory serves correctly.
Now, for the future, if you want to avoid this entire nasty dependency hell, I would highly suggest you use cabal-dev which will sandbox your package installations and never touch your actual user/global package database, in this case you'd just do:
$ cabal unpack gitit
$ cd gitit-0.8.0.1 # latest hackage version
$ cabal-dev install
It'll properly download and install all the needed dependencies like cabal install, but it'll sandbox them by creating a ./cabal-dev directory containing a self-contained package database. It never touches your global or user package db in ~/.ghc/. cabal-dev effectively makes editing cabal files and dealing with the diamond dependency problems Cabal faces a thing of the past, the way cabal-install made manually downloading packages a thing of the past.
It also turns out that there is an --only flag that lets one build and install only that package, just as the ./Setup route does.

Resources