As far as I know to make new projects yosog and yosog2 I do the following
$ yesod init
$ cd yosog
yosog$ cabal sandbox init
yosog$ cabal install
$ yesod init
$ cd yosog2
yosog2$ cabal sandbox init
yosog2$ cabal install
But each cabal install takes forever. How am I suppose to make a bunch of Yesod projects if each takes forever to compile?
It sounds like what you're really trying to do is have multiple separate projects reuse the same cabal sandbox. You can do this by specifying a shared --sandbox option to the cabal sandbox command. Note, however, that by sharing a sandbox, you're giving up on some of the protection that sandboxes are intended to provide.
It is kind of unusual to run multiple projects Yesod at the same time. Each would need their own tcp port, and run a completely separate server. Two Yesod projects would usually indicate completely different websites that have nothing to do with each other.
You can put multiple handlers and routes in one single project, so if you have related web pages/APIs you would install them with a single command. If you have pieces that are truly modular and reusable, you could put those handlers in library packages, but the main project will still build and install under a single Yesod program.
Related
I am trying to learn cabal, and have tested several my own little projects, now I want to clean them up.
Basically, if I am working without a sandbox, my workflow is:
run cabal init
edit src/Mylib.hs, and then edit mylibname.cabal file
run cabal build
run cabal repl and test my code
run cabal install
Now, I see my own project:
installed into ~/.cabal/lib/x86-64-linux-ghc-7.10.1
registered in ~/.ghc/package.conf.d
I can write import Mylib in my other haskell source code, so I think the package is successfully installed.
Then I want to uninstall the package, as the package itself is just meaningless experiment code.
I read this article, who says that:
There is no "cabal uninstall" command. You can only unregister
packages with ghc-pkg:
ghc-pkg unregister
so I run
ghc-pkg unregister mylibname
Now, it seems that the package is unregistered in ~/ghc/package.conf.d, however, there is still a compiled library in ~/.cabal/lib/x86-64-linux-ghc-7.10.1.
So, how could I completly remove my project, could I just rm -rf the library in ~/.cabal?
You can delete the files yourself from the packages directory. However, the reason no command to do so is provided is there's in general no guarantee something may not have linked against them elsewhere, and so such deletions may cause breakages. That said, there's also a tool that goes and does the deletion for you if you really want it.
http://hackage.haskell.org/package/cabal-uninstall
And there's a tool with a bit more functionality that also lets you figure out what packages have no reverse deps, so at least no other packages break:
https://github.com/iquiw/cabal-delete
If a have a library checked out locally that builds with cabal that is used by an application. I would like to build my application against the the local library rather than something from hackage but I'm not sure how to do this. This seems like something I should be able to do, I'm just don't seem to be able to work out how.
Sandboxing
In case it matters or complicates things, the application is in a cabal sandbox with the cabal-sandbox-config file in the route directory of the application.
What I'm Trying to accomplish
I'm building Yesod application and I want to tweak the behaviour of one of the dependencies (shakespeare). I would like to build my application against my tweaked version.
Use cabal sandbox add-source, which is designed specifically for this use case.
Example:
$ git clone https://github.com/SomeUser/SomeDependency
$ cd /path/to/my-project
$ cabal sandbox add-source /path/to/SomeDependency
$ cabal build
As a bonus, if you later update SomeDependency and try to rebuild my-project, cabal will notice that and reinstall SomeDependency.
Option 1:
You can just clone the project, and then run a cabal install in the cloned directory.
git clone https://github.com/yesodweb/shakespeare.git
This will give you a directory shakespeare which will contain a .cabal file.
So just enter the directory and run a cabal install. This will install shakespeare. Now continue with installing your project.
The key point:
You need to install shakespeare yourself first so that when you compile your own project, ghc or cabal doesn't try to install the shakespeare dependency (from hackage by default) on its own.
Option 2:
Install hackage-server
Upload a copy of shakespeare (your tweaked version) to your local hackage
Edit your cabal config to prioritize your local hackage over the haskell-hackage
remote-repo: hackage.haskell.org:http://hackage.haskell.org/packages/archive
remote-repo: local.hackage:http://local.hackage/packages/archive
This might make sense if you're going to be tweaking several packages, but you're probably better off not doing this because among other things, keeping track of updates to your tweaked versions is going to be a nightmare.
I'm writing a small Scotty app and have decided after using yesod that I cannot live without wai-handler-devel to live-reload code for me. I'm using cabal sandbox like a good little boy, but every time I run my development executable (through cabal run), I get the error Could not find module Web.Scotty. However, when I build the application executable (not the development executable), it all runs fine.
The two executables have identical dependencies in the cabal file. The app executable has a main that uses wai's run handler, while the development executable uses runQuit from wai-handler-devel.
I assume this is a sandboxing issue, because the usual setup seems to be to use runhaskell to execute the development server script - but since my application is sandboxed, it doesn't even find the DevelServer import.
I love the snap framework but I hate running 'cabal install' with each iteration (minor code change) I want to try out.
Is there an alternative for rapid iteration?
Start with
cabal install --reinstall -fhint snap
Then, for your project:
cabal clean
cabal configure -fdevelopment
cabal build
./dist/build/projname/projname
You shouldn't ever use cabal install for binaries that you don't want to be able to execute from arbitrary locations, anyway. You should be using cabal build for things you only want to run locally.
You will need to run cabal build and start the program again when you change Main.hs or your project's .cabal file.
If you have any further questions, comment - I'm the guy who implemented this functionality for
Snap.
Yesod provides yesod devel which automatically reloads code changes. I am not aware of a comparable capability in snap, but it is highly likely that they can reuse much of the Yesod code that does this.
Given the existence of Snap.Loader.Devel I'm guessing they might already provide something like what you are asking for, but I can't find the documentation on how to use it. The FAQ question How do I run my app in development mode still requires a cabal install; it's unclear from the docs whether you only need to do this once, or every time the code changes.
I'm working on the wxHaskell library, and wishing to keep my development work separate from the stable wxHaskell from hackage I'm using cabal-dev in the following manner:
I obtained the source for wxHaskell from darcs;
Because wxHaskell is comprised of three components I used cabal-dev add-source to add each one (wx, wxcore, wxdirect);
I was then able to install into a sandbox local package library by doing cabal-dev install wx, as expected, the dependencies were detected and everything built and installed.
Finally I successfully ran my test code by using ghc -package-conf to specify the location of the sandboxed package database.
The problem comes when I make modifications to the wxHaskell source. In order to build and install the updated code I have to use cabal-dev install --reinstall, which makes sense as I don't increment the version number; the build takes place and I see "Installing library in..." and "Registering..." but the changes I've made in the code aren't present in the recompiled sandbox library.
The work around I have at the moment is to delete the cabal-dev library and repeat the process every time I want to rebuild.
UPDATE: cabal-install >= 1.18 has support for sandboxes, and will be better maintained than cabal-dev going forward. Cabal-install also has better support for using add-source with sandboxes. Here's a description of the new sandboxing features in cabal-install: http://coldwa.st/e/blog/2013-07-30-Cabal-sandbox.html
Old answer:
As you found, 'add-source' is not meant for use with actively changing projects. I'm not sure that there is a good solution there either - it's difficult to track the location of an add-source'd project (there is no existing infrastructure for that, at least), and I'm not sure that's always the right thing.
Another workflow may serve you better - just use cabal-dev install, pointing to the sandbox you wish to use for future development. Recent versions of the cabal toolchain (by which I mean Cabal, cabal-install and cabal-dev) allow for this sort of thing:
$ ls
wx wxcore wxdirect
$ cabal-dev install --sandbox=<path-to-some-sandbox> ./wx ./wxcore ./wxdirect
...
(Note: I have not tested this with WX - kinks may arise that I'm unaware of!)
Assuming everything goes as expected, that will install the three packages from the local sub directories into the specified sandbox. Updating the source just means re-issuing a cabal-dev install command for the project that changed.
Keep in mind that you must either issue the repeated cabal-dev install commands in the correct order on your own, or you must use the batch command above and update version numbers accordingly.
I make no claims about this being ideal ;) but I think it's better than deleting the sandbox each time.
After some investigation I can confirm that this is a result of my misunderstanding regarding the usage of add-source, as detailed in "Using a sandbox-local Hackage" section of the README, which is given here (the strong was added by myself and indicates the reason for my misunderstanding):
Cabal-dev also allows you to use un-released packages as though they
were on hackage with cabal-dev add-source.
For example, the linux-ptrace and posix-waitpid packages were only
recently uploaded to hackage. Previously, cabal-dev was used to build
applications that depended on these two packages:
$ ls
linux-ptrace/ myProject/ posix-waitpid/
$ cd myProject
$ cabal-dev add-source ../linux-ptrace ../posix-waitpid
$ cabal-dev install
Note that cabal-dev add-source accepts a list of source locations.
Be careful, however, because packages that have been added are not
tied to their original source locations any more. Changes to the
linux-ptrace source in the above example will not be used by
myProject unless the user issues cabal-dev add-source with the
path to the linux-ptrace source again. This is similar to the
cabal install step you may do now to enable a project to make use of
changes to a dependency.