spago docs state:
packages.dhall: this file is meant to contain the totality of the packages available to your project (that is, any package you might want to import).In practice it pulls in the official package-set as a base, and you are then able to add any package that might not be in the package set, or override existing ones.
spago.dhall: this is your project configuration. It includes the above package set, the list of your dependencies, the source paths that will be used to build, and any other project-wide setting that spago will use. (my emphasis)
Why do both files have the notion/concept of dependencies? Example: packages.dhall and spago.dhall from the ebook.
spago.dhall dependencies can be found in the project .spago folder. But I cannot locate the ones from packages.dhall. Others are common like aff. A different perspective:
[...] what you choose is a "snapshot", which is a collection of certain versions of all available packages that are guaranteed to compile and work together.
The snapshot is defined in your
packages.dhallfile, and then you specify the specific packages that you want to use inspago.dhall. The version for each package comes from the snapshot.
That sounds, like spago.dhall is an excerpt of packages from packages.dhall.The note about versions is a bit confusing, as there aren't version specifiers in both files.
So, why two files? What is the mental model for someone coming from npm ecosystem with package.json (which might be present as well)?
The mental model is that of a Haskell developer, which is what most PureScript developers used to be, and many still are. :-)
But more seriously, the mental model is having multiple "projects" in a "solution", which is the model of Haskell's de-facto standard package manager, Stack. In Haskell this situation is very common, in PureScript - much less so, but still not unheard of.
In a situation like this it's usually beneficial to have all the "projects" to share a common set of packages, which are all guaranteed to be "compatible" with each other, which simply means that they all compile together and their tests pass. In Haskell Stack this common set of packages is defined in
stack.yaml. In Spago - it'spackages.dhall.Once you have this common base set of packages established, each individual project may pick and choose the particular packages that it uses. In Haskell Stack this is specified either in
package.yamlor in<project-name>.cabal(the latter being phased out). In Spago - it'sspago.dhall.But of course, when you have just the one project, having both
packages.dhallto establish the "base set" of packages and then, separately,spago.dhallto pick some particular packages from that set - may seem a bit redundant. And indeed, it's possible to do without thepackages.dhallfile completely: just specify the URL of the package set directly inspago.dhall, as the value of thepackagesproperty:This will work, but there is one important caveat: hashing. When the URL of the package set is specified in
packages.dhall, runningspago installwill compute a hash of that package set and put it insidepackages.dhall, right next to the URL. Here's what mine looks like:Then, if maintainers of the package set become evil and change the contents of that file, Spago will be able to notice that, recompute the hash, and reinstall the packages.
If you put the URL directly in
spago.dhall, this doesn't happen, and you're left with the slight possibility of your dependencies getting out of sync.Now to address this point separately:
If you look closer at the examples you linked, you'll see that these are not the same dependencies. The ones in
spago.dhallare dependencies of your package - the one wherespago.dhalllives.But
dependenciesinpackages.dhallare dependencies of thetest-unitpackage, which is being added to the package set as an override, presumably because we want to use the special versionstackless-default, which isn't present in the official package set. When you override a package like this, you can override any fields specified in that package's ownspago.dhall, and in this case we're overridingdependencies,repo, andversion.