diff --git a/README.markdown b/README.markdown index 4064be515..ff27c8ed3 100644 --- a/README.markdown +++ b/README.markdown @@ -15,7 +15,7 @@ https://github.com/data61/fp-course #### Special note 2 Since February 2017, this repository is no longer hosted at -https://github.com/NICTA/course which is deprecated. Data61 replaces what was +https://github.com/NICTA/course which is deprecated. Data61 replaces what was NICTA since July 2016. The new repository is located at https://github.com/data61/fp-course @@ -47,11 +47,11 @@ however, your first post might be moderated. This is simply to prevent spam. 2. [[haskell-exercises]](https://groups.google.com/forum/#!forum/haskell-exercises) is a Google Group for queries related specifically to this Data61 functional programming course material. This mailing list is not owned by Data61, but is - run by others who are keen to share ideas relating to the course. + run by others who are keen to share ideas relating to the course. 3. \#scalaz [on Freenode](irc://irc.freenode.net/#scalaz) is an IRC channel that is operated by others who are keen to share ideas relating to functional programming in - general. Most of the participants of this channel have completed the Data61 + general. Most of the participants of this channel have completed the Data61 functional programming course to some extent. They are in various timezones and share a passion for functional programming, so may be able to provide relatively quick assistance with questions. @@ -62,6 +62,10 @@ however, your first post might be moderated. This is simply to prevent spam. ### Getting Started +**NOTE** If you do not wish to install these dependencies, you may use a virtual machine +instead. [Instructions](ops/README.md) for automatically building a virtual machine are +available in this repository for your convenience. + 1. Install the Glasgow Haskell Compiler (GHC) version 7.10 or higher. 2. Change to the directory containing this document. @@ -170,7 +174,7 @@ To run the full test suite, build the project as follows: > cabal configure --enable-tests > cabal build > cabal test - + Tasty will also allow you to run only those tests whose description match a pattern. Tests are organised in nested groups named after the relevant module and function, so pattern matching should be intuitive. For example, to run the @@ -181,7 +185,7 @@ tests for the `List` module you could run: Likewise, to run only the tests for the `headOr` function in the `List` module, you could use: > cabal test tasty --show-detail=direct --test-option=--pattern=List/headOr - + In addition, GHCi may be used to run tasty tests. Assuming you have run `ghci` from the root of the project, you may do the following. Remember that GHCi has tab completion, so you can save yourself some typing. @@ -210,7 +214,7 @@ Executing the tests is done with the `doctest` executable, which you may install using: > cabal install doctest - + Once installed, you may use doctest to run the doctests for a given module: > doctest -isrc -Wall -fno-warn-type-defaults @@ -258,7 +262,7 @@ others. For example, in the progression, `Course.Functor` to `Course.Monad`, the exercises repeat a similar theme. Instead, a participant may wish to do different exercises, such as `Course.Parser`. In this case, the remaining answers are filled out, so that progress on to `Course.Parser` can begin -(which depends on correct answers up to `Course.Monad`). It is recommended to +(which depends on correct answers up to `Course.Monad`). It is recommended to take this deviation if it is felt that there is more reward in doing so. Answers for the exercises can be found here: diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..36aca224c --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,13 @@ +Vagrant.configure("2") do |config| + config.vm.box = "ubuntu/xenial64" + + config.vm.provider 'virtualbox' do |vbox| + vbox.memory = 4096 + vbox.cpus = 2 + vbox.gui = true + end + + config.vm.provision 'ansible' do |ansible| + ansible.playbook = 'ops/ansible.yaml' + end +end diff --git a/ops/README.md b/ops/README.md new file mode 100644 index 000000000..33b72b544 --- /dev/null +++ b/ops/README.md @@ -0,0 +1,38 @@ +# Vagrant Box + +If you'd rather use a pre-configured haskell development environment, then these instructions will +get you up and running in a VirtualBox virtual machine. The machine includes: + + - A Xubuntu desktop environment + - GHC 8.0.2 installed + - doctest + - emacs with haskell-mode + - vim + - sublime + - VS Code + +**NOTE**: The VM's default user is `ubuntu` and their password is `ubuntu` + +**WARNING**: Building the environment might take a while and download gigabytes of pacakges over the internet. + +## Prerequisites + + - Install [VirtualBox](https://www.virtualbox.org/) + - Install [Vagrant](https://www.vagrantup.com/) + - Install [ansible](https://www.ansible.com/) + +## Make it so + +The following will download a VM image of Ubuntu and then provision it to build a desktop +environment for Haskell development. Once it's provisioned, reload the machine, which will log you +straight into a graphical environment. + +``` +cd fp-course +vagrant up +# go have lunch - this could take a while +vagrant reload +``` + +You should now see a virtual machine running Xubuntu. The course materials are checked out to +`~/fp-course` and you should have all required binaries on your PATH. diff --git a/ops/ansible.yaml b/ops/ansible.yaml new file mode 100644 index 000000000..d27021ee6 --- /dev/null +++ b/ops/ansible.yaml @@ -0,0 +1,54 @@ +--- +- name: "Install ansible deps (Python 2.7 stuff)" + hosts: all + user: ubuntu + gather_facts: false + tasks: + - name: "Install ansible requirements" + raw: apt-get update && apt-get install -y python2.7 python-simplejson + become: yes + +- name: "Setup Ubuntu 16.04" + hosts: all + user: ubuntu + + tasks: + - name: "Set ubuntu user's password to 'ubuntu'" + user: + name: ubuntu + password: $6$hVCglTDqXKLR45$b4M1N30zbQmieXbHpqm3z1yYCZKNq1jF554WU7AwiBI/z8DkbV1zyE.aYeZvOkCgxsWIJv63IBEwB9riNmdyY/ + become: yes + + - name: "Install packages" + apt: + name: "{{ item }}" + update_cache: yes + state: present + become: yes + with_items: + - emacs + - git + - vim + - xubuntu-desktop + - virtualbox-guest-x11 + + - name: "Automatically login as ubuntu user" + lineinfile: + line: autologin-user=ubuntu + dest: /usr/share/lightdm/lightdm.conf.d/60-xubuntu.conf + become: yes + + - name: "Checkout course repo" + git: + repo: https://github.com/data61/fp-course + dest: ~/fp-course + + - include: haskell.yaml + - include: vs-code.yaml + - include: sublime.yaml + + - name: "Copy emacs.d" + copy: + src: emacs.d/ + dest: ~/.emacs.d/ + mode: 0755 diff --git a/ops/emacs.d/init.el b/ops/emacs.d/init.el new file mode 100644 index 000000000..0d42077f7 --- /dev/null +++ b/ops/emacs.d/init.el @@ -0,0 +1,34 @@ +;; Pull in Marmalade packages +(require 'package) +(add-to-list 'package-archives + '("marmalade" . "http://marmalade-repo.org/packages/")) +(add-to-list 'package-archives + '("melpa" . "http://melpa.milkbox.net/packages/")) +(package-initialize) + +;; Ensure our preferred packages are all loaded in this install - taken from +;; http://batsov.com/articles/2012/02/19/package-management-in-emacs-the-good-the-bad-and-the-ugly/ +(defvar my-packages + '(markdown-mode + auto-complete + haskell-mode) + "A list of packages to ensure are installed at launch.") + +(require 'cl) +(defun my-packages-installed-p () + (loop for p in my-packages + when (not (package-installed-p p)) do (return nil) + finally (return t))) + +(unless (my-packages-installed-p) + ;; check for new packages (package versions) + (message "%s" "Emacs is now refreshing its package database...") + (package-refresh-contents) + (message "%s" " done.") + ;; install the missing packages + (dolist (p my-packages) + (when (not (package-installed-p p)) + (package-install p)))) + +;; Show column numbers in mode line +(column-number-mode t) diff --git a/ops/haskell.yaml b/ops/haskell.yaml new file mode 100644 index 000000000..be80f8cc6 --- /dev/null +++ b/ops/haskell.yaml @@ -0,0 +1,36 @@ +--- + +- name: Add ghc PPA + apt_repository: + repo: ppa:hvr/ghc + become: yes + +- name: Install ghc-8.0.2 + apt: + name: "{{ item }}" + update_cache: yes + state: present + with_items: + - ghc-8.0.2 + - cabal-install-1.24 + become: yes + +- name: Add cabal bin directory to PATH + lineinfile: + line: export PATH="{{ ansible_env.HOME }}/.cabal/bin:$PATH" + dest: ~/.profile + +- name: Add /opt/ghc/bin to the path + lineinfile: + line: export PATH=/opt/ghc/bin:$PATH + dest: ~/.profile + +- name: Update cabal + command: cabal update + environment: + PATH: "/opt/ghc/bin:{{ ansible_env.PATH }}" + +- name: Insall cabal packages + command: cabal install doctest + environment: + PATH: "/opt/ghc/bin:{{ ansible_env.PATH }}" diff --git a/ops/sublime.yaml b/ops/sublime.yaml new file mode 100644 index 000000000..92fd3b8cd --- /dev/null +++ b/ops/sublime.yaml @@ -0,0 +1,27 @@ +--- +- name: "Check if Sublime installed" + command: which subl + ignore_errors: true + register: haz_sublime + +- name: "Add apt key for sublime" + apt_key: + url: https://download.sublimetext.com/sublimehq-pub.gpg + state: present + become: yes + when: haz_sublime|failed + +- name: "Add source for sublime" + apt_repository: + repo: deb https://download.sublimetext.com/ apt/stable/ + state: present + become: yes + when: haz_sublime|failed + +- name: "Install sublime" + apt: + name: sublime-text + update_cache: yes + state: present + become: yes + when: haz_sublime|failed diff --git a/ops/vs-code.yaml b/ops/vs-code.yaml new file mode 100644 index 000000000..9d6d64780 --- /dev/null +++ b/ops/vs-code.yaml @@ -0,0 +1,27 @@ +--- +- name: "Check if VS Code is installed" + command: which code + ignore_errors: true + register: haz_code + +- name: "Download VS code" + get_url: + url: https://go.microsoft.com/fwlink/?LinkID=760868 + dest: /tmp/vs-code.deb + when: haz_code|failed + +# So the recommended install method is to install a thing with broken/missing +# dependencies, and then fix it. +- name: "Install VS Code deb" + command: dpkg -i /tmp/vs-code.deb + become: yes + ignore_errors: true + when: haz_code|failed + +- name: "Fix VS code installation" + command: apt-get install -fy + become: yes + when: haz_code|failed + +- name: "Install haskell syntax highlighting for VS Code" + command: code --install-extension justusadam.language-haskell