I have a project in a Cabal sandbox. There is a package I would like to use but the one on Hackage isn't suitable. There is an alternative dev branch that should meet my needs that the author has on Github. I've previously installed dev branches without a sandbox by using:
$ runhaskell Setup.hs configure --user
$ runhaskell Setup.hs build
$ runhaskell Setup.hs install
Obviously that's not going to work if I only want this repo installed in the sandbox.
My directory structure is set up like this:
../MyProject
../MyProject/.cabal-sandbox
../MyProject/exec/Main.hs
../MyProject/src/MyProject.hs
../MyProject/MyProject.cabal
There's both an executable and a library. My build-depends has about 18 package dependencies, of which this is one. So my questions:
Once I've downloaded the dev repo, where should I extract it to?
Once extracted, how do I build/install into my sandbox?
Once that's all done, do I need to modify my .cabal file at all?
Reproducing the correct answer as community-wiki from the comments:
Try cabal sandbox add-source. See coldwa.st/e/blog/2013-08-20-Cabal-sandbox.html for an example.
Related
I have checked out https://github.com/gitpod-io/template-haskell
and merged samples for a book (haskell in depth) into my branch.
Prebuilding has no effect, every opening of a workspace begins the entire build process from the beginning. So gitpod is effectively unusable for this project, as Zou have to wait for the entire build to complete, before ou can start using the workspace.
I presume the reason might be, that stack build stores the build artefacts in ~/.stack and that location is not part of the workspace, so it's lost when the workspace is closed.
Is that right? And then, how to keep the build result alive?
I just started using Gitpod so I'm not sure if there's a better way to do this, but I was able to get pretty close to what I wanted out of a prebuild by specifying a base dockerfile by putting this in my gitpod.yml:
image:
file: .gitpod.Dockerfile
and then creating a .gitpod.Dockerfile that starts with
FROM gitpod/workspace-full
and then install ghcup and use it to install my other dependencies:
RUN curl --proto 'https' -tlsv1.2 -sSf https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup > ./ghcup
RUN chmod 755 ./ghcup
RUN sudo mv ./ghcup /usr/local/bin
RUN ghcup install ghc
RUN ghcup install cabal
RUN ghcup install hls
RUN ghcup install stack
RUN sudo ln -s /home/gitpod/.ghcup/bin/stack /usr/local/bin/stack
RUN stack install ghcid
Wekan is an open-source Kanban Board which used to be easy to install using nodejs (given that you already set up your MongoDB). I am stumbling upon the actual installation steps of the guide to install Wekan on Ubuntu 16.04:
Download the latest version wekan source code using the wget command and extract it.
wget https://github.com/wekan/wekan/releases/download/v0.63/wekan-0.63.tar.gz
tar xf wekan-0.63.tar.gz
And you will get a new directory named bundle. Go to that directory and install the Wekan dependencies using the npm command as shown below.
cd bundle/programs/server
npm install
Figuring out the last stable version is easy, there are new stable versions nearly every day (as of March 2019), which somehow seem to contradict the common definition.
More importantly, the directory bundle/programs/server does not exist, only server, but it does not contain a main.js which would be necessary to run
node main.js
Other resources considered:
I did of course check the official documentation, but it looks not up-to-date. The page https://github.com/wekan/wekan/wiki/Install-and-Update is redirecting to a rather untidy page which does no longer talk about a standalone installation.
I prefer a minimal installation and not a solution using snap like described at computingforgeeks
There is also an unanswered question about a more specific installation around: Installing Wekan via Sandstorm on cPanel which follows a similar approach.
The latest releases on the Wekan page are actually no ready-to-use node builds.
Wekan is built using Meteor and you will need Meteor to create the build. This is because you could also build it using Meteor against other architectures than os.linux.x86_64.
So here is how to build the latest release as of today on your dev-machine to then deploy it:
Build it yourself
[1.] Install Meteor
curl https://install.meteor.com/ | sh
[2.] Download and extract the latest Wekan
wget https://github.com/wekan/wekan/archive/v2.48.tar.gz
tar xf wekan-2.48.tar.gz
cd wekan-2.48
[3.] Install Wekan Dependencies
./rebuild-wekan.sh
# use option 1
[4.] Install dependency Meteor packages
Now it gets dirty. Somehow the required packages are not included in the release (an issue should be opened at GH). You need to install them yourself:
# create packages dir
mkdir -p packages
cd packages
# clone packages
git clone git#github.com:wekan/wekan-ldap.git
git clone git#github.com:wekan/meteor-accounts-cas.git
git clone git#github.com:wekan/wekan-scrollbar.git
# install repo and extract packages
git clone git#github.com:wekan/meteor-accounts-oidc.git
mv meteor-accounts-oidc/packages/switch_accounts-oidc ./
mv meteor-accounts-oidc/packages/switch_oidc ./
rm -rf meteor-accounts-oidc/
cd ../
[5.] Build against your architecure
meteor build ../build --architecute os.linux.x86_64
# go grab a coffee... yes even with nvme SSD...
Once the build is ready you can go ../build and check out the wekan-2.48.tar.gz which now contains your built bundle including the described folders and files.
Use this bundle to deploy as described in the documentation.
Summary
This describes only how to create the build yourself and I am not giving any guarantee that the build package will run when deployed to your target environment.
I think there is either some issue with the way the releases are attached on GH or they explicitly want to keep it open against which arch you want to build.
In any case I would open an issue with demand for a more clear documentation and a description for reproduction of the errors your mentioned.
Further readings
https://guide.meteor.com/deployment.html#custom-deployment
I use npm link myDependency within myPackage so that I can work on both at the same time (vs. publishing myDependency after every change and then updating myPackage to test it.)
I would like to be able to use Travis CI with myPackage but, as one could expect (I actually forgot, but it became quite obvious after attempting to build): running npm install on Travis won't manage to install the linked package.
So, what can I do? I saw someone suggest using a Docker container but that feels like a lot of infrastructure and I'm not experienced with Docker. Another option I thought of was adding a pre-install script to clone the dev branch of myDependency repo into the node_modules folder.
First though, I'm sure I'm not the first person who ever worked on two packages alongside each other, so there must be some consensus on how this should be done.
I solved this by replicating my development set-up on Travis.
The key to solving this involves giving Travis a way to access GitHub. To do this, log in to GitHub and go to the Personal access tokens page.
You’ll see a form with a field for the name of your token and what permissions you want to grant access to. Fill in a name such as "Travis CI Pull Repo" and select the "repo" section. None of the others are necessary, so no need to give access to them. At the bottom of the page is a green button "Generate token."
Back in your code editor, create a .travis.yml file in the root directory of your project if you don’t have one already. We will be using a RubyGem for the next step, so if you don’t have Ruby gems installed, you’ll need to download it. You can check if you have it installed by running gem -v in the terminal.
If you do, run the following in the terminal to install the Travis RubyGem:
gem install travis
Next, in the terminal, make sure you’re working in your project’s root directory, and use the Travis gem to add the access token to your .travis.yml file:
travis encrypt GH_TOKEN="token-from-github-goes-here" --add
If you were successful, your .travis.yml file should have a bunch of random text an encrypted token saved:
env:
global:
secure: "lots-of-seemingly-random-characters"
That’s it! Travis should now be able to pull (and push if that’s what you’re into) to your GitHub repository.
Obviously your .travis.yml file can vary greatly from mine, but at it’s most basic, I set up .travis.yml like this:
language: node_js
node_js:
- '6'
cache:
directories:
- node_modules
install:
- npm install
script:
- npm run lint
- npm run test
env:
global:
secure: "lots-of-seemingly-random-characters"
To add the cloning and linking of the dependency, add a before_install section with the following commands:
before_install:
- git config credential.helper "store --file=.git/credentials"
- echo "https://${GH_TOKEN}:#github.com" > .git/credentials
- cd ..
- git clone https://github.com/my-name/my-dependency.git my-dependency
- cd my-dependency
- npm install
- npm link
- cd ../my-main-project
What is this actually doing?
We configure Git to use our saved access token.
We go one directory up and clone the repository into a new folder with the same name as the repository.
We go into the repository and install its dependencies.
We create a global NPM link.
Finally, we return to the main project (the one we are running Travis on). Note that this name must match the repository’s name on GitHub as that’s the name Travis will use.
In addition, we’ll need to actually use the link created above, so in the install section add the following line:
install:
- npm install
- npm link my-dependency
Make sure you put npm link after npm install as by default npm install will obliterate any links (a very annoying bug for those of us who use npm link).
I'm confused about where stack build PKG places the packages it installs. I had thought that, for example
mkdir foo
cd foo
stack build PKG_IN_HACKAGE_NOT_IN_RESOLVER
would create foo/.stack-work and put the specified package there (as if to had been specified as an "extra dependency"); but I seen on .stack-work and the package is available globally on my system.
If what I want is an entirely isolated (temporary) Haskell configuration in which to install and use PKG, how do I do that?
Let's say I have three of my own packages, A B & C, with dependencies on lots of additional packages in Hackage. I'm using cabal 1.18.
C depends on A & B.
B depends on A.
A & B have test suites.
I set up the sandbox like this:
cd /path/to/sandbox
cabal sandbox init
cabal sandbox add-source /path/to/A
cabal sandbox add-source /path/to/B
cabal sandbox add-source /path/to/C
I want to build all the packages, run all test suites on my packages but not dependency packages, showing full test output. What's the best way to do that?
Option 1
cd /path/to/sandbox
cabal install --enable-tests A B C
Problems:
There's no way to pass --show-details=always to cabal install.
Test output is hidden in a log file and not shown.
If the user happened to do cabal install A earlier, A won't get rebuilt and the tests won't get run.
Option 2
cd /path/to/A
cabal sandbox init --sandbox=/path/to/sandbox/.cabal-sandbox
cd /path/to/B
cabal sandbox init --sandbox=/path/to/sandbox/.cabal-sandbox
cd /path/to/A
cabal configure --enable-tests
cabal test --show-details=always
cd /path/to/B
cabal configure --enable-tests
cabal test --show-details=always
cabal install C
Problems:
This causes A and B libraries to be unnecessarily rebuilt.
Option 3
In the sandbox cabal.config, add the line tests: True.
Problems:
This will cause tests to run for all dependent packages from Hackage, which is very slow and fails in some cases.
Cabal is really missing functionality here. My plan is to generalize cabal so it has less (or no) concept of a "current package". Right now lots of commands assume that you're in a directory with a .cabal file and you want to do thing to that package. This is less often the case for large, multi-package projects as you've seen.
What I want is for cabal to take a list of targets for most commands, such as build, test, bench, etc. You can the run tests from several packages by
cabal test --show-details=always \
pkg-dir1:some-test1 pkg-dir1:some-test2 pkg-dir2
(The above example shows that it should be possible to specify just some sections of a package as well.)
I realize that this doesn't help you much now, but at least you know which direction we're moving in.